-
Notifications
You must be signed in to change notification settings - Fork 5
Code to select the aod motion computation method based on file versio… #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
8486b32
f250860
ee7d0f7
c1307c1
18c46c0
a9aa2f1
7e0835e
45a1f9e
a61d775
7e2dc49
4ac02b1
452df84
0a854db
418afa1
1d741aa
817e259
ee19c89
aa2dad5
a667013
f1c2a70
d7620db
205cdc4
5c681f8
1302179
666ddae
e2d236e
33b7752
0a7ed69
f876949
a40ff29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,3 +4,4 @@ getHost.m | |
| .* | ||
| *~ | ||
| ~* | ||
| startup*.* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
|
|
||
| function oldversion=checkFileVersion(fn) | ||
|
|
||
| oldversion = true ; | ||
| try | ||
| version = h5readatt(fn,'/','Version') ; | ||
| if (version==2) | ||
| oldversion = false ; | ||
| % motion data are in the new 3d format | ||
| else | ||
| br = aodReader(fn, 'Motion') ; | ||
| sz = size(br.motionCoordinates) ; | ||
| if rem(nthroot(sz(1),3),1)==0 % a way to handle files older than version 2 where a volume with cubic dimension was collected | ||
| oldversion = false ; | ||
| end | ||
| end | ||
| catch | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,16 +27,24 @@ function makeTuples(self, key) | |
|
|
||
| tuple = key; | ||
|
|
||
| br = getFile(acq.AodScan & key,'Motion'); | ||
| motionData = br(:,:,:); | ||
| [T D P] = size(motionData); | ||
| mot = reshape(motionData,[T 10 20 P]); | ||
| mot = permute(mot, [4 2 3 1]); | ||
| t = br(:,'t'); | ||
| coordinates = br.motionCoordinates; | ||
|
|
||
| fn = char(fetchn(acq.AodScan & key, 'aod_scan_filename')) ; % get the filename from db | ||
| oldversion = aod.checkFileversion(fn) ; % check if motion data is in old format, i.e. 2 planes or in new format, i.e. a volume | ||
|
||
| if (oldversion) | ||
| br = getFile(acq.AodScan & key,'Motion'); | ||
| motionData = br(:,:,:); | ||
| [T D P] = size(motionData); | ||
| mot = reshape(motionData,[T 10 20 P]); | ||
| mot = permute(mot, [4 2 3 1]); | ||
| t = br(:,'t'); | ||
| coordinates = br.motionCoordinates; | ||
|
|
||
|
|
||
| [xpos ypos zpos details] = aod.trackMotion(mot, t, coordinates); | ||
| [xpos,ypos,zpos,details] = aod.trackMotion(mot, t, coordinates); | ||
| else | ||
| % returned positions in microns and time in secs | ||
| % the motion data channel is hardcoded to 2, should be eventually guided by some info in the database | ||
| [xpos,ypos,zpos,t] = aod.trackMotion3D(fn, 2); | ||
| end | ||
| tuple.x = xpos; | ||
| tuple.y = ypos; | ||
| tuple.z = zpos; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
|
|
||
| function [x,y,z,t] = trackMotion3D(fn, analysischan) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we refactor this a bit so move all the code that deals with the raw file access into ScanMotion (like it is for the original code) and then make this method just take the data set and process it? that would keep the two consistent.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have to run motion detection during realtime acq as well as during offline analysis. Because realtime implementation came first, the code is residing in folder structure that we have for realtime stuff. We can rearrange if it is absolutely necessary, for sure we dont want to duplicate the same code in different folders |
||
|
|
||
| %% test function computeshifts | ||
| % requires z:\libraries\matlab in path | ||
| run(getLocalPath('/lab/libraries/hdf5matlab/setPath.m')) ; | ||
|
||
|
|
||
| downsampleFactor = 1 ; % skip frames if > 1 | ||
| numFramesToAverageForRef = 10 ; % frames to average to determine the reference frame against which motion is computed | ||
| useMultiCore = true ; | ||
| postRefStartFrameTime = 0 ; % N secs to skip before analyzing motion signals, in many cases, right after starting the point scan, there is a slight drift | ||
|
|
||
| br = aodReader(fn, 'Motion') ; | ||
|
||
| br1 = AodMotionCorrectionReader(fn) ; % if motion was corrected by using aod offsets, this is where they would be read | ||
|
||
|
|
||
| dat = br(:,:,:) ; | ||
| numSamples = br1.sz ; | ||
| duration = numSamples(:,1)/br1.Fs ; % sec | ||
|
|
||
| motion_fs = size(dat,1)/duration ; % this is based on the temporal sampling rate | ||
| delta_t = downsampleFactor/motion_fs ; | ||
|
|
||
| numPlanes = br.planes ; | ||
| coordinates = br.motionCoordinates ; | ||
|
|
||
| % get pmt chan data | ||
| dat2 = squeeze(dat(:,:,analysischan)) ; | ||
| clearvars dat ; | ||
| gridSize = sqrt(size(dat2,2)/numPlanes) ; | ||
|
|
||
| % frame number to start from | ||
| postRefStartFrame = max(round(postRefStartFrameTime*motion_fs),1) ; | ||
|
|
||
| % chop off the first N secs | ||
| dat2 = dat2(postRefStartFrame:end, :) ; | ||
|
|
||
| needReference = true ; % first get a reference frame | ||
| refparams = [] ; | ||
| calibparams = [0 1; 0 1; 0 1] ; % dont apply any calibration | ||
| shifts = zeros(size(dat2,1),3); % store motion vectors here | ||
| dat2(1,:) = mean(dat2(1:numFramesToAverageForRef,:)) ; % average frames for computing reference | ||
| [shifts(1,:), refparams] = computeshifts(dat2(1,:)',coordinates,gridSize,calibparams,refparams,needReference) ; % this position of the fitted sphere is treated as the reference | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this function is missing. above it references it being in lab\libraries\matlab but i don't see it there. also, please let's not spread these dependencies across multiple repositories.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is in z:\libraries\TwoPhoton\AOD_Control\MotionCorrection. Note that we are using the same motion detection code that is used from the Labview program during real-time acquisition.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really like duplicating code in two places, but at the same time in this case I think it would be better than spanning dependencies between two pretty separate projects. It also avoids unintended side effects if one of the formats changes the other would break.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, would make the sessions folder self contained but we will have to remember to keep the two folders synced. |
||
|
|
||
| % setup for parallel processing | ||
| if (useMultiCore) | ||
| try | ||
| mypool = parpool ; % use max processors | ||
| catch | ||
| fprintf('Unable to start parallel pool, single processor will be used') ; | ||
| useMultiCore = false ; | ||
| end | ||
| end | ||
|
|
||
| % take into account frames to skip, i.e. sampling rate of motion, | ||
| % downsample with averaging | ||
| adat = zeros(size(dat2)) ; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace these loops with matlab's implementation of downsampling.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did not change, cant find downsampling code that will average samples, dont want to deal with filters |
||
| if (downsampleFactor>1) | ||
| count = 0 ; | ||
| for ii=numFramesToAverageForRef+downsampleFactor:downsampleFactor:size(dat2,1) | ||
| count = count + 1 ; | ||
| adat(count,:) = adat(count,:) + sum(dat2(ii-downsampleFactor+1:ii,:)) ; | ||
| adat(count,:) = adat(count,:) / downsampleFactor ; | ||
| end | ||
| else | ||
| adat = dat2(numFramesToAverageForRef+1:end,:) ; | ||
| count = size(adat,1); | ||
| end | ||
|
|
||
| needReference=false ; % no need for a reference, start computing positions relative to the reference of spheres in subsequent motion frames | ||
| if (useMultiCore) | ||
| parfor ii=1:count | ||
| shifts(ii+numFramesToAverageForRef,:) = computeshifts(adat(ii,:)',coordinates,gridSize,calibparams,refparams,needReference) ; | ||
| end | ||
| delete(mypool) ; | ||
| else | ||
| for ii=1:count | ||
| shifts(ii+numFramesToAverageForRef,:) = computeshifts(adat(ii,:)',coordinates,gridSize,calibparams,refparams,needReference) ; | ||
| if (rem(count,100)==0) | ||
| fprintf('Processed %d frames', count) ; | ||
| end | ||
| end | ||
| end | ||
| x = squeeze(shifts(numFramesToAverageForRef+1:end,2)) ; | ||
| y = squeeze(shifts(numFramesToAverageForRef+1:end,1)) ; | ||
| z = squeeze(shifts(numFramesToAverageForRef+1:end,3)) ; | ||
| t=((0:1:length(x)-1)*delta_t)+(numFramesToAverageForRef/motion_fs) ; % the first motion position is after the last frame used for reference calculations | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is failing for me when analyzing
specifically the h5readatt fails so we fall through to the catch statement. i believe this experiment was recorded with the new format, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh... works fine for the file you mention on at-ssp, Matlab R2016b. Is h5readatt working for other files ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check it from a mac? i'm using this from my local machine (R2016a but that command was introduced in 2011a)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, h5readatt does not work on my Mac 2016a... let me check why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it works if the file name is /Volumes/M....
Is this what you meant in the comment getFile... To translate the file name for the platform used ?