Include physio processing#3
Conversation
jsheunis
left a comment
There was a problem hiding this comment.
Thanks! I've made some comments and asked some questions on various lines of code.
| 'CallBack', @generateReport, ... | ||
| 'UserData', 0,... | ||
| 'fontsize', gui_data.button_font_size); | ||
| gui_data.pb_get_physio_batch = uicontrol('Parent', gui_data.panel_rtsummary,... |
There was a problem hiding this comment.
The positioning of the button and dropdown on the GUI is not great, when run on my Mac:

@NinaWie Does is render differently on your system?
Previously I haven't given much attention to cross-platform functionality, at least in the sense that the display of the GUI and buttons are fine. Maybe that needs some more attention.
For this specific case, maybe check if you can update the position of these UIcontrols, and perhaps others on the same tab and group, such that the layout is user friendly.
There was a problem hiding this comment.
Yes, it renders perfectly fine on my system. But I now changed it such that "select vendor" is inside the drop down menu, which I like better than the label above the menu anyway. You can try again, the new commit should be part of the pull request already. Let me know if it's still ugly on the mac.
| matlabbatch{1}.spm.tools.physio.log_files.respiration = {''}; | ||
| matlabbatch{1}.spm.tools.physio.log_files.scan_timing = {''}; | ||
| elseif strcmp(data_vendor, 'Philips') | ||
| [scanphyslog, ~] = spm_select(1,'.*.log','Specify SCANPHYSLOG.log file',{}, default_path); |
There was a problem hiding this comment.
For some reason the SPM select box takes multiple seconds to open up on my system. @NinaWie do you experience the same behaviour? Just trying to see if it's just my system (which typically doesn't have this type of delay)
There was a problem hiding this comment.
It also takes a while on my system and actually the spm select box is not very user friendly anyways. I will change it to a matab file select object.
| end | ||
|
|
||
| % read scan parameters | ||
| input_params = inputdlg({'Number of scans:','Number of slices:','Number of dummies:', 'TR:', 'Onset slice:'}, 'Parameters for physio'); |
There was a problem hiding this comment.
It seems like some of these parameters can be derived from the data that were already analysed at this point, or entered by the user at an earlier stage, e.g. slices, scans, dummies. For clarity, @NinaWie did you create this input dialog because you are uncertain which variables already exist in the workspace, or for a different reason?
Another question, how are number of scans and dummies differentiated? e.g. if I have 5 dummies and 210 scans, that totals 215 scans. Is the "Numer of scans" then 210 or 215?
There was a problem hiding this comment.
I think the number of dummies is in addition to the others, so the number of scans would be 210. Good point, we have to specify this in the input dialog I guess. Regarding the other parameters, I couldn't find any except the number of scans in the previous parameters when doing online processing with rtQC, and I asked Lydia about it as well. We could read the number of slices and number of scans from the header of the nifti file, but since other parameters need to be input manually, we thought it would it better to do that for all of these parameters, also in case that a user processes some data online and then wants to do physio processing on other data. We can also discuss that in a Skype though.
There was a problem hiding this comment.
Ok, so as discussed you'll add most of the fields required for PhysIO to the defaults m-file. Then on the Post QC tab only ask the user to input the necessary remaining files/parameters (e.g. the physio traces as you do currently). Do you have the same understanding?
What I could do after that is run through the parameters you've added to the m-file and double check that they are not already declared or generated somewhere else throughout the process of Pre-QC and Online QC.
| matlabbatch{1}.spm.tools.physio.log_files.sampling_interval = []; | ||
| matlabbatch{1}.spm.tools.physio.log_files.relative_start_acquisition = 0; | ||
| matlabbatch{1}.spm.tools.physio.log_files.align_scan = 'last'; % sometimes first, sometimes last | ||
| matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Nslices = str2double(input_params{2}); |
There was a problem hiding this comment.
Does Physio create RETROICOR regressors per slice? Why is the number of slices important? Is slice order and/or interleaved specifications also important?
| matlabbatch{1}.spm.tools.physio.preproc.cardiac.initial_cpulse_select.auto_matched.min = 0.4; | ||
| matlabbatch{1}.spm.tools.physio.preproc.cardiac.initial_cpulse_select.auto_matched.file = 'initial_cpulse_kRpeakfile.mat'; | ||
| matlabbatch{1}.spm.tools.physio.preproc.cardiac.posthoc_cpulse_select.off = struct([]); | ||
| matlabbatch{1}.spm.tools.physio.model.output_multiple_regressors = 'multiple_regressors.txt'; |
There was a problem hiding this comment.
I think we should name this something like "retroicor_regressors.txt" to make it clearer what is contained in the file, since "multiple_regressors.txt" is also standard in SPM itself.
| if ispc % Windows is not case-sensitive | ||
| onPath = any(contains(pathCell, 'PhysIO')); | ||
| else | ||
| onPath = any(contains(pathCell, 'PhysIO')); | ||
| end |
There was a problem hiding this comment.
The outcome of both if and else components will be identical, right? I see no difference in lines 1471 and 1473.
There was a problem hiding this comment.
You're right, I changed it. I copied that from somewhere and didn't check whether there is a difference.
| error("ERROR: Physio toolbox not installed or not added to path. Follow installation instructions on https://github.com/translationalneuromodeling/tapas."); | ||
| end |
There was a problem hiding this comment.
The double quote gives an error in Matlab versions earlier than 2017a, I suggest we use single quotes for now and then add code to handle version differences in a future PR
| % template | ||
| matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Nprep = []; | ||
| matlabbatch{1}.spm.tools.physio.scan_timing.sync.nominal = struct([]); | ||
| matlabbatch{1}.spm.tools.physio.preproc.cardiac.modality = 'ECG'; |
There was a problem hiding this comment.
What other options are there for cardiac.modality? Since, for example, scanphyslog can also contain traces for PPU (versus ECG / VCG). Does this paramater have to be updated if this is the case?
There was a problem hiding this comment.
As I said in the comment below, I did not ask the user for this parameter to keep it as simple as possible. You are right though that we probably have to ask for it, because the options are kind of crucial and can't be read from the files themselves. I checked but the modality is not given in the file headers or corresponding json files. The options are ECG, OXY/PPU, ECG_WiFi and PPU_WiFi.
There was a problem hiding this comment.
This is one of the parameters that, in my opinion, we probably should ask for in the Post QC tab and not put in the defaults. What do you think?
There was a problem hiding this comment.
Yes, I will add it to the input window
| matlabbatch{1}.spm.tools.physio.model.rvt.no = struct([]); | ||
| matlabbatch{1}.spm.tools.physio.model.hrv.no = struct([]); |
There was a problem hiding this comment.
Is there a specific reason for excluding RVT and HRV regressors? Do you think it's sensible to give the user the choice of which regressors to include?
This would also depend on what we want to do with the regressors, if it's for offline correction or just for quality plotting and comparison purposes. I think eventually we want to do both, and currently I have to think a bit first before deciding which has priority. But worth thinking about how this would be handled programmatically already.
There was a problem hiding this comment.
In general, I took the template from physIO and added only the information that is required. The reason for not asking the users about more parameter was that I thought the more things have to be manually input, the more it just resembles spm. In explanation, you can also use physio with the SPM GUI and you have to specify all these parameters, so if we do the same, it will become redundant to include it in rtQC. Therefore my idea was to provide a simple version that only requires the mandatory input fields, and all other parameters are filled in with the defaults from the physIO template.
Of course however it does make sense to include RVT and HRV regressors if this information is relevant for further processing with rtQC. What exactly do you mean by "worth thinking about how this would be handled programmatically already"? How to get the user input for these parameters? Or how to implement offline correction / plotting with the regressors?
There was a problem hiding this comment.
Sorry I think my use of English was not great in that sentence. I meant that we should think how we set up functions and parameters such that we can use either defaults or user input to decide which regressors to generate.
Based on today's discussion I would say we add these options to the defaults for now, for e.g. default HRV could be no. Then at some point we should make it clear to the user that clicking the "Get PhysIO batch" button will generate a specific set of regressors based on defaults, and that they can change these defaults if required. I think a full explanation would fit better into the software documentation, and a very short info sentence would be useful in the app itself.
There was a problem hiding this comment.
I agree, I will add some message that the user can change the defaults if required.
| disp("Saved matlabbatch in:"); | ||
| disp(out_dir); | ||
|
|
||
| % spm_jobman('run',matlabbatch); |
There was a problem hiding this comment.
If this line is uncommented, am I correct in understanding that the resulting batch will generate the regressors and nothing else? Or does this also trigger further processes with Physio?
There was a problem hiding this comment.
If this line is uncommented, it starts the whole physIO processing and generate regressors as well as plots showing the regressors and signals over time. I remembered from our Skype conversation that we decided just to save the batch, but we could also include this line such that physio processing is directly executed. That's a design choice on how much you want to have rtQC do automatically.
There was a problem hiding this comment.
Ok, so as discussed today we will let this run. If Physio is not installed it will error out. If installed, it will:
- run the batch
- generate the regressors
- fetch useful timeseries and plots from Physio and plot in rtQC
- add the same useful information to the HTML report
I created a button for physio processing with the PhysIO toolbox.
When everything runs correctly, the batch file for physio will be saved in the general output directory that is specified in the PreQC tab.