#!/usr/bin/env python # note: in the script, runs are 1-based (probably expected) import string, sys, os from time import asctime # AFNI modules from afni_base import * from afni_util import * from option_list import * from db_mod import * import ask_me # ---------------------------------------------------------------------- # globals g_help_string = """ =========================================================================== afni_proc.py - generate a tcsh script for an AFNI process stream This python script can generate a processing script via a command-line interface, with an optional question/answer session (-ask_me), or by a tk GUI (eventually). The user should provide at least the input datasets (-dsets) and stimulus files (-regress_stim_*), in order to create an output script. See the 'DEFAULTS' section for a description of the default options for each block. The output script, when executed will create a results directory, copy input files into it, and perform all processing there. So the user can delete the results directory and re-run the script at their whim. Note that the user need not actually run the output script. The user should feel free to modify the script for their own evil purposes, before running it. The text interface can be accessed via the -ask_me option. It envokes a question & answer session, during which this program sets user options on the fly. The user may elect to enter some of the options on the command line, even if using -ask_me. See "-ask_me EXAMPLES", below. -------------------------------------------------- TIMING FILE NOTE: One issue that the user must be sure of is the timing of the stimulus files (whether -regress_stim_files or -regress_stim_times is used). The 'tcat' step will remove the number of pre-steady-state TRs that the user specifies (defaulting to 0). The stimulus files, provided by the user, must match datasets that have had such TRs removed (i.e. the stim files should start _after_ steady state has been reached). -------------------------------------------------- PROCESSING STEPS (of the output script): The output script will go through the following steps, unless the user specifies otherwise. automatic steps (the tcsh script will always perform these): setup : check subject arg, set run list, create output dir, and copy stim files tcat : copy input datasets and remove unwanted initial TRs default steps (the user may skip these, or alter their order): tshift : slice timing alignment on volumes (default is -time 0) volreg : volume registration (default to third volume) blur : blur each volume (default is 4mm fwhm) mask : create a 'brain' mask from the EPI data (dilate 1 voxel) scale : scale each run mean to 100, for each voxel (max of 200) regress : regression analysis (default is GAM, peak 1, with motion params) optional steps (the default is _not_ to apply these blocks) despike : truncate spikes in each voxel's time series empty : placehold for some user commamd (using 3dTcat as sample) -------------------------------------------------- EXAMPLES (options can be provided in any order): 1. Minimum use, provide datasets and stim files (or stim_times files). Note that a dataset suffix (e.g. HEAD) must be used with wildcards, so that datasets are not applied twice. In this case, a stim_file with many columns is given, allowing the script to change it to stim_times files. afni_proc.py -dsets epiRT*.HEAD \\ -regress_stim_files stims.1D or without any wildcard, the .HEAD suffix is not needed: afni_proc.py -dsets epiRT_r1+orig epiRT_r2+orig epiRT_r3+orig \\ -regress_stim_files stims.1D ** The following examples can be run from the AFNI_data2 directory, and are examples of how one might process the data for subject ED. Because the stimuli are on a 1-second grid, while the EPI data is on a 2-second grid (TR = 2.0), we ran make_stim_times.py to generate the stim_times files (which are now distributed in AFNI_data2) as follows: make_stim_times.py -prefix stim_times -tr 1.0 -nruns 10 -nt 272 \\ -files misc_files/all_stims.1D If your AFNI_data2 directory does not have misc_files/stim_times.*, then you can run the make_stim_times.py command from AFNI_data2. 2. This example shows basic usage, with the default GAM regressor. We specify the output script name, the subject ID, removal of the first 2 TRs of each run (before steady state), and volume alignment to the end of the runs (the anat was acquired after the EPI). The script name will default to proc.ED, based on -subj_id. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -subj_id ED \\ -tcat_remove_first_trs 2 \\ -volreg_align_to first \\ -regress_stim_times misc_files/stim_times.*.1D 3. Similar to #2, but add labels for the 4 stim types, and apply TENT as the basis function to get 14 seconds of response, on a 2-second TR grid. Also, copy the anat dataset(s) to the results directory, and align volumes to the third TR, instead of the first. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -subj_id ED.8 \\ -copy_anat ED/EDspgr \\ -tcat_remove_first_trs 2 \\ -volreg_align_to third \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_stim_labels ToolMovie HumanMovie \\ ToolPoint HumanPoint \\ -regress_basis 'TENT(0,14,8)' 4. This is the current AFNI_data2 class example. Similar to #3, but append a single -regress_opts_3dD option to include contrasts. The intention is to create a script very much like analyze_ht05. Note that the contrast files have been renamed from contrast*.1D to glt*.txt, though the contents have not changed. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -subj_id ED.8.glt \\ -copy_anat ED/EDspgr \\ -tcat_remove_first_trs 2 \\ -volreg_align_to third \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_stim_labels ToolMovie HumanMovie \\ ToolPoint HumanPoint \\ -regress_basis 'TENT(0,14,8)' \\ -regress_opts_3dD \\ -gltsym ../misc_files/glt1.txt -glt_label 1 FullF \\ -gltsym ../misc_files/glt2.txt -glt_label 2 HvsT \\ -gltsym ../misc_files/glt3.txt -glt_label 3 MvsP \\ -gltsym ../misc_files/glt4.txt -glt_label 4 HMvsHP \\ -gltsym ../misc_files/glt5.txt -glt_label 5 TMvsTP \\ -gltsym ../misc_files/glt6.txt -glt_label 6 HPvsTP \\ -gltsym ../misc_files/glt7.txt -glt_label 7 HMvsTM 5. Similar to #4, but replace some glt files with SYM, and request to run @auto_tlrc. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -subj_id ED.8.gltsym \\ -copy_anat ED/EDspgr \\ -tlrc_anat \\ -tcat_remove_first_trs 2 \\ -volreg_align_to third \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_stim_labels ToolMovie HumanMovie \\ ToolPoint HumanPoint \\ -regress_basis 'TENT(0,14,8)' \\ -regress_opts_3dD \\ -gltsym 'SYM: -ToolMovie +HumanMovie -ToolPoint +HumanPoint' \\ -glt_label 1 HvsT \\ -gltsym 'SYM: +HumanMovie -HumanPoint' \\ -glt_label 2 HMvsHP 6. Similar to #3, but find the response for the TENT functions on a 1-second grid, such as how the data is processed in the class script, s1.analyze_ht05. This is similar to using '-stim_nptr 2', and requires the addition of 3dDeconvolve option '-TR_times 1.0' to see the -iresp output on a 1.0 second grid. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -subj_id ED.15 \\ -copy_anat ED/EDspgr \\ -tcat_remove_first_trs 2 \\ -volreg_align_to third \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_stim_labels ToolMovie HumanMovie \\ ToolPoint HumanPoint \\ -regress_basis 'TENT(0,14,15)' \\ -regress_opts_3dD -TR_times 1.0 7. Similar to #2, but add the despike block, and skip the tshift and mask blocks (so the others must be specified). The user wants to apply a block that afni_proc.py does not deal with, putting it after the 'despike' block. So 'empty' is given after 'despike'. Also, apply a 4 second BLOCK response function, prevent the output of a fit time series dataset, run @auto_tlrc at the end, and specify an output script name. afni_proc.py -dsets ED/ED_r??+orig.HEAD \\ -blocks despike empty volreg blur scale regress \\ -script process_ED.b4 \\ -subj_id ED.b4 \\ -copy_anat ED/EDspgr \\ -tlrc_anat \\ -tcat_remove_first_trs 2 \\ -volreg_align_to third \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_basis 'BLOCK(4,1)' \\ -regress_no_fitts -------------------------------------------------- -ask_me EXAMPLES: a1. Apply -ask_me in the most basic form, with no other options. afni_proc.py -ask_me a2. Supply input datasets. afni_proc.py -ask_me -dsets ED/ED_r*.HEAD a3. Same as a2, but supply the datasets in expanded form. No suffix (.HEAD) is needed when wildcards are not used. afni_proc.py -ask_me \\ -dsets ED/ED_r01+orig ED/ED_r02+orig \\ ED/ED_r03+orig ED/ED_r04+orig \\ ED/ED_r05+orig ED/ED_r06+orig \\ ED/ED_r07+orig ED/ED_r08+orig \\ ED/ED_r09+orig ED/ED_r10+orig a4. Supply datasets, stim_times files and labels. afni_proc.py -ask_me \\ -dsets ED/ED_r*.HEAD \\ -regress_stim_times misc_files/stim_times.*.1D \\ -regress_stim_labels ToolMovie HumanMovie \\ ToolPoint HumanPoint -------------------------------------------------- DEFAULTS: basic defaults for each block (not all defaults) setup: - use 'SUBJ' for the subject id (option: -subj_id SUBJ) - create a t-shell script called 'proc_subj' (option: -script proc_subj) - use results directory 'SUBJ.results' (option: -out_dir SUBJ.results) tcat: - do not remove any of the first TRs empty: - do nothing (just copy the data using 3dTcat) despike: - NOTE: by default, this block is _not_ used - use no extra options (so automask is default) tshift: - align slices to the beginning of the TR volreg: - align to third volume of first run, -zpad 1 (option: -volreg_align_to third) (option: -volreg_zpad 1) blur: - blur data using a 4 mm FWHM filter (option: -blur_filter -1blur_fwhm) (option: -blur_size 4) mask: - apply union of masks from 3dAutomask on each run scale: - scale each voxel to mean of 100, clip values at 200 regress: - use GAM regressor for each stim (option: -regress_basis) - use quadratic baseline for each run (option: -regress_polort 2) - output fit time series - output ideal curves for GAM/BLOCK regressors - output iresp curves for non-GAM/non-BLOCK regressors -------------------------------------------------- OPTIONS: (information options, general options, block options) (block options are ordered by block) ------------ information options ------------ -help : show this help -hist : show the module history -ver : show the version number ------------ general execution and setup options ------------ -ask_me : ask the user about the basic options to apply When this option is used, the program will ask the user how they wish to set the basic options. The intention is to give the user a feel for what options to apply (without using -ask_me). -bash : show example execution command in bash form After the script file is created, this program suggests how to run it (piping stdout/stderr through 'tee'). If the user is running the bash shell, this option will suggest the 'bash' form of a command to execute the newly created script. example of tcsh form for execution: tcsh -x proc.ED.8.glt |& tee output.proc.ED.8.glt example of bash form for execution: tcsh -x proc.ED.8.glt 2>&1 | tee output.proc.ED.8.glt Please see "man bash" or "man tee" for more information. -blocks BLOCK1 ... : specify the processing blocks to apply e.g. -blocks volreg blur scale regress e.g. -blocks despike tshift volreg blur scale regress default: tshift volreg blur mask scale regress The user may apply this option to specify which processing blocks are to be included in the output script. The order of the blocks may be varied, and blocks may be skipped. See also '-do_block' (e.g. '-do_block despike'). -copy_anat ANAT : copy the ANAT dataset to the results dir e.g. -copy_anat Elvis/mprage+orig This will apply 3dcopy to copy the anatomical dataset(s) to the results directory. Note that if a +view is not given, 3dcopy will attempt to copy +acpc and +tlrc datasets, also. See also '3dcopy -help'. -copy_files file1 ... : copy file1, etc. into the results directory e.g. -copy_files glt_AvsB.txt glt_BvsC.1D glt_eat_cheese.txt e.g. -copy_files contrasts/glt_*.txt This option allows the user to copy some list of files into the results directory. This would happen before the tcat block, so such files may be used for other commands in the script (such as contrast files in 3dDeconvolve, via -regress_opts_3dD). -do_block BLOCK_NAME ...: add extra blocks in their default positions e.g. -do_block despike Currently, the 'despike' block is the only block not applied by default (in the processing script). Any block not included in the default list can be added via this option. The default position for 'despike' is between 'tcat' and 'tshift'. This option should not be used with '-blocks'. See also '-blocks'. -dsets dset1 dset2 ... : (REQUIRED) specify EPI run datasets e.g. -dsets Elvis_run1+orig Elvis_run2+orig Elvis_run3+orig e.g. -dsets Elvis_run*.HEAD The user must specify the list of EPI run datasets to analyze. When the runs are processed, they will be written to start with run 1, regardless of whether the input runs were just 6, 7 and 21. Note that when using a wildcard it is essential for the EPI datasets to be alphabetical, as that is how the shell will list them on the command line. For instance, epi_run1+orig through epi_run11+orig is not alphabetical. If they were specified via wildward their order would end up as run1 run10 run11 run2 ... Note also that when using a wildcard it is essential to specify the datasets suffix, so that the shell doesn't put both the .BRIK and .HEAD filenames on the command line (which would make it twice as many runs of data). -keep_rm_files : do not have script delete rm.* files at end e.g. -keep_rm_files The output script may generate temporary files in a block, which would be given names with prefix 'rm.'. By default, those files are deleted at the end of the script. This option blocks that deletion. -move_preproc_files : move preprocessing files to preproc.data dir At the end of the output script, create a 'preproc.data' directory, and move most of the files there (dfile, outcount, pb*, rm*). -no_proc_command : do not print afni_proc.py command in script e.g. -no_proc_command If this option is applied, the command used to generate the output script will be stored at the end of the script. -out_dir DIR : specify the output directory for the script e.g. -out_dir ED_results default: SUBJ.results The AFNI processing script will create this directory and perform all processing in it. -script SCRIPT_NAME : specify the name of the resulting script e.g. -script ED.process.script default: proc_subj The output of this program is a script file. This option can be used to specify the name of that file. See also -scr_overwrite, -subj_id. -scr_overwrite : overwrite any existing script e.g. -scr_overwrite If the output script file already exists, it will be overwritten only if the user applies this option. See also -script. -subj_id SUBJECT_ID : specify the subject ID for the script e.g. -subj_id elvis default: SUBJ The suject ID is used in dataset names and in the output directory name (unless -out_dir is used). This option allows the user to apply an appropriate naming convention. -tlrc_anat : run @auto_tlrc on '-copy_anat' dataset e.g. -tlrc_anat After the regression block, run @auto_tlrc on the anatomical dataset provided by '-copy_anat'. By default, warp the anat to align with TT_N27+tlrc, unless the '-tlrc_base' option is given. The -copy_anat option specifies which anatomy to transform. Please see '@auto_tlrc -help' for more information. See also -copy_anat, -tlrc_base, -tlrc_no_ss. -tlrc_base BASE_DSET : run "@auto_tlrc -base BASE_DSET" e.g. -tlrc_base TT_icbm452+tlrc default: -tlrc_base TT_N27+tlrc This option is used to supply an alternate -base dataset for @auto_tlrc. Otherwise, TT_N27+tlrc will be used. Note that the default operation of @auto_tlrc is to "skull strip" the input dataset. If this is not appropriate, consider also the '-tlrc_no_ss' option. Please see '@auto_tlrc -help' for more information. See also -tlrc_anat, -tlrc_no_ss. -tlrc_no_ss : add the -no_ss option to @auto_tlrc e.g. -tlrc_no_ss This option is used to tell @auto_tlrc not to perform the skull strip operation. Please see '@auto_tlrc -help' for more information. -tlrc_rmode RMODE : apply RMODE resampling in @auto_tlrc e.g. -tlrc_rmode NN This option is used to apply '-rmode RMODE' in @auto_tlrc. Please see '@auto_tlrc -help' for more information. -tlrc_suffix SUFFIX : apply SUFFIX to result of @auto_tlrc e.g. -tlrc_suffix auto_tlrc This option is used to apply '-suffix SUFFIX' in @auto_tlrc. Please see '@auto_tlrc -help' for more information. -verb LEVEL : specify the verbosity of this script e.g. -verb 2 default: 1 Print out extra information during execution. ------------ block options ------------ These options pertain to individual processing blocks. Each option starts with the block name. -tcat_remove_first_trs NUM : specify how many TRs to remove from runs e.g. -tcat_remove_first_trs 3 default: 0 Since it takes several seconds for the magnetization to reach a steady state (at the beginning of each run), the initial TRs of each run may have values that are significantly greater than the later ones. This option is used to specify how many TRs to remove from the beginning of every run. -despike_opts_3dDes OPTS... : specify additional options for 3dDespike e.g. -despike_opts_3dDes -nomask -ignore 2 By default, 3dDespike is used with only -prefix. Any other options must be applied via -despike_opts_3dDes. Note that the despike block is not applied by default. To apply despike in the processing script, use either '-do_block despike' or '-blocks ... despike ...'. Please see '3dDespike -help' for more information. See also '-do_blocks', '-blocks'. -tshift_align_to TSHIFT OP : specify 3dTshift alignment option e.g. -tshift_align_to -slice 14 default: -tzero 0 By default, each time series is aligned to the beginning of the TR. This option allows the users to change the alignment, and applies the option parmeters directly to the 3dTshift command in the output script. It is likely that the user will use either '-slice SLICE_NUM' or '-tzero ZERO_TIME'. Note that when aligning to an offset other than the beginning of the TR, and when applying the -regress_stim_files option, then it may be necessary to also apply -regress_stim_times_offset, to offset timing for stimuli to later within each TR. Please see '3dTshift -help' for more information. See also '-regress_stim_times_offset'. -tshift_interp METHOD : specify the interpolation method for tshift e.g. -tshift_interp -Fourier e.g. -tshift_interp -cubic default -quintic Please see '3dTshift -help' for more information. -tshift_opts_ts OPTS ... : specify extra options for 3dTshift e.g. -tshift_opts_ts -tpattern alt+z This option allows the user to add extra options to the 3dTshift command. Note that only one -tshift_opts_ts should be applied, which may be used for multiple 3dTshift options. Please see '3dTshift -help' for more information. -volreg_align_to POSN : specify the base position for volume reg e.g. -volreg_align_to last default: third This option takes 'first', 'third' or 'last' as a parameter. It specifies whether the EPI volumes are registered to the first or third volume (of the first run) or the last volume (of the last run). The choice of 'first' or 'third' should correspond to when the anatomy was acquired before the EPI data. The choice of 'last' should correspond to when the anatomy was acquired after the EPI data. The default of 'third' was chosen to go a little farther into the steady state data. Note that this is done after removing any volumes in the initial tcat operation. Please see '3dvolreg -help' for more information. See also -tcat_remove_first_trs, -volreg_base_ind. -volreg_base_ind RUN SUB : specify volume/brick indices for base e.g. -volreg_base_ind 10 123 default: 0 0 This option allow the user to specify exactly which dataset and sub-brick to use as the base registration image. Note that the SUB index applies AFTER the removal of pre-steady state images. * The RUN number is 1-based, matching the run list in the output shell script. The SUB index is 0-based, matching the sub-brick of EPI time series #RUN. Yes, one is 1-based, the other is 0-based. Life is hard. The user can apply only one of the -volreg_align_to and -volreg_base_ind options. See also -volreg_align_to, -tcat_remove_first_trs. -volreg_opts_vr OPTS ... : specify extra options for 3dvolreg e.g. -volreg_opts_vr -noclip -nomaxdisp This option allows the user to add extra options to the 3dvolreg command. Note that only one -volreg_opts_vr should be applied, which may be used for multiple 3dvolreg options. Please see '3dvolreg -help' for more information. -volreg_zpad N_SLICES : specify number of slices for -zpad e.g. -volreg_zpad 4 default: -volreg_zpad 1 This option allows the user to specify the number of slices applied via the -zpad option to 3dvolreg. -blur_filter FILTER : specify 3dmerge filter option e.g. -blur_filter -1blur_rms default: -1blur_fwhm This option allows the user to specify the filter option from 3dmerge. Note that only the filter option is set here, not the filter size. The two parts were separated so that users might generally worry only about the filter size. Please see '3dmerge -help' for more information. See also -blur_size. -blur_size SIZE_MM : specify the size, in millimeters e.g. -blur_size 6.0 default: 4 This option allows the user to specify the size of the blur used by 3dmerge. It is applied as the 'bmm' parameter in the filter option (such as -1blur_fwhm). Please see '3dmerge -help' for more information. See also -blur_filter. -blur_opts_merge OPTS ... : specify extra options for 3dmerge e.g. -blur_opts_merge -2clip -20 50 This option allows the user to add extra options to the 3dmerge command. Note that only one -blur_opts_merge should be applied, which may be used for multiple 3dmerge options. Please see '3dmerge -help' for more information. -mask_type TYPE : specify 'union' or 'intersection' mask type e.g. -mask_type intersection default: union This option is used to specify whether the mask applied to the analysis is the union of masks from each run, or the intersection. The only valid values for TYPE are 'union' and 'intersection'. This is not how to specify that no mask is applied at all, that is done by excluding the mask block with the '-blocks' option. Please see '3dAutomask -help', '3dMean -help' or '3dcalc -help'. See also -mask_dilate, -blocks. -mask_dilate NUM_VOXELS : specify the number of time to dilate the mask e.g. -mask_dilate 3 default: 1 By default, the masks generated from the EPI data are dilated by 1 step (voxel), via the -dilate option in 3dAutomask. With this option, the user may specify the dilation. Valid integers must be at least zero. Please see '3dAutomask -help' for more information. See also -mask_type. -scale_max_val MAX : specify the maximum value for scaled data e.g. -scale_max_val 1000 default 200 The scale step multiples the time series for each voxel by a scalar so that the mean for that particular run is 100 (allowing interpretation of EPI values as a percentage of the mean). Values of 200 represent a 100% change above the mean, and so can probably be considered garbage (or the voxel can be considered non-brain). The output values are limited so as not to sacrifice the precision of the values of short datasets. Note that in a short (2-byte integer) dataset, a large range of values means bits of accuracy are lost for the representation. No max will be applied if MAX is <= 100. Please see 'DATASET TYPES' in the output of '3dcalc -help'. See also -scale_no_max. -scale_no_max : do not apply a limit to the scaled values The default limit for scaled data is 200. Use of this option will remove any limit from being applied. See also -scale_max_val. -regress_basis BASIS : specify the regression basis function e.g. -regress_basis 'BLOCK(4,1)' e.g. -regress_basis 'BLOCK(5)' e.g. -regress_basis 'TENT(0,14,8)' default: GAM This option is used to set the basis function used by 3dDeconvolve in the regression step. This basis function will be applied to all user-supplied regressors (please let me know if there is need to apply different basis functions to different regressors). Please see '3dDeconvolve -help' for more information, or the link: http://afni.nimh.nih.gov/afni/doc/misc/3dDeconvolveSummer2004 See also -regress_basis_normall, -regress_stim_times. -regress_basis_normall NORM : specify the magnitude of basis functions e.g. -regress_basis_normall 1.0 This option is used to set the '-basis_normall' parameter in 3dDeconvolve. It specifies the height of each basis function. For the example basis functions, -basis_normall is not recommended. Please see '3dDeconvolve -help' for more information. See also -regress_basis. -regress_fitts_prefix PREFIX : specify a prefix for the -fitts option e.g. -regress_fitts_prefix model_fit default: fitts By default, the 3dDeconvolve command in the script will be given a '-fitts fitts' option. This option allows the user to change the prefix applied in the output script. The -regress_no_fitts option can be used to eliminate use of -fitts. Please see '3dDeconvolve -help' for more information. See also -regress_no_fitts. -regress_iresp_prefix PREFIX : specify a prefix for the -iresp option e.g. -regress_iresp_prefix model_fit default: iresp This option allows the user to change the -iresp prefix applied in the 3dDeconvolve command of the output script. By default, the 3dDeconvolve command in the script will be given a set of '-iresp iresp' options, one per stimulus type, unless the regression basis function is GAM. In the case of GAM, the response form is assumed to be known, so there is no need for -iresp. The stimulus label will be appended to this prefix so that a sample 3dDeconvolve option might look one of these 2 examples: -iresp 7 iresp_stim07 -iresp 7 model_fit_donuts The -regress_no_iresp option can be used to eliminate use of -iresp. Please see '3dDeconvolve -help' for more information. See also -regress_no_iresp, -regress_basis. -regress_make_ideal_sum IDEAL.1D : create IDEAL.1D file from regressors e.g. -regress_make_ideal_sum ideal_all.1D If the -regress_basis function is a single parameter function (either GAM or some form of BLOCK), then this option can be applied to create an ideal response curve which is the sum of the individual stimulus response curves. Use of this option will add a 3dTstat command to sum the regressor (of interest) columns of the 1D X-matrix, output by 3dDeconvolve. This is simlilar to the default behavior of creating ideal_STIM.1D files for each stimulus label, STIM. Please see '3dDeconvolve -help' and '3dTstat -help'. See also -regress_basis, -regress_no_ideals. -regress_no_fitts : do not supply -fitts to 3dDeconvolve e.g. -regress_no_fitts This option prevents the program from adding a -fitts option to the 3dDeconvolve command in the output script. See also -regress_fitts_prefix. -regress_no_ideals : do not generate ideal response curves e.g. -regress_no_ideals By default, if the GAM or BLOCK basis function is used, ideal resonse curve files are generated for each stimulus type (from the output X matrix using '3dDeconvolve -x1D'). The names of the ideal response function files look like 'ideal_LABEL.1D', for each stimulus label, LABEL. This option is used to supress generation of those files. See also -regress_basis, -regress_stim_labels. -regress_no_iresp : do not supply -iresp to 3dDeconvolve e.g. -regress_no_iresp This option prevents the program from adding a set of -iresp options to the 3dDeconvolve command in the output script. By default -iresp will be used unless the basis function is GAM. See also -regress_iresp_prefix, -regress_basis. -regress_no_motion : do not apply motion params in 3dDeconvolve e.g. -regress_no_motion This option prevents the program from adding the registration parameters (from volreg) to the 3dDeconvolve command. -regress_opts_3dD OPTS ... : specify extra options for 3dDeconvolve e.g. -regress_opts_3dD -gltsym ../contr/contrast1.txt \\ -glt_label 1 FACEvsDONUT \\ -xjpeg Xmat This option allows the user to add extra options to the 3dDeconvolve command. Note that only one -regress_opts_3dD should be applied, which may be used for multiple 3dDeconvolve options. Please see '3dDeconvolve -help' for more information, or the link: http://afni.nimh.nih.gov/afni/doc/misc/3dDeconvolveSummer2004 -regress_polort DEGREE : specify the polynomial degree of baseline e.g. -regress_polort 1 default: 2 3dDeconvolve models the baseline for each run separately, using Legendre polynomials (by default). This option specifies the degree of polynomial. Note that this will create DEGREE * NRUNS regressors. Please see '3dDeconvolve -help' for more information. -regress_stim_labels LAB1 ... : specify labels for stimulus types e.g. -regress_stim_labels houses faces donuts default: stim01 stim02 stim03 ... This option is used to apply a label to each stimulus type. The number of labels should equal the number of files used in the -regress_stim_times option, or the total number of columns in the files used in the -regress_stim_files option. These labels will be applied as '-stim_label' in 3dDeconvolve. Please see '3dDeconvolve -help' for more information. See also -regress_stim_times, -regress_stim_labels. -regress_stim_times FILE1 ... : specify files used for -stim_times e.g. -regress_stim_times ED_stim_times*.1D e.g. -regress_stim_times times_A.1D times_B.1D times_C.1D 3dDeconvolve will be run using '-stim_times'. This option is used to specify the stimulus timing files to be applied, one file per stimulus type. The order of the files given on the command line will be the order given to 3dDeconvolve. Each of these timing files will be given along with the basis function specified by '-regress_basis'. The user must specify either -regress_stim_times or -regress_stim_files if regression is performed, but not both. Note the form of the files is one row per run. If there is at most one stimulus per run, please add a trailing '*'. Labels may be specified using the -regress_stim_labels option. These two examples of such files are for a 3-run experiment. In the second example, there is only 1 stimulus at all, occuring in run 2. e.g. 0 12.4 27.3 29 * 30 40 50 e.g. * 20 * * Please see '3dDeconvolve -help' for more information, or the link: http://afni.nimh.nih.gov/afni/doc/misc/3dDeconvolveSummer2004 See also -regress_stim_files, -regress_stim_labels, -regress_basis, -regress_basis_normall, -regress_polort. -regress_stim_files FILE1 ... : specify TR-locked stim files e.g. -regress_stim_times ED_stim_file*.1D e.g. -regress_stim_times stim_A.1D stim_B.1D stim_C.1D Without the -regress_use_stim_files option, 3dDeconvolve will be run using '-stim_times', not '-stim_file'. The user can still specify the 3dDeconvolve -stim_file files here, but they would then be converted to -stim_times files using the script, make_stim_times.py . It might be more educational for the user to run make_stim_times.py outside afni_proc.py (such as was done before example 2, above), or to create the timing files directly. Each given file can be for multiple stimulus classes, where one column is for one stim class, and each row represents a TR. So each file should have NUM_RUNS * NUM_TRS rows. The stim_times files will be labeled stim_times.NN.1D, where NN is the stimulus index. Note that if the stimuli were presented at a fixed time after the beginning of a TR, the user should consider the option, -regress_stim_times_offset, to apply that offset. --- If the -regress_use_stim_files option is provided, 3dDeconvolve will be run using each stim_file as a regressor. The order of the regressors should match the order of any labels, provided via the -regress_stim_labels option. Please see '3dDeconvolve -help' for more information, or the link: http://afni.nimh.nih.gov/afni/doc/misc/3dDeconvolveSummer2004 See also -regress_stim_times, -regress_stim_labels, -regress_basis, -regress_basis_normall, -regress_polort, -regress_stim_times_offset, -regress_use_stim_files. -regress_stim_times_offset OFFSET : add OFFSET to -stim_times files e.g. -stim_times_offset 1.25 default: 0 If the -regress_stim_files option is used (so the script converts -stim_files to -stim_times before 3dDeconvolve), the user may want to add an offset to the times in the output timing files. For example, if -tshift_align_to is applied, and the user chooses to align volumes to the middle of the TR, it would be appropriate to add TR/2 to the times of the stim_times files. This OFFSET will be applied to the make_stim_times.py command in the output script. Please see 'make_stim_times.py -help' for more information. See also -regress_stim_files, -regress_use_stim_files, -tshift_align_to. -regress_use_stim_times : use -stim_file in regression, not -stim_times The default operation of afni_proc.py is to convert TR-locked files for the 3dDeconvolve -stim_file option to timing files for the 3dDeconvolve -stim_times option. If the -regress_use_stim_times option is provided, then no such conversion will take place. This assumes the -regress_stim_files option is applied to provide such -stim_file files. This option has been renamed from '-regress_no_stim_times'. Please see '3dDeconvolve -help' for more information. See also -regress_stim_files, -regress_stim_times, -regress_stim_labels. - R Reynolds Dec, 2006 thanks to Z Saad =========================================================================== """ g_history = """ afni_proc.py history: 1.0 Dec 20, 2006 : initial release 1.1 Dec 20, 2006 : added -regress_use_stim_files 1.2 Dec 21, 2006 : help, start -ask_me, updated when to use -iresp/ideal 1.3 Dec 22, 2006 : change help to assumme ED's stim_times files exist 1.4 Dec 25, 2006 : initial -ask_me 1.5 Dec 27, 2006 : ask_me help 1.6 Dec 28, 2006 : -gylsym examples, min(a,b) in scale block 1.7 Jan 03, 2007 : help updates, no blank '\\' line from -gltsym 1.8 Jan 08, 2007 : - changed default script name to proc.SUBJ_ID, and removed -script from most examples - added options -bash, -copy_files, -volreg_zpad, -tlrc_anat, -tlrc_base, -tlrc_no_ss, -tlrc_rmode, -tlrc_suffix 1.9 Jan 09, 2007 : added aligned line wrapping (see afni_util.py) 1.10 Jan 12, 2007 : set subj = $argv[1], added index to -glt_label in -help 1.11 Jan 12, 2007 : - added options -move_preproc_files, -regress_no_motion - use $output_dir var in script, and echo version at run-time - append .$subj to more output files 1.12 Jan 16, 2007 : allow no +view when using -tlrc_anat 1.13 Jan 17, 2007 : if -tlrc_anat, apply default option '-tlrc_suffix NONE' 1.14 Jan 26, 2007 : - if only 1 run, warn user, do not use 3dMean - changed all True/False uses to 1/0 (for older python versions) 1.15 Feb 02, 2007 : - output float for -blur_size - put execution command at top of script 1.16 Feb 21, 2007 : - added optional 'despike' block - added options -do_block and -despike_opts_3dDes 1.17 Feb 27, 2007 : - volreg_align_to defaults to 'third' (was 'first') - added +orig to despike input - added 'empty' block type, for a placeholder 1.18 Mar 15, 2007 : minor changes on the ides of March (oooooooh...) - x1D output file uses x1D suffix - removed now unneeded -full_first option in 3dDeconvolve 1.19 Mar 19, 2007 : allow for dataset TR stored in depreciated ms 1.20 Mar 25, 2007 : added -help for long-existing -regress_use_stim_files 1.21 Apr 19, 2007 : apply +orig in 1-run mean using 3dcopy 1.22 May 08, 2007 : - change read_options() to be compatible with python version 2.2 - '-basis_normall 1' is no longer used by default - rename -regress_no_stim_times to -regress_use_stim_files 1.23 Jun 01, 2007 : - changed name of Xmat to X.xmat.1D - by default, apply -xjpeg in 3dDeconvolve 1.24 Jun 04 2007 : added -scale_no_max """ g_version = "version 1.24, Jun 4, 2007" # ---------------------------------------------------------------------- # dictionary of block types and modification functions BlockLabels = ['tcat', 'despike', 'tshift', 'volreg', 'blur', 'mask', 'scale', 'regress', 'empty'] BlockModFunc = {'tcat' : db_mod_tcat, 'despike': db_mod_despike, 'tshift' : db_mod_tshift, 'volreg' : db_mod_volreg, 'blur' : db_mod_blur, 'mask' : db_mod_mask, 'scale' : db_mod_scale, 'regress': db_mod_regress, 'empty' : db_mod_empty} BlockCmdFunc = {'tcat' : db_cmd_tcat, 'despike': db_cmd_despike, 'tshift' : db_cmd_tshift, 'volreg' : db_cmd_volreg, 'blur' : db_cmd_blur, 'mask' : db_cmd_mask, 'scale' : db_cmd_scale, 'regress': db_cmd_regress, 'empty' : db_cmd_empty} AllOptionStyles = ['cmd', 'file', 'gui', 'sdir'] # default block labels, and other labels (along with the label they follow) DefLabels = ['tcat', 'tshift', 'volreg', 'blur', 'mask', 'scale', 'regress'] OtherDefLabels = {'despike':'tcat'} OtherLabels = ['empty'] # ---------------------------------------------------------------------- # data processing stream class class SubjProcSream: def __init__(self, label): self.label = label # name for stream self.valid_opts = None # list of possible user options self.user_opts = None # list of given user options self.blocks = [] # list of ProcessBlock elements self.dsets = [] # list of afni_name elements self.stims_orig = [] # orig list of stim files to apply self.stims = [] # list of stim files to apply self.opt_src = 'cmd' # option source self.subj_id = 'SUBJ' # hopefully user will replace this self.subj_label = '$subj' # replace this for execution self.out_dir = '' # output directory for use by script self.od_var = '' # output dir variable: $output_dir self.script = None # script name, default proc.SUBJ self.overwrite = 0 # overwrite script file? self.fp = None # file object self.anat = None # anatomoy to copy (afni_name class) self.rm_rm = 1 # remove rm.* files self.mot_labs = [] # labels for motion params self.verb = 1 # verbosity level self.tr = 0.0 # TR, in seconds self.reps = 0 # TRs per run self.runs = 0 # number of runs self.mask = None # mask dataset self.bindex = 0 # current block index self.pblabel = '' # previous block label return def show(self, mesg): # rcr - update print '%sSubjProcSream: %s' % (mesg, self.label) for block in self.blocks: block.show(' Block %d: ' % self.blocks.index(block)) print ' Dsets : ', if self.verb > 2: print for dset in self.dsets: dset.show() else: for dset in self.dsets: print dset.pv(), print if self.verb > 2: self.valid_opts.show('valid_opts: ') if self.verb > 1: self.user_opts.show('user_opts: ') def init_opts(self): self.valid_opts = OptionList('init_opts') # input style options rcr - update # self.valid_opts.add_opt('-opt_source', 1, [], AllOptionStyles) # general execution options self.valid_opts.add_opt('-blocks', -1, []) self.valid_opts.add_opt('-do_block', -1, []) self.valid_opts.add_opt('-dsets', -1, []) self.valid_opts.add_opt('-out_dir', 1, []) self.valid_opts.add_opt('-scr_overwrite', 0, []) self.valid_opts.add_opt('-script', 1, []) self.valid_opts.add_opt('-subj_id', -1, []) self.valid_opts.add_opt('-ask_me', 0, []) # QnA session self.valid_opts.add_opt('-bash', 0, []) self.valid_opts.add_opt('-copy_anat', 1, []) self.valid_opts.add_opt('-copy_files', -1, []) self.valid_opts.add_opt('-keep_rm_files', 0, []) self.valid_opts.add_opt('-move_preproc_files', 0, []) self.valid_opts.add_opt('-tlrc_anat', 0, []) self.valid_opts.add_opt('-tlrc_base', 1, []) self.valid_opts.add_opt('-tlrc_no_ss', 0, []) self.valid_opts.add_opt('-tlrc_rmode', 1, []) self.valid_opts.add_opt('-tlrc_suffix', 1, []) # self.valid_opts.add_opt('-remove_pXX_files', 0, []) # block options self.valid_opts.add_opt('-tcat_remove_first_trs', 1, []) self.valid_opts.add_opt('-despike_opts_3dDes', -1, []) self.valid_opts.add_opt('-tshift_align_to', -1, []) self.valid_opts.add_opt('-tshift_interp', 1, []) self.valid_opts.add_opt('-tshift_opts_ts', -1, []) self.valid_opts.add_opt('-volreg_align_to', 1, [], ['first','third', 'last']) self.valid_opts.add_opt('-volreg_base_ind', 2, []) self.valid_opts.add_opt('-volreg_opts_vr', -1, []) self.valid_opts.add_opt('-volreg_zpad', 1, []) self.valid_opts.add_opt('-blur_filter', 1, []) self.valid_opts.add_opt('-blur_size', 1, []) self.valid_opts.add_opt('-blur_opts_merge', -1, []) self.valid_opts.add_opt('-mask_type', 1, [], ['union','intersection']) self.valid_opts.add_opt('-mask_dilate', 1, []) self.valid_opts.add_opt('-scale_max_val', 1, []) self.valid_opts.add_opt('-scale_no_max', 0, []) self.valid_opts.add_opt('-regress_basis', 1, []) self.valid_opts.add_opt('-regress_basis_normall', 1, []) self.valid_opts.add_opt('-regress_polort', 1, []) self.valid_opts.add_opt('-regress_stim_files', -1, []) self.valid_opts.add_opt('-regress_stim_labels', -1, []) self.valid_opts.add_opt('-regress_stim_times', -1, []) self.valid_opts.add_opt('-regress_no_stim_times', 0, []) self.valid_opts.add_opt('-regress_stim_times_offset', 1, []) self.valid_opts.add_opt('-regress_use_stim_files', 0, []) self.valid_opts.add_opt('-regress_fitts_prefix', 1, []) self.valid_opts.add_opt('-regress_iresp_prefix', 1, []) self.valid_opts.add_opt('-regress_make_ideal_sum', 1, []) self.valid_opts.add_opt('-regress_no_fitts', 0, []) self.valid_opts.add_opt('-regress_no_ideals', 0, []) self.valid_opts.add_opt('-regress_no_iresp', 0, []) self.valid_opts.add_opt('-regress_no_motion', 0, []) self.valid_opts.add_opt('-regress_opts_3dD', -1, []) # other options self.valid_opts.add_opt('-help', 0, []) self.valid_opts.add_opt('-hist', 0, []) self.valid_opts.add_opt('-ver', 0, []) self.valid_opts.add_opt('-verb', 1, []) self.valid_opts.trailers = 0 # do not allow unknown options def get_user_opts(self): self.user_opts = read_options(sys.argv, self.valid_opts) if self.user_opts == None: return 1 # error condition if len(self.user_opts.olist) == 0: # no options: apply -help print g_help_string return 1 if self.user_opts.trailers: opt = self.user_opts.find_opt('trailers') if not opt: print "** seem to have trailers, but cannot find them!" else: print "** have invalid trailing args: %s", opt.show() return 1 # failure # apply the user options if self.apply_initial_opts(self.user_opts): return 1 # update out_dir now (may combine option results) if self.out_dir == '': self.out_dir = '%s.results' % self.subj_label self.od_var = '$output_dir' if self.verb > 3: self.show('end get_user_opts ') # apply the general options def apply_initial_opts(self, opt_list): opt = opt_list.find_opt('-verb') # set and use verb if opt != None: self.verb = int(opt.parlist[0]) opt = opt_list.find_opt('-help') # does the user want help? if opt != None: print g_help_string return 1 # terminate opt = opt_list.find_opt('-hist') # print the history if opt != None: print g_history return 1 # terminate opt = opt_list.find_opt('-ver') # show the version string if opt != None: print g_version return 1 # terminate opt = opt_list.find_opt('-subj_id') if opt != None: self.subj_id = opt.parlist[0] opt = opt_list.find_opt('-out_dir') if opt != None: self.out_dir = opt.parlist[0] opt = opt_list.find_opt('-script') if opt != None: self.script = opt.parlist[0] else: self.script = 'proc.%s' % self.subj_id opt = opt_list.find_opt('-scr_overwrite') if opt != None: self.overwrite = 1 opt = opt_list.find_opt('-copy_anat') if opt != None: self.anat = afni_name(opt.parlist[0]) opt = opt_list.find_opt('-keep_rm_files') if opt != None: self.rm_rm = 0 # init blocks from command line options, then check for an # alternate source rcr - will we use 'file' as source? def create_blocks(self): # first, note datasets opt = self.user_opts.find_opt('-dsets') if opt != None: for dset in opt.parlist: self.dsets.append(afni_name(dset)) blocklist = DefLabels # init to defaults # check for -do_block options opt = self.user_opts.find_opt('-do_block') if opt and opt.parlist and len(opt.parlist) > 0: if self.user_opts.find_opt('-blocks'): print '** error: -do_block invalid when using -blocks' return 1 # check additional blocks one by one errs = 0 for bname in opt.parlist: if bname in OtherDefLabels: preindex = blocklist.index(OtherDefLabels[bname]) if preindex < 0: print "** error: -do_block failure for '%s'" % bname errs += 1 # so add the block to blocklist preindex += 1 blocklist[preindex:preindex] = [bname] else: print "** error: '%s' is invalid in '-do_block'" % bname errs += 1 if errs > 0 : return 1 opt = self.user_opts.find_opt('-blocks') if opt: # then create blocklist from user opts (but prepend tcat) if opt.parlist[0] != 'tcat': blocklist = ['tcat'] + opt.parlist else: blocklist = opt.parlist for label in blocklist: rv = self.add_block(label) if rv != None: return rv # maybe the user wants to be quizzed for options uopt = self.user_opts.find_opt('-ask_me') if uopt != None: if ask_me.ask_me_subj_proc(self): return 1 for label in blocklist: block = self.find_block(label) if not block: print "** error: missing block '%s' in ask_me update"%label return 1 BlockModFunc[label](block, self, self.user_opts) # modify block # rcr - if there is another place to update options from, do it uopt = self.user_opts.find_opt('-opt_source') if uopt != None: print '** not ready to update options from %s' % str(uopt.parlist) return 1 # do some final error checking if len(self.dsets) == 0: print 'error: dsets have not been specified (consider -dsets)' return 1 if not uniq_list_as_dsets(self.dsets, 1): return 1 if not db_tlrc_opts_okay(self.user_opts): return 1 # create script from blocks and options def create_script(self): rv = self.get_run_info() if rv != None: return rv rv = self.init_script() # create the script file and header if rv != None: return rv errs = 0 for block in self.blocks: if not block.apply: continue # skip such blocks cmd_str = BlockCmdFunc[block.label](self, block) if cmd_str == None: print "** script creation failure for block '%s'" % block.label errs += 1 else: self.fp.write(add_line_wrappers(cmd_str)) if self.verb>2: block.show('+d post command creation: ') if self.verb>1: print '+d %s command: %s'%(block.label, cmd_str) rv = self.finalize_script() # finish the script if rv: errs += 1 if self.fp: self.fp.close() if errs > 0: return 1 # so we print all errors before leaving if self.verb > 0: if self.runs == 1: print "\n-------------------------------------\n" \ "** warning have only 1 run to analyze\n" \ "-------------------------------------" print "\n--> script is file: %s" % self.script if self.user_opts.find_opt('-bash'): # give bash form print ' (consider: "tcsh -x %s 2>&1 | tee output.%s") ' \ % (self.script, self.script) else: # give tcsh form print ' (consider the command "tcsh -x %s |& tee output.%s")' \ % (self.script, self.script) return def get_run_info(self): self.runs = len(self.dsets) if self.runs < 1: print "** have no dsets to analyze" return 1 # updated by 'tcat' opteration (and -remove_trs option) dset = self.dsets[0].rpv() list = read_attribute(dset, 'TAXIS_NUMS') if list == None: return 1 try: self.reps = int(list[0]) except: print "** reps '%s' is not an int?" % list[0] return 1 if self.reps < 1: print "** invalid nreps (%d) for dset %s" % (self.reps, dset) return 1 # and set units (to either sec (77002) or ms (77001)) try: units = int(list[2]) except: units = 77002 if units != 77001 and units != 77002: units = 77002 list = read_attribute(dset, 'TAXIS_FLOATS') if list == None: return 1 try: self.tr = float(list[1]) except: print "** TR '%s' is not a float?" % list[0] return 1 # specify units in string if units == 77001: unit_str = 'ms' else : unit_str = 's' if self.verb > 1: print '(reps, runs, tr) = (%d, %d, %s%s)' % \ (self.reps, self.runs, str(self.tr), unit_str) # and adjust TR if units == 77001: self.tr /= 1000.0 # create a new block for the given label, and append it to 'blocks' def add_block(self, label): block = ProcessBlock(label, self) if not block.valid: print '** invalid block : %s' % block.label return 1 if self.verb > 2: block.show('+d post init block: ') self.blocks.append(block) def find_block(self, label): for block in self.blocks: if block.label == label: return block return None def find_block_index(self, label): block = find_block(label) if block: return self.blocks.index(block) return None # set subj shell variable, check output dir, create and cd def init_script(self): if not self.overwrite and os.path.isfile(self.script): print "error: script file '%s' already exists, exiting..." % \ self.script return 1 try: self.fp = open(self.script,'w') except: print "cannot open script file '%s' for writing" % self.script return 1 self.fp.write('#!/usr/bin/env tcsh\n\n') self.fp.write('echo "auto-generated by afni_proc.py, %s"\n' % asctime()) self.fp.write('echo "(%s)"\n\n'% g_version) # include execution method in script if self.user_opts.find_opt('-bash'): # give bash form self.fp.write('# execute via : tcsh -x %s 2>&1 | tee output.%s\n\n'\ % (self.script, self.script)) else: # give tcsh form self.fp.write('# execute via : tcsh -x %s |& tee output.%s\n\n' \ % (self.script, self.script)) self.fp.write('# --------------------------------------------------\n' '# script setup\n\n' '# the user may specify a single subject to run with\n') self.fp.write('if ( $#argv > 0 ) then \n' ' set subj = $argv[1] \n' 'else \n' ' set subj = %s \n' 'endif\n\n' % self.subj_id ) self.fp.write('# assign output directory name\n' 'set output_dir = %s\n\n' % self.out_dir) self.fp.write('# verify that the results directory does not yet exist\n' 'if ( -d %s ) then \n' ' echo output dir "$subj.results" already exists\n' ' exit \n' 'endif\n\n' % self.od_var) self.fp.write('# set list of runs\n') self.fp.write('set runs = (`count -digits 2 1 %d`)\n\n' % self.runs) self.fp.write('# create results directory\n') self.fp.write('mkdir %s\n\n' % self.od_var) if len(self.stims_orig) > 0: # copy stim files into script's stim dir str = '# create stimuli directory, and copy stim files\n' \ 'mkdir %s/stimuli\ncp ' % self.od_var for ind in range(len(self.stims)): str += '%s ' % self.stims_orig[ind] str += '%s/stimuli\n\n' % self.od_var self.fp.write(add_line_wrappers(str)) if self.anat: str = '# copy anatomy to results dir\n' \ '3dcopy %s %s/%s\n\n' % \ (self.anat.rpv(), self.od_var, self.anat.prefix) self.fp.write(add_line_wrappers(str)) opt = self.user_opts.find_opt('-copy_files') if opt and len(opt.parlist) > 0: str = '# copy extra files into results dir\n' \ 'cp -rv %s %s\n\n' % \ (' '.join(quotize_list(opt.parlist,'')),self.od_var) self.fp.write(add_line_wrappers(str)) self.fp.flush() # and last steps def finalize_script(self): str = '# -------------------------------------------------------\n\n' self.fp.write(str) if self.rm_rm: self.fp.write('# remove temporary rm.* files\n' '\\rm -f rm.*\n\n') if self.user_opts.find_opt('-move_preproc_files'): cmd_str = \ "# move preprocessing files to 'preproc.data' directory\n" \ "mkdir preproc.data\n" \ "mv dfile.r??.1D outcount* pb??.$subj.r??.* rm.* preproc.data\n\n" self.fp.write(add_line_wrappers(cmd_str)) if self.user_opts.find_opt('-tlrc_anat'): cmd_str = db_cmd_tlrc(self.anat.pv(), self.user_opts) if cmd_str == None: print "** script creation failure for block 'tlrc'" return 1 self.fp.write(add_line_wrappers(cmd_str)) self.fp.write('# return to parent directory\n' 'cd ..\n\n') opt = self.user_opts.find_opt('-no_proc_command') str = '\n\n\n' \ '# -------------------------------------------------------\n' \ '# script generated by the command:\n' \ '#\n' \ '# %s %s\n' % (os.path.basename(sys.argv[0]), ' '.join(quotize_list(sys.argv[1:],''))) self.fp.write(add_line_wrappers(str)) if self.user_opts.find_opt('-ask_me'): str = '#\n# all applied options: ' for opt in self.user_opts.olist: if opt.name == '-ask_me': continue str += opt.name+' ' str += ' '.join(quotize_list(opt.parlist,'')) str += '\n' self.fp.write(add_line_wrappers(str)) # given a block, run, return a prefix of the form: pNN.SUBJ.rMM.BLABEL # NN = block index, SUBJ = subj label, MM = run, BLABEL = block label def prefix_form(self, block, run): return 'pb%02d.%s.r%02d.%s' % \ (self.bindex, self.subj_label, run, block.label) # same, but leave run as a variable def prefix_form_run(self, block): return 'pb%02d.%s.r$run.%s' % (self.bindex, self.subj_label,block.label) # same as prefix_form, but use previous block values (index and label) # (so we don't need the block) def prev_prefix_form(self, run): return 'pb%02d.%s.r%02d.%s' % \ (self.bindex-1, self.subj_label, run, self.pblabel) # same, but leave run as a variable def prev_prefix_form_run(self): return 'pb%02d.%s.r$run.%s' % \ (self.bindex-1, self.subj_label, self.pblabel) # same, but leave run wild def prev_prefix_form_rwild(self): return 'pb%02d.%s.r??.%s' % \ (self.bindex-1, self.subj_label, self.pblabel) class ProcessBlock: def __init__(self, label, proc): self.label = label # label is block type self.valid = 0 # block is not yet valid self.apply = 1 # apply block to output script self.verb = proc.verb # verbose level if not label in BlockModFunc: return self.opts = OptionList(label) # init option list BlockModFunc[label](self, proc, proc.user_opts) # add block if self.verb > 2: if self.valid: self.show('+d successful add ') else: print '+d invalid ProcessBlock: %s' % label def show(self, mesg): print '------- %sProcessBlock: %s -------' % (mesg, self.label) self.opts.show('new options: ') def run_proc(): ps = SubjProcSream('subject regression') ps.init_opts() rv = ps.get_user_opts() if rv != None: return rv rv = ps.create_blocks() if rv != None: return rv rv = ps.create_script() if rv != None: return rv # main if __name__ == '__main__': run_proc()