Skip to content

Commit

Permalink
Merge pull request #58 from MATLAB-Community-Toolboxes-at-INCF/enpack…
Browse files Browse the repository at this point in the history
…-datastore

Relocate custom datastore to root namespace
  • Loading branch information
stevevanhooser authored May 21, 2024
2 parents 035afed + 618fc44 commit d88fc68
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
classdef DeepInterpolationDataStore < matlab.io.Datastore & ...
classdef Datastore < matlab.io.Datastore & ...
matlab.io.datastore.Subsettable & ...
matlab.io.datastore.Shuffleable
%DEEPINTERPOLATIONDATASTORE - custom datastore for DeepInterpolation-MATLAB
% DATASTORE - custom datastore for DeepInterpolation-MATLAB
%
% This custom datastore provides flanking frames and the center frame
% upon one read.
%
% dids = DeepInterpolationDataStore(pathToTiffFile, options);
% dids = deepinterp.Datastore(pathToTiffFile, options);
%
% Input must be full path to a grayscale, single channel tiff stack of
% >'flankingFrames + 2' frames in order to work (this is according to
Expand Down Expand Up @@ -36,7 +36,7 @@
end

methods % begin methods section
function myds = DeepInterpolationDataStore(filePath, options)
function myds = Datastore(filePath, options)
arguments
filePath
options = struct();
Expand Down Expand Up @@ -257,4 +257,4 @@ function reset(myds)

end

end
end
2 changes: 1 addition & 1 deletion +deepinterp/setup.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ function setup()
addpath(fullfile(tbd, "sampleData"))
addpath(fullfile(tbd, "pretrainedModels"))
addpath(fullfile(tbd, "examples"))
addpath(fullfile(tbd, "datastore"))


2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The principle behind DeepInterpolation is illustrated in the following figure fr
![Figure 1a from Lecoq et al. 2021](sampleData/Lecoq_et_al_2021_Fig1a.png).
-->

To predict the frame-of-interest ("predicted frame"), a deep learning network uses data from several preceeding and succeeding video frames. During training, the network is modified so that it produces better and better representations of the predicted frames over several datasets. During inference, the network produces predicted frames that are used in place of the original data. If the signal in the data is well predicted by the information in the preceeding and succeeding frames, then the inferred data contains a reconstruction of the original data where the usual noise that occurs independently on each frame is greatly reduced, because it is not predicted on average. The signal can be inferred with high quality in part because the network can average out the independent noise in the preceeding and succeeding frames to uncover the underlying signal just prior to and just after the signal in the predicted frame.
To predict the frame-of-interest ("predicted frame"), a deep learning network uses data from several preceeding and succeeding video frames. During training, the network is modified so that it produces better and better representations of the predicted frames over several datasets. During inference, the network produces predicted frames that are used in place of the original data. DeepInterpolation works well in situations where the signal in the data is well predicted by the information in the preceeding and succeeding frames. In these cases, the inferred data contains a good reconstruction of the underlying signal while the noise that occurs independently on each frame is greatly reduced, because the noise is not predicted on average.

### Installation
🚧
Expand Down
Binary file modified examples/tiny_ophys_training.mlx
Binary file not shown.
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

%% Test 01: Check if matlab.io.Datastore is superclass.
% A deepinterpolation datastore inherits from abstract Datastore
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
assert(isa(dids,'matlab.io.Datastore'));

%% Test 02: Call the read
Expand All @@ -30,7 +30,7 @@
% The first frame that allows that is the 32nd!
% The combination of training data and center frame is called a "set" here, and the
% number of sets, following the logic above, is N-Frames - 62.
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
t = read(dids);
assert(iscell(t));
assert(numel(t) == 2);
Expand All @@ -39,7 +39,7 @@

%% Test 03: Call the read again
% Standard sequential datastore behavior: advance to "second" center-frame
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
[t,info] = read(dids);
assert(iscell(t));
Expand All @@ -50,7 +50,7 @@

%% Test 04: Successfully read until no more data
% The testdatastack should return 38 sets of training frames and reference frame
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
count = 0;
while(hasdata(dids))
read(dids);
Expand All @@ -59,7 +59,7 @@
assert(count == 38);

%% Test 05: Call read when out of data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
try
read(dids);
catch ME
Expand All @@ -69,12 +69,12 @@
%% Test 11: Call the readall method
% Standard sequential datastore behavior: return all data in a nx2 Cell array, for
% the test dataset n==38
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
allt = readall(dids);
assert(all(size(allt)==[38 2]));

%% Test 12: Call the readall method when out of data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
while(hasdata(dids))
read(dids);
end
Expand All @@ -83,7 +83,7 @@

%% Test 21: Call the reset method before any read
% Reset to "first" frame (in fact, the 32nd frame in the stack...)
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
reset(dids);
[t,info] = read(dids);
assert(iscell(t));
Expand All @@ -93,7 +93,7 @@
assert(info == "set=1/centerframe=32");

%% Test 22: Call the reset method after some reads
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
read(dids);
read(dids);
Expand All @@ -106,7 +106,7 @@
assert(info == "set=1/centerframe=32");

%% Test 23: Call the reset method after readall
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
tall = readall(dids);
reset(dids);
Expand All @@ -118,7 +118,7 @@
assert(info == "set=1/centerframe=32");

%% Test 24: Call the reset method when out of data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
while(hasdata(dids))
read(dids);
end
Expand All @@ -131,32 +131,32 @@
assert(info == "set=1/centerframe=32");

%% Test 31: Call the progress method before any reads
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
p = progress(dids);
assert(p==0);

%% Test 32: Call the progress method after readall but before read.
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
readall(dids);
p = progress(dids);
assert(p==0);

%% Test 33: Call the progress method after read
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
p = progress(dids);
assert((p-0.0270)<1e-4);

%% Test 34: Call the progress method when out of data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
while(hasdata(dids))
read(dids);
end
p = progress(dids);
assert((p-1.0)<1e-4);

%% Test 35: Progress produces correct output over all sets
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
idx = 1;
while(hasdata(dids))
p(idx) = progress(dids);
Expand All @@ -168,7 +168,7 @@
assert(all(diff(p) > 0), "progress must be monotonically increasing");

%% Test 41: Preview methods returns first set
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
t = preview(dids);
assert(iscell(t));
assert(numel(t) == 2);
Expand All @@ -177,7 +177,7 @@
assert((t{1}(323,23,44)-138)<1e-4);

%% Test 42: Preview methods returns first set after reads
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
read(dids);
t = preview(dids);
Expand All @@ -188,7 +188,7 @@
assert((t{1}(323,23,44)-138)<1e-4);

%% Test 43: Preview methods returns first set after readall
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
readall(dids);
t = preview(dids);
assert(iscell(t));
Expand All @@ -198,7 +198,7 @@
assert((t{1}(323,23,44)-138)<1e-4);

%% Test 44: Preview methods returns first set after reads and reset
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
read(dids);
reset(dids);
Expand All @@ -210,7 +210,7 @@
assert((t{1}(323,23,44)-138)<1e-4);

%% Test 45: Preview methods returns first set when out of data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
while hasdata(dids)
read(dids);
end
Expand All @@ -222,7 +222,7 @@
assert((t{1}(323,23,44)-138)<1e-4);

%% Test 46: Read after preview is from correct location
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
read(dids);
preview(dids);
Expand All @@ -234,13 +234,13 @@
assert(info == "set=3/centerframe=34");

%% Test 47: Readall after preview works correctly
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
preview(dids);
allt = readall(dids);
assert(all(size(allt)==[38 2]));

%% Test 48: Hasdata works correctly after preview
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
read(dids);
preview(dids);
assert(hasdata(dids));
Expand All @@ -249,22 +249,22 @@
% A partition of the deepinterpolation datastore is merely pointing to a different
% startframe and has a smaller number of available sets. All the other behaviors are
% derived from that
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,10,7);
assert(isa(subds,'matlab.io.Datastore'));

%% Test 51: Call Partition, check if the partition has correct properties
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,10,7);
assert(isequal(properties(dids),properties(subds)));

%% Test 52: Call Partition, check if the partition has correct methods
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,10,7);
assert(isequal(methods(dids),methods(subds)));

%% Test 53: Call Partition, successfully read from a partition
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,10,7);
[t,info] = read(subds);
assert(iscell(t));
Expand All @@ -274,14 +274,14 @@
assert(info == "set=1/centerframe=56");

%% Test 54: Call last Partition, read all data
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,13,13);
while hasdata(subds)
read(subds);
end

%% Test 55: Call Partition, check that total number of sets/frames is correct
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
partsets = 0;
for iii = 1:10
subds = partition(dids,10,iii);
Expand All @@ -290,15 +290,15 @@
assert(partsets-38 < 1e-4);

%% Test 56: Call partition with partition=1 and index=1 and validate
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,1,1);
assert(isequal(properties(dids),properties(subds)));
assert(isequal(methods(dids),methods(subds)));
assert(isequaln(read(subds),read(dids)));
assert(isequaln(preview(subds),preview(dids)));

%% Test 57: Partition a partition again and validate
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,2,2);
subsubds = partition(subds,2,2);
[t,info] = read(subsubds);
Expand All @@ -309,7 +309,7 @@
assert(info == "set=1/centerframe=61");

%% Test 58: Progress is working correctly in partitions
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = partition(dids,2,2);
idx = 1;
clear p
Expand All @@ -327,7 +327,7 @@
%% Test 60: Create a Subset of the datastore and validate
% deepinterpolation datastore is subsettable, again this just assigns the correct
% startframe and number of available sets, but points to the same file
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = subset(dids,5:20);
[t,info]=read(subds);
assert(iscell(t));
Expand All @@ -337,7 +337,7 @@
assert(info == "set=1/centerframe=36");

%% Test 61: Progress is working correctly in subsets
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
subds = subset(dids,5:10);
idx = 1;
clear p
Expand All @@ -354,27 +354,27 @@

%% Test 71: Fail on wrong image size
try
dids = DeepInterpolationDataStore(WRONGSIZETESTSTACKFULLFILE); %#ok<NASGU>
dids = deepinterp.Datastore(WRONGSIZETESTSTACKFULLFILE); %#ok<NASGU>
catch EM
assert(strcmp(EM.message,'Actual frame size is not equal to specified outputFrameSize'),"Fail on wrong tiff size");
end

%% Test 72: Read data with automatic resize
options.doAutoResize = true;
dids = DeepInterpolationDataStore(WRONGSIZETESTSTACKFULLFILE, options);
dids = deepinterp.Datastore(WRONGSIZETESTSTACKFULLFILE, options);
t = read(dids);
assert(iscell(t));
assert(numel(t) == 2);
assert(all((size(t{1})==[512 512 60])));
assert(all((size(t{2})==[512 512])));

%% Test 81: Shuffling returns randomized datastore without error
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
shds = shuffle(dids);
assert(isa(shds,'matlab.io.Datastore'));

%% Test 82: can read sequentially from shuffled datastore
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
shds = shuffle(dids);
count = 0;
while(hasdata(shds))
Expand All @@ -384,7 +384,7 @@
assert(count == 38);

%% Test 83: can read all from shuffled datastore
dids = DeepInterpolationDataStore(TESTSTACKFULLFILE);
dids = deepinterp.Datastore(TESTSTACKFULLFILE);
shds = shuffle(dids);
allt = readall(shds);
assert(all(size(allt)==[38 2]));
assert(all(size(allt)==[38 2]));

0 comments on commit d88fc68

Please sign in to comment.