diff --git a/DTIPrep/DTI/DTI.pm b/DTIPrep/DTI/DTI.pm index 5e185b33f..264a52319 100755 --- a/DTIPrep/DTI/DTI.pm +++ b/DTIPrep/DTI/DTI.pm @@ -2,17 +2,54 @@ =head1 NAME -DTI --- A set of utility functions for performing common tasks relating to DTI data (particularly with regards to perform DTI QC) +DTI::DTI --- A set of utility functions for performing common tasks relating to +DTI data (particularly with regards to performing DTI QC) =head1 SYNOPSIS -use DTI; + use DTI::DTI; + + my ($protXMLrefs) = &DTI::readDTIPrepXMLprot( $DTIPrepProtocol ); + + my ($QCoutdir) = &DTI::createOutputFolders( $outdir, $subjID, + $visit, $DTIPrepProtocol, + $runDTIPrep + ); + + my ($DTIs_list) = &DTI::getRawDTIFiles( $nativedir, $DTI_volumes ); + my ($anat) = &DTI::getAnatFile( $nativedir, $t1_scan_type ); + my ($DTIrefs) = &DTI::createDTIhashref( $DTIs_list, $anat, + $QCoutdir, $DTIPrepProtocol, + $protXMLrefs, $QCed2_step + ); + + my ($convert_status) = &DTI::convert_DTI( $dti_file, + $raw_nrrd, + '--short --minc-to-nrrd --dwi' + ); + + my ($copyProt_status) = &DTI::copyDTIPrepProtocol($DTIPrepProtocol, $QCProt); + my ($DTIPrep_status) = &DTI::runDTIPrep( $raw_nrrd, $DTIPrepProtocol, + $QCed_nrrd, $QCed2_nrrd + ); + + + ($convert_status) = &DTI::convert_DTI( $QCed_nrrd, + $QCed_minc, + '--nrrd-to-minc --dwi' + ); + ($insert_header) = &DTI::insertMincHeader( $dti_file, $data_dir, + $QCed_minc, $QCTxtReport, + $DTIPrepVersion + ); + =head1 DESCRIPTION -Really a mismatch of utility functions, primarily used by DTIPrep_pipeline.pl and DTIPrepRegister.pl +A mishmash of utility functions, primarily used by C +and C. -=head1 METHODS +=head2 Methods =cut @@ -33,21 +70,27 @@ use MNI::FileUtilities qw(check_output_dirs); @EXPORT_OK = qw(createOutputFolders getFiles sortParam insertMincHeader create_processed_maps); +=pod +=head3 createOutputFolders($outdir, $subjID, $visit, $protocol, $runDTIPrep) +Creates DTIPrep pipeline output folders. It will return the created output +folder only if the output folder was created. +INPUTS: + - $outdir : base output folder + - $subjID : candidate ID stored in dataset's basename + - $visit : visit label stored in dataset's basename + - $protocol : DTIPrep XML protocol to use (or used) to run DTIPrep + - $runDTIPrep: if set, will run DTIPrep and create the output dir. +Note: If C<$runDTIPrep> is not set, then DTIPrep was already run and the +output folder already exists. +RETURNS: C folder that will store DTIPrep outputs. -=pod -Create DTIPrep pipeline output folders. -- Inputs: - $outdir = base output folder (folder where all candidate's DTIPrep outputs will be saved) - - $subjID = candidate ID stored in dataset's basename - - $visit = visit label stored in dataset's basename - - $protocol = DTIPrep XML protocol that will be used (or has been used) to run DTIPrep - - $runDTIPrep = boolean variable. If set to 1, DTIPrep will be run and need to create output folders. If set to undef, DTIPrep has already been run and folder already exists -- Outputs: - $QC_out = candidate/visit/protocol folder that was created and that will store DTIPrep outputs. This will be return only if $QC_out exists in the file system. =cut + sub createOutputFolders{ my ($outdir, $subjID, $visit, $protocol, $runDTIPrep) = @_; @@ -63,22 +106,21 @@ sub createOutputFolders{ } +=pod +=head3 getFilesList($dir, $match) +Subroutine that will read the content of a directory and return a list +of files whose names match the string given in argument with C<$match>. +INPUTS: + - $dir : directory with DTI files to be fetch + - $match: string used to look for DTI files to be returned +RETURNS: list of DTI files found in C<$dir> matching C<$match> - - - - -=pod -Subroutine that will read the content of a directory and return a list -of files matching the string given in argument with $match. -Inputs: - $dir: directory containing files to be fetch - - $match: string used to look for files to be returned -Outputs: - @files_list: list of files found in $dir matching $match =cut + sub getFilesList { my ($dir, $match) = @_; my (@files_list) = (); @@ -101,13 +143,22 @@ sub getFilesList { =pod -Function that parses files in native MRI directory and grab -the T1 acquisition based on $t1_scan_type. -Inputs: - $nativedir: directory containing native imaging files - - $t1_scan_type: scan type string used for t1 acquisitions -Outputs: - If no anat was found, will return undef. - - If multiple anat were found, will return the first anat of the list. + +=head3 getAnatFile($nativedir, $t1_scan_type) + +Function that parses files in the native MRI directory and grabs +the T1 acquisition based on C<$t1_scan_type>. + +INPUTS: + - $nativedir : native directory + - $t1_scan_type: scan type string used for t1 acquisitions + +RETURNS: + - undef if no anat found + - $anat: anatomical file (first anat found if multiple anats were found). + =cut + sub getAnatFile { my ($nativedir, $t1_scan_type) = @_; @@ -124,17 +175,22 @@ sub getAnatFile { } +=pod + +=head3 getRawDTIFiles($nativedir, $DTI_volumes) +Function that parses files in the native MRI directories and fetches DTI files. +This function will also concatenate together multiple DTI files if the DTI +acquisition was performed across several DTI scans. +INPUTS: + - $nativedir : native directory + - $DTI_volumes: DTI's number of volumes + +RETURNS: list of matching DTI files found in the native directory -=pod -Function that parses files in native MRI directories and fetch DTI files. -This function will also concatenate together multipleDTI files if DTI -acquisition performed accross several DTI scans. -Inputs: - $nativedir: directory containing native files - - $DTIvolumes: DTI's number of volumes -Outputs: - @DTIs_list: list of matching DTIs found in native directory =cut + sub getRawDTIFiles{ my ($nativedir, $DTI_volumes) = @_; @@ -164,17 +220,21 @@ sub getRawDTIFiles{ } +=pod +=head3 copyDTIPrepProtocol($DTIPrepProtocol, $QCProt) +Function that will copy the C protocol to the output directory of +C. +INPUTS: + - $DTIPrepProtocol: C protocol to be copied + - $QCProt : future path of copied C protocol + +RETURNS: 1 on success, undef on failure -=pod -Function that will copy the DTIPrep protocol used to the output directory of DTIPrep. -Inputs: - $DTIPrepProtocol: DTIPrep protocol to be copied - - $QCProt: path of copied DTIPrep protocol -Outputs: - 1 if copy was successful - - undef if copy failed =cut + sub copyDTIPrepProtocol { my ($DTIPrepProtocol, $QCProt) = @_; @@ -189,35 +249,40 @@ sub copyDTIPrepProtocol { } +=pod +=head3 readDTIPrepXMLprot($DTIPrepProtocol) + +Read C XML protocol and return information into a hash. + +INPUT: XML protocol used (or that has been used) to run C + +RETURNS: reference to a hash containing C protocol as follows: + + entry => 'QC_QCOutputDirectory' => {} + => 'QC_QCedDWIFileNameSuffix' => { + 'value' => '_QCed.nrrd' + }, + => 'IMAGE_bCheck' => { + 'entry' => { + 'IMAGE_size' => { + 'value' => [ + '96', + '96', + '65' + ] + }, + 'IMAGE_reportFileMode' => { + 'value' => '1' + }, + ... + 'value' => 'Yes' + }, + => 'QC_badGradientPercentageTolerance' => { + ... - -=pod -Read DTIPrep XML protocol and return information into a hash. -- Inputs: - $DTIPrepProtocol = XML protocol used (or that has been used) to run DTIPrep -- Output: - $protXMLrefs = dereferenced hash containing DTIPrep protocol as follows: - entry => 'QC_QCOutputDirectory' => {} - => 'QC_QCedDWIFileNameSuffix' => { - 'value' => '_QCed.nrrd' - }, - => 'IMAGE_bCheck' => { - 'entry' => { - 'IMAGE_size' => { - 'value' => [ - '96', - '96', - '65' - ] - }, - 'IMAGE_reportFileMode' => { - 'value' => '1' - }, - ... - 'value' => 'Yes' - }, - => 'QC_badGradientPercentageTolerance' => { - etc... =cut + sub readDTIPrepXMLprot { my ($DTIPrepProtocol) = @_; @@ -231,27 +296,35 @@ sub readDTIPrepXMLprot { } +=pod +=head3 createDTIhashref($DTIs_list, $anat, $QCoutdir, $DTIPrepProtocol, $protXMLrefs, $QCed2_step) +Function that will determine output names based on each DTI file dataset and +return a hash of DTIref: - -=pod -Function that will determine output names based on each DTI file dataset and return a hash of DTIref: dti_file_1 -> Raw_nrrd => outputname -> QCed_nrrd => outputname -> QCTxtReport => outputname -> QCXmlReport => outputname -> QCed_minc => outputname -> QCProt => outputname - dti_file_2 -> Raw_nrrd => outputname etc... -Inputs: - $DTIs_list: list of native DTI files to be processed - - $anat: anat file to be used for processing - - $QCoutdir: output directory that will be used to stored processed data - - $DTIPrepProtocol: DTIPrep XML protocol used to run DTIPrep - - $protXMLrefs: hash containing all information about DTIPrep protocol to be used - - $QCed2_step: optionaly, step name at which DTIPrep will produce a secondary QCed file -Outputs: - $DTIrefs: hash containing outputs naming convension + dti_file_2 -> Raw_nrrd => outputname + ... + +INPUTS: + - $DTIs_list : list of native DTI files to be processed + - $anat : anatomical file to be used for processing + - $QCoutdir : processed output directory + - $DTIPrepProtocol: C XML protocol used to run C + - $protXMLrefs : hash containing info about C's protocol + - $QCed2_step : optionally, step name at which C will + produce a secondary QCed file + +RETURNS: hash containing outputs naming convention + =cut + sub createDTIhashref { my ($DTIs_list, $anat, $QCoutdir, $DTIPrepProtocol, $protXMLrefs, $QCed2_step) = @_; my %DTIrefs; @@ -274,19 +347,25 @@ sub createDTIhashref { } +=pod +=head3 determinePreprocOutputs($QCoutdir, $dti_file, $DTIPrepProtocol, $protXMLrefs) +Function that will determine pre processing output names (for either C +or C postprocessing) and append them to C<$DTIrefs>. +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti_file : raw DWI file to be processed + - $DTIPrepProtocol: C protocol to copy into output directory + - $protXMLrefs : hash containing info from C XML protocol + (including suffix for the different outputs) +RETURNS: $DTIrefs{$dti_file}{'Preproc'}{'Output'} fields for C +processing -=pod -Function that will determine post processing output names (for either DTIPrep or mincdiffusion postprocessing) and append them to $DTIrefs. -- Inputs: - $QCoutdir = directory that will contain output files - - $dti_file = raw DWI file to be processed - - $DTIPrepProtocol = DTIPrepProtocol to copy into output directory - - $protXMLrefs = hash containing informations stored in DTIPrep XML protocol (with suffix for the different outputs, among other things) -- Outputs: - $DTIrefs{$dti_file}{'Preproc'}{'Output'} fields for DTIPrep preprocessing =cut + sub determinePreprocOutputs { my ($QCoutdir, $dti_file, $DTIPrepProtocol, $protXMLrefs, $QCed2_step) = @_; @@ -322,14 +401,25 @@ sub determinePreprocOutputs { =pod -Function that will determine post processing output names (for either DTIPrep or mincdiffusion postprocessing) and append them to $DTIrefs. -- Inputs: - $QCoutdir = directory that will contain output files - - $dti_file = raw DWI file to be processed - - $anat = anatomic T1 image to be used for mincdiffusion postprocessing - - $protXMLrefs = hash containing informations stored in DTIPrep XML protocol (with suffix for the different outputs, among other things) -- Outputs: - $DTIrefs{$dti_file}{'Postproc'}{'Tool'} field storing which postprocessing pipeline was used - - $DTIrefs{$dti_file}{'Postproc'}{'Output'} fields for DTIPrep postprocessing + +=head3 determinePostprocOutputs($QCoutdir, $dti_file, $anat, $protXMLrefs) + +Function that will determine post processing output names (for either C +or C postprocessing) and append them to C<$DTIrefs>. + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti_file : raw DWI file to be processed + - $anat : T1 image to be used for C postprocessing + - $protXMLrefs: hash containing info from C XML protocol + (including suffix for the different outputs) + +RETURNS: + - $DTIrefs{$dti_file}{'Postproc'}{'Tool'} with postprocessing used + - $DTIrefs{$dti_file}{'Postproc'}{'Output'} fields for C postprocessing + =cut + sub determinePostprocOutputs { my ($QCoutdir, $dti_file, $anat, $protXMLrefs) = @_; @@ -353,13 +443,24 @@ sub determinePostprocOutputs { } } + =pod -Function that will determine DTIPrep's postprocessing output names (based on the XML protocol) and append them to $DTIrefs -- Inputs: - $QCoutdir = directory that will contain output files - - $dti_file = raw DWI file to be processed - - $protXMLrefs = hash containing informations stored in DTIPrep XML protocol (with suffix for the different outputs, among other things) -- Outputs: - $DTIrefs{$dti_file}{'Postproc'}{'Output'} fields for DTIPrep postprocessing + +=head3 determineDTIPrepPostprocOutputs($QCoutdir, $dti_file, $protXMLrefs) + +Function that will determine C's postprocessing output names (based on +the XML protocol) and append them to C<$DTIrefs> + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti_file : raw DWI file to be processed + - $protXMLrefs: hash containing info from C XML protocol + +RETURNS: $DTIrefs{$dti_file}{'Postproc'}{'Output'} fields for C +postprocessing + =cut + sub determineDTIPrepPostprocOutputs { my ($QCoutdir, $dti_file, $QCed_suffix, $protXMLrefs) = @_; @@ -421,14 +522,24 @@ sub determineDTIPrepPostprocOutputs { } } + =pod -Function that will determine mincdiffusion postprocessing output names and append them to $DTIrefs -- Inputs: - $QCoutdir = directory that will contain output files - - $dti_file = raw DWI file to be processed - - $QCed_suffix = QCed suffix used to create QCed nrrd and determine postprocessing file names - - $anat = anatomic T1 file to use for DWI-anat registration -- Outputs: - $DTIrefs{$dti_file}{'Postproc'} for mincdiffusion postprocessing + +=head3 determineMincdiffusionPostprocOutputs($QCoutdir, $dti_file, $QCed_suffix, $anat) + +Function that will determine C postprocessing output names and +append them to C<$DTIrefs> + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti_file : raw DWI file to be processed + - $QCed_suffix: QCed suffix for QCed NRRD & postprocessing file names + - $anat : anatomic T1 file to use for DWI-anat registration + +RETURNS: $DTIrefs{$dti_file}{'Postproc'} for C postprocessing + =cut + sub determineMincdiffusionPostprocOutputs { my ($QCoutdir, $dti_file, $QCed_suffix, $anat) = @_; @@ -463,14 +574,21 @@ sub determineMincdiffusionPostprocOutputs { } =pod -Function that convert minc file to nrrd or nrrd file to minc. -(depending on $options) -Inputs: - $file_in: file to be converted - - $file_out: converted file - - $options: conversion options: mnc2nrrd or nrrd2mnc -Outputs: - 1 if conversion was successful - - undef if conversion failed + +=head3 convert_DTI($file_in, $file_out, $options) + +Function that converts MINC file to NRRD or NRRD file to MINC. +(depending on C<$options>) + +INPUTS: + - $file_in : file to be converted + - $file_out: converted file + - $options : conversion options (C or C) + +RETURNS: 1 on success, undef on failure + =cut + sub convert_DTI { my ($file_in, $file_out, $options) = @_; @@ -491,19 +609,22 @@ sub convert_DTI { } +=pod +=head3 runDTIPrep($raw_nrrd, $protocol, $QCed_nrrd, $QCed2_nrrd) +Function that runs C on NRRD file. +INPUTS: + - $raw_nrrd : raw DTI NRRD file to be processed through C + - $protocol : C protocol used + - $QCed_nrrd : QCed file produced by C + - $QCed2_nrrd: optionally, secondary QCed file + +RETURNS: 1 on success, under on failure -=pod -Function that run DTIPrep on nrrd file. -Inputs: - $raw_nrrd: raw DTI nrrd file to be processed through DTIPrep - - $protocol: DTIPrep protocol used - - $QCed_nrrd: QCed file produced by DTIPrep - - $QCed2_nrrd: optionaly, secondary QCed file -Outputs: - 1 if QCed file found and secondary QCed file (if defined) is found - - undef if DTIPrep outputs not found =cut + sub runDTIPrep { my ($raw_nrrd, $protocol, $QCed_nrrd, $QCed2_nrrd) = @_; @@ -521,30 +642,34 @@ sub runDTIPrep { } +=pod +=head3 insertMincHeader($raw_file, $data_dir, $processed_minc, $QC_report, $DTIPrepVersion, $is_anat) +Inserts in the MINC header all the acquisition arguments except: + - acquisition:bvalues + - acquisition:direction_x + - acquisition:direction_y + - acquisition:direction_z + - acquisition:b_matrix +Takes the raw DTI file and the QCed MINC file as input and modifies +the QCed MINC file based on the raw MINC file's argument. + +If one of the value to insert is not defined, return undef, otherwise return 1. + +INPUTS: + - $raw_file : raw DTI MINC file to grep header information + - $data_dir : data dir as defined in the profile file + - $processed_minc: processed MINC file in which to insert header information + - $QC_report : C QC report text file + - $DTIPrepVersion: C version used to obtain processed file + - $is_anat : if set, will only insert processing, patient & study info + +RETURNS: 1 on success, undef on failure -=pod -Insert in the minc header all the acquisition arguments except: - - acquisition:bvalues - - acquisition:direction_x - - acquisition:direction_y - - acquisition:direction_z - - acquisition:b_matrix - -Takes the raw DTI file and the QCed minc file as input and modify -the QCed minc file based on the raw minc file's argument. - -Inputs: - $raw_file: raw DTI minc file to grep header information - - $data_dir: data dir as defined in the profile file - - $processed_minc: processed minc file in which header information will be inserted - - $QC_report: DTIPrep QC report text file - - $DTIPrepVersion: DTIPrep version used to obtain processed file - - $is_anat: if defined (=if file is anat based), will only insert processing, patient and study information -Outputs: - 1 if if all mincheader information was inserted - - undef otherwise =cut + sub insertMincHeader { my ($raw_file, $data_dir, $processed_minc, $QC_report, $DTIPrepVersion, $is_anat) = @_; @@ -567,16 +692,25 @@ sub insertMincHeader { } } + =pod -This will insert in the header of the processed file processing information. -Inputs: - $raw_dti: raw DTI minc file to grep header information - - $data_dir: data dir as defined in the profile file - - $processed_minc: processed minc file in which header information will be inserted - - $QC_report: DTIPrep QC report text file - - $DTIPrepVersion: DTIPrep version used to obtain processed file -Outputs: - 1 if all processed info were inserted in the processed minc header - - undef otherwise + +=head3 insertProcessInfo($raw_dti, $data_dir, $processed_minc, ...) + +This will insert in the header of the processed file processing information. If +one of the value to insert is not defined, return undef, otherwise return 1. + +INPUTS: + - $raw_dti : raw DTI MINC file to grep header information from + - $data_dir : data dir as defined in the profile file + - $processed_minc: processed MINC file in which to insert header info + - $QC_report : C QC report text file + - $DTIPrepVersion: C version used to obtain processed file + +RETURNS: 1 on success, undef on failure + =cut + sub insertProcessInfo { my ($raw_dti, $data_dir, $processed_minc, $QC_report, $DTIPrepVersion) = @_; @@ -614,18 +748,22 @@ sub insertProcessInfo { } +=pod +=head3 insertAcqInfo($raw_dti, $processed_minc) +Inserts acquisition information extracted from raw DTI dataset and insert it in +the processed file. If one of the value to insert is not defined, return +undef, otherwise return 1. +INPUTS: + - $raw_dti : raw DTI MINC file to grep header information + - $processed_minc: processed MINC file in which to insert header info + +RETURNS: 1 on success, undef on failure -=pod -Insert acquisition information extracted from raw DTI dataset and insert it in the processed file. -If one of the value to insert is not defined, return undef, otherwise return 1. -Inputs: - $raw_dti: raw DTI minc file to grep header information - - $processed_minc: processed minc file in which header information will be inserted -Outputs: - 1 if acquisition information were inserted in processed DTIPrep mincs - - undef otherwise =cut + sub insertAcqInfo { my ($raw_dti, $processed_minc) = @_; @@ -649,18 +787,23 @@ sub insertAcqInfo { } +=pod +=head3 insertFieldList($raw_dti, $processed_minc, $minc_field) +Inserts information extracted from raw DTI dataset and insert it in the +processed file. If one of the value to insert is not defined, return undef, +otherwise return 1. + +INPUTS: + - $raw_dti : raw DTI MINC file to grep header information from + - $processed_minc: processed MINC file in which to insert header info + - $minc_field : MINC field to be inserted in processed MINC file + +RETURNS: 1 on success, undef on failure -=pod -Insert information extracted from raw DTI dataset and insert it in the processed file. -If one of the value to insert is not defined, return undef, otherwise return 1. -Inputs: - $raw_dti: raw DTI minc file to grep header information - - $processed_minc: processed minc file in which header information will be inserted - - $minc_field: minc field to be inserted in processed minc file -Outputs: - 1 if information were inserted in processed DTIPrep mincs - - undef otherwise =cut + sub insertFieldList { my ($raw_dti, $processed_minc, $minc_field) = @_; @@ -694,16 +837,24 @@ sub insertFieldList { } } + =pod -Function that runs minc_modify_header and insert -minc header information if not already inserted. -Inputs: - $argument: argument to be inserted in minc header - - $value: value of the argument to be inserted in minc header - - $minc: minc file - - $awk: awk information to check if argument not already inserted in minc header -Outputs: - 1 if argument was indeed inserted into the minc file - - undef otherwise + +=head3 modify_header($argument, $value, $minc, $awk) + +Function that runs C and inserts MINC header information if +not already inserted. + +INPUTS: + - $argument: argument to be inserted in MINC header + - $value : value of the argument to be inserted in MINC header + - $minc : MINC file + - $awk : awk info to check if the argument was inserted in MINC header + +RETURNS: 1 if argument was inserted in the MINC header, undef otherwise + =cut + sub modify_header { my ($argument, $value, $minc, $awk) = @_; @@ -724,16 +875,22 @@ sub modify_header { } +=pod + +=head3 fetch_header_info($field, $minc, $awk, $keep_semicolon) +Function that fetches header information in MINC file. + +INPUTS: + - $field: field to look for in MINC header + - $minc : MINC file + - $awk : awk info to check if argument inserted in MINC header + - $keep_semicolon: if set, keep ";" at the end of extracted value + +RETURNS: value of the field found in the MINC header -=pod -Function that fetch header information in minc file -Inputs: - $field: field to look for in minc header - - $minc: minc file - - $awk: awk information to check if argument not already inserted in minc header - - $keep_semicolon: if defined, keep semicolon at the end of the value extracted -Outputs: - $value: value of the field found in the minc header =cut + sub fetch_header_info { my ($field, $minc, $awk, $keep_semicolon) = @_; @@ -751,18 +908,22 @@ sub fetch_header_info { } +=pod +=head3 get_header_list($splitter, $fields) +Gets the list of arguments and values to insert into the MINC header +(C, C and C). +INPUTS: + - $splitter: delimiter used to split list of fields stored in C<$fields> + - $fields : list header arguments/values to insert in the MINC header - -=pod -Get the list of arguments and values to insert into the mincheader (acquisition:*, patient:* and study:*). -Inputs: - $splitter: splitter used to separate list of fields stored in $fields - - $fields: list header arguments and values to insert in the minc header -Outputs: - $list: array of header arguments and values' list +RETURNS: - $list : array of header arguments and values' list - $list_size: size of the array $list + =cut + sub get_header_list { my ($splitter, $fields) = @_; @@ -781,21 +942,22 @@ sub get_header_list { } +=pod +=head3 mincdiff_preprocess($dti_file, $DTIrefs, $QCoutdir) +Function that runs C script from the C +tools on the QCed MINC and raw anat dataset. +INPUTS: + - $dti_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used + - $QCoutdir: directory used to create outputs from QC pipeline +RETURNS: 1 on success, undef on failure - - -=pod -Function that runs diff_preprocess.pl script from the mincdiffusion tools on the QCed minc and raw anat dataset. -- Arguments:- $dti_file: hash key to use to fetch file names (a.k.a. Raw DTI file) - - $DTIrefs: hash storing file names to be used - - $QCoutdir: directory used to create outputs from QC pipeline -- Returns: - 1 if all outputs were created - - undef if outputs were not created =cut + sub mincdiff_preprocess { my ($dti_file, $DTIrefs, $QCoutdir) = @_; @@ -823,21 +985,22 @@ sub mincdiff_preprocess { } +=pod +=head3 mincdiff_minctensor($dti_file, $DTIrefs, $QCoutdir, $niak_path) +Function that runs C script from the C tools on +the C preprocessed MINC and anatomical mask images. +INPUTS: + - $dti_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used + - $QCoutdir: directory used to create outputs from QC pipeline +RETURNS: 1 on success, undef on failure - - -=pod -Function that runs minctensor.pl script from the mincdiffusion tools on the mincdiff preprocessed minc and anatomical mask images. -- Arguments:- $dti_file: hash key to use to fetch file names (a.k.a. Raw DTI file) - - $DTIrefs: hash storing file names to be used - - $QCoutdir: directory used to create outputs from QC pipeline -- Returns: - 1 if all outputs were created - - undef if outputs were not created =cut + sub mincdiff_minctensor { my ($dti_file, $DTIrefs, $QCoutdir, $niak_path) = @_; @@ -869,20 +1032,20 @@ sub mincdiff_minctensor { } +=pod +=head3 RGBpik_creation($dti_file, $DTIrefs) +Function that runs C on the RGB map. +INPUTS: + - $dti_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used +RETURNS: 1 on success, undef on failure - - -=pod -Function that runs mincpik on the RGB map. -- Arguments:- $dti_file: hash key to use to fetch file names (a.k.a. Raw DTI file) - - $DTIrefs: hash storing file names to be used -- Returns: - 1 if rgb_pic was created - - undef if rgb_pic was not created =cut + sub RGBpik_creation { my ($dti_file, $DTIrefs) = @_; @@ -904,34 +1067,28 @@ sub RGBpik_creation { } +=pod +=head3 convert_DTIPrep_postproc_outputs($dti_file, $DTIrefs, $data_dir, $DTIPrepVersion) +This function will check if all C NRRD files were created and convert +them into MINC files with relevant header information inserted. +INPUTS: + - $dti_file : raw DTI dataset that was processed through C + - $DTIrefs : hash containing information about output names + - $data_dir : directory containing raw DTI dataset + - $DTIPrepVersion: C version used to process the DWI dataset +RETURNS: + - $nrrds_found : 1 if all NRRD outputs found, undef otherwise + - $mincs_created: 1 if all NRRD files converted to MINC files, + undef otherwise + - $hdrs_inserted: 1 if all header info inserted in MINC files, + undef otherwise - - - - - - - - - - - - -=pod -This function will check if all DTIPrep nrrd files were created and convert them into minc files with relevant header information inserted. -- Inputs: - $dti_file = raw DTI dataset that was processed through DTIPrep - - $DTIrefs = hash containing information about output names for all DWI datasets - - $data_dir = directory containing raw DTI dataset - - $DTIPrepVersion = DTIPrep version that was used to post process the DTI dataset -- Outputs: - $nrrds_found set to 1 if all nrrd outputs were found. If not, $nrrds_found is not defined - - $mincs_created set to 1 if all nrrd files were successfully converted to minc files. If not, $mincs_ -created is not defined. - - $hdrs_inserted set to 1 if all relevant header information were successfully inserted into the minc files. If not, $hdrs_inserted is not defined. =cut + sub convert_DTIPrep_postproc_outputs { my ($dti_file, $DTIrefs, $data_dir, $QCTxtReport, $DTIPrepVersion) = @_; @@ -985,15 +1142,26 @@ sub convert_DTIPrep_postproc_outputs { return ($nrrds_found, $mincs_created, $hdrs_inserted); } + =pod -Summarize which directions were rejected by DTIPrep for slice-wise correlations, + +=head3 getRejectedDirections($data_dir, $XMLReport) + +Summarize which directions were rejected by C for slice-wise +correlations, inter-lace artifacts, inter-gradient artifacts. -Inputs: - $data_dir = data_dir defined in the config file - - $QCReport = DTIPrep's QC txt report to extract rejected directions -Outputs: - $rm_slicewise = directions rejected due to slice wise correlations (number) - - $rm_interlace = directions rejected due to interlace artifacts (number) - - $rm_intergradient = directions rejected due to inter-gradient artifacts (number) + +INPUTS: + - $data_dir: data_dir defined in the config file + - $QCReport: C's QC txt report to extract rejected directions + +RETURNS: + - number of directions rejected due to slice wise correlations + - number of directions rejected due to interlace artifacts + - number of directions rejected due to inter-gradient artifacts + =cut + sub getRejectedDirections { my ($data_dir, $XMLReport) = @_; @@ -1060,3 +1228,22 @@ sub getRejectedDirections { return (\%summary); } + +1; + +__END__ + + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience + +=cut + + diff --git a/DTIPrep/DTIPrepRegister.pl b/DTIPrep/DTIPrepRegister.pl index b777b84bd..ee977b457 100755 --- a/DTIPrep/DTIPrepRegister.pl +++ b/DTIPrep/DTIPrepRegister.pl @@ -1,5 +1,62 @@ #!/usr/bin/perl -w +=pod + +=head1 NAME + +DTIPrepRegister.pl -- registers C outputs in the LORIS database + +=head1 SYNOPSIS + +perl DTIPrepRegister.pl C<[options]> + +Available options are: + +-profile : name of the config file in C<../dicom-archive/.loris-mri> + +-DTIPrep_subdir : C subdirectory storing the processed files to + be registered + +-DTIPrepProtocol: C protocol used to obtain the output files + +-DTI_file : native DWI file used to obtain the output files + +-anat_file : native anatomical dataset used to create FA, RGB and + other post-processed maps using C tools + +-DTIPrepVersion : C version used if it cannot be found in MINC + files' C header field + +-mincdiffusionVersion: C release version used if it cannot be + found in minc files' C + header field + +Note: C<-DTIPrepVersion> and C<-mincdiffusionVersion> are optional if the +version of those tools can be found directly in the MINC header of the +processed files. + +=head1 DESCRIPTION + +Registers DWI QC pipeline's output files of interest into the LORIS database +via C. + +The following output files will be inserted: + - QCed MINC file produced by C pre-processing step (i.e. DWI + dataset without the bad directions detected by C) + - Text QC report produced by DTPrep + - XML QC report produced by C + - RGB map produced by either C or C post-processing + - MD map produced by either C or C post-processing + - FA map produced by either C or C post-processing + - baseline image produced by C or C post-processing + - DTI mask produced by C post-processing (only if + C was used to post-process the data) + +=head2 Methods + +=cut + + use strict; use warnings; use Getopt::Tabular; @@ -43,6 +100,8 @@ -help for options +Documentation: perldoc DTIPrepRegister.pl + USAGE # Define the table describing the command-line options @@ -97,14 +156,13 @@ my $dbh = &NeuroDB::DBI::connect_to_db(@Settings::db); # Needed for log file -my $data_dir = &NeuroDB::DBI::getConfigSetting( - \$dbh,'dataDirBasepath' - ); -my $log_dir = "$data_dir/logs/DTIPrep_register"; +my $data_dir = &NeuroDB::DBI::getConfigSetting(\$dbh, 'dataDirBasepath'); +$data_dir =~ s/\/$//; # removing trailing / in $data_dir +my $log_dir = "$data_dir/logs/DTIPrep_register"; system("mkdir -p -m 770 $log_dir") unless (-e $log_dir); -my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); -my $date = sprintf("%4d-%02d-%02d_%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); -my $log = "$log_dir/DTIregister$date.log"; +my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); +my $date = sprintf("%4d-%02d-%02d_%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); +my $log = "$log_dir/DTIregister$date.log"; open(LOG,">>$log"); print LOG "\n==> Successfully connected to database \n"; print LOG "Log file, $date\n\n"; @@ -320,20 +378,25 @@ ############# =pod -Register XML protocol file into mri_processing_protocol table. -1. Check if protocol file was already registered in the database. -2. If protocol file already registered in the database, will return -the ProcessProtocolID from the database - If protocol file not registered yet in the database, will register -it in the database and return the ProcessProtocolID of the file -registered. -Inputs: $XMLProtocol= XML protocol file of DTIPrep to be registered - $data_dir = data directory in the prod file - $tool = Tool name of the protocol (a.k.a. "DTIPrep") -Outputs:$ProtocolID = ID of the registered protocol file -in mri_processing_protocol table that will be used to register output -files in the files table. + +=head3 register_XMLProt($XMLProtocol, $data_dir, $tool) + +Registers XML protocol file into the C table. It will +first check if protocol file was already registered in the database. If the +protocol file is already registered in the database, it will return the +Process Protocol ID from the database. If the protocol file is not registered +yet in the database, it will register it in the database and return the +C of the registered protocol file. + +INPUTS: + - $XMLProtocol: XML protocol file of C to be registered + - $data_dir : data directory from the C table, tool name of the + protocol (a.k.a. C) + +RETURNS: ID of the registered protocol file + =cut + sub register_XMLProt { my ($XMLProtocol, $data_dir, $tool) = @_; @@ -352,19 +415,23 @@ sub register_XMLProt { } +=pod +=head3 registerProtocol($protocol, $md5sum, $tool, $data_dir) +Registers protocol file into C table and move the +protocol to the C<$data_dir/protocols/DTIPrep> folder. +INPUTS: + - $protocol: protocol file to be registered + - $md5sum : MD5 sum of the protocol file to be registered + - $tool : tool of the protocol file (C) + - $data_dir: data directory (C) + +RETURNS: ID of the registered protocol file -=pod -Register protocol file into mri_processing_protocol table and move the protocol to the $data_dir/protocols/DTIPrep folder -Inputs: $protocol = protocol file to be registered - $md5sum = md5sum of the protocol file to be registered - $tool = tool of the protocol file (DTIPrep) - $data_dir = data_dir of the prod file -Output: $protPath if protocol has been successfully moved to the -datadir/protocol/tool folder and registered into the mri_processing_protocol table. =cut + sub registerProtocol { my ($protocol, $md5sum, $tool, $data_dir) = @_; @@ -391,21 +458,19 @@ sub registerProtocol { } +=pod +=head3 fetchProtocolID($md5sum) +Fetches the protocol ID in the C table based on +the XML protocol's MD5 sum. +INPUT: MD5 sum of the XML protocol +RETURNS: ID of the registered protocol file - - - -=pod -Fetches the protocol ID in the mri_processing_protocol table based on -the XML protocol's md5sum. -Input: $md5sum = md5sum of the XML protocol -Output: $ProtocolID = protocol ID from the mri_proceesing_protocol table -of the registered XML protocol file if could find a match with md5sum. =cut + sub fetchProtocolID { my ($md5sum) = @_; @@ -425,23 +490,31 @@ sub fetchProtocolID { return ($protocolID); } + =pod -Set the different parameters needed for minc files' registration -and call registerFile to register the minc file in the database -via register_processed_data.pl script. -Inputs: - $minc = minc file to be registered - - $raw_file = native file that was the source of the minc file to register - - $data_dir = data_dir directory set in the config file (/data/project/data) - - $inputs = input files used to obtain minc file to be registered - - $pipelineName= name of the pipeline used to obtain the minc file (a.k.a. DTIPrepPipeline) - - $toolName = tool name and version that was used to obtain the minc file - - $registeredXMLFile = registered DTIPrep XML report associated with the minc file - - $registeredQCReportFile = registered DTIPrep Txt report associated with the minc file - - $scanType = type of scan to be used to register the minc file - - $registered_nrrd = optionally, registered nrrd file that was used to create the minc file -Outputs: - $registeredMincFile if minc file was indeed registered in the database - - undef is not all options could be set or file was not registered in the database + +=head3 register_minc($minc, $raw_file, $data_dir, $inputs, $pipelineName, $toolName, $registeredXMLFile, $registeredQCReportFile, $scanType, $registered_nrrd) + +Sets the different parameters needed for MINC files' registration +and calls C<®isterFile> to register the MINC file in the database +via C script. + +INPUTS: + - $minc : MINC file to be registered + - $raw_file : source file of the MINC file to register + - $data_dir : data_dir directory from the config table + - $inputs : input files of the file to be registered + - $pipelineName : name of the pipeline used to obtain the MINC file + - $toolName : tool name and version used + - $registeredXMLFile : registered C XML report + - $registeredQCReportFile: registered C text report + - $scanType : scan type of the MINC file to register + - $registered_nrrd : optional, registered NRRD file used to create the MINC file + +RETURNS: registered MINC file on success, undef otherwise + =cut + sub register_minc { my ($minc, $raw_file, $data_dir, $inputs, $registeredXMLprotocolID, $pipelineName, $toolName, $registeredXMLFile, $registeredQCReportFile, $scanType, $registered_nrrd) = @_; @@ -549,19 +622,27 @@ sub register_minc { } + =pod -Set parameters needed to register the XML report/protocol of DTIPrep -and call registerFile to register the XML file via register_processed_data.pl. -Inputs: - $XMLFile = XML file to be registered - - $raw_file = Native DTI file that was processed to obtain the DTIPrep outputs - - $data_dir = data_dir as defined in the config file (a.k.a. /data/project/data) - - $QCReport = DTIPrep QCreport - - $inputs = input files that were used to process data through DTIPrep - - $pipelineName = name of the pipeline used to process DTIs (DTIPrepPipeline) - - $toolName = DTIPrep name and version that was used to process DTIs -Outputs: - $registeredXMLFile if the XML file was indeed registered in the database - - undef if could not set all parameters for registration or file could not be registered in the database + +=head3 register_XMLFile($XMLFile, $raw_file, $data_dir, $QCReport, $inputs, $pipelineName, $toolName) + +Sets parameters needed to register the XML report/protocol of C +and calls registerFile to register the XML file via register_processed_data.pl. + +INPUTS: + - $XMLFile : XML file to be registered + - $raw_file : native DWI file used to obtain the C outputs + - $data_dir : data directory (e.g. C) + - $QCReport : C QC text report + - $inputs : input files used to process data through C + - $pipelineName: pipeline name used to process DWIs (C) + - $toolName : C name and version used to process the DWI file + +RETURNS: the registered XNL file if it was registered in the database or undef + =cut + sub register_XMLFile { my ($XMLFile, $raw_file, $data_dir, $QCReport, $inputs, $registeredXMLprotocolID, $pipelineName, $toolName) = @_; @@ -630,18 +711,27 @@ sub register_XMLFile { } } + =pod -Set parameters needed to register the QCreport of DTIPrep -and call registerFile to register the QCreport file via register_processed_data.pl. -Inputs: - $QCReport = QC report file to be registered - - $raw_file = Native DTI file that was processed to obtain the DTIPrep outputs - - $data_dir = data_dir as defined in the config file (a.k.a. /data/project/data) - - $inputs = input files that were used to process data through DTIPrep - - $pipelineName = name of the pipeline used to process DTIs (DTIPrepPipeline) - - $toolName = DTIPrep name and version that was used to process DTIs -Outputs: - $registeredQCReportFile if the QC report file was indeed registered in the database - - undef if could not set all parameters for registration or file could not be registered in the database + +=head3 register_QCReport($QCReport, $raw_file, $data_dir, $inputs, $pipelineName, $toolName) + +Sets parameters needed to register the QCreport of C and calls +C<®isterFile> to register the QCreport file via +C. + +INPUTS: + - $QCReport : QC report file to be registered + - $raw_file : native DWI file used to obtain the C outputs + - $data_dir : data directory (e.g. C) + - $inputs : input files used to process data through C + - $pipelineName: pipeline name used to process DTIs (C) + - $toolName : C name and version used to process the DWI file + +RETURNS: registered QCReport file if it was registered in the database or undef + =cut + sub register_QCReport { my ($QCReport, $raw_file, $data_dir, $inputs, $registeredXMLprotocolID, $pipelineName, $toolName) = @_; @@ -703,15 +793,38 @@ sub register_QCReport { } } - + + =pod -This function checks that all the processing files exist on the filesystem and returns the files to be inserted in the database. When nrrd and minc files were found, it will only return the minc file. (nrrd files will be linked to the minc file when inserting files in the database). -- Inputs: - $dti_file = raw DTI dataset that is used as a key in $DTIrefs hash - - $DTIrefs = hash containing all output paths and tool information -- Outputs: - if all files have been found on the file system, will return: - - ($XMLProtocol, $QCReport, $XMLReport, $QCed_minc, $RGB_minc, $FA_minc, $MD_minc, $baseline_minc, $brain_mask_minc, $QCed2_minc) - - if there are some missing files, it will return undef + +=head3 getFiles($dti_file, $DTIrefs) + +This function checks that all the processing files exist on the filesystem and +returns the files to be inserted in the database. When NRRD and MINC files are +found, it will only return the MINC file. (NRRD files will be linked to the +MINC file when inserting files in the database). + +INPUTS: + - $dit_file: raw DTI dataset that is used as a key in C<$DTIrefs> hash + - $DTIref : hash containing all output paths and tool information + +RETURNS: + - $XMLProtocol : C XML protocol found in the file system + - $QCReport : C QC text report found in the file system + - $XMLReport : C QC XML report found in the file system + - $QCed_minc : QCed MINC file created after conversion of QCed NRRD file + - $RGB_minc : RGB MINC file found in the file system + - $FA_minc : FA MINC file found in the file system + - $MD_minc : MD MINC file found in the file system + - $baseline_minc : baseline MINC file found in the file system + - $brain_mask_minc: brain mask MINC file found in the file system + - $QCed2_minc : optional, secondary QCed MINC file created after + conversion of secondary QCed C NRRD file + - returns undef if there are some missing files (except for C + which is optional) + =cut + sub getFiles { my ($dti_file, $DTIrefs) = @_; @@ -729,17 +842,32 @@ sub getFiles { } } + =pod -Function that checks if all DTIPrep preprocessing files are present in the file system. -- Inputs: - $dti_file = raw DTI dataset that is used as a key in $DTIrefs hash - - $DTIrefs = hash containing all output paths and tool information -- Outputs: - $XMLProtocol = DTIPrep XML protocol that was found in the file system - - $QCReport = DTIPrep Txt QCReport that was found in the file system - - $XMLReport = DTIPrep XML QCReport that was found in the file system - - $QCed_minc = QCed minc file that was created after conversion of QCed DTIPrep nrrd file - - $QCed2_minc = Optionally, secondary QCed minc file that was created after conversion of secondary QCed DTIPrep nrrd file - - return undef if one of the file listed above is missing (except for QCed2_minc which is optional) + +=head3 checkPreprocessFiles($dti_file, $DTIrefs, $mri_files) + +Function that checks if all C pre-processing files are present in the +file system. + +INPUTS: + - $dti_file: raw DTI dataset that is used as a key in C<$DTIrefs> hash + - DTIrefs : hash containing all output paths and tool information + - mri_files: list of processed outputs to register or that have been + registered + +RETURNS: + - $XMLProtocol: C XML protocol found in the file system + - $QCReport : C text QC report found in the file system + - $XMLReport : C XML QC report found in the file system + - $QCed_minc : QCed MINC file created after conversion of QCed NRRD file + - $QCed2_minc : optional, secondary QCed MINC file created after + conversion of secondary QCed C NRRD file + - returns undef if one of the file listed above is missing (except + for C which is optional) + =cut + sub checkPreprocessFiles { my ($dti_file, $DTIrefs, $mri_files) = @_; @@ -777,27 +905,30 @@ sub checkPreprocessFiles { } +=pod +=head3 checkPostprocessFiles($dti_file, $DTIrefs, $mri_files) +Function that checks if all postprocessing files (from C or +C) are present in the file system. +INPUTS: + - $dti_file : raw DTI dataset that is used as a key in C<$DTIrefs> hash + - $DTIrefs : hash containing all output paths and tool information + - $mri_files: list of processed outputs to register or that have been registered + +RETURNS: + - $RGB_minc : RGB map + - $FA_minc : FA map + - $MD_minc : MD map + - $baseline_minc : baseline (or frame-0) map + - $brain_mask_minc: brain mask produced by C tools (not + available if C was run to obtain the + post-processing outputs) + - will return undef if one of the file listed above is missing -=pod -Function that checks if all postprocessing files (from DTIPrep or mincdiffusion) are present in the file system. -- Inputs: - $dti_file = raw DTI dataset that is used as a key in $DTIrefs hash - - $DTIrefs = hash containing all output paths and tool information -- Outputs: - if mincdiffusion was run and found all outputs on the filesystem, will return: - - $RGB_minc = RGB map - - $FA_minc = FA map - - $MD_minc = MD map - - $baseline_minc = baseline (or frame-0) map - - $brain_mask_minc = brain mask produced by mincdiffusion tools - - if DTIPrep was run and found all postprocessed outputs (nrrd & minc) on the filesystem, will return: - - $RGB_minc = RGB map - - $FA_minc = FA map - - $MD_minc = MD map - - $baseline_minc = baseline (or frame-0) map - - will return undef and print messages into the LOG file otherwise =cut + sub checkPostprocessFiles { my ($dti_file, $DTIrefs, $mri_files) = @_; @@ -898,20 +1029,22 @@ sub checkPostprocessFiles { } +=pod +=head3 getFileID($file, $src_name) +Fetches the source FileID from the database based on the C<$src_name> file +identified by C. +INPUTS: + - $file : output filename + - $src_name: source filename (file that has been used to obtain C<$file>) +RETURNS: source File ID (file ID of the source file that has been used to + obtain $file) - - - -=pod -Fetches the source FileID from the database based on the src_name file identified by getFileName. -Inputs: - $file = output filename - - $src_name = source filename (file that has been used to obtain $file) -Outputs: - $fileID = source File ID (file ID of the source file that has been used to obtain $file) =cut + sub getFileID { my ($file, $src_name) = @_; @@ -937,16 +1070,23 @@ sub getFileID { } +=pod +=head3 getToolName($file) +Fetches tool information stored either in the MINC file's header or in the +QC text report. + +INPUT: MINC or QC text report to look for tool information + +RETURNS: + - $src_pipeline: name of the pipeline used to obtain C<$file> (C) + - $src_tool : name and version of the tool used to obtain C<$file> + (C, C) -=pod -Fetches tool informations stored either in the minc's header or in the QCReport. -Inputs: - $file = minc or QC report to look for tool information -Outputs: - $src_pipeline= name of the pipeline used to obtain $file (a.k.a. DTIPrepPipeline) - - $src_tool = name and version of the tool used to obtain $file (DTIPrep_v1.1.6, mincdiffusion_v...) =cut -sub getToolName { + +sub getToolName { my ($file) = @_; my $src_pipeline = &DTI::fetch_header_info('processing:pipeline', @@ -971,13 +1111,23 @@ sub getToolName { return ($src_pipeline, $src_tool); } + =pod -Fetches the date at which DTIPrep pipeline was run either in the processed minc's header or in the QCReport. -Inputs: - $file = minc or QC report to look for tool information - - $data_dir = data_dir stored in the config file - - $QCReport = QC report created when $file was created -Outputs: - $pipeline_date = date at which the pipeline has been run to obtain $file + +=head3 getPipelineDate($file, $data_dir, $QCReport) + +Fetches the date at which the C pipeline was run either in the processed +MINC file's header or in the QC text report. + +INPUTS: + - $file : MINC or QC text report to look for tool information + - $data_dir: data directory (e.g. C) + - $QCReport: QC text report created when C<$file> was created + +RETURNS: date at which the pipeline has been run to obtain C<$file> + =cut + sub getPipelineDate { my ($file, $data_dir, $QCReport) = @_; @@ -1025,21 +1175,24 @@ sub getPipelineDate { } +=pod +=head3 insertReports($minc, $registeredXMLFile, $registeredQCReportFile) +Inserts the path to C's QC text, XML reports and XML protocol in the +MINC file's header. + +INPUTS: + - $minc : MINC file for which the header should be modified + - $registeredXMLfile : path to the registered C's QC XML report + - $registeredQCReportFile: path to the registered C's QC text report + +RETURNS: + - $Txtreport_insert: 1 on text report path insertion success, undef otherwise + - $XMLreport_insert: 1 on XML report path insertion success, undef otherwise -=pod -Insert in mincheader the path to DTIPrep's QC txt and xml reports and xml protocol. -Inputs: - $minc = minc file to modify header - - $registeredXMLFile = path to the registered DTIPrep's XML report - - $registeredQCReportFile = path to the registered DTIPrep's QC txt report -Outputs: - $Txtreport_insert = 1 if text report path insertion was successful - = undef if text report path was not inserted - - $XMLreport_insert = 1 if xml report path insertion was successful - = undef if xml report path was not inserted - - $protocol_insert = 1 if xml protocol path insertion was successful - = undef if xml protocol path was not inserted =cut + sub insertReports { my ($minc, $registeredXMLFile, $registeredQCReportFile) = @_; @@ -1060,21 +1213,24 @@ sub insertReports { } +=pod +=head3 insertPipelineSummary($minc, $data_dir, $XMLReport, $scanType) +Inserts in the MINC header a summary of C reports. This summary consists +of the directions rejected due to slice wise correlation, the directions +rejected due to interlace correlation, and the directions rejected due to +gradient wise correlation. +INPUTS: + - $minc : MINC file in which the summary will be inserted + - $data_dir : data directory (e.g. C) + - $XMLReport: C's XML QC report from which the summary will be extracted + +RETURNS: 1 on success, undef on failure -=pod -Insert in mincheader a summary of DTIPrep reports. -This summary consist of the directions rejected due to slice wise correlation, -the directions rejected due to interlace correlation, -and the directions rejected due to gradient wise correlation -Inputs: - $minc = minc file in which the summary will be inserted - - $data_dir = data_dir as defined in the config file - - $QCReport = DTIPrep's QC report from which the summary will be extractec -Outputs: - 1 if all information has been successfully inserted - - undef if at least one information has not been inserted =cut + sub insertPipelineSummary { my ($minc, $data_dir, $XMLReport, $scanType) = @_; @@ -1129,23 +1285,30 @@ sub insertPipelineSummary { } +=pod +=head3 registerFile($file, $src_fileID, $src_pipeline, $src_tool, $pipelineDate, $coordinateSpace, $scanType, $outputType, $inputs) +Registers file into the database via C with all +options. +INPUTS: + - $file : file to be registered in the database + - $src_fileID : source file's FileID + - $src_pipeline : pipeline used to obtain the file (C) + - $src_tool : name and version of the tool (C or C) + - $pipelineDate : file's creation date (= pipeline date) + - $coordinateSpace: file's coordinate space (= native, T1 ...) + - $scanType : file's scan type (= C, C, + C, C...) + - $outputType : file's output type (C<.xml>, C<.txt>, C<.mnc>...) + - $inputs : input files that were used to create the file to + be registered (intermediary files) + +RETURNS: registered file -=pod -Register file into the database via register_processed_data.pl with all options. -Inputs: - $file = file to be registered in the database - - $src_fileID = FileID of the source file used to obtain the file to be registered - - $src_pipeline = Pipeline used to obtain the file (DTIPrepPipeline) - - $src_tool = Name and version of the tool used to obtain the file (DTIPrep or mincdiffusion) - - $pipelineDate = file's creation date (= pipeline date) - - $coordinateSpace = file's coordinate space (= native, T1 ...) - - $scanType = file's scan type (= DTIPrepReg, DTIPrepDTIFA, DTIPrepDTIMD, DTIPrepDTIColorFA...) - - $outputType = file's output type (.xml, .txt, .mnc...) - - $inputs = files that were used to create the file to be registered (intermediary files) -Outputs: - $registeredFile = file that has been registered in the database =cut + sub registerFile { my ($file, $src_fileID, $src_pipeline, $src_tool, $pipelineDate, $coordinateSpace, $scanType, $outputType, $inputs, $registeredXMLprotocolID) = @_; @@ -1192,19 +1355,24 @@ sub registerFile { } +=pod + +=head3 fetchRegisteredFile($src_fileID, $src_pipeline, $pipelineDate, $coordinateSpace, $scanType, $outputType) +Fetches the registered file from the database to link it to the MINC files. +INPUTS: + - $src_fileID : FileID of the source native file + - $src_pipeline : pipeline name used to register the processed file + - $pipelineDate : pipeline data used to register the processed file + - $coordinateSpace: processed file's coordinate space + - $scanType : scan type used to register the processed file + - $outputType : output type used to register the processed file + +RETURNS: path to the registered processed file -=pod -Fetch the registered file from the database to link it to the minc files. -Inputs: - $src_fileID = FileID of the native file used to register the processed file - - $src_pipeline = Pipeline name used to register the processed file - - $pipelineDate = Pipeline data used to register the processed file - - $coordinateSpace = coordinate space used to register the processed file - - $scanType = scan type used to register the processed file - - $outputType = output type used to register the processed file -Outputs: - $registeredFile = path to the registered processed file =cut + sub fetchRegisteredFile { my ($src_fileID, $src_pipeline, $pipelineDate, $coordinateSpace, $scanType, $outputType) = @_; @@ -1235,19 +1403,36 @@ sub fetchRegisteredFile { } +=pod +=head3 register_DTIPrep_files($minc, $nrrd, $raw_file, $data_dir, $inputs, $registeredXMLProtocolID, $pipelineName, $DTIPrepVersion, $registeredXMLReportFile, $registeredQCReport, $scanType) +Registers C NRRD and MINC files. The MINC file will have a link to the +registered NRRD file (C<®ister_minc> function will modify the MINC header to +include this information) in addition to the links toward QC reports and +protocol. +INPUTS: + - $minc : MINC file to be registered + - $nrrd : NRRD file to be registered + - $raw_file : raw DWI file used to create the MINC file to + register + - $data_dir : data directory (e.g. C) + - $inputs : input files that were used to create the file to + be registered (intermediary files) + - $registeredXMLProtocolID: registered XML protocol file + - $pipelineName : name of the pipeline that created the file to be + registered (C) + - $DTIPrepVersion : C's version + - $registeredXMLReportFile: registered QC XML report file + - $registeredQCReport : registered QC text report file + - $scanType : scan type to use to label/register the MINC file -=pod -Register DTIPrep nrrd and minc files. The minc file will have a link to the registered nrrd file (register_minc function will modify mincheader to include this information) in addition to the links toward QC reports and protocol. -- Inputs: - files to be registered ($minc, $nrrd) - - registered QC report files ($registeredXMLReportFile, $registeredQCReportFile) - - $DTIPrepVersion used to produce the files -- Outputs: - registered minc files if the nrrd and minc files were successfully registered in the database - - undef if one argument of the function if missing or if nrrd file could not be registered +RETURNS: registered MINC files or undef on insertion's failure + =cut + sub register_DTIPrep_files { my ($minc, $nrrd, $raw_file, $data_dir, $inputs, $registeredXMLprotocolID, $pipelineName, $DTIPrepVersion, $registeredXMLReportFile, $registeredQCReportFile, $scanType) = @_; @@ -1301,24 +1486,28 @@ sub register_DTIPrep_files { } +=pod +=head3 register_nrrd($nrrd, $raw_file, $data_dir, $QCReport, $inputs, $pipelineName, $toolName, $scanType) +Sets parameters needed to register the NRRD file produced by C +and calls registerFile to register the NRRD file via +C. +INPUTS: + - $nrrd : NRRD file to be registered + - $raw_file : native DWI file used to obtain the C outputs + - $data_dir : data directory (e.g. C) + - $QCReport : C QC text report + - $inputs : input files used to process data through C + - $pipelineName: pipeline name used to process DTIs (C) + - $toolName : C name and version used to process the DWI file + - $scanType : NRRD file's scan type + +RETURNS: registered NRRD file or undef on insertion's failure -=pod -Set parameters needed to register the nrrd file produced by DTIPrep -and call registerFile to register the nrrd file via register_processed_data.pl. -Inputs: - $nrrd = nrrd file to be registered - - $raw_file = Native DTI file that was processed to obtain the DTIPrep outputs - - $data_dir = data_dir as defined in the config file (a.k.a. /data/project/data) - - $QCReport = DTIPrep QCreport - - $inputs = input files that were used to process data through DTIPrep - - $pipelineName = name of the pipeline used to process DTIs (DTIPrepPipeline) - - $toolName = DTIPrep name and version that was used to process DTIs - - $scanType = nrrd file's scan type -Outputs: - $registeredNrrdFile if the nrrd file was indeed registered in the database - - undef if could not set all parameters for registration or file could not be registered in the database =cut + sub register_nrrd { my ($nrrd, $raw_file, $data_dir, $QCReport, $inputs, $registeredXMLprotocolID, $pipelineName, $toolName, $scanType) = @_; @@ -1385,22 +1574,28 @@ sub register_nrrd { } +=pod +=head3 register_Preproc($mri_files, $dti_file, $data_dir, $pipelineName, $toolName, $process_step, $proc_file) +Gathers all C preprocessed files to be registered in the database +and calls C<®ister_DTIPrep_files> on all of them. Will register first the +NRRD file and then the MINC file for each scan type. + +INPUTS: + - $mri_files : hash containing all DTI output information + - $dti_file : native DWI file (that will be used as a key + for C<$mri_files>) + - $data_dir : data directory (e.g. C) + - $pipelineName: pipeline name (C) + - $toolName : tool's name and version + - $process_step: processing step (C or C) + - $proc_file : processed file key (C, C...) + +RETURNS: path to the MINC file that was registered -=pod -Gather all DTIPrep preprocessed files to be registered in the database -and call register_DTIPrep_files on all of them. Will register first the -nrrd file and then the minc file for each scan type. -Inputs: - $mri_files = hash containing all DTI output information - - $dti_file = native DTI file that was processed (that will be used as a key for $mri_files) - - $data_dir = data_dir defined in the config file - - $pipelineName = name of the pipeline used to preprocess data (DTIPrepPipeline) - - $toolName = name and version of the tool used to preprocess data - - $process_step = processing step ('Preproc' or 'Postproc') depending on the processed file - - $proc_file = key to the processed file to be registered ('QCed', 'QCed2'...) -Outputs: - $registered_minc = path to the minc file that was registered =cut + sub register_Preproc { my ($mri_files, $dti_file, $data_dir, $registeredXMLprotocolID, $pipelineName, $toolName, $process_step, $proc_file) = @_; @@ -1432,23 +1627,29 @@ sub register_Preproc { } +=pod +=head3 register_images($mri_files, $raw_file, $data_dir, $pipelineName, $toolName, $process_step) +Function to register processed images in the database depending on the tool +used to obtain them. Will call C<®ister_DTIPrep_files> if files to be +registered are obtained via C or C<®ister_minc> if files to be +registered are obtained using C tools. +INPUTS: + - $mri_files : hash with information about the files to be registered + - $raw_file : source raw image + - $data_dir : data directory (e.g. C) + - $pipelineName: name of the pipeline used (a.k.a C) + - $toolName : tool's version and name + - $process_step: processing step (pre-processing, post-processing) + +RETURNS: + - @registered : list of registered files + - @failed_to_register: list of files that failed to be registered in the DB -=pod -Function to register processed images in the database depending on the tool used to obtain them. -Will call register_DTIPrep_files if files to be registered are obtained via DTIPrep -or register_minc if files to be registered are obtained using mincdiffusion tools. -Inputs: - $mri_files: hash containing information about the files to be registered - - $raw_file: source raw image used to obtain processed files to be registered - - $data_dir: data directory where all images are stored (set in the prod file) - - $pipelineName: name of the pipeline used (a.k.a DTIPrep) - - $toolName: version and name of the tool used to produce the images to be registered - - $process_step: processing step (preprocessing, post-processing) -Outputs: - @registered: list of registered files - - @failed_to_register: list of files that failed to be registered in the database =cut + sub register_images { my ($mri_files, $raw_file, $data_dir, $pipelineName, $toolName, $process_step) = @_; @@ -1512,14 +1713,25 @@ sub register_images { } - =pod -Function that will return in a string the list of inputs used to process the data separated by ';'. -Inputs: - $mri_files = list of processed outputs to registered or that have been registered - - $process_step = processing step used for the processed output to determine inputs - - $proc_file = processing file to determine inputs used -Outputs:- $inputs_list = string with each inputs used separated by ';' + +=head3 getInputList($mri_files, $data_dir, $process_step, $proc_file) + +Function that will return in a string the list of inputs used to process the +data separated by ';'. + +INPUTS: + - $mri_files : list of processed outputs to register or that + have been registered + - $data_dir : data directory (e.g. C) + - $process_step: processing step used for the processed output + to determine inputs + - $proc_file : processing file to determine inputs used + +RETURNS: string with each inputs used separated by ';' + =cut + sub getInputList { my ($mri_files, $data_dir, $process_step, $proc_file) = @_; @@ -1553,17 +1765,20 @@ sub getInputList { } +=pod +=head3 fetchRegisteredMD5($md5sum) +Will check if MD5 sum has already been registered into the database. +INPUT: MD5 sum of the file +RETURNS: + - $registeredFile : registered FileID matching MD5 sum + - $registeredScanType: scan type of the registered C matching MD5 sum -=pod -Will check if md5sum has already been registered into the database. -Input: - $md5sum: md5sum of the file -Output: - $registeredFileID: registered FileID matching md5sum - - $registeredScanType: scan type of the registered FileID matching md5sum =cut + sub fetchRegisteredMD5 { my ($md5sum) = @_; @@ -1584,3 +1799,17 @@ sub fetchRegisteredMD5 { return ($registeredFile, $registeredScanType); } + +__END__ + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience + +=cut \ No newline at end of file diff --git a/DTIPrep/DTIPrep_pipeline.pl b/DTIPrep/DTIPrep_pipeline.pl index c4f41b7fd..369daa738 100755 --- a/DTIPrep/DTIPrep_pipeline.pl +++ b/DTIPrep/DTIPrep_pipeline.pl @@ -1,5 +1,86 @@ #!/usr/bin/perl -w +=pod + +=head1 NAME + +DTIPrep_pipeline.pl -- Run C and/or insert C's outputs in the +database. + +=head1 SYNOPSIS + +perl DTIPrep_pipeline.p C<[options]> + + +-profile : name of config file in + C<../dicom-archive/.loris_mri> + +-list : file containing the list of raw diffusion MINC + files (in C) + +-DTIPrepVersion : C version used (if cannot be found in + C binary path) + +-mincdiffusionVersion: C release version used (if cannot be + found in C scripts path) + +-runDTIPrep : if set, run C on the raw MINC DTI data + +-DTIPrepProtocol : C protocol to use (or used) to run C + +-registerFilesInDB : if set, registers outputs file in the database + + +B + +- tool version options (C<-DTIPrepVersion> & C<-mincdiffusionVersion>) +do not need to be set if they can be found directly in the path of the binary +tools. + +- the script can be run without the C<-runDTIPrep> option if execution of +C is not needed. + +- the script can be run without the C<-registerFilesInDB> option if +registration of C is not needed. + +=head1 DESCRIPTION + +C can be used to run C on native DWI datasets. It +will also organize, convert and register the outputs of C in the +database. + +If C<-runDTIPrep> option is not set, C processing will be skipped +(C outputs being already available, as well as the C protocol +that was used). + +B + +1) grep native DWI files from list of given native directories (C<-list> option) + +2) create (or fetch if C<-runDTIPrep> not set) output directories based + on the C version and protocol that are to be (or were) used + for C processing + +3) convert native DWI MINC file to NRRD and run C if C<-runDTIPrep> + option is set + +4) fetch C pre-processing outputs (QCed.nrrd, QCReport.txt, + QCXMLResults.xml & protocol.xml) + +5) convert pre-processed NRRD files back to MINC with all the header + information (based on the native MINC file) + +6) create post-processing files (FA, RGB maps...) with all the header + information + +7) call C to register the files in the database if + C<-registerFilesInDB> is set + +=head2 Methods + +=cut + + require 5.001; use strict; use Getopt::Tabular; @@ -37,6 +118,8 @@ -help for options +Documentation: perldoc DTIPrep_pipeline.pl. + USAGE # Set default option values @@ -90,28 +173,14 @@ my $dbh = &NeuroDB::DBI::connect_to_db(@Settings::db); # These settings are in the ConfigSettings table -my $data_dir = &NeuroDB::DBI::getConfigSetting( - \$dbh,'dataDirBasepath' - ); -my $t1_scan_type = &NeuroDB::DBI::getConfigSetting( - \$dbh,'t1_scan_type' - ); -my $DTI_volumes = &NeuroDB::DBI::getConfigSetting( - \$dbh,'DTI_volumes' - ); -my $reject_thresh = &NeuroDB::DBI::getConfigSetting( - \$dbh,'reject_thresh' - ); -my $niak_path = &NeuroDB::DBI::getConfigSetting( - \$dbh,'niak_path' - ); -my $QCed2_step = &NeuroDB::DBI::getConfigSetting( - \$dbh,'QCed2_step' - ); - -my $site = &NeuroDB::DBI::getConfigSetting( - \$dbh,'prefix' - ); +my $t1_scan_type = &NeuroDB::DBI::getConfigSetting(\$dbh, 't1_scan_type'); +my $DTI_volumes = &NeuroDB::DBI::getConfigSetting(\$dbh, 'DTI_volumes'); +my $reject_thresh = &NeuroDB::DBI::getConfigSetting(\$dbh, 'reject_thresh'); +my $niak_path = &NeuroDB::DBI::getConfigSetting(\$dbh, 'niak_path'); +my $QCed2_step = &NeuroDB::DBI::getConfigSetting(\$dbh,'QCed2_step'); +my $site = &NeuroDB::DBI::getConfigSetting(\$dbh, 'prefix'); +my $data_dir = &NeuroDB::DBI::getConfigSetting(\$dbh, 'dataDirBasepath'); +$data_dir =~ s/\/$//; # removing trailing / in $data_dir # Needed for log file my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); @@ -271,11 +340,20 @@ ############### =pod -Function that determine tool version used for processing. -- Inputs: - $tool = tool to search absolute path containing version information - - $match= string to match to determine tool version -- Output: - Version of the tool found or undef if version could not be determined based on the path + +=head3 identify_tool_version($tool, $match) + +Function that determines the tool version used for processing. + +INPUTS: + - $tool : tool to search absolute path containing version information + - $match: string to match to determine tool version + +RETURNS: version of the tool found, or undef if version could not be +determined based on the path + =cut + sub identify_tool_version { my ($tool, $match) = @_; @@ -289,20 +367,21 @@ sub identify_tool_version { } +=pod +=head3 getIdentifiers($nativedir) +Fetches C and visit label from the native directory of the dataset to +process. Relevant information will also be printed in the log file. +INPUT: native directory of the dataset to process +RETURNS: undef if could not determine the site, C, visit OR + - $candID : candidate DCCID + - $visit_label: visit label - - -=pod -Fetches candID and visit label from the native directory of the dataset to process. -Input: - $nativedir: native directory of the dataset to process -Output: - undef if could not find the site, candID or visit label. - - $candID and $visit_label informations if they were found. -Relevant information will also be printed in the log file. =cut + sub getIdentifiers { my ($nativedir) = @_; @@ -323,27 +402,33 @@ sub getIdentifiers { } +=pod +=head3 getOutputDirectories($outdir, $subjID, $visit, $DTIPrepProtocol, $runDTIPrep) +Determine pipeline's output directory based on the root C<$outdir>, C +protocol name, candidate ID C and visit label: +C +- If C<$runDTIPrep> is set, the function will create the output folders +- If C<$runDTIPrep> is not set, the function will check that the directory exists +INPUTS: + - $outdir : root directory for C outputs (in + C) + - $subjID : candidate ID of the DTI dataset to be processed + - $visit : visit label of the DTI dataset to be processed + - $DTIPrepProtocol: XML file with the C protocol to use + - $runDTIPrep : boolean, if output folders should be created in + the filesystem (before processing data through + C) if they don't exist +RETURNS: directory where processed files for the candidate, visit label and +DTIPrep protocol will be stored. - -=pod -Determine pipeline's output directory, based on the root outdir, DTIPrep protocol, candID and visit label: (outdir/ProtocolName/CandID/VisitLabel). -If $runDTIPrep is defined, the function will create the output folders. -If $runDTIPrep is not defined, will check that the directory exists. - -- Inputs: -$outdir = output directory where DTIPrep results for all datasets for all subjects will be stored (in /data/project/data/pipelines/DTIPrep/DTIPrep_version) - - $subjID = candidate ID of the DTI dataset to be processed - - $visit = visit label of the DTI dataset to be processed - - $DTIPrepProtocol= XML file with the DTIPrep protocol to be used for analyses - - $runDTIPrep = a boolean which will determine if OutputFolders should be created in the filesystem (before processing data through DTIPrep) if they don't exist - -- Ouput: - $QCoutdir = directory where processed files for the candidate, visit label and DTIPrep protocol will be stored. =cut + sub getOutputDirectories { my ($outdir, $subjID, $visit, $DTIPrepProtocol, $runDTIPrep) = @_; @@ -364,29 +449,27 @@ sub getOutputDirectories { } +=pod +=head3 fetchData($nativedir, $DTI_volumes, $t1_scan_type, $QCoutdir, $DTIPrepProtocol) +Fetches the raw DWI datasets and foreach DWI, determines output names to be used +and stores them into a hash (C<$DTIrefs>). Will also print relevant information +in the log file. +INPUTS: + - $nativedir : native directory to look for native DWI dataset + - $DTI_volumes : number of volumes expected in the DWI dataset + - $t1_scan_type : the scan type name of the T1 weighted dataset + - $QCoutdir : directory to save processed files + - $DTIPrepProtocol: XML C protocol to use +RETURNS: undef if could not find any raw DWI dataset OR + - $DTIs_list: list of raw DTIs found + - $DTIrefs : a hash with the pre-processing output names and paths - - - - - -=pod -Fetch the raw DWI datasets and foreach DWI, determine output names to be used and store them into a hash ($DTIrefs). - -- Inputs: - $nativedir = native directory to look for native DWI dataset. - - $DTI_volumes = number of volumes expected in the DWI dataset. - - $t1_scan_type = the scan type name of the T1 weighted dataset. - - $QCoutdir = directory to save processed files. - - $DTIPrepProtocol= XML DTIPrep protocol to be used to process DWI datasets. - -- Outputs: - Will return undef if could not find any raw DWI dataset. - - Will return the list of raw DTIs found and a hash with the preprocessing output names and paths if raw DWI dataset was found. - - Will also print relevant information in the log file. =cut + sub fetchData { my ($nativedir, $DTI_volumes, $t1_scan_type, $QCoutdir, $DTIPrepProtocol, $protXMLrefs, $QCed2_step) = @_; @@ -412,21 +495,26 @@ sub fetchData { } +=pod +=head3 preprocessingPipeline($DTIs_list, $DTIrefs, $QCoutdir, $DTIPrepProtocol) +Function that creates the output folders, gets the raw DTI files, converts them +to NRRD and runs C using a C protocol and a C protocol. +INPUTS: + - $DTIs_list : list of DWI files to process for a given C + - $DTIrefs : hash with output file names & paths for the + different DWI to process + - $QCoutdir : output directory to save preprocessed files + - $DTIPrepProtocol: XML C protocol to use for pre-processing -=pod -Function that creates the output folders, get the raw DTI files, convert them to nrrd and run DTIPrep using a bcheck protocol and a nobcheck protocol. - -Inputs: - $DTIs_list = list of DWI datasets to preprocess through DTIPrep for a given candidate and visit. - - $DTIrefs = hash where all output file names and paths for the different DWI are stored. - - $QCoutdir = output directory to use to save preprocessed files. - - $DTIPrepProtocol= XML DTIPrep protocol to be used to preprocess the DWI dataset. +RETURNS: + - 1 if at least one raw DWI dataset was successfully preprocessed + - undef if pre-processing was not successful on a least one raw DWI dataset -Outputs: - Will return undef if preprocessing was not successful on a least one raw DWI dataset - - Will return 1 if at least one raw DWI dataset was successfully preprocessed =cut + sub preprocessingPipeline { my ($DTIs_list, $DTIrefs, $QCoutdir, $DTIPrepProtocol) = @_; @@ -473,18 +561,20 @@ sub preprocessingPipeline { } +=pod +=head3 preproc_mnc2nrrd($raw_nrrd, $dti_file) +Function that converts MINC raw DWI file to NRRD and logs the conversion status. +INPUTS: + - $raw_nrrd: raw NRRD file to create + - $dti_file: raw DWI file to convert to NRRD +RETURNS: 1 on success, undef on failure -=pod -Function that convert minc raw DWI file to nrrd and log the conversion status. -Inputs: - $raw_nrrd = Raw nrrd file to create - - $dti_file = Raw DWI file to convert to nrrd -Output: - Will return undef if conversion failed, - - Will return 1 if conversion is a success. =cut + sub preproc_mnc2nrrd { my ($raw_nrrd, $dti_file) = @_; @@ -501,18 +591,21 @@ sub preproc_mnc2nrrd { } +=pod +=head3 preproc_DTIPrep($QCed_nrrd, $raw_nrrd, $DTIPrepProtocol, $QCed2_nrrd) +This function will call C<&DTI::runDTIPrep> to run C on the raw NRRD file. +INPUTS: + - $QCed_nrrd : QCed DWI NRRD file to be created by C + - $raw_nrrd : raw DWI NRRD file to process through C + - $DTIPrepProtocol: C XML Protocol to use to run C + +RETURNS: 1 on success, undef on failure -=pod -This function will call DTI::runDTIPrep to run DTIPrep on the raw nrrd file. -Inputs: - $QCed_nrrd = QCed DWI nrrd file to be created by DTIPrep - - $raw_nrrd = Raw DWI nrrd file to process through DTIPrep - - $DTIPrepProtocol = DTIPrep XML Protocol to use to run DTIPrep -Output: - Will return 1 if QCed nrrd already exist - - Will return $DTIPrep_status if DTIPrep is run. (DTIPrep_status can be equal to 1 if DTIPrep ran successfully, or undef if something went bad while running DTIPrep). =cut + sub preproc_DTIPrep { my ($QCed_nrrd, $raw_nrrd, $DTIPrepProtocol, $QCed2_nrrd) = @_; @@ -528,19 +621,22 @@ sub preproc_DTIPrep { } +=pod +=head3 preproc_copyXMLprotocol($QCProt, $QCoutdir, $DTIPrepProtocol) +Function that will call C<&DTI::copyDTIPrepProtocol> if the XML protocol has +not already been copied in C QC directory. +INPUTS: + - $QCProt : copied QC XML protocol (in QC output folder) + - $QCoutdir : QC output directory + - $DTIPrepProtocol: C XML protocol used to run C +RETURNS: 1 on success, undef on failure -=pod -Function that will call DTI::copyDTIPrepProtocol if the XML protocol has not already been copied in DTIPrep QC outdir. -Inputs: - $QCProt = Copied QC XML protocol (in QC output folder) - - $QCoutdir = QC output directory - - $DTIPrepProtocol = DTIPrep XML protocol used to run DTIPrep -Output: - Will return 1 if XML protocol has already been copied - - Or will return $copyProt_status from DTI::copyDTIPrepProtocol (which will be either equal to 1 if copy was successful or undef if copy failed). =cut + sub preproc_copyXMLprotocol { my ($QCProt, $QCoutdir, $DTIPrepProtocol) = @_; @@ -556,22 +652,28 @@ sub preproc_copyXMLprotocol { } +=pod +=head3 check_and_convertPreprocessedFiles($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, $DTIPrepProtocol, $DTIPrepVersion) +This function will check pre-processing outputs and call +C<&convertPreproc2mnc>, which will convert and reinsert headers into MINC file. +INPUTS: + - $DTIs_list : list of raw DWI that were pre-processed + - $DTIrefs : hash with list of raw DTIs as a key & + corresponding output names as values + - $data_dir : directory containing raw DWI dataset + - $QCoutdir : directory containing preprocessed outputs + - $DTIPrepProtocol: C XML protocol used to run C + - $DTIPrepVersion : C version that was run to pre-process images +RETURNS: + - undef if could not find pre-processed files or convert them to MINC + - 1 if successful conversion & all pre-processing files found in the QC directory -=pod -This function will check preprocessing outputs and call convertPreproc2mnc, which will convert and reinsert headers into minc file. -Inputs: - $DTIs_list = list of raw DWI that were processed - - $DTIrefs = hash with list of raw DTIs as a key and corresponding output names as values - - $data_dir = directory containing raw DWI dataset - - $QCoutdir = directory containing preprocessed outputs - - $DTIPrepProtocol = DTIPrep XML protocol used to run DTIPrep - - $DTIPrepVersion = DTIPrep version that was run to preprocess images -Output: - Will return undef if could not find preprocessed files or convert it to minc. - - Will return 1 if conversion was a success and all preprocessing files were found in QC outdir. =cut + sub check_and_convertPreprocessedFiles { my ($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, $DTIPrepProtocol, $DTIPrepVersion) = @_; @@ -608,27 +710,30 @@ sub check_and_convertPreprocessedFiles { } +=pod +=head3 checkPreprocessOutputs($dti_file, $DTIrefs, $QCoutdir, $DTIPrepProtocol) +Checks if all pre-processing C files are in the output folder. They +should include: + - QCed NRRD file + - C QC text report + - C QC XML report + - a copy of the protocol used to run C +Relevant information will also be printed in the log file. +INPUTS: + - $dti_file : raw DWI file that was processed + - $DTIrefs : hash containing output names + - $QCoutdir : pre-processing output directory + - $DTIPrepProtocol: C XML protocol that was used to run C +RETURNS: undef if at least one output file is missing; 1 if all output files +were found - -=pod -Check if all Preprocessing DTIPrep files are in the output folder. -They should include: - QCed nrrd file - - DTIPrep QC text report - - DTIPrep QC xml report - - & a copy of the protocol used to run DTIPrep (QCProt) -Inputs: - $dti_file = raw DWI file that was processed - - $DTIrefs = hash containing output names - - $QCoutdir = preprocessing output directory - - $DTIPrepProtocol = DTIPrep XML protocol that was used to run DTIPrep -Output: - Will return 1 if all output files could be found - - Will return undef if at least one output file is missing. -Relevant information will also be printed in the log file. =cut + sub checkPreprocessOutputs { my ($dti_file, $DTIrefs, $QCoutdir, $DTIPrepProtocol) = @_; @@ -662,20 +767,23 @@ sub checkPreprocessOutputs { } +=pod +=head3 convertPreproc2mnc($dti_file, $DTIrefs, $data_dir, $DTIPrepVersion) +This function will convert to MINC DTI QCed NRRD file from C and reinsert +all MINC header information. +INPUTS: + - $dti_file : raw DWI file to be processed + - $DTIrefs : hash containing output names + - $data_dir : directory containing the raw dataset + - $DTIPrepVersion: C version used to pre-process raw DWI +RETURNS: 1 if QCed MINC file created and exists; undef otherwise -=pod -This function will convert to minc DTI QCed nrrd file from DTIPrep and reinsert all mincheader informations. -Inputs: - $dti_file = Raw DWI file to be processed - - $DTIrefs = Hash containing output names - - $data_dir = Directory containing the raw dataset - - $DTIPrepVersion = DTIPrep version used to preprocess raw DWI -Output: - Will return 1 if QCed minc file has been created or already exists - - Will return undef if QCed DWI was not successfully converted to minc =cut + sub convertPreproc2mnc { my ($dti_file, $DTIrefs, $data_dir, $DTIPrepVersion) = @_; @@ -713,27 +821,26 @@ sub convertPreproc2mnc { } +=pod +=head3 mincdiffusionPipeline($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, ...) +Running post-processing pipeline that will check if post-processing outputs +already exist. If they don't exist, it will call C<&runMincdiffusion> to run +the C tools. +INPUTS: + - $DTIs_list : list with raw DWI to post-process + - $DTIrefs : hash containing output names and paths + - $data_dir : directory hosting raw DWI dataset + - $QCoutdir : QC process output directory + - $DTIPrepProtocol: C XML protocol used to run C + - $mincdiffVersion: C version +RETURNS: 1 if all post-processing outputs found, undef otherwise - - - -=pod -Post processing pipeline will: - - check if post processing outputs already exists - - if no post-processed outputs, it will call &runMincdiffusion to run mincdiffusion tools -Inputs: - $DTIs_list = list with raw DWI to post-process - - $DTIrefs = hash containing output names and paths - - $data_dir = directory hosting raw DWI dataset - - $QCoutdir = QC process output directory - - $DTIPrepProtocol = DTIPrep XML protocol used to run DTIPrep - - $mincdiffVersion = mincdiffusion version -Output: - Will return undef if post-processing outputs could not be created - - Will return 1 if post-processing outputs was sucessfully created or already created =cut + sub mincdiffusionPipeline { my ($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, $DTIPrepProtocol, $mincdiffVersion, $niak_path) = @_; @@ -784,20 +891,21 @@ sub mincdiffusionPipeline { } +=pod +=head3 checkMincdiffusionPostProcessedOutputs($dti_file, $DTIrefs, $QCoutdir) +Function that checks if all outputs are present in the QC output directory. +INPUTS: + - $dti_file: raw DWI dataset to use as a key in C<$DTIrefs> + - $DTIrefs : hash containing output names + - $QCoutdir: QC output directory +RETURNS: 1 if all post processing outputs were found, undef otherwise - -=pod -Function that check if all outputs are present in the QC output directory. -Inputs: - $dti_file = raw DWI dataset to use as a key in $DTIrefs - - $DTIrefs = hash containing output names - - $QCoutdir = QC output directory -Output: - return 1 if all post processing outputs were found - - return undef if could not find all post processing outputs =cut + sub checkMincdiffusionPostProcessedOutputs { my ($dti_file, $DTIrefs, $QCoutdir) = @_; @@ -833,27 +941,23 @@ sub checkMincdiffusionPostProcessedOutputs { } +=pod +=head3 runMincdiffusionTools($dti_file, $DTIrefs, $data_dir, $QCoutdir, $mincdiffVersion) +Will create FA, MD and RGB maps. +INPUTS: + - $dti_file : raw DWI file that is used as a key in C<$DTIrefs> + - $DTIrefs : hash containing output names and paths + - $data_dir : directory containing raw datasets + - $QCoutdir : QC output directory + - $mincdiffVersion: C version used +RETURNS: 1 on success, undef on failure - - - - - - -=pod -Will create FA, MD and RGB maps. -Inputs: - $dti_file = raw DWI file that is used as a key in $DTIrefs - - $DTIrefs = hash containing output names and paths - - $data_dir = directory containing raw datasets - - $QCoutdir = QC output directory - - $mincdiffVersion = mincdiffusion version used -Output: - Return 1 if mincdiffusion pipeline was successful - - Return undef if at least one step of the mincdiffusion pipeline failed =cut + sub runMincdiffusionTools { my ($dti_file, $DTIrefs, $data_dir, $QCoutdir, $mincdiffVersion, $niak_path) = @_; @@ -916,16 +1020,26 @@ sub runMincdiffusionTools { } } + =pod -Function that loop through DTI files acquired for the candID and session to check if DTIPrep post processed nrrd files have been created and convert them to minc files with relevant header information. -- Inputs: - $DTIs_list = list of DTI files for the session and candidate - - $DTIrefs = hash containing all the reference for output naming for all DTIs - - $data_dir = directory containing the raw DTI dataset - - $QCoutdir = directory containing the processed data - - $DTIPrepVersion = Version of DTIPrep used to process the data -- Outputs: - Return 1 if nrrd files were found and converted to minc with the relevant minc header information - - Return undef otherwise with the error written to the log file + +=head3 check_and_convert_DTIPrep_postproc_outputs($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, $DTIPrepVersion) + +Function that loops through DTI files acquired for the C and session to +check if C post processed NRRD files have been created and converts them +to MINC files with relevant header information. + +INPUTS: + - $DTIs_list : list of DTI files for the session and candidate + - $DTIrefs : hash containing references for DTI output naming + - $data_dir : directory containing the raw DTI dataset + - $QCoutdir : directory containing the processed data + - $DTIPrepVersion: version of C used to process the data + +RETURNS: 1 on success, undef on failure + =cut + sub check_and_convert_DTIPrep_postproc_outputs { my ($DTIs_list, $DTIrefs, $data_dir, $QCoutdir, $DTIPrepVersion) = @_; @@ -958,20 +1072,23 @@ sub check_and_convert_DTIPrep_postproc_outputs { } +=pod +=head3 register_processed_files_in_DB($DTIs_list, $DTIrefs, $profile, $QCoutdir, $DTIPrepVersion, $mincdiffVersion) +Calls the script C to register processed files into the +database. +INPUT: + - $DTIs_list : list of native DTI files processed + - $DTIrefs : hash containing the processed filenames + - $profile : config file (in C<../dicom-archive/.loris_mri>) + - $QCoutdir : output directory containing the processed files + - $DTIPrepVersion : C version used to obtain QCed files + - $mincdiffVersion: C tool version used - -=pod -Calls the script DTIPrepRegister.pl to register processed files into the database. -Inputs: - $DTIs_list: list of native DTI files processed - - $DTIrefs: hash containing the processed filenames - - $profile: config file (a.k.a ./dicom-archive/.loris_mri/prod) - - $QCoutdir: output directory containing the processed files - - $DTIPrepVersion: DTIPrep version used to obtain QCed files - - $mincdiffVersion: mincdiffusion tool version used to obtain post-processing files =cut + sub register_processed_files_in_DB { my ($DTIs_list, $DTIrefs, $profile, $QCoutdir, $DTIPrepVersion, $mincdiffVersion) = @_; @@ -1000,3 +1117,16 @@ sub register_processed_files_in_DB { } +__END__ + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience + +=cut \ No newline at end of file diff --git a/Mincinfo_wrapper b/Mincinfo_wrapper deleted file mode 120000 index b01c91f17..000000000 --- a/Mincinfo_wrapper +++ /dev/null @@ -1 +0,0 @@ -uploadNeuroDB/bin/Mincinfo_wrapper \ No newline at end of file diff --git a/README.md b/README.md index 68623b1bb..cee7da501 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -This Readme covers release 19.0 of the LORIS Imaging Insertion Pipeline for Ubuntu or CentOS systems +This Readme covers release 20.0 of the LORIS Imaging Insertion Pipeline for Ubuntu or CentOS systems -This repo accompanies the [LORIS neuroimaging data platform main repo](https://github.com/aces/Loris/releases), release 19.0.*.
-For documentation and detailed setup information, please see the [LORIS wiki](https://github.com/aces/Loris/wiki/Imaging-Database). +This repo accompanies the [LORIS neuroimaging data platform main repo](https://github.com/aces/Loris/releases), release 20.0.*.
+For documentation and detailed setup information, please see the [LORIS-MRI documentation](docs/) for your installed version. This repo can be installed on the same VM as the main LORIS codebase, or on a different machine such as a designated fileserver where large imaging filesets are to be stored. @@ -66,10 +66,6 @@ Download the pre-compiled package for your operating system. Install required d Note: The installer will allow Apache to write to the /data/ directories by adding user lorisadmin to the Apache linux group. To ensure this change takes effect, log out and log back into your terminal session before running the imaging pipeline. The installer will also set Apache group ownership of certain /data/ subdirectories. - After having run the install script, it is possible to verify that certain - fields were correctly populated by `imaging_install.sh` (see - [section 2.4](02-Install.md#2.4-post-installation-checks)). - #### 4. Configure paths and environment Ensure that /home/lorisadmin/.bashrc includes the statement: @@ -78,8 +74,12 @@ The installer will also set Apache group ownership of certain /data/ subdirector Then source the .bashrc file. -
-Installation complete. +**INSTALLATION COMPLETE!** + +Please refer to the [Install](docs/02-Install.md) section in the +[LORIS-MRI documentation](docs/) for your installed version for: +- customizations and protocol configurations ([Section 2.2](docs/02-Install.md#configuration)). +- verifying that certain fields were correctly populated by `imaging_install.sh` +([Section 2.3](docs/02-Install.md#post-installation-checks)). -For customizations and protocol configurations, see LORIS Imaging Setup Guide : https://github.com/aces/Loris/wiki/Imaging-Database diff --git a/VERSION b/VERSION index 49e3587fb..e88320d7c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -19.0.0 +20.0.0 diff --git a/batch_uploads_imageuploader b/batch_uploads_imageuploader index 144bd514f..ad893af56 100755 --- a/batch_uploads_imageuploader +++ b/batch_uploads_imageuploader @@ -4,19 +4,18 @@ =head1 NAME -batch_uploads_imageuploader -- a script that runs imaging_upload_file.pl in +batch_uploads_imageuploader -- a script that runs C in batch mode =head1 SYNOPSIS -./batch_uploads_imageuploader -profile prod < list_of_scans.txt > log_batch_imageuploader.txt 2>&1 `[options]` +./batch_uploads_imageuploader -profile prod < list_of_scans.txt > log_batch_imageuploader.txt 2>&1 C[options]> Available options are: --profile : name of the config file in - C<../dicom-archive/.loris_mri> +-profile: name of the config file in C<../dicom-archive/.loris_mri> --verbose : if set, be verbose +-verbose: if set, be verbose =head1 DESCRIPTION @@ -274,9 +273,9 @@ close MAIL; Function that inserts into the C table entries for data coming from the list of scans in the text file provided when calling -batch_upload_imageuploader +C -INPUTS : +INPUTS: - $patientname : The patient name - $phantom : 'Y' if the entry is for a phantom, 'N' otherwise @@ -320,14 +319,6 @@ __END__ =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/batch_uploads_tarchive b/batch_uploads_tarchive index 84bf07fbf..74d260151 100755 --- a/batch_uploads_tarchive +++ b/batch_uploads_tarchive @@ -4,7 +4,8 @@ =head1 NAME -batch_uploads_tarchive - upload a batch of tarchives using script tarchiveLoader +batch_uploads_tarchive - upload a batch of DICOM archives using script +C =head1 SYNOPSIS @@ -12,38 +13,39 @@ batch_uploads_tarchive - upload a batch of tarchives using script tarchiveLoader =head1 DESCRIPTION -This script uploads a list of tarchive files to the database by calling script +This script uploads a list of DICOM archives to the database by calling script C on each file in succession. The list of files to process is read -from STDIN, one file name per line. Each file name is assumed to be a path relative -to C (see below). +from C, one file name per line. Each file name is assumed to be a path +relative to C (see below). The following settings of file F<$ENV{LORIS_CONFIG}/.loris-mri/prod> affect the -behvavior of batch_uploads_tarchive (where C<$ENV{LORIS_CONFIG}> is the value of -the Unix environment variable LORIS_CONFIG): +behvaviour of C (where C<$ENV{LORIS_CONFIG}> is the +value of the Unix environment variable C): =over 4 =item * -B : controls where the STDOUT and STDERR of each qsub command - (see below) will go, namely in +B : controls where the C and C of each qsub +command (see below) will go, namely in F<< $dataDirBasepath/batch_output/tarstdout.log >> and F<< $dataDirBasepath/batch_output/tarstderr.log >> - (where C<< >> is the index of the tarchive file processed, the first file having - index 1). + (where C<< >> is the index of the DICOM archive processed, the + first file having index 1). =item * -B: directory that contains the tarchive files to process. The path - of the files listed on STDIN should be relative to this directory. +B: directory that contains the DICOM archives to process. +The path of the files listed on C should be relative to this directory. =item * -B: whether the output (STDOUT) of each tarchiveLoader command should be - processed by the qsub Unix command (allows batch execution of jobs on the - Sun Grid Engine, if available). If set, then the qsub command will send its STDOUT - and STDERR according to the value of dataDirBasepath (see above). +B: whether the output (STDOUT) of each C command +should be processed by the C Unix command (allows batch execution of jobs +on the Sun Grid Engine, if available). If set, then the C command will +send its C and C according to the value of C +(see above). =item * B: upon completion of the script, an email will be sent to email address - $mail_user cointaining the list of files processed by batch_upload_tarchive + $mail_user containing the list of files processed by C =back @@ -70,10 +72,6 @@ The database hostname Code cleanup: remove unused C<-D> and C<-v> program arguments -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/concat_mri.pl b/concat_mri.pl deleted file mode 120000 index 45384ee42..000000000 --- a/concat_mri.pl +++ /dev/null @@ -1 +0,0 @@ -uploadNeuroDB/bin/concat_mri.pl \ No newline at end of file diff --git a/create.sql b/create.sql new file mode 100644 index 000000000..e69de29bb diff --git a/dicom-archive/DICOM/DCMSUM.pm b/dicom-archive/DICOM/DCMSUM.pm index 402c245b0..0960b004d 100644 --- a/dicom-archive/DICOM/DCMSUM.pm +++ b/dicom-archive/DICOM/DCMSUM.pm @@ -35,9 +35,11 @@ use NeuroDB::ExitCodes; Creates a new instance of this class. -INPUTS: DICOM directory, target location +INPUTS: + - $dcm_dir: DICOM directory + - $tmp_dir: target location -RETURNS: a DICOM::DCMSUM object +RETURNS: a C object =cut @@ -86,18 +88,18 @@ sub new { =pod -=head3 database($dbh, $meta, $update, $tarType, $tarLog, $DCMmd5, ...) +=head3 database($dbh, $meta, $update, $tarType, $tarLog, $DCMmd5, $Archivemd5, $Archive, $neurodbCenterName) -Inserts or updates the tarchive tables. +Inserts or updates the C tables. INPUTS: - $dbh : database handle - $meta : name of the .meta file - - $update : set to 1 to update tarchive entry, 0 otherwise + - $update : set to 1 to update C entry, 0 otherwise - $tarType : tar type version - $tarLog : name of the .log file - $DCMmd5 : DICOM MD5SUM - - $Archivemd5 : tarchive MD5SUM + - $Archivemd5 : DICOM archive MD5 sum - $Archive : archive location - $neurodbCenterName: center name @@ -431,7 +433,7 @@ QUERY =head3 read_file($file) -Reads the content of a file (typically .meta file in the tarchive). +Reads the content of a file (typically .meta file in the DICOM archive). INPUT: the file to be read @@ -782,10 +784,10 @@ sub fill_header { =head3 confirm_single_study() Confirms that only one DICOM study is in the DICOM directory to be archived. -Returns False if there is more than one StudyUID, otherwise it returns that -StudyUID. +Returns C if there is more than one C, otherwise it returns +that C. -RETURNS: StudyUID found in the DICOM directory, or false if more than one +RETURNS: C found in the DICOM directory, or C if more than one study was found =cut @@ -1149,9 +1151,10 @@ sub date_format { =head3 md5sum($filename) -Computes the MD5 sum of a file and outputs a format similar to md5sum on Linux. +Computes the MD5 sum of a file and outputs a format similar to C on +Linux. -INPUT: file name to use to computer MD5 sum +INPUT: file name to use to compute MD5 sum RETURNS: MD5 sum of the file @@ -1172,10 +1175,6 @@ sub md5sum { Fix comments written as #fixme in the code. -=head1 BUGS - -None reported. - =head1 LICENSING Copyright (c) 2006 by J-Sebastian Muehlboeck, McConnell Brain Imaging Centre, diff --git a/dicom-archive/DICOM/DICOM.pm b/dicom-archive/DICOM/DICOM.pm index 9fb5bf53b..06c05909e 100644 --- a/dicom-archive/DICOM/DICOM.pm +++ b/dicom-archive/DICOM/DICOM.pm @@ -1,12 +1,39 @@ -# DICOM.pm -# Andrew Crabb (ahc@jhu.edu), May 2002. -# Jonathan Harlap (jharlap@bic.mni.mcgill.ca) 2003 -# Perl module to read DICOM headers. -# TODO: add support for sequences (SQ) (currently being skipped) -# $Id: DICOM.pm 4 2007-12-11 20:21:51Z jharlap $ - package DICOM; +=pod + +=head1 NAME + +DICOM::DICOM -- Perl library that allows Perl programs to read the headers of +medical image files conforming to DICOM standards. + +=head1 SYNOPSIS + + use DICOM; + + my $dicom = DICOM->new(); + $dicom->fill($dicomFile); + my $patientName = $dicom->value('0010', '0010'); + +=head1 DESCRIPTION + +DICOM (Digital Imaging and Communications in Medicine) is a standard +designed to allow medical image files to be transferred, stored and +viewed on different makes of computers. Perl is a multi-platform +language that excels at system tasks such as file manipulation. It's +easy to learn, particularly if you are familiar with C or the Unix +shells and utility programs. + +This library provides the methods to read and parse a DICOM file, then +to recover the contents of each header element by their standard DICOM +group and element codes. Header element values can be edited (either +through the GUI or command line) and the modified file written back to +disk. + +=head2 Methods + +=cut + use strict; use vars qw($VERSION %dict); @@ -35,6 +62,17 @@ BEGIN { } } + +=pod + +=head3 new() >> (constructor) + +Creates a new instance of this class. + +RETURNS: a C object + +=cut + sub new { my $class = shift; @@ -44,7 +82,16 @@ sub new { return $elements; } -# Store and process the command line options from hash ref. + +=pod + +=head3 processOpts($href) + +Stores and process the command line options from hash ref. + +INPUT: a hash reference + +=cut sub processOpts { my $this = shift; @@ -61,7 +108,20 @@ sub processOpts { $this->write($outfile) if (defined($outfile)); } -# Fill in hash with header members from given file. + +=pod + +=head3 fill($infile, $big_endian_image) + +Fills in hash with header members from given file. + +INPUTS: + - $infile : file + - $big_endian_image: big endian image (optional) + +RETURNS: 1 if duplication, 0 on success + +=cut sub fill { my ($this, $infile, $big_endian_image) = @_; @@ -99,9 +159,18 @@ sub fill { return 0; } -# Write currently open file to given file name, or to current name -# if no new name specified. All fields before value are written -# verbatim; value field is stored as is (possibly edited). + +=pod + +=head3 write($outfile) + +Writes currently open file to given file name, or to current name if no new +name specified. All fields before value are written verbatim; value field +is stored as is (possibly edited). + +INPUT: file to write into + +=cut sub write { my ($this, $outfile) = @_; @@ -115,7 +184,16 @@ sub write { close(OUTFILE); } -# Print all elements, to disk if file handle supplied. + +=pod + +=head3 printContents($outfile) + +Prints all elements, to disk if file handle supplied. + +INPUT: file to print into + +=cut sub printContents { my ($this, $OUTFILE) = @_; @@ -134,7 +212,16 @@ sub printContents { } } -# Return sorted array of references to element arrays. + +=pod + +=head3 contents() + +Returns a sorted array of references to element arrays. + +RETURNS: sorted array of references + +=cut sub contents { my $this = shift; @@ -155,7 +242,18 @@ sub contents { return @all; } -# Set field index to sort by. Return 1 if new index, else 0. + +=pod + +=head3 setIndex($val) + +Sets field index to sort by. + +INPUT: value + +RETURNS: 1 if new index, else 0. + +=cut sub setIndex { my $this = shift; @@ -170,13 +268,35 @@ sub setIndex { return 1; } -# Return sort index. + +=pod + +=head3 getIndex() + +Returns the sort index. + +RETURNS: sort index + +=cut sub getIndex { return $sortIndex; } -# Return value of the element at (group, element). + +=pod + +=head3 value($gp, $el) + +Returns value of the element at (group, element). + +INPUTS: + - $gp: group + - $el: element + +RETURNS: value of the element + +=cut sub value { my $this = shift; @@ -186,8 +306,21 @@ sub value { return (defined($elem->value())) ? $elem->value() : ""; } -# Return field of given index from element. -# Params: Group, Element, Field index. + +=pod + +=head3 field($gp, $el, $fieldname) + +Returns field of given index from element. + +INPUTS: + - $gp : group + - $el : element + - $fieldname: field index + +RETURNS: field of given index from element + +=cut sub field { my $this = shift; @@ -197,10 +330,21 @@ sub field { return $elem->{$fieldname}; } -# Edit header value from string. -# String format: 'gggg,eeee=newvalue' or 'fieldname=newvalue'. -# gggg, eeee = group, element (in hex); XXXX = new value. -# fieldname = name of field from @dicom_fields. + +=pod + +=head3 editHeader($editstr) + +Edit header value from string. +String format: 'gggg,eeee=newvalue' or 'fieldname=newvalue'. + gggg, eeee = group, element (in hex); + fieldname = name of field from @dicom_fields. + +INPUT: string to edit + +RETURNS: undef unless group and element are defined + +=cut sub editHeader { my ($this, $editstr) = @_; @@ -219,7 +363,18 @@ sub editHeader { $this->setElementValue($gp, $el, $val); } -# Return group and element number of field with given name. + +=pod + +=head3 fieldByName($searchname) + +Returns group and element number of field with given name. + +INPUT: name of the field to search + +RETURNS: group and element number of field + +=cut sub fieldByName { my ($this, $searchname) = @_; @@ -238,7 +393,19 @@ sub fieldByName { return ($gp, $el); } -# Replace value of given element. + +=pod + +=head3 setElementValue($gp, $el, $newvalue) + +Replaces value of given element. + +INPUTS: + - $gp : group + - $el : element + - $newvalue: new value + +=cut sub setElementValue { my $this = shift; @@ -247,14 +414,34 @@ sub setElementValue { $elem->setValue($newvalue); } -# ------------------------------------------------------------ -# Utility Functions (non-public) -# ------------------------------------------------------------ + +# ------------------------------------------------------------------ +# Utility Functions (non-public) +# ------------------------------------------------------------------ + + +=pod + +=head3 hexadecimally() + + +=cut sub hexadecimally { hex($a) <=> hex($b); } + +=pod + +=head3 sortByField() + +Sort array of value by field. + +RETURNS: sorted array + +=cut + sub sortByField { my @aarr = @$a; my @barr = @$b; @@ -266,57 +453,35 @@ sub sortByField { } } -# Doesn't do anything in non-graphical case. -sub loop {} -1; -__END__ +=pod -=head1 NAME +=head3 loop() -DICOM.pm is a Perl library that allows Perl programs to read the -headers of medical image files conforming to DICOM standards. - -=head1 SYNOPSIS +Doesn't do anything in non-graphical case. - use DICOM; - my $dicom = DICOM->new(); - $dicom->fill($dicomFile); - my $patientName = $dicom->value('0010', '0010'); - -=head1 DESCRIPTION - -DICOM (Digital Imaging and Communications in Medicine) is a standard -designed to allow medical image files to be transferred, stored and -viewed on different makes of computers. Perl is a multiplatform -language that excels at system tasks such as file manipulation. It's -easy to learn, particularly if you are familiar with C or the Unix -shells and utility programs. - -This library provides the methods to read and parse a DICOM file, then -to recover the contents of each header element by their standard DICOM -group and element codes. Header element values can be edited (either -through the GUI or command line) and the modified file written back to -disk. - -=head2 Methods - -=over 4 +=cut -=item * $object->fill($filename) +sub loop {} -Fills the DICOM object with data from the file $filename +1; +__END__ -=back +=pod =head1 SEE ALSO The DICOM standard - http://medical.nema.org/ -=head1 AUTHOR +=head1 TO DO -Andrew Crabb, Eahc@jhu.eduE -Jonathan Harlap, Ejharlap@bic.mni.mcgill.caE +Add support for sequences (SQ) (currently being skipped) + +Better documentation for: + - setIndex() + - hexadecimally() -- non public? + - loop - doesn't do anything in non-graphical case. investigate if this + function is used, if not, remove =head1 COPYRIGHT AND LICENSE @@ -327,4 +492,13 @@ This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.0 or, at your option, any later version of Perl 5 you may have available. +License: GPLv3 + +=head1 AUTHORS + +Andrew Crabb, Eahc@jhu.eduE, +Jonathan Harlap, Ejharlap@bic.mni.mcgill.caE, +LORIS community and McGill Centre for Integrative Neuroscience + + =cut diff --git a/dicom-archive/DICOM/Element.pm b/dicom-archive/DICOM/Element.pm index 4d26faad1..1e5ed6653 100644 --- a/dicom-archive/DICOM/Element.pm +++ b/dicom-archive/DICOM/Element.pm @@ -1,20 +1,35 @@ -# Element.pm ver 0.3 -# Andrew Crabb (ahc@jhu.edu), May 2002. -# Element routines for DICOM.pm: a Perl module to read DICOM headers. -# $Id: Element.pm 4 2007-12-11 20:21:51Z jharlap $ - -# Each element is a hash with the following keys: -# group Group (hex). -# element Element within group (hex). -# offset Offset from file start (dec). -# code Field code eg 'US', 'UI'. -# length Field value length (dec). -# name Field descriptive name. -# value Value. -# header All bytes up to value, for easy writing. - package DICOM::Element; +=pod + +=head1 NAME + +DICOM::Element -- Element routines for C module + +=head1 SYNOPSIS + + use DICOM::Element; + + + +=head1 DESCRIPTION + +Element routines for C module to read binary DICOM headers. + +Each element is a hash with the following keys: + - group : group (hex) + - element: element within group (hex) + - offset : offset from file start (dec) + - code : field code eg 'US', 'UI' + - length : field value length (dec) + - name : field descriptive name + - value : value + - header : all bytes up to value, for easy writing + +=head2 Methods + +=cut + use strict; use DICOM::VRfields; use vars qw($VERSION %VR); @@ -38,17 +53,41 @@ BEGIN { } } + +=pod + +=head3 new() >> (constructor) + +Creates a new instance of this class. + +RETURNS: a C object + +=cut + sub new { my $type = shift; my $self = {}; return bless $self, $type; } -# Fill in self from file. + +=pod + +=head3 fill($IN, $dictref) + +Fills in C from file. + +INPUTS: + - $IN : input file + - $dictref : DICOM dictionary + +RETURNS: element hash + +=cut sub fill { my $this = shift; - my ($IN, $dictref, $big_endian_image) = @_; + my ($IN, $dictref) = @_; my %dict = %$dictref; #my ($group, $element, $offset, $code, $length, $name, $value, $header); my $vrstr; @@ -104,12 +143,26 @@ sub fill { return $this; } -# readInt(instream, bytelength, fieldlength). -# instream: Input file stream. -# bytelength: SHORT (2) or INT (4) bytes. -# fieldlength:Total number of bytes in the field. -# If fieldlength > bytelength, multiple values are read in and -# stored as a string representation of an array. + +=pod + +=head3 readInt($IN, $bytes, $len). + +Decodes one or more integers that were encoded as a string of bytes +(2 or 4 bytes per number) in the file whose handle is passed as argument. + +INPUTS: + - $IN : input file stream. + - $bytes: SHORT (2) or INT (4) bytes. + - $len : total number of bytes in the field. + +If C > C, multiple values are read in and stored as a +string representation of an array. + +RETURNS: string representation of the array of decoded integers + (e.g. '[34, 65, 900]') + +=cut sub readInt { my ($IN, $bytes, $len) = @_; @@ -132,6 +185,20 @@ sub readInt { return $val; } + +=pod + +=head3 writeInt($OUT, $bytes) + +Encodes each integer stored in string C<$this->{'value'}> as a 2 or 4 byte +string and writes them in a file + +INPUTS: + - $OUT : output file + - $bytes: number of bytes (2 for shorts 4 for integers) in the field + +=cut + sub writeInt { my ($this, $OUT, $bytes) = @_; my $val = $this->{value}; @@ -146,6 +213,24 @@ sub writeInt { } } + +=pod + +=head3 readFloat($IN, $format, $len) + +Decodes a floating point number that was encoded as a string of bytes in the +file whose handle is passed as argument. + +INPUTS: + - $IN : input file stream + - $format: format used when decoding (with Perl's C) the number: + C for floats and C for doubles + - $len : total number of bytes in the field + +RETURNS: string + +=cut + sub readFloat { my ($IN, $format, $len) = @_; my ($buff, $val); @@ -156,6 +241,31 @@ sub readFloat { return sprintf("%e", $val); } + +=pod + +=head3 readSequence($IN, $len) + +Skips over either a fixed number of bytes or over multiple sets of byte +sequences delimited with specific byte values. When doing the latter, +byte C<0x00000000> is used to signal the end of the set of sequences. +The sequence of bytes read is always discarded. + +Three different cases: + - implicit Value Representation (VR), explicit length + - explicit VR, undefined length, items of defined length (w/end delimiter) + - implicit VR, undefined length, items of undefined length + + +INPUTS: + - $IN : input file stream + - $len: total number of bytes to skip, or 0 if all sequences should be + skipped until the delimiter C<0x00000000> is found + +RETURNS: 'skipped' string + +=cut + sub readSequence { my ($IN, $len) = @_; my ($buff, $val); @@ -204,9 +314,20 @@ sub readSequence { } -# Return the Value Field length, and length before Value Field. -# Implicit VR: Length is 4 byte int. -# Explicit VR: 2 bytes hold VR, then 2 byte length. +=pod + +=head3 readLength($IN) + +Reads the length of a VR from a file, as an integer encoded on 16 or 32 bits. + - Implicit Value Representation (VR): Length is 4 byte int. + - Explicit VR: 2 bytes hold VR, then 2 byte length. + +INPUT: input file stream + +RETURNS: the VR code (string of length 2) and the length of the associated + VR value + +=cut sub readLength { my ($IN) = @_; @@ -272,7 +393,18 @@ sub readLength { return ($vrstr, $length); } -# Return the values of each field. + +=pod + +=head3 values() + +Returns the properties of a VR: group, element, offset, code, length, name and +value. + +RETURNS: the properties of a VR: group, element, offset, code, length, name and + value + +=cut sub values { my $this = shift; @@ -285,7 +417,14 @@ sub values { return @vals; } -# Print formatted representation of element to stdout. + +=pod + +=head3 print() + +Prints formatted representation of element to C. + +=cut sub print { my $this = shift; @@ -294,7 +433,17 @@ sub print { printf "(%04X, %04X) %s %6d: %-33s = %s\n", hex($gp), hex($el), $code, $len, $name, $val; } -# Return a string representation of the value field (null if binary). + +=pod + +=head3 valueString() + +Returns a string representation of the value field. + +RETURNS: string representation of the value field, or null if value field is + binary + +=cut sub valueString { my $this = shift; @@ -318,8 +467,17 @@ sub valueString { return $value; } -# Write this data element to disk. All fields up to value are stored in -# immutable field 'header' - write this to disk then value field. + +=pod + +=head3 write($OUTFILE) + +Writes this data element to disk. All fields up to value are stored in +immutable field 'header' - write this to disk then value field. + +INPUT: output file + +=cut sub write { my ($this, $OUTFILE) = @_; @@ -341,13 +499,33 @@ sub write { } } + +=pod + +=head3 value() + +Returns the value of the field. + +RETURNS: value field + +=cut + sub value { my $this = shift; return $this->{'value'}; } -# Set the value field of this element. Truncates to max length. + +=pod + +=head3 setValue($value) + +Sets the value field of this element. Truncates to max length. + +INPUT: value field + +=cut sub setValue { my $this = shift; @@ -357,6 +535,17 @@ sub setValue { $this->{'value'} = $value; } + +=pod + +=head3 byteswap($valref) + +Swaps byte. + +INPUT: value reference + +=cut + sub byteswap { my ($valref) = @_; @@ -373,3 +562,25 @@ sub byteswap { 1; __END__ +=pod + +=head1 TO DO + +Better documentation of the following functions: + - readInt() + - readFloat() + - readSequence($IN, $len) + - readLength($IN) + - writeInt($OUT, $bytes) + - byteswap($valref) + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience + +=cut diff --git a/dicom-archive/DICOM/Fields.pm b/dicom-archive/DICOM/Fields.pm index af278eadf..03abbae99 100644 --- a/dicom-archive/DICOM/Fields.pm +++ b/dicom-archive/DICOM/Fields.pm @@ -1,9 +1,62 @@ -# Definitions of fields of DICOM headers. -# Andrew Crabb (ahc@jhu.edu), May 2002. -# $Id: Fields.pm 4 2007-12-11 20:21:51Z jharlap $ - package DICOM::Fields; +=pod + +=head1 NAME + +DICOM::Fields -- Definitions of fields of DICOM headers. + +=head1 SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize dictionary. + # Read the contents of the DICOM dictionary into a hash by group and element. + # dicom_private is read after dicom_fields, so overrides common fields. + BEGIN { + foreach my $line (@dicom_fields, @dicom_private) { + next if ($line =~ /^\#/); + my ($group, $elem, $code, $numa, $name) = split(/\s+/, $line); + my @lst = ($code, $name); + $dict{$group}{$elem} = [@lst]; + } + } + + +=head1 DESCRIPTION + +Definitions of fields of DICOM headers. This file is provided purely for +experimental use. + +Simply creating an array of: + + 0000 0000 UL 1 GroupLength + 0000 0001 UL 1 CommandLengthToEnd + 0000 0002 UI 1 AffectedSOPClassUID + 0000 0003 UI 1 RequestedSOPClassUID + 0000 0010 CS 1 CommandRecognitionCode + 0000 0100 US 1 CommandField + 0000 0110 US 1 MessageID + 0000 0120 US 1 MessageIDBeingRespondedTo + 0000 0200 AE 1 Initiator + 0000 0300 AE 1 Receiver + 0000 0400 AE 1 FindLocation + 0000 0600 AE 1 MoveDestination + 0000 0700 US 1 Priority + 0000 0800 US 1 DataSetType + 0000 0850 US 1 NumberOfMatches + 0000 0860 US 1 ResponseSequenceNumber + 0000 0900 US 1 Status + 0000 0901 AT 1-n OffendingElement + 0000 0902 LO 1 ErrorComment + 0000 0903 US 1 ErrorID + ... + +=cut + + use strict; require Exporter; @@ -1921,3 +1974,18 @@ END_DICOM_FIELDS # 7Fxx 0020 OW 1-n VariableCoefficientsSDVN # 7Fxx 0030 OW 1-n VariableCoefficientsSDHN # 7Fxx 0040 OW 1-n VariableCoefficientsSDDN + + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience + +=cut + diff --git a/dicom-archive/DICOM/Private.pm b/dicom-archive/DICOM/Private.pm index a3d3e39aa..9f244dfcd 100644 --- a/dicom-archive/DICOM/Private.pm +++ b/dicom-archive/DICOM/Private.pm @@ -1,8 +1,42 @@ -# Definitions of (optional) private fields of DICOM headers. -# $Id: Private.pm 4 2007-12-11 20:21:51Z jharlap $ - package DICOM::Private; +=pod + +=head1 NAME + +DICOM::Private -- Definitions of (optional) private fields of DICOM headers. + +=head1 SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize dictionary. + # Read the contents of the DICOM dictionary into a hash by group and element. + # dicom_private is read after dicom_fields, so overrides common fields. + BEGIN { + foreach my $line (@dicom_fields, @dicom_private) { + next if ($line =~ /^\#/); + my ($group, $elem, $code, $numa, $name) = split(/\s+/, $line); + my @lst = ($code, $name); + $dict{$group}{$elem} = [@lst]; + } + } + +=head1 DESCRIPTION + +Definitions of (optional) private fields of DICOM headers. By default, none +are defined in the LORIS-MRI code base but users could define them here. + +Example format: + + 0000 0000 UL 1 GroupLength + ... + +=cut + + use strict; use vars qw(@ISA @EXPORT $VERSION @dicom_private); @@ -19,3 +53,16 @@ $VERSION = sprintf "%d", q$Revision: 4 $ =~ /: (\d+)/; # Example format: # 0000 0000 UL 1 GroupLength END_DICOM_PRIVATE + + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience + +=cut \ No newline at end of file diff --git a/dicom-archive/DICOM/VRfields.pm b/dicom-archive/DICOM/VRfields.pm index bcd18cfca..94d083738 100644 --- a/dicom-archive/DICOM/VRfields.pm +++ b/dicom-archive/DICOM/VRfields.pm @@ -1,9 +1,66 @@ -# VRfields.pm -# Andrew Crabb (ahc@jhu.edu), May 2002. -# $Id: VRfields.pm 4 2007-12-11 20:21:51Z jharlap $ - package DICOM::VRfields; +=pod + +=head1 NAME + +DICOM::VRfields -- Value Representations (DICOM Standard PS 3.5 Sect 6.2) + +=head1 SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize VR hash. + # Fill in VR definitions from DICOM_fields. + BEGIN { + foreach my $line (@VR) { + next if ($line =~ /^\#/); + my ($vr, $name, $len, $fix, $numeric, $byteswap) = split(/\t+/, $line); + $VR{$vr} = [($name, $len, $fix, $numeric, $byteswap)]; + } + } + +=head1 DESCRIPTION + +Value Representations (DICOM Standard PS 3.5 Sect 6.2) + - Bytes=0 => Undefined length. + - Fixed=1 => Exact field length, otherwise max length. + +Simply creating an array of DICOM Value Representations: + + Code Name Bytes Fixed Numeric ByteSwap + AE 'Application Entity' 16 0 0 0 + AS 'Age String' 4 1 0 0 + AT 'Attribute Tag' 4 1 0 1 + CS 'Code String' 16 0 0 0 + DA 'Date' 8 1 0 0 + DS 'Decimal String' 16 0 1 0 + DT 'Date Time' 26 0 0 0 + FL 'Floating Point Single' 4 1 1 1 + FD 'Floating Point Double' 8 1 1 1 + IS 'Integer String' 12 0 1 0 + LO 'Long Strong' 64 0 0 0 + LT 'Long Text' 10240 0 0 0 + OB 'Other Byte String' 0 0 0 0 + OW 'Other Word String' 0 0 0 1 + PN 'Person Name' 64 0 0 0 + SH 'Short String' 16 0 0 0 + SL 'Signed Long' 4 1 1 1 + SQ 'Sequence of Items' 0 0 0 0 + SS 'Signed Short' 2 1 1 1 + ST 'Short Text' 1024 0 0 0 + TM 'Time' 16 0 0 0 + UI 'Unique Identifier UID' 64 0 0 0 + UL 'Unsigned Long' 4 1 1 1 + UN 'Unknown' 0 0 0 0 + US 'Unsigned Short' 2 1 1 1 + UT 'Unlimited Text' 0 0 0 0 + +=cut + + use strict; use vars qw(@ISA @EXPORT $VERSION @VR); @@ -46,3 +103,18 @@ UN 'Unknown' 0 0 0 0 US 'Unsigned Short' 2 1 1 1 UT 'Unlimited Text' 0 0 0 0 END_VR + + +=pod + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience + +=cut + diff --git a/dicom-archive/dicomTar.pl b/dicom-archive/dicomTar.pl index 1ea485cc5..42628d8cd 100755 --- a/dicom-archive/dicomTar.pl +++ b/dicom-archive/dicomTar.pl @@ -23,18 +23,18 @@ =head1 SYNOPSIS -database : Use a database if you have one set up for you. Just trying will fail miserably --mri_upload_update : Update the mri_upload table by inserting the correct - tarchiveID +-mri_upload_update : Update the C table by inserting the + correct C -clobber : Specify the name of the config file which resides in - .loris_mri in the current directory + C<.loris_mri> in the current directory -centerName : Specify the symbolic center name to be stored alongside the DICOM institution -verbose : Be verbose if set --version : Print cvs version number and exit +-version : Print CVS version number and exit =head1 DESCRIPTION @@ -44,9 +44,9 @@ =head1 DESCRIPTION - If the source contains only one valid STUDY worth of DICOM it will create a descriptive summary, a (gzipped) DICOM tarball. The tarball with the metadata - and a logfile will then be retarred into the final TARCHIVE. + and a logfile will then be retarred into the final C. -- md5sums are reported for every step. +- MD5 sums are reported for every step. - It can also be used with a MySQL database. @@ -325,7 +325,7 @@ =head2 Methods =head3 archive_head() -Function that prints the tarchive header +Function that prints the DICOM archive header =cut @@ -366,9 +366,9 @@ =head3 read_file($file) Function that reads file contents into a variable -INPUT : $file : file to be read +INPUT: file to be read -RETURNS : $content : file contents +RETURNS: file contents =cut @@ -390,11 +390,7 @@ sub read_file { =head1 TO DO -Nothing planned. - -=head1 BUGS - -None reported. +Fix comments written as #fixme in the code. =head1 LICENSING diff --git a/dicom-archive/updateMRI_Upload.pl b/dicom-archive/updateMRI_Upload.pl index 3713d2727..cd4c97c62 100755 --- a/dicom-archive/updateMRI_Upload.pl +++ b/dicom-archive/updateMRI_Upload.pl @@ -65,15 +65,7 @@ =head1 DESCRIPTION If there already is an entry in C with the same C as C's, the script will exit with an error message saying that C is already up to date with respect to -C. - -=head1 TO DO - -Nothing. - -=head1 BUGS - -None reported. +C. =head1 LICENSING diff --git a/docs/01-Introduction.md b/docs/01-Introduction.md index 2069fb7be..7bfe540f7 100644 --- a/docs/01-Introduction.md +++ b/docs/01-Introduction.md @@ -1,6 +1,68 @@ # 1.0 - Introduction -## 1.1 What is LORIS? +### 1.1 What is LORIS-MRI? -## 1.2 How does LORIS work? +LORIS-MRI comprises the core libraries for loading and inserting imaging +data in LORIS. +It is maintained in a separate repository so that it can be installed +on the file server and separated from the web server. +These documents assume you have some knowledge regarding LORIS and +a functioning installation of the core LORIS codebase. For information +regarding LORIS itself, please consult the [LORIS wiki][1]. +LORIS-MRI is a set of libraries, scripts, and settings responsible for the +insertion, organization, and archiving of uploaded imaging datasets. +It expects an uploaded, compressed file containing +a [DICOM][2] scan session composed of many DICOM files. These DICOM files +will be archived on the server and converted to [MINC][3] and (optionally) +[NIfTI][4] files. Knowledge of these file formats can be helpful, but are not +necessary for using or installing LORIS-MRI. + +LORIS-MRI allows you to easily organize and archive your imaging datasets +and links them with corresponding behavioral data in LORIS. Scans can be viewed +and quality controlled in the LORIS front end via web browser, facilitating +collaboration between radiologists, clinicians and researchers. + +### 1.2 How does LORIS-MRI work? + +![user_story](images/user_story.png) + +LORIS-MRI allows multiple ways to upload scans, but typically, users +upload a compressed (.tgz, .tar.gz, or .zip) DICOM folder via the Imaging +Uploader module that should be composed of **only** DICOM files. LORIS requires +that the uploaded file name follow the naming convention +`PSCID_CANDID_VISIT-LABEL`. +In addition, all DICOM datasets uploaded via the Imaging Uploader or +transferred on the LORIS-MRI server must be free of any identifying +information (*e.g.* patient name). A tool can be provided to the sites to +facilitate de-identification. Please contact the LORIS team for details. + +The LORIS-MRI pipeline starts once the scans are uploaded to the server. +The pipeline can start automatically if the autolaunch configuration is +set, otherwise a back-end administrator can manually run the pipeline. +These options and scripts are detailed in the +[Pipeline Triggering Options documentation](05-PipelineLaunchOptions.md). + +Insertion progress can be tracked by the user through the Log Viewer in the +Imaging Uploader module, where descriptive messages can be consulted. +The output of the main key steps in the insertion progress can also be consulted +through: + - the LORIS DICOM Archive module for successfully archived DICOM datasets`*` + - the Imaging Browser module for MINC files (generated from DICOM) that pass the +study-defined MRI protocol`*` + - BrainBrowser using 3D or 4D navigation of these MINC files. More details on +BrainBrowser's capabilities can be found [here.][5] + +`*` Please note that all acquisitions are included in the DICOM archival +step. However, specific acquisitions (such as `localizers` or `scouts`) can be +excluded from the steps of the pipeline that start at, and follow the DICOM to +MINC conversion by specifying them in the `excluded_series_description` +field of the Config module (under the Imaging Pipeline section). Note that what +the series descriptions entered in that Config field need to be an exact match +of the series description DICOM field. + +[1]: https://github.com/aces/Loris/wiki +[2]: http://dicomiseasy.blogspot.ca/2011/10/introduction-to-dicom-chapter-1.html +[3]: https://en.wikibooks.org/wiki/MINC/Introduction +[4]: https://nifti.nimh.nih.gov/ +[5]: https://brainbrowser.cbrain.mcgill.ca/ diff --git a/docs/02-Install.md b/docs/02-Install.md index 01dabe03a..7abcfe956 100644 --- a/docs/02-Install.md +++ b/docs/02-Install.md @@ -6,7 +6,7 @@ Dependencies and installation information are documented on the LORIS-MRI [README.md](../README.md) file. -## 2.2 Configuration +## 2.2 Configuration Following a successful install, some configurations and customizations are needed and outlined in the next three sub-sections. @@ -32,64 +32,64 @@ If age is not a critical factor in study visit scheduling, define Min value as 0, and Max value as 2147483647 (maximum `int`). -Alternatively, LORIS provides a PHP script in its `tools/` directory -`populate_visit_windows.php` that can be used. +Alternatively, LORIS provides a PHP script called `populate_visit_windows.php` +in its `tools/` directory that can be used. 4. **`mri_scan_type`** and **`mri_protocol`** tables -Ensure your `mri_scan_type` and `mri_protocol` tables contains an entry for +Ensure your `mri_scan_type` and `mri_protocol` tables contain an entry for each type of scan in the study protocol. The `mri_protocol` table is used to identify incoming scans based on their -SeriesDescription **OR** scan parameter values (TE, TR, slice thickness, etc). +series description **OR** scan parameter values (TE, TR, slice thickness, etc). By default, this table is populated with entries for t1, t2, fMRI and DTI, and -the columns defining expected scan parameters (e.g. `TE_Range`) are defined very -broadly. +the columns defining expected scan parameters (*e.g.* `TE_Range`) are defined +very broadly. The `Scan_type` column values are defined in the `mri_scan_type` table -(e.g. 44=t1); do not include hyphens, spaces or periods in your +(*e.g.* 44=t1). Do not include commas, hyphens, spaces or periods in your `mri_scan_type.Scan_type` column values. 5. **`Config`** table The `Config` table can also be accessed and customized from the LORIS front-end -via the `Configuration` module, accessible under the Admin menu. Here are the +via the `Configuration` module, accessible under the `Admin` menu. Here are the configuration settings that impact directly or indirectly the pipeline: -Under the section `Study`: +Under the `Study` section: * `ImagingUploader Auto Launch`: Used by the Imaging Uploader to automatically launch the insertion scripts on the uploaded scan -Under the section `Paths` +Under the `Paths` section: * `Imaging Data`: Where the imaging data is stored; typically `/data/$PROJECT/data/` * `LORIS-MRI Code`: Where the MRI code base is installed; typically `/data/$PROJECT/bin/mri/` * `MRI-Upload Directory`: Where the uploaded scans get stored; typically `/data/incoming/` * `MINC Files`: Where the MINC images are stored; typically `/data/$PROJECT/data/` * `Images`: Where the images displayed in Imaging Browser are stored; typically `/data/$PROJECT/data/` - Under the section `Imaging Modules` + Under the `Imaging Modules` section: * `Patient ID regex`: Used by the DICOM Archive module to show/hide the PatientID info * `Patient name regex`: Used by the DICOM Archive module to show/hide the Patient Name info * `Lego phantom regex`: Used by the DICOM Archive module to show/hide the Patient Name info for phantoms * `Living phantom regex`: Used by the DICOM Archive module to show/hide the Patient Name info for phantoms - * `Imaging Browser Tabulated Scan Types`: Used by Imaging Browser main page which lists the different imaging sessions across candidates. This setting will determine which modalities will have their QC status displayed in that listing page + * `Imaging Browser Tabulated Scan Types`: Used by Imaging Browser's main page which lists the different imaging sessions across candidates. This setting will determine which modalities will have their QC status displayed in that listing page - Under the section `Imaging Pipeline` - * `Loris-MRI Data Directory`: Directory where imaging data is stored; typically `/data/$PROJECT/data/` + Under the `Imaging Pipeline` section: + * `LORIS-MRI Data Directory`: Directory where imaging data is stored; typically `/data/$PROJECT/data/` * `Study Name`: Prefix to be used in all filenames inserted into the `files` table and visible in the front-end via the Imaging Browser module * `User to notify when executing the pipeline`: User email address to be used when notification is to be sent by the pipeline * `Full path to get_dicom_info.pl script`: Typically `/data/$PROJECT/bin/mri/dicom-arhive/get_dicom_info.pl` * `Horizontal pictures creation`: Used to pass or not pass the argument `-horizontal` to `mincpik` when generating pictures to be displayed in Imaging Browser. * `NIfTI file creation`: Used to enable or disable automated NIfTI file creation - * `dcm2mnc binary to use when converting`: Allows the user to specify the binary file to be used when converting DICOM files to MINC. The default setting is to use the binary provided by the MINC tools, namely `dcm2mnc + * `dcm2mnc binary to use when converting`: Allows the user to specify the binary file to be used when converting DICOM files to MINC. The default setting is to use the binary provided by the MINC tools, namely `dcm2mnc` * `Path to Tarchives`: Directory where the original DICOMs are archived; typically `/data/$PROJECT/data/tarchive/` * `Upload creation of candidates`: Enable or disable candidate creation into LORIS when running the insertion pipeline * `Project batch management used`: Enable or disable batch management - * `If site is used`: Obsolete **To be confirmed**. This option used to allow the scans' incoming and archival paths to be configured based on the scanning sites * `Number of volumes in native DTI acquisitions`: Used by the DTIPrep pipeline * `Scan type of native T1 acquisition`: Name as specified in the `mri_scan_type` table. Used by the DTIPrep pipeline - * `Max number of DTI rejected directions for passing QC`: Number of directions that can be rejected and still pass QC. Used by the DTIPrep pipeline + * `Max number of DTI rejected directions for passing QC`: Maximum number of directions that can be removed from a DTI scan to pass QC. Used by the DTIPrep pipeline * `NIAK Path`: Path to NIAK if MINC diffusion is to be run. Used by the DTIPrep pipeline * `Secondary QCed dataset`: Path where a secondary QC'ed dataset is to be stored. Used by the DTIPrep pipeline - + * `excluded_series_description`: series descriptions to be excluded from the steps of the pipeline that start at, and follow the DICOM to MINC conversion. Note that the series description entered in that field need to be an exact match of what is present in the DICOM series description field. + * `ComputeDeepQC`: Enable or disable the automated computation of image quality control. Feature to be integrated in the code base in a **future** release. ### 2.2.2 LORIS @@ -97,7 +97,7 @@ Under the section `Paths` Projects can upload scans and launch the pipeline in a variety of options -detailed in [PipelineOptions](05-PipelineOptions.md). +detailed in the [PipelineLaunchOptions](05-PipelineLaunchOptions.md) section. Irrespective of the project's choice as to whether the imaging scan is to be uploaded through the Imaging Uploader GUI or not, pipeline insertion progress can be consulted through a live 'Log Viewer' panel. @@ -108,22 +108,23 @@ the [LORIS repository: Imaging Uploader Specification](https://github.com/aces/L 2. **DICOM Archive** -This LORIS module provides a front-end display of the details of the archived -DICOMs from the database `tarchive_*` tables. The only setting that impacts the -display of this module are the regex settings in the `Configuration` module -under the section `Imaging Modules`. These settings determine whether the +This LORIS module provides a front-end display with the details of the archived +DICOM study from the database `tarchive_*` tables. The only setting that +impacts the display of this module are the regex settings in the `Configuration` +module under the section `Imaging Modules`. These settings determine whether the Patient Name/Patient ID header values are displayed in full, or show up as **INVALID-HIDDEN**. More detailed specifications can be consulted in the -[LORIS repository: DICOM Archive Specification](https://github.com/aces/Loris/blob/master/modules/dicom_arhive/README.md). +[LORIS repository: DICOM Archive Specification](https://github.com/aces/Loris/blob/master/modules/dicom_archive/README.md). 3. **Imaging Browser** -Imaging Browser accesses the PIC images directly from the filesystem where they -are stored. It also provides the option to doownload some files. Ensure that: -- `/data/$PROJ` directory and subdirectories are readable and executable by +The Imaging Browser module accesses the screenshot (PIC) images directly from +the filesystem where they are stored. It also provides the option to download +some files. Ensure that: +- `/data/$PROJECT` directory and subdirectories are readable and executable by the Apache linux user. - the Configuration module (*Paths*) `Imaging data`, `MINC files` and `Images` settings are set (typically: `/data/$PROJECT/data/`). @@ -135,15 +136,15 @@ More detailed specifications can be consulted in the Brainbrowser displays the MINC images within the browser. It accesses those MINC images directly from the filesystem. Ensure that: -- `/data/$PROJ` directory and subdirectories are readable and executable by +- `/data/$PROJECT` directory and subdirectories are readable and executable by the Apache linux user. - the Configuration module (*Paths*) `MINC files` setting is - `/data/$PROJ/data/`. -- the _project/config.xml_ file (in the main LORIS codebase) contains the + `/data/$PROJECT/data/`. +- the `project/config.xml` file (in the main LORIS codebase) contains the proper MINC toolkit path in the `` tagset. More detailed specifications can be consulted in the -[LORIS repository:Brainbrowser Specification](https://github.com/aces/Loris/blob/master/modules/brainbrowser/README.md). +[LORIS repository: Brainbrowser Specification](https://github.com/aces/Loris/blob/master/modules/brainbrowser/README.md). 5. **MRI Violated Scans** @@ -153,11 +154,11 @@ Data loaded in this module gets populated automatically by the insertion scripts. As such, scans whose parameters can't be matched against the `mri_protocol` table during the imaging insertion process, will be flagged as protocol violations and will not have their MINC/NIfTI volumes loaded in the -database. The type of error (scan identification, protocol violation) will be -listed and can be reviewed from the front-end. +Imaging Browser module. Violated scans can be viewed and the type of error +(scan identification, protocol violation) can be reviewed from the front-end. More detailed specifications can be consulted in the -[LORIS repository:MRI Violated Scans Specification](https://github.com/aces/Loris/blob/master/modules/mri_violations/README.md). +[LORIS repository: MRI Violated Scans Specification](https://github.com/aces/Loris/blob/master/modules/mri_violations/README.md). ### 2.2.3 LORIS-MRI @@ -167,9 +168,12 @@ More detailed specifications can be consulted in the - `/data/*` subdirectories were created by the imaging install script. If not, it may be due to `root:root` ownership of the `/data/` mount on your system. Ensure these subdirectories are created manually, particularly: - `/data/$PROJ/data/*`, `/data/$PROJ/bin/mri/` and `/data/incoming/` + `/data/$PROJECT/bin/mri/`, `/data/incoming/`, and those inside + `/data/$PROJECT/data/`, namely `assembly`, `batch_output`, `logs`, + `pic`, `tarchive`, and `trashbin`. + -- `/data/$PROJ/` directory and subdirectories must be readable and executable +- `/data/$PROJECT/` directory and subdirectories must be readable and executable by the Apache linux user. It may also help to ensure the `/data/` mount is executable. After any modifications, ensure you restart apache. @@ -177,11 +181,11 @@ More detailed specifications can be consulted in the - `isFileToBeRegisteredGivenProtocol()` - * By default, any scan will be inserted if it matches an _mri_protocol_ + * By default, any scan will be inserted if it matches an `mri_protocol` table entry. - * To **whitelist/blacklist** specific scan types -- e.g. in the case of + * To **whitelist/blacklist** specific scan types -- *e.g.* in the case of protocol exclusion, case sensitivity or labelling variance -- modify the - subroutine, e.g.: + subroutine, *e.g.*: ```perl if($acquisitionProtocol eq 't1' or $acquisitionProtocol eq 't2' or $acquisitionProtocol eq 'dti' or $acquisitionProtocol eq 'bold' or $acquisitionProtocol =~ /fmri/) { return 1; } @@ -189,7 +193,7 @@ if($acquisitionProtocol eq 't1' or $acquisitionProtocol eq 't2' or $acquisitionP - `getSNRModalities()` - Routine to instruct the pipeline which 3-D modalities to include when + Routine to instruct the pipeline which 3D modalities to include when computing the signal-to-noise-ratio (SNR) on MINC images. - `getSubjectIDs()` @@ -199,14 +203,14 @@ if($acquisitionProtocol eq 't1' or $acquisitionProtocol eq 't2' or $acquisitionP - `filterParameters()` - Routine that takes in a file as an object and removes all parameters of lenngth > 1000 + Routine that takes in a file as an object and removes all parameters of length > 1000 -- `get_DTI_Site_CandID_Visit()` +- `get_DTI_CandID_Visit()` - Used for the DTIPrep pipeline + Used by the DTIPrep pipeline -## 2.3 Post-installation checks +## 2.3 Post-installation checks #### 2.3.1 Make sure the environment file is writable by Apache @@ -224,9 +228,9 @@ To ensure that BrainBrowser can load MINC images, the MINC toolkit must be installed on a separate machine, ensure the MINC toolkit is installed in both locations.) -Ensure the _project/config.xml_ file (in the main LORIS codebase) contains the +Ensure the `project/config.xml` file (in the main LORIS codebase) contains the following tagset, specifying the MINC toolkit path local to the main LORIS - codebase (/opt/minc/ in this example): + codebase (`/opt/minc/` in this example): ```xml @@ -235,38 +239,38 @@ Ensure the _project/config.xml_ file (in the main LORIS codebase) contains the #### 2.3.3. Verify filesystem permissions -Ensure that permissions on /data/$projectname and /data/incoming and their +Ensure that permissions on /data/$PROJECT and /data/incoming and their subdirectories are set such that lorisadmin and the Apache linux user can read, write _and_ execute all contents. -The following must be recursively owned by the lorisadmin user and by Apache +The following must be recursively owned by the lorisadmin user and Apache group: ```bash -/data/$projectname/data/ -/data/$projectname/bin/mri/ +/data/$PROJECT/data/ +/data/$PROJECT/bin/mri/ /data/incoming/ -/data/$projectname/bin/mri/dicom-archive/.loris_mri/prod +/data/$PROJECT/bin/mri/dicom-archive/.loris_mri/prod ``` #### 2.3.4 Verify Configuration module settings for Imaging Pipeline In the LORIS front-end, under the Admin menu, go to the `Config` module. Verify/set the following config settings (examples below illustrated for a project named `demo`): -Under the section `Imaging Pipeline`: - * `Loris-MRI Data Directory` (typically `/data/demo/data/`) +Under the `Imaging Pipeline` section: + * `LORIS-MRI Data Directory` (typically `/data/$PROJECT/data/`) * `Study Name` (`exampleStudy`; this name will be appended as a prefix to the filenames in LORIS' Imaging Browser) * `User to notify when executing the pipeline` - * `Full path to get_dicom_info.pl script`(typically `/data/demo/bin/mri/dicom-archive/get_dicom_info.pl`) - * `Path to Tarchives` (typically `/data/demo/data/tarchive/`) + * `Full path to get_dicom_info.pl script`(typically `/data/$PROJECT/bin/mri/dicom-archive/get_dicom_info.pl`) + * `Path to Tarchives` (typically `/data/$PROJECT/data/tarchive/`) -Under the section `Path`: - * `Imaging Data` (typically `/data/demo/data/`) - * `LORIS-MRI Code`(typically `/data/demo/bin/mri/`) - * `MINC files` (typically `/data/demo/data/`) - * `Images` (typically `/data/demo/data/`) +Under the `Path` section: + * `Imaging Data` (typically `/data/$PROJECT/data/`) + * `LORIS-MRI Code`(typically `/data/$PROJECT/bin/mri/`) + * `MINC files` (typically `/data/$PROJECT/data/`) + * `Images` (typically `/data/$PROJECT/data/`) -Click 'Submit' at the end of the Configuration page to save any changes. +Click `Submit` at the end of the Configuration page to save any changes. #### 2.3.5 Troubleshooting guideline diff --git a/docs/03-TechnicalInfrastructure.md b/docs/03-TechnicalInfrastructure.md index 39dfec511..2c326a700 100644 --- a/docs/03-TechnicalInfrastructure.md +++ b/docs/03-TechnicalInfrastructure.md @@ -4,39 +4,44 @@ ## 3.1 Back end directory structure The root directory of the imaging part of a LORIS instance is typically - `/data/project`. + `/data/$PROJECT`. ``` ## Imaging pipeline file directory structure / |__ data - |__ project + |__ incoming + |__ $PROJECT |__ bin | |__ mri |__ data |__ assembly - |__ incoming - |__ jiv + |__ batch_output |__ logs + |__ DTIPrep_pipeline* + |__ DTIPrep_register* |__ pic - |__ pipelines - |__ protocols |__ tarchive |__ trashbin + |__ pipelines* + |__ protocols* ``` +`*` _denotes optional directories that are not automatically created by the +install script. They are created when running the `DTIprep` pipeline_ + Within that project directory, there are typically two directories: - The `bin/mri` directory is a copy of all the imaging scripts downloaded from - the [GitHub Loris-MRI repository](https://github.com/aces/Loris-MRI). - Details about the content of this folder can be found in - [section 5](04-Scripts.md). + the [GitHub LORIS-MRI repository](https://github.com/aces/Loris-MRI). + Details about the content of this folder can be found in the + [script section](04-Scripts.md). - The `data` directory stores all the imaging-related data that will be created by the imaging scripts. The following subsections will describe the content of the different - subdirectories found under `/data/project/data`. + subdirectories found under `/data/$PROJECT/data`. #### The `assembly` directory @@ -50,7 +55,7 @@ The MINC images that can be viewed via BrainBrowser in the imaging browser `data/assembly/123456/V1/mri/native/project_123456_V1_T1W_001.mnc`. ``` -## Content of the /data/project/data/assembly directory +## Content of the /data/$PROJECT/data/assembly directory . |__ CandID |__ Visit @@ -74,39 +79,29 @@ Incoming scans from the Imaging uploader module (or automatic cron jobs) are datasets. -#### The `jiv` directory - -Jiv images produced by the imaging insertion pipeline are organized per - candidates in the `data/jiv` folder. - -``` -## Content of the /data/project/data/jiv directory -. -|__ CandID - |__ project_CandID_Visit_modality_number_fileid.header - |__ project_CandID_Visit_modality_number_fileid.raw_byte.gz -``` - - #### The `logs` directory -The logs of the scripts are created under `data/logs` in `/data/project`. +The logs of the scripts are created under `data/logs` in `/data/$PROJECT`. ``` -## Content of the /data/project/data/logs directory +## Content of the /data/$PROJECT/data/logs directory . -|__ TarLoad.log - |__ DTIPrep_pipeline - | |__ DTI_QC`date`.log - | |__ DTI_QC`date`.log - |__ DTIPrep_register - | |__ DTIregister`date`.log - | |__ DTIregister`date`.log - |__ registerProcessed - |__ registerProcessed`date`.log - |__ registerProcessed`date`.log +|__ TarLoad-`hh-mm-xxxxxx`.log +|__ DTIPrep_pipeline* +| |__ DTI_QC`date`.log +| |__ DTI_QC`date`.log +|__ DTIPrep_register* +| |__ DTIregister`date`.log +| |__ DTIregister`date`.log +|__ registerProcessed* + |__ registerProcessed`date`.log + |__ registerProcessed`date`.log ``` +`*` _denotes optional directories that are not automatically created by the +install script_ +`hh-mm-xxxxxx` _where_ `hh` _denotes the hour the insertion to the database +took place,_ `mm` _the minutes, and_ `xxxxxx` _a random alphanumeric string._ #### The `pic` directory @@ -114,7 +109,7 @@ The screenshots displayed in the imaging browser module for each modality is stored within the `data/pic` folder and organized per candidates. ``` -## Content of the /data/project/data/pic directory +## Content of the /data/$PROJECT/data/pic directory . |__ CandID |__ project_CandID_Visit_modality_number_fileid_check.jpg @@ -130,7 +125,7 @@ Processed incoming data or DTIPrep pipeline outputs are stored within pipelines are saved in the `data/protocols` directory. ``` -## Content of the /data/project/data/pipelines directory +## Content of the /data/$PROJECT/data/pipelines directory . |__ DTIPrep |__ DTIPrep_version @@ -142,7 +137,7 @@ Processed incoming data or DTIPrep pipeline outputs are stored within |__ file.mnc |__ file.nrrd -## Content of the /data/project/data/protocols directory +## Content of the /data/$PROJECT/data/protocols directory . |__ protocols |__ DTIPrep @@ -153,11 +148,11 @@ Processed incoming data or DTIPrep pipeline outputs are stored within #### The `tarchive` directory The DICOM archives listed in the DICOM archive module are stored in the - `data/tarchive` directory and organized folders representing the different - years of acquisition. + `data/tarchive` directory and organized within folders representing the + different years of acquisition. ``` -## Content of the /data/project/data/tarchive directory +## Content of the /data/$PROJECT/data/tarchive directory . |__ year_1 |__ DCM_`date`_tarchive.tar @@ -175,7 +170,7 @@ The scans that violates the established imaging protocol and listed in the MRI violated scans module are stored within the directory `data/trashbin`. ``` -## Content of the /data/project/data/trashbin directory +## Content of the /data/$PROJECT/data/trashbin directory . |__ Tarload-XX1 |__ file.mnc @@ -197,8 +192,8 @@ The database infrastructure is divided in six main components based on the ### 3.2.1 MRI upload table Summary information about the imaging upload status can be found in the - mri_upload table. This includes links to the DICOM archive tables (described - in the next section) and to the session table. It also includes summary + `mri_upload` table. This includes links to the DICOM archive tables (described + in the next section) and to the `session` table. It also includes summary information regarding the upload and the insertion process performed after the upload. @@ -211,75 +206,75 @@ The first step to insert a new imaging session into the database is the insertion of the DICOM study. In the database, all information related to a DICOM study is being organized into three different tables: - * the **_tarchive_** table stores information about the whole imaging session, + * the `tarchive` table stores information about the whole imaging session, including patient, scanner and study information, as well as the location of the archived DICOM dataset. Each row correspond to a specific imaging - session identified by the DICOM header _StudyUID_. - * the **_tarchive\_series_** table stores information about each modality that + session identified by the DICOM header `StudyUID`. + * the `tarchive_series` table stores information about each modality that was acquired during the imaging session (T1W, T2W...). This information include imaging parameters such as TR, TE, TI, slice thickness, sequence name... Each row corresponds to a different modality identified by the - DICOM header SeriesUID and EchoTime. This table is linked to the - _tarchive_ table via the _TarchiveID_ foreign key. - * the **_tarchive\_files_** table stores information about each DICOM found in + DICOM header `SeriesUID` and `EchoTime`. This table is linked to the + `tarchive` table via the `TarchiveID` foreign key. + * the `tarchive_files` table stores information about each DICOM found in the imaging session. Each row correspond to one DICOM file and is linked - to the _tarchive_ table via the _TarchiveID_ foreign key and to the - _tarchive\_series_ table via the _TarchiveSeriesID_ foreign key. + to the `tarchive` table via the `TarchiveID` foreign key and to the + `tarchive_series` table via the `TarchiveSeriesID` foreign key. ![tarchive_tables](images/tarchive_tables.png) In the front end of LORIS, you can see the DICOM studies using the _DICOM Archive_ module under the _Imaging_ tab. The information displayed in - this module comes from the three tarchive tables mentioned above. + this module comes from the three `tarchive` tables mentioned above. -Note: the SessionID field of the tarchive table is populated once at least one - MINC file derived from that DICOM study got inserted in the tables described - in 3.2.2. +Note: the `SessionID` field of the `tarchive` table is populated once at least + one MINC file derived from that DICOM study got inserted in the tables + described in 3.2.3. ### 3.2.3 Files tables The second step to insert a new imaging session into the database is the conversion of the DICOM study into the MINC files that will be inserted based - on the imaging protocol used. Having the dataset converted in MINC allow + on the imaging protocol used. Having the dataset converted in MINC allows visualization of the images directly in the browser. -Once all MINC files are created (via the dcm2mnc converter from the minctools), +Once all MINC files are created (via the `dcm2mnc` converter from the MINC tools), the backend scripts will pull the information stored in the following tables in order to identify the scan type each MINC file created: - * the **_mri\_scan\_type_** table stores the name of the scan type linked - along with the ID field that will be used to identify the scan type - * the **_mri\_protocol_** table stores each scan type's parameters that will + * the `mri_scan_type` table stores the name of the scan type linked + along with the `ID` field that will be used to identify the scan type + * the `mri_protocol` table stores each scan type's parameters that will be used to identify the scan type (TR, TE, TI, slice_thickness...) - * the **_mri\_protocol\_checks_** table stores additional protocol checks + * the `mri_protocol_checks` table stores additional protocol checks after an acquisition has been identified in order to automatically flag some acquisitions based on information stored in specific DICOM headers Every MINC file that matches the protocol defined in the tables mentioned above will be inserted in the database using the following tables: - * the **_files_** table contains the information about the MINC file itself + * the `files` table contains the information about the MINC file itself (its location, the identified scan type, the file type...). Each row - correspond a one MINC file identified by the SeriesUID and EchoTime + correspond to one MINC file identified by the `SeriesUID` and `EchoTime` header information. - * the **_parameter\_file_** table contains all the information stored in the + * the `parameter_file` table contains all the information stored in the MINC header. Each row in that table stores a combination of a specific - header for a specific MINC file. This table is linked to the _files_ - table using the foreign key _FileID_ and to the _parameter\_type_ - table using the foreign key _ParameterTypeID_. Note: The parameter type + header for a specific MINC file. This table is linked to the `files` + table using the foreign key `FileID` and to the `parameter_type` + table using the foreign key `ParameterTypeID`. Note: The `parameter_type` table is automatically populated with the insertion of the first MINC file in the database and stores the data dictionary for each MINC header field. - * the **_ImagingFileTypes_** table contains the different file format that - can be inserted into the _files_ table (.mnc, .txt, .xml...). The field - _type_ of the table _ImagingFileTypes_ is linked to the _FileType_ field - of the _files_ table. - * the **_mri\_scanner_** table contains information specific to the scanner + * the `ImagingFileTypes` table contains the different file format that + can be inserted into the `files` table (`.mnc`, `.txt`, `.xml`...). The + field `type` of the table `ImagingFileTypes` is linked to the `FileType` + field of the `files` table. + * the `mri_scanner` table contains information specific to the scanner used to obtain the images. By convention, each scanner is assigned a - candidate in the candidate table which is linked to the _mri\_scanner_ - table using the _CandID_ foreign key. In addition, the _ID_ field of the - _mri\_scanner_ table is linked to the _ScannerID_ field of the _files_ + candidate in the `candidate` table which is linked to the `mri_scanner` + table using the `CandID` foreign key. In addition, the `ID` field of the + `mri_scanner` table is linked to the `ScannerID` field of the `files` table. @@ -292,26 +287,26 @@ Once an image has been inserted into the database, it is possible to view it ### 3.2.4 MRI violation tables In the event a scan does not match any of the protocol mentioned in the - _mri_protocol_ table, LORIS automatically flags it as a violated scan. + `mri_protocol` table, LORIS automatically flags it as a violated scan. Below is the description of the different tables involved in the organization of such scans: - * the **_MRICandidateErrors_** table stores scans for which the _PSCID_ and - the _CandID_ fields stored in the PatientName of the DICOMs do not match - any of the registered candidates in the _candidate_ table. This is linked - to the _tarchive_ table via the _TarchiveID_ foreign key. - * the **_mri\_violations\_log_** table ***STORES SOMETHING BUT I DON'T - REMEMBER WHAT EXACTLY...*** - * the **_mri\_protocol\_violated\_scans_** table stores the violated scans' + * the `MRICandidateErrors` table stores scans for which the `PSCID` and + the `CandID` fields stored in the `PatientName` of the DICOMs do not match + any of the registered candidates in the `candidate` table. This is linked + to the `tarchive` table via the `TarchiveID` foreign key. + * the `mri_violations_log` table stores files for which a specific DICOM field + does not match the requirement specified in the `mri_protocol_checks` + * the `mri_protocol_violated_scans` table stores the violated scans' parameters (TR, TE, TI...) for easy identification of what is different between the violated scan and the imaging protocol specified in the - _mri\_protocol_ table. This table is linked to the tarchive table via - the _TarchiveID_ foreign key and to the candidate table via the _CandID_ - and _PSCID_ foreign keys. - * the **_violations\_resolved_** is linked to the three other tables mentioned - in this section. For each entry in that table, the _TypeTable_ field - allows to specify the table to link **_violations\_resolved_** to and the - _ExtID_ allows to specify the ID to use from the linked table. Below is a + `mri_protocol` table. This table is linked to the `tarchive` table via + the `TarchiveID` foreign key and to the `candidate` table via the `CandID` + and `PSCID` foreign keys. + * the `violations_resolved` is linked to the three other tables mentioned + in this section. For each entry in that table, the `TypeTable` field + allows to specify the table to link `violations_resolved` to and the + `ExtID` allows to specify the ID to use from the linked table. Below is a table illustrating this concept. | TableType | ExtID | @@ -328,14 +323,14 @@ In the _Imaging Browser_ module, it is possible to view the images via _BrainBrowser_ and directly perform quality control of the images. The quality control information is then stored in the following tables: - * the **_files\_qcstatus_** table stores the QC status of the MINC file and - is linked to the _files_ table via the _FileID_ foreign key. - * the **_feedback\_mri\_comments_** table stores all the comments associated + * the `files_qcstatus` table stores the QC status of the MINC file and + is linked to the `files` table via the `FileID` foreign key. + * the `feedback_mri_comments` table stores all the comments associated to a given scan. These comments can be predefined (from the table - **_feedback\_mri\_predefined\_comments_** or a text entered by the user - based on the comment type stored in **_feedback\_mri\_comment\_types_**). - * session level QC information are saved in the **_session_** table and - session level comments are saved in the **_feedback\_mri\_comments_** + `feedback_mri_predefined_comments` or a text entered by the user + based on the comment type stored in `feedback_mri_comment_types`). + * session level QC information are saved in the `session` table and + session level comments are saved in the `feedback_mri_comments` table. ![qc_tables](images/QC_tables.png) @@ -343,22 +338,22 @@ In the _Imaging Browser_ module, it is possible to view the images via ### 3.2.6 Processed data tables -Any native scan inserted into the files table can be processed and the output +Any native scan inserted into the `files` table can be processed and the output of this processing can be inserted into the database and linked to the native scan. For this, two additional tables require our attention (in light blue in the graphic below): - * the **_files\_intermediary_** table allows to link processed data with the - native datasets (our even intermediary outputs). The _Input\_FileID_ and - _Output\_FileID_ fields of that table are links to the _FileID_ field of - the _files_ table mentioned in section 3.2.2. Note that the native file - used to create processed outputs is always stored in the files table in - the _SourceFileID_ field, which is linked to the _FileID_ field of the + * the `files_intermediary` table allows to link processed data with the + native datasets (or even intermediary outputs). The `Input_FileID` and + `Output_FileID` fields of that table are links to the `FileID` field of + the `files` table mentioned in section 3.2.3. Note that the native file + used to create processed outputs is always stored in the `files` table in + the `SourceFileID` field, which is linked to the `FileID` field of the same table. - * the **_mri\_processing\_protocol_** table stores the imaging processing + * the `mri_processing_protocol` table stores the imaging processing protocols used to produce processed data. This table is linked to the - _files_ table using the _ProcessProtocolID_ foreign key. Additionally, - the field _FileType_ of the _mri\_processing\_protocol_ table is linked - to the _type_ field of the _ImagingFileTypes_ table. + `files` table using the `ProcessProtocolID` foreign key. Additionally, + the field `FileType` of the `mri_processing_protocol` table is linked + to the `type` field of the `ImagingFileTypes` table. -![processed_tables](images/Processed_data_tables.png) \ No newline at end of file +![processed_tables](images/Processed_data_tables.png) diff --git a/docs/04-Scripts.md b/docs/04-Scripts.md index 44fb0dce9..278cb8dc6 100644 --- a/docs/04-Scripts.md +++ b/docs/04-Scripts.md @@ -7,7 +7,7 @@ invited to consult the documentation - at the terminal by typing: ```angular2html -perldoc %SCRIPT_NAME% +perldoc %/PATH/TO/THE/SCRIPT/SCRIPT_NAME% ``` - in markdown format, on the [LORIS-MRI repository](../scripts_md/). @@ -83,7 +83,8 @@ Neuroscience ## 4.2 - Pipeline flow A very brief illustration of the key and expected outcomes at different steps in -the execution of the pipeline are shown below +the execution of the pipeline are shown below. + ![pipeline_flow](images/pipeline_schematic.png) This figure highlights the few @@ -109,10 +110,10 @@ uploadNeuroDB/minc_insertion.pl -acquisition_protocol t2w -bypass_extra_file_che Note carefully the following arguments: -- *acquisition_protocol*: must be a known scan type according to the +- `-acquisition_protocol`: must be a known scan type according to the `mri_scan_type` table -- *tarchive_Path*: the DICOM tarball -- *mincPath*: note this file may have been placed in the `trashbin` directory +- `-tarchive_Path`: the DICOM tarball +- `-mincPath`: note this file may have been placed in the `trashbin` directory See also: [MRI-PR#141](https://github.com/aces/Loris-MRI/pull/141) for more examples. @@ -120,13 +121,13 @@ See also: [MRI-PR#141](https://github.com/aces/Loris-MRI/pull/141) for more #### Rerunning the Imaging pipeline - If one of the final steps such as the MINC conversion is failing, you may - wish to just re-run the tarchiveLoader script. + wish to just re-run the `tarchiveLoader` script. > When the need arises to re-load imaging data in LORIS, it is generally not sufficient to just re-run the MINC/NIfTI loading step (`tarchiveLoader` or `batch_uploads_tarchive`). The pipeline steps must be re-run starting - with dicomTar.pl (see section 5.4 of - [Pipeline triggering options](05-PipelineOptions.md)). + with `dicomTar.pl` (see section 5.4 of + [Pipeline Triggering Options documentation](05-PipelineLaunchOptions.md)). In general, to re-load an imaging dataset through the pipeline from the start (from `dicomTar.pl`) -- Ensure entries from the previous attempt to load the @@ -137,12 +138,12 @@ In general, to re-load an imaging dataset through the pipeline from the start - `files` (best to delete from this table last) - `mri_upload` - `session` - not recommended - only if necessary, and only if no other data is - associated to this session e.g. on the Behavioural side of Loris. + associated to this session (*e.g.* on the Behavioural side of LORIS). - `tarchive` -It is also recommended to remove from the tarchive directory the last generated +It is also recommended to remove from the `tarchive` directory the last generated `*.tar` package for this dataset, as well as files in the `assembly/`, `pic/`, - `jiv/`, and `trashbin/` directories. + and `trashbin/` directories. If any Quality Control flags or comments exist for these scans, you may also wish to delete specific records from `files_qcstatus` and the `mri_feedback_*` @@ -155,6 +156,7 @@ For backing up, re-labelling and re-loading MRI datasets with QC information, In cases where a subject was scanned in two scanner sessions as part of the same study Timepoint, anonymize both DICOM datasets using the same Visit Label in - the PatientName (or PatientID), and upload as two separate DICOM datasets. The - insertion pipeline will automatically associate and display both sets of - images acquired in both scanner sessions under the same `session` table record. + the Patient Name (or Patient ID) field of the DICOM, and upload as two + separate DICOM datasets. The insertion pipeline will automatically + associate and display both sets of images acquired in both scanner sessions + under the same `session` table record. diff --git a/docs/05-PipelineLaunchOptions.md b/docs/05-PipelineLaunchOptions.md index 0ea90d5f5..23d235881 100644 --- a/docs/05-PipelineLaunchOptions.md +++ b/docs/05-PipelineLaunchOptions.md @@ -34,7 +34,7 @@ uploadNeuroDB/imaging_upload_file.pl -profile prod -upload_id $UploadIDID /PATH/ ``` where `$UploadID` is the number corresponding to the `UploadID` column in the -Imaging Uploader table, and `/PATH/TO/UPLOAD/` is typically the +Imaging Uploader (`mri_upload`) table, and `/PATH/TO/UPLOAD/` is typically the `/data/incoming/` directory. This is a typical option for a project prospectively collecting data with @@ -68,12 +68,12 @@ pre-scheduled times, as per the project's requirements). The insertion pipeline can also be triggered using the command: ``` -./batch_uploads_imageuploader -profile prod < scans_list.txt >log_batch_imageuploader.txt 2>&1 +./batch_uploads_imageuploader -profile prod < scans_list.txt > log_batch_imageuploader.txt 2>&1 ``` This is an option that addresses retrospectively collected data where uploading -hundreds of scans, one scan at a time, using the LORIS Imaging Uploader a +hundreds of scans, one scan at a time, using the LORIS Imaging Uploader user-friendly interface is impractical. It is also the option of choice for prospective studies that want to benefit from tracking scans through the Imaging Uploader while automating the upload and insertion process without a user/GUI @@ -89,7 +89,7 @@ by spaces: 1. the full path to the zipped DICOM dataset (`.zip`, `.tgz`, `.tar.gz`), 2. Y or N depending on whether the scan is for a phantom or not, and -3. the patient name following the PSCID_CandID_VisitLabel LORIS convention for +3. the patient name following the `PSCID_CandID_VisitLabel` LORIS convention for real candidates. Leave BLANK for phantoms. diff --git a/docs/AppendixA-Troubleshooting_guideline.md b/docs/AppendixA-Troubleshooting_guideline.md index a76be3e8f..515ebb22c 100644 --- a/docs/AppendixA-Troubleshooting_guideline.md +++ b/docs/AppendixA-Troubleshooting_guideline.md @@ -12,7 +12,7 @@ _**Table 1: Common errors encountered during LORIS-MRI installation, and their p |:------|:------|:----------| |`install_driver(mysql) failed: Can't locate DBD/mysql.pm`|Missing dependency|`sudo apt-get install libdbd-mysql-perl`| |`ERROR: You don't have a configuration file named 'prod' in: /data/%PROJECT%/bin/mri/dicom-archive/.loris_mri/`| Your `environment` file does not contain your actual LORIS-MRI project name. Instead, it contains the placeholder `%PROJECT%` as provided in the 'generic' file and/or your `environment` file is not sourced| Source the environment file located in `/data/$PROJECT/bin/mri/` after making sure that the `$PROJECT` variable is replaced with your LORIS-MRI project name| -|`ERROR: You don't have a configuration file named 'prod' in: /data/loris-MRI/bin/mri/dicom-archive/.loris_mri/` *note*: `loris-MRI` is an example project name used in this illustration| Wrong file and/or directory permissions| Make sure that the `/data/loris-MRI/bin/mri` directory, and all directories within are readable by the user running the scripts (`lorisadmin` or the front-end `apache` user)| +|`ERROR: You don't have a configuration file named 'prod' in: /data/loris-MRI/bin/mri/dicom-archive/.loris_mri/` *note*: `loris-MRI` is an example project name used in this illustration| Wrong file and/or directory permissions| Make sure that the `/data/$PROJECT/bin/mri` directory, and all directories within are readable by the user running the scripts (`lorisadmin` or the front-end `apache` user)| |`ERROR: You don't have a configuration file named 'prod' in: /data/loris-MRI/bin/mri/dicom-archive/.loris_mri/` *note*: `loris-MRI` is an example project name used in this illustration| Syntax error in the `prod` file in the customized routines (for example a missing closing bracket)| Check the routines that were customized for your project needs| |`DB connection failed`| Database credentials in the `prod` file were entered incorrectly during the install, or they were modified subsequently| Make sure that your `prod` file contains the correct database connection/credentials information in the `DATABASE Settings, Section I`| @@ -23,7 +23,7 @@ _**Table 2: Common errors encountered due to missing LORIS (front-end) module se |:------|:------|:----------| |Images thumbnails do not show up in Imaging Browser. They appear as a broken image icon|Wrong permissions to the `/data/$PROJECT/data/pic/` folder|Ensure that the `apache` user can read/execute the `pic` images folder| |Images thumbnails do not show up in Imaging Browser. They appear as a broken image icon|Wrong `Images` path under the `Paths` section in LORIS Configuration module|Ensure the path to the images is correct, typically `/data/$PROJECT/data/`| -|4-D images (e.g. DTI, fMRI) in brainbrowser do not show any volumes (Play button not displayed)|Most likely a dcm2mnc conversion error|Post an issue on the [minc-toolkit Github Issues page](https://github.com/BIC-MNI/minc-toolkit/issues)| +|4-D images (*e.g.* DTI, fMRI) in brainbrowser do not show any volumes (Play button not displayed)|Most likely a dcm2mnc conversion error|Post an issue on the [minc-toolkit Github Issues page](https://github.com/BIC-MNI/minc-toolkit/issues)| |Brainbrowser says `Loading…` but no image shows up|Wrong permissions to the `/data/$PROJECT/data/assembly/` folder|Ensure that the apache user can read/execute the MINC `assembly` images folder| |Brainbrowser says `Loading…` but no image shows up|Wrong `Images` path under the `Paths` section in LORIS Configuration module|Ensure the path to the MINC images is correct, typically `/data/$PROJECT/data/`| |Brainbrowser says `Loading…` but no image shows up|The `config.xml` in LORIS does not have the MINC Toolkit Path set properly|Fill out the path `` to the MINC Toolkit Installation in the `config.xml` (on the LORIS side). The last trailing `/` in the path is mandatory| @@ -35,14 +35,14 @@ _**Table 3: Common errors encountered during execution of the LORIS-MRi insertio |:------|:------|:----------| |`The Candidate info validation has failed`|PatientName/PatientID header in the DICOMs not anonymized according to the LORIS convention `(PSCID_CandID_VisitLabel)`|Use [DICAT](https://github.com/aces/DICAT) to anonymize it properly OR Use the DICOM toolkit `dcmodify` command. The following one-line command (to be run from the folder where the DICOM files are) which anonymizes your entire folder of DICOM files is: `for i in $(find -type f); do dcmodify -ma PatientName="PSCID_CandID_VisitLabel" -nb $i; done`| |`The Candidate info validation has failed`|The upload scan contains at least one file that is NOT of type DICOM (.bmp or .pdf are common)|Remove any file in the upload that is not of type DICOM| -|`... error message = 'No space left on device ...'`|The temporary directory where the insertion scripts peform its intermediate steps is full. This directory is set to a default value of `/tmp` as specified in the line `export TMPDIR=/tmp` of the `environment` file |Change the `TMPDIR` path in the environment file to a directory with enough space. A good rule of thumb is to have at least 2-3 times the size of the scan being processed as writable space. This space is usually automatically emptied by the pipeline upon a successful execution| +|`... error message = 'No space left on device ...'`|The temporary directory where the insertion scripts perform its intermediate steps is full. This directory is set to a default value of `/tmp` as specified in the line `export TMPDIR=/tmp` of the `environment` file |Change the `TMPDIR` path in the environment file to a directory with enough space. A good rule of thumb is to have at least 2-3 times the size of the scan being processed as writable space. This space is usually automatically emptied by the pipeline upon a successful execution| |`ERROR: This class is designed around the notion of a 'Study'. You can't use it with data from multiple studies. The following study UIDs were found: '1.3.12.2.1107.66060.300000004' '1.3.12.2.1107.66060.300000007' The dicomTar execution has failed`|The upload contains acquisitions from two scanning sessions|Separate into two separate uploads| -|`Out of memory!` during the execution of `dicomTar.pl`|The Transfer syntax of the uploaded scan is other than Little Endian Explicit (such as Implicit or JPEG lossless)|Use the DICOM toolkit `dcmconv` to convert. An example command that changes the transfer syntax to Little Endian Explicit on all DICOM files within a given folder is: `for i in $(find -type f); do dcmconv --write-xfer-little $i $i; done`| -|`Number of MINC files that will be considered for inserting into the database: 0. No data could be converted into valid MINC files. Localizers will not be considered!`|The upload contains only ‘localizer’ type SeriesDescription|Localizers are not processed by default in LORIS| -|My uploaded DICOM study contains 6 modalities but only 5 were inserted. The 6th modality was not converted to MINC, neither inserted into the MRI Violated Scans module. In addition, during insertion, the message `Number of MINC files that will be considered for inserting into the database: 5` is displayed, confirming that only 5 files are considered|The missing modality is probably a `localizer` acquisition. `tarchiveLoader` is specifically 'instructed' to exclude this modality|No action needed. This is the expected behavior of the LORIS-MRI insertion pipeline| +|`Out of memory!` during the execution of `dicomTar.pl`|The Transfer syntax of the uploaded scan is other than Little Endian Explicit (such as Big endian, Little Endian Implicit or JPEG lossless)|First run `dcmdump` on one of the DICOM files within your archive. Look for the value of the tag `TransferSyntaxUID`. If it is of the form `JPEGLossless*` you will have to convert all the DICOM files in your archive so that the transfer syntax becomes Little Endian Explicit. You can use `dcmdjpeg` to do so, with a command like `dcmdjpeg file.dcm file.dcm` for each file. For those files with a transfer syntax other than `JPEGLossless*`, use the DICOM toolkit `dcmconv` to convert. An example command that changes the transfer syntax to Little Endian Explicit on all DICOM files within a given folder is: `for i in $(find -type f); do dcmconv --write-xfer-little $i $i; done`| +|`Number of MINC files that will be considered for inserting into the database: 0. No data could be converted into valid MINC files.` Your project's excluded series descriptions `will not be considered!`|The upload contains only acquisitions that have `SeriesDescription` which are excluded by the project|Projects can specify what acquisitions' `SeriesDescription` are not to be processed by default in LORIS| +|My uploaded DICOM study contains 6 modalities but only 5 were inserted. The 6th modality was not converted to MINC, neither inserted into the MRI Violated Scans module. In addition, during insertion, the message `Number of MINC files that will be considered for inserting into the database: 5` is displayed, confirming that only 5 files are considered|The missing modality is probably matching one of the excluded series descriptions set in the Config Module under the Imaging Pipeline section. `tarchiveLoader` is specifically 'instructed' to exclude those modalities|Make sure these excluded series descriptions have correctly been set (note, they need to be entered as an exact match to what is present in the DICOM file)| |My uploaded DICOM study contains 6 modalities but only 5 were inserted. The 6th modality was not converted to MINC, neither inserted into the MRI Violated Scans module. In addition, during insertion, the message `Number of MINC files that will be considered for inserting into the database: 5` is displayed, confirming that only 5 files are considered|Probably the DICOM headers have blank SeriesNumber. LORIS-MRI generates MINC files and names them temporarily (in intermediate insertion steps) based on their SeriesNumber, before it proceeds to renaming them once the protocol is identified from the `mri_protocol` table. Having no SeriesNumber defaults to `0`, causing overwrites on the intermediate MINC files generated|Ensure that your DICOM headers include a non-blank SeriesNumber for every acquisition in that specific study| |`The target directory does not contain a single DICOM file`|Probably the DICOM headers have blank StudyUID. The logic of insertion within LORIS-MRI depends on a StudyUID header|Ensure that your DICOM headers include a non-blank StudyUID header| -|My resting-state fMRI scans are tagged as task fMRI although I have 2 entries in the `mri_protocol` table|The resting-state scan has parameters that match those of the task entry of the `mri_protocol` table, and the task-related entry in the `mri_protocol` table precedes that of the resting-state fMRI|Make sure the `mri_protocol` table has parameters that discern between all the study acquired modalities in an **exclusive** manner (i.e. no two row entries have overlapping parameters across all their columns)| +|My resting-state fMRI scans are tagged as task fMRI although I have 2 entries in the `mri_protocol` table|The resting-state scan has parameters that match those of the task entry of the `mri_protocol` table, and the task-related entry in the `mri_protocol` table precedes that of the resting-state fMRI|Make sure the `mri_protocol` table has parameters that discern between all the study acquired modalities in an **exclusive** manner (*i.e.* no two row entries have overlapping parameters across all their columns)| |`no MINCs inserted`|Possibly all the MINC images are violated scans|Check the details of the image headers (from the MRI Violated Scans module or using `mincheader`) against the `mri_protocol` table entries, and adjust the table protocol parameters accordingly| @@ -52,8 +52,8 @@ Key configuration points to verify: - Depending on your operating system, some dependencies might be missing. During initial troubleshooting of the imaging pipeline, note any related - error messages (e.g. `install_driver(mysql) failed: Can't locate DBD/mysql - .pm`) and install missing packages as needed (e.g. + error messages (*e.g.* `install_driver(mysql) failed: Can't locate DBD/mysql + .pm`) and install missing packages as needed (*e.g.* `sudo apt-get install libdbi-perl`, `sudo apt-get install libdbd-mysql-perl`, `sudo apt-get install libarchive-zip-perl`). @@ -72,22 +72,22 @@ Verify in the Imaging Browser's View Session page that a `jpg` showing 3 slice orientations displays properly; if not, verify your permissions and restart apache: ``` -sudo chmod o+r /data/$PROJ/bin -sudo chmod o+r /data/$PROJ/data +sudo chmod o+r /data/$PROJECT/bin +sudo chmod o+r /data/$PROJECT/data sudo service apache2 restart ``` -If download links do not work, ensure that the `/data/$PROJ/data/assembly` +If download links do not work, ensure that the `/data/$PROJECT/data/assembly` directory and subdirectories are executable. ### A.3 Logs troubleshooting notes Error and output messages from the imaging insertion scripts are logged in files - created under the `/data/$PROJ/data/logs/` directory. To view messages from + created under the `/data/$PROJECT/data/logs/` directory. To view messages from the last script run, consult the most recent log file modified in this - directory. These log files reference an *uploadID* used to identify each + directory. These log files reference an `uploadID` used to identify each imaging dataset -- consult the `mri_upload` database table to look up which - uploadID has been assigned to your scans. + `uploadID` has been assigned to your scans. ***Caveat:*** When the imaging insertion pipeline is auto-launched by the Imaging Uploader module, the pipeline scripts' log files are output to @@ -100,7 +100,7 @@ Error and output messages from the imaging insertion scripts are logged in files If upload was successful but issues were encountered with the imaging insertion pipeline scripts: -- CentOS: check for additional dependencies/configurations (e.g. DICOM +- CentOS: check for additional dependencies/configurations (*e.g.* DICOM Dictionary path) in the detailed [CentOS Imaging Installation transcript](https://github.com/aces/Loris/wiki/CentOS-Imaging-installation-transcript) - Manually re-run the entire pipeline sequence using the diff --git a/docs/images/user_story.png b/docs/images/user_story.png new file mode 100644 index 000000000..842cb563c Binary files /dev/null and b/docs/images/user_story.png differ diff --git a/docs/scripts_md/BackPopulateSNRAndAcquisitionOrder.md b/docs/scripts_md/BackPopulateSNRAndAcquisitionOrder.md index 2d95ecf5b..1c1904a94 100644 --- a/docs/scripts_md/BackPopulateSNRAndAcquisitionOrder.md +++ b/docs/scripts_md/BackPopulateSNRAndAcquisitionOrder.md @@ -1,9 +1,9 @@ # NAME BackPopulateSNRAndAcquisitionOrder.pl -- a script that back populates the -AcqOrderPerModality column of the files table, and the signal-to-noise ratio -(SNR) values in the parameter\_file table for inserted MINC files. The SNR is -computed using MINC tools built-in algorithms. +`AcqOrderPerModality` column of the `files` table, and the signal-to-noise +ratio (SNR) values in the `parameter_file` table for inserted MINC files. The +SNR is computed using MINC tools built-in algorithms. # SYNOPSIS @@ -11,11 +11,10 @@ perl tools/BackPopulateSNRAndAcquisitionOrder.pl `[options]` Available options are: -\-profile : name of the config file in - `../dicom-archive/.loris_mri` +\-profile : name of the config file in `../dicom-archive/.loris_mri` -\-tarchive\_id : The Tarchive ID of the DICOM archive (.tar files) to be - processed from the `tarchive` table +\-tarchive\_id: ID of the DICOM archive (.tar file) to be processed from the + `tarchive` table # DESCRIPTION @@ -23,19 +22,10 @@ This script will back populate the `files` table with entries for the `AcqOrderPerModality` column; in reference to: https://github.com/aces/Loris-MRI/pull/160 as well as populate the `parameter_file` table with SNR entries in reference -to: -https://github.com/aces/Loris-MRI/pull/142 -It can take in TarchiveID as an argument if only a specific DICOM archive -(.tar files) is to be processed; otherwise, all DICOM archives (.tar files) in -the `tarchive` table are processed. - -# TO DO - -Nothing planned. - -# BUGS - -None reported. +to: https://github.com/aces/Loris-MRI/pull/142 +It can take in `TarchiveID` as an argument if only a specific DICOM archive +(.tar files) is to be processed; otherwise, all DICOM archives (`tar` +files) in the `tarchive` table are processed. # LICENSING diff --git a/docs/scripts_md/DBI.md b/docs/scripts_md/DBI.md index 45795837b..ce1a61781 100644 --- a/docs/scripts_md/DBI.md +++ b/docs/scripts_md/DBI.md @@ -22,21 +22,27 @@ the LORIS-MRI code base and the LORIS backend database. ### connect\_to\_db($db\_name, $db\_user, $db\_pass, $db\_host) -This method connects to the LORIS database ($db\_database) on host ($db\_host) -as username ($db\_user) & password ($db\_pass). The function dies with a -database connection error when the connection failed or returns a DBI database -handler. +This method connects to the LORIS database (`$db_database`) on host +(`$db_host`) as username (`$db_user`) & password (`$db_pass`). The function +dies with a database connection error when the connection failed or returns a +DBI database handler. -INPUT: optional: database, username, password, host +INPUTS: + - $db\_name: database name (optional) + - $db\_user: database user (optional) + - $db\_pass: password for `$db_user` (optional) + - $db\_host: database host (optional) RETURNS: DBI database handler when connection is successful ### getConfigSetting($dbh, $name) -This method fetches the value ($value) stored in the `Config` table for a -specific config setting ($name) specified as an input. +This method fetches the value (`$value`) stored in the `Config` table for a +specific config setting (`$name`) specified as an input. -INPUT: database handler, name of the config setting +INPUTS: + - $dbh : database handler + - $name: name of the config setting RETURNS: value corresponding to the config setting in the `Config` table of LORIS @@ -45,10 +51,6 @@ RETURNS: value corresponding to the config setting in the `Config` table Expand the package with more functions. -# BUGS - -None reported - # COPYRIGHT AND LICENSE Copyright (c) 2003 by Jonathan Harlap, McConnell Brain Imaging Centre, diff --git a/docs/scripts_md/DCMSUM.md b/docs/scripts_md/DCMSUM.md index 51dcecf65..cadff542f 100644 --- a/docs/scripts_md/DCMSUM.md +++ b/docs/scripts_md/DCMSUM.md @@ -14,22 +14,24 @@ Deals with DICOM summaries for archiving and other purposes. Creates a new instance of this class. -INPUTS: DICOM directory, target location +INPUTS: + - $dcm\_dir: DICOM directory + - $tmp\_dir: target location -RETURNS: a DICOM::DCMSUM object +RETURNS: a `DICOM::DCMSUM` object -### database($dbh, $meta, $update, $tarType, $tarLog, $DCMmd5, ...) +### database($dbh, $meta, $update, $tarType, $tarLog, $DCMmd5, $Archivemd5, $Archive, $neurodbCenterName) -Inserts or updates the tarchive tables. +Inserts or updates the `tarchive` tables. INPUTS: - $dbh : database handle - $meta : name of the .meta file - - $update : set to 1 to update tarchive entry, 0 otherwise + - $update : set to 1 to update `tarchive` entry, 0 otherwise - $tarType : tar type version - $tarLog : name of the .log file - $DCMmd5 : DICOM MD5SUM - - $Archivemd5 : tarchive MD5SUM + - $Archivemd5 : DICOM archive MD5 sum - $Archive : archive location - $neurodbCenterName: center name @@ -37,7 +39,7 @@ RETURNS: 1 on success ### read\_file($file) -Reads the content of a file (typically .meta file in the tarchive). +Reads the content of a file (typically .meta file in the DICOM archive). INPUT: the file to be read @@ -115,10 +117,10 @@ RETURNS: header information ### confirm\_single\_study() Confirms that only one DICOM study is in the DICOM directory to be archived. -Returns False if there is more than one StudyUID, otherwise it returns that -StudyUID. +Returns `False` if there is more than one `StudyUID`, otherwise it returns +that `StudyUID`. -RETURNS: StudyUID found in the DICOM directory, or false if more than one +RETURNS: `StudyUID` found in the DICOM directory, or `false` if more than one study was found ### print\_header() @@ -201,9 +203,10 @@ RETURNS: formatted date, or the different between two dates ### md5sum($filename) -Computes the MD5 sum of a file and outputs a format similar to md5sum on Linux. +Computes the MD5 sum of a file and outputs a format similar to `md5sum` on +Linux. -INPUT: file name to use to computer MD5 sum +INPUT: file name to use to compute MD5 sum RETURNS: MD5 sum of the file @@ -211,10 +214,6 @@ RETURNS: MD5 sum of the file Fix comments written as #fixme in the code. -# BUGS - -None reported. - # LICENSING Copyright (c) 2006 by J-Sebastian Muehlboeck, McConnell Brain Imaging Centre, diff --git a/docs/scripts_md/DICOM.md b/docs/scripts_md/DICOM.md new file mode 100644 index 000000000..06fa49d42 --- /dev/null +++ b/docs/scripts_md/DICOM.md @@ -0,0 +1,177 @@ +# NAME + +DICOM::DICOM -- Perl library that allows Perl programs to read the headers of +medical image files conforming to DICOM standards. + +# SYNOPSIS + + use DICOM; + + my $dicom = DICOM->new(); + $dicom->fill($dicomFile); + my $patientName = $dicom->value('0010', '0010'); + +# DESCRIPTION + +DICOM (Digital Imaging and Communications in Medicine) is a standard +designed to allow medical image files to be transferred, stored and +viewed on different makes of computers. Perl is a multi-platform +language that excels at system tasks such as file manipulation. It's +easy to learn, particularly if you are familiar with C or the Unix +shells and utility programs. + +This library provides the methods to read and parse a DICOM file, then +to recover the contents of each header element by their standard DICOM +group and element codes. Header element values can be edited (either +through the GUI or command line) and the modified file written back to +disk. + +## Methods + +### new() >> (constructor) + +Creates a new instance of this class. + +RETURNS: a `DICOM::DICOM` object + +### processOpts($href) + +Stores and process the command line options from hash ref. + +INPUT: a hash reference + +### fill($infile, $big\_endian\_image) + +Fills in hash with header members from given file. + +INPUTS: + - $infile : file + - $big\_endian\_image: big endian image (optional) + +RETURNS: 1 if duplication, 0 on success + +### write($outfile) + +Writes currently open file to given file name, or to current name if no new +name specified. All fields before value are written verbatim; value field +is stored as is (possibly edited). + +INPUT: file to write into + +### printContents($outfile) + +Prints all elements, to disk if file handle supplied. + +INPUT: file to print into + +### contents() + +Returns a sorted array of references to element arrays. + +RETURNS: sorted array of references + +### setIndex($val) + +Sets field index to sort by. + +INPUT: value + +RETURNS: 1 if new index, else 0. + +### getIndex() + +Returns the sort index. + +RETURNS: sort index + +### value($gp, $el) + +Returns value of the element at (group, element). + +INPUTS: + - $gp: group + - $el: element + +RETURNS: value of the element + +### field($gp, $el, $fieldname) + +Returns field of given index from element. + +INPUTS: + - $gp : group + - $el : element + - $fieldname: field index + +RETURNS: field of given index from element + +### editHeader($editstr) + +Edit header value from string. +String format: 'gggg,eeee=newvalue' or 'fieldname=newvalue'. + gggg, eeee = group, element (in hex); + fieldname = name of field from @dicom\_fields. + +INPUT: string to edit + +RETURNS: undef unless group and element are defined + +### fieldByName($searchname) + +Returns group and element number of field with given name. + +INPUT: name of the field to search + +RETURNS: group and element number of field + +### setElementValue($gp, $el, $newvalue) + +Replaces value of given element. + +INPUTS: + - $gp : group + - $el : element + - $newvalue: new value + +### hexadecimally() + +### sortByField() + +Sort array of value by field. + +RETURNS: sorted array + +### loop() + +Doesn't do anything in non-graphical case. + +# SEE ALSO + +The DICOM standard - http://medical.nema.org/ + +# TO DO + +Add support for sequences (SQ) (currently being skipped) + +Better documentation for: + - setIndex() + - hexadecimally() -- non public? + - loop - doesn't do anything in non-graphical case. investigate if this + function is used, if not, remove + +# COPYRIGHT AND LICENSE + +Copyright (C) 2002 by Andrew Crabb +Some parts are Copyright (C) 2003 by Jonathan Harlap + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.6.0 or, +at your option, any later version of Perl 5 you may have available. + +License: GPLv3 + +# AUTHORS + +Andrew Crabb, , +Jonathan Harlap, , +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/DTI.md b/docs/scripts_md/DTI.md new file mode 100644 index 000000000..3dc47b091 --- /dev/null +++ b/docs/scripts_md/DTI.md @@ -0,0 +1,424 @@ +# NAME + +DTI::DTI --- A set of utility functions for performing common tasks relating to +DTI data (particularly with regards to performing DTI QC) + +# SYNOPSIS + + use DTI::DTI; + + my ($protXMLrefs) = &DTI::readDTIPrepXMLprot( $DTIPrepProtocol ); + + my ($QCoutdir) = &DTI::createOutputFolders( $outdir, $subjID, + $visit, $DTIPrepProtocol, + $runDTIPrep + ); + + my ($DTIs_list) = &DTI::getRawDTIFiles( $nativedir, $DTI_volumes ); + my ($anat) = &DTI::getAnatFile( $nativedir, $t1_scan_type ); + my ($DTIrefs) = &DTI::createDTIhashref( $DTIs_list, $anat, + $QCoutdir, $DTIPrepProtocol, + $protXMLrefs, $QCed2_step + ); + + my ($convert_status) = &DTI::convert_DTI( $dti_file, + $raw_nrrd, + '--short --minc-to-nrrd --dwi' + ); + + my ($copyProt_status) = &DTI::copyDTIPrepProtocol($DTIPrepProtocol, $QCProt); + my ($DTIPrep_status) = &DTI::runDTIPrep( $raw_nrrd, $DTIPrepProtocol, + $QCed_nrrd, $QCed2_nrrd + ); + + + ($convert_status) = &DTI::convert_DTI( $QCed_nrrd, + $QCed_minc, + '--nrrd-to-minc --dwi' + ); + ($insert_header) = &DTI::insertMincHeader( $dti_file, $data_dir, + $QCed_minc, $QCTxtReport, + $DTIPrepVersion + ); + +# DESCRIPTION + +A mishmash of utility functions, primarily used by `DTIPrep_pipeline.pl` +and `DTIPrepRegister.pl`. + +## Methods + +### createOutputFolders($outdir, $subjID, $visit, $protocol, $runDTIPrep) + +Creates DTIPrep pipeline output folders. It will return the created output +folder only if the output folder was created. + +INPUTS: + - $outdir : base output folder + - $subjID : candidate ID stored in dataset's basename + - $visit : visit label stored in dataset's basename + - $protocol : DTIPrep XML protocol to use (or used) to run DTIPrep + - $runDTIPrep: if set, will run DTIPrep and create the output dir. + +Note: If `$runDTIPrep` is not set, then DTIPrep was already run and the +output folder already exists. + +RETURNS: `candidate/visit/protocol` folder that will store DTIPrep outputs. + +### getFilesList($dir, $match) + +Subroutine that will read the content of a directory and return a list +of files whose names match the string given in argument with `$match`. + +INPUTS: + - $dir : directory with DTI files to be fetch + - $match: string used to look for DTI files to be returned + +RETURNS: list of DTI files found in `$dir` matching `$match` + +### getAnatFile($nativedir, $t1\_scan\_type) + +Function that parses files in the native MRI directory and grabs +the T1 acquisition based on `$t1_scan_type`. + +INPUTS: + - $nativedir : native directory + - $t1\_scan\_type: scan type string used for t1 acquisitions + +RETURNS: + - undef if no anat found + - $anat: anatomical file (first anat found if multiple anats were found). + +### getRawDTIFiles($nativedir, $DTI\_volumes) + +Function that parses files in the native MRI directories and fetches DTI files. +This function will also concatenate together multiple DTI files if the DTI +acquisition was performed across several DTI scans. + +INPUTS: + - $nativedir : native directory + - $DTI\_volumes: DTI's number of volumes + +RETURNS: list of matching DTI files found in the native directory + +### copyDTIPrepProtocol($DTIPrepProtocol, $QCProt) + +Function that will copy the `DTIPrep` protocol to the output directory of +`DTIPrep`. + +INPUTS: + - $DTIPrepProtocol: `DTIPrep` protocol to be copied + - $QCProt : future path of copied `DTIPrep` protocol + +RETURNS: 1 on success, undef on failure + +### readDTIPrepXMLprot($DTIPrepProtocol) + +Read `DTIPrep` XML protocol and return information into a hash. + +INPUT: XML protocol used (or that has been used) to run `DTIPrep` + +RETURNS: reference to a hash containing `DTIPrep` protocol as follows: + + entry => 'QC_QCOutputDirectory' => {} + => 'QC_QCedDWIFileNameSuffix' => { + 'value' => '_QCed.nrrd' + }, + => 'IMAGE_bCheck' => { + 'entry' => { + 'IMAGE_size' => { + 'value' => [ + '96', + '96', + '65' + ] + }, + 'IMAGE_reportFileMode' => { + 'value' => '1' + }, + ... + 'value' => 'Yes' + }, + => 'QC_badGradientPercentageTolerance' => { + ... + +### createDTIhashref($DTIs\_list, $anat, $QCoutdir, $DTIPrepProtocol, $protXMLrefs, $QCed2\_step) + +Function that will determine output names based on each DTI file dataset and +return a hash of DTIref: + + dti_file_1 -> Raw_nrrd => outputname + -> QCed_nrrd => outputname + -> QCTxtReport => outputname + -> QCXmlReport => outputname + -> QCed_minc => outputname + -> QCProt => outputname + dti_file_2 -> Raw_nrrd => outputname + ... + +INPUTS: + - $DTIs\_list : list of native DTI files to be processed + - $anat : anatomical file to be used for processing + - $QCoutdir : processed output directory + - $DTIPrepProtocol: `DTIPrep` XML protocol used to run `DTIPrep` + - $protXMLrefs : hash containing info about `DTIPrep`'s protocol + - $QCed2\_step : optionally, step name at which `DTIPrep` will + produce a secondary QCed file + +RETURNS: hash containing outputs naming convention + +### determinePreprocOutputs($QCoutdir, $dti\_file, $DTIPrepProtocol, $protXMLrefs) + +Function that will determine pre processing output names (for either `DTIPrep` +or `mincdiffusion` postprocessing) and append them to `$DTIrefs`. + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti\_file : raw DWI file to be processed + - $DTIPrepProtocol: `DTIPrep` protocol to copy into output directory + - $protXMLrefs : hash containing info from `DTIPrep` XML protocol + (including suffix for the different outputs) + +RETURNS: $DTIrefs{$dti\_file}{'Preproc'}{'Output'} fields for `DTIPrep` +processing + +### determinePostprocOutputs($QCoutdir, $dti\_file, $anat, $protXMLrefs) + +Function that will determine post processing output names (for either `DTIPrep` +or `mincdiffusion` postprocessing) and append them to `$DTIrefs`. + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti\_file : raw DWI file to be processed + - $anat : T1 image to be used for `mincdiffusion` postprocessing + - $protXMLrefs: hash containing info from `DTIPrep` XML protocol + (including suffix for the different outputs) + +RETURNS: + - $DTIrefs{$dti\_file}{'Postproc'}{'Tool'} with postprocessing used + - $DTIrefs{$dti\_file}{'Postproc'}{'Output'} fields for `DTIPrep` postprocessing + +### determineDTIPrepPostprocOutputs($QCoutdir, $dti\_file, $protXMLrefs) + +Function that will determine `DTIPrep`'s postprocessing output names (based on +the XML protocol) and append them to `$DTIrefs` + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti\_file : raw DWI file to be processed + - $protXMLrefs: hash containing info from `DTIPrep` XML protocol + +RETURNS: $DTIrefs{$dti\_file}{'Postproc'}{'Output'} fields for `DTIPrep` +postprocessing + +### determineMincdiffusionPostprocOutputs($QCoutdir, $dti\_file, $QCed\_suffix, $anat) + +Function that will determine `mincdiffusion` postprocessing output names and +append them to `$DTIrefs` + +INPUTS: + - $QCoutdir : directory that will contain output files + - $dti\_file : raw DWI file to be processed + - $QCed\_suffix: QCed suffix for QCed NRRD & postprocessing file names + - $anat : anatomic T1 file to use for DWI-anat registration + +RETURNS: $DTIrefs{$dti\_file}{'Postproc'} for `mincdiffusion` postprocessing + +### convert\_DTI($file\_in, $file\_out, $options) + +Function that converts MINC file to NRRD or NRRD file to MINC. +(depending on `$options`) + +INPUTS: + - $file\_in : file to be converted + - $file\_out: converted file + - $options : conversion options (`mnc2nrrd` or `nrrd2mnc`) + +RETURNS: 1 on success, undef on failure + +### runDTIPrep($raw\_nrrd, $protocol, $QCed\_nrrd, $QCed2\_nrrd) + +Function that runs `DTIPrep` on NRRD file. + +INPUTS: + - $raw\_nrrd : raw DTI NRRD file to be processed through `DTIPrep` + - $protocol : `DTIPrep` protocol used + - $QCed\_nrrd : QCed file produced by `DTIPrep` + - $QCed2\_nrrd: optionally, secondary QCed file + +RETURNS: 1 on success, under on failure + +### insertMincHeader($raw\_file, $data\_dir, $processed\_minc, $QC\_report, $DTIPrepVersion, $is\_anat) + +Inserts in the MINC header all the acquisition arguments except: + - acquisition:bvalues + - acquisition:direction\_x + - acquisition:direction\_y + - acquisition:direction\_z + - acquisition:b\_matrix + +Takes the raw DTI file and the QCed MINC file as input and modifies +the QCed MINC file based on the raw MINC file's argument. + +If one of the value to insert is not defined, return undef, otherwise return 1. + +INPUTS: + - $raw\_file : raw DTI MINC file to grep header information + - $data\_dir : data dir as defined in the profile file + - $processed\_minc: processed MINC file in which to insert header information + - $QC\_report : `DTIPrep` QC report text file + - $DTIPrepVersion: `DTIPrep` version used to obtain processed file + - $is\_anat : if set, will only insert processing, patient & study info + +RETURNS: 1 on success, undef on failure + +### insertProcessInfo($raw\_dti, $data\_dir, $processed\_minc, ...) + +This will insert in the header of the processed file processing information. If +one of the value to insert is not defined, return undef, otherwise return 1. + +INPUTS: + - $raw\_dti : raw DTI MINC file to grep header information from + - $data\_dir : data dir as defined in the profile file + - $processed\_minc: processed MINC file in which to insert header info + - $QC\_report : `DTIPrep` QC report text file + - $DTIPrepVersion: `DTIPrep` version used to obtain processed file + +RETURNS: 1 on success, undef on failure + +### insertAcqInfo($raw\_dti, $processed\_minc) + +Inserts acquisition information extracted from raw DTI dataset and insert it in +the processed file. If one of the value to insert is not defined, return +undef, otherwise return 1. + +INPUTS: + - $raw\_dti : raw DTI MINC file to grep header information + - $processed\_minc: processed MINC file in which to insert header info + +RETURNS: 1 on success, undef on failure + +### insertFieldList($raw\_dti, $processed\_minc, $minc\_field) + +Inserts information extracted from raw DTI dataset and insert it in the +processed file. If one of the value to insert is not defined, return undef, +otherwise return 1. + +INPUTS: + - $raw\_dti : raw DTI MINC file to grep header information from + - $processed\_minc: processed MINC file in which to insert header info + - $minc\_field : MINC field to be inserted in processed MINC file + +RETURNS: 1 on success, undef on failure + +### modify\_header($argument, $value, $minc, $awk) + +Function that runs `minc_modify_header` and inserts MINC header information if +not already inserted. + +INPUTS: + - $argument: argument to be inserted in MINC header + - $value : value of the argument to be inserted in MINC header + - $minc : MINC file + - $awk : awk info to check if the argument was inserted in MINC header + +RETURNS: 1 if argument was inserted in the MINC header, undef otherwise + +### fetch\_header\_info($field, $minc, $awk, $keep\_semicolon) + +Function that fetches header information in MINC file. + +INPUTS: + - $field: field to look for in MINC header + - $minc : MINC file + - $awk : awk info to check if argument inserted in MINC header + - $keep\_semicolon: if set, keep ";" at the end of extracted value + +RETURNS: value of the field found in the MINC header + +### get\_header\_list($splitter, $fields) + +Gets the list of arguments and values to insert into the MINC header +(`acquisition:*`, `patient:*` and `study:*`). + +INPUTS: + - $splitter: delimiter used to split list of fields stored in `$fields` + - $fields : list header arguments/values to insert in the MINC header + +RETURNS: - $list : array of header arguments and values' list + - $list\_size: size of the array $list + +### mincdiff\_preprocess($dti\_file, $DTIrefs, $QCoutdir) + +Function that runs `diff_preprocess.pl` script from the `mincdiffusion` +tools on the QCed MINC and raw anat dataset. + +INPUTS: + - $dti\_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used + - $QCoutdir: directory used to create outputs from QC pipeline + +RETURNS: 1 on success, undef on failure + +### mincdiff\_minctensor($dti\_file, $DTIrefs, $QCoutdir, $niak\_path) + +Function that runs `minctensor.pl` script from the `mincdiffusion` tools on +the `mincdiff` preprocessed MINC and anatomical mask images. + +INPUTS: + - $dti\_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used + - $QCoutdir: directory used to create outputs from QC pipeline + +RETURNS: 1 on success, undef on failure + +### RGBpik\_creation($dti\_file, $DTIrefs) + +Function that runs `mincpik` on the RGB map. + +INPUTS: + - $dti\_file: hash key to use to fetch file names (e.g. raw DWI file) + - $DTIrefs : hash storing file names to be used + +RETURNS: 1 on success, undef on failure + +### convert\_DTIPrep\_postproc\_outputs($dti\_file, $DTIrefs, $data\_dir, $DTIPrepVersion) + +This function will check if all `DTIPrep` NRRD files were created and convert +them into MINC files with relevant header information inserted. + +INPUTS: + - $dti\_file : raw DTI dataset that was processed through `DTIPrep` + - $DTIrefs : hash containing information about output names + - $data\_dir : directory containing raw DTI dataset + - $DTIPrepVersion: `DTIPrep` version used to process the DWI dataset + +RETURNS: + - $nrrds\_found : 1 if all NRRD outputs found, undef otherwise + - $mincs\_created: 1 if all NRRD files converted to MINC files, + undef otherwise + - $hdrs\_inserted: 1 if all header info inserted in MINC files, + undef otherwise + +### getRejectedDirections($data\_dir, $XMLReport) + +Summarize which directions were rejected by `DTIPrep` for slice-wise +correlations, +inter-lace artifacts, inter-gradient artifacts. + +INPUTS: + - $data\_dir: data\_dir defined in the config file + - $QCReport: `DTIPrep`'s QC txt report to extract rejected directions + +RETURNS: + - number of directions rejected due to slice wise correlations + - number of directions rejected due to interlace artifacts + - number of directions rejected due to inter-gradient artifacts + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/DTIPrepRegister.md b/docs/scripts_md/DTIPrepRegister.md new file mode 100644 index 000000000..3fbdf31a6 --- /dev/null +++ b/docs/scripts_md/DTIPrepRegister.md @@ -0,0 +1,419 @@ +# NAME + +DTIPrepRegister.pl -- registers `DTIPrep` outputs in the LORIS database + +# SYNOPSIS + +perl DTIPrepRegister.pl `[options]` + +Available options are: + +\-profile : name of the config file in `../dicom-archive/.loris-mri` + +\-DTIPrep\_subdir : `DTIPrep` subdirectory storing the processed files to + be registered + +\-DTIPrepProtocol: `DTIPrep` protocol used to obtain the output files + +\-DTI\_file : native DWI file used to obtain the output files + +\-anat\_file : native anatomical dataset used to create FA, RGB and + other post-processed maps using `mincdiffusion` tools + +\-DTIPrepVersion : `DTIPrep` version used if it cannot be found in MINC + files' `processing:pipeline` header field + +\-mincdiffusionVersion: `mincdiffusion` release version used if it cannot be + found in minc files' `processing:pipeline` + header field + +Note: `-DTIPrepVersion` and `-mincdiffusionVersion` are optional if the +version of those tools can be found directly in the MINC header of the +processed files. + +# DESCRIPTION + +Registers DWI QC pipeline's output files of interest into the LORIS database +via `register_processed_data.pl`. + +The following output files will be inserted: + - QCed MINC file produced by `DTIPrep` pre-processing step (i.e. DWI + dataset without the bad directions detected by `DTIPrep`) + - Text QC report produced by DTPrep + - XML QC report produced by `DTIPrep` + - RGB map produced by either `DTIPrep` or `mincdiffusion` post-processing + - MD map produced by either `DTIPrep` or `mincdiffusion` post-processing + - FA map produced by either `DTIPrep` or `mincdiffusion` post-processing + - baseline image produced by `DTIPrep` or `mincdiffusion` post-processing + - DTI mask produced by `mincdiffusion` post-processing (only if + `mincdiffusion` was used to post-process the data) + +## Methods + +### register\_XMLProt($XMLProtocol, $data\_dir, $tool) + +Registers XML protocol file into the `mri_processing_protocol` table. It will +first check if protocol file was already registered in the database. If the +protocol file is already registered in the database, it will return the +Process Protocol ID from the database. If the protocol file is not registered +yet in the database, it will register it in the database and return the +`ProcessProtocolID` of the registered protocol file. + +INPUTS: + - $XMLProtocol: XML protocol file of `DTIPrep` to be registered + - $data\_dir : data directory from the `Config` table, tool name of the + protocol (a.k.a. `DTIPrep`) + +RETURNS: ID of the registered protocol file + +### registerProtocol($protocol, $md5sum, $tool, $data\_dir) + +Registers protocol file into `mri_processing_protocol` table and move the +protocol to the `$data_dir/protocols/DTIPrep` folder. + +INPUTS: + - $protocol: protocol file to be registered + - $md5sum : MD5 sum of the protocol file to be registered + - $tool : tool of the protocol file (`DTIPrep`) + - $data\_dir: data directory (`/data/$PROJECT/data`) + +RETURNS: ID of the registered protocol file + +### fetchProtocolID($md5sum) + +Fetches the protocol ID in the `mri_processing_protocol` table based on +the XML protocol's MD5 sum. + +INPUT: MD5 sum of the XML protocol + +RETURNS: ID of the registered protocol file + +### register\_minc($minc, $raw\_file, $data\_dir, $inputs, $pipelineName, $toolName, $registeredXMLFile, $registeredQCReportFile, $scanType, $registered\_nrrd) + +Sets the different parameters needed for MINC files' registration +and calls `®isterFile` to register the MINC file in the database +via `register_processed_data.pl` script. + +INPUTS: + - $minc : MINC file to be registered + - $raw\_file : source file of the MINC file to register + - $data\_dir : data\_dir directory from the config table + - $inputs : input files of the file to be registered + - $pipelineName : name of the pipeline used to obtain the MINC file + - $toolName : tool name and version used + - $registeredXMLFile : registered `DTIPrep` XML report + - $registeredQCReportFile: registered `DTIPrep` text report + - $scanType : scan type of the MINC file to register + - $registered\_nrrd : optional, registered NRRD file used to create the MINC file + +RETURNS: registered MINC file on success, undef otherwise + +### register\_XMLFile($XMLFile, $raw\_file, $data\_dir, $QCReport, $inputs, $pipelineName, $toolName) + +Sets parameters needed to register the XML report/protocol of `DTIPrep` +and calls registerFile to register the XML file via register\_processed\_data.pl. + +INPUTS: + - $XMLFile : XML file to be registered + - $raw\_file : native DWI file used to obtain the `DTIPrep` outputs + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $QCReport : `DTIPrep` QC text report + - $inputs : input files used to process data through `DTIPrep` + - $pipelineName: pipeline name used to process DWIs (`DTIPrepPipeline`) + - $toolName : `DTIPrep` name and version used to process the DWI file + +RETURNS: the registered XNL file if it was registered in the database or undef + +### register\_QCReport($QCReport, $raw\_file, $data\_dir, $inputs, $pipelineName, $toolName) + +Sets parameters needed to register the QCreport of `DTIPrep` and calls +`®isterFile` to register the QCreport file via +`register_processed_data.pl`. + +INPUTS: + - $QCReport : QC report file to be registered + - $raw\_file : native DWI file used to obtain the `DTIPrep` outputs + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $inputs : input files used to process data through `DTIPrep` + - $pipelineName: pipeline name used to process DTIs (`DTIPrepPipeline`) + - $toolName : `DTIPrep` name and version used to process the DWI file + +RETURNS: registered QCReport file if it was registered in the database or undef + +### getFiles($dti\_file, $DTIrefs) + +This function checks that all the processing files exist on the filesystem and +returns the files to be inserted in the database. When NRRD and MINC files are +found, it will only return the MINC file. (NRRD files will be linked to the +MINC file when inserting files in the database). + +INPUTS: + - $dit\_file: raw DTI dataset that is used as a key in `$DTIrefs` hash + - $DTIref : hash containing all output paths and tool information + +RETURNS: + - $XMLProtocol : `DTIPrep` XML protocol found in the file system + - $QCReport : `DTIPrep` QC text report found in the file system + - $XMLReport : `DTIPrep` QC XML report found in the file system + - $QCed\_minc : QCed MINC file created after conversion of QCed NRRD file + - $RGB\_minc : RGB MINC file found in the file system + - $FA\_minc : FA MINC file found in the file system + - $MD\_minc : MD MINC file found in the file system + - $baseline\_minc : baseline MINC file found in the file system + - $brain\_mask\_minc: brain mask MINC file found in the file system + - $QCed2\_minc : optional, secondary QCed MINC file created after + conversion of secondary QCed `DTIPrep` NRRD file + - returns undef if there are some missing files (except for `QCed2_minc` + which is optional) + +### checkPreprocessFiles($dti\_file, $DTIrefs, $mri\_files) + +Function that checks if all `DTIPrep` pre-processing files are present in the +file system. + +INPUTS: + - $dti\_file: raw DTI dataset that is used as a key in `$DTIrefs` hash + - DTIrefs : hash containing all output paths and tool information + - mri\_files: list of processed outputs to register or that have been + registered + +RETURNS: + - $XMLProtocol: `DTIPrep` XML protocol found in the file system + - $QCReport : `DTIPrep` text QC report found in the file system + - $XMLReport : `DTIPrep` XML QC report found in the file system + - $QCed\_minc : QCed MINC file created after conversion of QCed NRRD file + - $QCed2\_minc : optional, secondary QCed MINC file created after + conversion of secondary QCed `DTIPrep` NRRD file + - returns undef if one of the file listed above is missing (except + for `QCed2_minc` which is optional) + +### checkPostprocessFiles($dti\_file, $DTIrefs, $mri\_files) + +Function that checks if all postprocessing files (from `DTIPrep` or +`mincdiffusion`) are present in the file system. + +INPUTS: + - $dti\_file : raw DTI dataset that is used as a key in `$DTIrefs` hash + - $DTIrefs : hash containing all output paths and tool information + - $mri\_files: list of processed outputs to register or that have been registered + +RETURNS: + - $RGB\_minc : RGB map + - $FA\_minc : FA map + - $MD\_minc : MD map + - $baseline\_minc : baseline (or frame-0) map + - $brain\_mask\_minc: brain mask produced by `mincdiffusion` tools (not + available if `DTIPrep` was run to obtain the + post-processing outputs) + - will return undef if one of the file listed above is missing + +### getFileID($file, $src\_name) + +Fetches the source FileID from the database based on the `$src_name` file +identified by `getFileName`. + +INPUTS: + - $file : output filename + - $src\_name: source filename (file that has been used to obtain `$file`) + +RETURNS: source File ID (file ID of the source file that has been used to + obtain $file) + +### getToolName($file) + +Fetches tool information stored either in the MINC file's header or in the +QC text report. + +INPUT: MINC or QC text report to look for tool information + +RETURNS: + - $src\_pipeline: name of the pipeline used to obtain `$file` (`DTIPrepPipeline`) + - $src\_tool : name and version of the tool used to obtain `$file` + (`DTIPrep_v1.1.6`, `mincdiffusion_v...`) + +### getPipelineDate($file, $data\_dir, $QCReport) + +Fetches the date at which the `DTIPrep` pipeline was run either in the processed +MINC file's header or in the QC text report. + +INPUTS: + - $file : MINC or QC text report to look for tool information + - $data\_dir: data directory (e.g. `/data/$PROJECT/data`) + - $QCReport: QC text report created when `$file` was created + +RETURNS: date at which the pipeline has been run to obtain `$file` + +### insertReports($minc, $registeredXMLFile, $registeredQCReportFile) + +Inserts the path to `DTIPrep`'s QC text, XML reports and XML protocol in the +MINC file's header. + +INPUTS: + - $minc : MINC file for which the header should be modified + - $registeredXMLfile : path to the registered `DTIPrep`'s QC XML report + - $registeredQCReportFile: path to the registered `DTIPrep`'s QC text report + +RETURNS: + - $Txtreport\_insert: 1 on text report path insertion success, undef otherwise + - $XMLreport\_insert: 1 on XML report path insertion success, undef otherwise + +### insertPipelineSummary($minc, $data\_dir, $XMLReport, $scanType) + +Inserts in the MINC header a summary of `DTIPrep` reports. This summary consists +of the directions rejected due to slice wise correlation, the directions +rejected due to interlace correlation, and the directions rejected due to +gradient wise correlation. + +INPUTS: + - $minc : MINC file in which the summary will be inserted + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $XMLReport: `DTIPrep`'s XML QC report from which the summary will be extracted + +RETURNS: 1 on success, undef on failure + +### registerFile($file, $src\_fileID, $src\_pipeline, $src\_tool, $pipelineDate, $coordinateSpace, $scanType, $outputType, $inputs) + +Registers file into the database via `register_processed_data.pl` with all +options. + +INPUTS: + - $file : file to be registered in the database + - $src\_fileID : source file's FileID + - $src\_pipeline : pipeline used to obtain the file (`DTIPrepPipeline`) + - $src\_tool : name and version of the tool (`DTIPrep` or `mincdiffusion`) + - $pipelineDate : file's creation date (= pipeline date) + - $coordinateSpace: file's coordinate space (= native, T1 ...) + - $scanType : file's scan type (= `DTIPrepReg`, `DTIPrepDTIFA`, + `DTIPrepDTIMD`, `DTIPrepDTIColorFA`...) + - $outputType : file's output type (`.xml`, `.txt`, `.mnc`...) + - $inputs : input files that were used to create the file to + be registered (intermediary files) + +RETURNS: registered file + +### fetchRegisteredFile($src\_fileID, $src\_pipeline, $pipelineDate, $coordinateSpace, $scanType, $outputType) + +Fetches the registered file from the database to link it to the MINC files. + +INPUTS: + - $src\_fileID : FileID of the source native file + - $src\_pipeline : pipeline name used to register the processed file + - $pipelineDate : pipeline data used to register the processed file + - $coordinateSpace: processed file's coordinate space + - $scanType : scan type used to register the processed file + - $outputType : output type used to register the processed file + +RETURNS: path to the registered processed file + +### register\_DTIPrep\_files($minc, $nrrd, $raw\_file, $data\_dir, $inputs, $registeredXMLProtocolID, $pipelineName, $DTIPrepVersion, $registeredXMLReportFile, $registeredQCReport, $scanType) + +Registers `DTIPrep` NRRD and MINC files. The MINC file will have a link to the +registered NRRD file (`®ister_minc` function will modify the MINC header to +include this information) in addition to the links toward QC reports and +protocol. + +INPUTS: + - $minc : MINC file to be registered + - $nrrd : NRRD file to be registered + - $raw\_file : raw DWI file used to create the MINC file to + register + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $inputs : input files that were used to create the file to + be registered (intermediary files) + - $registeredXMLProtocolID: registered XML protocol file + - $pipelineName : name of the pipeline that created the file to be + registered (`DTIPrepPipeline`) + - $DTIPrepVersion : `DTIPrep`'s version + - $registeredXMLReportFile: registered QC XML report file + - $registeredQCReport : registered QC text report file + - $scanType : scan type to use to label/register the MINC file + +RETURNS: registered MINC files or undef on insertion's failure + +### register\_nrrd($nrrd, $raw\_file, $data\_dir, $QCReport, $inputs, $pipelineName, $toolName, $scanType) + +Sets parameters needed to register the NRRD file produced by `DTIPrep` +and calls registerFile to register the NRRD file via +`register_processed_data.pl`. + +INPUTS: + - $nrrd : NRRD file to be registered + - $raw\_file : native DWI file used to obtain the `DTIPrep` outputs + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $QCReport : `DTIPrep` QC text report + - $inputs : input files used to process data through `DTIPrep` + - $pipelineName: pipeline name used to process DTIs (`DTIPrepPipeline`) + - $toolName : `DTIPrep` name and version used to process the DWI file + - $scanType : NRRD file's scan type + +RETURNS: registered NRRD file or undef on insertion's failure + +### register\_Preproc($mri\_files, $dti\_file, $data\_dir, $pipelineName, $toolName, $process\_step, $proc\_file) + +Gathers all `DTIPrep` preprocessed files to be registered in the database +and calls `®ister_DTIPrep_files` on all of them. Will register first the +NRRD file and then the MINC file for each scan type. + +INPUTS: + - $mri\_files : hash containing all DTI output information + - $dti\_file : native DWI file (that will be used as a key + for `$mri_files`) + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $pipelineName: pipeline name (`DTIPrepPipeline`) + - $toolName : tool's name and version + - $process\_step: processing step (`Preproc` or `Postproc`) + - $proc\_file : processed file key (`QCed`, `QCed2`...) + +RETURNS: path to the MINC file that was registered + +### register\_images($mri\_files, $raw\_file, $data\_dir, $pipelineName, $toolName, $process\_step) + +Function to register processed images in the database depending on the tool +used to obtain them. Will call `®ister_DTIPrep_files` if files to be +registered are obtained via `DTIPrep` or `®ister_minc` if files to be +registered are obtained using `mincdiffusion` tools. + +INPUTS: + - $mri\_files : hash with information about the files to be registered + - $raw\_file : source raw image + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $pipelineName: name of the pipeline used (a.k.a `DTIPrep`) + - $toolName : tool's version and name + - $process\_step: processing step (pre-processing, post-processing) + +RETURNS: + - @registered : list of registered files + - @failed\_to\_register: list of files that failed to be registered in the DB + +### getInputList($mri\_files, $data\_dir, $process\_step, $proc\_file) + +Function that will return in a string the list of inputs used to process the +data separated by ';'. + +INPUTS: + - $mri\_files : list of processed outputs to register or that + have been registered + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $process\_step: processing step used for the processed output + to determine inputs + - $proc\_file : processing file to determine inputs used + +RETURNS: string with each inputs used separated by ';' + +### fetchRegisteredMD5($md5sum) + +Will check if MD5 sum has already been registered into the database. + +INPUT: MD5 sum of the file + +RETURNS: + - $registeredFile : registered FileID matching MD5 sum + - $registeredScanType: scan type of the registered `FileID` matching MD5 sum + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/DTIPrep_pipeline.md b/docs/scripts_md/DTIPrep_pipeline.md new file mode 100644 index 000000000..a68b48bd5 --- /dev/null +++ b/docs/scripts_md/DTIPrep_pipeline.md @@ -0,0 +1,311 @@ +# NAME + +DTIPrep\_pipeline.pl -- Run `DTIPrep` and/or insert `DTIPrep`'s outputs in the +database. + +# SYNOPSIS + +perl DTIPrep\_pipeline.p `[options]` + +\-profile : name of config file in + `../dicom-archive/.loris_mri` + +\-list : file containing the list of raw diffusion MINC + files (in `assembly/DCCID/Visit/mri/native`) + +\-DTIPrepVersion : `DTIPrep` version used (if cannot be found in + `DTIPrep` binary path) + +\-mincdiffusionVersion: `mincdiffusion` release version used (if cannot be + found in `mincdiffusion` scripts path) + +\-runDTIPrep : if set, run `DTIPrep` on the raw MINC DTI data + +\-DTIPrepProtocol : `DTIPrep` protocol to use (or used) to run `DTIPrep` + +\-registerFilesInDB : if set, registers outputs file in the database + +**Notes:** + +\- tool version options (`-DTIPrepVersion` & `-mincdiffusionVersion`) +do not need to be set if they can be found directly in the path of the binary +tools. + +\- the script can be run without the `-runDTIPrep` option if execution of +`DTIPrep` is not needed. + +\- the script can be run without the `-registerFilesInDB` option if +registration of `DTIPrep` is not needed. + +# DESCRIPTION + +`DTIPrep_pipeline.pl` can be used to run `DTIPrep` on native DWI datasets. It +will also organize, convert and register the outputs of `DTIPrep` in the +database. + +If `-runDTIPrep` option is not set, `DTIPrep` processing will be skipped +(`DTIPrep` outputs being already available, as well as the `DTIPrep` protocol +that was used). + +**This pipeline will:** + +1) grep native DWI files from list of given native directories (`-list` option) + +2) create (or fetch if `-runDTIPrep` not set) output directories based + on the `DTIPrep` version and protocol that are to be (or were) used + for `DTIPrep` processing + +3) convert native DWI MINC file to NRRD and run `DTIPrep` if `-runDTIPrep` + option is set + +4) fetch `DTIPrep` pre-processing outputs (QCed.nrrd, QCReport.txt, + QCXMLResults.xml & protocol.xml) + +5) convert pre-processed NRRD files back to MINC with all the header + information (based on the native MINC file) + +6) create post-processing files (FA, RGB maps...) with all the header + information + +7) call `DTIPrepRegister.pl` to register the files in the database if + `-registerFilesInDB` is set + +## Methods + +### identify\_tool\_version($tool, $match) + +Function that determines the tool version used for processing. + +INPUTS: + - $tool : tool to search absolute path containing version information + - $match: string to match to determine tool version + +RETURNS: version of the tool found, or undef if version could not be +determined based on the path + +### getIdentifiers($nativedir) + +Fetches `CandID` and visit label from the native directory of the dataset to +process. Relevant information will also be printed in the log file. + +INPUT: native directory of the dataset to process + +RETURNS: undef if could not determine the site, `CandID`, visit OR + - $candID : candidate DCCID + - $visit\_label: visit label + +### getOutputDirectories($outdir, $subjID, $visit, $DTIPrepProtocol, $runDTIPrep) + +Determine pipeline's output directory based on the root `$outdir`, `DTIPrep` +protocol name, candidate ID `CandID` and visit label: +`outdir/ProtocolName/CandID/VisitLabel` + +\- If `$runDTIPrep` is set, the function will create the output folders + +\- If `$runDTIPrep` is not set, the function will check that the directory exists + +INPUTS: + - $outdir : root directory for `DTIPrep` outputs (in + `/data/$PROJECT/data/pipelines/DTIPrep/DTIPrep_version`) + - $subjID : candidate ID of the DTI dataset to be processed + - $visit : visit label of the DTI dataset to be processed + - $DTIPrepProtocol: XML file with the `DTIPrep` protocol to use + - $runDTIPrep : boolean, if output folders should be created in + the filesystem (before processing data through + `DTIPrep`) if they don't exist + +RETURNS: directory where processed files for the candidate, visit label and +DTIPrep protocol will be stored. + +### fetchData($nativedir, $DTI\_volumes, $t1\_scan\_type, $QCoutdir, $DTIPrepProtocol) + +Fetches the raw DWI datasets and foreach DWI, determines output names to be used +and stores them into a hash (`$DTIrefs`). Will also print relevant information +in the log file. + +INPUTS: + - $nativedir : native directory to look for native DWI dataset + - $DTI\_volumes : number of volumes expected in the DWI dataset + - $t1\_scan\_type : the scan type name of the T1 weighted dataset + - $QCoutdir : directory to save processed files + - $DTIPrepProtocol: XML `DTIPrep` protocol to use + +RETURNS: undef if could not find any raw DWI dataset OR + - $DTIs\_list: list of raw DTIs found + - $DTIrefs : a hash with the pre-processing output names and paths + +### preprocessingPipeline($DTIs\_list, $DTIrefs, $QCoutdir, $DTIPrepProtocol) + +Function that creates the output folders, gets the raw DTI files, converts them +to NRRD and runs `DTIPrep` using a `bcheck` protocol and a `nobcheck` protocol. + +INPUTS: + - $DTIs\_list : list of DWI files to process for a given `CandID/Visit` + - $DTIrefs : hash with output file names & paths for the + different DWI to process + - $QCoutdir : output directory to save preprocessed files + - $DTIPrepProtocol: XML `DTIPrep` protocol to use for pre-processing + +RETURNS: + - 1 if at least one raw DWI dataset was successfully preprocessed + - undef if pre-processing was not successful on a least one raw DWI dataset + +### preproc\_mnc2nrrd($raw\_nrrd, $dti\_file) + +Function that converts MINC raw DWI file to NRRD and logs the conversion status. + +INPUTS: + - $raw\_nrrd: raw NRRD file to create + - $dti\_file: raw DWI file to convert to NRRD + +RETURNS: 1 on success, undef on failure + +### preproc\_DTIPrep($QCed\_nrrd, $raw\_nrrd, $DTIPrepProtocol, $QCed2\_nrrd) + +This function will call `&DTI::runDTIPrep` to run `DTIPrep` on the raw NRRD file. + +INPUTS: + - $QCed\_nrrd : QCed DWI NRRD file to be created by `DTIPrep` + - $raw\_nrrd : raw DWI NRRD file to process through `DTIPrep` + - $DTIPrepProtocol: `DTIPrep` XML Protocol to use to run `DTIPrep` + +RETURNS: 1 on success, undef on failure + +### preproc\_copyXMLprotocol($QCProt, $QCoutdir, $DTIPrepProtocol) + +Function that will call `&DTI::copyDTIPrepProtocol` if the XML protocol has +not already been copied in `DTIPrep` QC directory. + +INPUTS: + - $QCProt : copied QC XML protocol (in QC output folder) + - $QCoutdir : QC output directory + - $DTIPrepProtocol: `DTIPrep` XML protocol used to run `DTIPrep` + +RETURNS: 1 on success, undef on failure + +### check\_and\_convertPreprocessedFiles($DTIs\_list, $DTIrefs, $data\_dir, $QCoutdir, $DTIPrepProtocol, $DTIPrepVersion) + +This function will check pre-processing outputs and call +`&convertPreproc2mnc`, which will convert and reinsert headers into MINC file. + +INPUTS: + - $DTIs\_list : list of raw DWI that were pre-processed + - $DTIrefs : hash with list of raw DTIs as a key & + corresponding output names as values + - $data\_dir : directory containing raw DWI dataset + - $QCoutdir : directory containing preprocessed outputs + - $DTIPrepProtocol: `DTIPrep` XML protocol used to run `DTIPrep` + - $DTIPrepVersion : `DTIPrep` version that was run to pre-process images + +RETURNS: + - undef if could not find pre-processed files or convert them to MINC + - 1 if successful conversion & all pre-processing files found in the QC directory + +### checkPreprocessOutputs($dti\_file, $DTIrefs, $QCoutdir, $DTIPrepProtocol) + +Checks if all pre-processing `DTIPrep` files are in the output folder. They +should include: + - QCed NRRD file + - `DTIPrep` QC text report + - `DTIPrep` QC XML report + - a copy of the protocol used to run `DTIPrep` + +Relevant information will also be printed in the log file. + +INPUTS: + - $dti\_file : raw DWI file that was processed + - $DTIrefs : hash containing output names + - $QCoutdir : pre-processing output directory + - $DTIPrepProtocol: `DTIPrep` XML protocol that was used to run `DTIPrep` + +RETURNS: undef if at least one output file is missing; 1 if all output files +were found + +### convertPreproc2mnc($dti\_file, $DTIrefs, $data\_dir, $DTIPrepVersion) + +This function will convert to MINC DTI QCed NRRD file from `DTIPrep` and reinsert +all MINC header information. + +INPUTS: + - $dti\_file : raw DWI file to be processed + - $DTIrefs : hash containing output names + - $data\_dir : directory containing the raw dataset + - $DTIPrepVersion: `DTIPrep` version used to pre-process raw DWI + +RETURNS: 1 if QCed MINC file created and exists; undef otherwise + +### mincdiffusionPipeline($DTIs\_list, $DTIrefs, $data\_dir, $QCoutdir, ...) + +Running post-processing pipeline that will check if post-processing outputs +already exist. If they don't exist, it will call `&runMincdiffusion` to run +the `mincdiffusion` tools. + +INPUTS: + - $DTIs\_list : list with raw DWI to post-process + - $DTIrefs : hash containing output names and paths + - $data\_dir : directory hosting raw DWI dataset + - $QCoutdir : QC process output directory + - $DTIPrepProtocol: `DTIPrep` XML protocol used to run `DTIPrep` + - $mincdiffVersion: `mincdiffusion` version + +RETURNS: 1 if all post-processing outputs found, undef otherwise + +### checkMincdiffusionPostProcessedOutputs($dti\_file, $DTIrefs, $QCoutdir) + +Function that checks if all outputs are present in the QC output directory. + +INPUTS: + - $dti\_file: raw DWI dataset to use as a key in `$DTIrefs` + - $DTIrefs : hash containing output names + - $QCoutdir: QC output directory + +RETURNS: 1 if all post processing outputs were found, undef otherwise + +### runMincdiffusionTools($dti\_file, $DTIrefs, $data\_dir, $QCoutdir, $mincdiffVersion) + +Will create FA, MD and RGB maps. + +INPUTS: + - $dti\_file : raw DWI file that is used as a key in `$DTIrefs` + - $DTIrefs : hash containing output names and paths + - $data\_dir : directory containing raw datasets + - $QCoutdir : QC output directory + - $mincdiffVersion: `mincdiffusion` version used + +RETURNS: 1 on success, undef on failure + +### check\_and\_convert\_DTIPrep\_postproc\_outputs($DTIs\_list, $DTIrefs, $data\_dir, $QCoutdir, $DTIPrepVersion) + +Function that loops through DTI files acquired for the `CandID` and session to +check if `DTIPrep` post processed NRRD files have been created and converts them +to MINC files with relevant header information. + +INPUTS: + - $DTIs\_list : list of DTI files for the session and candidate + - $DTIrefs : hash containing references for DTI output naming + - $data\_dir : directory containing the raw DTI dataset + - $QCoutdir : directory containing the processed data + - $DTIPrepVersion: version of `DTIPrep` used to process the data + +RETURNS: 1 on success, undef on failure + +### register\_processed\_files\_in\_DB($DTIs\_list, $DTIrefs, $profile, $QCoutdir, $DTIPrepVersion, $mincdiffVersion) + +Calls the script `DTIPrepRegister.pl` to register processed files into the +database. + +INPUT: + - $DTIs\_list : list of native DTI files processed + - $DTIrefs : hash containing the processed filenames + - $profile : config file (in `../dicom-archive/.loris_mri`) + - $QCoutdir : output directory containing the processed files + - $DTIPrepVersion : `DTIPrep` version used to obtain QCed files + - $mincdiffVersion: `mincdiffusion` tool version used + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/Element.md b/docs/scripts_md/Element.md new file mode 100644 index 000000000..1fdf201dc --- /dev/null +++ b/docs/scripts_md/Element.md @@ -0,0 +1,170 @@ +# NAME + +DICOM::Element -- Element routines for `DICOM::DICOM` module + +# SYNOPSIS + + use DICOM::Element; + +# DESCRIPTION + +Element routines for `DICOM::DICOM` module to read binary DICOM headers. + +Each element is a hash with the following keys: + - group : group (hex) + - element: element within group (hex) + - offset : offset from file start (dec) + - code : field code eg 'US', 'UI' + - length : field value length (dec) + - name : field descriptive name + - value : value + - header : all bytes up to value, for easy writing + +## Methods + +### new() >> (constructor) + +Creates a new instance of this class. + +RETURNS: a `DICOM::Element` object + +### fill($IN, $dictref) + +Fills in `self` from file. + +INPUTS: + - $IN : input file + - $dictref : DICOM dictionary + +RETURNS: element hash + +### readInt($IN, $bytes, $len). + +Decodes one or more integers that were encoded as a string of bytes +(2 or 4 bytes per number) in the file whose handle is passed as argument. + +INPUTS: + - $IN : input file stream. + - $bytes: SHORT (2) or INT (4) bytes. + - $len : total number of bytes in the field. + +If `fieldlength` > `bytelength`, multiple values are read in and stored as a +string representation of an array. + +RETURNS: string representation of the array of decoded integers + (e.g. '\[34, 65, 900\]') + +### writeInt($OUT, $bytes) + +Encodes each integer stored in string `$this-`{'value'}> as a 2 or 4 byte +string and writes them in a file + +INPUTS: + - $OUT : output file + - $bytes: number of bytes (2 for shorts 4 for integers) in the field + +### readFloat($IN, $format, $len) + +Decodes a floating point number that was encoded as a string of bytes in the +file whose handle is passed as argument. + +INPUTS: + - $IN : input file stream + - $format: format used when decoding (with Perl's `unpack`) the number: + `f` for floats and `d` for doubles + - $len : total number of bytes in the field + +RETURNS: string + +### readSequence($IN, $len) + +Skips over either a fixed number of bytes or over multiple sets of byte +sequences delimited with specific byte values. When doing the latter, +byte `0x00000000` is used to signal the end of the set of sequences. +The sequence of bytes read is always discarded. + +Three different cases: + - implicit Value Representation (VR), explicit length + - explicit VR, undefined length, items of defined length (w/end delimiter) + - implicit VR, undefined length, items of undefined length + +INPUTS: + - $IN : input file stream + - $len: total number of bytes to skip, or 0 if all sequences should be + skipped until the delimiter `0x00000000` is found + +RETURNS: 'skipped' string + +### readLength($IN) + +Reads the length of a VR from a file, as an integer encoded on 16 or 32 bits. + - Implicit Value Representation (VR): Length is 4 byte int. + - Explicit VR: 2 bytes hold VR, then 2 byte length. + +INPUT: input file stream + +RETURNS: the VR code (string of length 2) and the length of the associated + VR value + +### values() + +Returns the properties of a VR: group, element, offset, code, length, name and +value. + +RETURNS: the properties of a VR: group, element, offset, code, length, name and + value + +### print() + +Prints formatted representation of element to `STDOUT`. + +### valueString() + +Returns a string representation of the value field. + +RETURNS: string representation of the value field, or null if value field is + binary + +### write($OUTFILE) + +Writes this data element to disk. All fields up to value are stored in +immutable field 'header' - write this to disk then value field. + +INPUT: output file + +### value() + +Returns the value of the field. + +RETURNS: value field + +### setValue($value) + +Sets the value field of this element. Truncates to max length. + +INPUT: value field + +### byteswap($valref) + +Swaps byte. + +INPUT: value reference + +# TO DO + +Better documentation of the following functions: + - readInt() + - readFloat() + - readSequence($IN, $len) + - readLength($IN) + - writeInt($OUT, $bytes) + - byteswap($valref) + +# LICENSING + +License: GPLv3 + +# AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/ExitCodes.md b/docs/scripts_md/ExitCodes.md index 2912d71f8..69f73c68e 100644 --- a/docs/scripts_md/ExitCodes.md +++ b/docs/scripts_md/ExitCodes.md @@ -43,22 +43,23 @@ Below is a list of the possible exit codes: 5\. Common file manipulation failures (exit codes from 60 to 79) -6\. Common other generic failures (exit codes from 80 to 149) +6\. Other common generic failures (exit codes from 80 to 149) \##### ---- SECTION 2: SCRIPT SPECIFIC EXIT CODES NOT COVERED IN SECTION 1 -7\. Exit codes from batch\_uploads\_imageuploader (exit codes from 150 to 159) +7\. Exit codes from `batch_uploads_imageuploader` (exit codes from 150 to 159) -8\. Exit codes from DTIPrep/DTIPrepRegister.pl (exit codes from 160 to 169) +8\. Exit codes from `DTIPrep/DTIPrepRegister.pl` (exit codes from 160 to 169) -9\. Exit codes from uploadNeuroDB/NeuroDB/ImagingUpload.pm (exit codes from +9\. Exit codes from `uploadNeuroDB/NeuroDB/ImagingUpload.pm` (exit codes from 170 to 179) -11\. Exit codes from uploadNeuroDB/minc\_insertion.pl (exit codes from 180 to 189) +10\. Exit codes from `uploadNeuroDB/minc_insertion.pl` (exit codes from 180 +to 189) -12\. Exit codes from uploadNeuroDB/tarchiveLoader (exit codes from 190 to 199) +11\. Exit codes from `uploadNeuroDB/tarchiveLoader` (exit codes from 190 to 199) -13\. Exit codes from uploadNeuroDB/NeuroDB/bin/minc2jiv.pl (exit codes from 200 +12\. Exit codes from former scripts that have been removed (exit codes from 200 to 210) # LICENSING diff --git a/docs/scripts_md/Fields.md b/docs/scripts_md/Fields.md new file mode 100644 index 000000000..295153742 --- /dev/null +++ b/docs/scripts_md/Fields.md @@ -0,0 +1,59 @@ +# NAME + +DICOM::Fields -- Definitions of fields of DICOM headers. + +# SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize dictionary. + # Read the contents of the DICOM dictionary into a hash by group and element. + # dicom_private is read after dicom_fields, so overrides common fields. + BEGIN { + foreach my $line (@dicom_fields, @dicom_private) { + next if ($line =~ /^\#/); + my ($group, $elem, $code, $numa, $name) = split(/\s+/, $line); + my @lst = ($code, $name); + $dict{$group}{$elem} = [@lst]; + } + } + +# DESCRIPTION + +Definitions of fields of DICOM headers. This file is provided purely for +experimental use. + +Simply creating an array of: + + 0000 0000 UL 1 GroupLength + 0000 0001 UL 1 CommandLengthToEnd + 0000 0002 UI 1 AffectedSOPClassUID + 0000 0003 UI 1 RequestedSOPClassUID + 0000 0010 CS 1 CommandRecognitionCode + 0000 0100 US 1 CommandField + 0000 0110 US 1 MessageID + 0000 0120 US 1 MessageIDBeingRespondedTo + 0000 0200 AE 1 Initiator + 0000 0300 AE 1 Receiver + 0000 0400 AE 1 FindLocation + 0000 0600 AE 1 MoveDestination + 0000 0700 US 1 Priority + 0000 0800 US 1 DataSetType + 0000 0850 US 1 NumberOfMatches + 0000 0860 US 1 ResponseSequenceNumber + 0000 0900 US 1 Status + 0000 0901 AT 1-n OffendingElement + 0000 0902 LO 1 ErrorComment + 0000 0903 US 1 ErrorID + ... + +# LICENSING + +License: GPLv3 + +# AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/File.md b/docs/scripts_md/File.md index fd755e0c6..71b2896a3 100644 --- a/docs/scripts_md/File.md +++ b/docs/scripts_md/File.md @@ -63,8 +63,8 @@ RETURNS: 0 if no file was found, 1 otherwise. ### findFile($filename) -Finds the FileID pertaining to a file as defined by parameter `$filename`, -which is a full /path/to/file. +Finds the `FileID` pertaining to a file as defined by parameter `$filename`, +which is a full `/path/to/file`. INPUT: full path to the file to look for an ID in the database. @@ -110,6 +110,16 @@ Gets the database handle reference which the object is using internally. RETURNS: DBI database handle reference. +### getFileType($file) + +Determines the imaging file type based on the extension of the file to insert +and the list of available types in the `ImagingFileTypes` table of the +database. + +INPUT: the path to the imaging file to determine the file type + +RETURNS: the type of the imaging file given as an argument + ### loadFileFromDisk($filename) Reads the headers from the file specified by `$filename` and loads the current @@ -123,13 +133,17 @@ RETURNS: 0 if any failure occurred or 1 otherwise. Sets the fileData property named `$propertyName` to the value of `$value`. -INPUT: name of the fileData property, value of the fileData property to be set +INPUTS: + - $paramName: name of the `fileData` property + - $value : value of the `fileData` property to be set ### setParameter($parameterName, $value) Sets the parameter named `$parameterName` to the value of `$value`. -INPUT: name of the parameter, value of the parameter to be set +INPUTS: + - $paramName: name of the parameter + - $value : value of the parameter to be set ### removeParameter($parameterName) @@ -139,12 +153,12 @@ INPUT: name of the parameter to remove ### getParameterTypeID($parameter) -Gets the ParameterTypeID for the parameter `$parameter`. If `$parameter` +Gets the `ParameterTypeID` for the parameter `$parameter`. If `$parameter` does not exist, it will be created. INPUT: name of the parameter type -RETURNS: (int) ParameterTypeID +RETURNS: `ParameterTypeID` (int) ### removeWhitespace($value) @@ -159,9 +173,7 @@ RETURNS: string or array of the value without white spaces Other operations should be added: perhaps `get*` methods for those fields in the `files` table which are lookup fields. -# BUGS - -None reported. +Fix comments written as #fixme in the code. # COPYRIGHT AND LICENSE diff --git a/docs/scripts_md/FileDecompress.md b/docs/scripts_md/FileDecompress.md index ac3e4555c..9cacf49fc 100644 --- a/docs/scripts_md/FileDecompress.md +++ b/docs/scripts_md/FileDecompress.md @@ -58,14 +58,6 @@ This function will return the type of the archive RETURNS: type of the archive -# TO DO - -Nothing planned. - -# BUGS - -None reported - # COPYRIGHT AND LICENSE License: GPLv3 diff --git a/docs/scripts_md/ImagingUpload.md b/docs/scripts_md/ImagingUpload.md index 3dfa4915f..add737596 100644 --- a/docs/scripts_md/ImagingUpload.md +++ b/docs/scripts_md/ImagingUpload.md @@ -42,10 +42,10 @@ moved to a final destination directory. INPUTS: - $dbhr : database handler - $uploaded\_temp\_folder: temporary directory of the upload - - $upload\_id : uploadID from the mri\_upload table + - $upload\_id : `uploadID` from the `mri_upload` table - $pname : patient name - - $profile : name of the configuration file - (typically `prod`) + - $profile : name of the configuration file in + `/data/$PROJECT/data` (typically `prod`) RETURNS: new instance of this class @@ -62,7 +62,7 @@ RETURNS: 1 on success, 0 on failure This method executes the following actions: - Runs `dicomTar.pl` with `-clobber -database -profile prod` options - - Extracts the TarchiveID of the DICOM archive created by `dicomTar.pl` + - Extracts the `TarchiveID` of the DICOM archive created by `dicomTar.pl` - Updates the `mri_upload` table if `dicomTar.pl` ran successfully RETURNS: 1 on success, 0 on failure @@ -86,7 +86,7 @@ RETURNS: 1 on success, 0 on failure This method extracts the patient name field from the DICOM file header using `dcmdump` and compares it with the patient name information stored in the -mri\_upload table. +`mri_upload` table. INPUT: full path to the DICOM file @@ -112,17 +112,17 @@ RETURNS: the exit code of the command ### runCommand($command) This method will run any linux command given as an argument using back-tilt -and will return the back-tilt return value (which is STDOUT). +and will return the back-tilt return value (which is `STDOUT`). INPUT: the linux command to be executed -RETURNS: back-tilt return value (STDOUT) +RETURNS: back-tilt return value (`STDOUT`) ### CleanUpDataIncomingDir($uploaded\_file) This method cleans up and removes the uploaded file from the data directory once the uploaded file has been inserted into the database and saved in the -tarchive folder. +`tarchive` folder. RETURNS: 1 on success, 0 on failure @@ -147,14 +147,6 @@ INPUTS: - $field: name of the column in the table to be updated - $value: value of the column to be set -# TO DO - -Nothing planned. - -# BUGS - -None reported - # COPYRIGHT AND LICENSE License: GPLv3 diff --git a/docs/scripts_md/MRI.md b/docs/scripts_md/MRI.md index 505e972c5..9c2f943f4 100644 --- a/docs/scripts_md/MRI.md +++ b/docs/scripts_md/MRI.md @@ -31,41 +31,51 @@ all of its children. ### getSubjectIDs($patientName, $scannerID, $dbhr) Determines the candidate ID and visit label for the subject based on patient -name and (for calibration data) scannerID. +name and (for calibration data) scanner ID. -INPUTS: patient name, scanner ID and database handle reference +INPUTS: + - $patientName: patient name + - $scannerID : scanner ID + - $dbhr : database handle reference RETURNS: a reference to a hash containing elements including `CandID`, `visitLabel` and `visitNo`, or, in the case of failure, `undef` -### subjectIDIsValid($CandID, $PSCID, $dbhr) +### subjectIDIsValid($CandID, $PSCID, $visit\_label, $dbhr, $create\_visit\_label) Verifies that the subject IDs match. -INPUTS: candidate's CandID, candidate's PSCID and the database handle reference +INPUTS: + - $candID : candidate's `CandID` + - $pscid : candidate's `PSCID` + - $visit\_label : visit label + - $dbhr : the database handle reference + - $create\_visit\_label: boolean, if true, will create the visit label RETURNS: 1 if the ID pair matches, 0 otherwise ### subjectIDExists($CandID, $dbhr) -Verifies that the subject ID (CandID) exists. +Verifies that the subject ID (`CandID`) exists. -INPUTS: candidate's CandID and the database handle reference +INPUTS: + - $candID: candidate's `CandID` + - $dbhr : the database handle reference RETURNS: 1 if the ID exists, 0 otherwise ### getScannerCandID($scannerID, $dbhr) -Retrieves the candidate (CandID) for the given scanner. +Retrieves the candidate (`CandID`) for the given scanner. INPUTS: the scanner ID and the database handle reference -RETURNS: the CandID or (if none exists) undef +RETURNS: the `CandID` or (if none exists) undef -### getSessionID($subjectIDref, $studyDate, $dbhr, $objective, ...) +### getSessionID($subjectIDref, $studyDate, $dbhr, $objective, $noStagingCheck) -Gets (or creates) the session ID, given CandID and visitLabel (contained -inside the hashref `$subjectIDref`). Unless `$noStagingCheck` is true, it +Gets (or creates) the session ID, given `CandID` and visit label (contained +inside the hash ref `$subjectIDref`). Unless `$noStagingCheck` is true, it also determines whether staging is required using the `$studyDate` (formatted YYYYMMDD) to determine whether staging is required based on a simple algorithm: @@ -82,27 +92,35 @@ simple algorithm: > > \- Otherwise, staging is not required. -INPUTS: hash reference of subject IDs, study date, database handle reference, -the objective of the study and a no staging check flag. +INPUTS: + - $subjectIDref : hash reference of subject IDs + - $studyDate : study date + - $dbhr : database handle reference + - $objective : the objective of the study + - $noStagingCheck: a no staging check flag -RETURNS: a list of two items, (sessionID, requiresStaging) +RETURNS: a list of two items, (`sessionID`, `requiresStaging`) ### checkMRIStudyDates($studyDateJD, $dbhr, @fileIDs) This method tries to figure out if there may have been labelling problems which would put the files in a staging area that does not actually exist. -INPUTS: study date, database handle reference and array of fileIDs to check the -study date +INPUTS: + - $studyDateJD: study date + - $dbhr : database handle reference + - @fileIDs : array of `fileIDs` to check the study date RETURNS: 1 if the file requires staging, 0 otherwise ### getObjective($subjectIDsref, $dbhr) -Attempts to determine the SubprojectID of a timepoint given the subjectIDs -hashref `$subjectIDsref` and a database handle reference `$dbhr` +Attempts to determine the `SubprojectID` of a timepoint given the subject IDs +hash ref `$subjectIDsref` and a database handle reference `$dbhr` -INPUTS: subjectIDs hashref and database handle reference +INPUTS: + - $subjectIDsref: subjectIDs hashref + - $dbhr : database handle reference RETURNS: the determined objective, or 0 @@ -111,12 +129,15 @@ RETURNS: the determined objective, or 0 Determines the type of the scan described by MINC headers based on `mri_protocol` table in the database. -INPUTS: center's name, objective of the study, file hashref, database handle -reference +INPUTS: + - $center\_name: center's name + - $objective : objective of the study + - $fileref : file hash ref + - $dbhr : database handle reference RETURNS: textual name of scan type from the `mri_scan_type` table -### insert\_violated\_scans($dbhr, $series\_desc, $minc\_location, ...) +### insert\_violated\_scans($dbhr, $series\_desc, $minc\_location, $patient\_name, $candid, $pscid, $visit, $tr, $te, $ti, $slice\_thickness, $xstep, $ystep, $zstep, $xspace, $yspace, $zspace, $time, $seriesUID) Inserts scans that do not correspond to any of the defined protocol from the `mri_protocol` table into the `mri_protocol_violated_scans` table of the @@ -125,29 +146,31 @@ database. INPUTS: - $dbhr : database handle reference - $series\_desc : series description of the scan - - $minc\_location : minc location of the file + - $minc\_location : location of the MINC file - $patient\_name : patient name of the scan - - $candid : candidate's CandID - - $pscid : candidate's PSCID + - $candid : candidate's `CandID` + - $pscid : candidate's `PSCID` - $visit : visit of the scan - $tr : repetition time of the scan - $te : echo time of the scan - $ti : inversion time of the scan - $slice\_thickness: slice thickness of the image - - $xstep : x-step of the image - - $ystep : y-step of the image - - $zstep : z-step of the image - - $xspace : x-space of the image - - $yspace : y-space of the image - - $zspace : z-space of the image + - $xstep : `x-step` of the image + - $ystep : `y-step` of the image + - $zstep : `z-step` of the image + - $xspace : `x-space` of the image + - $yspace : `y-space` of the image + - $zspace : `z-space` of the image - $time : time dimension of the scan - - $seriesUID : seriesUID of the scan + - $seriesUID : `SeriesUID` of the scan ### debug\_inrange($val, $range) Will evaluate whether the scalar `$value` is in the specified `$range`. -INPUTS: scalar value, scalar range string +INPUTS: + - $val : scalar value to evaluate + - $range: scalar range string RETURNS: 1 if in range, 0 if not in range @@ -155,7 +178,9 @@ RETURNS: 1 if in range, 0 if not in range Determines the type of the scan identified by its scan type ID. -INPUTS: scan type ID and database handle reference +INPUTS: + - $typeID: scan type ID + - $dbhr : database handle reference RETURNS: Textual name of scan type @@ -163,26 +188,33 @@ RETURNS: Textual name of scan type Determines the type of the scan identified by scan type. -INPUTS: scan type and database handle reference +INPUTS: + - $type: scan type + - $dbhr: database handle reference RETURNS: ID of the scan type ### in\_range($value, $range\_string) Determines whether numerical value falls within the range described by range -string. Range string is a comma-separated list of range units. A single range -unit follows the syntax either "X" or "X-Y". +string. Range string is a single range unit which follows the syntax +"X" or "X-Y". -INPUTS: numerical value and the range to use +INPUTS: + - $value : numerical value to evaluate + - $range\_string: the range to use RETURNS: 1 if the value is in range, 0 otherwise ### floats\_are\_equal($f1, $f2, $nb\_decimals) -Checks whether f1 and f2 are equal (considers only the first nb\_decimals -decimals). +Checks whether float 1 and float 2 are equal (considers only the first +`$nb_decimals` decimals). -INPUTS: float 1, float 2 and the number of first decimals +INPUTS: + - $f1 : float 1 + - $f2 : float 2 + - $nb\_decimals: the number of first decimals RETURNS: 1 if the numbers are relatively equal, 0 otherwise @@ -193,31 +225,34 @@ Generates a valid SQL WHERE expression to test `$field` against It returns a scalar range SQL string appropriate to use as a WHERE condition (`SELECT ... WHERE range_to_sql(...)`). -INPUTS: scalar field, scalar range string that follows the same format as in -`&in_range()` +INPUTS: + - $field : scalar field + - $range\_string: scalar range string that follows the same format as in + `&in_range()` RETURNS: scalar range SQL string ### register\_db($file\_ref) -Registers the NeuroDB::File object referenced by `$file_ref` into the database. +Registers the `NeuroDB::File` object referenced by `$file_ref` into the +database. -INPUT: file hashref +INPUT: file hash ref -RETURNS: 0 if the file is already registered, the new FileID otherwise +RETURNS: 0 if the file is already registered, the new `FileID` otherwise ### mapDicomParameters($file\_ref) -Maps DICOM parameters to more meaningful names in the NeuroDB::File object +Maps DICOM parameters to more meaningful names in the `NeuroDB::File` object referenced by `$file_ref`. -INPUT: file hashref +INPUT: file hash ref -### findScannerID($manufacturer, $model, $serialNumber, ...) +### findScannerID($manufacturer, $model, $serialNumber, $softwareVersion, $centerID, $dbhr, $register\_new) -Finds the scannerID for the scanner as defined by `$manufacturer`, `$model`, +Finds the scanner ID for the scanner as defined by `$manufacturer`, `$model`, `$serialNumber`, `$softwareVersion`, using the database attached to the DBI -database handle reference `$dbhr`. If no scannerID exists, one will be +database handle reference `$dbhr`. If no scanner ID exists, one will be created. INPUTS: @@ -231,7 +266,7 @@ INPUTS: RETURNS: (int) scanner ID -### registerScanner($manufacturer, $model, $serialNumber, ...) +### registerScanner($manufacturer, $model, $serialNumber, $softwareVersion, $centerID, $dbhr) Registers the scanner as defined by `$manufacturer`, `$model`, `$serialNumber`, `$softwareVersion`, into the database attached to the DBI @@ -249,36 +284,40 @@ RETURNS: (int) scanner ID ### createNewCandID($dbhr) -Creates a new CandID. +Creates a new `CandID`. INPUT: database handle reference -RETURNS: (int) CandID +RETURNS: `CandID` (int) ### getPSC($patientName, $dbhr) -Looks for the site alias in whatever field (usually patient\_name or -patient\_id) is provided and return the MRI alias and CenterID. +Looks for the site alias using the `session` table `CenterID` as +a first resource, for the cases where it is created using the front-end, +otherwise, find the site alias in whatever field (usually `patient_name` +or `patient_id`) is provided, and return the `MRI_alias` and `CenterID`. -INPUTS: patient name, database handle reference +INPUTS: + - $patientName: patient name + - $dbhr : database handle reference RETURNS: a two element array: - first is the MRI alias of the PSC or "UNKN" - - second is the centerID or 0 + - second is the `CenterID` or 0 ### compute\_hash($file\_ref) -Semi-intelligently generates a hash (MD5 digest) for the NeuroDB::File object +Semi-intelligently generates a hash (MD5 digest) for the `NeuroDB::File` object referenced by `$file_ref`. -INPUT: file hashref +INPUT: file hash ref RETURNS: the generated MD5 hash ### is\_unique\_hash($file\_ref) Determines if the file is unique using the hash (MD5 digest) from the -NeuroDB::File object referenced by `$file_ref`. +`NeuroDB::File` object referenced by `$file_ref`. INPUT: file hashref @@ -292,42 +331,30 @@ object referenced by `$file_ref`. INPUTS: - $file\_ref : file hash ref - - $data\_dir : data directory (`/data/$PROJECT/data` typically) - - $dest\_dir : destination directory (`/data/$PROJECT/data/pic` - typically) + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $dest\_dir : destination directory (e.g. `/data/$PROJECT/data/pic`) - $horizontalPics: boolean, whether to create horizontal pics (1) or not (0) RETURNS: 1 if the pic was generated or 0 otherwise. -### make\_jiv($file\_ref, $data\_dir, $dest\_dir) - -Generates JIV data for the Imaging Browser module for the `NeuroDB::File` -object referenced by `$file_ref`. - -INPUTS: - - $file\_ref : file hash ref - - $data\_dir : data directory (`/data/$PROJECT/data` typically) - - $dest\_dir : destination directory (`/data/$PROJECT/data/jiv` - typically) - -RETURNS: 1 if the JIV data was generated or 0 otherwise. - ### make\_nii($fileref, $data\_dir) Creates NIfTI files associated with MINC files and append its path to the -parameter\_file table using the parameter\_type "check\_nii\_filename". +`parameter_file` table using the `parameter_type` `check_nii_filename`. -INPUTS: file hashref and data directory (typically `/data/project/data`) +INPUTS: + - $fileref : file hash ref + - $data\_dir: data directory (e.g. `/data/$PROJECT/data`) -### make\_minc\_pics($dbhr, $TarchiveSource, $profile, $minFileID, ...) +### make\_minc\_pics($dbhr, $TarchiveSource, $profile, $minFileID, $debug, $verbose) Creates pics associated with MINC files. INPUTS: - $dbhr : database handle reference - - $TarchiveSource: tarchiveID of the DICOM study - - $profile : the profile (typically named `prod`) - - $minFileID : smaller FileID to be used to run `mass_pic.pl` + - $TarchiveSource: `TarchiveID` of the DICOM study + - $profile : the profile file (typically named `prod`) + - $minFileID : smaller `FileID` to be used to run `mass_pic.pl` - $debug : boolean, whether in debug mode (1) or not (0) - $verbose : boolean, whether in verbose mode (1) or not (0) @@ -341,19 +368,17 @@ RETURNS: a unix timestamp (integer) or 0 if something went wrong ### lookupCandIDFromPSCID($pscid, $dbhr) -Looks up the CandID for a given PSCID. +Looks up the `CandID` for a given `PSCID`. -INPUTS: candidate's PSCID, database handle reference +INPUTS: + - $pscid: candidate's `PSCID` + - $dbhr : database handle reference -RETURNS: the CandID or 0 if the PSCID does not exist +RETURNS: the `CandID` or 0 if the `PSCID` does not exist # TO DO -Nothing planned. - -# BUGS - -None reported. +Fix comments written as #fixme in the code. # COPYRIGHT AND LICENSE @@ -365,5 +390,4 @@ License: GPLv3 # AUTHORS Jonathan Harlap , -LORIS community -and McGill Centre for Integrative Neuroscience +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/MRIProcessingUtility.md b/docs/scripts_md/MRIProcessingUtility.md index 6017d4f67..78965107a 100644 --- a/docs/scripts_md/MRIProcessingUtility.md +++ b/docs/scripts_md/MRIProcessingUtility.md @@ -30,8 +30,7 @@ utilities ); my $CandMismatchError = $utility->validateCandidate( - $subjectIDsref, - $tarchiveInfo{'SourceLocation'} + $subjectIDsref ); $utility->computeSNR($TarchiveID, $ArchLoc, $profile); @@ -46,11 +45,11 @@ scripts of LORIS. ### new($dbhr, $debug, $TmpDir, $logfile, $verbose) >> (constructor) -Creates a new instance of this class. The parameter \`\\$dbhr\` is a reference -to a DBI database handle, used to set the object's database handle, so that all -the DB-driven methods will work. +Creates a new instance of this class. The parameter `$dbhr` is a reference +to a `DBI` database handle, used to set the object's database handle, so that +all the DB-driven methods will work. -INPUT: DBI database handle +INPUT: `DBI` database handle RETURNS: new instance of this class. @@ -59,81 +58,104 @@ RETURNS: new instance of this class. Writes error log. This is a useful function that will close the log and write error messages in case of abnormal program termination. -INPUTS: notification message, fail status of the process, log directory +INPUTS: + - $message : notification message + - $failStatus: fail status of the process + - $LogDir : log directory -### lookupNextVisitLabel($candID, $dbhr) +### lookupNextVisitLabel($CandID, $dbhr) Will look up for the next visit label of candidate `CandID`. Useful only if the visit label IS NOT encoded somewhere in the patient ID or patient name. -INPUTS: candidate's CandID, database handle reference +INPUTS: + - $CandID: candidate's `CandID` + - $dbhr : database handle reference RETURNS: next visit label found for the candidate ### getFileNamesfromSeriesUID($seriesuid, @alltarfiles) Will extract from the `tarchive_files` table a list of DICOM files -matching a given SeriesUID. +matching a given `SeriesUID`. -INPUTS: seriesUID, list of tar files +INPUTS: + - $seriesUID : `SeriesUID` to use for matching + - @alltarfiles: list of DICOM files matching the `SeriesUID` -RETURNS: list of DICOM files corresponding to the seriesUID +RETURNS: list of DICOM files corresponding to the `SeriesUID` -### extract\_tarchive($tarchive, $tarchive\_srcloc, $seriesuid) +### extract\_tarchive($tarchive, $upload\_id, $seriesuid) Extracts the DICOM archive so that data can actually be uploaded. -INPUTS: path to the DICOM archive, source location from the `tarchive` table, -(optionally seriesUID) +INPUTS: + - $tarchive : path to the DICOM archive + - $upload\_id: upload ID of the study + - $seriesuid: optionally a series UID RETURNS: the extracted DICOM directory -### extractAndParseTarchive($tarchive, $tarchive\_srcloc, $seriesuid) +### extractAndParseTarchive($tarchive, $upload\_id, $seriesuid) -Extracts and parses the tarchive. +Extracts and parses the DICOM archive. -INPUTS: path to the tarchive, source location from the tarchive table, -(optionally seriesUID) +INPUTS: + - $tarchive : path to the DICOM archive + - $upload\_id: upload ID of the study + - $seriesuid: optionally a series UID -RETURNS: extract suffix, extracted DICOM directory, tarchive meta data header +RETURNS: + - $ExtractSuffix: extract suffix + - $study\_dir : extracted study directory + - $header : study meta data header -### determineSubjectID($scannerID, $tarchiveInfo, $to\_log) +### determineSubjectID($scannerID, $tarchiveInfo, $to\_log, $upload\_id) -Determines subject's ID based on scanner ID and tarchive information. +Determines subject's ID based on scanner ID and DICOM archive information. -INPUTS: scanner ID, tarchive information hashref, boolean if this step should -be logged +INPUTS: + - $scannerID : scanner ID, + - $tarchiveInfo: DICOM archive information hash ref, + - $to\_log : boolean if this step should be logged + - $upload\_id : upload ID of the study -RETURNS: subject's ID hashref containing CandID, PSCID and Visit Label +RETURNS: subject's ID hash ref containing `CandID`, `PSCID` and Visit Label information ### createTarchiveArray($tarchive, $globArchiveLocation) -Creates the tarchive information hashref. +Creates the DICOM archive information hash ref. -INPUTS: tarchive's path, globArchiveLocation argument specified when running -the insertion scripts +INPUTS: + - $tarchive : tarchive's path + - $globArchiveLocation: globArchiveLocation argument specified when running + the insertion scripts -RETURNS: tarchive information hashref +RETURNS: DICOM archive information hash ref -### determinePSC($tarchiveInfo, $to\_log) +### determinePSC($tarchiveInfo, $to\_log, $upload\_id) -Determines the PSC based on the tarchive information hashref. +Determines the PSC based on the DICOM archive information hash ref. -INPUTS: tarchive information hashref, whether this step should be logged +INPUTS: + - $tarchiveInfo: DICOM archive information hash ref + - $to\_log : boolean, whether this step should be logged + - $upload\_id : upload ID of the study RETURNS: array of two elements: center name and center ID -### determineScannerID($tarchiveInfo, $to\_log, $centerID, $NewScanner) +### determineScannerID($tarchiveInfo, $to\_log, $centerID, $NewScanner, $upload\_id) Determines which scanner ID was used for DICOM acquisitions. INPUTS: - - $tarchiveInfo: tarchive information hashref + - $tarchiveInfo: archive information hash ref - $to\_log : whether this step should be logged - $centerID : center ID - $NewScanner : whether a new scanner entry should be created if the scanner used is a new scanner for the study + - $upload\_id : upload ID of the study RETURNS: scanner ID @@ -141,15 +163,17 @@ RETURNS: scanner ID UNUSED -### computeMd5Hash($file, $tarchive\_srcloc) +### computeMd5Hash($file, $upload\_id) Computes the MD5 hash of a file and makes sure it is unique. -INPUTS: file to use to compute the MD5 hash, tarchive source location +INPUTS: + - $file : file to use to compute the MD5 hash + - $upload\_id: upload ID of the study RETURNS: 1 if the file is unique, 0 otherwise -### getAcquisitionProtocol($file, $subjectIDsref, $tarchiveInfo, ...) +### getAcquisitionProtocol($file, $subjectIDsref, $tarchiveInfo, $center\_name, $minc, $acquisitionProtocol, $bypass\_extra\_file\_checks, $upload\_id) Determines the acquisition protocol and acquisition protocol ID for the MINC file. If `$acquisitionProtocol` is not set, it will look for the acquisition @@ -159,15 +183,19 @@ true, then it will bypass the additional protocol checks from the `mri_protocol_checks` table using `&extra_file_checks`. INPUTS: - - $file : file's information hashref - - $subjectIDsref : subject's information hashref - - $tarchiveInfo : tarchive's information hashref + - $file : file's information hash ref + - $subjectIDsref : subject's information hash ref + - $tarchiveInfo : DICOM archive's information hash ref - $center\_name : center name - $minc : absolute path to the MINC file - $acquisitionProtocol : acquisition protocol if already knows it - $bypass\_extra\_file\_checks: boolean, if set bypass the extra checks + - $upload\_id : upload ID of the study -RETURNS: acquisition protocol, acquisition protocol ID, array of extra checks +RETURNS: + - $acquisitionProtocol : acquisition protocol + - $acquisitionProtocolID : acquisition protocol ID + - $extra\_validation\_status : extra validation status ("pass", "exclude", "warning") ### extra\_file\_checks($scan\_type, $file, $CandID, $Visit\_Label, $PatientName) @@ -176,8 +204,8 @@ this information here since the file isn't registered in the database yet. INPUTS: - $scan\_type : scan type of the file - - $file : file information hashref - - $CandID : candidate's CandID + - $file : file information hash ref + - $CandID : candidate's `CandID` - $Visit\_Label: visit label of the scan - $PatientName: patient name of the scan @@ -185,69 +213,107 @@ RETURNS: - pass, warn or exclude flag depending on the worst failed check - array of failed checks if any were failed +### loop\_through\_protocol\_violations\_checks($scan\_type, $severity, $headers, $file) + +Loops through all protocol violations checks for a given severity and creates +a hash with all the checks that need to be applied on that specific scan type +and severity. + +INPUTS: + - $scan\_type: scan type of the file + - $severity : severity of the checks we want to loop through (exclude or warning) + - $headers : list of different headers found in the `mri_protocol_checks` + table for a given scan type + - $file : file information hash ref + +RETURNS: a hash with all information about the checks for a given scan type +and severity + +### insert\_into\_mri\_violations\_log($valid\_fields, $severity, $pname, $candID, $visit\_label, $file) + +For a given protocol failure, it will insert into the `mri_violations_log` +table all the information about the scan and the protocol violation. + +INPUTS: + - $valid\_fields: string with valid values for the header and scan type + - $severity : severity of the violation ("exclude" or "warning") + - $pname : Patient name associated with the scan + - $candID : `CandID` associated with the scan + - $visit\_label : visit label associated with the scan + - $file : information about the scan + ### update\_mri\_acquisition\_dates($sessionID, $acq\_date) -Updates the mri\_acquisition\_dates table by a new acquisition date `$acq_date`. +Updates the `mri_acquisition_dates` table by a new acquisition date +`$acq_date`. -INPUTS: session ID, acquisition date +INPUTS: + - $sessionID: session ID + - $acq\_date : acquisition date -### loadAndCreateObjectFile($minc, $tarchive\_srcloc) +### loadAndCreateObjectFile($minc, $upload\_id) Loads and creates the object file. -INPUTS: location of the minc file, tarchive source location +INPUTS: + - $minc : location of the minc file + - $upload\_id: upload ID of the study -RETURNS: file information hashref +RETURNS: file information hash ref -### move\_minc($minc, $subjectIDsref, $minc\_type, $fileref, $prefix, ...) +### move\_minc($minc, $subjectIDsref, $minc\_type, $fileref, $prefix, $data\_dir, $tarchive\_srcloc, $upload\_id) Renames and moves the MINC file. INPUTS: - $minc : path to the MINC file - - $subjectIDsref : subject's ID hashref - - $minc\_type : MINC file information hashref - - $fileref : file information hashref + - $subjectIDsref : subject's ID hash ref + - $minc\_type : MINC file information hash ref + - $fileref : file information hash ref - $prefix : study prefix - - $data\_dir : data directory (typically /data/project/data) - - $tarchive\_srcloc: tarchive source location + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) + - $tarchive\_srcloc: DICOM archive source location + - $upload\_id : upload ID of the study RETURNS: new name of the MINC file with path relative to `$data_dir` -### registerScanIntoDB($minc\_file, $tarchiveInfo, $subjectIDsref, ...) +### registerScanIntoDB($minc\_file, $tarchiveInfo, $subjectIDsref, $acquisitionProtocol, $minc, $extra\_validation\_status, $reckless, $sessionID, $upload\_id) Registers the scan into the database. INPUTS: - - $minc\_file : MINC file information hashref - - $tarchiveInfo : tarchive information hashref - - $subjectIDsref : subject's ID information hashref - - $acquisitionProtocol: acquisition protocol - - $minc : MINC file to register into the database - - $checks : failed checks to register with the file - - $reckless : boolean, if reckless or not - - $tarchive : tarchive path - - $sessionID : session ID of the MINC file + - $minc\_file : MINC file information hash ref + - $tarchiveInfo : tarchive information hash ref + - $subjectIDsref : subject's ID information hash ref + - $acquisitionProtocol : acquisition protocol + - $minc : MINC file to register into the database + - $$extra\_validation\_status: extra validation status (if 'exclude', then + will not register the scan in the files table) + - $reckless : boolean, if reckless or not + - $sessionID : session ID of the MINC file + - $upload\_id : upload ID of the study RETURNS: acquisition protocol ID of the MINC file -### dicom\_to\_minc($study\_dir, $converter, $get\_dicom\_info, $exclude, ...) +### dicom\_to\_minc($study\_dir, $converter, $get\_dicom\_info, $exclude, $mail\_user, $upload\_id) Converts a DICOM study into MINC files. INPUTS: - $study\_dir : DICOM study directory to convert - $converter : converter to be used - - $get\_dicom\_info : get DICOM information setting from the Config table - - $exclude : which files to exclude from the dcm2mnc command + - $get\_dicom\_info : get DICOM information setting from the `Config` table + - $exclude : which files to exclude from the `dcm2mnc` command - $mail\_user : mail of the user - - $tarchive\_srcloc: tarchive source location + - $upload\_id : upload ID of the study -### get\_mincs($minc\_files, $tarchive\_srcloc) +### get\_mincs($minc\_files, $upload\_id) Greps the created MINC files and returns a sorted list of those MINC files. -INPUTS: empty array to store the list of MINC files, tarchive source location +INPUTS: + - $minc\_files: empty array to store the list of MINC files + - $upload\_id : upload ID of the study ### concat\_mri($minc\_files) @@ -261,79 +327,97 @@ Register programs. INPUT: program to register -### moveAndUpdateTarchive($tarchive\_location, $tarchiveInfo) +### moveAndUpdateTarchive($tarchive\_location, $tarchiveInfo, $upload\_id) -Moves and updates the tarchive table with the new location of the tarchive. +Moves and updates the `tarchive` table with the new location of the +DICOM archive. -INPUTS: tarchive location, tarchive information hashref +INPUTS: + - $tarchive\_location: DICOM archive location + - $tarchiveInfo : DICOM archive information hash ref + - $upload\_id : upload ID of the study -RETURNS: the new tarchive location +RETURNS: the new DICOM archive location -### CreateMRICandidates($subjectIDsref, $gender, $tarchiveInfo, $User, ...) +### CreateMRICandidates($subjectIDsref, $gender, $tarchiveInfo, $User, $centerID, $upload\_id) -Registers a new candidate in the candidate table. +Registers a new candidate in the `candidate` table. INPUTS: - - $subjectIDsref: subject's ID information hashref + - $subjectIDsref: subject's ID information hash ref - $gender : gender of the candidate - - $tarchiveInfo : tarchive information hashref + - $tarchiveInfo : tarchive information hash ref - $User : user that is running the pipeline - $centerID : center ID + - upload\_id : upload ID of the study -### setMRISession($subjectIDsref, $tarchiveInfo) +### setMRISession($subjectIDsref, $tarchiveInfo, $upload\_id) Sets the imaging session ID. This function will call `&NeuroDB::MRI::getSessionID` which in turn will either: - - grep sessionID if visit for that candidate already exists, or - - create a new session if visit label does not exist for that - candidate yet + - grep the session ID if visit for that candidate already exists, or + - create a new session if visit label does not exist for that candidate yet -INPUTS: subject's ID information hashref, tarchive information hashref +INPUTS: + - $subjectIDsref: subject's ID information hashr ef + - $tarchiveInfo : DICOM archive information hash ref + - $upload\_id : upload ID of the study -RETURNS: session ID, if the new session requires staging +RETURNS: + - $sessionID : session ID + - $requiresStaging: whether the new session requires staging -### validateArchive($tarchive, $tarchiveInfo) +### validateArchive($tarchive, $tarchiveInfo, $upload\_id) Validates the DICOM archive by comparing the MD5 of the `$tarchive file` and -the one stored in the tarchive information hashref `$tarchiveInfo` derived +the one stored in the tarchive information hash ref `$tarchiveInfo` derived from the database. The function will exits with an error message if the -tarchive is not validated. +DICOM archive is not validated. -INPUTS: tarchive file, tarchive information hashref +INPUTS: + - $tarchive : DICOM archive file + - $tarchiveInfo: DICOM archive information hash ref + - $upload\_id : upload ID of the study ### which\_directory($subjectIDsref, $data\_dir) Determines where the MINC files to be registered into the database will go. -INPUTS: subject's ID information hashref, data directory (typically -/data/project/data) +INPUTS: + - $subjectIDsref: subject's ID information hashref + - $data\_dir : data directory (e.g. `/data/$PROJECT/data`) RETURNS: the final directory in which the registered MINC files will go -(typically /data/project/data/assembly/CandID/visit/mri/) +(typically `/data/$PROJECT/data/assembly/CandID/visit/mri/`) -### validateCandidate($subjectIDsref, $tarchive\_srcloc) +### validateCandidate($subjectIDsref) Check that the candidate's information derived from the patient name field of -the DICOM files is valid (CandID and PSCID of the candidate should correspond -to the same subject in the database). +the DICOM files is valid (`CandID` and `PSCID` of the candidate should +correspond to the same subject in the database). -INPUTS: subject's ID information hashref, tarchive source location +INPUT: subject's ID information hash ref RETURNS: the candidate mismatch error, or undef if the candidate is validated or a phantom -### computeSNR($tarchiveID, $tarchive\_srcloc, $profile) +### computeSNR($tarchiveID, $upload\_id, $profile) Computes the SNR on the modalities specified in the `getSNRModalities()` routine of the `$profile` file. -INPUTS: tarchive ID, tarchive source location, configuration file (usually prod) +INPUTS: + - $tarchiveID: DICOM archive ID + - $upload\_id : upload ID of the study + - $profile : configuration file (usually prod) -### orderModalitiesByAcq($tarchiveID, $tarchive\_srcloc) +### orderModalitiesByAcq($tarchiveID, $upload\_id) Order imaging modalities by acquisition number. -INPUTS: tarchive ID, tarchive source location +INPUTS: + - $tarchiveID: DICOM archive ID + - $uploadID : upload ID of the study ### getUploadIDUsingTarchiveSrcLoc($tarchive\_srcloc) @@ -346,27 +430,35 @@ RETURNS: the found upload ID ### spool($message, $error, $upload\_id, $verb) -Calls the Notify->spool function to log all messages. +Calls the `Notify-`spool> function to log all messages. INPUTS: - $message : message to be logged in the database - - $error : if 'Y' it's an error log, + - $error : 'Y' for an error log, 'N' otherwise - - $upload\_id : the upload\_id + - $upload\_id : the upload ID - $verb : 'N' for few main messages, 'Y' for more messages (developers) +### isValidMRIProtocol() + +Ensures no column in the `mri_protocol` nor the `mri_protocol_checks` +tables has comma-separated values. + +RETURNS: 1 on success, 0 on failure + # TO DO Document the following functions: - concat\_mri($minc\_files) - registerProgs(@toregister) -Remove function get\_acqusitions($study\_dir, \\@acquisitions) that is not used +Remove the function get\_acqusitions($study\_dir, \\@acquisitions) that is not used -# BUGS +Remove the function isValidMRIProtocol() once the database schema is configured +to prevent users from entering non-conform entries in the `mri_protocol` table -None reported (or list of bugs) +Fix comments written as #fixme in the code # LICENSING diff --git a/docs/scripts_md/MakeArchiveLocationRelative.md b/docs/scripts_md/MakeArchiveLocationRelative.md index 07b9f8361..b6d2d7961 100644 --- a/docs/scripts_md/MakeArchiveLocationRelative.md +++ b/docs/scripts_md/MakeArchiveLocationRelative.md @@ -2,7 +2,7 @@ MakeArchiveLocationRelative.pl -- Removes the root directory from the `ArchiveLocation` field in the `tarchive` table to make the path to the -tarchive relative. +DICOM archive relative. # SYNOPSIS @@ -10,7 +10,7 @@ perl MakeArchiveLocationRelative.pl `[options]` Available option is: -\-profile: name of the config file in ../dicom-archive/.loris\_mri +\-profile: name of the config file in `../dicom-archive/.loris_mri` # DESCRIPTION @@ -27,7 +27,9 @@ This function will grep all the `TarchiveID` and associated `ArchiveLocation` present in the `tarchive` table and will create a hash of this information including new `ArchiveLocation` to be inserted into the database. -INPUTS database handle, location of the `tarchive` directory +INPUTS: + - $dbh : database handle + - $tarchiveLibraryDir: location of the `tarchive` directory RETURNS: hash with tarchive information and new archive location @@ -35,15 +37,9 @@ RETURNS: hash with tarchive information and new archive location This function will update the `tarchive` table with the new `ArchiveLocation`. -INPUTS: database handle, hash with `tarchive` information. - -# TO DO - -Nothing planned. - -# BUGS - -None reported. +INPUTS: + - $dbh : database handle + - %tarchive\_list: hash with `tarchive` information. # LICENSING diff --git a/docs/scripts_md/Notify.md b/docs/scripts_md/Notify.md index 0443aa5e0..164157c8d 100644 --- a/docs/scripts_md/Notify.md +++ b/docs/scripts_md/Notify.md @@ -26,7 +26,7 @@ LORIS - particularly with regards to spooling new messages. ### new($dbh) >> (constructor) -Creates a new instance of this class. The parameter `\$dbh` is a +Creates a new instance of this class. The parameter `$dbh` is a reference to a DBI database handle, used to set the object's database handle, so that all the DB-driven methods will work. @@ -34,7 +34,7 @@ INPUT: DBI database handle RETURNS: new instance of this class. -### spool($type, $message, $centerID, $origin, $processID, ...) +### spool($type, $message, $centerID, $origin, $processID, $isError, $isVerb) Spools a new notification message, `$message`, into the `notification_spool` table for notification type `$type`. If `$centerID` is specified, only @@ -53,7 +53,7 @@ RETURNS: 1 on success, 0 on failure ### getTypeID($type) -Gets the notification typeID for the notification of type `$type`. +Gets the notification type ID for the notification of type `$type`. INPUT: notification type @@ -63,7 +63,7 @@ RETURNS: the notification typeID, or undef if none exists Gets the notification types for which there are unsent messages spooled. -RETURNS: an array of hashrefs, each of which has keys `NotificationTypeID` and +RETURNS: an array of hash ref, each of which has keys `NotificationTypeID` and `SubjectLine` and `CenterID` ### getSpooledMessagesByTypeID($typeID, $centerID) @@ -71,34 +71,32 @@ RETURNS: an array of hashrefs, each of which has keys `NotificationTypeID` and Gets the spooled messages for a given `NotificationTypeID` specified by `$typeID`, optionally directed to the center specified by `$centerID`. -INPUTS: notification type ID, (optionally the center ID) +INPUTS: + - $typeID : notification type ID + - $centerID: the center ID (optional) -RETURNS: an array of hashrefs, each of which has keys `TimeSpooled` and +RETURNS: an array of hash refs, each of which has keys `TimeSpooled` and `Message` ### getRecipientsByTypeID($typeID, $centerID) -Gets the recipient list for a given NotificationTypeID specified by +Gets the recipient list for a given `NotificationTypeID` specified by `$typeID`, optionally directed to the center specified by `$centerID`. -INPUTS: notification type ID, (optionally the center ID) +INPUTS: + - $typeID : notification type ID + - $centerID: the center ID (optional) RETURNS: an array of email addresses ### markMessagesAsSentByTypeID($typeID, $centerID) -Marks all messages as sent with a given NotificationTypeID specified by +Marks all messages as sent with a given `NotificationTypeID` specified by `$typeID` and optionally `$centerID`. -INPUTS: notification type ID, (optionally the center ID) - -# TO DO - -Nothing planned. - -# BUGS - -None reported. +INPUTS: + - $typeID : notification type ID + - $centerID: the center ID (optional) # COPYRIGHT diff --git a/docs/scripts_md/Private.md b/docs/scripts_md/Private.md new file mode 100644 index 000000000..a7a8dc80f --- /dev/null +++ b/docs/scripts_md/Private.md @@ -0,0 +1,39 @@ +# NAME + +DICOM::Private -- Definitions of (optional) private fields of DICOM headers. + +# SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize dictionary. + # Read the contents of the DICOM dictionary into a hash by group and element. + # dicom_private is read after dicom_fields, so overrides common fields. + BEGIN { + foreach my $line (@dicom_fields, @dicom_private) { + next if ($line =~ /^\#/); + my ($group, $elem, $code, $numa, $name) = split(/\s+/, $line); + my @lst = ($code, $name); + $dict{$group}{$elem} = [@lst]; + } + } + +# DESCRIPTION + +Definitions of (optional) private fields of DICOM headers. By default, none +are defined in the LORIS-MRI code base but users could define them here. + +Example format: + + 0000 0000 UL 1 GroupLength + ... + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/ProdToConfig.md b/docs/scripts_md/ProdToConfig.md new file mode 100644 index 000000000..d4e31f3db --- /dev/null +++ b/docs/scripts_md/ProdToConfig.md @@ -0,0 +1,43 @@ +# NAME + +ProdToConfig.pl -- a script that populates the `Config` table in the database +with entries from the `$profile` file. + +# SYNOPSIS + +perl tools/ProdToConfig.pl \`\[options\]\` + +The available option is: + +\-profile : name of the config file in + `../dicom-archive/.loris_mri` + +# DESCRIPTION + +This script needs to be run once during the upgrade to LORIS-MRI v18.0.0. Its +purpose is to remove some variables defined in the `$profile` file to the +Configuration module within LORIS. This script assumes that the LORIS upgrade +patch has been run, with table entries created and set to default values. This +script will then update those values with those that already exist in the +`$profile` file. If the table entry does not exist in the `$profile`, its +value will be kept at the value of a new install. + +## Methods + +### updateConfigFromProd($config\_name, $config\_value) + +Function that updates the values in the `Config` table for the columns as +specified in the `$config_name` variable. + +INPUTS: + - $config\_name : column to set in the `Config` table + - $config\_value: value to use in the `Config` table + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative +Neuroscience diff --git a/docs/scripts_md/VRfields.md b/docs/scripts_md/VRfields.md new file mode 100644 index 000000000..8a6bb5d14 --- /dev/null +++ b/docs/scripts_md/VRfields.md @@ -0,0 +1,64 @@ +# NAME + +DICOM::VRfields -- Value Representations (DICOM Standard PS 3.5 Sect 6.2) + +# SYNOPSIS + + use DICOM::Element; + use DICOM::Fields; # Standard header definitions. + use DICOM::Private; # Private or custom definitions. + + # Initialize VR hash. + # Fill in VR definitions from DICOM_fields. + BEGIN { + foreach my $line (@VR) { + next if ($line =~ /^\#/); + my ($vr, $name, $len, $fix, $numeric, $byteswap) = split(/\t+/, $line); + $VR{$vr} = [($name, $len, $fix, $numeric, $byteswap)]; + } + } + +# DESCRIPTION + +Value Representations (DICOM Standard PS 3.5 Sect 6.2) + - Bytes=0 => Undefined length. + - Fixed=1 => Exact field length, otherwise max length. + +Simply creating an array of DICOM Value Representations: + + Code Name Bytes Fixed Numeric ByteSwap + AE 'Application Entity' 16 0 0 0 + AS 'Age String' 4 1 0 0 + AT 'Attribute Tag' 4 1 0 1 + CS 'Code String' 16 0 0 0 + DA 'Date' 8 1 0 0 + DS 'Decimal String' 16 0 1 0 + DT 'Date Time' 26 0 0 0 + FL 'Floating Point Single' 4 1 1 1 + FD 'Floating Point Double' 8 1 1 1 + IS 'Integer String' 12 0 1 0 + LO 'Long Strong' 64 0 0 0 + LT 'Long Text' 10240 0 0 0 + OB 'Other Byte String' 0 0 0 0 + OW 'Other Word String' 0 0 0 1 + PN 'Person Name' 64 0 0 0 + SH 'Short String' 16 0 0 0 + SL 'Signed Long' 4 1 1 1 + SQ 'Sequence of Items' 0 0 0 0 + SS 'Signed Short' 2 1 1 1 + ST 'Short Text' 1024 0 0 0 + TM 'Time' 16 0 0 0 + UI 'Unique Identifier UID' 64 0 0 0 + UL 'Unsigned Long' 4 1 1 1 + UN 'Unknown' 0 0 0 0 + US 'Unsigned Short' 2 1 1 1 + UT 'Unlimited Text' 0 0 0 0 + +# LICENSING + +License: GPLv3 + +# AUTHORS + +Andrew Crabb (ahc@jhu.edu), +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/batch_uploads_imageuploader.md b/docs/scripts_md/batch_uploads_imageuploader.md new file mode 100644 index 000000000..2d36709c0 --- /dev/null +++ b/docs/scripts_md/batch_uploads_imageuploader.md @@ -0,0 +1,59 @@ +# NAME + +batch\_uploads\_imageuploader -- a script that runs `imaging_upload_file.pl` in +batch mode + +# SYNOPSIS + +./batch\_uploads\_imageuploader -profile prod < list\_of\_scans.txt > log\_batch\_imageuploader.txt 2>&1 C\[options\]> + +Available options are: + +\-profile: name of the config file in `../dicom-archive/.loris_mri` + +\-verbose: if set, be verbose + +# DESCRIPTION + +This script runs the Loris-MRI insertion pipeline on multiple scans. The list of +scans are provided through a text file (e.g. `list_of_scans.txt`) with one scan +details per line. +The scan details includes the path to the scan, identification as to whether the +scan is for a phantom (Y) or not (N), and the candidate name for non-phantom +entries. + +Like the LORIS Imaging Uploader interface, this script also validates the +candidate's name against the (start of the) filename and creates an entry in the +`mri_upload` table. + +An example of what `list_of_scans.txt` might contain for 3 uploads to be +inserted: + + /data/incoming/PSC0001_123457_V1.tar.gz N PSC0000_123456_V1 + /data/incoming/lego_Phantom_MNI_20140101.zip Y + /data/incoming/PSC0001_123457_V1_RES.tar.gz N PSC0000_123456_V1 + +## Methods + +### insertIntoMRIUpload($patientname, $phantom, $fullpath) + +Function that inserts into the `mri_upload` table entries for data coming from +the list of scans in the text file provided when calling +`batch_upload_imageuploader` + +INPUTS: + - $patientname : The patient name + - $phantom : 'Y' if the entry is for a phantom, + 'N' otherwise + - $fullpath : Path to the uploaded file + +RETURNS: $upload\_id : The upload ID + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative +Neuroscience diff --git a/docs/scripts_md/batch_uploads_tarchive.md b/docs/scripts_md/batch_uploads_tarchive.md index 2d81baf17..69383421c 100644 --- a/docs/scripts_md/batch_uploads_tarchive.md +++ b/docs/scripts_md/batch_uploads_tarchive.md @@ -1,6 +1,7 @@ # NAME -batch\_uploads\_tarchive - upload a batch of tarchives using script tarchiveLoader +batch\_uploads\_tarchive - upload a batch of DICOM archives using script +`tarchiveLoader` # SYNOPSIS @@ -8,29 +9,30 @@ batch\_uploads\_tarchive - upload a batch of tarchives using script tarchiveLoad # DESCRIPTION -This script uploads a list of tarchive files to the database by calling script +This script uploads a list of DICOM archives to the database by calling script `tarchiveLoader` on each file in succession. The list of files to process is read -from STDIN, one file name per line. Each file name is assumed to be a path relative -to `tarchiveLibraryDir` (see below). +from `STDIN`, one file name per line. Each file name is assumed to be a path +relative to `tarchiveLibraryDir` (see below). The following settings of file `$ENV{LORIS_CONFIG}/.loris-mri/prod` affect the -behvavior of batch\_uploads\_tarchive (where `$ENV{LORIS_CONFIG}` is the value of -the Unix environment variable LORIS\_CONFIG): +behvaviour of `batch_uploads_tarchive` (where `$ENV{LORIS_CONFIG}` is the +value of the Unix environment variable `LORIS_CONFIG`): -- **dataDirBasepath** : controls where the STDOUT and STDERR of each qsub command - (see below) will go, namely in +- **dataDirBasepath** : controls where the `STDOUT` and `STDERR` of each qsub +command (see below) will go, namely in `$dataDirBasepath/batch_output/tarstdout.log` and `$dataDirBasepath/batch_output/tarstderr.log` - (where `` is the index of the tarchive file processed, the first file having - index 1). -- **tarchiveLibraryDir**: directory that contains the tarchive files to process. The path - of the files listed on STDIN should be relative to this directory. -- **is\_qsub**: whether the output (STDOUT) of each tarchiveLoader command should be - processed by the qsub Unix command (allows batch execution of jobs on the - Sun Grid Engine, if available). If set, then the qsub command will send its STDOUT - and STDERR according to the value of dataDirBasepath (see above). + (where `` is the index of the DICOM archive processed, the + first file having index 1). +- **tarchiveLibraryDir**: directory that contains the DICOM archives to process. +The path of the files listed on `STDIN` should be relative to this directory. +- **is\_qsub**: whether the output (STDOUT) of each `tarchiveLoader` command +should be processed by the `qsub` Unix command (allows batch execution of jobs +on the Sun Grid Engine, if available). If set, then the `qsub` command will +send its `STDOUT` and `STDERR` according to the value of `dataDirBasepath` +(see above). - **mail\_use**: upon completion of the script, an email will be sent to email address - $mail\_user cointaining the list of files processed by batch\_upload\_tarchive + $mail\_user containing the list of files processed by `batch_uploads_tarchive` File prod should also contain the information needed to connect to the database in an array `@db` containing four elements: @@ -44,10 +46,6 @@ array `@db` containing four elements: Code cleanup: remove unused `-D` and `-v` program arguments -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/concat_mri.md b/docs/scripts_md/concat_mri.md index bd1f5dfbb..d719e52ea 100644 --- a/docs/scripts_md/concat_mri.md +++ b/docs/scripts_md/concat_mri.md @@ -9,8 +9,8 @@ concat\_mri.pl \[options\] \[minc\_files\] - **-debug** : print commands but do not execute them - **-verbose** : print additional information while running - **-compress** : compress resulting output files with `gzip` -- **-stdin** : do not read the names of the MINC files on the commmand line but read them -from STDIN instead +- **-stdin** : do not read the names of the MINC files on the command line but read them +from `STDIN` instead - **-postfix text** : create output file names using the file name without its extension, followed by `text` and the extension. For example, if `-postfix _test` is used and the file name passed on the command line is `scan.mnc`, the resulting output file will be `scan_test.mnc`. @@ -34,7 +34,7 @@ automatically. # DESCRIPTION -This script parses the MINC files passed on the command line (or read from STDIN) and +This script parses the MINC files passed on the command line (or read from `STDIN`) and uses `mincinfo` to extract specific header information from each of them. It then groups together the files that have identical values for the following properties: patient name, study ID, contrast agent flag (unless `-ignorecontrast` is specified, see @@ -46,14 +46,6 @@ will be the first element in the list of dimension names). Note that `mincresamp be called on a specific file before the actual merging takes place (see `-nonslicetolerance` above). Finally, note that merging of the MINC files is done with `mincconcat`. -# TO DO - -Nothing. - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/database_files_update.md b/docs/scripts_md/database_files_update.md index c563f7d45..9dc6d9439 100644 --- a/docs/scripts_md/database_files_update.md +++ b/docs/scripts_md/database_files_update.md @@ -9,7 +9,7 @@ perl database\_files\_update.pl `[options]` Available option is: -\-profile: name of the config file in ../dicom-archive/.loris\_mri +\-profile: name of the config file in `../dicom-archive/.loris_mri` # DESCRIPTION @@ -22,7 +22,9 @@ tables to remove the `data_dir` part of the path for security improvements. Gets the list of MINC files to update the location in the `files` table. -INPUTS: data directory from the `Config` tables, database handle +INPUTS: + - $data\_dir: data directory (e.g. `/data/$PROJECT/data`) + - $dbh : database handle RETURNS: hash of MINC locations, array of FileIDs @@ -30,39 +32,37 @@ RETURNS: hash of MINC locations, array of FileIDs Updates the location of MINC files in the `files` table. -INPUTS: File ID, new MINC relative location, database handle +INPUTS: + - $fileID : file's ID + - $new\_minc\_location: new MINC relative location + - $dbh : database handle RETURNS: Number of rows affected by the update (should always be 1) ### get\_parameter\_files($data\_dir, $parameter\_type, $dbh) -Gets list of JIV files to update location in the `parameter_file` table by +Gets list of PIC files to update location in the `parameter_file` table by removing the root directory from the path. -INPUTS: data directory, parameter type name for the JIV, database handle +INPUTS: + - $data\_dir : data directory (e.g. `/data$PROJECT/data`) + - $parameter\_type: name of the parameter type for the PIC + - $dbh : database handle -RETURNS: hash of JIV file locations, array of FileIDs +RETURNS: hash of PIC file locations, array of `FileIDs` -### update\_parameter\_file\_location($fileID, $new\_file\_location, ...) +### update\_parameter\_file\_location($fileID, $new\_file\_location, $parameter\_type, $dbh) -Updates the location of JIV files in the `parameter_file` table. +Updates the location of PIC files in the `parameter_file` table. INPUTS: - - $fileID : FileID - - $new\_file\_location: new location of the JIV file - - $parameter\_type : parameter type name for the JIV + - $fileID : file's ID + - $new\_file\_location: new location of the PIC file + - $parameter\_type : parameter type name for the PIC - $dbh : database handle RETURNS: number of rows affected by the update (should always be 1) -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/dicomTar.md b/docs/scripts_md/dicomTar.md index 6082ab14c..9b61fa22d 100644 --- a/docs/scripts_md/dicomTar.md +++ b/docs/scripts_md/dicomTar.md @@ -14,18 +14,18 @@ Available options are: \-database : Use a database if you have one set up for you. Just trying will fail miserably -\-mri\_upload\_update : Update the mri\_upload table by inserting the correct - tarchiveID +\-mri\_upload\_update : Update the `mri_upload` table by inserting the + correct `tarchiveID` \-clobber : Specify the name of the config file which resides in - .loris\_mri in the current directory + `.loris_mri` in the current directory \-centerName : Specify the symbolic center name to be stored alongside the DICOM institution \-verbose : Be verbose if set -\-version : Print cvs version number and exit +\-version : Print CVS version number and exit # DESCRIPTION @@ -34,9 +34,9 @@ target directory which will be the archive location. \- If the source contains only one valid STUDY worth of DICOM it will create a descriptive summary, a (gzipped) DICOM tarball. The tarball with the metadata - and a logfile will then be retarred into the final TARCHIVE. + and a logfile will then be retarred into the final `tarchive`. -\- md5sums are reported for every step. +\- MD5 sums are reported for every step. \- It can also be used with a MySQL database. @@ -44,23 +44,19 @@ target directory which will be the archive location. ### archive\_head() -Function that prints the tarchive header +Function that prints the DICOM archive header ### read\_file($file) Function that reads file contents into a variable -INPUT : $file : file to be read +INPUT: file to be read -RETURNS : $content : file contents +RETURNS: file contents # TO DO -Nothing planned. - -# BUGS - -None reported. +Fix comments written as #fixme in the code. # LICENSING diff --git a/docs/scripts_md/imaging_upload_file.md b/docs/scripts_md/imaging_upload_file.md index a084abf0a..83b1c2043 100644 --- a/docs/scripts_md/imaging_upload_file.md +++ b/docs/scripts_md/imaging_upload_file.md @@ -5,12 +5,11 @@ and insertion pipeline sequence # SYNOPSIS -perl imaging\_upload\_file.pl </path/to/UploadedFile> \`\[options\]\` +perl imaging\_upload\_file.pl </path/to/UploadedFile> `[options]` Available options are: -\-profile : name of the config file in - `../dicom-archive/.loris_mri` +\-profile : name of the config file in `../dicom-archive/.loris_mri` \-upload\_id : The Upload ID of the given scan uploaded @@ -18,18 +17,18 @@ Available options are: # DESCRIPTION -The program does the following +The program does the following: \- Gets the location of the uploaded file (.zip, .tar.gz or .tgz) \- Unzips the uploaded file -\- Uses the ImagingUpload class to : +\- Uses the `ImagingUpload` class to: 1) Validate the uploaded file (set the validation to true) - 2) Run dicomTar.pl on the file (set the dicomTar to true) - 3) Run tarchiveLoader on the file (set the minc-created to true) - 4) Removes the uploaded file once the previous steps have completed - 5) Update the mri\_upload table + 2) Run `dicomTar.pl` on the file (set the `dicomTar` to true) + 3) Run `tarchiveLoader` on the file (set the minc-created to true) + 4) Remove the uploaded file once the previous steps have completed + 5) Update the `mri_upload` table ## Methods @@ -37,39 +36,40 @@ The program does the following Function that gets the patient name using the upload ID -INPUT : $upload\_id : The upload ID +INPUT: The upload ID -RETURNS : $patient\_name : The patient name +RETURNS: The patient name ### getFilePathUsingUploadID($upload\_id) Functions that gets the file path from the \`mri\_upload\` table using the upload ID -INPUT : $upload\_id : The upload ID +INPUT: The upload ID -RETURNS : $file\_path : The full path to the uploaded file +RETURNS: The full path to the uploaded file ### getNumberOfMincFiles($upload\_id) Function that gets the count of MINC files created and inserted using the upload ID -INPUT : $upload\_id: The upload ID +INPUT: The upload ID -RETURNS : $minc\_created and $minc\_inserted: count of MINC files created and -inserted +RETURNS: + - $minc\_created : count of MINC files created + - $minc\_inserted: count of MINC files inserted ### spool() -Function that calls the Notify->spool function to log all messages +Function that calls the `Notify-`spool> function to log all messages INPUTS: - - $this : Reference to the class - - $message : Message to be logged in the database - - $error : If 'Y' it's an error log , 'N' otherwise - - $verb : 'N' for summary messages, - 'Y' for detailed messages (developers) + - $this : Reference to the class + - $message: Message to be logged in the database + - $error : If 'Y' it's an error log , 'N' otherwise + - $verb : 'N' for summary messages, + 'Y' for detailed messages (developers) # TO DO @@ -77,10 +77,6 @@ Add a check that the uploaded scan file is accessible by the front end user (i.e. that the user-group is set properly on the upload directory). Throw an error and log it, otherwise. -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/imaging_upload_file_cronjob.md b/docs/scripts_md/imaging_upload_file_cronjob.md index 08817f09e..8993ef1e8 100644 --- a/docs/scripts_md/imaging_upload_file_cronjob.md +++ b/docs/scripts_md/imaging_upload_file_cronjob.md @@ -1,33 +1,24 @@ # NAME imaging\_upload\_file\_cronjob.pl -- a wrapper script that calls the single step -script \`imaging\_upload\_file.pl\` for uploaded scans on which the insertion +script `imaging_upload_file.pl` for uploaded scans on which the insertion pipeline has not been launched. # SYNOPSIS -perl imaging\_upload\_file\_cronjob.pl \`\[options\]\` +perl imaging\_upload\_file\_cronjob.pl `[options]` Available options are: -\-profile : Name of the config file in - `../dicom-archive/.loris_mri` +\-profile : Name of the config file in `../dicom-archive/.loris_mri` \-verbose : If set, be verbose # DESCRIPTION -The program gets a series of rows from \`mri\_upload\` on which the insertion +The program gets a series of rows from `mri_upload` on which the insertion pipeline has not been run yet, and launches it. -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/mass_nii.md b/docs/scripts_md/mass_nii.md index a1aac0b92..c34438834 100644 --- a/docs/scripts_md/mass_nii.md +++ b/docs/scripts_md/mass_nii.md @@ -19,17 +19,9 @@ Available options are: # DESCRIPTION -This script generates NIfTI images for the inserted MINC files with a FileID +This script generates NIfTI images for the inserted MINC files with a `FileID` between the specified `minFileID` and `maxFileID`. -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/mass_perldoc_md_creation.md b/docs/scripts_md/mass_perldoc_md_creation.md new file mode 100644 index 000000000..71dfd33b2 --- /dev/null +++ b/docs/scripts_md/mass_perldoc_md_creation.md @@ -0,0 +1,31 @@ +# NAME + +mass\_perldoc\_md\_creation.pl -- Script to mass produce the `.md` files +derived from the documentation of the perl scripts and libraries. + +# SYNOPSIS + +perl mass\_perldoc\_md\_creation.pl `[options]` + +Available options are: + +\-profile: name of the config file in `../dicom-archive/.loris_mri` + +\-verbose: be verbose (boolean) + +# DESCRIPTION + +This script will need to be run once per release to make sure the `.md` files +derived from the documentation of the perl scripts and libraries are updated. + +If any new script have been added to a given release, make sure to include it +in the variable called `@script_list` at the beginning of the script. + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative +Neuroscience diff --git a/docs/scripts_md/mass_pic.md b/docs/scripts_md/mass_pic.md index 268f96413..74c779969 100644 --- a/docs/scripts_md/mass_pic.md +++ b/docs/scripts_md/mass_pic.md @@ -8,7 +8,7 @@ perl mass\_pic.pl `[options]` Available options are: -\-profile : name of the config file in ../dicom-archive/.loris\_mri +\-profile : name of the config file in `../dicom-archive/.loris_mri` \-mincFileID: integer, minimum `FileID` to operate on @@ -22,14 +22,6 @@ This scripts will generate pics for every registered MINC file that have a `FileID` from the `files` table between the specified `minFileID` and `maxFileID`. -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/minc_deletion.md b/docs/scripts_md/minc_deletion.md index d6190cb8f..ff806c8fb 100644 --- a/docs/scripts_md/minc_deletion.md +++ b/docs/scripts_md/minc_deletion.md @@ -11,12 +11,11 @@ perl minc\_deletion.pl `[options]` Available options are: -\-profile : name of the config file in - `../dicom-archive/.loris_mri` +\-profile : name of the config file in `../dicom-archive/.loris_mri` -\-series\_uid : the series UID of the file to be deleted +\-series\_uid: the series UID of the file to be deleted -\-fileid : the file ID of the file to be deleted +\-fileid : the file ID of the file to be deleted # DESCRIPTION @@ -24,7 +23,7 @@ This program deletes MINC files from LORIS by: - Moving the existing files (`.mnc`, `.nii`, `.jpg`, `.header`, `.raw_byte.gz`) to the archive directory: `/data/$PROJECT/data/archive/` - Deleting all related data from `parameter_file` & `files` tables - - Deleting data from `files_qcstatus` & `feedback_mri_comments` + - Deleting data from `files_qcstatus` and `feedback_mri_comments` database tables if the `-delqcdata` option is set. In most cases you would want to delete this when the images change - Deleting `mri_acquisition_dates` entry if it is the last file @@ -34,19 +33,11 @@ Users can use the argument `select` to view the record that could be removed from the database, or `confirm` to acknowledge that the data in the database will be deleted once the script executes. -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 # AUTHORS -Gregory Luneau, the LORIS community and McGill Centre -for Integrative Neuroscience +Gregory Luneau, +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/minc_insertion.md b/docs/scripts_md/minc_insertion.md index 7ef7f5d60..fc509c80a 100644 --- a/docs/scripts_md/minc_insertion.md +++ b/docs/scripts_md/minc_insertion.md @@ -8,16 +8,13 @@ perl minc\_insertion.pl `[options]` Available options are: -\-profile : name of the config file in - `../dicom-archive/.loris_mri` +\-profile : name of the config file in `../dicom-archive/.loris_mri` \-reckless : uploads data to database even if study protocol is not defined or violated \-force : forces the script to run even if validation failed -\-noJIV : prevents the JIVs from being created - \-mincPath : the absolute path to the MINC file \-tarchivePath: the absolute path to the tarchive file @@ -64,15 +61,7 @@ and setting extra parameters ### logHeader() -Creates and prints the LOG header. - -# TO DO - -Nothing planned. - -# BUGS - -None reported. +Function that adds a header with relevant information to the log file. # LICENSING diff --git a/docs/scripts_md/mincpik.md b/docs/scripts_md/mincpik.md index 43777a07e..7e6744a75 100644 --- a/docs/scripts_md/mincpik.md +++ b/docs/scripts_md/mincpik.md @@ -17,16 +17,16 @@ options that affect the behaviour of `mincpik` is as follows: - **-verbose** : be verbose - **-clobber** : if it exists, overwrite the output file. An error is produced if `outfile` exists and this option is not used. -- **-fake** : do not actually run the command but instead print on STDOUT all the calls to the - scripts and external tools (see above) issued to generate the image +- **-fake** : do not actually run the command but instead print on `STDOUT` all +the calls to the scripts and external tools (see above) issued to generate the image - **-slice index** : `index` (starts at 0) of the slice to use to generate the image. Defaults to `int(n/2)` (where `n` is the total number of slices) if not specified. - **-scale scale** : scaling factor to use when generating the image. Defaults to 2. Note that this option is ignored if `-width` is used (see below) - **-width width** : autoscale the image so it has a fixed width (in number of pixels). If this option is used, then the scaling factor (`-scale` option) is ignored. -- **-depth 8|16** : bitdepth for resulting image (8 or 16). This option should be used -on big-endian machines only. +- **-depth 8|16** : bit depth for resulting image (8 or 16). This option should +be used on big-endian machines only. - **-title** : whether the image should be generated with a title or not - **-title\_text title** : title text for the generated image - **-title\_size size** : font size (in pt.) to use when generating the image title @@ -73,14 +73,6 @@ The `outfile` command line argument is optional. If not specified, output will b written to STDOUT. If `outfile` is specified, the file extension will determine the type of the generated image (`.jpg` for JPEG images, `.gif` for GIF images, etc...) -# TO DO - -Nothing - -# BUGS - -None reported. - # LICENSING License: GPLv3 diff --git a/docs/scripts_md/register_processed_data.md b/docs/scripts_md/register_processed_data.md new file mode 100644 index 000000000..044db85b4 --- /dev/null +++ b/docs/scripts_md/register_processed_data.md @@ -0,0 +1,140 @@ +# NAME + +register\_processed\_data.pl -- Inserts processed data and links it to the source +data + +# SYNOPSIS + +perl register\_processed\_data.pl `[options]` + +Available options are: + +\-profile : name of config file in `../dicom-archive/.loris_mri` + +\-file : file that will be registered in the database + (full path from the root directory is required) + +\-sourceFileID : FileID of the raw input dataset that was processed + to obtain the file to be registered in the database + +\-sourcePipeline : pipeline name that was used to obtain the file to be + registered (example: `DTIPrep_pipeline`) + +\-tool : tool name and version that was used to obtain the + file to be registered (example: `DTIPrep_v1.1.6`) + +\-pipelineDate : date at which the processing pipeline was run + +\-coordinateSpace: space coordinate of the file + (i.e. linear, nonlinear or native) + +\-scanType : file scan type stored in the `mri_scan_type` table + (i.e. QCedDTI, RGBqc, TxtQCReport, XMLQCReport...) + +\-outputType : output type to be registered in the database + (i.e. QCed, processed, QCReport) + +\-inputFileIDs : list of input fileIDs used to obtain the file to + be registered (each fileID separated by ';') + +\-protocolID : ID of the registered protocol used to process data + +Note: All options are required as they will be necessary to insert a file in +the database. + +# DESCRIPTION + +This script inserts processed data in the `files` and `parameter_file` tables. + +## Methods + +### getSessionID($sourceFileID, $dbh) + +This function returns the `SessionID` based on the provided `sourceFileID`. + +INPUTS: + - $sourceFileID: source FileID + - $dbh : database handle + +RETURNS: session ID + +### getScannerID($sourceFileID, $dbh) + +This function gets the `ScannerID` from the `files` table using +`sourceFileID`. + +INPUTS: + - $sourceFileID: source `FileID` + - $dbh : database handle + +RETURNS: scanner ID + +### getAcqProtID($scanType, $dbh) + +This function returns the `AcquisitionProtocolID` of the file to register in +the database based on `scanType` in the `mri_scan_type` table. + +INPUTS: + - $scanType: scan type + - $dbh : database handle + +RETURNS: acquisition protocol ID + +### fetchMincHeader($file, $field) + +This function parses the MINC header and looks for a specific field value. + +INPUTS: + - $file : MINC file + - $field: MINC header field values + +RETURNS: MINC header value + +### copy\_file($filename, $subjectIDsref, $scan\_type, $fileref) + +Moves files to `assembly` folder. + +INPUTS: + - $filename : file to copy + - $subjectIDsref: subject ID hash ref + - $scan\_type : scan type + - $fileref : file hash ref + +RETURNS: file name of the copied file + +### getSourceFilename($sourceFileID) + +Greps source file name from the database using `SourceFileID`. + +INPUT: ID of the source file + +RETURNS: name of the source file + +### which\_directory($subjectIDsref) + +Determines where the MINC files will go. + +INPUT: subject ID hash ref + +RETURNS: directory where the MINC files will go + +### insert\_intermedFiles($fileID, $inputFileIDs, $tool) + +Function that will insert the intermediary outputs that were used to obtain the +processed file into the `files_intermediary` table of the database. + +INPUTS: + - $fileID : fileID of the registered processed file + - $inputFileIDs: array containing the list of input files that were + used to obtain the processed file + - $tool : tool that was used to obtain the processed file + +RETURNS: 1 on success, undef on failure + +# LICENSING + +License: GPLv3 + +# AUTHORS + +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/remove_jiv_data_from_db_and_filesystem.md b/docs/scripts_md/remove_jiv_data_from_db_and_filesystem.md new file mode 100644 index 000000000..b6ab2bb4b --- /dev/null +++ b/docs/scripts_md/remove_jiv_data_from_db_and_filesystem.md @@ -0,0 +1,22 @@ +# NAME + +remove\_jiv\_data\_from\_db\_and\_filesystem.pl -- Cleans up the JIV data from the +database tables and the filesystem + +# SYNOPSIS + +perl remove\_jiv\_data\_from\_db\_and\_filesystem.pl `[options]` + +Available option is: + +\-profile: name of the config file in ../dicom-archive/.loris\_mri + +# DESCRIPTION + +This script will remove the JIV files from the `parameter_file` table and +move them to the `$data_dir/archive/bkp_jiv_produced_before_LORIS_20.0` directory of the filesystem for +projects that wish to clean up the JIV data produced in the past. Note that +from release 20.0, JIV datasets will not be produced anymore by the imaging +insertion scripts. + +## Methods diff --git a/docs/scripts_md/seriesuid2fileid.md b/docs/scripts_md/seriesuid2fileid.md index d045136c3..8c657f919 100644 --- a/docs/scripts_md/seriesuid2fileid.md +++ b/docs/scripts_md/seriesuid2fileid.md @@ -2,27 +2,27 @@ seriesuid2fileid -- a script that displays a report about the pipeline insertion progress and outcome (including MRI violation status) of imaging datasets, based -on series UID(s) provided as STDIN. +on series `UID(s)` provided as `STDIN`. # SYNOPSIS perl tools/seriesuid2fileid -There are no available options. Once the script is invoked, series UID can be +There are no available options. Once the script is invoked, series `UID` can be input to display the status. The `$profile` file for database connection credentials is assumed to be `prod`. # DESCRIPTION -The program takes series UID from STDIN and returns a report with: +The program takes series `UID` from `STDIN` and returns a report with: - - SeriesUID - - SeriesDescription - - TarchiveID - - m_p_v_s_ID - - mri_v_log - - FileID - - FileName + - C + - C + - C + - C + - C + - C + - C The `m_p_v_s_ID` column displays, if present, the `ID` record from the `mri_protocol_violated_scans` table together with a count representing the @@ -30,19 +30,11 @@ number of times this scan violated the study MRI protocol, and the `mri_v_log` displays the `Severity` level of the violations as defined in the `mri_protocol_checks` table. -# TO DO - -Nothing planned. - -# BUGS - -None reported. - # LICENSING License: GPLv3 # AUTHORS -Gregory Luneau, LORIS community and McGill Centre for -Integrative Neuroscience +Gregory Luneau, +LORIS community and McGill Centre for Integrative Neuroscience diff --git a/docs/scripts_md/tarchiveLoader.md b/docs/scripts_md/tarchiveLoader.md index ed656e393..566b477dc 100644 --- a/docs/scripts_md/tarchiveLoader.md +++ b/docs/scripts_md/tarchiveLoader.md @@ -2,7 +2,7 @@ tarchiveLoader -- this script performs the following: -\- validation of the tarchive +\- validation of the DICOM archive \- conversion of DICOM datasets into MINC files @@ -15,41 +15,38 @@ perl uploadNeuroDB/tarchiveLoader </path/to/DICOM-tarchive> `[options]` Available options are: -\-profile : Name of the config file in - `../dicom-archive/.loris_mri` +\-profile : Name of the config file in `../dicom-archive/.loris_mri` -\-force : Force the script to run even if the validation - has failed +\-force : Force the script to run even if the validation + has failed -\-reckless : Upload data to database even if study protocol is - not defined or violated +\-reckless : Upload data to database even if study protocol is + not defined or violated -\-globLocation : Loosen the validity check of the tarchive allowing - for the possibility that the tarchive was moved to - a different directory - -\-noJIV : Prevent the JIVs from being created +\-globLocation : Loosen the validity check of the tarchive allowing + for the possibility that the tarchive was moved to + a different directory \-newScanner : By default a new scanner will be registered if the data you upload requires it. You can risk turning it off -\-keeptmp : Keep temporary directory. Make sense if have - infinite space on your server +\-keeptmp : Keep temporary directory. Make sense if have + infinite space on your server -\-xlog : Open an xterm with a tail on the current log file +\-xlog : Open an xterm with a tail on the current log file -\-verbose : If set, be verbose +\-verbose : If set, be verbose -\-seriesuid : Only insert this SeriesUID +\-seriesuid : Only insert this `SeriesUID` -\-acquisition\_protocol : Suggest the acquisition protocol to use +\-acquisition\_protocol : Suggest the acquisition protocol to use -\-bypass\_extra\_file\_checks : Bypass extra\_file\_checks +\-bypass\_extra\_file\_checks: Bypass `extra_file_checks` # DESCRIPTION -This script interacts with the NeuroDB database system. It will fetch or modify +This script interacts with the LORIS database system. It will fetch or modify contents of the following tables: `session`, `parameter_file`, `parameter_type`, `parameter_type_category`, `files`, `mri_staging`, `notification_spool` @@ -58,7 +55,7 @@ contents of the following tables: ### logHeader() -Function that adds a header with relevant information to the log file +Function that adds a header with relevant information to the log file. # TO DO @@ -74,9 +71,7 @@ Function that adds a header with relevant information to the log file \- add to config file whether or not to autocreate scanners -# BUGS - -None reported. +\- fix comments written as #fixme in the code # LICENSING diff --git a/docs/scripts_md/tarchive_validation.md b/docs/scripts_md/tarchive_validation.md index f628f549c..f4b8d2544 100644 --- a/docs/scripts_md/tarchive_validation.md +++ b/docs/scripts_md/tarchive_validation.md @@ -9,7 +9,7 @@ perl tarchive\_validation.pl `[options]` Available options are: -\-profile : name of the config file in ../dicom-archive/.loris-mri +\-profile : name of the config file in `../dicom-archive/.loris-mri` \-reckless : upload data to the database even if the study protocol is not defined or if it is violated @@ -32,19 +32,19 @@ against the one inserted in the database using checksum \- Verification of the PSC information using whatever field containing the site string (typically, the patient name or patient ID) -\- Verification of the ScannerID of the DICOM study archive (optionally +\- Verification of the `ScannerID` of the DICOM study archive (optionally creates a new scanner entry in the database if necessary) \- Optionally, creation of candidates as needed and standardization of gender information when creating the candidates (DICOM uses M/F, LORIS database uses Male/Female) -\- Check of the CandID/PSCID match. It's possible that the CandID exists, but -that CandID and PSCID do not correspond to the same candidate. This would -fail further down silently, so we explicitly check that this information is -correct here. +\- Check of the `CandID`/`PSCID` match. It's possible that the `CandID` +exists, but that `CandID` and `PSCID` do not correspond to the same +candidate. This would fail further down silently, so we explicitly check that +this information is correct here. -\- Validation of the SessionID +\- Validation of the `SessionID` \- Optionally, completion of extra filtering on the DICOM dataset, if needed @@ -55,15 +55,7 @@ to `TRUE` if the above validations were successful ### logHeader() -Creates and prints the LOG header. - -# TO DO - -Nothing planned. - -# BUGS - -None reported. +Function that adds a header with relevant information to the log file. # LICENSING diff --git a/docs/scripts_md/updateMRI_Upload.md b/docs/scripts_md/updateMRI_Upload.md index afb519226..bb63a9ea6 100644 --- a/docs/scripts_md/updateMRI_Upload.md +++ b/docs/scripts_md/updateMRI_Upload.md @@ -34,15 +34,7 @@ expected outcome), it will insert a record in `mri_upload` with the following pr If there already is an entry in `mri_upload` with the same `ArchiveLocation` as `T`'s, the script will exit with an error message saying that `mri_upload` is already up to date with respect to -`T`. - -# TO DO - -Nothing. - -# BUGS - -None reported. +`T`. # LICENSING diff --git a/environment b/environment index 3f66687fa..48500833f 100644 --- a/environment +++ b/environment @@ -1,4 +1,4 @@ -export PATH=%MINC_TOOLKIT_DIR%/bin:/data/%PROJECT%/bin/mri:/data/%PROJECT%/bin/mri/uploadNeuroDB:/data/%PROJECT%/bin/mri/dicom-archive:$PATH +export PATH=%MINC_TOOLKIT_DIR%/bin:/data/%PROJECT%/bin/mri:/data/%PROJECT%/bin/mri/uploadNeuroDB:/data/%PROJECT%/bin/mri/uploadNeuroDB/bin:/data/%PROJECT%/bin/mri/dicom-archive:$PATH export PERL5LIB=/data/%PROJECT%/bin/mri/uploadNeuroDB:$PERL5LIB export TMPDIR=/tmp export LORIS_CONFIG=/data/%PROJECT%/bin/mri/dicom-archive diff --git a/imaging_install.sh b/imaging_install.sh index 3adf22a10..12975ad1f 100755 --- a/imaging_install.sh +++ b/imaging_install.sh @@ -71,6 +71,9 @@ sudo -S cpan install Time::JulianDay sudo -S cpan install Path::Class sudo -S cpan install Archive::Extract sudo -S cpan install Archive::Zip +sudo -S cpan install Pod::Perldoc +sudo -S cpan install Pod::Markdown +sudo -S cpan install Pod::Usage echo ####################################################################################### @@ -82,7 +85,6 @@ echo "Creating the data directories" sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/tarchive" #holds tared dicom-folder sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/pic" #holds jpegs generated for the MRI-browser sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/logs" #holds logs from pipeline script - sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/jiv" #holds JIVs used for JIV viewer sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/assembly" #holds the MINC files sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/batch_output" #contains the result of the SGE (queue sudo -S su $USER -c "mkdir -m 770 -p $mridir/dicom-archive/.loris_mri" diff --git a/imaging_install_MacOSX.sh b/imaging_install_MacOSX.sh index 24163f1ca..7f3ad847d 100755 --- a/imaging_install_MacOSX.sh +++ b/imaging_install_MacOSX.sh @@ -48,7 +48,6 @@ echo "Creating the data directories" sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/tarchive" #holds tared dicom-folder sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/pic" #holds jpegs generated for the MRI-browser sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/logs" #holds logs from pipeline script - sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/jiv" #holds JIVs used for JIV viewer sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/assembly" #holds the MINC files sudo -S su $USER -c "mkdir -m 770 -p /data/$PROJ/data/batch_output" #contains the result of the SGE (queue sudo -S su $USER -c "mkdir -m 770 -p $mridir/dicom-archive/.loris_mri" diff --git a/minc2jiv.pl b/minc2jiv.pl deleted file mode 120000 index b076a3576..000000000 --- a/minc2jiv.pl +++ /dev/null @@ -1 +0,0 @@ -uploadNeuroDB/bin/minc2jiv.pl \ No newline at end of file diff --git a/mincpik b/mincpik deleted file mode 120000 index b5232eba6..000000000 --- a/mincpik +++ /dev/null @@ -1 +0,0 @@ -uploadNeuroDB/bin/mincpik \ No newline at end of file diff --git a/tools/BackPopulateSNRAndAcquisitionOrder.pl b/tools/BackPopulateSNRAndAcquisitionOrder.pl index 27f1e6512..0f3237765 100755 --- a/tools/BackPopulateSNRAndAcquisitionOrder.pl +++ b/tools/BackPopulateSNRAndAcquisitionOrder.pl @@ -5,9 +5,9 @@ =head1 NAME BackPopulateSNRAndAcquisitionOrder.pl -- a script that back populates the -AcqOrderPerModality column of the files table, and the signal-to-noise ratio -(SNR) values in the parameter_file table for inserted MINC files. The SNR is -computed using MINC tools built-in algorithms. +C column of the C table, and the signal-to-noise +ratio (SNR) values in the C table for inserted MINC files. The +SNR is computed using MINC tools built-in algorithms. =head1 SYNOPSIS @@ -16,11 +16,10 @@ =head1 SYNOPSIS Available options are: --profile : name of the config file in - C<../dicom-archive/.loris_mri> +-profile : name of the config file in C<../dicom-archive/.loris_mri> --tarchive_id : The Tarchive ID of the DICOM archive (.tar files) to be - processed from the C table +-tarchive_id: ID of the DICOM archive (.tar file) to be processed from the + C table @@ -30,11 +29,10 @@ =head1 DESCRIPTION C column; in reference to: https://github.com/aces/Loris-MRI/pull/160 as well as populate the C table with SNR entries in reference -to: -https://github.com/aces/Loris-MRI/pull/142 -It can take in TarchiveID as an argument if only a specific DICOM archive -(.tar files) is to be processed; otherwise, all DICOM archives (.tar files) in -the C table are processed. +to: https://github.com/aces/Loris-MRI/pull/142 +It can take in C as an argument if only a specific DICOM archive +(.tar files) is to be processed; otherwise, all DICOM archives (C +files) in the C table are processed. =cut @@ -208,14 +206,6 @@ =head1 DESCRIPTION =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/tools/MakeArchiveLocationRelative.pl b/tools/MakeArchiveLocationRelative.pl index 797567697..814691fe1 100644 --- a/tools/MakeArchiveLocationRelative.pl +++ b/tools/MakeArchiveLocationRelative.pl @@ -6,7 +6,7 @@ =head1 NAME MakeArchiveLocationRelative.pl -- Removes the root directory from the C field in the C table to make the path to the -tarchive relative. +DICOM archive relative. =head1 SYNOPSIS @@ -14,7 +14,7 @@ =head1 SYNOPSIS Available option is: --profile: name of the config file in ../dicom-archive/.loris_mri +-profile: name of the config file in C<../dicom-archive/.loris_mri> =head1 DESCRIPTION @@ -114,7 +114,9 @@ =head3 getTarchiveList($dbh, $tarchiveLibraryDir) present in the C table and will create a hash of this information including new C to be inserted into the database. -INPUTS database handle, location of the C directory +INPUTS: + - $dbh : database handle + - $tarchiveLibraryDir: location of the C directory RETURNS: hash with tarchive information and new archive location @@ -162,7 +164,9 @@ =head3 updateArchiveLocation($dbh, %tarchive_list) This function will update the C table with the new C. -INPUTS: database handle, hash with C information. +INPUTS: + - $dbh : database handle + - %tarchive_list: hash with C information. =cut @@ -200,14 +204,6 @@ sub updateArchiveLocation { =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/tools/ProdToConfig.pl b/tools/ProdToConfig.pl index 8a19a9c1d..d72eb07fc 100755 --- a/tools/ProdToConfig.pl +++ b/tools/ProdToConfig.pl @@ -4,8 +4,8 @@ =head1 NAME -ProdToConfig.pl -- a script that populates the `Config` table in the database -with entries from the $profile file. +ProdToConfig.pl -- a script that populates the C table in the database +with entries from the C<$profile> file. =head1 SYNOPSIS @@ -21,12 +21,12 @@ =head1 DESCRIPTION This script needs to be run once during the upgrade to LORIS-MRI v18.0.0. Its -purpose is to remove some variables defined in the $profile file to the +purpose is to remove some variables defined in the C<$profile> file to the Configuration module within LORIS. This script assumes that the LORIS upgrade patch has been run, with table entries created and set to default values. This script will then update those values with those that already exist in the -$profile file. If the table entry does not exist in the $profile, its value will -be kept at the value of a new install. +C<$profile> file. If the table entry does not exist in the C<$profile>, its +value will be kept at the value of a new install. =head2 Methods @@ -146,12 +146,12 @@ =head2 Methods =head3 updateConfigFromProd($config_name, $config_value) -Function that updates the values in the `Config` table for the columns as -specified in the $config_name +Function that updates the values in the C table for the columns as +specified in the C<$config_name> variable. -INPUTS : - - $config_name : Column to set in the Config table - - $config_value : Value to use in the Config table +INPUTS: + - $config_name : column to set in the C table + - $config_value: value to use in the C table =cut @@ -189,14 +189,6 @@ sub updateConfigFromProd { =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/tools/database_files_update.pl b/tools/database_files_update.pl index 4bd197bde..ee20a0faf 100644 --- a/tools/database_files_update.pl +++ b/tools/database_files_update.pl @@ -13,7 +13,7 @@ =head1 SYNOPSIS Available option is: --profile: name of the config file in ../dicom-archive/.loris_mri +-profile: name of the config file in C<../dicom-archive/.loris_mri> =head1 DESCRIPTION @@ -67,9 +67,8 @@ =head2 Methods my $dbh = &NeuroDB::DBI::connect_to_db(@Settings::db); # these settings are in the database and can be set in the Configuration module of LORIS -my $data_dir = &NeuroDB::DBI::getConfigSetting( - \$dbh,'dataDirBasepath' - ); +my $data_dir = &NeuroDB::DBI::getConfigSetting(\$dbh,'dataDirBasepath'); +$data_dir =~ s/\/$//; # Needed for log file my $log_dir = "$data_dir/logs"; @@ -99,24 +98,6 @@ =head2 Methods print LOG "No file was found with a path starting from the root directory (i.e. including $data_dir)\n"; } -#### Updating jiv location in parameter_file table #### -my ($jiv_location_refs, $fileIDs_jiv) = get_parameter_files($data_dir, 'jiv_path', $dbh); - -if ($jiv_location_refs) { - foreach my $fileID (@$fileIDs_jiv) { - my $new_jiv_location = $jiv_location_refs->{$fileID}; - $new_jiv_location =~ s/$data_dir\///i; - my ($rows_affected) = update_parameter_file_location($fileID, $new_jiv_location, 'jiv_path', $dbh); # update jiv location in parameter_file table. - if ($rows_affected == 1) { - print LOG "Updated jiv location with $fileID FileID to $new_jiv_location.\n"; - } else { - print LOG "ERROR: $rows_affected while updating jiv location with $fileID FileID to $new_jiv_location.\n"; - } - } -} else { - print LOG "No jiv was found with a path starting from the root directory (i.e. including $data_dir)\n"; -} - #### Updating pic location in parameter_file table #### my ($pic_location_refs, $fileIDs_pic) = get_parameter_files($data_dir, 'check_pic_filename', $dbh); @@ -165,7 +146,9 @@ =head3 get_minc_files($data_dir, $dbh) Gets the list of MINC files to update the location in the C table. -INPUTS: data directory from the C tables, database handle +INPUTS: + - $data_dir: data directory (e.g. C) + - $dbh : database handle RETURNS: hash of MINC locations, array of FileIDs @@ -202,7 +185,10 @@ =head3 update_minc_location($fileID, $new_minc_location, $dbh) Updates the location of MINC files in the C table. -INPUTS: File ID, new MINC relative location, database handle +INPUTS: + - $fileID : file's ID + - $new_minc_location: new MINC relative location + - $dbh : database handle RETURNS: Number of rows affected by the update (should always be 1) @@ -225,12 +211,15 @@ sub update_minc_location { =head3 get_parameter_files($data_dir, $parameter_type, $dbh) -Gets list of JIV files to update location in the C table by +Gets list of PIC files to update location in the C table by removing the root directory from the path. -INPUTS: data directory, parameter type name for the JIV, database handle +INPUTS: + - $data_dir : data directory (e.g. C) + - $parameter_type: name of the parameter type for the PIC + - $dbh : database handle -RETURNS: hash of JIV file locations, array of FileIDs +RETURNS: hash of PIC file locations, array of C =cut @@ -265,14 +254,14 @@ sub get_parameter_files { =pod -=head3 update_parameter_file_location($fileID, $new_file_location, ...) +=head3 update_parameter_file_location($fileID, $new_file_location, $parameter_type, $dbh) -Updates the location of JIV files in the C table. +Updates the location of PIC files in the C table. INPUTS: - - $fileID : FileID - - $new_file_location: new location of the JIV file - - $parameter_type : parameter type name for the JIV + - $fileID : file's ID + - $new_file_location: new location of the PIC file + - $parameter_type : parameter type name for the PIC - $dbh : database handle RETURNS: number of rows affected by the update (should always be 1) @@ -309,14 +298,6 @@ sub update_parameter_file_location { =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/tools/example_scripts/deletemincsqlwrapper.pl b/tools/example_scripts/deletemincsqlwrapper.pl index de0de4984..9444bda77 100755 --- a/tools/example_scripts/deletemincsqlwrapper.pl +++ b/tools/example_scripts/deletemincsqlwrapper.pl @@ -176,14 +176,6 @@ =head1 DESCRIPTION =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 diff --git a/tools/mass_perldoc_md_creation.pl b/tools/mass_perldoc_md_creation.pl new file mode 100644 index 000000000..3d0c277cd --- /dev/null +++ b/tools/mass_perldoc_md_creation.pl @@ -0,0 +1,182 @@ +#!/usr/bin/perl -w + +=pod + +=head1 NAME + +mass_perldoc_md_creation.pl -- Script to mass produce the C<.md> files +derived from the documentation of the perl scripts and libraries. + +=head1 SYNOPSIS + +perl mass_perldoc_md_creation.pl C<[options]> + +Available options are: + +-profile: name of the config file in C<../dicom-archive/.loris_mri> + +-verbose: be verbose (boolean) + + +=head1 DESCRIPTION + +This script will need to be run once per release to make sure the C<.md> files +derived from the documentation of the perl scripts and libraries are updated. + +If any new script have been added to a given release, make sure to include it +in the variable called C<@script_list> at the beginning of the script. + +=head1 LICENSING + +License: GPLv3 + +=head1 AUTHORS + +LORIS community and McGill Centre for Integrative +Neuroscience + +=cut + + +use strict; +use warnings; + +use File::Basename; +use Getopt::Tabular; + + +use NeuroDB::DBI; +use NeuroDB::ExitCodes; + +my @script_list = ( + 'DTIPrep/DTI/DTI.pm', + 'DTIPrep/DTIPrepRegister.pl', + 'DTIPrep/DTIPrep_pipeline.pl', + 'batch_uploads_imageuploader', + 'batch_uploads_tarchive', + 'dicom-archive/DICOM/DCMSUM.pm', + 'dicom-archive/DICOM/DICOM.pm', + 'dicom-archive/DICOM/Element.pm', + 'dicom-archive/DICOM/Fields.pm', + 'dicom-archive/DICOM/Private.pm', + 'dicom-archive/DICOM/VRfields.pm', + 'dicom-archive/dicomTar.pl', + 'dicom-archive/updateMRI_Upload.pl', + 'tools/BackPopulateSNRAndAcquisitionOrder.pl', + 'tools/MakeArchiveLocationRelative.pl', + 'tools/ProdToConfig.pl', + 'tools/database_files_update.pl', + 'tools/mass_perldoc_md_creation.pl', + 'tools/seriesuid2fileid', + 'uploadNeuroDB/NeuroDB/DBI.pm', + 'uploadNeuroDB/NeuroDB/ExitCodes.pm', + 'uploadNeuroDB/NeuroDB/File.pm', + 'uploadNeuroDB/NeuroDB/FileDecompress.pm', + 'uploadNeuroDB/NeuroDB/ImagingUpload.pm', + 'uploadNeuroDB/NeuroDB/MRI.pm', + 'uploadNeuroDB/NeuroDB/MRIProcessingUtility.pm', + 'uploadNeuroDB/NeuroDB/Notify.pm', + 'uploadNeuroDB/bin/concat_mri.pl', + 'uploadNeuroDB/bin/mincpik', + 'uploadNeuroDB/imaging_upload_file.pl', + 'uploadNeuroDB/imaging_upload_file_cronjob.pl', + 'uploadNeuroDB/mass_nii.pl', + 'uploadNeuroDB/mass_pic.pl', + 'uploadNeuroDB/minc_deletion.pl', + 'uploadNeuroDB/minc_insertion.pl', + 'uploadNeuroDB/register_processed_data.pl', + 'uploadNeuroDB/tarchiveLoader', + 'uploadNeuroDB/tarchive_validation.pl' +); + + +my $profile; +my $verbose = 0; + +my $profile_desc = "name of config file in ../dicom-archive/.loris_mri"; + +my @opt_table = ( + [ "-profile", "string", 1, \$profile, $profile_desc ], + [ "-verbose", "boolean", 1, \$verbose, "Be verbose." ] +); + +my $Help = < Successfully connected to database \n" if $verbose; + + + +## get data directory from the Config table +my $loris_mri_path = NeuroDB::DBI::getConfigSetting(\$dbh, 'MRICodePath'); +$loris_mri_path =~ s/\/$//; + + + +## add the LORIS-MRI directory path to the list of scripts +@script_list = map { $loris_mri_path . '/' . $_ } @script_list; + + + +## create the list of md file based on @script_list and change extension to .md +my $md_path = $loris_mri_path . '/docs/scripts_md/'; +my @suffixes = (".pl", ".pm"); +my @md_list = map { $md_path . basename($_, @suffixes) . ".md"} @script_list; + + + +## loop through script array and create the .md files using pod2markdown +my $git_add = "git add"; +for my $index (0 .. $#script_list) { + my $script = $script_list[$index]; + my $md_file = $md_list[$index]; + my $command = "pod2markdown $script $md_file"; + print $command . "\n" if $verbose; + system($command); + $git_add .= ' ' . $md_file . ' '; + +} + +my $message = "\n\tMD files created! \n\tTo add them to git, run the following " + . "command in the terminal: \n\n"; +print $message . $git_add . "\n"; + + +exit $NeuroDB::ExitCodes::SUCCESS; diff --git a/tools/remove_jiv_data_from_db_and_filesystem.pl b/tools/remove_jiv_data_from_db_and_filesystem.pl new file mode 100644 index 000000000..9da03074b --- /dev/null +++ b/tools/remove_jiv_data_from_db_and_filesystem.pl @@ -0,0 +1,153 @@ +#! /usr/bin/perl + + +=pod + +=head1 NAME + +remove_jiv_data_from_db_and_filesystem.pl -- Cleans up the JIV data from the +database tables and the filesystem + +=head1 SYNOPSIS + +perl remove_jiv_data_from_db_and_filesystem.pl C<[options]> + +Available option is: + +-profile: name of the config file in ../dicom-archive/.loris_mri + +=head1 DESCRIPTION + +This script will remove the JIV files from the C table and +move them to the C<$data_dir/archive/bkp_jiv_produced_before_LORIS_20.0> directory of the filesystem for +projects that wish to clean up the JIV data produced in the past. Note that +from release 20.0, JIV datasets will not be produced anymore by the imaging +insertion scripts. + +=head2 Methods + +=cut + +use strict; +use warnings; + +use Getopt::Tabular; +use File::Copy; + +use NeuroDB::DBI; +use NeuroDB::ExitCodes; + + + +my $profile; +my $profile_desc = "name of config file in ../dicom-archive/.loris_mri"; + +my @opt_table = ( + [ "-profile", "string", 1, \$profile, + "name of config file in ../dicom-archive/.loris_mri" + ] +); + +my $Help = < Successfully connected to database \n"; + + + + +## select the JIV parameter type ID from parameter_type +my $query = "SELECT ParameterTypeID FROM parameter_type WHERE Name='jiv_path'"; +my $sth = $dbh->prepare($query); +$sth->execute(); + +my $row = $sth->fetchrow_hashref(); +if ( !$row ) { + print "\n==> Did not find any entry in the parameter_type table with " + . "Name='jiv_path'. Exiting now.\n"; + exit $NeuroDB::ExitCodes::SUCCESS; +} +my $param_type_id = $row->{'ParameterTypeID'}; + + + + +## check to see if there are entries in the parameter_file table +$query = "SELECT * FROM parameter_file WHERE ParameterTypeID=?"; +$sth = $dbh->prepare($query); +$sth->execute($param_type_id); +$row = $sth->fetchrow_hashref(); +my $message = "\n==> Did not find any JIV entries in table parameter_file.\n"; +print $message if ( !$row ); + +# delete entries from parameter_file +my $delete = "DELETE FROM parameter_file WHERE ParameterTypeID=?"; +my $delete_sth = $dbh->prepare($delete); +$delete_sth->execute($param_type_id); + +# check to make sure entries have been deleted +$sth->execute($param_type_id); +$row = $sth->fetchrow_hashref(); +if ( !$row ) { + print "\n==> Succesfully deleted all JIV entries in parameter_file.\n"; + $delete = "DELETE FROM parameter_type WHERE ParameterTypeID=?"; + $delete_sth = $dbh->prepare($delete); + $delete_sth->execute($param_type_id); +} else { + print "\n==> Could not delete all JIV entries in parameter_file.\n"; + exit; +} + + + + +## backup the JIV directory to the archive directory on the filesystem +# grep the data_dir from the Configuration module of LORIS +my $data_dir = &NeuroDB::DBI::getConfigSetting(\$dbh, 'dataDirBasepath'); +$data_dir =~ s/\/$//; +my $jiv_dir = $data_dir . "/jiv"; +my $jiv_bkp = $data_dir . "/archive/bkp_jiv_produced_before_LORIS_20.0"; +if (-d $jiv_dir) { + move($jiv_dir, $jiv_bkp) or die "Cannot move $jiv_dir to $jiv_bkp: $!\n"; + print "\n==> Successfully backed up the jiv directory to $jiv_bkp.\n"; +} + + + +exit $NeuroDB::ExitCodes::SUCCESS; diff --git a/tools/seriesuid2fileid b/tools/seriesuid2fileid index 825a11eab..39c45a522 100755 --- a/tools/seriesuid2fileid +++ b/tools/seriesuid2fileid @@ -6,28 +6,28 @@ seriesuid2fileid -- a script that displays a report about the pipeline insertion progress and outcome (including MRI violation status) of imaging datasets, based -on series UID(s) provided as STDIN. +on series C provided as C. =head1 SYNOPSIS perl tools/seriesuid2fileid -There are no available options. Once the script is invoked, series UID can be +There are no available options. Once the script is invoked, series C can be input to display the status. The C<$profile> file for database connection credentials is assumed to be C. =head1 DESCRIPTION -The program takes series UID from STDIN and returns a report with: +The program takes series C from C and returns a report with: - - SeriesUID - - SeriesDescription - - TarchiveID - - m_p_v_s_ID - - mri_v_log - - FileID - - FileName + - C + - C + - C + - C + - C + - C + - C The C column displays, if present, the C record from the C table together with a count representing the @@ -184,21 +184,13 @@ __END__ =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported. - =head1 LICENSING License: GPLv3 =head1 AUTHORS -Gregory Luneau, LORIS community and McGill Centre for -Integrative Neuroscience +Gregory Luneau, +LORIS community and McGill Centre for Integrative Neuroscience =cut diff --git a/uploadNeuroDB/NeuroDB/DBI.pm b/uploadNeuroDB/NeuroDB/DBI.pm index 9aba96c9a..66f30c4b2 100755 --- a/uploadNeuroDB/NeuroDB/DBI.pm +++ b/uploadNeuroDB/NeuroDB/DBI.pm @@ -38,12 +38,16 @@ use DBI; =head3 connect_to_db($db_name, $db_user, $db_pass, $db_host) -This method connects to the LORIS database ($db_database) on host ($db_host) -as username ($db_user) & password ($db_pass). The function dies with a -database connection error when the connection failed or returns a DBI database -handler. +This method connects to the LORIS database (C<$db_database>) on host +(C<$db_host>) as username (C<$db_user>) & password (C<$db_pass>). The function +dies with a database connection error when the connection failed or returns a +DBI database handler. -INPUT: optional: database, username, password, host +INPUTS: + - $db_name: database name (optional) + - $db_user: database user (optional) + - $db_pass: password for C<$db_user> (optional) + - $db_host: database host (optional) RETURNS: DBI database handler when connection is successful @@ -69,10 +73,12 @@ sub connect_to_db =head3 getConfigSetting($dbh, $name) -This method fetches the value ($value) stored in the C table for a -specific config setting ($name) specified as an input. +This method fetches the value (C<$value>) stored in the C table for a +specific config setting (C<$name>) specified as an input. -INPUT: database handler, name of the config setting +INPUTS: + - $dbh : database handler + - $name: name of the config setting RETURNS: value corresponding to the config setting in the C table of LORIS @@ -89,7 +95,16 @@ sub getConfigSetting $query = $query . $where; my $sth = $$dbh->prepare($query); $sth->execute($name); - if ( $sth->rows > 0 ) { + + if ( $sth->rows > 1 ){ + # if more than one row returned, push data into an array that will be + # dereferenced into $value + my @values; + while (my $row = $sth->fetchrow_array()) { + push (@values, $row); + } + $value = \@values; + } elsif ( $sth->rows > 0 ) { $value = $sth->fetchrow_array(); } return $value; @@ -103,10 +118,6 @@ sub getConfigSetting Expand the package with more functions. -=head1 BUGS - -None reported - =head1 COPYRIGHT AND LICENSE Copyright (c) 2003 by Jonathan Harlap, McConnell Brain Imaging Centre, diff --git a/uploadNeuroDB/NeuroDB/ExitCodes.pm b/uploadNeuroDB/NeuroDB/ExitCodes.pm index 7830c027c..e536c0be1 100755 --- a/uploadNeuroDB/NeuroDB/ExitCodes.pm +++ b/uploadNeuroDB/NeuroDB/ExitCodes.pm @@ -56,18 +56,19 @@ Below is a list of the possible exit codes: ##### ---- SECTION 2: SCRIPT SPECIFIC EXIT CODES NOT COVERED IN SECTION 1 -7. Exit codes from batch_uploads_imageuploader (exit codes from 150 to 159) +7. Exit codes from C (exit codes from 150 to 159) -8. Exit codes from DTIPrep/DTIPrepRegister.pl (exit codes from 160 to 169) +8. Exit codes from C (exit codes from 160 to 169) -9. Exit codes from uploadNeuroDB/NeuroDB/ImagingUpload.pm (exit codes from +9. Exit codes from C (exit codes from 170 to 179) -10. Exit codes from uploadNeuroDB/minc_insertion.pl (exit codes from 180 to 189) +10. Exit codes from C (exit codes from 180 +to 189) -11. Exit codes from uploadNeuroDB/tarchiveLoader (exit codes from 190 to 199) +11. Exit codes from C (exit codes from 190 to 199) -12. Exit codes from uploadNeuroDB/NeuroDB/bin/minc2jiv.pl (exit codes from 200 +12. Exit codes from former scripts that have been removed (exit codes from 200 to 210) @@ -144,7 +145,6 @@ our $NOT_A_SINGLE_STUDY = 85; # if the upload regroups multiple studies - ##### ---- SECTION 2: SCRIPT SPECIFIC EXIT CODES NOT COVERED IN SECTION 1 @@ -182,11 +182,9 @@ our $CANDIDATE_MISMATCH = 181; # if candidate PSCID and CandID do not match # file related failures our $NO_VALID_MINC_CREATED = 190; # if no valid MINC file was created - # (non-localizers) + # (excluding project-specified acquisitions) -## -- FROM uploadNeuroDB/NeuroDB/bin/minc2jiv.pl (exit codes from 200 to 210) +## -- FROM former scripts that have been removed (exit codes from 200 to 210) our $REGISTER_PROGRAM_FAILURE = 200; # if MNI::Spawn::RegisterPrograms failed - -## -- FROM \ No newline at end of file diff --git a/uploadNeuroDB/NeuroDB/File.pm b/uploadNeuroDB/NeuroDB/File.pm index d5d3130a0..d79e3c899 100755 --- a/uploadNeuroDB/NeuroDB/File.pm +++ b/uploadNeuroDB/NeuroDB/File.pm @@ -128,8 +128,8 @@ sub loadFile { =head3 findFile($filename) -Finds the FileID pertaining to a file as defined by parameter C<$filename>, -which is a full /path/to/file. +Finds the C pertaining to a file as defined by parameter C<$filename>, +which is a full C. INPUT: full path to the file to look for an ID in the database. @@ -249,7 +249,8 @@ sub getDatabaseHandleRef { =head3 getFileType($file) Determines the imaging file type based on the extension of the file to insert -and the list of available types in the ImagingFileTypes table of the database. +and the list of available types in the C table of the +database. INPUT: the path to the imaging file to determine the file type @@ -367,7 +368,9 @@ sub loadFileFromDisk { Sets the fileData property named C<$propertyName> to the value of C<$value>. -INPUT: name of the fileData property, value of the fileData property to be set +INPUTS: + - $paramName: name of the C property + - $value : value of the C property to be set =cut @@ -392,7 +395,9 @@ sub setFileData { Sets the parameter named C<$parameterName> to the value of C<$value>. -INPUT: name of the parameter, value of the parameter to be set +INPUTS: + - $paramName: name of the parameter + - $value : value of the parameter to be set =cut @@ -442,12 +447,12 @@ sub removeParameter { =head3 getParameterTypeID($parameter) -Gets the ParameterTypeID for the parameter C<$parameter>. If C<$parameter> +Gets the C for the parameter C<$parameter>. If C<$parameter> does not exist, it will be created. INPUT: name of the parameter type -RETURNS: (int) ParameterTypeID +RETURNS: C (int) =cut @@ -517,9 +522,7 @@ __END__ Other operations should be added: perhaps C methods for those fields in the C table which are lookup fields. -=head1 BUGS - -None reported. +Fix comments written as #fixme in the code. =head1 COPYRIGHT AND LICENSE diff --git a/uploadNeuroDB/NeuroDB/FileDecompress.pm b/uploadNeuroDB/NeuroDB/FileDecompress.pm index e567ca43f..c5eebef4c 100755 --- a/uploadNeuroDB/NeuroDB/FileDecompress.pm +++ b/uploadNeuroDB/NeuroDB/FileDecompress.pm @@ -137,14 +137,6 @@ sub getType { =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported - =head1 COPYRIGHT AND LICENSE License: GPLv3 diff --git a/uploadNeuroDB/NeuroDB/ImagingUpload.pm b/uploadNeuroDB/NeuroDB/ImagingUpload.pm index f48461d7f..5ecbeabca 100755 --- a/uploadNeuroDB/NeuroDB/ImagingUpload.pm +++ b/uploadNeuroDB/NeuroDB/ImagingUpload.pm @@ -78,10 +78,10 @@ moved to a final destination directory. INPUTS: - $dbhr : database handler - $uploaded_temp_folder: temporary directory of the upload - - $upload_id : uploadID from the mri_upload table + - $upload_id : C from the C table - $pname : patient name - - $profile : name of the configuration file - (typically C) + - $profile : name of the configuration file in + C (typically C) RETURNS: new instance of this class @@ -310,7 +310,7 @@ sub IsCandidateInfoValid { This method executes the following actions: - Runs C with C<-clobber -database -profile prod> options - - Extracts the TarchiveID of the DICOM archive created by C + - Extracts the C of the DICOM archive created by C - Updates the C table if C ran successfully RETURNS: 1 on success, 0 on failure @@ -437,7 +437,7 @@ sub runTarchiveLoader { This method extracts the patient name field from the DICOM file header using C and compares it with the patient name information stored in the -mri_upload table. +C table. INPUT: full path to the DICOM file @@ -543,11 +543,11 @@ sub runCommandWithExitCode { =head3 runCommand($command) This method will run any linux command given as an argument using back-tilt -and will return the back-tilt return value (which is STDOUT). +and will return the back-tilt return value (which is C). INPUT: the linux command to be executed -RETURNS: back-tilt return value (STDOUT) +RETURNS: back-tilt return value (C) =cut @@ -565,7 +565,7 @@ sub runCommand { This method cleans up and removes the uploaded file from the data directory once the uploaded file has been inserted into the database and saved in the -tarchive folder. +C folder. RETURNS: 1 on success, 0 on failure @@ -672,14 +672,6 @@ sub updateMRIUploadTable { =pod -=head1 TO DO - -Nothing planned. - -=head1 BUGS - -None reported - =head1 COPYRIGHT AND LICENSE License: GPLv3 diff --git a/uploadNeuroDB/NeuroDB/MRI.pm b/uploadNeuroDB/NeuroDB/MRI.pm index 3f4f26fed..e00c2af52 100755 --- a/uploadNeuroDB/NeuroDB/MRI.pm +++ b/uploadNeuroDB/NeuroDB/MRI.pm @@ -62,9 +62,12 @@ $FLOAT_EQUALS_NB_DECIMALS = 4; =head3 getSubjectIDs($patientName, $scannerID, $dbhr) Determines the candidate ID and visit label for the subject based on patient -name and (for calibration data) scannerID. +name and (for calibration data) scanner ID. -INPUTS: patient name, scanner ID and database handle reference +INPUTS: + - $patientName: patient name + - $scannerID : scanner ID + - $dbhr : database handle reference RETURNS: a reference to a hash containing elements including C, C and C, or, in the case of failure, C @@ -99,11 +102,16 @@ sub getSubjectIDs { =pod -=head3 subjectIDIsValid($CandID, $PSCID, $dbhr) +=head3 subjectIDIsValid($CandID, $PSCID, $visit_label, $dbhr, $create_visit_label) Verifies that the subject IDs match. -INPUTS: candidate's CandID, candidate's PSCID and the database handle reference +INPUTS: + - $candID : candidate's C + - $pscid : candidate's C + - $visit_label : visit label + - $dbhr : the database handle reference + - $create_visit_label: boolean, if true, will create the visit label RETURNS: 1 if the ID pair matches, 0 otherwise @@ -132,9 +140,11 @@ sub subjectIDIsValid { =head3 subjectIDExists($CandID, $dbhr) -Verifies that the subject ID (CandID) exists. +Verifies that the subject ID (C) exists. -INPUTS: candidate's CandID and the database handle reference +INPUTS: + - $candID: candidate's C + - $dbhr : the database handle reference RETURNS: 1 if the ID exists, 0 otherwise @@ -155,11 +165,11 @@ sub subjectIDExists { =head3 getScannerCandID($scannerID, $dbhr) -Retrieves the candidate (CandID) for the given scanner. +Retrieves the candidate (C) for the given scanner. INPUTS: the scanner ID and the database handle reference -RETURNS: the CandID or (if none exists) undef +RETURNS: the C or (if none exists) undef =cut @@ -181,10 +191,10 @@ sub getScannerCandID { =pod -=head3 getSessionID($subjectIDref, $studyDate, $dbhr, $objective, ...) +=head3 getSessionID($subjectIDref, $studyDate, $dbhr, $objective, $noStagingCheck) -Gets (or creates) the session ID, given CandID and visitLabel (contained -inside the hashref C<$subjectIDref>). Unless C<$noStagingCheck> is true, it +Gets (or creates) the session ID, given C and visit label (contained +inside the hash ref C<$subjectIDref>). Unless C<$noStagingCheck> is true, it also determines whether staging is required using the C<$studyDate> (formatted YYYYMMDD) to determine whether staging is required based on a simple algorithm: @@ -205,10 +215,14 @@ simple algorithm: =back -INPUTS: hash reference of subject IDs, study date, database handle reference, -the objective of the study and a no staging check flag. +INPUTS: + - $subjectIDref : hash reference of subject IDs + - $studyDate : study date + - $dbhr : database handle reference + - $objective : the objective of the study + - $noStagingCheck: a no staging check flag -RETURNS: a list of two items, (sessionID, requiresStaging) +RETURNS: a list of two items, (C, C) =cut @@ -357,8 +371,10 @@ sub getSessionID { This method tries to figure out if there may have been labelling problems which would put the files in a staging area that does not actually exist. -INPUTS: study date, database handle reference and array of fileIDs to check the -study date +INPUTS: + - $studyDateJD: study date + - $dbhr : database handle reference + - @fileIDs : array of C to check the study date RETURNS: 1 if the file requires staging, 0 otherwise @@ -402,10 +418,12 @@ sub checkMRIStudyDates { =head3 getObjective($subjectIDsref, $dbhr) -Attempts to determine the SubprojectID of a timepoint given the subjectIDs -hashref C<$subjectIDsref> and a database handle reference C<$dbhr> +Attempts to determine the C of a timepoint given the subject IDs +hash ref C<$subjectIDsref> and a database handle reference C<$dbhr> -INPUTS: subjectIDs hashref and database handle reference +INPUTS: + - $subjectIDsref: subjectIDs hashref + - $dbhr : database handle reference RETURNS: the determined objective, or 0 @@ -454,8 +472,11 @@ sub getObjective Determines the type of the scan described by MINC headers based on C table in the database. -INPUTS: center's name, objective of the study, file hashref, database handle -reference +INPUTS: + - $center_name: center's name + - $objective : objective of the study + - $fileref : file hash ref + - $dbhr : database handle reference RETURNS: textual name of scan type from the C table @@ -605,7 +626,7 @@ sub identify_scan_db { =pod -=head3 insert_violated_scans($dbhr, $series_desc, $minc_location, ...) +=head3 insert_violated_scans($dbhr, $series_desc, $minc_location, $patient_name, $candid, $pscid, $visit, $tr, $te, $ti, $slice_thickness, $xstep, $ystep, $zstep, $xspace, $yspace, $zspace, $time, $seriesUID) Inserts scans that do not correspond to any of the defined protocol from the C table into the C table of the @@ -614,23 +635,23 @@ database. INPUTS: - $dbhr : database handle reference - $series_desc : series description of the scan - - $minc_location : minc location of the file + - $minc_location : location of the MINC file - $patient_name : patient name of the scan - - $candid : candidate's CandID - - $pscid : candidate's PSCID + - $candid : candidate's C + - $pscid : candidate's C - $visit : visit of the scan - $tr : repetition time of the scan - $te : echo time of the scan - $ti : inversion time of the scan - $slice_thickness: slice thickness of the image - - $xstep : x-step of the image - - $ystep : y-step of the image - - $zstep : z-step of the image - - $xspace : x-space of the image - - $yspace : y-space of the image - - $zspace : z-space of the image + - $xstep : C of the image + - $ystep : C of the image + - $zstep : C of the image + - $xspace : C of the image + - $yspace : C of the image + - $zspace : C of the image - $time : time dimension of the scan - - $seriesUID : seriesUID of the scan + - $seriesUID : C of the scan =cut @@ -676,7 +697,9 @@ QUERY Will evaluate whether the scalar C<$value> is in the specified C<$range>. -INPUTS: scalar value, scalar range string +INPUTS: + - $val : scalar value to evaluate + - $range: scalar range string RETURNS: 1 if in range, 0 if not in range @@ -702,7 +725,9 @@ sub debug_inrange { Determines the type of the scan identified by its scan type ID. -INPUTS: scan type ID and database handle reference +INPUTS: + - $typeID: scan type ID + - $dbhr : database handle reference RETURNS: Textual name of scan type @@ -738,7 +763,9 @@ sub scan_type_id_to_text { Determines the type of the scan identified by scan type. -INPUTS: scan type and database handle reference +INPUTS: + - $type: scan type + - $dbhr: database handle reference RETURNS: ID of the scan type @@ -772,10 +799,12 @@ sub scan_type_text_to_id { =head3 in_range($value, $range_string) Determines whether numerical value falls within the range described by range -string. Range string is a comma-separated list of range units. A single range -unit follows the syntax either "X" or "X-Y". +string. Range string is a single range unit which follows the syntax +"X" or "X-Y". -INPUTS: numerical value and the range to use +INPUTS: + - $value : numerical value to evaluate + - $range_string: the range to use RETURNS: 1 if the value is in range, 0 otherwise @@ -789,19 +818,14 @@ sub in_range return 0 unless $range_string; return 0 unless defined($value); - my @ranges = split(/,/, $range_string); - - my $range = 0; - foreach $range (@ranges) { - chomp($range); - if($range=~/^[0-9.]+$/) { ## single value element - return 1 if &floats_are_equal($value, $range, $FLOAT_EQUALS_NB_DECIMALS); - } else { ## range X-Y - $range =~ /([0-9.]+)-([0-9.]+)/; - return 1 if ($1 <= $value && $value <= $2) - || &floats_are_equal($value, $1, $FLOAT_EQUALS_NB_DECIMALS) - || &floats_are_equal($value, $2, $FLOAT_EQUALS_NB_DECIMALS); - } + chomp($range_string); + if($range_string=~/^[0-9.]+$/) { ## single value element + return 1 if &floats_are_equal($value, $range_string, $FLOAT_EQUALS_NB_DECIMALS); + } else { ## range_string X-Y + $range_string =~ /([0-9.]+)-([0-9.]+)/; + return 1 if ($1 <= $value && $value <= $2) + || &floats_are_equal($value, $1, $FLOAT_EQUALS_NB_DECIMALS) + || &floats_are_equal($value, $2, $FLOAT_EQUALS_NB_DECIMALS); } ## if we've gotten this far, we're out of range. @@ -812,10 +836,13 @@ sub in_range =head3 floats_are_equal($f1, $f2, $nb_decimals) -Checks whether f1 and f2 are equal (considers only the first nb_decimals -decimals). +Checks whether float 1 and float 2 are equal (considers only the first +C<$nb_decimals> decimals). -INPUTS: float 1, float 2 and the number of first decimals +INPUTS: + - $f1 : float 1 + - $f2 : float 2 + - $nb_decimals: the number of first decimals RETURNS: 1 if the numbers are relatively equal, 0 otherwise @@ -837,8 +864,10 @@ C<$range_string> using the same C<$range_string> syntax as C<&in_range()>. It returns a scalar range SQL string appropriate to use as a WHERE condition (C