#! /usr/bin/env perl
############################################################################
############################################################################
### Run CIVET processing pipeline within the PMP framework.
###
### In the current version, CIVET requires a quarantine of the software
### invoked and an environment file.
###
### Authors:
### Original pipeline scripts by: Jason Lerch
### Pre-modular versions of CIVET: Yasser Ad-Dab'bagh
### Modular CIVET: Oliver Lyttelton, J-Sebastian Muehlboeck,
### Yasser Ad-Dab'bagh, Kelvin Mok, Claude Lepage
### Project started in May 3, 2005
###
### Copyright Alan C. Evans
### Professor of Neurology
### McGill University
###
### For more information, have a look at our documentation at:
### http://wiki.bic.mni.mcgill.ca/index.php/CIVET
###
############################################################################
############################################################################
use strict;
use FindBin;
use Cwd qw( abs_path );
use Env qw( PATH );
# All modules that will be used in either case are declared here
use Getopt::Tabular;
use PMP::PMP;
use PMP::pbs;
use PMP::sge;
use PMP::spawn;
use PMP::Array;
use MNI::Startup;
use MNI::PathUtilities qw(split_path);
use MNI::FileUtilities qw(check_output_dirs check_output_path);
use MNI::DataDir;
use lib "$FindBin::Bin";
use MRI_Image;
use Processing_Pipeline_Main;
$PATH = "$FindBin::Bin/progs:${PATH}";
# Set interrupt handler (for cleaning of lock files)
$SIG{'INT'} = 'CLEANUP';
$SIG{'TERM'} = 'CLEANUP';
my $version = "1.1.12";
my $versionDate= "February, 2013";
my $usage = "\nUSAGE:\n$ProgramName -sourcedir
-targetdir -prefix [options] id1 id2 ... idn > &\n
ALTERNATIVE USAGE:\n
$ProgramName -sourcedir -targetdir -prefix -id-file [options] > &\n\n";
my $whatsnew = < { 'type' => "spawn",
'maxqueued' => 10000,
'granularity' => 1,
'command' => undef,
'queue' => undef,
'hosts' => undef,
'opts' => undef },
'MNIBIC' => { 'type' => "sge",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "qsub",
'queue' => "all.q",
'hosts' => undef,
'opts' => undef },
'ZLAB' => { 'type' => "sge",
'maxqueued' => 100,
'granularity' => 1,
'command' => "qsub",
'queue' => "all.q",
'hosts' => undef,
'opts' => undef },
'CLUMEQ' => { 'type' => "pbs", ## this was krylov
'maxqueued' => 100,
'granularity' => 1,
'command' => "msub",
'queue' => "brain",
'hosts' => undef,
'opts' => "-l ncpus=1" },
'GUILLIMIN' => { 'type' => "pbs",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "msub",
'queue' => undef,
'hosts' => undef,
'opts' => "-l walltime=8:00:00 -l nodes=1:ppn=1" },
'COLOSSE' => { 'type' => "pbs",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "msub",
'queue' => "default",
'hosts' => undef,
'opts' => "-P eim-670-aa -l h_rt=6:00:00" },
'RQCHP' => { 'type' => "pbs",
'maxqueued' => 800,
'granularity' => 1,
'command' => "qsub",
'queue' => "qwork\@ms",
'hosts' => undef,
'opts' => "-l walltime=7:00:00" },
'KISTI' => { 'type' => "pbs",
'maxqueued' => 100,
'granularity' => 1,
'command' => "msub", ## check
'queue' => undef, ## check
'hosts' => undef,
'opts' => undef },
'NIH' => { 'type' => "pbs",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "qsub",
'queue' => "norm",
'hosts' => undef,
'opts' => "-l nodes=1:p2800" },
'NUPPI' => { 'type' => "sge",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "qsub",
'queue' => undef, ## check
'hosts' => undef,
'opts' => undef },
'JUDGE' => { 'type' => "pbs",
'maxqueued' => 1000,
'granularity' => 1,
'command' => "msub",
'queue' => "common",
'hosts' => undef,
'opts' => "-l walltime=08:00:00" },
'JUROPA' => { 'type' => "pbs", # should never run on Juropa
'maxqueued' => 1000, # because ppn=16 not filled
'granularity' => 1,
'command' => "msub",
'queue' => "common",
'hosts' => undef,
'opts' => "-l walltime=08:00:00 -l nodes=1:ppn=1 -v tpt=2" } );
my $PMPtype = ( $ENV{'CIVET_JOB_SCHEDULER'} || "DEFAULT" );
my $PMPmaxQueued = $PMPconf{$PMPtype}{maxqueued};
my $PMPgranularity = $PMPconf{$PMPtype}{granularity};
my $PMPqueue = $PMPconf{$PMPtype}{queue};
my $PMPhosts = $PMPconf{$PMPtype}{hosts};
my $PMPopts = $PMPconf{$PMPtype}{opts};
############# Default models for pipeline
my $CIVETModel = "icbm152nl";
my $TemplateSize = "1.00";
### add avg64 model for cortical_surface, sphere models,
my %CIVETmodels = ( 'icbm152nl_09a' => {
'RegLinDir' => MNI::DataDir::dir("mni-models"),
'RegLinModel' => "mni_icbm152_t1_tal_nlin_asym_09a",
'RegNLDir' => MNI::DataDir::dir("mni-models"),
'RegNLModel' => "mni_icbm152_t1_tal_nlin_asym_09a",
'TemplateDir' => MNI::DataDir::dir("ICBM"),
'TemplateModel' => "icbm_template",
'SurfaceMaskDir' => MNI::DataDir::dir("mni-models"),
'SurfaceMask' => "mni_icbm152_t1_tal_nlin_asym_09a_mask.obj",
'SurfRegModelDir' => "$FindBin::Bin/models",
'SurfRegModel' => "surf_reg_model_left.obj",
'SurfRegDataTerm' => "surf_reg_model_left.txt",
'SurfAtlasLeft' => "$FindBin::Bin/models/surface_atlas.txt",
'SurfAtlasRight' => "$FindBin::Bin/models/surface_atlas.txt",
'WhiteSurfMask' => "$FindBin::Bin/models/Cerebellum_Ventricles_SubCortical_Mask.mnc",
'TagFileDir' => MNI::DataDir::dir("classify"),
'TagFile' => "ntags_1000_prob_90_nobg.tag",
'bgTagFile' => "ntags_1000_bg.tag",
'AnimalAtlas' => undef,
'AnimalAtlasDir' => undef,
'AnimalNLRegDir' => undef,
'AnimalNLRegModel' => undef
},
'icbm152nl_09s' => {
'RegLinDir' => MNI::DataDir::dir("mni-models"),
'RegLinModel' => "mni_icbm152_t1_tal_nlin_sym_09a",
'RegNLDir' => MNI::DataDir::dir("mni-models"),
'RegNLModel' => "mni_icbm152_t1_tal_nlin_sym_09a",
'TemplateDir' => MNI::DataDir::dir("ICBM"),
'TemplateModel' => "icbm_template",
'SurfaceMaskDir' => MNI::DataDir::dir("mni-models"),
'SurfaceMask' => "mni_icbm152_t1_tal_nlin_sym_09a_mask.obj",
'SurfRegModelDir' => "$FindBin::Bin/models",
'SurfRegModel' => "surf_reg_model_left.obj",
'SurfRegDataTerm' => "surf_reg_model_left.txt",
'SurfAtlasLeft' => "$FindBin::Bin/models/surface_atlas.txt",
'SurfAtlasRight' => "$FindBin::Bin/models/surface_atlas.txt",
'WhiteSurfMask' => "$FindBin::Bin/models/Cerebellum_Ventricles_SubCortical_Mask.mnc",
'TagFileDir' => MNI::DataDir::dir("classify"),
'TagFile' => "ntags_1000_prob_90_nobg.tag",
'bgTagFile' => "ntags_1000_bg.tag",
'AnimalAtlas' => undef,
'AnimalAtlasDir' => undef,
'AnimalNLRegDir' => undef,
'AnimalNLRegModel' => undef
},
'icbm152nl' => {
'RegLinDir' => MNI::DataDir::dir("mni-models"),
'RegLinModel' => "icbm_avg_152_t1_tal_nlin_symmetric_VI",
'RegNLDir' => MNI::DataDir::dir("mni-models"),
'RegNLModel' => "icbm_avg_152_t1_tal_nlin_symmetric_VI",
'TemplateDir' => MNI::DataDir::dir("ICBM"),
'TemplateModel' => "icbm_template",
'SurfaceMaskDir' => MNI::DataDir::dir("mni-models"),
'SurfaceMask' => "icbm_avg_152_t1_tal_nlin_symmetric_VI_mask.obj",
'SurfRegModelDir' => "$FindBin::Bin/models",
'SurfRegModel' => "surf_reg_model_left.obj",
'SurfRegDataTerm' => "surf_reg_model_left.txt",
'SurfAtlasLeft' => "$FindBin::Bin/models/surface_atlas.txt",
'SurfAtlasRight' => "$FindBin::Bin/models/surface_atlas.txt",
'WhiteSurfMask' => "$FindBin::Bin/models/Cerebellum_Ventricles_SubCortical_Mask.mnc",
'TagFileDir' => MNI::DataDir::dir("classify"),
'TagFile' => "ntags_1000_prob_90_nobg.tag",
'bgTagFile' => "ntags_1000_bg.tag",
'AnimalAtlas' => undef,
'AnimalAtlasDir' => undef,
'AnimalNLRegDir' => undef,
'AnimalNLRegModel' => undef
},
'icbm152lin' => {
'RegLinDir' => MNI::DataDir::dir("mni-models"),
'RegLinModel' => "icbm_avg_152_t1_tal_lin_symmetric",
'RegNLDir' => MNI::DataDir::dir("mni-models"),
'RegNLModel' => "icbm_avg_152_t1_tal_lin_symmetric",
'TemplateDir' => MNI::DataDir::dir("ICBM"),
'TemplateModel' => "icbm_template",
'SurfaceMaskDir' => MNI::DataDir::dir("mni-models"),
'SurfaceMask' => "icbm_avg_152_t1_tal_lin_symmetric_mask.obj",
'SurfRegModelDir' => "$FindBin::Bin/models",
'SurfRegModel' => "surf_reg_model_left.obj",
'SurfRegDataTerm' => "surf_reg_model_left.txt",
'SurfAtlasLeft' => "$FindBin::Bin/models/surface_atlas.txt",
'SurfAtlasRight' => "$FindBin::Bin/models/surface_atlas.txt",
'WhiteSurfMask' => "$FindBin::Bin/models/Cerebellum_Ventricles_SubCortical_Mask.mnc",
'TagFileDir' => MNI::DataDir::dir("classify"),
'TagFile' => "ntags_1000_prob_90_nobg.tag",
'bgTagFile' => "ntags_1000_bg.tag",
'AnimalAtlas' => undef,
'AnimalAtlasDir' => undef,
'AnimalNLRegDir' => undef,
'AnimalNLRegModel' => undef
},
'ADNInl' => {
'RegLinDir' => MNI::DataDir::dir("mni-models"),
'RegLinModel' => "mni_adni_t1w_tal_nlin_asym",
'RegNLDir' => MNI::DataDir::dir("mni-models"),
'RegNLModel' => "mni_adni_t1w_tal_nlin_asym",
'TemplateDir' => MNI::DataDir::dir("ICBM"),
'TemplateModel' => "icbm_template",
'SurfaceMaskDir' => MNI::DataDir::dir("mni-models"),
'SurfaceMask' => "mni_adni_t1w_tal_nlin_asym_mask.obj",
'SurfRegModelDir' => "$FindBin::Bin/models",
'SurfRegModel' => "surf_reg_model_left.obj",
'SurfRegDataTerm' => "surf_reg_model_left.txt",
'SurfAtlasLeft' => "$FindBin::Bin/models/surface_atlas.txt",
'SurfAtlasRight' => "$FindBin::Bin/models/surface_atlas.txt",
'WhiteSurfMask' => "$FindBin::Bin/models/Cerebellum_Ventricles_SubCortical_Mask-ADNI.mnc",
'TagFileDir' => MNI::DataDir::dir("classify-ADNI"),
'TagFile' => "mni_adni_t1w_tal_nlin_asym_ntags_1000_nobg.tag",
'bgTagFile' => "mni_adni_t1w_tal_nlin_asym_ntags_1000_bg.tag",
'AnimalAtlas' => undef,
'AnimalAtlasDir' => undef,
'AnimalNLRegDir' => undef,
'AnimalNLRegModel' => undef
},
);
############# The status report filename:
my $statusReportFile = "CIVET_status_report.csv";
############# Options for how CIVET is to be run: the default will be to run
############# t1 data, cleaning tags, ANIMAL, the production of 82k
############# polygon surfaces, no symmetry stages, and surface registration.
my $inputType = "t1only";
my $correctPVE = 0;
my $maskType = "t1only";
my $interpMethod = "trilinear";
my $headheight = 0;
my $N3Distance = undef;
my $N3Damping = "1.0e-07";
my $lsqtype = "-lsq9";
my $Area_fwhm = "40";
my $Volume_fwhm = "40";
my $VBM = "noVBM";
my $VBM_fwhm = 8;
my $VBM_symmetry = "noSymmetry";
my $VBM_cerebellum = "Cerebellum";
my $surface = "SURFACE";
my $MaskBloodVessels = 0;
my @thickness = ("tlink","20");
my $ResampleSurfaces = 0;
my $MeanCurvature = 0;
my $CombineSurfaces = 0;
my @SurfaceAtlas = ();
my $animal = "noANIMAL";
my $AnimalAtlas = undef;
my $AnimalAtlasDir = undef;
my $AnimalNLRegDir = undef;
my $AnimalNLRegModel = undef;
############# Some directories that the user will need to specify
my $sourceDir = undef;
my $target = undef;
my $prefix = undef;
my $sourceSubDir = "noIdSubDir";
my $idTextFile = undef;
############# Options table
my @leftOverArgs;
my @argTbl = (
["Execution control", "section"],
["-spawn", "const", "DEFAULT", \$PMPtype, "Use the perl system interface to spawn jobs [default: use local host scheduler $PMPtype]"],
["-queue", "string", 1, \$PMPqueue, "Which queue to use", ""],
["-hosts", "string", 1, \$PMPhosts, "Colon separated list of hosts", ""],
["-qopts", "string", 1, \$PMPopts, "Extra options to queuing system", ""],
["-no-granular|-granular", "boolean", 1, \$PMPgranularity,
"Granularity level for submission of jobs using queueing system."],
["-maxqueued", "string", 1, \$PMPmaxQueued,
"Maximum number of jobs that can be submitted at once.", ""],
["File options", "section"],
["-sourcedir", "string", 1, \$sourceDir, "Directory containing the source files.", ""],
["-targetdir", "string", 1, \$target, "Directory where processed data will be placed.", ""],
["-prefix", "string", 1, \$prefix, "File prefix to be used in naming output files.", ""],
["-id-subdir", "const", "IdSubDir", \$sourceSubDir,
"Indicate that the source directory contains sub-directories for each id"],
["-id-file", "string", 1, \$idTextFile, "A text file that contains all the subject id\'s (separated by space, tab, return or comma) that CIVET will run on.", ""],
["Pipeline options", "section"],
["-template", "string", 1, \$TemplateSize,
"Define the template for image processing in stereotaxic space (0.50, 0.75, 1.00, 1.50, 2.00, 3.00, 4.00, 6.00).", ""],
["-model", "string", 1, \$CIVETModel,
"Define the model for image-processing: " .
"\"icbm152nl_09s\" (MNI ICBM152 non-linear symmetric (2009)), " .
"\"icbm152nl_09a\" (MNI ICBM152 non-linear asymmetric (2009)), " .
"\"icbm152nl\" (MNI ICBM152 non-linear 6th generation), " .
"\"icbm152lin\" (MNI ICBM152 linear), " .
"\"ADNInl\" (MNI ADNI non-linear) ",
""],
["-surface-atlas", "string", 2, \@SurfaceAtlas,
"Define the atlas for surface parcellation ",
" "],
["CIVET options", "section"],
["-multispectral", "const", "multispectral", \$inputType,
"Use T1, T2 and PD native files for tissue classification."],
["-correct-pve|-no-correct-pve", "boolean", 1, \$correctPVE,
"Apply correction to the mean and variance of tissue types at pve iterations."],
["-spectral_mask", "const", "multispectral", \$maskType,
"Use T1, T2 and PD stereotaxic files for brain masking."],
["-interp", "string", 1, \$interpMethod,
"Interpolation method from native to stereotaxic space (\"trilinear\", \"tricubic\", \"sinc\"",
""],
["-headheight", "string", 1, \$headheight,
"head height in mm for neck cropping (suggested value: 170; default 0=none).", ""],
["-N3-distance", "string", 1, \$N3Distance,
"N3 spline distance in mm (suggested values: 200 for 1.5T scan; 50 for 3T scan).", ""],
["-N3-damping", "string", 1, \$N3Damping,
"N3 damping coefficient (lambda) (suggested values: 1.0e-07).", ""],
["-lsq6", "const", "-lsq6", \$lsqtype,
"use 6-parameter transformation for linear registration [default -lsq9]" ],
["-lsq12", "const", "-lsq12", \$lsqtype,
"use 12-parameter transformation for linear registration [default -lsq9]" ],
["-no-surfaces", "const", "noSURFACE", \$surface, "don\'t build surfaces"],
["-mask-blood-vessels|-no-mask-blood-vessels", "boolean", 1, \$MaskBloodVessels,
"mask blood vessels prior to white surface extraction"],
["-thickness", "string", 2, \@thickness,
"compute cortical thickness and blur [tlink|tlaplace|tnear|tnormal] [kernel size in mm]"],
["-resample-surfaces|-no-resample-surfaces", "boolean", 1, \$ResampleSurfaces,
"resample cortical surfaces"],
["-mean-curvature|-no-mean-curvature", "boolean", 1, \$MeanCurvature,
"produce mean curvature maps on surfaces"],
["-area-fwhm", "string", 1, \$Area_fwhm,
"blurring kernel size in mm for resampled surface areas", ""],
["-volume-fwhm", "string", 1, \$Volume_fwhm,
"blurring kernel size in mm for resampled surface volumes", ""],
["-combine-surfaces|-no-combine-surfaces", "boolean", 1, \$CombineSurfaces,
"combine left and right cortical surfaces"],
["VBM options", "section"],
["-VBM", "const", "VBM", \$VBM,
"process VBM files for analysis [default -no-VBM]"],
["-no-VBM", "const", "noVBM", \$VBM, "don\'t process VBM files for analysis"],
["-VBM-fwhm", "string", 1, \$VBM_fwhm,
"blurring kernel size in mm for volume", ""],
["-VBM-symmetry", "const", "Symmetry", \$VBM_symmetry,
"run symmetry tools [default -no-VBM-symmetry]"],
["-no-VBM-symmetry", "const", "noSymmetry", \$VBM_symmetry,
"don\'t run symmetry tools"],
["-VBM-cerebellum", "const", "Cerebellum", \$VBM_cerebellum,
"keep cerebellum in VBM maps"],
["-no-VBM-cerebellum", "const", "noCerebellum", \$VBM_cerebellum,
"mask out cerebellum in VBM maps [default -VBM-cerebellum]"],
["ANIMAL options", "section"],
["-animal", "const", "ANIMAL", \$animal,
"run volumetric ANIMAL segmentation and cortical surface lobe parcellation [default -no-animal]"],
["-no-animal", "const", "noANIMAL", \$animal,
"don\'t run volumetric ANIMAL segmentation and cortical surface lobe parcellation"],
["-symmetric_atlas", "const", "-symmetric_atlas", \$AnimalAtlas,
"Use linear symmetric atlas for ANIMAL segmentation (old way)"],
["-lobe_atlas", "const", "-lobe_atlas", \$AnimalAtlas,
"Use non-linear lobe atlas for ANIMAL segmentation (new way)"],
["-animal-atlas-dir", "string", 1, \$AnimalAtlasDir,
"Directory containing the segmentation atlas", ""],
["Pipeline control", "section"],
["-run", "const", "run", \$command, "Run the pipeline."],
["-status-from-files", "const", "statusFromFiles", \$command, "Compute pipeline status from files"],
["-print-stages", "const", "printStages", \$command, "Print the pipeline stages."],
["-print-status", "const", "printStatus", \$command, "Print the status of each pipeline."],
["-make-graph", "const", "makeGraph", \$command, "Create dot graph file."],
["-make-filename-graph", "const", "makeFilenameGraph", \$command, "Create dot graph of filenames."],
["-print-status-report", "const", "printStatusReport", \$command, "Writes a CSV status report to file in cwd."],
["Stage Control", "section"],
["-reset-all", "const", "resetAll", \$resetAll, "Start the pipeline from the beginning."],
["-reset-from", "string", 1, \$resetFrom, "Restart from the specified stage.", ""],
["-reset-after", "string", 1, \$resetAfter, "Restart after the specified stage.", ""],
["-reset-to", "string", 1, \$resetTo, "Run up to and including the specified stage.", ""],
["-reset-running|-no-reset-running", "boolean", 1, \$resetRunning, "Restart currently running jobs."],
);
GetOptions(\@argTbl, \@ARGV, \@leftOverArgs) or die "\n";
############# Basic usage
my @dsids;
if ($idTextFile) {
open (IDTEXTFILE, "$idTextFile") or die ("Cannot open '$idTextFile': $!");
# read the whole text file into one string
my $idstext = "";
while (my $idline = ) {
$idstext .= $idline;
}
close (IDTEXTFILE) or die ("Cannot close '$idTextFile': $!");
# split the string on whitespace (\s) or comma
@dsids = split(/[\s,]+/, $idstext);
}
else {
@dsids = @leftOverArgs or die $usage;
}
unless ($prefix && $target && $sourceDir) {
die "\n\n*******ERROR********: \n You must specify -prefix, -targetdir, and -sourcedir \n********************\n\n\n";
}
$target =~ s#/+$##; # remove trailing / at end of directory name, if any
$target = abs_path( $target );
$sourceDir = abs_path( $sourceDir );
############# Override default PMP options based on command line options
$PMPconf{$PMPtype}{maxqueued} = $PMPmaxQueued;
$PMPconf{$PMPtype}{granularity} = $PMPgranularity;
$PMPconf{$PMPtype}{queue} = $PMPqueue;
$PMPconf{$PMPtype}{hosts} = $PMPhosts;
$PMPconf{$PMPtype}{opts} = $PMPopts;
############# Set no file buffering for stdout (buffer is printed every 1 line)
$| = 1;
############# Print the CIVET options list and related error messages
my $DATE = `date`;
chomp( $DATE );
my $UNAME = `uname -s -n -r`;
chomp( $UNAME );
print "\n\n* Pipeline started at $DATE on $UNAME \n";
print "\n* This is CIVET $version, $versionDate \n";
print "\n* CIVET Command line is:\n $0 @ARGV \n";
print "\n* The source directory is: '$sourceDir' \n";
print "* The target directory is: '$target' \n";
print "* The prefix is: '$prefix' \n";
print "* The PMP class is: '$PMPconf{$PMPtype}{type}' \n";
print "* The $PMPtype queue type is: '$PMPconf{$PMPtype}{queue}' \n";
print "* The $PMPtype batch host(s) is/are: '$PMPconf{$PMPtype}{hosts}' \n";
print "* The $PMPtype global options are: '$PMPconf{$PMPtype}{opts}' \n";
############# The -like template (0.50, 0.75, 1.00, 1.50, 2.00, 3.00, 4.00, 6.00)
my $Template = "$CIVETmodels{$CIVETModel}{TemplateDir}/" .
"$CIVETmodels{$CIVETModel}{TemplateModel}_${TemplateSize}mm.mnc";
print "* Template for image-processing is:\n $Template \n";
############# Define registration targets and directories and print them
print "* Using $CIVETModel model for data-processing pipeline:\n";
my $regLinModelDir = $CIVETmodels{$CIVETModel}{RegLinDir};
my $regNLModelDir = $CIVETmodels{$CIVETModel}{RegNLDir};
print "* Registration linear model directory is: \n $regLinModelDir \n";
print "* Registration non-linear model directory is:\n $regNLModelDir \n";
my $regLinModel = $CIVETmodels{$CIVETModel}{RegLinModel};
my $regNLModel = $CIVETmodels{$CIVETModel}{RegNLModel};
print "* Registration linear model is: \n $regLinModel \n";
print "* Registration non-linear model is:\n $regNLModel \n";
############# Define intermediate registration targets and directories and print them
my $intermediate_model = undef;
############# Define Surface registration targets and directories and print them
my $SurfRegModelDir = $CIVETmodels{$CIVETModel}{SurfRegModelDir};
my $SurfRegModel = $CIVETmodels{$CIVETModel}{SurfRegModel};
my $SurfRegDataTerm = $CIVETmodels{$CIVETModel}{SurfRegDataTerm};
print "* Surface registration model directory is: \n ${SurfRegModelDir} \n";
print "* Surface registration model is: \n ${SurfRegModel} \n";
print "* Surface registration dataterm is: \n ${SurfRegDataTerm} \n";
############# Choose surface parcellation atlas if surfaces are to be resampled.
if( defined @SurfaceAtlas ) {
if( !$ResampleSurfaces ) {
die "You specified a surface parcellation atlas but did not ask to " .
"resample the surfaces. Use -resample-surfaces option.\n";
}
if( defined $SurfaceAtlas[0] && defined $SurfaceAtlas[1] ) {
if( -e $SurfaceAtlas[0] && -e $SurfaceAtlas[1] ) {
$CIVETmodels{$CIVETModel}{SurfAtlasLeft} = $SurfaceAtlas[0];
$CIVETmodels{$CIVETModel}{SurfAtlasRight} = $SurfaceAtlas[1];
} else {
if( -e "$CIVETmodels{$CIVETModel}{SurfRegModelDir}/$SurfaceAtlas[0]" &&
-e "$CIVETmodels{$CIVETModel}{SurfRegModelDir}/$SurfaceAtlas[1]" ) {
$CIVETmodels{$CIVETModel}{SurfAtlasLeft} = "$CIVETmodels{$CIVETModel}{SurfRegModelDir}/$SurfaceAtlas[0]";
$CIVETmodels{$CIVETModel}{SurfAtlasRight} = "$CIVETmodels{$CIVETModel}{SurfRegModelDir}/$SurfaceAtlas[1]";
} else {
die "You specified a surface parcellation atlas but the atlas " .
"cannot be found. Please check filename for atlas.\n";
}
}
}
}
print "* Surface parcellation model (left) is: \n $CIVETmodels{$CIVETModel}{SurfAtlasLeft}\n";
print "* Surface parcellation model (right) is: \n $CIVETmodels{$CIVETModel}{SurfAtlasRight}\n";
############# Choose ANIMAL model.
if( $animal eq "ANIMAL" ) {
if( ( defined $AnimalAtlas ) &&
( $AnimalAtlas eq "-symmetric_atlas" || $AnimalAtlas eq "-lobe_atlas" ) ) {
if( !( defined $AnimalAtlasDir ) ) {
# Try to get the default one in the quarantine, if it has been installed.
$AnimalAtlasDir = MNI::DataDir::dir("ANIMAL_INSECT");
}
if( !( -e $AnimalAtlasDir ) ) {
print "Warning: Required ANIMAL atlas directory $AnimalAtlasDir does not exist.\n";
$animal = "noANIMAL";
} else {
if( $AnimalAtlas eq "-symmetric_atlas" ) {
$AnimalAtlasDir .= "/icbm152-symmetric-v1.0/";
$AnimalNLRegModel = "icbm_avg_152_t1_tal_lin_symmetric";
$AnimalNLRegDir = MNI::DataDir::dir("mni-models");
} elsif( $AnimalAtlas eq "-lobe_atlas" ) {
$AnimalAtlasDir .= "/icbm152-lobes-v1.1/";
$AnimalNLRegModel = "icbm_avg_152_t1_tal_nlin_symmetric_VI";
$AnimalNLRegDir = MNI::DataDir::dir("mni-models");
}
if( !( -e $AnimalAtlasDir ) ) {
print "Warning: Required ANIMAL atlas directory $AnimalAtlasDir does not exist.\n";
$animal = "noANIMAL";
}
}
} else {
print "Warning: You must specify an atlas to use ANIMAL segmentation.\n";
$animal = "noANIMAL";
}
}
if( $animal eq "ANIMAL" ) {
$CIVETmodels{$CIVETModel}{AnimalAtlas} = $AnimalAtlas;
$CIVETmodels{$CIVETModel}{AnimalAtlasDir} = $AnimalAtlasDir;
$CIVETmodels{$CIVETModel}{AnimalNLRegDir} = $AnimalNLRegDir;
$CIVETmodels{$CIVETModel}{AnimalNLRegModel} = $AnimalNLRegModel;
print "* ANIMAL atlas is $AnimalAtlas \n";
print "* ANIMAL atlas directory is: \n ${AnimalAtlasDir} \n";
print "* ANIMAL non-linear registration model directory is: \n ${AnimalNLRegDir} \n";
print "* ANIMAL non-linear registration model is: \n ${AnimalNLRegModel} \n";
print "\n";
print "* -WARNING- -WARNING- -WARNING-\n\n";
print "* We recommend that you no longer use the ANIMAL segmentation in CIVET\n";
print "* until the new lobe segmentation based on the iterative non-linear \n";
print "* ICBM152 model is fully validated and released. Current results based\n";
print "* on the linear symmetric model are inaccurate and should not be used.\n";
}
############# Print the Pipeline and Stage Control commands
if( !($command eq "run") ) {
$resetRunning = 0;
}
print "\n\n* Pipeline Control command is: '$command'";
print "\n* Stage control commands are: " .
( $resetAll ) ? ( "reset all" ) : (
( $resetFrom ) ? ( "reset from '$resetFrom'" ) : (
( $resetAfter ) ? ( "reset after '$resetAfter'" ) : (
( $resetTo ) ? ( "reset to $resetTo" ) : ( "reset all" )
)
)
) . " and " .
( $resetRunning ) ? ( "'reset-running'" ) : ( "'no-reset-running'" );
print "\n\n\n* Data-set Subject ID(s) is/are: '@dsids'\n\n\n";
system("mkdir -p ${target}") if (! -d ${target});
############# An array to store the pipeline definitions for each subject
my $pipes = PMP::Array->new();
#########################################################
# Set up the pipeline output directories for each subject
#########################################################
foreach my $dsid (@dsids) {
##### Create image object. #####
# depending on the two options your files can be in on target
# or there can be subdirs for every subject
my $Source_Base;
if ($sourceSubDir eq "noIdSubDir") {
$Source_Base = "${sourceDir}/";
} else {
$Source_Base = "${sourceDir}/${dsid}/";
}
my $image = MRI_Image->new( $version,
$Source_Base,
$target,
$prefix,
$dsid,
$inputType,
$correctPVE,
$maskType,
$interpMethod,
$headheight,
$MaskBloodVessels,
$N3Distance,
$N3Damping,
$lsqtype,
$surface,
\@thickness,
$ResampleSurfaces,
$MeanCurvature,
$Area_fwhm,
$Volume_fwhm,
$CombineSurfaces,
$VBM,
$VBM_fwhm,
$VBM_symmetry,
$VBM_cerebellum,
$animal,
$Template,
\$CIVETmodels{$CIVETModel} );
##### Create references once, for first subject only #####
if( $dsid eq $dsids[0] ) {
$image->make_references( $target );
}
##### Create the pipeline environment. #####
my $pipeline;
if ($PMPconf{$PMPtype}{type} eq "spawn") {
$pipeline = PMP::spawn->new();
$PMPgranularity = 0;
} elsif ($PMPconf{$PMPtype}{type} eq "sge") {
$pipeline = PMP::sge->new();
$pipeline->setCommand($PMPconf{$PMPtype}{command});
$pipeline->setQueue($PMPconf{$PMPtype}{queue});
$pipeline->setHosts($PMPconf{$PMPtype}{hosts}) if( defined $PMPconf{$PMPtype}{hosts} );
$pipeline->setQueueOptions($PMPconf{$PMPtype}{opts}) if( defined $PMPconf{$PMPtype}{opts} );
$pipeline->setPriorityScheme("later-stages");
} elsif ($PMPconf{$PMPtype}{type} eq "pbs") {
$pipeline = PMP::pbs->new();
$pipeline->setCommand($PMPconf{$PMPtype}{command});
$pipeline->setQueue($PMPconf{$PMPtype}{queue});
$pipeline->setHosts($PMPconf{$PMPtype}{hosts}) if( defined $PMPconf{$PMPtype}{hosts} );
$pipeline->setQueueOptions($PMPconf{$PMPtype}{opts}) if( defined $PMPconf{$PMPtype}{opts} );
$pipeline->setPriorityScheme("later-stages");
}
# set some generic pipeline options
$pipeline->name($dsid);
$pipeline->debug(0);
$pipeline->statusDir("${target}/${dsid}/logs");
##################################### ################# #################
# This used to be the definition of stages... Now it is in modules
##################################### ################# #################
CIVET_Main::create_pipeline(
\$pipeline,
\$image,
\$CIVETmodels{$CIVETModel},
$intermediate_model,
$Template
);
####################################################################################
# Pipeline management
####################################################################################
############# Set the status of the stages.
if ($resetAll && ($resetAll eq "resetAll") ) {
# Restart all stages
$pipeline->resetAll();
} else {
# restart from a given stage;
$pipeline->resetFromStage($resetFrom) if( $resetFrom );
$pipeline->resetAfterStage($resetAfter) if( $resetAfter );
$pipeline->subsetToStage($resetTo) if( $resetTo );
# Rerun any failures from a previous run of this subjects pipe
$pipeline->resetFailures();
# Reset running jobs if that's what the user wants.
$pipeline->resetRunning() if ($resetRunning);
}
$pipeline->updateStatus();
############# Add this pipe to our happy array of pipes
$pipes->addPipe($pipeline);
} ####################################### end of foreach
############# Now run whatever it is that the user wanted done
if ($command eq "printStatus" ) {
$pipes->printUnfinished();
}
elsif ($command eq "printStatusReport") {
$pipes->printStatusReport($statusReportFile);
}
elsif ($command eq "statusFromFiles") {
$pipes->updateFromFiles();
$pipes->printUnfinished();
}
elsif ($command eq "printStages") {
$pipes->printStages();
}
elsif ($command eq "makeGraph") {
$pipes->createDotGraph("dependency-graph.dot");
}
elsif ($command eq "makeFilenameGraph") {
$pipes->createFilenameDotGraph("filename-dependency-graph.dot","${target}/$dsids[0]/");
}
elsif ($command eq "run") {
# register all the programs
$pipes->registerPrograms();
$pipes->maxQueued($PMPmaxQueued);
$pipes->setGranularity($PMPgranularity);
$pipes->run();
}
else {
print "huh? Grunkle little gnu, grunkle\n";
}
############# Voila!! #############
# Set interrupt handler (for cleaning of lock files)
sub CLEANUP {
print "\nCaught signal - cleaning up all lock files\n\n";
$pipes->cleanup();
exit(1);
}