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 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