123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- function createFrames()
-
- %%%%%%%%%%%%%%%%%% DLB created 5/21/07 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % VERSION 2.3
- %
- % Updated: 2/23/09
- %
- % USEAGE: >> createFrames *hit Enter* :p
- %
- % DEPENDENCIES:
- % - you need a C:\Data folder (you should have this in Jeraj's grp
- % - need a data set WITH a .header file that was obtained using
- % Robert Pyzalski's adv2fl, adv2float, or Get_image program
- %
- % WHAT IT DOES:
- % this function converts anything from pyzalski's script into amira format
- % and puts the .am files in their appropriate places.
- % breaks up dynamic (4D) PET scans of any size and
- % correctly writes them as SUV or MBq/ml into Amira format regardless
- % of: the number of frames, pixel size, FOV size, recon grid. Currently
- % only C-11, F-18, Cu-61, and Cu-64 tracers have been put in. It
- % shouldn't be too much trouble to add others if ever the need arises.
- %
- % YES I'M AWARE THAT I DON'T APPLY THE 1/2 VOXEL SHIFT TO THE CT
- % Change amiraCTWriter if it bothers you.
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % CHANGES to createFrames:
- %
- % VERSION 2.3
- % edit: removed the char(13) problem from certain headers that add extra
- % carrage returns, Ngoneh spotted it
- % - I changed the syntax that searches through the header files
- % DLB - 2/23/09
- %
- % VERSION 2.2
- % edit: Matt V pointed out MBq to mCi conversion still incorrect
- % - from *0.037 to /37. Finally correct
- % - FIXED 'static' and 'dynamic' string length bug that would ignore
- % any 'static' scan mode. Used 'else' to rename scan_mode for 'static'
- % cases. WILL NOT WORK with strcmp for future reference.
- % DLB - 1/6/09
- %
- % VERSION 2.1
- % edit: Matt V noted that my MBq to mCi conversion was incorrect
- % - fixed both from *0.037 to /37 dumb mistake
- % DLB - 11/5/08
- %
- % edit: Added stuff to the GUI that automatically updates
- % - mCi and uCi values for Matt V
- % - SUV factor for awesomeness
- % DLB - 10/24/08
- %
- % edit:
- % - Fixed flipz for all the PET's
- % - Added a mCi indicator to GUI
- % - Changed injection time and scan start times
- % DLB - 10/23/08
- %
- % VERSION 2.0
- % edit: After renaming this createStatic, I've switched back because I
- % like createFrames better (as does everyone else). Now the program:
- % - reads any size CT (converts them to shorts, thanks Keisha).
- % - has a nice SUV GUI with units and matching colours
- % - automatically flips the z dimension without asking
- % - added amiraCTWriter, amiraWriter, and checkHeader
- % - still need to write the WriteToHeader function!! lazy lazy
- % DLB - 10/17/08
- %
- % VERSION 1.0
- % edit: Added the _SUV_fr and _MBq_fr to the file ID (fid).
- % DLB - 12/13/07
- %
- % edit: Keisha pointed out the SUV calc was wrong along with a host of
- % other problems (radionuclide_name, logical check). I removed the ~
- % from logical and all seems to work fine.
- % DLB - 12/12/07
- %
- % edit: now added error messages and changes in case the header file has
- % insufficient information for the SUV calculation. cut out a bunch of
- % redundant code.
- % DLB - 11/28/07
- %
- % edit: now the ultimate... prompts you for MBq/ml or SUV values.
- % also prompts you for z-flipping. correctly decay corrects residual
- % to the initial syringe measurement, then corrects that value to the
- % start of the scan. all this is done by reading the header. no
- % more createFrames('flip')! won't work!
- % DLB - 11/27/07
- %
- % edit: added varargin to handle flipdim(?,3).
- % usage: createFrames('flip') - DLB 9/20/07
- % or createFrames <enter> for regular mode
- %
- % future will put in 'SUV' option as well
- %
- % edit: added half a voxel length to amira images, b/c that's how amira
- % reads them in. we've been doing it wrong all along!! - DLB 9/20/07
- %
- % edit: Changed the XYZBox in writing to Amira such that
- % everything is centered relative to a 50 cm CT FOV. ex. a 38 cm FOV is
- % centered so that it is in the center of the bounding box. - DLB 9/20/07
- % ____________ ____________
- % | | | | ______ |
- % | 30 | | to | | | |
- % |______| | | | 30 | |
- % | 50 | | |______| | <-- 50 cm
- % |____________| |____________|
- %
- % edit: Super huge update. Can now read multiple or single files of any
- % size file input without running out of memory!! 256x256 for 33
- % frames tested, works. This thing can handle it all now - DLB
- % 9/(18-19)/07
- % edit: now can read 1 file at a time again isa() - DLB 9/18/07
- % edit: now reads multiple files at once - DLB 9/16/07
- % edit: reads 4 unit frames e.g. 1120 - DLB summer 07
- % edit: reads header info now - DLB 5/22/07
- %
- % STOLE THE fprintp stuff from RTF's geom2am.m
- %
- warning off;
- s = pwd;
- cd C:\Data\
- %% here I'm just going to flip everything by default, uncomment the dialog for else
- % flip = questdlg('Flip the z dimension for everything you select?','Z-flip','Yes','No','Cancel');
- flip = 'Yes';
- % GUI for picking your .img files
- [filename, pathname, filterindex] = uigetfile({'*.img';'*.*'},'File Selector','Multiselect','on');
- if isequal(filename,0)
- disp('User selected Cancel')
- fclose all
- return
- else
- if isa(filename,'cell')
- for k = 1:length(filename)
- disp(['User selected ', fullfile(pathname, filename{k})])
- leng = length(filename);
- end
- else
- disp(['User selected ', fullfile(pathname, filename)])
- leng = 1;
- end
- end
- for numFile = 1:leng
- header_filename = filename;
- % open the .img file and associated .header file
- if isa(filename,'cell')
- header_fid = fopen([pathname strrep(header_filename{numFile},'.img','.header')],'r','ieee-be');
- fil = filename{numFile};
- else
- header_fid = fopen([pathname strrep(header_filename,'.img','.header')],'r','ieee-be');
- fil = filename;
- end
- header_num = fread(header_fid,inf);
- header = char(header_num(find(header_num~=13)))';
-
- % find dimensions of image
- modality = header(findstr(header,'modality = ')+11:findstr(header,'scan_mode = ')-2);
- XCount = str2num(header(findstr(header,'x_dim = ')+7:findstr(header,'y_dim')-2));
- YCount = str2num(header(findstr(header,'y_dim = ')+8:findstr(header,'z_dim')-2));
- ZCount = str2num(header(findstr(header,'z_dim = ')+8:findstr(header,'x_pixdim')-2));
- xpixdim = str2num(header(findstr(header,'x_pixdim = ')+11:findstr(header,'y_pixdim = ')-2));
- ypixdim = str2num(header(findstr(header,'y_pixdim = ')+11:findstr(header,'z_pixdim = ')-2));
- zpixdim = str2num(header(findstr(header,'z_pixdim = ')+11:findstr(header,'plane_thickness')-2));
- % I dont' know why I put this in. CT doesn't write 'scan_mode =' maybe?
- if isempty(modality)
- modality = header(findstr(header,'modality = ')+11:findstr(header,'image1_datetime = ')-2);
- end
-
- switch modality
- case 'CT'
- cd(pathname);
- cd('..');
- if exist('Formatted','dir') ~= 7
- mkdir Formatted
- end
- cd('Formatted');
- data = reshape(fread(fopen([pathname fil],'r','ieee-be'),inf,'float=>short'),XCount,YCount,ZCount);
- if strcmp(flip,'Yes')
- data = flipdim(data,3);
- end
- amiraCTWriter(data,strrep(fil,'.img','.am'),xpixdim,ypixdim,zpixdim,XCount,YCount,ZCount,xpixdim*XCount,zpixdim*ZCount);
- case 'PET' % this can only be a string of 2 characters for comparison to 'CT'
- voxel_value = questdlg(['Output voxel values for: ' fil],'Voxel Values','SUV','MBq/ml','Both','Cancel');
- scan_mode = header(findstr(header,'scan_mode = ')+12:findstr(header,'radionuclide_name = ')-2);
- % check to see if scan is dynamic or static
- if strcmp(scan_mode,'dynamic')
- frames = str2num(header(findstr(header,'number_of_frames = ')+18:findstr(header,'scan_datetime')-2));
- ZCount = ZCount/frames; % should always be 35 b/c # of axial PET slices
- else
- scan_mode = 'static';
- end
- % you need to make sure voxel_value is only 3 elements long for
- % the OR if statements later on. stupid need to find a more
- % elegent fix.
- switch length(voxel_value)
- case 4
- voxel_value = 'Bot';
- case 6
- voxel_value = 'MBq';
- end
-
- if ((strcmp(voxel_value,'SUV')) | (strcmp(voxel_value,'Bot')))
- if isempty(findstr(header,'patient_wt (kg)'))
- patient_wt = 0;
- tracer_activity = str2num(header(findstr(header,'tracer_activity = ')+17:findstr(header,'meas_datetime')-2));
- else
- patient_wt = str2num(header(findstr(header,'patient_wt (kg) = ')+17:findstr(header,'meas_datetime')-2));
- tracer_activity = str2num(header(findstr(header,'tracer_activity = ')+17:findstr(header,'patient_wt (kg) = ')-2));
- end
- meas_datetime = header(findstr(header,'meas_datetime')+27:findstr(header,'pre_inj_volume')-2);
- meas_datetime = meas_datetime(find((1-isspace(meas_datetime)))); % sparses the string (removes any spaces)
- scan_datetime = header(findstr(header,'scan_datetime = ')+27:findstr(header,'frame1_date')-2);
- scan_datetime = scan_datetime(find((1-isspace(scan_datetime)))); % sparses the string (removes any spaces)
- admin_datetime = header(findstr(header,'admin_datetime = ')+28:findstr(header,'post_inj_activity')-2);
- admin_datetime = admin_datetime(find((1-isspace(admin_datetime)))); % sparses the string (removes any spaces)
- post_inj_activity = str2num(header(findstr(header,'post_inj_activity = ')+20:findstr(header,'post_inj_datetime')-2));
- post_inj_datetime = header(findstr(header,'post_inj_datetime = ')+ 31:findstr(header,'decay_corr')-2);
- post_inj_datetime = post_inj_datetime(find((1-isspace(post_inj_datetime)))); % sparses the string (removes any spaces)
- radionuclide_name = header(findstr(header,'radionuclide_name = ')+20:findstr(header,'tracer_name')-2);
- radionuclide_name = radionuclide_name(find((1-isspace(radionuclide_name)))); % sparses the string (removes any spaces)
-
- if isempty(meas_datetime)
- meas_datetime = '00:00:00';
- end
- if isempty(admin_datetime)
- admin_datetime = '00:00:00';
- end
- if isempty(post_inj_datetime)
- post_inj_datetime = '00:00:00';
- end
-
- [status,patient_wt, tracer_activity, meas_datetime, scan_datetime, admin_datetime, post_inj_activity, post_inj_datetime, radionuclide_name] = checkHeader(fil,patient_wt, tracer_activity, meas_datetime, scan_datetime, admin_datetime, post_inj_activity, post_inj_datetime, radionuclide_name);
-
- % stop this program if the gui heard "cancel"
- if status == 'kill'
- disp('Cancelled at header GUI');
- return
- end
-
- % finding the time difference between the measured activity
- % time and the residual measured time, in seconds
- delta_hr = (str2num([post_inj_datetime(1) post_inj_datetime(2)])-str2num([meas_datetime(1) meas_datetime(2)]))*3600;
- delta_min = (str2num([post_inj_datetime(4) post_inj_datetime(5)])-str2num([meas_datetime(4) meas_datetime(5)]))*60;
- delta_sec = (str2num([post_inj_datetime(7) post_inj_datetime(8)])-str2num([meas_datetime(7) meas_datetime(8)]));
- delta_time = delta_hr + delta_min + delta_sec;
- switch radionuclide_name
- % all half life in sec
- case '61Cu'
- t_half = 3.333*3600;
- case '18F'
- t_half = 6588;
- case '64Cu'
- t_half = 45720;
- case '11C'
- t_half = 20.334*60;
- end
-
- % correcting the measured syringe activity by subtracting
- % off the decay corrected residual activity
- true_inj_activity = tracer_activity - post_inj_activity*exp(delta_time*log(2)/t_half);
-
- % finding the time difference between the measured activity
- % time and the start of the scan
- scan_delta_hr = (str2num([scan_datetime(1) scan_datetime(2)])-str2num([meas_datetime(1) meas_datetime(2)]))*3600;
- scan_delta_min = (str2num([scan_datetime(4) scan_datetime(5)])-str2num([meas_datetime(4) meas_datetime(5)]))*60;
- scan_delta_sec = (str2num([scan_datetime(7) scan_datetime(8)])-str2num([meas_datetime(7) meas_datetime(8)]));
- scan_delta_time = scan_delta_hr + scan_delta_min + scan_delta_sec;
-
- % decay correcting the injected dose to the start of the scan
- true_inj_activity_at_scan_start = true_inj_activity*exp(-scan_delta_time*log(2)/t_half);
- %prepare to open and write the PET_SUV
- cd(pathname)
- cd('..')
- if exist('Processed','dir') ~= 7
- mkdir Processed
- end
- cd Processed
-
-
- switch scan_mode
- case 'dynamic'
- if exist('frames','dir') ~= 7
- mkdir frames;
- end
- cd frames
- file_id = fopen([pathname fil],'r','ieee-be');
- for t = 1:frames
- data = reshape(fread(file_id,XCount*YCount*ZCount,'float'),XCount,YCount,ZCount);
- data = data./(true_inj_activity_at_scan_start/(patient_wt*1000));
- if strcmp(flip,'Yes')
- data = flipdim(data,3);
- end
- amiraWriter(data,[strrep(fil,'.img','_SUV_fr') int2str(t) '.am'],xpixdim,ypixdim,zpixdim,XCount,YCount,ZCount,xpixdim*XCount,zpixdim*ZCount);
- end
- case 'static'
- data = reshape(fread(fopen([pathname fil],'r','ieee-be'),inf,'float'),XCount,YCount,ZCount);
- data = data./(true_inj_activity_at_scan_start/(patient_wt*1000));
- if strcmp(flip,'Yes')
- data = flipdim(data,3);
- end
- amiraWriter(data,strrep(fil,'.img','_SUV.am'),xpixdim,ypixdim,zpixdim,XCount,YCount,ZCount,xpixdim*XCount,zpixdim*ZCount);
- end
- clear data;
- end
- if ((strcmp(voxel_value,'MBq')) | (strcmp(voxel_value,'Bot')))
- %prepare to open and write the PET_SUV
- cd(pathname)
- cd('..')
- if exist('Formatted','dir') ~= 7
- mkdir Formatted
- end
- cd Formatted
- switch scan_mode
- case 'dynamic'
- fseek(header_fid,findstr(header,'number_of_frames')+18,'bof');
- frames = str2num(char(fread(header_fid,findstr(header,'scan_datetime')-findstr(header,'number_of_frames')-20,'char')'));
- if exist('frames','dir') ~= 7
- mkdir frames
- end
- cd frames
- file_id = fopen([pathname fil],'r','ieee-be');
- for t = 1:frames
- data = reshape(fread(file_id,XCount*YCount*ZCount,'float'),XCount,YCount,ZCount);
- if strcmp(flip,'Yes')
- data = flipdim(data,3);
- end
- amiraWriter(data,[strrep(fil,'.img','_MBq_fr') int2str(t) '.am'],xpixdim,ypixdim,zpixdim,XCount,YCount,ZCount,xpixdim*XCount,zpixdim*ZCount);
- end
- case 'static'
- data = reshape(fread(fopen([pathname fil],'r','ieee-be'),inf,'float'),XCount,YCount,ZCount);
- if strcmp(flip,'Yes')
- data = flipdim(data,3);
- end
- amiraWriter(data,strrep(fil,'.img','_MBq.am'),xpixdim,ypixdim,zpixdim,XCount,YCount,ZCount,xpixdim*XCount,zpixdim*ZCount);
- clear data;
- end
- end
- end
- end
- fclose all;
- cd(s);
- end
- %% BELOW ARE FUNCTIONS THAT THIS PROGRAM NEEDS TO EXECUTE %%
- %
- % DO NOT MESS WITH THESE OR YOU WILL INCUR MY WRATH!!!
- %
- % amiraWriter
- % amiraCTWriter
- % checkHeader
- %
- % Seriously, hands off!!!
- %
- %% amiraWriter
- function amiraWriter(data,filename,dx,dy,dz,M,N,P,FOV,zFOV)
- fid = fopen([filename],'w');
- fprintf(fid,'# AmiraMesh 3D BINARY 2.0\n\n');
- fprintf(fid,['# CreationDate: ' datestr(now,'ddd mmm') datestr(now,' dd HH:MM:SS yyyy') '\n\n']);
- fprintf(fid,'define Lattice %g %g %g\n\n',M,N,P);
- fprintf(fid,'Parameters {\n');
- fprintf(fid,' Content "%gx%gx%g %s, uniform coordinates",',M,N,P,'float');
- fprintf(fid,' BoundingBox %g %g %g %g %g %g,\n',(50-FOV)/2+dx/2,50-(50-FOV)/2-dx/2,(50-FOV)/2+dy/2,50-(50-FOV)/2-dy/2,0,zFOV-dz);
- fprintf(fid,' CoordType "uniform"\n');
- fprintf(fid,'}\n\n');
- fprintf(fid,'Lattice { %s Data } @1\n\n','float');
- fprintf(fid,'# Data section follows\n');
- fprintf(fid,'@1\n');
- fclose(fid); % close the text part of the file
- fid = fopen([filename],'ab','ieee-be');
- fwrite(fid,data(:,:,:),'float');
- fclose(fid);
- disp(['Wrote to ' filename]);
- end
-
- %% amiraCTWriter
- function amiraCTWriter(data,filename,dx,dy,dz,M,N,P,FOV,zFOV)
- fid = fopen([filename],'w');
- fprintf(fid,'# AmiraMesh 3D BINARY 2.0\n\n');
- fprintf(fid,['# CreationDate: ' datestr(now,'ddd mmm') datestr(now,' dd HH:MM:SS yyyy') '\n\n']);
- fprintf(fid,'define Lattice %g %g %g\n\n',M,N,P);
- fprintf(fid,'Parameters {\n');
- fprintf(fid,' Content "%gx%gx%g %s, uniform coordinates",',M,N,P,'short');
- fprintf(fid,' BoundingBox %g %g %g %g %g %g,\n',0,FOV-dx,0,FOV-dy,0,zFOV-dz);
- fprintf(fid,' CoordType "uniform"\n');
- fprintf(fid,'}\n\n');
- fprintf(fid,'Lattice { %s Data } @1\n\n','short');
- fprintf(fid,'# Data section follows\n');
- fprintf(fid,'@1\n');
- fclose(fid); % close the text part of the file
- fid = fopen([filename],'ab','ieee-be');
- fwrite(fid,data(:,:,:),'short');
- fclose(fid);
- end
- %% checkHeader
- function [status,patient_wt, tracer_activity, meas_datetime, scan_datetime, injection_time, post_inj_activity, post_inj_datetime, radionuclide_name] = checkHeader(study_name,patient_wt,tracer_activity,meas_datetime,scan_datetime,injection_time,post_inj_activity,post_inj_datetime,radionuclide_name)
- global okay_val
- global cancel_val
- global writeit_val
- okay_val = 0;
- cancel_val = 0;
- writeit_val = 0;
- status = 1; % this tells createStatic to stop trying to process data. status = 'kill'
- gui = figure('Position',[700,500,310,303]);
- patient_ID_txt = uicontrol('Style','text','String','Patient ID:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8 272 80 20]);
- patient_ID = uicontrol('Style','text','String',study_name,'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[92 272 180 20]);
- patient_wt_txt = uicontrol('Style','text','String','Patient Weight:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8 246 80 20]);
- patient_wt_units = uicontrol('Style','text','String','kgs','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 246 25 20]);
- tracer_activity_txt = uicontrol('Style','text','String','Tracer Activity:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8 220 80 20]);
- % all the txt in the gui
- meas_datetime_units = uicontrol('Style','text','String','MBq @','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 220 35 20]);
- meas_datetime_mCi = uicontrol('Style','text','String','mCi','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 194 35 20]);
- scan_datetime_time = uicontrol('Style','text','String','hh:mm:ss','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[246 220 46 20]);
- scan_datetime_txt = uicontrol('Style','text','String','Scan Start Time:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8 168 80 20]);
- scan_datetime_hh = uicontrol('Style','text','String','hh:mm:ss','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 168 46 20]);
- injection_time_txt = uicontrol('Style','text','String','Injection Time:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8,142,80,20]);
- scan_datetime_txt2 = uicontrol('Style','text','String','hh:mm:ss','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 142 46 20]);
- post_inj_activity_txt = uicontrol('Style','text','String','Post Inj Activity:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8 116 80 20]);
- post_inj_datetime_txt = uicontrol('Style','text','String','MBq @','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150,116,35,20]);
- post_inj_datetime_time = uicontrol('Style','text','String','hh:mm:ss','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[246 116 46 20]);
- post_inj_datetime_uCi = uicontrol('Style','text','String','uCi','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 90 35 20]);
- radionuclide_name_txt = uicontrol('Style','text','String','Radionuclide:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8,64,80,20]);
- radionuclide_name_txt2 = uicontrol('Style','text','String','ex: 18F or 61Cu','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','left','Position',[150 64 80 20]);
- SUV_factor_txt = uicontrol('Style','text','String','SUV Factor:','BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','right','Position',[8,38,80,20]);
- % all the editable fields
- patient_wt_var = uicontrol('Style','edit','String',patient_wt,'BackgroundColor','white','Position',[92 250 55 20]);
- tracer_activity_var = uicontrol('Style','edit','String',tracer_activity,'BackgroundColor','white','Position',[92 224 55 20]);
- tracer_activity_mCi = uicontrol('Style','text','String',num2str(tracer_activity/37),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Position',[92 194 55 20]);
- meas_datetime_var = uicontrol('Style','edit','String',meas_datetime,'BackgroundColor','white','Position',[188 224 55 20]);
- scan_datetime_var = uicontrol('Style','edit','String',scan_datetime,'BackgroundColor','white','Position',[92 172 55 20]);
- injection_time_var = uicontrol('Style','edit','String',injection_time,'BackgroundColor','white','Position',[92 146 55 20]);
- post_inj_activity_var = uicontrol('Style','edit','String',post_inj_activity,'BackgroundColor','white','Position',[92 120 55 20]);
- post_inj_datetime_var = uicontrol('Style','edit','String',post_inj_datetime,'BackgroundColor','white','Position',[188 120 55 20]);
- post_inj_activity_uCi = uicontrol('Style','text','String',num2str(post_inj_activity/37*1000),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Position',[92 90 55 20]);
- radionuclide_name_var = uicontrol('Style','edit','String',radionuclide_name,'BackgroundColor','white','Position',[92 68 55 20]);
- okay = uicontrol('Style','pushbutton','String','Okay','Position',[25,5,70,25],'Callback',@okay_Callback);
- cancel = uicontrol('Style','pushbutton','String','Cancel','Position',[105,5,70,25],'Callback',@cancel_Callback);
- writeit = uicontrol('Style','pushbutton','String','Write to header','Position',[185,5,100,25],'Callback',@writeit_Callback);
-
- wait_for_it = 0;
- while wait_for_it == 0
- pause(1); % listen for a button push
- % listen for updates to Tracer Activity and update the mCi box
- tracer_activity = str2num(get(tracer_activity_var,'String'));
- tracer_activity_mCi = uicontrol('Style','text','String',num2str(tracer_activity/37),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Position',[92 194 55 20]);
- post_inj_activity = str2num(get(post_inj_activity_var,'String'));
- post_inj_activity_uCi = uicontrol('Style','text','String',num2str(post_inj_activity/37*1000),'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Position',[92 90 55 20]);
- %% this part calculates the SUV factor with the parameters shown
- tracer_activity = str2num(get(tracer_activity_var,'String'));
- post_inj_activity = str2num(get(post_inj_activity_var,'String'));
- radionuclide_name = get(radionuclide_name_var,'String');
- post_inj_datetime = get(post_inj_datetime_var,'String');
- meas_datetime = get(meas_datetime_var,'String');
- scan_datetime = get(scan_datetime_var,'String');
- patient_wt = str2num(get(patient_wt_var,'String'));
- % finding the time difference between the measured activity
- % time and the residual measured time, in seconds
- delta_hr = (str2num([post_inj_datetime(1) post_inj_datetime(2)])-str2num([meas_datetime(1) meas_datetime(2)]))*3600;
- delta_min = (str2num([post_inj_datetime(4) post_inj_datetime(5)])-str2num([meas_datetime(4) meas_datetime(5)]))*60;
- delta_sec = (str2num([post_inj_datetime(7) post_inj_datetime(8)])-str2num([meas_datetime(7) meas_datetime(8)]));
- delta_time = delta_hr + delta_min + delta_sec;
- switch radionuclide_name
- case '61Cu'
- t_half = 3.333*3600; % half life in sec
- case '18F'
- t_half = 6588;
- case '64Cu'
- t_half = 45720;
- case '11C'
- t_half = 20.334*60;
- end
-
- % correcting the measured syringe activity by subtracting
- % off the decay corrected residual activity
- true_inj_activity = tracer_activity - post_inj_activity*exp(delta_time*log(2)/t_half);
- % finding the time difference between the measured activity
- % time and the start of the scan
- scan_delta_hr = (str2num([scan_datetime(1) scan_datetime(2)])-str2num([meas_datetime(1) meas_datetime(2)]))*3600;
- scan_delta_min = (str2num([scan_datetime(4) scan_datetime(5)])-str2num([meas_datetime(4) meas_datetime(5)]))*60;
- scan_delta_sec = (str2num([scan_datetime(7) scan_datetime(8)])-str2num([meas_datetime(7) meas_datetime(8)]));
- scan_delta_time = scan_delta_hr + scan_delta_min + scan_delta_sec;
- % decay correcting the injected dose to the start of the scan
- true_inj_activity_at_scan_start = true_inj_activity*exp(-scan_delta_time*log(2)/t_half);
- SUV_factor = 1/(true_inj_activity_at_scan_start/(patient_wt*1000));
- SUV_factor_var = uicontrol('Style','text','String',SUV_factor,'BackgroundColor',[0.8 0.8 0.8],'HorizontalAlignment','center','Position',[92 38 55 20]);
- % Listen for hit
- if okay_val == 1
- patient_wt = str2num(get(patient_wt_var,'String'));
- tracer_activity = str2num(get(tracer_activity_var,'String'));
- meas_datetime = get(meas_datetime_var,'String');
- scan_datetime = get(scan_datetime_var,'String');
- injection_time = get(injection_time_var,'String');
- post_inj_activity = str2num(get(post_inj_activity_var,'String'));
- post_inj_datetime = get(post_inj_datetime_var,'String');
- radionuclide_name = get(radionuclide_name_var,'String');
- wait_for_it = 1;
- close(gui);
- end
- if cancel_val == 1
- disp('Cancel was hit');
- close(gui);
- wait_for_it = 1;
- status = 'kill';
- return
- end
- if writeit_val == 1
- disp('Cancel was hit');
- close(gui);
- wait_for_it = 1;
- return
- end
- end
- end
- function okay_Callback(source,eventdata)
- global okay_val
- global cancel_val
- global writeit_val
- okay_val = 1;
- cancel_val = 0;
- writeit_val = 0;
- end
-
- function cancel_Callback(source,eventdata)
- global okay_val
- global cancel_val
- global writeit_val
- okay_val = 0;
- cancel_val = 1;
- writeit_val = 0;
- end
- function writeit_Callback(source,eventdata)
- global okay_val
- global cancel_val
- global writeit_val
- okay_val = 0;
- cancel_val = 0;
- writeit_val = 0;
- disp('Write to header dun work yet!');
- end
|