From 6858b01559d31bb30453767a8750084e8cc0fa35 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:33:22 +0100 Subject: [PATCH 01/62] Create spiders.py --- dax/spiders.py | 390 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 dax/spiders.py diff --git a/dax/spiders.py b/dax/spiders.py new file mode 100644 index 00000000..85632fcc --- /dev/null +++ b/dax/spiders.py @@ -0,0 +1,390 @@ +""" + Title: spiders.py + Author: Benjamin Yvernault + contact: b.yvernault@ucl.ac.uk + Purpose: + Spider base class and class for Scan and Session spider + Spider name must be: Spider_[name]_v[version].py +""" + +__author__ = 'Benjamin Yvernault' +__email__ = 'b.yvernault@ucl.ac.uk' +__purpose__ = "Spider base class and class for Scan and Session spider." +__version__ = '1.0.0' +__modifications__ = '26 August 2015 - Original write' + +import os +import re +import getpass +import collections +import SpiderUtils +from dax import XnatUtils +from datetime import datetime + +class Spider(object): + """ + Base class for spider + + :param spider_path: spider file path + :param jobdir: directory for temporary files + :param xnat_project: project ID on XNAT + :param xnat_subject: subject label on XNAT + :param xnat_session: experiment label on XNAT + :param xnat_host: host for XNAT if not set in environment variables + :param xnat_user: user for XNAT if not set in environment variables + :param xnat_pass: password for XNAT if not set in environment variables + :param suffix: suffix to the assessor creation + :param manual: if using the spider manually (not on the cluster) (boolean) + ask user if the HOST/USER/PASS are not set for XNAT + """ + def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + # Spider path: + self.spider_path = spider_path + # directory for temporary files + create it + self.jobdir = jobdir + XnatUtils.makedir(os.path.abspath(self.jobdir)) + # to copy results at the end + self.spider_handler = None + # Xnat info: + self.xnat_project = xnat_project + self.xnat_subject = xnat_subject + self.xnat_session = xnat_session + # Xnat connection settings: + self.host = self.get_default_value("xnat_host", "XNAT_HOST", xnat_host) + self.user = self.get_default_value("xnat_host", "XNAT_USER", xnat_user) + self.pwd = self.get_default_value("xnat_host", "XNAT_PASS", xnat_pass) + # Suffix + if suffix[0] != '_': self.suffix = '_'+suffix + else: self.suffix = suffix + # Set the suffix_proc remove any special characters and replace by '_' + self.suffix = re.sub('[^a-zA-Z0-9]', '_', self.suffix) + self.manual = manual + # print time writer: + self.time_writer = SpiderUtils.TimedWriter() + + def get_default_value(self, variable, env_name, value): + """ + Return the default value for the variable: + if arg not NULL + else env variables define by arguments + + :param variable: variable name + :param env_name: name of the environment variable + :param value: value given by the user + :return: default value + """ + if value: + return value + else: + if env_name in os.environ: + return os.environ[env_name] + else: + if not self.manual: + err = "%s not set by user." % (env_name) + err += "\nTo set it choose one of this solution:" + err += "\n\tSet arguments '%s' in the spider class" % (variable) + err += "\n\tSet the environment variable %s" % (env_name) + raise ValueError(err) + else: + msg = """Enter <{var}>:""".format(var=variable) + if env_name == 'XNAT_PASS': + return getpass.getpass(prompt=msg) + else: + return raw_input(msg) + + def select_obj(self, intf, obj_label, resource): + """ + Select scan or assessor resource + + :param obj_label: xnat object label (scan ID or assessor label) + :param resource: folder name under the xnat object + return pyxnat object + """ + tmp_dict = collections.OrderedDict([('project', self.xnat_project), + ('subject', self.xnat_subject), + ('experiment', self.xnat_session)]) + #try on scan + tmp_dict_scan = tmp_dict + tmp_dict_scan['scan'] = obj_label + tmp_dict_scan['resource'] = resource + xnat_obj = intf.select(self.select_str(tmp_dict_scan)) + if xnat_obj: + return xnat_obj + else: + #else try assessor + tmp_dict_assessor = tmp_dict + tmp_dict_assessor['assessor'] = obj_label + tmp_dict_assessor['out/resource'] = resource + xnat_obj = intf.select(self.select_str(tmp_dict_assessor)) + if xnat_obj: + return xnat_obj + else: + err = "No XNAT Object found with the following values: " + err += str(tmp_dict) + err += "\n scan or assessor: %s / resource: %s " % (obj_label, + resource) + raise ValueError(err) + + def download(self, obj_label, resource, folder): + """ + Return a python list of the files downloaded for the resource on the scan + example: + download(scan_id, "DICOM", "/Users/test") + or + download(assessor_label, "DATA", "/Users/test") + + :param obj_label: xnat object label (scan ID or assessor label) + :param resource: folder name under the xnat object + :param folder: download directory + :return: python list of files downloaded + """ + # Open connection to XNAT + xnat = XnatUtils.get_interface(host=self.host, user=self.user, pwd=self.pwd) + resource_obj = self.select_obj(intf=xnat, + obj_label=obj_label, + resource=resource) + # close connection + xnat.disconnect() + return XnatUtils.download_files_from_obj(directory=folder, + resource_obj=resource_obj) + + def define_spider_process_handler(self): + """ + Define the SpiderProcessHandler for the end of any spider + """ + raise NotImplementedError() + + def has_spider_handler(self): + """ + Init Spider Handler if it was not already created. + """ + if not self.spider_handler: + self.define_spider_process_handler() + + def upload(self, fpath, resource): + """ + upload files to the queue on the cluster to be upload to XNAT by DAX pkg + E.g: + spider.upload("/Users/DATA/", "DATA") + spider.upload("/Users/stats_dir/statistical_measures.txt", "STATS") + + :param fpath: path to the folder/file to be uploaded + :param resource: folder name to upload to on the assessor + """ + self.has_spider_handler() + if os.path.isfile(fpath): + if resource == 'PDF': + self.spider_handler.add_pdf(fpath) + else: + self.spider_handler.add_file(fpath, resource) + elif os.path.isdir(fpath): + self.spider_handler.add_folder(fpath, resource) + else: + err = "upload(): file path does not exist: %s" % (fpath) + raise ValueError(err) + + def upload_dict(self, files_dict): + """ + upload files to the queue on the cluster to be upload to XNAT by DAX pkg + following the files python dictionary: {resource_name : fpath} + E.g: + fdict = {"DATA" : "/Users/DATA/", "PDF": "/Users/PDF/report.pdf"} + spider.upload_dict("/Users/DATA/", "DATA") + + :param files_dict: python dictionary containing the pair resource/fpath + """ + self.has_spider_handler() + for resource, fpath in files_dict.items(): + if isinstance(fpath, str): + self.upload(fpath, resource) + elif isinstance(fpath, list): + for ffpath in fpath: + self.upload(ffpath, resource) + else: + err = "upload_dict(): variable not recognize in dictionary for resource %s : %s" % (resource, type(fpath)) + raise ValueError(err) + + def end(self): + """ + Finish the script by sending the end of script flag and cleaning the folder + + :param jobdir: directory for the spider + """ + self.has_spider_handler() + self.spider_handler.done() + self.spider_handler.clean(self.jobdir) + self.print_end() + + def run(self): + """ + Method to execute the process + """ + raise NotImplementedError() + + def finish(self): + """ + Method to copy the results in the Spider Results folder dax.RESULTS_DIR + """ + raise NotImplementedError() + + def print_init(self, argument_parse, author, email): + """ + Print a message to display information on the init parameters, author, + email, and arguments using time writer + + :param argument_parse: argument parser + :param author: author of the spider + :param email: email of the author + """ + self.print_info(author, email) + self.time_writer('-------- Spider starts --------') + self.time_writer('Date and Time at the beginning of the Spider: ', str(datetime.now())) + self.time_writer('INFO: Arguments') + self.print_args(argument_parse) + + def print_msg(self, message): + """ + Print message using time writer + + :param message: string displayed for the user + """ + self.time_writer(message) + + def print_err(self, err_message): + """ + Print error message using time writer + + :param err_message: error message displayed for the user + """ + self.time_writer.print_stderr_message(err_message) + + def print_info(self, author, email): + """ + Print information on the spider using time writer + + :param author: author of the spider + :param email: email of the author + """ + self.print_msg("Running spider : %s" %(self.spider_path)) + self.print_msg("Spider Author: %s" % (author)) + self.print_msg("Author Email: %s" % (email)) + + def print_args(self, argument_parse): + """ + print arguments given to the Spider + + :param argument_parse: argument parser + """ + self.time_writer("-- Arguments given to the spider --") + for info, value in vars(argument_parse).items(): + self.time_writer("""{info} : {value}""".format(info=info, value=value)) + self.time_writer("-----------------------------------") + + def print_end(self): + """ + Last print statement to give the time and date at the end of the spider + """ + self.time_writer('\nTime at the end of the Spider: ', str(datetime.now())) + + @staticmethod + def run_system_cmd(cmd): + """ + Run system command line via os.system() + :param cmd: command to run + """ + os.system(cmd) + + @staticmethod + def select_str(xnat_dict): + """ + Return string for pyxnat to select object from python dict + :param tmp_dict: python dictionary with xnat information + keys = ["project", "subject", "experiement", "scan", "resource"] + or + keys = ["project", "subject", "experiement", "assessor", "out/resource"] + return string to select pyxnat object + """ + select_str = '' + for key, value in xnat_dict.items(): + if value: + select_str += '''/{key}/{label}'''.format(key=key, label=value) + return select_str + + +class ScanSpider(Spider): + """ + class for scan-spider + + :param super --> see base class + :param xnat_scan: scan ID on XNAT (if running on a specific scan) + """ + def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, + xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host, xnat_user, xnat_pass, suffix, manual) + self.xnat_scan = xnat_scan + + def define_spider_process_handler(self): + """ + Define the SpiderProcessHandler for the end of session spider + """ + # Create the SpiderProcessHandler if first time upload + self.spider_handler = XnatUtils.SpiderProcessHandler(self.spider_path, + self.suffix, + self.xnat_project, + self.xnat_subject, + self.xnat_session, + self.xnat_scan) + + def pre_run(self): + """ + Method to download the inputs + """ + raise NotImplementedError() + + def run(self): + """ + Method to execute the process + """ + raise NotImplementedError() + + def finish(self): + """ + Method to copy the results in the Spider Results folder dax.RESULTS_DIR + """ + raise NotImplementedError() + +class SessionSpider(Spider): + """ + class for session-spider + + :param super --> see base class + """ + def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + super(SessionSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host, xnat_user, xnat_pass, suffix, manual) + + def define_spider_process_handler(self): + """ + Define the SpiderProcessHandler for the end of session spider + """ + # Create the SpiderProcessHandler if first time upload + self.spider_handler = XnatUtils.SpiderProcessHandler(self.spider_path, + self.suffix, + self.xnat_project, + self.xnat_subject, + self.xnat_session) + + def run(self): + """ + Method to execute the process + """ + raise NotImplementedError() + + def finish(self): + """ + Method to copy the results in the Spider Results folder dax.RESULTS_DIR + """ + raise NotImplementedError() From 3d1508d91f4a9f6b318b4e8efbcca2c702c0c2ad Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:34:47 +0100 Subject: [PATCH 02/62] Create PathSettings.py --- dax/PathSettings.py | 115 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 dax/PathSettings.py diff --git a/dax/PathSettings.py b/dax/PathSettings.py new file mode 100644 index 00000000..015e9ccd --- /dev/null +++ b/dax/PathSettings.py @@ -0,0 +1,115 @@ +""" + Title: PathSettings.py + Author: Benjamin Yvernault + contact: b.yvernault@ucl.ac.uk + Purpose: + Python file defining the paths required by your spiders/processors/modules. +""" + +__author__ = 'byvernault' +__email__ = 'b.yvernault@ucl.ac.uk' +__purpose__ = "Python file defining the paths required by your spiders/processors/modules." +__modifications__ = '24 August 2015 - Original write' + +import os +from os.path import expanduser + +USER_HOME = expanduser("~") +# Definition of the different paths. +# Path for software for Spider/Processor on default system for Vanderbilt University +DEFAULT_MASIMATLAB_PATH = os.path.join(USER_HOME,'masimatlab') +DEFAULT_ANTS_PATH = '/scratch/mcr/ANTs-build/bin/' +DEFAULT_ART_PATH = '/scratch/mcr/art/' +DEFAULT_FSL_PATH = '/scratch/mcr/fsl5/' +DEFAULT_MASIFUSION_DTIQA = '/scratch/mcr/src/masi-fusion/' #V208 +DEFAULT_MASIFUSION_MA = '/scratch/mcr/full-multi-atlas/masi-fusion/src/' #V253 current +DEFAULT_MIPAV_PATH = '/scratch/mcr/full-multi-atlas/mipav/' +DEFAULT_MIPAV_PATH_CURRENT = '/scratch/mcr/full-multi-atlas/mipav-current/' +DEFAULT_NIFTYREG_PATH = '/scratch/mcr/NiftyReg/niftyreg_install/' +DEFAULT_RECON_FREESURFER_PATH = '/scratch/mcr/freesurfer/' +DEFAULT_REGALADIN_PATH = '/scratch/mcr/NiftyReg/niftyreg_build/reg-apps/reg_aladin' +DEFAULT_SPM_PATH = '/gpfs21/scratch/mcr/spm8/' +DEFAULT_SPM12_PATH = '/gpfs21/scratch/mcr/spm12/' +DEFAULT_TRACULA_FREESURFER_PATH = '/scratch/mcr/freesurfer5.3_TRACULA2014-05-26' +#Path for tools for Module on default system for Vanderbilt University +DEFAULT_DCM2NII_PATH = '/gpfs21/scratch/mcr/mricron' +DEFAULT_DCMDJPEG_PATH = '/usr/local/dcmtk/latest/x86_64/gcc46/nonet/bin' +#REDCap +API_URL = 'https://redcap.vanderbilt.edu/api/' + +#MASIMATLAB +if 'MASIMATLAB_PATH' not in os.environ: + MASIMATLAB_PATH = DEFAULT_MASIMATLAB_PATH +else: + MASIMATLAB_PATH = os.environ['MASIMATLAB_PATH'] +#ANTS_PATH +if 'ANTS_PATH' not in os.environ: + ANTS_PATH = DEFAULT_ANTS_PATH +else: + ANTS_PATH = os.environ['ANTS_PATH'] +#ART_PATH +if 'ART_PATH' not in os.environ: + ART_PATH = DEFAULT_ART_PATH +else: + ART_PATH = os.environ['ART_PATH'] +#FSL_PATH +if 'FSL_PATH' not in os.environ: + FSL_PATH = DEFAULT_FSL_PATH +else: + FSL_PATH = os.environ['FSL_PATH'] +#MASIFUSION_PATH +#v208 +if 'MASIFUSION_DTIQA' not in os.environ: + MASIFUSION_DTIQA = DEFAULT_MASIFUSION_DTIQA +else: + MASIFUSION_DTIQA = os.environ['MASIFUSION_DTIQA'] +#Current +if 'MASIFUSION_MA' not in os.environ: + MASIFUSION_MA = DEFAULT_MASIFUSION_MA +else: + MASIFUSION_MA = os.environ['MASIFUSION_MA'] +#MIPAV_PATH +if 'MIPAV_PATH' not in os.environ: + MIPAV_PATH = DEFAULT_MIPAV_PATH +else: + MIPAV_PATH = os.environ['MIPAV_PATH'] +#NIFTYREG_PATH +if 'NIFTYREG_PATH' not in os.environ: + NIFTYREG_PATH = DEFAULT_NIFTYREG_PATH +else: + NIFTYREG_PATH = os.environ['NIFTYREG_PATH'] +#RECON_FREESURFER_PATH +if 'RECON_FREESURFER_PATH' not in os.environ: + RECON_FREESURFER_PATH = DEFAULT_RECON_FREESURFER_PATH +else: + RECON_FREESURFER_PATH = os.environ['RECON_FREESURFER_PATH'] +#REGALADIN_PATH +if 'REGALADIN_PATH' not in os.environ: + REGALADIN_PATH = DEFAULT_REGALADIN_PATH +else: + REGALADIN_PATH = os.environ['REGALADIN_PATH'] +#SPM_PATH +if 'SPM_PATH' not in os.environ: + SPM_PATH = DEFAULT_SPM_PATH +else: + SPM_PATH = os.environ['SPM_PATH'] +if 'SPM12_PATH' not in os.environ: + SPM12_PATH = DEFAULT_SPM12_PATH +else: + SPM_PATH = os.environ['SPM12_PATH'] + +#TRACULA_FREESURFER_PATH +if 'TRACULA_FREESURFER_PATH' not in os.environ: + TRACULA_FREESURFER_PATH = DEFAULT_TRACULA_FREESURFER_PATH +else: + TRACULA_FREESURFER_PATH = os.environ['TRACULA_FREESURFER_PATH'] +#DCM2NII_PATH +if 'DCM2NII_PATH' not in os.environ: + DCM2NII_PATH = DEFAULT_DCM2NII_PATH +else: + DCM2NII_PATH = os.environ['DCM2NII_PATH'] +#DCMDJPEG_PATH +if 'DCMDJPEG_PATH' not in os.environ: + DCMDJPEG_PATH = DEFAULT_DCMDJPEG_PATH +else: + DCMDJPEG_PATH = os.environ['DCMDJPEG_PATH'] From 976d8a0605fcb6c81cb29458efde6f902e36da94 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:37:51 +0100 Subject: [PATCH 03/62] Delete PathSettings.py --- dax/PathSettings.py | 115 -------------------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 dax/PathSettings.py diff --git a/dax/PathSettings.py b/dax/PathSettings.py deleted file mode 100644 index 015e9ccd..00000000 --- a/dax/PathSettings.py +++ /dev/null @@ -1,115 +0,0 @@ -""" - Title: PathSettings.py - Author: Benjamin Yvernault - contact: b.yvernault@ucl.ac.uk - Purpose: - Python file defining the paths required by your spiders/processors/modules. -""" - -__author__ = 'byvernault' -__email__ = 'b.yvernault@ucl.ac.uk' -__purpose__ = "Python file defining the paths required by your spiders/processors/modules." -__modifications__ = '24 August 2015 - Original write' - -import os -from os.path import expanduser - -USER_HOME = expanduser("~") -# Definition of the different paths. -# Path for software for Spider/Processor on default system for Vanderbilt University -DEFAULT_MASIMATLAB_PATH = os.path.join(USER_HOME,'masimatlab') -DEFAULT_ANTS_PATH = '/scratch/mcr/ANTs-build/bin/' -DEFAULT_ART_PATH = '/scratch/mcr/art/' -DEFAULT_FSL_PATH = '/scratch/mcr/fsl5/' -DEFAULT_MASIFUSION_DTIQA = '/scratch/mcr/src/masi-fusion/' #V208 -DEFAULT_MASIFUSION_MA = '/scratch/mcr/full-multi-atlas/masi-fusion/src/' #V253 current -DEFAULT_MIPAV_PATH = '/scratch/mcr/full-multi-atlas/mipav/' -DEFAULT_MIPAV_PATH_CURRENT = '/scratch/mcr/full-multi-atlas/mipav-current/' -DEFAULT_NIFTYREG_PATH = '/scratch/mcr/NiftyReg/niftyreg_install/' -DEFAULT_RECON_FREESURFER_PATH = '/scratch/mcr/freesurfer/' -DEFAULT_REGALADIN_PATH = '/scratch/mcr/NiftyReg/niftyreg_build/reg-apps/reg_aladin' -DEFAULT_SPM_PATH = '/gpfs21/scratch/mcr/spm8/' -DEFAULT_SPM12_PATH = '/gpfs21/scratch/mcr/spm12/' -DEFAULT_TRACULA_FREESURFER_PATH = '/scratch/mcr/freesurfer5.3_TRACULA2014-05-26' -#Path for tools for Module on default system for Vanderbilt University -DEFAULT_DCM2NII_PATH = '/gpfs21/scratch/mcr/mricron' -DEFAULT_DCMDJPEG_PATH = '/usr/local/dcmtk/latest/x86_64/gcc46/nonet/bin' -#REDCap -API_URL = 'https://redcap.vanderbilt.edu/api/' - -#MASIMATLAB -if 'MASIMATLAB_PATH' not in os.environ: - MASIMATLAB_PATH = DEFAULT_MASIMATLAB_PATH -else: - MASIMATLAB_PATH = os.environ['MASIMATLAB_PATH'] -#ANTS_PATH -if 'ANTS_PATH' not in os.environ: - ANTS_PATH = DEFAULT_ANTS_PATH -else: - ANTS_PATH = os.environ['ANTS_PATH'] -#ART_PATH -if 'ART_PATH' not in os.environ: - ART_PATH = DEFAULT_ART_PATH -else: - ART_PATH = os.environ['ART_PATH'] -#FSL_PATH -if 'FSL_PATH' not in os.environ: - FSL_PATH = DEFAULT_FSL_PATH -else: - FSL_PATH = os.environ['FSL_PATH'] -#MASIFUSION_PATH -#v208 -if 'MASIFUSION_DTIQA' not in os.environ: - MASIFUSION_DTIQA = DEFAULT_MASIFUSION_DTIQA -else: - MASIFUSION_DTIQA = os.environ['MASIFUSION_DTIQA'] -#Current -if 'MASIFUSION_MA' not in os.environ: - MASIFUSION_MA = DEFAULT_MASIFUSION_MA -else: - MASIFUSION_MA = os.environ['MASIFUSION_MA'] -#MIPAV_PATH -if 'MIPAV_PATH' not in os.environ: - MIPAV_PATH = DEFAULT_MIPAV_PATH -else: - MIPAV_PATH = os.environ['MIPAV_PATH'] -#NIFTYREG_PATH -if 'NIFTYREG_PATH' not in os.environ: - NIFTYREG_PATH = DEFAULT_NIFTYREG_PATH -else: - NIFTYREG_PATH = os.environ['NIFTYREG_PATH'] -#RECON_FREESURFER_PATH -if 'RECON_FREESURFER_PATH' not in os.environ: - RECON_FREESURFER_PATH = DEFAULT_RECON_FREESURFER_PATH -else: - RECON_FREESURFER_PATH = os.environ['RECON_FREESURFER_PATH'] -#REGALADIN_PATH -if 'REGALADIN_PATH' not in os.environ: - REGALADIN_PATH = DEFAULT_REGALADIN_PATH -else: - REGALADIN_PATH = os.environ['REGALADIN_PATH'] -#SPM_PATH -if 'SPM_PATH' not in os.environ: - SPM_PATH = DEFAULT_SPM_PATH -else: - SPM_PATH = os.environ['SPM_PATH'] -if 'SPM12_PATH' not in os.environ: - SPM12_PATH = DEFAULT_SPM12_PATH -else: - SPM_PATH = os.environ['SPM12_PATH'] - -#TRACULA_FREESURFER_PATH -if 'TRACULA_FREESURFER_PATH' not in os.environ: - TRACULA_FREESURFER_PATH = DEFAULT_TRACULA_FREESURFER_PATH -else: - TRACULA_FREESURFER_PATH = os.environ['TRACULA_FREESURFER_PATH'] -#DCM2NII_PATH -if 'DCM2NII_PATH' not in os.environ: - DCM2NII_PATH = DEFAULT_DCM2NII_PATH -else: - DCM2NII_PATH = os.environ['DCM2NII_PATH'] -#DCMDJPEG_PATH -if 'DCMDJPEG_PATH' not in os.environ: - DCMDJPEG_PATH = DEFAULT_DCMDJPEG_PATH -else: - DCMDJPEG_PATH = os.environ['DCMDJPEG_PATH'] From f03aa599c4d640fb5c386bb1c4f639a7864c42af Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:40:11 +0100 Subject: [PATCH 04/62] Adding utils to spiders.py --- dax/spiders.py | 109 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 85632fcc..11ab4481 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -15,9 +15,10 @@ import os import re +import sys +import time import getpass import collections -import SpiderUtils from dax import XnatUtils from datetime import datetime @@ -61,7 +62,7 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session self.suffix = re.sub('[^a-zA-Z0-9]', '_', self.suffix) self.manual = manual # print time writer: - self.time_writer = SpiderUtils.TimedWriter() + self.time_writer = TimedWriter() def get_default_value(self, variable, env_name, value): """ @@ -388,3 +389,107 @@ def finish(self): Method to copy the results in the Spider Results folder dax.RESULTS_DIR """ raise NotImplementedError() + +#### CLASSES #### +# class to display time +class TimedWriter(object): + '''Class to automatically write timed output message + Args: + name - Names to write with output (default=None) + + Examples: + >>>a = Time_Writer() + >>>a("this is a test") + [00d 00h 00m 00s] this is a test + >>>sleep(60) + >>>a("this is a test") + [00d 00h 01m 00s] this is a test + + Written by Andrew Plassard (Vanderbilt) + ''' + def __init__(self, name=None): + self.start_time = time.localtime() + self.name = name + + def print_stderr_message(self, text): + '''Prints a timed message to stderr''' + self.print_timed_message(text, pipe=sys.stderr) + + def print_timed_message(self, text, pipe=sys.stdout): + '''Prints a timed message + Args: + text - text to display + pipe - pipe to write to (default: sys.stdout) + ''' + msg = "" + if self.name: + msg = "[%s]" % self.name + time_now = time.localtime() + time_diff = time.mktime(time_now)-time.mktime(self.start_time) + (days, res) = divmod(time_diff, 86400) + (hours, res) = divmod(res, 3600) + (mins, secs) = divmod(res, 60) + msg = "%s[%dd %02dh %02dm %02ds] %s" % (msg, days, hours, mins, secs, text) + print >> pipe, msg + + def __call__(self, text, pipe=sys.stdout): + '''Prints a timed message + Inputs: + text - text to display + pipe - pipe to write to (default: sys.stdout)''' + self.print_timed_message(text, pipe=pipe) + +#### Functions #### +def get_default_argparser(name, description): + """ + Return default argparser arguments for all Spider + + :return: argparser obj + """ + from argparse import ArgumentParser + ap = ArgumentParser(prog=name, description=description) + ap.add_argument('-p', dest='proj_label', help='Project Label', required=True) + ap.add_argument('-s', dest='subj_label', help='Subject Label', required=True) + ap.add_argument('-e', dest='sess_label', help='Session Label', required=True) + ap.add_argument('-d', dest='temp_dir', help='Temporary Directory', required=True) + ap.add_argument('--suffix', dest='suffix', help='assessor suffix. default: None', default=None) + ap.add_argument('-m', dest='manual', help='Manual: Ask user for XNAT loggings if not set', action='store_true') + return ap + +def get_session_argparser(name, description): + """ + Return session argparser arguments for session Spider + + :return: argparser obj + """ + ap = get_default_argparser(name, description) + return ap + +def get_scan_argparser(name, description): + """ + Return scan argparser arguments for scan Spider + + :return: argparser obj + """ + ap = get_default_argparser(name, description) + ap.add_argument('-c', dest='scan_label', help='Scan label', required=True) + return ap + +def is_good_version(version): + """ + Check the format of the version and return true if it's a proper format. + Format: X.Y.Z + see http://semver.org + + :param version: version given by the user + """ + vers = version.split('.') + if len(vers) != 3: + return False + else: + if not vers[0].isdigit() or \ + not vers[1].isdigit() or \ + not vers[2].isdigit(): + return False + return True + From c7465c9da8d4197eb5605a8764ebfa94bdb5141b Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:43:51 +0100 Subject: [PATCH 05/62] Create GenerateSpiderTemplate Executable to generate spider --- bin/dax_tools/GenerateSpiderTemplate | 324 +++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 bin/dax_tools/GenerateSpiderTemplate diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate new file mode 100644 index 00000000..a0a6b922 --- /dev/null +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -0,0 +1,324 @@ +""" + Title: generate_spider_template.py + Author: Benjamin Yvernault + contact: b.yvernault@ucl.ac.uk + Purpose: + Generate your Spider.py following the template for spider describe in this file. +""" + +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +__author__ = 'Benjamin Yvernault' +__email__ = 'b.yvernault@ucl.ac.uk' +__purpose__ = "Generate your Spider.py following the template for spider describe in this file." +__version__ = '1.0.0' +__modifications__ = '21 August 2015 - Original write' + +import os +from dax import spiders +from datetime import datetime + +DEFAULT_TEMPLATE = """''' + Author: {author} + contact: {email_addr} + Spider name: {name} + Spider version: {version} + Creation date: {now} + Purpose: {purpose} +''' + +__author__ = "{author}" +__email__ = "{email_addr}" +__purpose__ = "{purpose}" +__spider_name__ = "{name}" +__version__ = "{version}" +__modifications__ = "{now} - Original write" + +# Python packages import +import os +import sys +from datetime import datetime +from dax import XnatUtils, spiders, RESULTS_DIR, ScanSpider, SessionSpider +""" + +SCAN_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" +def parse_args(): + ''' + Argument parser for the spider input variables + by default: + -p : proj_label + -s : subj_label + -e : sess_label + -d : temp_dir + --suffix : suffix + --manual : manual + -c : scan_label + + :return: argument parser object created by parse_args() + ''' + from argparse import ArgumentParser + ap = spiders.get_scan_argparser("{name}", "{purpose}") + + # + # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # + + return ap.parse_args() + +class Spider_{name}(ScanSpider): + ''' + Scan Spider class to do: {purpose} + + :param spider_path: spider file path + :param jobdir: directory for temporary files + :param xnat_project: project ID on XNAT + :param xnat_subject: subject label on XNAT + :param xnat_session: experiment label on XNAT + :param xnat_scan: scan label on XNAT + :param xnat_host: host for XNAT if not set in environment variables + :param xnat_user: user for XNAT if not set in environment variables + :param xnat_pass: password for XNAT if not set in environment variables + :param suffix: suffix to the assessor creation + :param manual: if using the spider manually (not on the cluster) (boolean) + ask user if the HOST/USER/PASS are not set for XNAT + ''' + def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, + xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): + super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host, xnat_user, xnat_pass, suffix, manual) + self.xnat_scan = xnat_scan + self.inputs = list() + + def pre_run(self, argument_parse): + ''' + Method to download data from XNAT + + :param argument_parse: argument parser object return by parse_args() + ''' + resource = 'XXXX' #resource to download from the scan on XNAT + folder = os.path.join(self.jobdir, 'inputs') + os.makedirs(folder) + self.inputs.extend(self.download(self.xnat_scan, resource, folder)) + + # + # YOU CAN ADD MORE line to download other data LIKE + # self.inputs.extend(self.download(**kwargs)) + # + + def run(self): + ''' + Method running the process for the spider on the inputs data + ''' + # + # CODE THAT YOU WANT TO RUN ON THE DATA + # + + def finish(self): + ''' + Method to copy the results in the Spider Results folder dax.RESULTS_DIR + ''' + self.time_writer('Results saved in folder: %s' % (RESULTS_DIR)) + results_dict = {{'PDF': pdfpath, + # + # ADD OTHER RESULTS YOU WANT TO SAVE + # + }} + self.upload_dict(results_dict) + self.end() + +if __name__ == '__main__': + args = parse_args() + # generate spider object: + spider_obj = Spider_{name}(script_name=os.path.basename(sys.argv[0])[:-3], + xnat_project=args.proj_label, + xnat_subject=args.subj_label, + xnat_session=args.sess_label, + xnat_scan=args.scan_label, + xnat_host=None, + xnat_user=None, + xnat_pass=None, + manual=args.manual, + suffix=args.suffix) + # print some information before starting + spider_obj.print_init(args, "{author}", "{email_addr}") + + # Pre-run method to download data from XNAT + spider_obj.pre_run(args) + + # Run method + spider_obj.run() + + # Finish method to copy results + spider_obj.finish() +""" + +SESSION_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" +def parse_args(): + ''' + Argument parser for the spider input variables + by default: + -p : proj_label + -s : subj_label + -e : sess_label + -d : temp_dir + --suffix : suffix + --manual : manual + + :return: argument parser object created by parse_args() + ''' + from argparse import ArgumentParser + ap = spiders.get_session_argparser("{name}", "{purpose}") + + # + # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # + + return ap.parse_args() + +class Spider_{name}(SessionSpider): + ''' + Session Spider class to do: {purpose} + + :param spider_path: spider file path + :param jobdir: directory for temporary files + :param xnat_project: project ID on XNAT + :param xnat_subject: subject label on XNAT + :param xnat_session: experiment label on XNAT + :param xnat_host: host for XNAT if not set in environment variables + :param xnat_user: user for XNAT if not set in environment variables + :param xnat_pass: password for XNAT if not set in environment variables + :param suffix: suffix to the assessor creation + :param manual: if using the spider manually (not on the cluster) (boolean) + ask user if the HOST/USER/PASS are not set for XNAT + ''' + def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): + super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host, xnat_user, xnat_pass, suffix, manual) + self.inputs = list() + + def pre_run(self, argument_parse): + ''' + Method to download data from XNAT + + :param argument_parse: argument parser object return by parse_args() + ''' + resource = 'XXXX' #resource to download from the scan on XNAT + folder = os.path.join(self.jobdir, 'inputs') + os.makedirs(folder) + self.inputs.extend(self.download(argument_parse.scan, resource, folder)) + + # + # YOU CAN ADD MORE line to download other data LIKE + # self.inputs.extend(self.download(**kwargs)) + # + + def run(self): + ''' + Method running the process for the spider on the inputs data + ''' + # + # CODE THAT YOU WANT TO RUN ON THE DATA + # + + def finish(self): + ''' + Method to copy the results in the Spider Results folder dax.RESULTS_DIR + ''' + self.time_writer('Results saved in folder: %s' % (RESULTS_DIR)) + results_dict = {{'PDF': pdfpath, + # + # ADD OTHER RESULTS YOU WANT TO SAVE + # + }} + self.upload_dict(results_dict) + self.end() + +if __name__ == '__main__': + args = parse_args() + # generate spider object: + spider_obj = Spider_{name}(script_name=os.path.basename(sys.argv[0])[:-3], + xnat_project=args.proj_label, + xnat_subject=args.subj_label, + xnat_session=args.sess_label, + xnat_host=None, + xnat_user=None, + xnat_pass=None, + manual=args.manual, + suffix=args.suffix) + # print some information before starting + spider_obj.print_init(args, "{author}", "{email_addr}") + + # Pre-run method to download data from XNAT + spider_obj.pre_run(args) + + # Run method + spider_obj.run() + + # Finish method to copy results + spider_obj.finish() +""" + +def write_spider(spider_fpath, templates, args): + """ + Create the Spider path with the proper template + + :param spider_fpath: path where the spider script will be saved + :param templates: template to use (scan or session) + :param args: arguments parser + """ + spider_code = templates.format(author=args.author, + email_addr=args.email, + name=args.name, + version=args.version, + now=str(datetime.now()), + purpose=args.purpose) + f_obj = open(spider_fpath, "w") + f_obj.writelines(spider_code) + f_obj.close() + +def parse_args(): + """ + Parser for arguments + """ + from argparse import ArgumentParser + usage = "Generates snapshots/preview for the scans for all subjects in a project." + argp = ArgumentParser(prog='make_preview_xnat', description=usage) + argp.add_argument('-n', dest='name', help='Name for Spider. E.G: fMRIQA.', required=True) + argp.add_argument('-v', dest='version', + help='Spider version (format: X.Y.Z). E.G: 1.0.0', required=True) + argp.add_argument('-a', dest='author', help='Author name.', required=True) + argp.add_argument('-e', dest='email', help='Author email address.', required=True) + argp.add_argument('-p', dest='purpose', help='Spider purpose.', required=True) + argp.add_argument('-c', dest='on_scan', action='store_true', help='Use Scan type Spider.') + argp.add_argument('-d', dest='directory', + help="Directory where the spider file will be generated. Default: current directory.", + default=None) + return argp.parse_args() + +if __name__ == '__main__': + ARGS = parse_args() + + # Removing Spider if present in name + if ARGS.name[:6] == "Spider": + ARGS.name = ARGS.name[6:] + if not spiders.is_good_version(ARGS.version): + err = "wrong format version given to script." + \ + "It must follow the X.Y.Z template with X, Y, and Z integers." + \ + "Look at http://semver.org for more information." + raise ValueError(err) + + TEMP = """Spider_{name}_v{version}.py""" + SPIDER_NAME = TEMP.format(name=ARGS.name, + version=ARGS.version.replace('.', '_')) + if ARGS.directory and os.path.exists(ARGS.directory): + SPIDER_FPATH = os.path.join(ARGS.directory, SPIDER_NAME) + else: + SPIDER_FPATH = os.path.join(os.getcwd(), SPIDER_NAME) + if ARGS.on_scan: + print "Generating file %s for scan spider %s ..." % (SPIDER_FPATH, ARGS.name) + write_spider(SPIDER_FPATH, SCAN_LEVEL_TEMPLATE, ARGS) + else: + print "Generating file %s for session spider %s ..." % (SPIDER_FPATH, ARGS.name) + write_spider(SPIDER_FPATH, SESSION_LEVEL_TEMPLATE, ARGS) From 029c2751dee0eea8d6e9e41a077370df39677404 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:46:01 +0100 Subject: [PATCH 06/62] Add ScanSpider and SessionSpider to init --- dax/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dax/__init__.py b/dax/__init__.py index e2b4a5fb..400e52ab 100644 --- a/dax/__init__.py +++ b/dax/__init__.py @@ -1,11 +1,12 @@ +import bin +import log +import XnatUtils +from .task import Task from .cluster import PBS -from .dax_settings import DEFAULT_EMAIL_OPTS, RESULTS_DIR, ADMIN_EMAIL, API_URL, API_KEY_DAX, REDCAP_VAR, DEFAULT_GATEWAY, SMTP_HOST, SMTP_FROM, SMTP_PASS, DEFAULT_MAX_AGE from .launcher import Launcher +from .version import VERSION as __version__ +from .XnatUtils import SpiderProcessHandler from .modules import ScanModule, SessionModule +from .spiders import ScanSpider, SessionSpider from .processors import ScanProcessor, SessionProcessor -from .task import Task -from .XnatUtils import SpiderProcessHandler -import XnatUtils -import bin -import log -from .version import VERSION as __version__ +from .dax_settings import DEFAULT_EMAIL_OPTS, RESULTS_DIR, ADMIN_EMAIL, API_URL, API_KEY_DAX, REDCAP_VAR, DEFAULT_GATEWAY, SMTP_HOST, SMTP_FROM, SMTP_PASS, DEFAULT_MAX_AGE From 2570414e3dbbe3795a03312f613996143d147e27 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Mon, 14 Sep 2015 17:55:53 +0100 Subject: [PATCH 07/62] updating display --- bin/Xnat_tools/Xnatupload | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Xnat_tools/Xnatupload b/bin/Xnat_tools/Xnatupload index c952ca7f..26c11370 100755 --- a/bin/Xnat_tools/Xnatupload +++ b/bin/Xnat_tools/Xnatupload @@ -409,7 +409,7 @@ def upload_data_xnat(xnat,options,scan_list,assessor_list): for index,ps in enumerate(sorted(proj_subj_list)): project=ps.split('-x-')[0] subject=ps.split('-x-')[1] - logger.info(' * '+str(index+1)+'/'+str(number)+' Project/Subject : '+project+'/'+subject) + logger.info(' * '+str(index+1)+'/'+str(number)+' subjects -- Pair Project/Subject : '+project+'/'+subject) ##SCAN## for scan in extract_obj_one_subject(project,subject,scan_list): scan_obj,_=get_xnat_obj(xnat,scan,options.session_type) From 00365fdd9878dd080c8a627c0bcc7fb34cdbb927 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 09:19:44 +0100 Subject: [PATCH 08/62] Adding new executables to setup --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index e989b95d..488f7d16 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,9 @@ def readme(): 'bin/dax_tools/dax_update_tasks', 'bin/dax_tools/dax_upload', 'bin/dax_tools/run_spider', + 'bin/dax_tools/GenerateModuleTemplate', + 'bin/dax_tools/GenerateProcessorTemplate', + 'bin/dax_tools/GenerateSpiderTemplate', 'bin/freesurfer_tools/fsupload', 'bin/freesurfer_tools/fsdownload', 'bin/freesurfer_tools/fsview', From 4ba05c03fb531477ea9e90fb392ca65c5bae1f7a Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 09:30:59 +0100 Subject: [PATCH 09/62] Adding display and help --- bin/dax_tools/GenerateSpiderTemplate | 54 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index a0a6b922..40a75c33 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -61,7 +61,9 @@ def parse_args(): ap = spiders.get_scan_argparser("{name}", "{purpose}") # - # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # example to add one options: + # ap.add_argument("--option", dest="option_id", default=None, help="Option description.", required=True) # return ap.parse_args() @@ -92,9 +94,9 @@ class Spider_{name}(ScanSpider): def pre_run(self, argument_parse): ''' - Method to download data from XNAT + Method to download data from XNAT - :param argument_parse: argument parser object return by parse_args() + :param argument_parse: argument parser object return by parse_args() ''' resource = 'XXXX' #resource to download from the scan on XNAT folder = os.path.join(self.jobdir, 'inputs') @@ -108,7 +110,7 @@ class Spider_{name}(ScanSpider): def run(self): ''' - Method running the process for the spider on the inputs data + Method running the process for the spider on the inputs data ''' # # CODE THAT YOU WANT TO RUN ON THE DATA @@ -116,7 +118,7 @@ class Spider_{name}(ScanSpider): def finish(self): ''' - Method to copy the results in the Spider Results folder dax.RESULTS_DIR + Method to copy the results in the Spider Results folder dax.RESULTS_DIR ''' self.time_writer('Results saved in folder: %s' % (RESULTS_DIR)) results_dict = {{'PDF': pdfpath, @@ -156,16 +158,16 @@ if __name__ == '__main__': SESSION_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" def parse_args(): ''' - Argument parser for the spider input variables - by default: - -p : proj_label - -s : subj_label - -e : sess_label - -d : temp_dir - --suffix : suffix - --manual : manual - - :return: argument parser object created by parse_args() + Argument parser for the spider input variables + by default: + -p : proj_label + -s : subj_label + -e : sess_label + -d : temp_dir + --suffix : suffix + --manual : manual + + :return: argument parser object created by parse_args() ''' from argparse import ArgumentParser ap = spiders.get_session_argparser("{name}", "{purpose}") @@ -200,9 +202,9 @@ class Spider_{name}(SessionSpider): def pre_run(self, argument_parse): ''' - Method to download data from XNAT - - :param argument_parse: argument parser object return by parse_args() + Method to download data from XNAT + + :param argument_parse: argument parser object return by parse_args() ''' resource = 'XXXX' #resource to download from the scan on XNAT folder = os.path.join(self.jobdir, 'inputs') @@ -216,7 +218,7 @@ class Spider_{name}(SessionSpider): def run(self): ''' - Method running the process for the spider on the inputs data + Method running the process for the spider on the inputs data ''' # # CODE THAT YOU WANT TO RUN ON THE DATA @@ -224,7 +226,7 @@ class Spider_{name}(SessionSpider): def finish(self): ''' - Method to copy the results in the Spider Results folder dax.RESULTS_DIR + Method to copy the results in the Spider Results folder dax.RESULTS_DIR ''' self.time_writer('Results saved in folder: %s' % (RESULTS_DIR)) results_dict = {{'PDF': pdfpath, @@ -262,11 +264,11 @@ if __name__ == '__main__': def write_spider(spider_fpath, templates, args): """ - Create the Spider path with the proper template - - :param spider_fpath: path where the spider script will be saved - :param templates: template to use (scan or session) - :param args: arguments parser + Create the Spider path with the proper template + + :param spider_fpath: path where the spider script will be saved + :param templates: template to use (scan or session) + :param args: arguments parser """ spider_code = templates.format(author=args.author, email_addr=args.email, @@ -280,7 +282,7 @@ def write_spider(spider_fpath, templates, args): def parse_args(): """ - Parser for arguments + Parser for arguments """ from argparse import ArgumentParser usage = "Generates snapshots/preview for the scans for all subjects in a project." From 04cba4faff01abb89d00e6d25ff162f602740f86 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 09:57:15 +0100 Subject: [PATCH 10/62] Update GenerateSpiderTemplate --- bin/dax_tools/GenerateSpiderTemplate | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index 40a75c33..b551510f 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -174,6 +174,8 @@ def parse_args(): # # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # example to add one options: + # ap.add_argument("--option", dest="option_id", default=None, help="Option description.", required=True) # return ap.parse_args() From e87ab151cf457a2f40b96d0edeb81612e695bbf2 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 10:15:45 +0100 Subject: [PATCH 11/62] Update spiders.py --- dax/spiders.py | 187 +++++++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 91 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 11ab4481..0095f203 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -5,11 +5,12 @@ Purpose: Spider base class and class for Scan and Session spider Spider name must be: Spider_[name]_v[version].py + Utils for spiders """ __author__ = 'Benjamin Yvernault' __email__ = 'b.yvernault@ucl.ac.uk' -__purpose__ = "Spider base class and class for Scan and Session spider." +__purpose__ = "Spider base class, Scan and Session spider class, and Utils for spiders." __version__ = '1.0.0' __modifications__ = '26 August 2015 - Original write' @@ -43,8 +44,8 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session # Spider path: self.spider_path = spider_path # directory for temporary files + create it - self.jobdir = jobdir - XnatUtils.makedir(os.path.abspath(self.jobdir)) + self.jobdir = os.path.abspath(jobdir) + XnatUtils.makedir(self.jobdir) # to copy results at the end self.spider_handler = None # Xnat info: @@ -66,14 +67,14 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session def get_default_value(self, variable, env_name, value): """ - Return the default value for the variable: - if arg not NULL - else env variables define by arguments - - :param variable: variable name - :param env_name: name of the environment variable - :param value: value given by the user - :return: default value + Return the default value for the variable: + if arg not NULL + else env variables define by arguments + + :param variable: variable name + :param env_name: name of the environment variable + :param value: value given by the user + :return: default value """ if value: return value @@ -96,11 +97,11 @@ def get_default_value(self, variable, env_name, value): def select_obj(self, intf, obj_label, resource): """ - Select scan or assessor resource - - :param obj_label: xnat object label (scan ID or assessor label) - :param resource: folder name under the xnat object - return pyxnat object + Select scan or assessor resource + + :param obj_label: xnat object label (scan ID or assessor label) + :param resource: folder name under the xnat object + return pyxnat object """ tmp_dict = collections.OrderedDict([('project', self.xnat_project), ('subject', self.xnat_subject), @@ -129,16 +130,16 @@ def select_obj(self, intf, obj_label, resource): def download(self, obj_label, resource, folder): """ - Return a python list of the files downloaded for the resource on the scan - example: - download(scan_id, "DICOM", "/Users/test") - or - download(assessor_label, "DATA", "/Users/test") - - :param obj_label: xnat object label (scan ID or assessor label) - :param resource: folder name under the xnat object - :param folder: download directory - :return: python list of files downloaded + Return a python list of the files downloaded for the resource on the scan + example: + download(scan_id, "DICOM", "/Users/test") + or + download(assessor_label, "DATA", "/Users/test") + + :param obj_label: xnat object label (scan ID or assessor label) + :param resource: folder name under the xnat object + :param folder: download directory + :return: python list of files downloaded """ # Open connection to XNAT xnat = XnatUtils.get_interface(host=self.host, user=self.user, pwd=self.pwd) @@ -152,26 +153,26 @@ def download(self, obj_label, resource, folder): def define_spider_process_handler(self): """ - Define the SpiderProcessHandler for the end of any spider + Define the SpiderProcessHandler for the end of any spider """ raise NotImplementedError() def has_spider_handler(self): """ - Init Spider Handler if it was not already created. + Init Spider Handler if it was not already created. """ if not self.spider_handler: self.define_spider_process_handler() def upload(self, fpath, resource): """ - upload files to the queue on the cluster to be upload to XNAT by DAX pkg - E.g: - spider.upload("/Users/DATA/", "DATA") - spider.upload("/Users/stats_dir/statistical_measures.txt", "STATS") - - :param fpath: path to the folder/file to be uploaded - :param resource: folder name to upload to on the assessor + upload files to the queue on the cluster to be upload to XNAT by DAX pkg + E.g: + spider.upload("/Users/DATA/", "DATA") + spider.upload("/Users/stats_dir/statistical_measures.txt", "STATS") + + :param fpath: path to the folder/file to be uploaded + :param resource: folder name to upload to on the assessor """ self.has_spider_handler() if os.path.isfile(fpath): @@ -187,13 +188,13 @@ def upload(self, fpath, resource): def upload_dict(self, files_dict): """ - upload files to the queue on the cluster to be upload to XNAT by DAX pkg - following the files python dictionary: {resource_name : fpath} - E.g: - fdict = {"DATA" : "/Users/DATA/", "PDF": "/Users/PDF/report.pdf"} - spider.upload_dict("/Users/DATA/", "DATA") - - :param files_dict: python dictionary containing the pair resource/fpath + upload files to the queue on the cluster to be upload to XNAT by DAX pkg + following the files python dictionary: {resource_name : fpath} + E.g: + fdict = {"DATA" : "/Users/DATA/", "PDF": "/Users/PDF/report.pdf"} + spider.upload_dict("/Users/DATA/", "DATA") + + :param files_dict: python dictionary containing the pair resource/fpath """ self.has_spider_handler() for resource, fpath in files_dict.items(): @@ -208,9 +209,9 @@ def upload_dict(self, files_dict): def end(self): """ - Finish the script by sending the end of script flag and cleaning the folder + Finish the script by sending the end of script flag and cleaning the folder - :param jobdir: directory for the spider + :param jobdir: directory for the spider """ self.has_spider_handler() self.spider_handler.done() @@ -219,24 +220,24 @@ def end(self): def run(self): """ - Method to execute the process + Method to execute the process """ raise NotImplementedError() def finish(self): """ - Method to copy the results in the Spider Results folder dax.RESULTS_DIR + Method to copy the results in the Spider Results folder dax.RESULTS_DIR """ raise NotImplementedError() def print_init(self, argument_parse, author, email): """ - Print a message to display information on the init parameters, author, - email, and arguments using time writer + Print a message to display information on the init parameters, author, + email, and arguments using time writer - :param argument_parse: argument parser - :param author: author of the spider - :param email: email of the author + :param argument_parse: argument parser + :param author: author of the spider + :param email: email of the author """ self.print_info(author, email) self.time_writer('-------- Spider starts --------') @@ -246,26 +247,26 @@ def print_init(self, argument_parse, author, email): def print_msg(self, message): """ - Print message using time writer + Print message using time writer - :param message: string displayed for the user + :param message: string displayed for the user """ self.time_writer(message) def print_err(self, err_message): """ - Print error message using time writer + Print error message using time writer - :param err_message: error message displayed for the user + :param err_message: error message displayed for the user """ self.time_writer.print_stderr_message(err_message) def print_info(self, author, email): """ - Print information on the spider using time writer + Print information on the spider using time writer - :param author: author of the spider - :param email: email of the author + :param author: author of the spider + :param email: email of the author """ self.print_msg("Running spider : %s" %(self.spider_path)) self.print_msg("Spider Author: %s" % (author)) @@ -273,9 +274,9 @@ def print_info(self, author, email): def print_args(self, argument_parse): """ - print arguments given to the Spider + print arguments given to the Spider - :param argument_parse: argument parser + :param argument_parse: argument parser """ self.time_writer("-- Arguments given to the spider --") for info, value in vars(argument_parse).items(): @@ -284,27 +285,29 @@ def print_args(self, argument_parse): def print_end(self): """ - Last print statement to give the time and date at the end of the spider + Last print statement to give the time and date at the end of the spider """ self.time_writer('\nTime at the end of the Spider: ', str(datetime.now())) @staticmethod def run_system_cmd(cmd): """ - Run system command line via os.system() - :param cmd: command to run + Run system command line via os.system() + + :param cmd: command to run """ os.system(cmd) @staticmethod def select_str(xnat_dict): """ - Return string for pyxnat to select object from python dict - :param tmp_dict: python dictionary with xnat information - keys = ["project", "subject", "experiement", "scan", "resource"] - or - keys = ["project", "subject", "experiement", "assessor", "out/resource"] - return string to select pyxnat object + Return string for pyxnat to select object from python dict + + :param tmp_dict: python dictionary with xnat information + keys = ["project", "subject", "experiement", "scan", "resource"] + or + keys = ["project", "subject", "experiement", "assessor", "out/resource"] + :return string: string path to select pyxnat object """ select_str = '' for key, value in xnat_dict.items(): @@ -328,7 +331,7 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session def define_spider_process_handler(self): """ - Define the SpiderProcessHandler for the end of session spider + Define the SpiderProcessHandler for the end of session spider """ # Create the SpiderProcessHandler if first time upload self.spider_handler = XnatUtils.SpiderProcessHandler(self.spider_path, @@ -340,19 +343,19 @@ def define_spider_process_handler(self): def pre_run(self): """ - Method to download the inputs + Method to download the inputs """ raise NotImplementedError() def run(self): """ - Method to execute the process + Method to execute the process """ raise NotImplementedError() def finish(self): """ - Method to copy the results in the Spider Results folder dax.RESULTS_DIR + Method to copy the results in the Spider Results folder dax.RESULTS_DIR """ raise NotImplementedError() @@ -369,7 +372,7 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session def define_spider_process_handler(self): """ - Define the SpiderProcessHandler for the end of session spider + Define the SpiderProcessHandler for the end of session spider """ # Create the SpiderProcessHandler if first time upload self.spider_handler = XnatUtils.SpiderProcessHandler(self.spider_path, @@ -380,32 +383,34 @@ def define_spider_process_handler(self): def run(self): """ - Method to execute the process + Method to execute the process """ raise NotImplementedError() def finish(self): """ - Method to copy the results in the Spider Results folder dax.RESULTS_DIR + Method to copy the results in the Spider Results folder dax.RESULTS_DIR """ raise NotImplementedError() #### CLASSES #### # class to display time class TimedWriter(object): - '''Class to automatically write timed output message - Args: - name - Names to write with output (default=None) - - Examples: - >>>a = Time_Writer() - >>>a("this is a test") - [00d 00h 00m 00s] this is a test - >>>sleep(60) - >>>a("this is a test") - [00d 00h 01m 00s] this is a test - - Written by Andrew Plassard (Vanderbilt) + ''' + Class to automatically write timed output message + + Args: + name - Names to write with output (default=None) + + Examples: + >>>a = Time_Writer() + >>>a("this is a test") + [00d 00h 00m 00s] this is a test + >>>sleep(60) + >>>a("this is a test") + [00d 00h 01m 00s] this is a test + + Written by Andrew Plassard (Vanderbilt) ''' def __init__(self, name=None): self.start_time = time.localtime() @@ -436,7 +441,8 @@ def __call__(self, text, pipe=sys.stdout): '''Prints a timed message Inputs: text - text to display - pipe - pipe to write to (default: sys.stdout)''' + pipe - pipe to write to (default: sys.stdout) + ''' self.print_timed_message(text, pipe=pipe) #### Functions #### @@ -492,4 +498,3 @@ def is_good_version(version): not vers[2].isdigit(): return False return True - From 3330135f03cec22df4af76a813f24b1087495473 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 10:34:57 +0100 Subject: [PATCH 12/62] adding information and fixing scan spider template --- bin/dax_tools/GenerateSpiderTemplate | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index b551510f..7feb83a6 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -46,14 +46,16 @@ SCAN_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" def parse_args(): ''' Argument parser for the spider input variables - by default: + by default (set in get_session_argparser): -p : proj_label -s : subj_label -e : sess_label - -d : temp_dir - --suffix : suffix - --manual : manual -c : scan_label + -d : temp_dir + --suffix : suffix (suffix for assessor proctype on XNAT) + --manual : manual (Manual: Ask user for XNAT loggings if not set) + your arguments: + ... :return: argument parser object created by parse_args() ''' @@ -87,9 +89,8 @@ class Spider_{name}(ScanSpider): ''' def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): - super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, xnat_host, xnat_user, xnat_pass, suffix, manual) - self.xnat_scan = xnat_scan self.inputs = list() def pre_run(self, argument_parse): @@ -159,14 +160,16 @@ SESSION_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" def parse_args(): ''' Argument parser for the spider input variables - by default: + by default (set in get_session_argparser): -p : proj_label -s : subj_label -e : sess_label -d : temp_dir - --suffix : suffix - --manual : manual - + --suffix : suffix (suffix for assessor proctype on XNAT) + --manual : manual (Manual: Ask user for XNAT loggings if not set) + your arguments: + ... + :return: argument parser object created by parse_args() ''' from argparse import ArgumentParser From 619caa2eb54b423e43f40a7c96aa72e68b33cf07 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 10:52:28 +0100 Subject: [PATCH 13/62] Update spiders.py --- dax/spiders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dax/spiders.py b/dax/spiders.py index 0095f203..ae66792a 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -459,7 +459,7 @@ def get_default_argparser(name, description): ap.add_argument('-e', dest='sess_label', help='Session Label', required=True) ap.add_argument('-d', dest='temp_dir', help='Temporary Directory', required=True) ap.add_argument('--suffix', dest='suffix', help='assessor suffix. default: None', default=None) - ap.add_argument('-m', dest='manual', help='Manual: Ask user for XNAT loggings if not set', action='store_true') + ap.add_argument('--manual', dest='manual', help='Manual: Ask user for XNAT loggings if not set', action='store_true') return ap def get_session_argparser(name, description): From d28cdbef0f61069407730b5c413899dc5f8bb914 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 10:56:01 +0100 Subject: [PATCH 14/62] Update GenerateSpiderTemplate --- bin/dax_tools/GenerateSpiderTemplate | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index 7feb83a6..92539a87 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -133,7 +133,7 @@ class Spider_{name}(ScanSpider): if __name__ == '__main__': args = parse_args() # generate spider object: - spider_obj = Spider_{name}(script_name=os.path.basename(sys.argv[0])[:-3], + spider_obj = Spider_{name}(spider_path=os.path.basename(sys.argv[0])[:-3], xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, @@ -141,8 +141,8 @@ if __name__ == '__main__': xnat_host=None, xnat_user=None, xnat_pass=None, - manual=args.manual, - suffix=args.suffix) + suffix=args.suffix, + manual=args.manual) # print some information before starting spider_obj.print_init(args, "{author}", "{email_addr}") @@ -245,15 +245,15 @@ class Spider_{name}(SessionSpider): if __name__ == '__main__': args = parse_args() # generate spider object: - spider_obj = Spider_{name}(script_name=os.path.basename(sys.argv[0])[:-3], + spider_obj = Spider_{name}(spider_path=os.path.basename(sys.argv[0])[:-3], xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, xnat_host=None, xnat_user=None, xnat_pass=None, - manual=args.manual, - suffix=args.suffix) + suffix=args.suffix, + manual=args.manual) # print some information before starting spider_obj.print_init(args, "{author}", "{email_addr}") From f9c90e5a391d32a62eb89b294ffc7f7e2ecc9375 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:01:13 +0100 Subject: [PATCH 15/62] Update GenerateSpiderTemplate --- bin/dax_tools/GenerateSpiderTemplate | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index 92539a87..ded1fb94 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -133,7 +133,7 @@ class Spider_{name}(ScanSpider): if __name__ == '__main__': args = parse_args() # generate spider object: - spider_obj = Spider_{name}(spider_path=os.path.basename(sys.argv[0])[:-3], + spider_obj = Spider_{name}(spider_path=sys.argv[0], xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, @@ -245,7 +245,7 @@ class Spider_{name}(SessionSpider): if __name__ == '__main__': args = parse_args() # generate spider object: - spider_obj = Spider_{name}(spider_path=os.path.basename(sys.argv[0])[:-3], + spider_obj = Spider_{name}(spider_path=sys.argv[0], xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, From 92296ec8c6f9af231e28df9aba6230b0e1c80b21 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:13:28 +0100 Subject: [PATCH 16/62] fixing issues on super argument for init --- bin/dax_tools/GenerateSpiderTemplate | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index ded1fb94..e80785f9 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -89,8 +89,8 @@ class Spider_{name}(ScanSpider): ''' def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): - super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, - xnat_host, xnat_user, xnat_pass, suffix, manual) + super(Spider_{name}, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, + xnat_host, xnat_user, xnat_pass, suffix, manual) self.inputs = list() def pre_run(self, argument_parse): @@ -201,8 +201,8 @@ class Spider_{name}(SessionSpider): ''' def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): - super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host, xnat_user, xnat_pass, suffix, manual) + super(Spider_{name}, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, + xnat_host, xnat_user, xnat_pass, suffix, manual) self.inputs = list() def pre_run(self, argument_parse): From ed93ff8053c243f5c49f2869c6a7ca2516a22948 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:19:38 +0100 Subject: [PATCH 17/62] fixing str issue in a message --- dax/spiders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index ae66792a..87a0c8bd 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -241,7 +241,7 @@ def print_init(self, argument_parse, author, email): """ self.print_info(author, email) self.time_writer('-------- Spider starts --------') - self.time_writer('Date and Time at the beginning of the Spider: ', str(datetime.now())) + self.time_writer('Date and Time at the beginning of the Spider: '+ str(datetime.now())) self.time_writer('INFO: Arguments') self.print_args(argument_parse) @@ -287,7 +287,7 @@ def print_end(self): """ Last print statement to give the time and date at the end of the spider """ - self.time_writer('\nTime at the end of the Spider: ', str(datetime.now())) + self.time_writer('\nTime at the end of the Spider: '+ str(datetime.now())) @staticmethod def run_system_cmd(cmd): From e9ecad3797329de48cc4f7f4be197a7c01db19bd Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:24:42 +0100 Subject: [PATCH 18/62] Update spiders.py --- dax/spiders.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 87a0c8bd..deb4a105 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -44,8 +44,7 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session # Spider path: self.spider_path = spider_path # directory for temporary files + create it - self.jobdir = os.path.abspath(jobdir) - XnatUtils.makedir(self.jobdir) + self.jobdir = XnatUtils.makedir(os.path.abspath(jobdir)) # to copy results at the end self.spider_handler = None # Xnat info: From 8f4e49850ae82fa533d5253408cfa26ad2be08b3 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:49:31 +0100 Subject: [PATCH 19/62] Adding time_writer to SpiderProcessHandler Adding the time_writer to SpiderProcessHandler to print statements. --- dax/spiders.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index deb4a105..044859d4 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -286,7 +286,7 @@ def print_end(self): """ Last print statement to give the time and date at the end of the spider """ - self.time_writer('\nTime at the end of the Spider: '+ str(datetime.now())) + self.time_writer('Time at the end of the Spider: '+ str(datetime.now())) @staticmethod def run_system_cmd(cmd): @@ -338,7 +338,8 @@ def define_spider_process_handler(self): self.xnat_project, self.xnat_subject, self.xnat_session, - self.xnat_scan) + self.xnat_scan, + time_writer=self.time_writer) def pre_run(self): """ @@ -378,7 +379,8 @@ def define_spider_process_handler(self): self.suffix, self.xnat_project, self.xnat_subject, - self.xnat_session) + self.xnat_session, + time_writer=self.time_writer) def run(self): """ From 3c4e682ef232de7bc29da7e3147a2f711e05938e Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:56:37 +0100 Subject: [PATCH 20/62] time_writer in SpiderProcessHandler Adding time_writer to process handler if set --- dax/XnatUtils.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index 969c616c..c0ab70d3 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -128,11 +128,12 @@ def select_assessor(self, intf): class SpiderProcessHandler: """ Handle the results of a spider """ - def __init__(self, script_name, suffix, project, subject, experiment, scan=None): + def __init__(self, script_name, suffix, project, subject, experiment, scan=None, time_writer=None): """ initialization """ #Variables: self.error = 0 self.has_pdf = 0 + self.time_writer = time_writer # Get the process name and the version if len(script_name.split('/')) > 1: script_name = os.path.basename(script_name) @@ -173,8 +174,23 @@ def __init__(self, script_name, suffix, project, subject, experiment, scan=None) #Remove files in directories clean_directory(self.directory) - print'INFO: Handling results ...' - print''' -Creating folder {folder} for {label}'''.format(folder=self.directory, label=assessor_label) + msg = '''INFO: Handling results ...\n -Creating folder {folder} for {label}'''.format(folder=self.directory, + label=assessor_label) + self.print_msg(msg) + + def print_msg(self, msg): + """ Print message using time_writer if set, print otherwise """ + if self.time_writer: + self.time_writer(msg) + else: + print msg + + def print_err(self, msg): + """ Print error message using time writer if set, print otherwise""" + if self.time_writer: + self.time_writer.print_stderr_message(err_message) + else: + print "Error: "+msg def set_error(self): """ set the error to one """ @@ -184,7 +200,7 @@ def file_exists(self, fpath): """ check if file exists """ if not os.path.isfile(fpath.strip()): self.error = 1 - print '''ERROR: file {file} does not exists.'''.format(file=fpath) + self.print_err('''file {file} does not exists.'''.format(file=fpath)) return False else: return True @@ -193,7 +209,7 @@ def folder_exists(self, fpath): """ check if folder exists """ if not os.path.isdir(fpath.strip()): self.error = 1 - print '''ERROR: folder {folder} does not exists.'''.format(folder=fpath) + self.print_err('''folder {folder} does not exists.'''.format(folder=fpath)) return False else: return True @@ -201,7 +217,7 @@ def folder_exists(self, fpath): @staticmethod def print_copying_statement(label, src, dest): """ print statement for copying data """ - print ''' -Copying {label}: {src} to {dest}'''.format(label=label, src=src, dest=dest) + self.print_msg(''' -Copying {label}: {src} to {dest}'''.format(label=label, src=src, dest=dest)) def add_pdf(self, filepath): """ add a file to resource pdf in the upload dir """ @@ -249,10 +265,10 @@ def add_folder(self, folderpath, resource_name=None): self.print_copying_statement(res, folderpath, dest) # Directories are the same except shutil.Error as excep: - print 'Directory not copied. Error: %s' % excep + self.print_err('Directory not copied. Error: %s' % excep) # Any error saying that the directory doesn't exist except OSError as excep: - print 'Directory not copied. Error: %s' % excep + self.print_err('Directory not copied. Error: %s' % excep) def set_assessor_status(self, status): """ Set the status of an assessor """ @@ -267,10 +283,10 @@ def set_assessor_status(self, status): if assessor.exists() and former_status == JOB_RUNNING : if self.assr_handler.get_proctype() == 'FS': assessor.attrs.set('fs:fsdata/procstatus', status) - print ' -status set for FreeSurfer to '+str(status) + self.print_msg(' -status set for FreeSurfer to '+str(status)) else: assessor.attrs.set('proc:genProcData/procstatus', status) - print ' -status set for assessor to '+str(status) + self.print_msg(' -status set for assessor to '+str(status)) except: # fail to access XNAT -- let dax_upload set the status pass @@ -285,13 +301,13 @@ def done(self): f_obj.close() #Finish the folder if not self.error and self.has_pdf: - print 'INFO: Job ready to be upload, error: '+ str(self.error) + self.print_msg('INFO: Job ready to be upload, error: '+ str(self.error)) #make the flag folder open(os.path.join(self.directory, READY_TO_UPLOAD+'.txt'), 'w').close() #set status to ReadyToUpload self.set_assessor_status(READY_TO_UPLOAD) else: - print 'INFO: Job failed, check the outlogs, error: '+ str(self.error) + self.print_msg('INFO: Job failed, check the outlogs, error: '+ str(self.error)) #make the flag folder open(os.path.join(self.directory, JOB_FAILED+'.txt'), 'w').close() #set status to JOB_FAILED From b87b451801eadc30cc8658c8a9a3b091839eebc1 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 11:59:11 +0100 Subject: [PATCH 21/62] Update XnatUtils.py --- dax/XnatUtils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index c0ab70d3..308fd1de 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -214,8 +214,7 @@ def folder_exists(self, fpath): else: return True - @staticmethod - def print_copying_statement(label, src, dest): + def print_copying_statement(self, label, src, dest): """ print statement for copying data """ self.print_msg(''' -Copying {label}: {src} to {dest}'''.format(label=label, src=src, dest=dest)) From ccbcd253cce39215f71351aac5ddd026fadfe809 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 12:01:39 +0100 Subject: [PATCH 22/62] Update XnatUtils.py --- dax/XnatUtils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index 308fd1de..18470a7e 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -174,9 +174,8 @@ def __init__(self, script_name, suffix, project, subject, experiment, scan=None, #Remove files in directories clean_directory(self.directory) - msg = '''INFO: Handling results ...\n -Creating folder {folder} for {label}'''.format(folder=self.directory, - label=assessor_label) - self.print_msg(msg) + self.print_msg("INFO: Handling results ...") + self.print_msg('''-Creating folder {folder} for {label}'''.format(folder=self.directory, label=assessor_label) def print_msg(self, msg): """ Print message using time_writer if set, print otherwise """ From 6c2f2cb81b2270fafa41cdd439353af250c3529f Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 14:19:27 +0100 Subject: [PATCH 23/62] Update XnatUtils.py --- dax/XnatUtils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index 18470a7e..8a8e3ee9 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -175,7 +175,7 @@ def __init__(self, script_name, suffix, project, subject, experiment, scan=None, clean_directory(self.directory) self.print_msg("INFO: Handling results ...") - self.print_msg('''-Creating folder {folder} for {label}'''.format(folder=self.directory, label=assessor_label) + self.print_msg('''-Creating folder {folder} for {label}'''.format(folder=self.directory, label=assessor_label)) def print_msg(self, msg): """ Print message using time_writer if set, print otherwise """ From cbe9647e20c648225def905f202bfb5f2c98c656 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 14:22:17 +0100 Subject: [PATCH 24/62] Update XnatUtils.py --- dax/XnatUtils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index 8a8e3ee9..4f1c46f1 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -224,7 +224,7 @@ def add_pdf(self, filepath): if filepath.lower().endswith('.ps'): pdf_path = os.path.splitext(filepath)[0]+'.pdf' ps2pdf_cmd = '''ps2pdf {ps} {pdf}'''.format(ps=filepath, pdf=pdf_path) - print ''' -Convertion {cmd} ...'''.format(cmd=ps2pdf_cmd) + self.print_msg(''' -Convertion {cmd} ...'''.format(cmd=ps2pdf_cmd)) os.system(ps2pdf_cmd) else: pdf_path = filepath From 23b7d84964d8e3c07739f46056c265401af95c45 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 14:25:53 +0100 Subject: [PATCH 25/62] Update XnatUtils.py --- dax/XnatUtils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dax/XnatUtils.py b/dax/XnatUtils.py index 4f1c46f1..f07c56bd 100644 --- a/dax/XnatUtils.py +++ b/dax/XnatUtils.py @@ -142,7 +142,7 @@ def __init__(self, script_name, suffix, project, subject, experiment, scan=None, if 'Spider' in script_name: script_name = script_name[7:] - #ge the processname from spider + # get the processname from spider if len(re.split("/*_v[0-9]/*", script_name)) > 1: self.version = script_name.split('_v')[-1].replace('_','.') proctype = re.split("/*_v[0-9]/*", script_name)[0]+'_v'+self.version.split('.')[0] @@ -156,6 +156,8 @@ def __init__(self, script_name, suffix, project, subject, experiment, scan=None, suffix = '_'+suffix # suffix: remove any special characters and replace by '_' suffix = re.sub('[^a-zA-Z0-9]', '_', suffix) + if suffix[-1] == '_': + suffix = suffix[:-1] proctype = proctype + suffix #Create the assessor handler From cd506bb706bf35685d2a118bea54656825832f31 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 14:36:33 +0100 Subject: [PATCH 26/62] Adding sys.stdout has stream handler for logger --- bin/Xnat_tools/Xnatcheck | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Xnat_tools/Xnatcheck b/bin/Xnat_tools/Xnatcheck index 16fd66e7..f7c16ff5 100755 --- a/bin/Xnat_tools/Xnatcheck +++ b/bin/Xnat_tools/Xnatcheck @@ -265,7 +265,7 @@ def setup_info_logger(name,logfile): if logfile: handler=logging.FileHandler(logfile,'w') else: - handler=logging.StreamHandler() + handler=logging.StreamHandler(sys.stdout) logger = logging.getLogger(name) logger.setLevel(logging.INFO) From 72999d3b9353dc3aadf51a7499f2d2abf4910c56 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 16 Sep 2015 14:40:59 +0100 Subject: [PATCH 27/62] logger stream to sys.stdout --- dax/log.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dax/log.py b/dax/log.py index 968b4428..a8c4ad06 100644 --- a/dax/log.py +++ b/dax/log.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import sys import logging def setup_debug_logger(name, logfile): @@ -10,7 +11,7 @@ def setup_debug_logger(name, logfile): if logfile: handler = logging.FileHandler(logfile, 'w') else: - handler = logging.StreamHandler() + handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) logger = logging.getLogger(name) @@ -24,7 +25,7 @@ def setup_info_logger(name, logfile): if logfile: handler = logging.FileHandler(logfile, 'w') else: - handler = logging.StreamHandler() + handler = logging.StreamHandler(sys.stdout) logger = logging.getLogger(name) logger.setLevel(logging.INFO) @@ -37,7 +38,7 @@ def setup_critical_logger(name, logfile): if logfile: handler = logging.FileHandler(logfile, 'w') else: - handler = logging.StreamHandler() + handler = logging.StreamHandler(sys.stdout) logger = logging.getLogger(name) logger.setLevel(logging.CRITICAL) @@ -49,7 +50,7 @@ def setup_warning_logger(name, logfile): if logfile: handler = logging.FileHandler(logfile, 'w') else: - handler = logging.StreamHandler() + handler = logging.StreamHandler(sys.stdout) logger = logging.getLogger(name) logger.setLevel(logging.WARNING) @@ -61,11 +62,9 @@ def setup_error_logger(name, logfile): if logfile: handler = logging.FileHandler(logfile, 'w') else: - handler = logging.StreamHandler() + handler = logging.StreamHandler(sys.stdout) logger = logging.getLogger(name) logger.setLevel(logging.ERROR) logger.addHandler(handler) return logger - - From 81b457adb4fbf49ddb7e296464ca6993b85a47de Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 23 Sep 2015 16:28:58 +0100 Subject: [PATCH 28/62] if manual ask for the info If manual options use, ask user for the value --- dax/spiders.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 044859d4..3263eaa8 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -78,21 +78,21 @@ def get_default_value(self, variable, env_name, value): if value: return value else: - if env_name in os.environ: - return os.environ[env_name] + if self.manual: + msg = """Enter <{var}>:""".format(var=variable) + if env_name == 'XNAT_PASS': + return getpass.getpass(prompt=msg) + else: + return raw_input(msg) else: - if not self.manual: + if env_name in os.environ: + return os.environ[env_name] + else: err = "%s not set by user." % (env_name) err += "\nTo set it choose one of this solution:" err += "\n\tSet arguments '%s' in the spider class" % (variable) err += "\n\tSet the environment variable %s" % (env_name) raise ValueError(err) - else: - msg = """Enter <{var}>:""".format(var=variable) - if env_name == 'XNAT_PASS': - return getpass.getpass(prompt=msg) - else: - return raw_input(msg) def select_obj(self, intf, obj_label, resource): """ From d1a89b3d7ccd52af6a6b48cbd6eb8328098a7022 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 23 Sep 2015 16:33:13 +0100 Subject: [PATCH 29/62] Update spiders.py --- dax/spiders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 3263eaa8..a7d79489 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -53,8 +53,8 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session self.xnat_session = xnat_session # Xnat connection settings: self.host = self.get_default_value("xnat_host", "XNAT_HOST", xnat_host) - self.user = self.get_default_value("xnat_host", "XNAT_USER", xnat_user) - self.pwd = self.get_default_value("xnat_host", "XNAT_PASS", xnat_pass) + self.user = self.get_default_value("xnat_user", "XNAT_USER", xnat_user) + self.pwd = self.get_default_value("xnat_pass", "XNAT_PASS", xnat_pass) # Suffix if suffix[0] != '_': self.suffix = '_'+suffix else: self.suffix = suffix From e75adea7105c44d7b4f16b1a9bd2086933808be1 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 23 Sep 2015 17:51:44 +0100 Subject: [PATCH 30/62] Host/user/pwd editing the pwd and user and host --- dax/spiders.py | 57 +++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index a7d79489..af70e12a 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -36,11 +36,9 @@ class Spider(object): :param xnat_user: user for XNAT if not set in environment variables :param xnat_pass: password for XNAT if not set in environment variables :param suffix: suffix to the assessor creation - :param manual: if using the spider manually (not on the cluster) (boolean) - ask user if the HOST/USER/PASS are not set for XNAT """ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): # Spider path: self.spider_path = spider_path # directory for temporary files + create it @@ -54,13 +52,12 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session # Xnat connection settings: self.host = self.get_default_value("xnat_host", "XNAT_HOST", xnat_host) self.user = self.get_default_value("xnat_user", "XNAT_USER", xnat_user) - self.pwd = self.get_default_value("xnat_pass", "XNAT_PASS", xnat_pass) + self.pwd = self.get_pwd(xnat_pwd, xnat_user) # Suffix if suffix[0] != '_': self.suffix = '_'+suffix else: self.suffix = suffix # Set the suffix_proc remove any special characters and replace by '_' self.suffix = re.sub('[^a-zA-Z0-9]', '_', self.suffix) - self.manual = manual # print time writer: self.time_writer = TimedWriter() @@ -78,20 +75,37 @@ def get_default_value(self, variable, env_name, value): if value: return value else: - if self.manual: - msg = """Enter <{var}>:""".format(var=variable) - if env_name == 'XNAT_PASS': - return getpass.getpass(prompt=msg) - else: - return raw_input(msg) + if env_name in os.environ: + return os.environ[env_name] else: - if env_name in os.environ: - return os.environ[env_name] + err = "%s not set by user." % (env_name) + err += "\nTo set it choose one of this solution:" + err += "\n\tSet arguments '%s' in the spider class" % (variable) + err += "\n\tSet the environment variable %s" % (env_name) + raise ValueError(err) + + def get_pwd(self, pwd, user): + """ + Return the password from env or ask user if the user was set + + :param pwd: password + :param user: user + :return: default value + """ + if pwd: + return pwd + else: + if env_name in os.environ: + return os.environ[env_name] + else: + if user: + msg = "Enter password for XNAT:" + return getpass.getpass(prompt=msg) else: - err = "%s not set by user." % (env_name) + err = "XNAT_HOST not set by user." err += "\nTo set it choose one of this solution:" - err += "\n\tSet arguments '%s' in the spider class" % (variable) - err += "\n\tSet the environment variable %s" % (env_name) + err += "\n\tSet arguments 'xnat_pass' in the spider class" + err += "\n\tSet the environment variable XNAT_HOST" raise ValueError(err) def select_obj(self, intf, obj_label, resource): @@ -323,9 +337,9 @@ class for scan-spider :param xnat_scan: scan ID on XNAT (if running on a specific scan) """ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, - xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", xnat_host=None, xnat_user=None): super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host, xnat_user, xnat_pass, suffix, manual) + xnat_host, xnat_user, xnat_pass, suffix) self.xnat_scan = xnat_scan def define_spider_process_handler(self): @@ -366,9 +380,9 @@ class for session-spider :param super --> see base class """ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", manual=False): + xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", xnat_host=None, xnat_user=None): super(SessionSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host, xnat_user, xnat_pass, suffix, manual) + xnat_host, xnat_user, xnat_pass, suffix) def define_spider_process_handler(self): """ @@ -460,7 +474,8 @@ def get_default_argparser(name, description): ap.add_argument('-e', dest='sess_label', help='Session Label', required=True) ap.add_argument('-d', dest='temp_dir', help='Temporary Directory', required=True) ap.add_argument('--suffix', dest='suffix', help='assessor suffix. default: None', default=None) - ap.add_argument('--manual', dest='manual', help='Manual: Ask user for XNAT loggings if not set', action='store_true') + ap.add_argument('--host', dest='host', help='Set XNAT Host. Default: using env variable XNAT_HOST', default=None) + ap.add_argument('--user', dest='user', help='Set XNAT User. Default: using env variable XNAT_USER', default=None) return ap def get_session_argparser(name, description): From d1692d516d1c28ab556b5c263854cdeddd76dec2 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 10:40:02 +0100 Subject: [PATCH 31/62] Adding the modules used by DAX --- dax/xnat_modules/default_proc/proc_module.jar | Bin 0 -> 16422 bytes .../default_proc/proc_module/rebuild_proc.sh | 1 + .../proc/display/proc_genProcData_display.xml | 212 + .../proc_module/src/schemas/proc/proc.xsd | 42 + .../src/scripts/FileViewerProcessing.js | 166 + .../src/scripts/FileViewerProcessingPdf.js | 154 + .../XDATScreen_edit_proc_genProcData.vm | 100 + .../XDATScreen_report_proc_genProcData.vm | 406 ++ .../screens/proc_genProcData_search.vm | 42 + .../xnat_imageSessionData_assessments.vm | 157 + .../xnat_imageSessionData_report.vm | 228 + dax/xnat_modules/freesurfer/fs_module.jar | Bin 0 -> 47969 bytes .../freesurfer/fs_module/rebuild_fs.sh | 1 + .../modules/screens/Fs_fsData_QC_64.java | 26 + .../screens/XDATScreen_edit_fs_fsData.java | 33 + .../schemas/fs/display/fs_fsData_display.xml | 5137 +++++++++++++++++ .../fs/display/fs_longFSData_display.xml | 224 + .../fs_module/src/schemas/fs/fs.xsd | 332 ++ .../fs_module/src/scripts/slideshow.js | 403 ++ .../src/templates/layouts/Fs_fsData_QC_64.vm | 94 + .../src/templates/screens/Fs_fsData_QC_64.vm | 185 + .../screens/XDATScreen_edit_fs_fsData.vm | 95 + .../screens/XDATScreen_report_fs_fsData.vm | 234 + 23 files changed, 8272 insertions(+) create mode 100644 dax/xnat_modules/default_proc/proc_module.jar create mode 100755 dax/xnat_modules/default_proc/proc_module/rebuild_proc.sh create mode 100644 dax/xnat_modules/default_proc/proc_module/src/schemas/proc/display/proc_genProcData_display.xml create mode 100644 dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd create mode 100644 dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js create mode 100644 dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessingPdf.js create mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm create mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm create mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm create mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm create mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm create mode 100644 dax/xnat_modules/freesurfer/fs_module.jar create mode 100755 dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm create mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm diff --git a/dax/xnat_modules/default_proc/proc_module.jar b/dax/xnat_modules/default_proc/proc_module.jar new file mode 100644 index 0000000000000000000000000000000000000000..7fa80805dc7f9b0e6aac107d776882a6fd9014da GIT binary patch literal 16422 zcmb_@1yG*JvNjOh-Q8V+ySsaE2=49@+=9Ei6I_D3ySqCC53WD#Irn6D@9x&QReyg) zF<&v=Gu`jYOi$1A$Vq+xMg{-}2M3^1WD^DWoj?Ep14s)i@zaRQh|s+Z0RVgekdp)h zfA0bG?{0E`tBm~C<3GyM{4(Mq!iq|?(jq^lM~0;&X=o>5BxxweM#gIt=w}!=cI{{- zq^ZTFCmlbm2>|dmF?oeQdI0?PS9?2sx?j`$a}St*_n;M0)KPS>wlh3Q;)Ly@hZiyy48_Mx zjB5j8t(0Q}MBC8u;e)&?Wus_y~*FmmZE3%DyzcStg6RWqlyj zSn?Vwg9Nue)RXRd)kZdm9Tq*ME3M z%>ShJKBSJZp_Sa*Zy`MgJ)M8sqjj;gI8k4=TM~o!bZYx70oPgnk^G|Vn4=E@6oHD0 z7I0BKL+JyiK8XNfN@t(){oP3;xHu@mqHS;u$S#mM?P{UB%x%~Vhih}v!$F|X43uBf zP1B8pATfGSIhxebQow5YOIa(or|s0`!AQR|a_6}>E?tr8d^tuc&X0$a6U&pE3Uzep zt6bFz?H`$(b2c8*1r0|aahtkQOu*ZbewAMf{m0Ie2E3@S^+{*u%s8HCG)Ej%DNAUI zN(m@;;WMSgJC2s9A^ZE05U)1B2Vl%i%&y#)(q?ZDq>8JxM9M+lF*Aj7*~Kq=K76LD zFFiq67tYX_4;%MfX3)TFB3&Sn*V=wvcbUPu&nvGoft{1{&AnijQRh=oi6cPB1)wfB z&pC9gVrQPnhf>>j>Mv2(J`dM9N$>E+2w6yvaps|40)Tw9ZvgM|9#Es&c3UklWO>zs z4F^vZ1q?N^Xup*4Ex}ef&HXeD+(8Lu?Vp_03r$Ymxbrb!`18;5JL@g}0P#qEi0-Re zLo&A|WAjA)iSMkm0j#~TBa}?t-nQd4%^0=QXKhaElk1)z$1tDUXhjscOQc&$hb|b1 zpqz3_F*w@`pV!P5M7CTy1nSX1Xy*&iw!cAD?3!DtW{ z@lX9YHge8~nGYSvUh3=U7T(z1OE+m8BS#s7TTl_#^vxHE+m_FEO}-I2>%e8?wl>L% zlxRB8B0Bpp7^6wuw?W?Zlg_ozG1{U*exm)s{`3T16oo4OQh_Cgq_@IH+em$*+@v31 zB=M=M*$kC9(Yn{tiV>%>joxR4gQt?^Ym(W$>@OGMb@X+4emQ9{=8BBe-zMuu>mkM@ zj+~sbs3F4cYKK(_+O0hPXX!7;)%hU+ruoK2Be(XvsWn+kXyIhv0Hk z0-_9ib=XjGaryL6xR2eQTKY(SO+o0S4$BDVx4$dD-|T_HZ4K$HH>^vO$<6#k zahrH@tU|bHaGSpp2Gm&}2~PjW=ke145E-?YKX@>lD_I7iQ2@`46kOhSbdF#pGS-_n zghL6|`Oa)7h&~$e&W|XFPAF|)637UUM?pj4o1mhlA-=4_N4WFT+Np=5Vx(gsJ%9%D zE&$4tPcYiFbuwm>lL~1=bnR>vMJRX4JDrVewOBX3^qctek{CwzO?CYMZW8++at2?f zSgRY@Tfcu*H_;5j=rra&mei;BKcV`n$(=y+0k?QuF&Vye4&^{0(BmLIKQqk>MpQdw zb+4FbZpP#T{r3ts&mXjOPt> zXEdY-Mj!d(>Mu~2WOw-rua|63!0C1Io||?ducvC(G*m%kI=MSyfZ4o6QhB&pRZxfT z+>%Ag&pQ>4Ri}c5=;vnCd_MHK;4d@z#s#%YHG1ri6$Ej!8#$0>a2Z4b7TCprB|^MB z*vBv!d(?seVni3~K`Mb#CmFMfF`c?Ec1M=)K%j#sc3j@Y-?EK+Tc@RxX=CR52Vk?3}i4%QJj08MzYb48O65F)e-8 zonMMEu;<(Z$3{F2@aZrgMx9x-aQORTt74sZN^}7jJ&PxAZHP zgk~0yn#i(BemV0llNw6ml<@4=T;E;g2Z@ih%EgyAn(bX(Y~GBzyIpTS9an#6)Zq3p=wX=le(WM%NKmFP zlpU+9sa7hW;IK|7&$=-*cMu*QCk3xKrcR5XJT~8hMGjO_F!^q%HIK5|ERb5@!I`cd zx6ZpxLo}PGjuWW-ff_t2Yo(0E4$yoLgoVqU^e#nE8p3|;Jl?rdbz`<1SUCkaxxu2& zR;ZOwt|bvVW$iGukJ9_Rt=8`ko4lU#hls>$wo4mz&Y=>_%^zsksG`;EW~0~k$>uf(;Bo6tC@8Qe|a zeR6^AWl7bk34@Xe%Py!V`1m9-*SE^M;V`*srWHrF^rl3L63s=J*1K`?f#0Hnckp$7as5?`5?u5Vl&>?X`T#{!$vO!;NCH7-|UwZX@ zDpqab*$u}*>avAcutAIf#=zg91l+tEWzl^B1j+Q%XM~kbD&fJtmDkR<8#0dyn!1km zTgP;)i3!||ci~vn#wdkLh~Pw%{qkFOp3y%lMfi3`cn1CN@=QBZ8;5`8nScFC68$Fw z{8vvAQwu{CQ$uG%yZ5xu(B9tE%9z&7e)f}w^)d^xSHc&N(jXyUkjCD%BXGf^d~3WXjE3p!_gopOC^MYm^GK@ePxabjk-hIxXyaW(w!#;Ai%-x;&uoZ-t z}@mAw??YEnO5{Z_n-iRy**sRXf3=-{nWrtU|@II(crgR6@OhPyKP1t)rOsk6k0% zwXk6l8Q^Fn6*-D9)-~1(VOe09fE`5=@ ztNI+GV{eTpFtg@#LZ_KsOFQASC&5>d(+KM|&465j6T)(bq4e1eHFA}o{WrL;pH7~- zXO%Svs3Xb36vT|edby=5U{-vmGwG~kaw+RT#wXy@Bk;9VY|dXqgXyAM@X2(|{R}Ua z>D{V<7sdmW#OIkh8$6sd7rItN&p(c%%12m>dlA;aBz2`)+CesbP|nZvW&rPY5#E83 z^P?}x|EO>`!E-2e2JRop0phL?$%1K!yeI_cu%f(*wO9tw(FK;C#$@d4@fj-ZOJCfM z&-ftXmiD-^LtA~geV5^ejty)`eL*xK)H*-(P+mAc`M!WRT9|5q4JJWaaRM-lUvj*S zMN~77*tP=;%Q3ut_@i=JuZ)bGpMp~ym@;G-2A9ua4z4lt92=Pf$-J8<8xtW7r=oCb zC$<>kcGKqzwrEHX9G+DuOsjKQcgt+mNX15D{c5)%6dEN`hEa&Uave;RQbckEseoC~ z4=UnCA~S?Wv%7qHkak(P#*aqnlEI&S{n0_@QVON7RZTP7iWQjbQK+>Lh7cIor!mu| z^(1uJ!mEmtlJo*orbo^fpxt3^%?9hP$Yh3OP}J>93t`jeY(dV`D^~3i^bQ#I_X?}L z2Uwxif$%_q6}z2=i||=@WJ3bI4uUS25rk>m;Z4{3L_+S@Rjmt~l-I$Cvdi@6%THcl z(kdy8H1W*K9Fy#_uZ8QP71f;bvS-8#08+}GhUV-%(Y{w}$L4D_A)*zHVp>C0S@kLm z9TcnIp4m>s@!)kXq4iJeEe4;+Uvyuj?3YJimC1iw)T*ocUToETpIsDUnkHY$lg=k9FIQDMTWQVeZbbGO-{IftsN}=9xshACF zp8uDI`zwYE-jt<2+vCKC6@N=<^_B1OCrwdB9aqpo4vTxmle1iq&Wl6S>f;3$I-;q{ zH?INl#d&RmjVQ`94+2=OUc!{!(&LUD=WOOpMWU%+aR&AljCwUng2YvwO8kwgc)p$` z{*;&ddE`>}K$@lJ#<#?3ya#?y+o^>M$exue>Dk zd}}#a4k@W+U4VH3eNPP%GhppmK>z^C-|9AhUo9d1FV1EaU4c=VH`^)eeg&v3i% zEJ1=^McQXstW*jG)J@xlgCP~FSX%MA(SnyVPGaGZn0VF6ZcH&^`?a4i zL4t)Kl1hCT9D{Zb&LZvdwxlis`6COL7SSTAPY=^ZHp@_b+y3NDJA}C(1BFwHw6j!_ z!|Y{HJHl_tc73ySASq|r4WTG)B<#d-#Lc@!$i5kvD$(@SIfX&NOEHR|E!j*Ab|0`_ zt+^n;kUG=%E_Qvyh2Xb>Uav=6F?Gf*XH51_%<#P025ZWUM{)HkOhj4MZ*d%PE1tF_ zimQ^^tQDg9n4rZ53)W(tkh;N@sU+zuQDW4hE1_=fTOovB$wB1mB^@)q5DZo==0Jdr zo*iBmiXl(DFUkH9n_}=%KyJ8-&?0&oshR00dyb4?FcdfGGkW#~x)!o8K}JC!0B%kk zl!KcE4Vj02-BAU+M^@%5cB|Jb53N!{KjRoWF(c_^Ajy9HO3q7WKiac=`jUWwN$`Vy za3UH|%NM{4Jrc+!u=+WnP1%^5R%FUo3CeT_!C1|rMAio2JtJT`)y2@kQf8#ye(F$jdoYY81jKa41Fuy!g+zlqziR~^IG^goX*8@am|@fSNO1BeOFK_~ME zO-2^?WA4Y%%np5n3sT85G%hzyoPeUQFE>x%lgo#)2^!Bbkbr%`sJL#%%eyIqE>cn` zLl2?!6PF3G!72b$P3KOACzZ6E(5v%b3lZrlZvsBZ@dZBUzbZG{ug*@!$5P=prJ*lq zB50Ca*Q9E4I9DzgI|)vc4i_<2Tzb-wF}I*Ku20Q2;;i8^bn^>z*S3>#>Qw-xOMFP}-0gr+TPtH2``O52eQN z3xoC$sB{90gR)i@i+KyhP6>)6iN1Qt*?PCI;{6l&Tsd2Yc0%|9E^<4s_T$Qfqdrqt zC#>KyShOk&cMhkS*VzKen$$!Rt<#aDo8v1~s$%gDj@tAXscw_UvHy$%x|MRlEF5S7TloxqnoMYcPJBf282FDnohSJqR`UgFB1%yjw>La zT#hqu8(NU6`!gJ6wsIUke)idq&IlpH9sKdai8)HVnDPVnbGc|MC0>f}Sz_v0Vr)uc z_cXJb0(J47L@)ck8F~a`D{((xSfU!{9N|eg6Nw4P_Qw}=pq@I&4wcleylI(cNxXqU z(-y5l3dAY)2Vt;2zI{Q{4D8TkK8fFGK6dkzT$DTce3`9g&Fg4)nAIP0W#@y&l*nRn zzy-(}z+=U>H$UccJ3T<>lB<|2H19p29zL}B;;l{^F5LpvF|G%Yxuipw;B@PVPc#dY zbW)gByl!wq$9<>&vo#VqST5jEb)H=>^D(%FcpN_$uRBe!k?(X%ly51M3w5T@?HTGv z@k89T!=sS(nk}$KOZ01loLoNx28GwRld>al1)jgvv27u7{ZAf(sS46e=ch-KE> z%C^QxXRL~Ogf_+rzVduTVtEDj7EYjul;s@+(wCjntahCgEUc`BvC< zF#M;)9_@ei{aqoR0kVq^Uih`g8!(lI<`!~I7lGRc4IZgXs8cs{$ljF+>88|&I4eHq zwevi5>!K}J|qokRhFa$klQ)zG+uns7e9vKs+rG1mXwMQfm;>Juw-8m+dnc!%) z&-GRo*|L*zxpCGW3SmBUJ?C%w!?1)RXJ3tk6fUGb1=2e%~u(XU2C)1Ac$?j zbyH-xzS}Ar_J+^g_-(i4wE#g}cys-q>+q=mD>(N0c7}#l{}fRAzt#C)g>rjCJv)69 zS|`i8SblRqdgT7`Yeli9ZnuR#+5jt+N>Z$dsgMGF&UmHu5+atE7XIg(uQQVT&ee&x zmv=$0bY~>CT)5xnMxMdvCVv=-%gy#MFNl4LX`Ny};MBr}^lsfq zI^4eH6SBPUVzqw%;XM~pPernT1_S`u|L{+_5c}Uo`jZg9lHzYqO2^Q^)IsOZk$($$ zKHA&O1jji>n}Ga5&j>LKv8<)#H~=Y(rN9)QyG&v1Ah-r_UH!58N0`FtFT7NP-h%;5 z(zuni%}b9or!qEcSYH|s-cE&|9WIL9ISvRsHrQUVud&I{!43>OoI)dx1^W--s&uRk zb^@1thZtfR>dxEwjl)vS&ndRo-A&W>RC0A$LN?Vqy&_mA?ET8mfQHP7DH0idxUNvz z$y)I5fzF6Lq{!|sJwz^T3SiTzjjMc2dLDfhe}-STDy|?4luQR3#gHPUln%R+PhYZ0 z?NizC3EH=rC6ovmWTWs~F7ue>qImF&Tfv9psO=#29g+=x)?1gm2eDC^u3xUu`ChIf z@(j)!+mQ7zsk%afur}YW`l!3dpvRybb(!Up$VA81F{0{68w{UP&SkRE%%qI}Jn8)t z&L$v}DxWr$&@hnLNgx2=mi5OeGIp52t|#1n2Pni1-t{@c4J)~pD8j?F)=+L!>iv;k zMi&2uo}-C=kGOzpqW_Q@rYoCd=XS7vO#VtY42n9+Wd!J_JL>QS2L>@dKCm!&!qE@# zp{Y?ywA*R~(V7MwPJKDSm-$iDvh9=b=;QHNK4)VUh*wxdI*X>vd#*Lw&Bp1x8|Q(- zKdc@#ixV2Q`!i7)Ujea1mIABl8s86&kpRBmHd!o(ozfU z5c%yt(Amy0oSO0?2>yZ45;!uG7 za7fEs;Pi6X9<`5d@we)I2&Vj?#&4q)Zn~v1ckqw52Dkjj0ph*#B7!W2n+&;)T#;C9JGRl(&^LSbR+%`26<{V&9a zLiJAX3PyQ$&*zaseCxIx=g9ZLtzYQ8K`{Xltg-Qqo&X?A;JxLD_S zM9?1p`RRJxh3;H5Wc)JRwa>oTUf8<#`N`)|i%+4wcjYaKcLqrklq_|a(;AC|6pQ7^s&K51 z0w<^(X52>*qfbKP`DD^_G^U=a2j(ia{6CYwC8s12kpt*Daf82P$P4#hisk+o{2Y%I zkkwe`HM8LfXy4mVvRkwL<4L$P$>|aLh*zv_DK>>V)%**3OGDj@4@mq7bwzyigKu$p zu0}+S)F(rpgDSJY^f6FFQ%BiUWQBst!gM(IbJ=b%IJ%l6^c#WF5c$T=Np|R6c?NNB ztvFaVg9W#AMw{bfa>NwVgipgZPDxua&=8oQ02F(z^TXmxIOXeqdFb)wiCf!%^1Q% z2HrxZpNMzM7b1%}oY4FRmfTBJZc^%WvN@Z(8_ED>oQaZEfdC_u=d= z#ssY6v*MZ5d{8by1G<)ukM@3edFHx_pXz8ldk_v@PIQ39!ju)aGmz)H-JULZwCQ5o z+}etRA-m4F=JK`rXx%J>rAJcJ!{nHz7bG3tC&mf0oI2Ke>^twu-ZA%JE9v#1X^m;d zM0oy+{IZoi(7Es|?K87`%Q1~@UD zUFde8yG^%3WkPV=C9m?!m(gs&C+w}sDa+4%=C{`elM@LU=Zk#Nq8$gWAV_Qw=ypJx z#t;fX0Bo-xi}14dHOg}#pOAUV1H;QExc2zAl=08@cjbDUhxI_oSwFMV#=8|O_m8qi z)ePfCNP=~;U$NDj>LaMl`;lZ~XRHBovkz!4^_+Y@|IP`TI5u*fKnlsOH6b30bru~m z_rfw9kaqroO2C{{w~(n?XQhgH7e-(wGUyYd5^xt8DCEz0Ux#fOWd`gg^6@9K>H6q8 z{|!KEN=o!~!Vl(8TyO`NwDAlHHiPt;L(c)GP+Q+d)t|#%FkkKal6nan^&d^8ozhGJ z$|Ofl-CG7DGnKoNyT0;t6*GA4g=ZX5%ksxdUzrD^mQP)Y`A~l#GBjOWM-0d_(J_e~ z92*aJp&$?cB(Z|=WKt1Xi;2P(bg>CS05`^D1*TxNV-XU*GVq+?T0!Zn~Tgw2w< zos;yVR2m?+z3*w(S$Qi2Q&Zn)cb)C+=Jc~TBW_|%fT1kig^w%-((t4)Dr)KpY;<%P z3mfq21kSg%VR=w8QA>F>4MMQ(@sOo3Pd2R#~Vs7Vt)TW*4BY93j+7hs^Ud2LwI|kTCCPv}~>zTMj-wB!GgtNg@no~@Q z;QKWw#Gl-qs|93D(>(-wFb>w4X4+{hk;MDGttIN?lJv!*6O!;H{FB4gu0An55qvDP zhB?oln5!U#B!ub`gKzXROwcBe`w>%~U2c<=#0at5ktem2b$ETuDyUf;2X2lA+VNMl z_e-dcZk7z2W6~t63@(t+4yO+}FD-p8Qjc+~LzksJaIhd!WbZgygKP77=qwWMTMhig z)_Ft2ByONX$0Mn~d4k(ecs)*RFu=q=k?p48W>Tr9mfU}efMe}fiPfAjE>#bNK!SFD zb~#0IkTM3+Z=gqs{@F)qaor?pWB5dy9*#KdHYCG90CFGv;d^&XXZgI-7J>cd9u$gz zWPPPJRBW^w`VwT+O-YUTMjXM=zRehULcZ;hf$NSp>h1@!QDvs%E=@^)j_0q05Fuk< zk}(kR_Sojhca>bNufZdzbnR!h%D<;j*rl8-C`ntlk*?xM;7~3{NqYwz#01jeB@f4I zj*0~60+9$=Tqf zc0X(4CdJlUklsgdrk=nXut_Hchxuj5Dtd>ZCBt|9 zNhBVzCG_hiw1b&mi@)h0ZF0y!F8BkF#4aTDtvo#(Take+$mECa)YS~o1q@<9aT3iGZKv#(Vg*@4L{r=F=@^r z7ILJ}{jl8uVg7t-j?(U3Fmh72t5N|=;#ji5>rCG?#r@i8?{z0xAfwz-`du!**>tV4x>DI8A5^4Pl8E``8|7y{!{ z$RWDcVTRph65f-6VUa@KQ8f}$%B3)4roI{=cSx5$#eufO{>LY?5h0X#gm_W?)LD`q z8iB82{-`m9FJSK}PV}b14=`YE!66bvGrm2J>QZa;s?irKSydA#x+1 zY|t6nE07nk#SQD0B%VggRICf*C+06L`|X+Q$cLRKl>$((3tBVoJA51CbQP1 zU=Sb>EEee&%p2*6^g4H)O{6)VPKg3yT>z+@#wWtsPMIONDHin$exbs%V5Sv55KTOB ziRL3=D1v22H3OC60b;fFG}xBykoKUm+M@GMrCbkh2x%v^nuC0-Zn)_Gjt^!A>q`bI zvq-x4IF1UxCYYV&U@M+cu2pRUz%nhWY-?!)-t#z_1QPmPtWYi(agcK3SS$b&4K(jfG5*#&;A}bw5|;nU)o4YM(EB3*%W7#L)I&-!ldF{ zc|Pztid}0|1aSPOX9M|@2ljc@=@Y!pi4l^5RKYMK#`;uT#MTZc2`(HE3L~5mPLtpu zc}$kZ#}?$a434Y)^fP)}{a1Irl8S-j_Ok>Xu zmJU47S5!4)b1;vE?XM7Q2W~kzAr>&z1_4UYPbiOi*OY+UO7ErO&0^ET$(15RXaTqj(ECUIgf(3g{Alp(cChuWuB&@uErbc-yAY(UPfkSz%~5xXJbf`sFR3%% zK$G-omXoAH|D1(5OO+G1wZQ`B?)XaB zmF8D%$xBvxYMgp*M}gY|ODbvN)^1}TB8*pVayf!#PtkL&_%eT}$=2(3rWG2TW(gpP zUU2mZKYc471dp6lBEqgGr@)FJp>yONAWKS5~(+1YxmVN47Od9H|fGkJG`k8yU!ZVoq`Pq-_OZfpiLQc6< zMo4T;*hjeB6)_c!&{oFLaC;@52(kc-jm0R-Bk0)LK^w_1#f7Q}B%aQy z&XJd}O4);G*Mw*y(M(ko4_`HL6IXyjaf!7u;~#;2^s{`dvW1|+!?k429(0QVo(;RY zD^F1Zjh~vF+7k!2C+^A%OkzN-xu-LYLMqdLM3coX%B70CWac`S6oOoi9br*?|Iwm8 zPIZJjV{YEBp3f_^DJ7%4E4v-K=rc@l9{CBJ9io$Z6h}~gF>;6T!#$8F$VQ@)?@&X| zO4;3GAN{Sg?(xsfBVO-(2jJT%e)We<-EZxg$uxt8s&_KB-E6GVHJlCXK}LQzOD9fF z`Igi;lpXAbhG~{oHq66#I-aMyXaKd&e#ggM2?)f=ajTvzdSnD6kBE6(dn>9thPanfb=)|m$SYYMNaDn>a!YC&RnBQ%g<;(DkiU9> zppBs9*Di^vCg2H4n1@?snveoA!gAw*P@6i| z3fmv@CvtI}Ws@Cz@h`lK)@!)PGed-nP?O^;i3?29#Hf7sy_5ICmD^ zm>;!@9S$)TcHbGBQ)wzs964}A7JN8ARf=9AP7Lh`!jR^pegwP=6UH;)-J! zV3etQVg<#oO(tMt#~%_057%bb- zXDsfS9T+yib=5g0%0*VdFcTDtoN%-Rwk5vuE13b!aXHxY!&?Cljz7weRSCEV z;Rb0tQZbV|ybibp5q~Du1qkq3i2Hs69qr@>51L7Dg=mFg3ErbF0~p90-k1B3;CNbX z}1YT!Er0F}H!VTuA{ z-3X)vc7O{C0c@J&uCZnKppQz%$P7I(ZMwp31mZdpLs>GdrFk>&VV%)#DJSZrN5uU{ zRdt^iaAMn!4z`ua*~E}$yXXUI0$&@HtK~vS+H~NK+g>Odli8c7to#FOnayspUC$~P zWyB}NFqxZ+7K?TQMsWEEsfR0vN@l9i;zc9qbbpor>=dOPk!wsMuM3pXH{nD~1Pnbf z*DVl=dDEA&M#U0uMgh|;p)n+(O$|a2yAZhUl%zHIP379MPN=X>syN-))zl=ONdBOY zQCz@c9HJ^y?C9l1jO||7BDFs+MZ~K78FOjo9)lf&z( zM_7jU5Z3WyNs)aUnSCLxztBz-p9b0Wf`N(}ew$_{#HEkx!mIy>t<+w^smdl4A^;tg zyDp)X2ccDMIz15;D!Cs$J{+-9n~SBj<>hEp=7*5=yYhf^uT!SL)cE0){^LQpeOL@X zQa$PYN>E{dy1w9gx}2eBdO-j5$t$ViF8ZNbVxH^HrO3^ZSq#IUiw`6nUK?mpi{++2 z^Jy9Va9(=h^n)$lrm$B_&?e(l%4D$~^D)nmPNGChY0rGgc3ZQ8+c)j;{o)L}M`Xyp z;8^{DD=WXQfL0ArX|<{Lz*=oPkUT%>!0~XvNs72haU|3gXE)~a{r3NkAa(6>BEyVjcomHRbO8eUv*Ak`M*Z^Gx zZe!8)xlq+L5DH~ZvEBR-ZzcF-C9rlKilD6b!fYjaKvx_2zPeRSpzOO88ypS(2#qmu zvbFgkZ<N)l0ZB=&zMNCkL2PCf@A^pinpis;pD1EH+@9~Jp}BUSpv`0iE8&H z-r=>G3rYM*3WIFHGk83121p}-n74W%i=*!%-3>>OYN%^Z^Gmhw+w#RYgtwiGzs)Wh zH!6q1?{~?sb+HlQ!tr|Ay?j))E&{3w;%rmg3uVv-d~FmlABMI#myY6)xFo;nD%-`| zvBlW`;vU#q>R`DRv}M7+E@eeq?Kh`X*2x zMgDCjdMBx8H=jqlO}h_lcz1Jgu#j>hyC}qCi@k`Eg1*pUBuau^h{SPYZO1B2w3O_dPwuvRlWB;{|%P@h;YGIh?HpHa$xI`925w z#}=!PRXm+#cfKgxf&mhVK(Kdb(pE%{E&{3YCP&Ht$Wj;8r;0TSS^X?%Yiy6ert zzc`k^ru$AQ_&wL~on`q;cHWxr8vlWM{L^6XWW--`_jWD+uKJ6b`1jL%Cnx@rcR2d* zHQz7g-|8rTul`Ph_$BgxrT&Y$_(#`&&$DMOf;Xg)N_wDPy;`Kk^{6G5md%);BJpY%3{z>z1!1{mo==b2Fcbw@j zK}7uHRQ}4~zfh6fs+F<{@_`#nhMj}HDGqw@|^`X&1ROZUHeli%Syzr_3P zsr_*Rzra0zoXGFtDDUu|UsC(GHvZSE^dGR#pTqw9J6QH#rr%n)Z-=74p5cE1aQX8v zzpsP7U+DglApHMgn7_Z?{ijDx{cDuBmKnw04fK~q(BBq^|5< + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + proc_genprocdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS proc_genprocdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='proc:genProcData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd b/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd new file mode 100644 index 00000000..8b9a537b --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js b/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js new file mode 100644 index 00000000..d2d23385 --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js @@ -0,0 +1,166 @@ +function FileViewerProcessing(_obja){ + //categories.object + this.loading=0; + this.requestRender=false; + this.obja=_obja; + if(this.obja.categories==undefined){ + this.obja.categories=new Object(); + this.obja.categories.ids=new Array(); + } + + if(this.obja.categories["misc"]==undefined || this.obja.categories["misc"]==null){ + this.obja.categories["misc"]=new Object(); + this.obja.categories["misc"].cats=new Array(); + } + + this.init=function(){ + if(this.loading==0){ + this.loading=1; + this.resetCounts(); + var catCallback={ + success:this.processCatalogs, + failure:this.handleFailure, + cache:false, // Turn off caching for IE + scope:this + } + + YAHOO.util.Connect.asyncRequest('GET',this.obja.uri + '/resources?all=true&format=json&file_stats=true&sortBy=category,cat_id,label×tamp=' + (new Date()).getTime(),catCallback,null,this); + }else if(this.loading==1){ + //in process + } + } + + this.handleFailure=function(o){ + closeModalPanel("refresh_file"); + alert("Error loading files"); + } + + this.getAssessor=function(ac, aid){ + var gsAssessors=this.obja.categories[ac]; + if(gsAssessors!=undefined && gsAssessors!=null){ + for(var gsaC=0;gsaC"; + } else { + var callback={ + success:function(oResponse){ + files = (eval("(" + oResponse.responseText + ")")).ResultSet.Result; + if (files.length>0) { + file=files[0]; + var pdfImage=serverRoot+"/images/pdf.gif"; + oResponse.argument.dest.innerHTML=""; + oResponse.argument.dest.innerHTML=""; + } else { + oResponse.argument.dest.innerHTML="No PDF"; + } + }, + failure:function(oResponse){ + }, + argument:{dest:dest} + }; + cat_uri=this.objp.uri + "/resources/" + assessors[aC].cats[acAC].xnat_abstractresource_id; + YAHOO.util.Connect.asyncRequest('GET',cat_uri + '/files?format=json×tamp=' + (new Date()).getTime(),callback,null); + } + } + } + if(pdfFound==false){ + dest.innerHTML="No PDF"; + } + } + } + } + } +} diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm new file mode 100644 index 00000000..7d1392f1 --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm @@ -0,0 +1,100 @@ + +$page.setTitle("XDAT") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) + +#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) +#set($days = [ 1..31 ]) +#set($years = [ $!turbineUtils.getYear()..1990]) + +#set($qcValues = [["Bad","Bad"], ["Failed","Failed"], ["Rerun","Rerun"], ["Passed","Passed"], ["Good","Good"], ["OK","OK"]]) +#if ($data.message) +$data.message +#end +

+

+ +#if($vr) + Invalid parameters:
$vr.toHTML()
+
+#end + + + + + + + + + + + + +
+ + + + +
+
Processor Details
+
+
+ + + + +
+ + + + + + + + + + +
+
+ #parse("/screens/xnat_edit_experimentData.vm") +
+
#parse("/screens/EditProjectSpecificFields.vm")
+ + + + + + +

Processor QC
+ + + + + #xdatHiddenBox("proc:genProcData/validation/xnat_validationData_id" $item "") + #xdatHiddenBox("proc:genProcData/imageSession_ID" $item "") + #xdatHiddenBox("proc:genProcData/validation/validated_by" $item $user.username) + #xdatHiddenBox("proc:genProcData/validation/date" $item "") +
Status#cndaSelectBoxSimple("proc:genProcData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("proc:genProcData/validation/method" $item "" $vr)
Notes#xdatTextArea("proc:genProcData/validation/notes" $item "" $vr 10 30)
+
+ +
+
+
+ #xdatEditProps($item $edit_screen) + +
+
+ + diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm new file mode 100644 index 00000000..fa56125a --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm @@ -0,0 +1,406 @@ + +$page.setTitle("Processing Details") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) +#if ($turbineUtils.GetPassedParameter("popup", $data)) + #set ($popup = $turbineUtils.GetPassedParameter("popup", data) ) + #set ($popup = "false") +#end + + + + + + + + + + +
+ + + + +
+ Processing Details +
+
+ + + + + +
+ + + + + + + + +
Label$!item.getStringProperty("proc:genProcData/label")
Proc Type$!item.getStringProperty("proc:genProcData/proctype")
Proc Version$!item.getStringProperty("proc:genProcData/procversion")
Proc Date$!item.getProperty("proc:genProcData/date")
ID$!item.getStringProperty("proc:genProcData/ID")
Note$!item.getStringProperty("proc:genProcData/note")
Version$!item.getIntegerProperty("proc:genProcData/version")
+
+ + + + + + + + +
Job Information
Job Status$!item.getStringProperty("proc:genProcData/procstatus")
Job ID$!item.getStringProperty("proc:genProcData/jobid")
Job Start Date$!item.getStringProperty("proc:genProcData/jobstartdate")
Job Node$!item.getStringProperty("proc:genProcData/jobnode")
Walltime Used$!item.getStringProperty("proc:genProcData/walltimeused")
Mem Used$!item.getStringProperty("proc:genProcData/memused")
+
+ + + + + + + +
QC Information
Status$!item.getStringProperty("proc:genProcData/validation/status")
Set by$!item.getStringProperty("proc:genProcData/validation/validated_by")
Date$!item.getStringProperty("proc:genProcData/validation/date")
Method$!item.getStringProperty("proc:genProcData/validation/method")
Notes$!item.getStringProperty("proc:genProcData/validation/notes")
+
+ #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) +
+
+ + + #set($xnat_abstractResource_1_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file").size() - 1) + #if($xnat_abstractResource_1_NUM_ROWS>=0) + + + + #end + + #set($xnat_abstractResource_3_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file").size() - 1) + #if($xnat_abstractResource_3_NUM_ROWS>=0) + + + + #end + + #set($xnat_addField_5_NUM_ROWS=$item.getChildItems("proc:genProcData/parameters/addParam").size() - 1) + #if($xnat_addField_5_NUM_ROWS>=0) + + + + #end + + + #set($prov_processStep_7_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep").size() - 1) + #if($prov_processStep_7_NUM_ROWS>=0) + + + + #end + + #set($xnat_experimentData_share_9_NUM_ROWS=$item.getChildItems("proc:genProcData/sharing/share").size() - 1) + #if($xnat_experimentData_share_9_NUM_ROWS>=0) + + + + #end + + #set($xnat_abstractResource_12_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource").size() - 1) + #if($xnat_abstractResource_12_NUM_ROWS>=0) + + + + #end + + + #set($xnat_experimentData_field_14_NUM_ROWS=$item.getChildItems("proc:genProcData/fields/field").size() - 1) + #if($xnat_experimentData_field_14_NUM_ROWS>=0) + + + + #end + + + #set($proc_genProcData_scan_15_NUM_ROWS=$item.getChildItems("proc:genProcData/scans/scan").size() - 1) + #if($proc_genProcData_scan_15_NUM_ROWS>=0) + + + + #end +
+ + + + +
+ #foreach($xnat_abstractResource_1_COUNTER in [0..$xnat_abstractResource_1_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_size")
+
+ + +
+ #set($xnat_abstractResource_tag_2_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_2_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_2_COUNTER in [0..$xnat_abstractResource_tag_2_NUM_ROWS]) + + + + + + +

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+ + +
+ #foreach($xnat_abstractResource_3_COUNTER in [0..$xnat_abstractResource_3_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_size")
+
+
+ #set($xnat_abstractResource_tag_4_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_4_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_4_COUNTER in [0..$xnat_abstractResource_tag_4_NUM_ROWS]) + + + + + + +

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+
+ #foreach($xnat_addField_5_COUNTER in [0..$xnat_addField_5_NUM_ROWS]) + + + + + + +

proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]
+ + + +
addField$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/addField")
name$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/name")
+
+ + #end +
+
+ + + + + + + + +

proc:genProcData/provenance
+ +
+
+
+ #foreach($prov_processStep_7_COUNTER in [0..$prov_processStep_7_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]
+ + + + + + + + + + + + +
program$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program")
program/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/version")
program/arguments$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/arguments")
timestamp$!item.getProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/timestamp")
cvs$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/cvs")
user$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/user")
machine$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/machine")
platform$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform")
platform/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform/version")
compiler$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler")
compiler/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler/version")
+
+
+ #set($prov_processStep_library_8_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library").size() - 1) + #if($prov_processStep_library_8_NUM_ROWS>=0) + #foreach($prov_processStep_library_8_COUNTER in [0..$prov_processStep_library_8_NUM_ROWS]) + + + + + + +

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]
+ + + +
library$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/library")
version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/version")
+
+ + #end + #end +
+
+ + #end +
+
+ +
+
+ #foreach($xnat_experimentData_share_9_COUNTER in [0..$xnat_experimentData_share_9_NUM_ROWS]) + + + + + + +

proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]
+ + + + + + +
share$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/share")
label$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/label")
project$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/project")
visit$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/visit")
protocol$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/protocol")
+
+ + #end +
+
+
+ #foreach($xnat_abstractResource_12_COUNTER in [0..$xnat_abstractResource_12_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_size")
+
+
+ #set($xnat_abstractResource_tag_13_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_13_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_13_COUNTER in [0..$xnat_abstractResource_tag_13_NUM_ROWS]) + + + + + + +

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+
+ #foreach($xnat_experimentData_field_14_COUNTER in [0..$xnat_experimentData_field_14_NUM_ROWS]) + + + + + + +

proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]
+ + + +
field$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/field")
name$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/name")
+
+ + #end +
+
+
+ #foreach($proc_genProcData_scan_15_COUNTER in [0..$proc_genProcData_scan_15_NUM_ROWS]) + + + + + + +

proc:genProcData/scans/scan[$proc_genProcData_scan_15_COUNTER]
+ +
+
+ + #end +
+
+ +
diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm new file mode 100644 index 00000000..6243957f --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID + #xdatSearchField($schemaElement $schemaElement.getDisplayField("EXPT_ID")) + Date + #xdatSearchField($schemaElement $schemaElement.getDisplayField("DATE")) + Project + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROJECT")) + Inserted + #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_DATE")) +
Creator + #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_USER")) + procstatus + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCSTATUS")) + proctype + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCTYPE")) +
diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm new file mode 100644 index 00000000..bba72af3 --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm @@ -0,0 +1,157 @@ + + + + + + + +#if($om.getMinimalLoadAssessors().size()>0) + +
Processing
+ + + + + + + + + + + + + #set ($assessorCounter = 3000) + + #foreach ($proc in $om.getChildItems("assessors/assessor")) + #set ($procDate = "") + #set ($xsiType = $!proc.getXSIType()) + #set ($procType = $!proc.getXSIType()) + #set ($procDate = $!proc.getProperty("date")) + #set ($procID = $!proc.getProperty("ID")) + #set ($procLabel = $!proc.getProperty("label")) + #set ($procField = "${procType}.ID") + #set ($procurl = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) + #set ($editprocurl = "$link.setPage('XDATScreen_edit_proc_genProcData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','proc:genProcData').addPathInfo('search_field','proc:genProcData.ID')") + #set ($editfsprocurl = "$link.setPage('XDATScreen_edit_fs_fsData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") + #set ($pdfImage = $content.getURI("images/pdf.gif")) + + #set ($procStatus = "") + #if ($procType == 'proc:genProcData' || $procType == 'fs:fsData') + #set ($procStatus = $!proc.getProperty("procstatus")) + #end + + #set ($qcStatus = $!proc.getProperty("xnat:experimentData.validation/status")) + + + + + + + + + + #if($xsiType == 'proc:genProcData') + #if($qcStatus == 'Needs QA') + + #else + + #end + #elseif ($xsiType == 'fs:fsData') + #if($qcStatus == 'Needs QA') + + #else + + #end + #end + + + + + + #set ($assessorCounter= $assessorCounter + 1) + #end +
TypePDFProc DateProc IDJob StatusQC StatusFiles
+ + + + + #if($proc.canRead($user)) + #set ( $url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) + #if($proc.getHeader()) + $!proc.getHeader() + #elseif ($procType == 'xnat:qcAssessmentData') + #set ($qcType = $!proc.getProperty("type")) + $qcType + #elseif ($procType == 'proc:genProcData') + #set ($procType = $!proc.getProperty("proctype")) + $procType + #else + $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) + #end + #else + #if($proc.getHeader()) + $!proc.getHeader() + #elseif ($procType == 'xnat:qcAssessmentData') + #set ($qcType = $!proc.getProperty("type")) + $qcType + #elseif ($procType == 'proc:genProcData') + #set ($procType = $!proc.getProperty("proctype")) + $procType + #else + $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) + #end + #end + +
...
+
$!procDate$!procLabel$!procStatus$!qcStatus$!qcStatus$!qcStatus$!qcStatus + +
+ +
+ +#end diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm new file mode 100644 index 00000000..0bbcfbac --- /dev/null +++ b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm @@ -0,0 +1,228 @@ + +#if($project) + +#else + #set($project=$om.getProject()) +#end + + +#set($subject = $mr.getSubjectData()) +#if($item.needsActivation()) +
This session is in quarantine.    Activate

+#end +#addCustomScreens($om.getXSIType() "report/errors") +#parse($turbineUtils.getTemplateName("_title",$om.getXSIType(),$project)) +#if($project) + +#else +#set($project=$mr.getProject()) +#end +
+ +#addCustomScreens($om.getXSIType() "report/alert") +#parse("/screens/workflow_alert.vm") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #set ($scanCounter = 101) + #parse($turbineUtils.getTemplateName("_reconstructions",$om.getXSIType(),$project)) + + + + + + + #set ($scanCounter = 202) + + + + + + +
+ #parse($turbineUtils.getTemplateName("_details",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postDetails") +
+ #parse("/screens/ReportProjectSpecificFields.vm") +
+ #parse("/screens/qc_summary.vm") +
+ #addCustomScreens($om.getXSIType() "report/preScans") +
+

+ #parse($turbineUtils.getTemplateName("_scans",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postScans") +
+ #parse($turbineUtils.getTemplateName("_assessments",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postAssessments") +

+ #addCustomScreens($om.getXSIType() "report/postRecons") +
+ #parse("/screens/workflow_summary.vm") +
+ #addCustomScreens($om.getXSIType() "report/postWorkflowSummary") +
+ + + + + + + diff --git a/dax/xnat_modules/freesurfer/fs_module.jar b/dax/xnat_modules/freesurfer/fs_module.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb84413825369245b276836524aa4f1c97f3a9df GIT binary patch literal 47969 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 Q!hZd^e0>~Ms(yU>f4b0my8r+H literal 0 HcmV?d00001 diff --git a/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh b/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh new file mode 100755 index 00000000..8c212caf --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh @@ -0,0 +1 @@ +rm ../fs_module.jar;jar vcf ../fs_module.jar src diff --git a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java new file mode 100644 index 00000000..f3061bc2 --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java @@ -0,0 +1,26 @@ +package org.nrg.xnat.turbine.modules.screens; + + +import java.io.File; +import java.util.Iterator; + +import org.apache.turbine.util.RunData; +import org.apache.velocity.context.Context; +import org.nrg.xdat.om.FsFsdata; +import org.nrg.xdat.om.XnatImagesessiondata; +import org.nrg.xdat.om.XnatResourcecatalog; +import org.nrg.xdat.turbine.modules.screens.SecureReport; + +public class Fs_fsData_QC_64 extends SecureReport { + public static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Fs_fsData_QC_64.class); + public void finalProcessing(RunData data, Context context) { + try{ + org.nrg.xdat.om.FsFsdata fs = new org.nrg.xdat.om.FsFsdata(item); + context.put("fs",fs); + XnatImagesessiondata om = fs.getImageSessionData(); + context.put("mr",om); + } catch(Exception e){ + logger.debug("Fs_fsData_QC_64", e); + } + } +} diff --git a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java new file mode 100644 index 00000000..bb2732e8 --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java @@ -0,0 +1,33 @@ +package org.nrg.xnat.turbine.modules.screens; + + +import org.apache.turbine.util.RunData; +import org.apache.velocity.context.Context; +import org.nrg.xdat.turbine.utils.TurbineUtils; +import org.nrg.xft.ItemI; +import org.nrg.xft.XFTItem; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class XDATScreen_edit_fs_fsData extends org.nrg.xnat.turbine.modules.screens.EditImageAssessorScreen { + static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(XDATScreen_edit_fs_fsData.class); + /* (non-Javadoc) + * @see org.nrg.xdat.turbine.modules.screens.EditScreenA#getElementName() + */ + public String getElementName() { + return "fs:fsData"; + } + + public ItemI getEmptyItem(RunData data) throws Exception + { + return super.getEmptyItem(data); + } + /* (non-Javadoc) + * @see org.nrg.xdat.turbine.modules.screens.SecureReport#finalProcessing(org.apache.turbine.util.RunData, org.apache.velocity.context.Context) + */ + public void finalProcessing(RunData data, Context context) { + String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + + context.put("today", today); + } +}; diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml new file mode 100644 index 00000000..f3fa1343 --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml @@ -0,0 +1,5137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + fs_fsdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_fsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:fsData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3)> + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + + + + + + + + + + --> + ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) + + + + + + + + + + + + + + ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) + + + + + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) + + + + + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + ROUND((CAST(@COL1 AS numeric))/1000,3) + + + + ROUND((CAST(@COL1 AS numeric))/1000,3) + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml new file mode 100644 index 00000000..8f8d4fdb --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + CAST(COALESCE(FLOOR(CAST((CAST(((@Field1) - (@Field2))AS FLOAT4)/365) AS numeric)),FLOOR((EXTRACT(YEAR FROM @Field1)) - (@Field3))) AS numeric) + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + fs_longfsdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_longfsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:longFSData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd new file mode 100644 index 00000000..af7eafee --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js b/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js new file mode 100644 index 00000000..7de59913 --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js @@ -0,0 +1,403 @@ +//================================================== +// slide object +//================================================== +function slideImg(src,link,txt,target,attr) { + // s = new slideImg(); + + // Image URL + this.src = src; + + // Link URL + this.link = link; + + //Alt text for the image + this.text = txt; + + // Name of the target window ("_blank") + this.target = target; + + // Custom duration for the slide, in milliseconds. + // This is an optional parameter. + // this.timeout = 3000 + + // Attributes for the target window: + // width=n,height=n,resizable=yes or no,scrollbars=yes or no, + // toolbar=yes or no,location=yes or no,directories=yes or no, + // status=yes or no,menubar=yes or no,copyhistory=yes or no + // Example: "width=200,height=300" + this.attr = attr; + + // Create an image object for the slide + if (document.images) { + this.image = new Image(); + } + + // Flag to tell when load() has already been called + this.loaded = false; + + //-------------------------------------------------- + this.load = function() { + // This method loads the image for the slide + + if (!document.images) { return; } + + if (!this.loaded) { + this.image.src = this.src; + this.image.alt = this.text; + this.loaded = true; + } + } + + //-------------------------------------------------- + this.hotlink = function() { + // This method jumps to the slide's link. + // If a window was specified for the slide, then it opens a new window. + var mywindow; + + // If this slide does not have a link, do nothing + if (!this.link) return; + + // Open the link in a separate window? + if (this.target) { + + // If window attributes are specified, + // use them to open the new window + if (this.attr) { + mywindow = window.open(this.link, this.target, this.attr); + + } else { + // If window attributes are not specified, do not use them + // (this will copy the attributes from the originating window) + mywindow = window.open(this.link, this.target); + } + + // Pop the window to the front + if (mywindow && mywindow.focus) mywindow.focus(); + + } else { + // Open the link in the current window + location.href = this.link; + } + } +} + +//================================================== +// slideshow object +//================================================== +function slideshow( slideshowname ) { + // ss = new slideshow("ss"); + + // Name of this object + // (required if you want your slideshow to auto-play) + // For example, "SLIDES1" + this.name = slideshowname; + + // When we reach the last slide, should we loop around to start the + // slideshow again? + this.repeat = true; + + // Number of images to pre-fetch. + // -1 = preload all images. + // 0 = load each image is it is used. + // n = pre-fetch n images ahead of the current image. + // I recommend preloading all images unless you have large + // images, or a large amount of images. + this.prefetch = -1; + + // IMAGE element on your HTML page. + // For example, document.images.SLIDES1IMG + this.image; + + // ID of a DIV element on your HTML page that will contain the text. + // For example, "slides2text" + // Note: after you set this variable, you should call + // the update() method to update the slideshow display. + this.textid; + + // Milliseconds to pause between slides. + // Individual slides can override this. + this.timeout = 3000; + + // Hook functions to be called before and after updating the slide + // this.pre_update_hook = function() { } + // this.post_update_hook = function() { } + + // These are private variables + this.slides = new Array(); + this.current = 0; + this.timeoutid = 0; + + //-------------------------------------------------- + // Public methods + //-------------------------------------------------- + this.add_slide = function(slide) { + // Add a slide to the slideshow. + // For example: + // SLIDES1.add_slide(new slide("s1.jpg", "link.html")) + + var i = this.slides.length; + + // Prefetch the slide image if necessary + if (this.prefetch == -1) { + slide.load(); + } + + this.slides[i] = slide; + } + + //-------------------------------------------------- + this.play = function(timeout) { + // This method implements the automatically running slideshow. + // If you specify the "timeout" argument, then a new default + // timeout will be set for the slideshow. + + // Make sure we're not already playing + this.pause(); + + // If the timeout argument was specified (optional) + // then make it the new default + if (timeout) { + this.timeout = timeout; + } + + // If the current slide has a custom timeout, use it; + // otherwise use the default timeout + if (typeof this.slides[ this.current ].timeout != 'undefined') { + timeout = this.slides[ this.current ].timeout; + } else { + timeout = this.timeout; + } + + // After the timeout, call this.loop() + this.timeoutid = setTimeout( this.name + ".loop()", timeout); + } + +//-------------------------------------------------- + this.playPause = function(id) { + // This method implements the automatically running slideshow. + // If you specify the "timeout" argument, then a new default + // timeout will be set for the slideshow. + + if (document.getElementById(id).value == "Pause") { + document.getElementById(id).value = "Play "; + clearTimeout(this.timeoutid); + this.timeoutid = 0; + } else { + this.next(); + + document.getElementById(id).value = "Pause"; + + clearTimeout(this.timeoutid); + this.timeoutid = 0; + + // If the current slide has a custom timeout, use it; + // otherwise use the default timeout + if (typeof this.slides[ this.current ].timeout != 'undefined') { + timeout = this.slides[ this.current ].timeout; + } else { + timeout = this.timeout; + } + + // After the timeout, call this.loop() + this.timeoutid = setTimeout( this.name + ".loop()", timeout); + } + } + + //-------------------------------------------------- + this.pause = function() { + // This method stops the slideshow if it is automatically running. + + if (this.timeoutid != 0) { + + clearTimeout(this.timeoutid); + this.timeoutid = 0; + + } + } + + //-------------------------------------------------- + this.update = function() { + // This method updates the slideshow image on the page + + // Make sure the slideshow has been initialized correctly + if (! this.valid_image()) { return; } + + + // Convenience variable for the current slide + var slide = this.slides[ this.current ]; + + // Load the slide image if necessary + slide.load(); + + // Update the image. + this.image.src = slide.image.src; + this.image.alt = slide.text; + this.image.title = slide.text; + + // Call the post-update hook function if one was specified + if (typeof this.post_update_hook == 'function') { + this.post_update_hook(); + } + + // Do we need to pre-fetch images? + if (this.prefetch > 0) { + + var next, prev, count; + + // Pre-fetch the next slide image(s) + next = this.current; + prev = this.current; + count = 0; + do { + + // Get the next and previous slide number + // Loop past the ends of the slideshow if necessary + if (++next >= this.slides.length) next = 0; + if (--prev < 0) prev = this.slides.length - 1; + + // Preload the slide image + this.slides[next].load(); + this.slides[prev].load(); + + // Keep going until we have fetched + // the designated number of slides + + } while (++count < this.prefetch); + } + } + + //-------------------------------------------------- + this.goto_slide = function(n) { + // This method jumpts to the slide number you specify. + // If you use slide number -1, then it jumps to the last slide. + // You can use this to make links that go to a specific slide, + // or to go to the beginning or end of the slideshow. + // Examples: + // onClick="myslides.goto_slide(0)" + // onClick="myslides.goto_slide(-1)" + // onClick="myslides.goto_slide(5)" + + if (n == -1) { + n = this.slides.length - 1; + } + + if (n < this.slides.length && n >= 0) { + this.current = n; + } + + this.update(); + } + + //-------------------------------------------------- + this.next = function() { + // This method advances to the next slide. + + // Increment the image number + if (this.current < this.slides.length - 1) { + this.current++; + } else if (this.repeat) { + this.current = 0; + } + + this.update(); + } + + + //-------------------------------------------------- + this.previous = function() { + // This method goes to the previous slide. + + // Decrement the image number + if (this.current > 0) { + this.current--; + } else if (this.repeat) { + this.current = this.slides.length - 1; + } + + this.update(); + } + + //-------------------------------------------------- + this.zoomUp = function() { + // This method increments the image height by 50 + var oldHeight = this.image.height; + this.image.height = oldHeight + 50; + this.update(); + } + + //-------------------------------------------------- + this.zoomDown = function() { + // This method increments the image height by 50 + var oldHeight = this.image.height; + this.image.height = oldHeight - 50; + this.update(); + } + + //-------------------------------------------------- + this.get_text = function() { + // This method returns the text of the current slide + + return(this.slides[ this.current ].text); + } + + //-------------------------------------------------- + this.hotlink = function() { + // This method calls the hotlink() method for the current slide. + + this.slides[ this.current ].hotlink(); + } + +//-------------------------------------------------- + this.loop = function() { + // This method is for internal use only. + // This method gets called automatically by a JavaScript timeout. + // It advances to the next slide, then sets the next timeout. + // If the next slide image has not completed loading yet, + // then do not advance to the next slide yet. + + // Make sure the next slide image has finished loading + if (this.current < this.slides.length - 1) { + next_slide = this.slides[this.current + 1]; + if (next_slide.image.complete == null || next_slide.image.complete) { + this.next(); + } + } else { // we're at the last slide + this.next(); + } + + // Keep playing the slideshow + this.play( ); + } + + + //-------------------------------------------------- + this.valid_image = function() { + // Returns 1 if a valid image has been set for the slideshow + + if (!this.image) + { + return false; + } + else { + return true; + } + } + + //-------------------------------------------------- + this.getElementById = function(element_id) { + // This method returns the element corresponding to the id + + if (document.getElementById) { + return document.getElementById(element_id); + } + else if (document.all) { + return document.all[element_id]; + } + else if (document.layers) { + return document.layers[element_id]; + } else { + return undefined; + } + } + } + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm new file mode 100644 index 00000000..f1d2d6ee --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm @@ -0,0 +1,94 @@ +##LAYOUT (also see other file in screens) +##Copyright 2005 Harvard University / Howard Hughes Medical Institute (HHMI) All Rights Reserved + +#set ($projlabel = $om.getProject()) +#set ($subjlabel = $mr.getSubjectData().getLabel()) +#set ($mrlabel = $om.getImageSessionData().getLabel()) +#set ($xsi_type = $!item.getXSIType()) +#set ($fslabel = $!item.getStringProperty("$xsi_type/label")) +#set ($snapshots_path = "/xnat/data/archive/projects/$projlabel/subjects/$subjlabel/experiments/$mrlabel/assessors/$fslabel/out/resources/SNAPSHOTS/files") + + + + + + + $!systemName + #includeJSFile() + + + + + + + + + + +
+ $screen_placeholder +
+ + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm new file mode 100644 index 00000000..63585c58 --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm @@ -0,0 +1,185 @@ +##SCREEN (also see other file in screens) + + + +
+ + + + + + + + + +
+
+ 2D Slices +
Session: $om.getImageSessionData().getLabel()Zoom Delay:
+ + + + + + + + + +
AXIAL SLICES
+
+ + + + + +
+
SST Axial Slices
+ + + + + + + + + + +
CORONAL SLICES
+ + + + + +
SST Coronal Slices
+ + + + + + + + + + +
SAGITTAL SLICES
+ + + + + +
SST Sagittal Slices
+ + + #set ($search_element = "xnat:mrSessiondata") + #set ($search_field = "xnat:mrSessiondata.ID") + #set ($search_value = $om.getImagesessionId()) + #set ($project = $om.getProject()) + + #xdatPassItemFormFields($search_element $search_field $search_value $project) + #set ($label = "DATA") + + +
+ + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm new file mode 100644 index 00000000..b287106e --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm @@ -0,0 +1,95 @@ + +$page.setTitle("XDAT") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) + +#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) +#set($days = [ 1..31 ]) +#set($years = [ $!turbineUtils.getYear()..1990]) + +#set($qcValues = [["Failed","Failed"],["Failed-needs reprocessing","Failed-needs reprocessing"],["Passed","Passed"],["Passed with edits","Passed with edits"], ["Rerun","Rerun"]]) +#if ($data.message) + $data.message +#end +

+

+ +#if($vr) + Invalid parameters:
$vr.toHTML()
+
+#end + + + + + + + + + + + + +
+ + + + +
+
Freesurfer Details
+
+
+ + + + +
+ + + + + + + + + + +
+
+ #parse("/screens/xnat_edit_experimentData.vm") +
+
#parse("/screens/EditProjectSpecificFields.vm")
+ + + + + + +

FreeSurfer QC
+ + + + + #xdatHiddenBox("fs:fsData/validation/xnat_validationData_id" $item "") + #xdatHiddenBox("fs:fsData/imageSession_ID" $item "") + #xdatHiddenBox("fs:fsData/fsversion" $item "") + #xdatHiddenBox("fs:fsData/procversion" $item "") + #xdatHiddenBox("fs:fsData/validation/validated_by" $item $user.username) + #xdatHiddenBox("fs:fsData/validation/date" $item "") +
Status#cndaSelectBoxSimple("fs:fsData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("fs:fsData/validation/method" $item "" $vr)
Notes#xdatTextArea("fs:fsData/validation/notes" $item "" $vr 10 30)
+
+ +
+
+
+ #xdatEditProps($item $edit_screen) +
+
+ + diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm new file mode 100644 index 00000000..016dc27d --- /dev/null +++ b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm @@ -0,0 +1,234 @@ + +$page.setTitle("Freesurfer Analysis Details") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) +#if ($data.getParameters().getString("popup")) + #set ($popup = $data.getParameters().getString("popup") ) + #set ($popup = "false") +#end + + + + + + + + +
+ + + + +
+ Freesurfer Analysis Details +
+
+ + + + + +
+ + #set ($id=".ID") + #set ($field="$om.getImageSessionData().getXSIType()$id") + + #set ($url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$om.getImageSessionData().getXSIType()).addPathInfo('search_field',$field).addPathInfo('search_value',$om.getImageSessionData().getId()).addPathInfo('project',$om.getProject())") + + + + + + + +
Project$!item.getStringProperty("fs:fsData/project")
MRSession$om.getImageSessionData().getLabel()
FS ID$!item.getStringProperty("fs:fsData/label")
FS Date$!item.getProperty("fs:fsData/date")
Note$!item.getStringProperty("fs:fsData/note")
FS Version$!item.getStringProperty("fs:fsData/fsversion")
Proc Version$!item.getStringProperty("fs:fsData/procversion")
+
+ + + + + + + + +
Job Information
Job Status$!item.getStringProperty("fs:fsData/procstatus")
Job ID$!item.getStringProperty("fs:fsData/jobid")
Job Start Date$!item.getStringProperty("fs:fsData/jobstartdate")
Job Node$!item.getStringProperty("fs:fsData/jobnode")
Walltime Used$!item.getStringProperty("fs:fsData/walltimeused")
Mem Used$!item.getStringProperty("fs:fsData/memused")
+
+ + + + + + + +
QC Information
Status$!item.getStringProperty("fs:fsData/validation/status")
Set by$!item.getStringProperty("fs:fsData/validation/validated_by")
Date$!item.getStringProperty("fs:fsData/validation/date")
Method$!item.getStringProperty("fs:fsData/validation/method")
Notes$!item.getStringProperty("fs:fsData/validation/notes")
+
+ #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) +
+
+ +
+
+ +#set ($url = "$link.setPage('Fs_fsData_QC_64.vm').addPathInfo('search_value',$item.getProperty('ID')).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") +View Snapshots + +
+
+ +#set ($scanCounter = 0) + + + Subcortical Segmentation + + +
+ + +
+#set ($scanCounter = 1) + + + Surface Measures + + + + + + +
+ +
+#set ($scanCounter = 2) + + + Processing parameters + + + + + +
+ +
+#set ($scanCounter = 3) + + + Log files + + + + From a30ce492a9a1fa2f9911eb58a0fabe4114ecc66c Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 10:42:52 +0100 Subject: [PATCH 32/62] Create modules --- dax/xnat_modules/modules | 1 + 1 file changed, 1 insertion(+) create mode 100644 dax/xnat_modules/modules diff --git a/dax/xnat_modules/modules b/dax/xnat_modules/modules new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/dax/xnat_modules/modules @@ -0,0 +1 @@ + From 52b53c76098a4a7bd29b29b83b9cd22cc88d5c61 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 10:43:00 +0100 Subject: [PATCH 33/62] Delete modules --- dax/xnat_modules/modules | 1 - 1 file changed, 1 deletion(-) delete mode 100644 dax/xnat_modules/modules diff --git a/dax/xnat_modules/modules b/dax/xnat_modules/modules deleted file mode 100644 index 8b137891..00000000 --- a/dax/xnat_modules/modules +++ /dev/null @@ -1 +0,0 @@ - From 7e1707657846a5ff4ea45d6dfc5c15b1f203eac8 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 10:51:05 +0100 Subject: [PATCH 34/62] adding the files for the processor with a new organisation --- dax/xnat_modules/fs_module/rebuild_fs.sh | 1 + .../modules/screens/Fs_fsData_QC_64.java | 26 + .../screens/XDATScreen_edit_fs_fsData.java | 33 + .../schemas/fs/display/fs_fsData_display.xml | 5137 +++++++++++++++++ .../fs/display/fs_longFSData_display.xml | 224 + .../fs_module/src/schemas/fs/fs.xsd | 332 ++ .../fs_module/src/scripts/slideshow.js | 403 ++ .../src/templates/layouts/Fs_fsData_QC_64.vm | 94 + .../src/templates/screens/Fs_fsData_QC_64.vm | 185 + .../screens/XDATScreen_edit_fs_fsData.vm | 95 + .../screens/XDATScreen_report_fs_fsData.vm | 234 + dax/xnat_modules/jar_files/fs_module.jar | Bin 0 -> 47969 bytes dax/xnat_modules/jar_files/proc_module.jar | Bin 0 -> 16422 bytes dax/xnat_modules/proc_module/rebuild_proc.sh | 1 + .../proc/display/proc_genProcData_display.xml | 212 + .../proc_module/src/schemas/proc/proc.xsd | 42 + .../src/scripts/FileViewerProcessing.js | 166 + .../src/scripts/FileViewerProcessingPdf.js | 154 + .../XDATScreen_edit_proc_genProcData.vm | 100 + .../XDATScreen_report_proc_genProcData.vm | 406 ++ .../screens/proc_genProcData_search.vm | 42 + .../xnat_imageSessionData_assessments.vm | 157 + .../xnat_imageSessionData_report.vm | 228 + 23 files changed, 8272 insertions(+) create mode 100755 dax/xnat_modules/fs_module/rebuild_fs.sh create mode 100644 dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java create mode 100644 dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java create mode 100644 dax/xnat_modules/fs_module/src/schemas/fs/display/fs_fsData_display.xml create mode 100644 dax/xnat_modules/fs_module/src/schemas/fs/display/fs_longFSData_display.xml create mode 100644 dax/xnat_modules/fs_module/src/schemas/fs/fs.xsd create mode 100644 dax/xnat_modules/fs_module/src/scripts/slideshow.js create mode 100644 dax/xnat_modules/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm create mode 100644 dax/xnat_modules/fs_module/src/templates/screens/Fs_fsData_QC_64.vm create mode 100644 dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm create mode 100644 dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm create mode 100644 dax/xnat_modules/jar_files/fs_module.jar create mode 100644 dax/xnat_modules/jar_files/proc_module.jar create mode 100755 dax/xnat_modules/proc_module/rebuild_proc.sh create mode 100644 dax/xnat_modules/proc_module/src/schemas/proc/display/proc_genProcData_display.xml create mode 100644 dax/xnat_modules/proc_module/src/schemas/proc/proc.xsd create mode 100644 dax/xnat_modules/proc_module/src/scripts/FileViewerProcessing.js create mode 100644 dax/xnat_modules/proc_module/src/scripts/FileViewerProcessingPdf.js create mode 100644 dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm create mode 100644 dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm create mode 100644 dax/xnat_modules/proc_module/src/templates/screens/proc_genProcData_search.vm create mode 100644 dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm create mode 100644 dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm diff --git a/dax/xnat_modules/fs_module/rebuild_fs.sh b/dax/xnat_modules/fs_module/rebuild_fs.sh new file mode 100755 index 00000000..41e9d242 --- /dev/null +++ b/dax/xnat_modules/fs_module/rebuild_fs.sh @@ -0,0 +1 @@ +rm ../jar_files/fs_module.jar;jar vcf ../jar_files/fs_module.jar src diff --git a/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java b/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java new file mode 100644 index 00000000..f3061bc2 --- /dev/null +++ b/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java @@ -0,0 +1,26 @@ +package org.nrg.xnat.turbine.modules.screens; + + +import java.io.File; +import java.util.Iterator; + +import org.apache.turbine.util.RunData; +import org.apache.velocity.context.Context; +import org.nrg.xdat.om.FsFsdata; +import org.nrg.xdat.om.XnatImagesessiondata; +import org.nrg.xdat.om.XnatResourcecatalog; +import org.nrg.xdat.turbine.modules.screens.SecureReport; + +public class Fs_fsData_QC_64 extends SecureReport { + public static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Fs_fsData_QC_64.class); + public void finalProcessing(RunData data, Context context) { + try{ + org.nrg.xdat.om.FsFsdata fs = new org.nrg.xdat.om.FsFsdata(item); + context.put("fs",fs); + XnatImagesessiondata om = fs.getImageSessionData(); + context.put("mr",om); + } catch(Exception e){ + logger.debug("Fs_fsData_QC_64", e); + } + } +} diff --git a/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java b/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java new file mode 100644 index 00000000..bb2732e8 --- /dev/null +++ b/dax/xnat_modules/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java @@ -0,0 +1,33 @@ +package org.nrg.xnat.turbine.modules.screens; + + +import org.apache.turbine.util.RunData; +import org.apache.velocity.context.Context; +import org.nrg.xdat.turbine.utils.TurbineUtils; +import org.nrg.xft.ItemI; +import org.nrg.xft.XFTItem; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class XDATScreen_edit_fs_fsData extends org.nrg.xnat.turbine.modules.screens.EditImageAssessorScreen { + static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(XDATScreen_edit_fs_fsData.class); + /* (non-Javadoc) + * @see org.nrg.xdat.turbine.modules.screens.EditScreenA#getElementName() + */ + public String getElementName() { + return "fs:fsData"; + } + + public ItemI getEmptyItem(RunData data) throws Exception + { + return super.getEmptyItem(data); + } + /* (non-Javadoc) + * @see org.nrg.xdat.turbine.modules.screens.SecureReport#finalProcessing(org.apache.turbine.util.RunData, org.apache.velocity.context.Context) + */ + public void finalProcessing(RunData data, Context context) { + String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + + context.put("today", today); + } +}; diff --git a/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_fsData_display.xml b/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_fsData_display.xml new file mode 100644 index 00000000..f3fa1343 --- /dev/null +++ b/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_fsData_display.xml @@ -0,0 +1,5137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + fs_fsdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_fsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:fsData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@COL1 AS numeric),0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@Field1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3)> + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + ROUND(CAST(@COL1 AS numeric)/1000,3) + + + + + + + + + + + + + --> + ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) + + + + + + + + + + + + + + ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) + + + + + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) + + + + + + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) + + + + ROUND((CAST(@COL1 AS numeric))/1000,3) + + + + ROUND((CAST(@COL1 AS numeric))/1000,3) + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) + + + + + ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_longFSData_display.xml b/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_longFSData_display.xml new file mode 100644 index 00000000..8f8d4fdb --- /dev/null +++ b/dax/xnat_modules/fs_module/src/schemas/fs/display/fs_longFSData_display.xml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + CAST(COALESCE(FLOOR(CAST((CAST(((@Field1) - (@Field2))AS FLOAT4)/365) AS numeric)),FLOOR((EXTRACT(YEAR FROM @Field1)) - (@Field3))) AS numeric) + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + fs_longfsdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_longfsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:longFSData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/fs_module/src/schemas/fs/fs.xsd b/dax/xnat_modules/fs_module/src/schemas/fs/fs.xsd new file mode 100644 index 00000000..af7eafee --- /dev/null +++ b/dax/xnat_modules/fs_module/src/schemas/fs/fs.xsd @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/fs_module/src/scripts/slideshow.js b/dax/xnat_modules/fs_module/src/scripts/slideshow.js new file mode 100644 index 00000000..7de59913 --- /dev/null +++ b/dax/xnat_modules/fs_module/src/scripts/slideshow.js @@ -0,0 +1,403 @@ +//================================================== +// slide object +//================================================== +function slideImg(src,link,txt,target,attr) { + // s = new slideImg(); + + // Image URL + this.src = src; + + // Link URL + this.link = link; + + //Alt text for the image + this.text = txt; + + // Name of the target window ("_blank") + this.target = target; + + // Custom duration for the slide, in milliseconds. + // This is an optional parameter. + // this.timeout = 3000 + + // Attributes for the target window: + // width=n,height=n,resizable=yes or no,scrollbars=yes or no, + // toolbar=yes or no,location=yes or no,directories=yes or no, + // status=yes or no,menubar=yes or no,copyhistory=yes or no + // Example: "width=200,height=300" + this.attr = attr; + + // Create an image object for the slide + if (document.images) { + this.image = new Image(); + } + + // Flag to tell when load() has already been called + this.loaded = false; + + //-------------------------------------------------- + this.load = function() { + // This method loads the image for the slide + + if (!document.images) { return; } + + if (!this.loaded) { + this.image.src = this.src; + this.image.alt = this.text; + this.loaded = true; + } + } + + //-------------------------------------------------- + this.hotlink = function() { + // This method jumps to the slide's link. + // If a window was specified for the slide, then it opens a new window. + var mywindow; + + // If this slide does not have a link, do nothing + if (!this.link) return; + + // Open the link in a separate window? + if (this.target) { + + // If window attributes are specified, + // use them to open the new window + if (this.attr) { + mywindow = window.open(this.link, this.target, this.attr); + + } else { + // If window attributes are not specified, do not use them + // (this will copy the attributes from the originating window) + mywindow = window.open(this.link, this.target); + } + + // Pop the window to the front + if (mywindow && mywindow.focus) mywindow.focus(); + + } else { + // Open the link in the current window + location.href = this.link; + } + } +} + +//================================================== +// slideshow object +//================================================== +function slideshow( slideshowname ) { + // ss = new slideshow("ss"); + + // Name of this object + // (required if you want your slideshow to auto-play) + // For example, "SLIDES1" + this.name = slideshowname; + + // When we reach the last slide, should we loop around to start the + // slideshow again? + this.repeat = true; + + // Number of images to pre-fetch. + // -1 = preload all images. + // 0 = load each image is it is used. + // n = pre-fetch n images ahead of the current image. + // I recommend preloading all images unless you have large + // images, or a large amount of images. + this.prefetch = -1; + + // IMAGE element on your HTML page. + // For example, document.images.SLIDES1IMG + this.image; + + // ID of a DIV element on your HTML page that will contain the text. + // For example, "slides2text" + // Note: after you set this variable, you should call + // the update() method to update the slideshow display. + this.textid; + + // Milliseconds to pause between slides. + // Individual slides can override this. + this.timeout = 3000; + + // Hook functions to be called before and after updating the slide + // this.pre_update_hook = function() { } + // this.post_update_hook = function() { } + + // These are private variables + this.slides = new Array(); + this.current = 0; + this.timeoutid = 0; + + //-------------------------------------------------- + // Public methods + //-------------------------------------------------- + this.add_slide = function(slide) { + // Add a slide to the slideshow. + // For example: + // SLIDES1.add_slide(new slide("s1.jpg", "link.html")) + + var i = this.slides.length; + + // Prefetch the slide image if necessary + if (this.prefetch == -1) { + slide.load(); + } + + this.slides[i] = slide; + } + + //-------------------------------------------------- + this.play = function(timeout) { + // This method implements the automatically running slideshow. + // If you specify the "timeout" argument, then a new default + // timeout will be set for the slideshow. + + // Make sure we're not already playing + this.pause(); + + // If the timeout argument was specified (optional) + // then make it the new default + if (timeout) { + this.timeout = timeout; + } + + // If the current slide has a custom timeout, use it; + // otherwise use the default timeout + if (typeof this.slides[ this.current ].timeout != 'undefined') { + timeout = this.slides[ this.current ].timeout; + } else { + timeout = this.timeout; + } + + // After the timeout, call this.loop() + this.timeoutid = setTimeout( this.name + ".loop()", timeout); + } + +//-------------------------------------------------- + this.playPause = function(id) { + // This method implements the automatically running slideshow. + // If you specify the "timeout" argument, then a new default + // timeout will be set for the slideshow. + + if (document.getElementById(id).value == "Pause") { + document.getElementById(id).value = "Play "; + clearTimeout(this.timeoutid); + this.timeoutid = 0; + } else { + this.next(); + + document.getElementById(id).value = "Pause"; + + clearTimeout(this.timeoutid); + this.timeoutid = 0; + + // If the current slide has a custom timeout, use it; + // otherwise use the default timeout + if (typeof this.slides[ this.current ].timeout != 'undefined') { + timeout = this.slides[ this.current ].timeout; + } else { + timeout = this.timeout; + } + + // After the timeout, call this.loop() + this.timeoutid = setTimeout( this.name + ".loop()", timeout); + } + } + + //-------------------------------------------------- + this.pause = function() { + // This method stops the slideshow if it is automatically running. + + if (this.timeoutid != 0) { + + clearTimeout(this.timeoutid); + this.timeoutid = 0; + + } + } + + //-------------------------------------------------- + this.update = function() { + // This method updates the slideshow image on the page + + // Make sure the slideshow has been initialized correctly + if (! this.valid_image()) { return; } + + + // Convenience variable for the current slide + var slide = this.slides[ this.current ]; + + // Load the slide image if necessary + slide.load(); + + // Update the image. + this.image.src = slide.image.src; + this.image.alt = slide.text; + this.image.title = slide.text; + + // Call the post-update hook function if one was specified + if (typeof this.post_update_hook == 'function') { + this.post_update_hook(); + } + + // Do we need to pre-fetch images? + if (this.prefetch > 0) { + + var next, prev, count; + + // Pre-fetch the next slide image(s) + next = this.current; + prev = this.current; + count = 0; + do { + + // Get the next and previous slide number + // Loop past the ends of the slideshow if necessary + if (++next >= this.slides.length) next = 0; + if (--prev < 0) prev = this.slides.length - 1; + + // Preload the slide image + this.slides[next].load(); + this.slides[prev].load(); + + // Keep going until we have fetched + // the designated number of slides + + } while (++count < this.prefetch); + } + } + + //-------------------------------------------------- + this.goto_slide = function(n) { + // This method jumpts to the slide number you specify. + // If you use slide number -1, then it jumps to the last slide. + // You can use this to make links that go to a specific slide, + // or to go to the beginning or end of the slideshow. + // Examples: + // onClick="myslides.goto_slide(0)" + // onClick="myslides.goto_slide(-1)" + // onClick="myslides.goto_slide(5)" + + if (n == -1) { + n = this.slides.length - 1; + } + + if (n < this.slides.length && n >= 0) { + this.current = n; + } + + this.update(); + } + + //-------------------------------------------------- + this.next = function() { + // This method advances to the next slide. + + // Increment the image number + if (this.current < this.slides.length - 1) { + this.current++; + } else if (this.repeat) { + this.current = 0; + } + + this.update(); + } + + + //-------------------------------------------------- + this.previous = function() { + // This method goes to the previous slide. + + // Decrement the image number + if (this.current > 0) { + this.current--; + } else if (this.repeat) { + this.current = this.slides.length - 1; + } + + this.update(); + } + + //-------------------------------------------------- + this.zoomUp = function() { + // This method increments the image height by 50 + var oldHeight = this.image.height; + this.image.height = oldHeight + 50; + this.update(); + } + + //-------------------------------------------------- + this.zoomDown = function() { + // This method increments the image height by 50 + var oldHeight = this.image.height; + this.image.height = oldHeight - 50; + this.update(); + } + + //-------------------------------------------------- + this.get_text = function() { + // This method returns the text of the current slide + + return(this.slides[ this.current ].text); + } + + //-------------------------------------------------- + this.hotlink = function() { + // This method calls the hotlink() method for the current slide. + + this.slides[ this.current ].hotlink(); + } + +//-------------------------------------------------- + this.loop = function() { + // This method is for internal use only. + // This method gets called automatically by a JavaScript timeout. + // It advances to the next slide, then sets the next timeout. + // If the next slide image has not completed loading yet, + // then do not advance to the next slide yet. + + // Make sure the next slide image has finished loading + if (this.current < this.slides.length - 1) { + next_slide = this.slides[this.current + 1]; + if (next_slide.image.complete == null || next_slide.image.complete) { + this.next(); + } + } else { // we're at the last slide + this.next(); + } + + // Keep playing the slideshow + this.play( ); + } + + + //-------------------------------------------------- + this.valid_image = function() { + // Returns 1 if a valid image has been set for the slideshow + + if (!this.image) + { + return false; + } + else { + return true; + } + } + + //-------------------------------------------------- + this.getElementById = function(element_id) { + // This method returns the element corresponding to the id + + if (document.getElementById) { + return document.getElementById(element_id); + } + else if (document.all) { + return document.all[element_id]; + } + else if (document.layers) { + return document.layers[element_id]; + } else { + return undefined; + } + } + } + diff --git a/dax/xnat_modules/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm b/dax/xnat_modules/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm new file mode 100644 index 00000000..f1d2d6ee --- /dev/null +++ b/dax/xnat_modules/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm @@ -0,0 +1,94 @@ +##LAYOUT (also see other file in screens) +##Copyright 2005 Harvard University / Howard Hughes Medical Institute (HHMI) All Rights Reserved + +#set ($projlabel = $om.getProject()) +#set ($subjlabel = $mr.getSubjectData().getLabel()) +#set ($mrlabel = $om.getImageSessionData().getLabel()) +#set ($xsi_type = $!item.getXSIType()) +#set ($fslabel = $!item.getStringProperty("$xsi_type/label")) +#set ($snapshots_path = "/xnat/data/archive/projects/$projlabel/subjects/$subjlabel/experiments/$mrlabel/assessors/$fslabel/out/resources/SNAPSHOTS/files") + + + + + + + $!systemName + #includeJSFile() + + + + + + + + + + +
+ $screen_placeholder +
+ + diff --git a/dax/xnat_modules/fs_module/src/templates/screens/Fs_fsData_QC_64.vm b/dax/xnat_modules/fs_module/src/templates/screens/Fs_fsData_QC_64.vm new file mode 100644 index 00000000..63585c58 --- /dev/null +++ b/dax/xnat_modules/fs_module/src/templates/screens/Fs_fsData_QC_64.vm @@ -0,0 +1,185 @@ +##SCREEN (also see other file in screens) + + + +
+ + + + + + + + + +
+
+ 2D Slices +
Session: $om.getImageSessionData().getLabel()Zoom Delay:
+ + + + + + + + + +
AXIAL SLICES
+
+ + + + + +
+
SST Axial Slices
+ + + + + + + + + + +
CORONAL SLICES
+ + + + + +
SST Coronal Slices
+ + + + + + + + + + +
SAGITTAL SLICES
+ + + + + +
SST Sagittal Slices
+ + + #set ($search_element = "xnat:mrSessiondata") + #set ($search_field = "xnat:mrSessiondata.ID") + #set ($search_value = $om.getImagesessionId()) + #set ($project = $om.getProject()) + + #xdatPassItemFormFields($search_element $search_field $search_value $project) + #set ($label = "DATA") + + +
+ + diff --git a/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm b/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm new file mode 100644 index 00000000..b287106e --- /dev/null +++ b/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm @@ -0,0 +1,95 @@ + +$page.setTitle("XDAT") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) + +#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) +#set($days = [ 1..31 ]) +#set($years = [ $!turbineUtils.getYear()..1990]) + +#set($qcValues = [["Failed","Failed"],["Failed-needs reprocessing","Failed-needs reprocessing"],["Passed","Passed"],["Passed with edits","Passed with edits"], ["Rerun","Rerun"]]) +#if ($data.message) + $data.message +#end +

+

+ +#if($vr) + Invalid parameters:
$vr.toHTML()
+
+#end + + + + + + + + + + + + +
+ + + + +
+
Freesurfer Details
+
+
+ + + + +
+ + + + + + + + + + +
+
+ #parse("/screens/xnat_edit_experimentData.vm") +
+
#parse("/screens/EditProjectSpecificFields.vm")
+ + + + + + +

FreeSurfer QC
+ + + + + #xdatHiddenBox("fs:fsData/validation/xnat_validationData_id" $item "") + #xdatHiddenBox("fs:fsData/imageSession_ID" $item "") + #xdatHiddenBox("fs:fsData/fsversion" $item "") + #xdatHiddenBox("fs:fsData/procversion" $item "") + #xdatHiddenBox("fs:fsData/validation/validated_by" $item $user.username) + #xdatHiddenBox("fs:fsData/validation/date" $item "") +
Status#cndaSelectBoxSimple("fs:fsData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("fs:fsData/validation/method" $item "" $vr)
Notes#xdatTextArea("fs:fsData/validation/notes" $item "" $vr 10 30)
+
+ +
+
+
+ #xdatEditProps($item $edit_screen) +
+
+ + diff --git a/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm b/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm new file mode 100644 index 00000000..016dc27d --- /dev/null +++ b/dax/xnat_modules/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm @@ -0,0 +1,234 @@ + +$page.setTitle("Freesurfer Analysis Details") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) +#if ($data.getParameters().getString("popup")) + #set ($popup = $data.getParameters().getString("popup") ) + #set ($popup = "false") +#end + + + + + + + + +
+ + + + +
+ Freesurfer Analysis Details +
+
+ + + + + +
+ + #set ($id=".ID") + #set ($field="$om.getImageSessionData().getXSIType()$id") + + #set ($url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$om.getImageSessionData().getXSIType()).addPathInfo('search_field',$field).addPathInfo('search_value',$om.getImageSessionData().getId()).addPathInfo('project',$om.getProject())") + + + + + + + +
Project$!item.getStringProperty("fs:fsData/project")
MRSession$om.getImageSessionData().getLabel()
FS ID$!item.getStringProperty("fs:fsData/label")
FS Date$!item.getProperty("fs:fsData/date")
Note$!item.getStringProperty("fs:fsData/note")
FS Version$!item.getStringProperty("fs:fsData/fsversion")
Proc Version$!item.getStringProperty("fs:fsData/procversion")
+
+ + + + + + + + +
Job Information
Job Status$!item.getStringProperty("fs:fsData/procstatus")
Job ID$!item.getStringProperty("fs:fsData/jobid")
Job Start Date$!item.getStringProperty("fs:fsData/jobstartdate")
Job Node$!item.getStringProperty("fs:fsData/jobnode")
Walltime Used$!item.getStringProperty("fs:fsData/walltimeused")
Mem Used$!item.getStringProperty("fs:fsData/memused")
+
+ + + + + + + +
QC Information
Status$!item.getStringProperty("fs:fsData/validation/status")
Set by$!item.getStringProperty("fs:fsData/validation/validated_by")
Date$!item.getStringProperty("fs:fsData/validation/date")
Method$!item.getStringProperty("fs:fsData/validation/method")
Notes$!item.getStringProperty("fs:fsData/validation/notes")
+
+ #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) +
+
+ +
+
+ +#set ($url = "$link.setPage('Fs_fsData_QC_64.vm').addPathInfo('search_value',$item.getProperty('ID')).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") +View Snapshots + +
+
+ +#set ($scanCounter = 0) + + + Subcortical Segmentation + + +
+ + +
+#set ($scanCounter = 1) + + + Surface Measures + + + + + + +
+ +
+#set ($scanCounter = 2) + + + Processing parameters + + + + + +
+ +
+#set ($scanCounter = 3) + + + Log files + + + + diff --git a/dax/xnat_modules/jar_files/fs_module.jar b/dax/xnat_modules/jar_files/fs_module.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb84413825369245b276836524aa4f1c97f3a9df GIT binary patch literal 47969 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 Q!hZd^e0>~Ms(yU>f4b0my8r+H literal 0 HcmV?d00001 diff --git a/dax/xnat_modules/jar_files/proc_module.jar b/dax/xnat_modules/jar_files/proc_module.jar new file mode 100644 index 0000000000000000000000000000000000000000..7fa80805dc7f9b0e6aac107d776882a6fd9014da GIT binary patch literal 16422 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 + + + + + + + + + + + + '/@WEBAPP/images/r.gif'::text + + + + + + + + + + + + + + + + + COALESCE(@Field2, @Field1) + + + + + + + + + + + + + + + + + + + + + + proc_genprocdata_project_id + + + + + + + + + + + SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS proc_genprocdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH + + + + + + + + + + + + field + SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='proc:genProcData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/proc_module/src/schemas/proc/proc.xsd b/dax/xnat_modules/proc_module/src/schemas/proc/proc.xsd new file mode 100644 index 00000000..8b9a537b --- /dev/null +++ b/dax/xnat_modules/proc_module/src/schemas/proc/proc.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dax/xnat_modules/proc_module/src/scripts/FileViewerProcessing.js b/dax/xnat_modules/proc_module/src/scripts/FileViewerProcessing.js new file mode 100644 index 00000000..d2d23385 --- /dev/null +++ b/dax/xnat_modules/proc_module/src/scripts/FileViewerProcessing.js @@ -0,0 +1,166 @@ +function FileViewerProcessing(_obja){ + //categories.object + this.loading=0; + this.requestRender=false; + this.obja=_obja; + if(this.obja.categories==undefined){ + this.obja.categories=new Object(); + this.obja.categories.ids=new Array(); + } + + if(this.obja.categories["misc"]==undefined || this.obja.categories["misc"]==null){ + this.obja.categories["misc"]=new Object(); + this.obja.categories["misc"].cats=new Array(); + } + + this.init=function(){ + if(this.loading==0){ + this.loading=1; + this.resetCounts(); + var catCallback={ + success:this.processCatalogs, + failure:this.handleFailure, + cache:false, // Turn off caching for IE + scope:this + } + + YAHOO.util.Connect.asyncRequest('GET',this.obja.uri + '/resources?all=true&format=json&file_stats=true&sortBy=category,cat_id,label×tamp=' + (new Date()).getTime(),catCallback,null,this); + }else if(this.loading==1){ + //in process + } + } + + this.handleFailure=function(o){ + closeModalPanel("refresh_file"); + alert("Error loading files"); + } + + this.getAssessor=function(ac, aid){ + var gsAssessors=this.obja.categories[ac]; + if(gsAssessors!=undefined && gsAssessors!=null){ + for(var gsaC=0;gsaC"; + } else { + var callback={ + success:function(oResponse){ + files = (eval("(" + oResponse.responseText + ")")).ResultSet.Result; + if (files.length>0) { + file=files[0]; + var pdfImage=serverRoot+"/images/pdf.gif"; + oResponse.argument.dest.innerHTML=""; + oResponse.argument.dest.innerHTML=""; + } else { + oResponse.argument.dest.innerHTML="No PDF"; + } + }, + failure:function(oResponse){ + }, + argument:{dest:dest} + }; + cat_uri=this.objp.uri + "/resources/" + assessors[aC].cats[acAC].xnat_abstractresource_id; + YAHOO.util.Connect.asyncRequest('GET',cat_uri + '/files?format=json×tamp=' + (new Date()).getTime(),callback,null); + } + } + } + if(pdfFound==false){ + dest.innerHTML="No PDF"; + } + } + } + } + } +} diff --git a/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm b/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm new file mode 100644 index 00000000..7d1392f1 --- /dev/null +++ b/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm @@ -0,0 +1,100 @@ + +$page.setTitle("XDAT") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) + +#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) +#set($days = [ 1..31 ]) +#set($years = [ $!turbineUtils.getYear()..1990]) + +#set($qcValues = [["Bad","Bad"], ["Failed","Failed"], ["Rerun","Rerun"], ["Passed","Passed"], ["Good","Good"], ["OK","OK"]]) +#if ($data.message) +$data.message +#end +

+

+ +#if($vr) + Invalid parameters:
$vr.toHTML()
+
+#end + + + + + + + + + + + + +
+ + + + +
+
Processor Details
+
+
+ + + + +
+ + + + + + + + + + +
+
+ #parse("/screens/xnat_edit_experimentData.vm") +
+
#parse("/screens/EditProjectSpecificFields.vm")
+ + + + + + +

Processor QC
+ + + + + #xdatHiddenBox("proc:genProcData/validation/xnat_validationData_id" $item "") + #xdatHiddenBox("proc:genProcData/imageSession_ID" $item "") + #xdatHiddenBox("proc:genProcData/validation/validated_by" $item $user.username) + #xdatHiddenBox("proc:genProcData/validation/date" $item "") +
Status#cndaSelectBoxSimple("proc:genProcData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("proc:genProcData/validation/method" $item "" $vr)
Notes#xdatTextArea("proc:genProcData/validation/notes" $item "" $vr 10 30)
+
+ +
+
+
+ #xdatEditProps($item $edit_screen) + +
+
+ + diff --git a/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm b/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm new file mode 100644 index 00000000..fa56125a --- /dev/null +++ b/dax/xnat_modules/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm @@ -0,0 +1,406 @@ + +$page.setTitle("Processing Details") +$page.setLinkColor($ui.alink) +$page.setVlinkColor($ui.vlink) +#if ($turbineUtils.GetPassedParameter("popup", $data)) + #set ($popup = $turbineUtils.GetPassedParameter("popup", data) ) + #set ($popup = "false") +#end + + + + + + + + + + +
+ + + + +
+ Processing Details +
+
+ + + + + +
+ + + + + + + + +
Label$!item.getStringProperty("proc:genProcData/label")
Proc Type$!item.getStringProperty("proc:genProcData/proctype")
Proc Version$!item.getStringProperty("proc:genProcData/procversion")
Proc Date$!item.getProperty("proc:genProcData/date")
ID$!item.getStringProperty("proc:genProcData/ID")
Note$!item.getStringProperty("proc:genProcData/note")
Version$!item.getIntegerProperty("proc:genProcData/version")
+
+ + + + + + + + +
Job Information
Job Status$!item.getStringProperty("proc:genProcData/procstatus")
Job ID$!item.getStringProperty("proc:genProcData/jobid")
Job Start Date$!item.getStringProperty("proc:genProcData/jobstartdate")
Job Node$!item.getStringProperty("proc:genProcData/jobnode")
Walltime Used$!item.getStringProperty("proc:genProcData/walltimeused")
Mem Used$!item.getStringProperty("proc:genProcData/memused")
+
+ + + + + + + +
QC Information
Status$!item.getStringProperty("proc:genProcData/validation/status")
Set by$!item.getStringProperty("proc:genProcData/validation/validated_by")
Date$!item.getStringProperty("proc:genProcData/validation/date")
Method$!item.getStringProperty("proc:genProcData/validation/method")
Notes$!item.getStringProperty("proc:genProcData/validation/notes")
+
+ #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) +
+
+ + + #set($xnat_abstractResource_1_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file").size() - 1) + #if($xnat_abstractResource_1_NUM_ROWS>=0) + + + + #end + + #set($xnat_abstractResource_3_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file").size() - 1) + #if($xnat_abstractResource_3_NUM_ROWS>=0) + + + + #end + + #set($xnat_addField_5_NUM_ROWS=$item.getChildItems("proc:genProcData/parameters/addParam").size() - 1) + #if($xnat_addField_5_NUM_ROWS>=0) + + + + #end + + + #set($prov_processStep_7_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep").size() - 1) + #if($prov_processStep_7_NUM_ROWS>=0) + + + + #end + + #set($xnat_experimentData_share_9_NUM_ROWS=$item.getChildItems("proc:genProcData/sharing/share").size() - 1) + #if($xnat_experimentData_share_9_NUM_ROWS>=0) + + + + #end + + #set($xnat_abstractResource_12_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource").size() - 1) + #if($xnat_abstractResource_12_NUM_ROWS>=0) + + + + #end + + + #set($xnat_experimentData_field_14_NUM_ROWS=$item.getChildItems("proc:genProcData/fields/field").size() - 1) + #if($xnat_experimentData_field_14_NUM_ROWS>=0) + + + + #end + + + #set($proc_genProcData_scan_15_NUM_ROWS=$item.getChildItems("proc:genProcData/scans/scan").size() - 1) + #if($proc_genProcData_scan_15_NUM_ROWS>=0) + + + + #end +
+ + + + +
+ #foreach($xnat_abstractResource_1_COUNTER in [0..$xnat_abstractResource_1_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_size")
+
+ + +
+ #set($xnat_abstractResource_tag_2_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_2_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_2_COUNTER in [0..$xnat_abstractResource_tag_2_NUM_ROWS]) + + + + + + +

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+ + +
+ #foreach($xnat_abstractResource_3_COUNTER in [0..$xnat_abstractResource_3_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_size")
+
+
+ #set($xnat_abstractResource_tag_4_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_4_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_4_COUNTER in [0..$xnat_abstractResource_tag_4_NUM_ROWS]) + + + + + + +

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+
+ #foreach($xnat_addField_5_COUNTER in [0..$xnat_addField_5_NUM_ROWS]) + + + + + + +

proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]
+ + + +
addField$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/addField")
name$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/name")
+
+ + #end +
+
+ + + + + + + + +

proc:genProcData/provenance
+ +
+
+
+ #foreach($prov_processStep_7_COUNTER in [0..$prov_processStep_7_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]
+ + + + + + + + + + + + +
program$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program")
program/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/version")
program/arguments$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/arguments")
timestamp$!item.getProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/timestamp")
cvs$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/cvs")
user$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/user")
machine$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/machine")
platform$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform")
platform/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform/version")
compiler$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler")
compiler/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler/version")
+
+
+ #set($prov_processStep_library_8_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library").size() - 1) + #if($prov_processStep_library_8_NUM_ROWS>=0) + #foreach($prov_processStep_library_8_COUNTER in [0..$prov_processStep_library_8_NUM_ROWS]) + + + + + + +

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]
+ + + +
library$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/library")
version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/version")
+
+ + #end + #end +
+
+ + #end +
+
+ +
+
+ #foreach($xnat_experimentData_share_9_COUNTER in [0..$xnat_experimentData_share_9_NUM_ROWS]) + + + + + + +

proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]
+ + + + + + +
share$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/share")
label$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/label")
project$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/project")
visit$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/visit")
protocol$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/protocol")
+
+ + #end +
+
+
+ #foreach($xnat_abstractResource_12_COUNTER in [0..$xnat_abstractResource_12_NUM_ROWS]) + + + + + + + + + +

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]
+ + + + + +
note$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_size")
+
+
+ #set($xnat_abstractResource_tag_13_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag").size() - 1) + #if($xnat_abstractResource_tag_13_NUM_ROWS>=0) + #foreach($xnat_abstractResource_tag_13_COUNTER in [0..$xnat_abstractResource_tag_13_NUM_ROWS]) + + + + + + +

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]
+ + + +
tag$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/name")
+
+ + #end + #end +
+
+ + #end +
+
+
+ #foreach($xnat_experimentData_field_14_COUNTER in [0..$xnat_experimentData_field_14_NUM_ROWS]) + + + + + + +

proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]
+ + + +
field$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/field")
name$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/name")
+
+ + #end +
+
+
+ #foreach($proc_genProcData_scan_15_COUNTER in [0..$proc_genProcData_scan_15_NUM_ROWS]) + + + + + + +

proc:genProcData/scans/scan[$proc_genProcData_scan_15_COUNTER]
+ +
+
+ + #end +
+
+ +
diff --git a/dax/xnat_modules/proc_module/src/templates/screens/proc_genProcData_search.vm b/dax/xnat_modules/proc_module/src/templates/screens/proc_genProcData_search.vm new file mode 100644 index 00000000..6243957f --- /dev/null +++ b/dax/xnat_modules/proc_module/src/templates/screens/proc_genProcData_search.vm @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID + #xdatSearchField($schemaElement $schemaElement.getDisplayField("EXPT_ID")) + Date + #xdatSearchField($schemaElement $schemaElement.getDisplayField("DATE")) + Project + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROJECT")) + Inserted + #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_DATE")) +
Creator + #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_USER")) + procstatus + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCSTATUS")) + proctype + #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCTYPE")) +
diff --git a/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm b/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm new file mode 100644 index 00000000..bba72af3 --- /dev/null +++ b/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm @@ -0,0 +1,157 @@ + + + + + + + +#if($om.getMinimalLoadAssessors().size()>0) + +
Processing
+ + + + + + + + + + + + + #set ($assessorCounter = 3000) + + #foreach ($proc in $om.getChildItems("assessors/assessor")) + #set ($procDate = "") + #set ($xsiType = $!proc.getXSIType()) + #set ($procType = $!proc.getXSIType()) + #set ($procDate = $!proc.getProperty("date")) + #set ($procID = $!proc.getProperty("ID")) + #set ($procLabel = $!proc.getProperty("label")) + #set ($procField = "${procType}.ID") + #set ($procurl = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) + #set ($editprocurl = "$link.setPage('XDATScreen_edit_proc_genProcData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','proc:genProcData').addPathInfo('search_field','proc:genProcData.ID')") + #set ($editfsprocurl = "$link.setPage('XDATScreen_edit_fs_fsData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") + #set ($pdfImage = $content.getURI("images/pdf.gif")) + + #set ($procStatus = "") + #if ($procType == 'proc:genProcData' || $procType == 'fs:fsData') + #set ($procStatus = $!proc.getProperty("procstatus")) + #end + + #set ($qcStatus = $!proc.getProperty("xnat:experimentData.validation/status")) + + + + + + + + + + #if($xsiType == 'proc:genProcData') + #if($qcStatus == 'Needs QA') + + #else + + #end + #elseif ($xsiType == 'fs:fsData') + #if($qcStatus == 'Needs QA') + + #else + + #end + #end + + + + + + #set ($assessorCounter= $assessorCounter + 1) + #end +
TypePDFProc DateProc IDJob StatusQC StatusFiles
+ + + + + #if($proc.canRead($user)) + #set ( $url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) + #if($proc.getHeader()) + $!proc.getHeader() + #elseif ($procType == 'xnat:qcAssessmentData') + #set ($qcType = $!proc.getProperty("type")) + $qcType + #elseif ($procType == 'proc:genProcData') + #set ($procType = $!proc.getProperty("proctype")) + $procType + #else + $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) + #end + #else + #if($proc.getHeader()) + $!proc.getHeader() + #elseif ($procType == 'xnat:qcAssessmentData') + #set ($qcType = $!proc.getProperty("type")) + $qcType + #elseif ($procType == 'proc:genProcData') + #set ($procType = $!proc.getProperty("proctype")) + $procType + #else + $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) + #end + #end + +
...
+
$!procDate$!procLabel$!procStatus$!qcStatus$!qcStatus$!qcStatus$!qcStatus + +
+ +
+ +#end diff --git a/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm b/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm new file mode 100644 index 00000000..0bbcfbac --- /dev/null +++ b/dax/xnat_modules/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm @@ -0,0 +1,228 @@ + +#if($project) + +#else + #set($project=$om.getProject()) +#end + + +#set($subject = $mr.getSubjectData()) +#if($item.needsActivation()) +
This session is in quarantine.    Activate

+#end +#addCustomScreens($om.getXSIType() "report/errors") +#parse($turbineUtils.getTemplateName("_title",$om.getXSIType(),$project)) +#if($project) + +#else +#set($project=$mr.getProject()) +#end +
+ +#addCustomScreens($om.getXSIType() "report/alert") +#parse("/screens/workflow_alert.vm") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #set ($scanCounter = 101) + #parse($turbineUtils.getTemplateName("_reconstructions",$om.getXSIType(),$project)) + + + + + + + #set ($scanCounter = 202) + + + + + + +
+ #parse($turbineUtils.getTemplateName("_details",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postDetails") +
+ #parse("/screens/ReportProjectSpecificFields.vm") +
+ #parse("/screens/qc_summary.vm") +
+ #addCustomScreens($om.getXSIType() "report/preScans") +
+

+ #parse($turbineUtils.getTemplateName("_scans",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postScans") +
+ #parse($turbineUtils.getTemplateName("_assessments",$om.getXSIType(),$project)) +
+ #addCustomScreens($om.getXSIType() "report/postAssessments") +

+ #addCustomScreens($om.getXSIType() "report/postRecons") +
+ #parse("/screens/workflow_summary.vm") +
+ #addCustomScreens($om.getXSIType() "report/postWorkflowSummary") +
+ + + + + + + From 8e294f6c4de4eecb5316a1633efdd970f4b9f7c4 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 10:52:24 +0100 Subject: [PATCH 35/62] removing the previous files --- dax/xnat_modules/default_proc/proc_module.jar | Bin 16422 -> 0 bytes .../default_proc/proc_module/rebuild_proc.sh | 1 - .../proc/display/proc_genProcData_display.xml | 212 - .../proc_module/src/schemas/proc/proc.xsd | 42 - .../src/scripts/FileViewerProcessing.js | 166 - .../src/scripts/FileViewerProcessingPdf.js | 154 - .../XDATScreen_edit_proc_genProcData.vm | 100 - .../XDATScreen_report_proc_genProcData.vm | 406 -- .../screens/proc_genProcData_search.vm | 42 - .../xnat_imageSessionData_assessments.vm | 157 - .../xnat_imageSessionData_report.vm | 228 - dax/xnat_modules/freesurfer/fs_module.jar | Bin 47969 -> 0 bytes .../freesurfer/fs_module/rebuild_fs.sh | 1 - .../modules/screens/Fs_fsData_QC_64.java | 26 - .../screens/XDATScreen_edit_fs_fsData.java | 33 - .../schemas/fs/display/fs_fsData_display.xml | 5137 ----------------- .../fs/display/fs_longFSData_display.xml | 224 - .../fs_module/src/schemas/fs/fs.xsd | 332 -- .../fs_module/src/scripts/slideshow.js | 403 -- .../src/templates/layouts/Fs_fsData_QC_64.vm | 94 - .../src/templates/screens/Fs_fsData_QC_64.vm | 185 - .../screens/XDATScreen_edit_fs_fsData.vm | 95 - .../screens/XDATScreen_report_fs_fsData.vm | 234 - 23 files changed, 8272 deletions(-) delete mode 100644 dax/xnat_modules/default_proc/proc_module.jar delete mode 100755 dax/xnat_modules/default_proc/proc_module/rebuild_proc.sh delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/schemas/proc/display/proc_genProcData_display.xml delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessingPdf.js delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm delete mode 100644 dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm delete mode 100644 dax/xnat_modules/freesurfer/fs_module.jar delete mode 100755 dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm delete mode 100644 dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm diff --git a/dax/xnat_modules/default_proc/proc_module.jar b/dax/xnat_modules/default_proc/proc_module.jar deleted file mode 100644 index 7fa80805dc7f9b0e6aac107d776882a6fd9014da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16422 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 - - - - - - - - - - - - '/@WEBAPP/images/r.gif'::text - - - - - - - - - - - - - - - - - COALESCE(@Field2, @Field1) - - - - - - - - - - - - - - - - - - - - - - proc_genprocdata_project_id - - - - - - - - - - - SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS proc_genprocdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH - - - - - - - - - - - - field - SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='proc:genProcData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd b/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd deleted file mode 100644 index 8b9a537b..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/schemas/proc/proc.xsd +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js b/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js deleted file mode 100644 index d2d23385..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/scripts/FileViewerProcessing.js +++ /dev/null @@ -1,166 +0,0 @@ -function FileViewerProcessing(_obja){ - //categories.object - this.loading=0; - this.requestRender=false; - this.obja=_obja; - if(this.obja.categories==undefined){ - this.obja.categories=new Object(); - this.obja.categories.ids=new Array(); - } - - if(this.obja.categories["misc"]==undefined || this.obja.categories["misc"]==null){ - this.obja.categories["misc"]=new Object(); - this.obja.categories["misc"].cats=new Array(); - } - - this.init=function(){ - if(this.loading==0){ - this.loading=1; - this.resetCounts(); - var catCallback={ - success:this.processCatalogs, - failure:this.handleFailure, - cache:false, // Turn off caching for IE - scope:this - } - - YAHOO.util.Connect.asyncRequest('GET',this.obja.uri + '/resources?all=true&format=json&file_stats=true&sortBy=category,cat_id,label×tamp=' + (new Date()).getTime(),catCallback,null,this); - }else if(this.loading==1){ - //in process - } - } - - this.handleFailure=function(o){ - closeModalPanel("refresh_file"); - alert("Error loading files"); - } - - this.getAssessor=function(ac, aid){ - var gsAssessors=this.obja.categories[ac]; - if(gsAssessors!=undefined && gsAssessors!=null){ - for(var gsaC=0;gsaC"; - } else { - var callback={ - success:function(oResponse){ - files = (eval("(" + oResponse.responseText + ")")).ResultSet.Result; - if (files.length>0) { - file=files[0]; - var pdfImage=serverRoot+"/images/pdf.gif"; - oResponse.argument.dest.innerHTML=""; - oResponse.argument.dest.innerHTML=""; - } else { - oResponse.argument.dest.innerHTML="No PDF"; - } - }, - failure:function(oResponse){ - }, - argument:{dest:dest} - }; - cat_uri=this.objp.uri + "/resources/" + assessors[aC].cats[acAC].xnat_abstractresource_id; - YAHOO.util.Connect.asyncRequest('GET',cat_uri + '/files?format=json×tamp=' + (new Date()).getTime(),callback,null); - } - } - } - if(pdfFound==false){ - dest.innerHTML="No PDF"; - } - } - } - } - } -} diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm deleted file mode 100644 index 7d1392f1..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_edit_proc_genProcData.vm +++ /dev/null @@ -1,100 +0,0 @@ - -$page.setTitle("XDAT") -$page.setLinkColor($ui.alink) -$page.setVlinkColor($ui.vlink) - -#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) -#set($days = [ 1..31 ]) -#set($years = [ $!turbineUtils.getYear()..1990]) - -#set($qcValues = [["Bad","Bad"], ["Failed","Failed"], ["Rerun","Rerun"], ["Passed","Passed"], ["Good","Good"], ["OK","OK"]]) -#if ($data.message) -$data.message -#end -

-

- -#if($vr) - Invalid parameters:
$vr.toHTML()
-
-#end - - - - - - - - - - - - -
- - - - -
-
Processor Details
-
-
- - - - -
- - - - - - - - - - -
-
- #parse("/screens/xnat_edit_experimentData.vm") -
-
#parse("/screens/EditProjectSpecificFields.vm")
- - - - - - -

Processor QC
- - - - - #xdatHiddenBox("proc:genProcData/validation/xnat_validationData_id" $item "") - #xdatHiddenBox("proc:genProcData/imageSession_ID" $item "") - #xdatHiddenBox("proc:genProcData/validation/validated_by" $item $user.username) - #xdatHiddenBox("proc:genProcData/validation/date" $item "") -
Status#cndaSelectBoxSimple("proc:genProcData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("proc:genProcData/validation/method" $item "" $vr)
Notes#xdatTextArea("proc:genProcData/validation/notes" $item "" $vr 10 30)
-
- -
-
-
- #xdatEditProps($item $edit_screen) - -
-
- - diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm deleted file mode 100644 index fa56125a..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/XDATScreen_report_proc_genProcData.vm +++ /dev/null @@ -1,406 +0,0 @@ - -$page.setTitle("Processing Details") -$page.setLinkColor($ui.alink) -$page.setVlinkColor($ui.vlink) -#if ($turbineUtils.GetPassedParameter("popup", $data)) - #set ($popup = $turbineUtils.GetPassedParameter("popup", data) ) - #set ($popup = "false") -#end - - - - - - - - - - -
- - - - -
- Processing Details -
-
- - - - - -
- - - - - - - - -
Label$!item.getStringProperty("proc:genProcData/label")
Proc Type$!item.getStringProperty("proc:genProcData/proctype")
Proc Version$!item.getStringProperty("proc:genProcData/procversion")
Proc Date$!item.getProperty("proc:genProcData/date")
ID$!item.getStringProperty("proc:genProcData/ID")
Note$!item.getStringProperty("proc:genProcData/note")
Version$!item.getIntegerProperty("proc:genProcData/version")
-
- - - - - - - - -
Job Information
Job Status$!item.getStringProperty("proc:genProcData/procstatus")
Job ID$!item.getStringProperty("proc:genProcData/jobid")
Job Start Date$!item.getStringProperty("proc:genProcData/jobstartdate")
Job Node$!item.getStringProperty("proc:genProcData/jobnode")
Walltime Used$!item.getStringProperty("proc:genProcData/walltimeused")
Mem Used$!item.getStringProperty("proc:genProcData/memused")
-
- - - - - - - -
QC Information
Status$!item.getStringProperty("proc:genProcData/validation/status")
Set by$!item.getStringProperty("proc:genProcData/validation/validated_by")
Date$!item.getStringProperty("proc:genProcData/validation/date")
Method$!item.getStringProperty("proc:genProcData/validation/method")
Notes$!item.getStringProperty("proc:genProcData/validation/notes")
-
- #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) -
-
- - - #set($xnat_abstractResource_1_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file").size() - 1) - #if($xnat_abstractResource_1_NUM_ROWS>=0) - - - - #end - - #set($xnat_abstractResource_3_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file").size() - 1) - #if($xnat_abstractResource_3_NUM_ROWS>=0) - - - - #end - - #set($xnat_addField_5_NUM_ROWS=$item.getChildItems("proc:genProcData/parameters/addParam").size() - 1) - #if($xnat_addField_5_NUM_ROWS>=0) - - - - #end - - - #set($prov_processStep_7_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep").size() - 1) - #if($prov_processStep_7_NUM_ROWS>=0) - - - - #end - - #set($xnat_experimentData_share_9_NUM_ROWS=$item.getChildItems("proc:genProcData/sharing/share").size() - 1) - #if($xnat_experimentData_share_9_NUM_ROWS>=0) - - - - #end - - #set($xnat_abstractResource_12_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource").size() - 1) - #if($xnat_abstractResource_12_NUM_ROWS>=0) - - - - #end - - - #set($xnat_experimentData_field_14_NUM_ROWS=$item.getChildItems("proc:genProcData/fields/field").size() - 1) - #if($xnat_experimentData_field_14_NUM_ROWS>=0) - - - - #end - - - #set($proc_genProcData_scan_15_NUM_ROWS=$item.getChildItems("proc:genProcData/scans/scan").size() - 1) - #if($proc_genProcData_scan_15_NUM_ROWS>=0) - - - - #end -
- - - - -
- #foreach($xnat_abstractResource_1_COUNTER in [0..$xnat_abstractResource_1_NUM_ROWS]) - - - - - - - - - -

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]
- - - - - -
note$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/file_size")
-
- - -
- #set($xnat_abstractResource_tag_2_NUM_ROWS=$item.getChildItems("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag").size() - 1) - #if($xnat_abstractResource_tag_2_NUM_ROWS>=0) - #foreach($xnat_abstractResource_tag_2_COUNTER in [0..$xnat_abstractResource_tag_2_NUM_ROWS]) - - - - - - -

proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]
- - - -
tag$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/in/file[$xnat_abstractResource_1_COUNTER]/tags/tag[$xnat_abstractResource_tag_2_COUNTER]/name")
-
- - #end - #end -
-
- - #end -
-
- - -
- #foreach($xnat_abstractResource_3_COUNTER in [0..$xnat_abstractResource_3_NUM_ROWS]) - - - - - - - - - -

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]
- - - - - -
note$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/file_size")
-
-
- #set($xnat_abstractResource_tag_4_NUM_ROWS=$item.getChildItems("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag").size() - 1) - #if($xnat_abstractResource_tag_4_NUM_ROWS>=0) - #foreach($xnat_abstractResource_tag_4_COUNTER in [0..$xnat_abstractResource_tag_4_NUM_ROWS]) - - - - - - -

proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]
- - - -
tag$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/out/file[$xnat_abstractResource_3_COUNTER]/tags/tag[$xnat_abstractResource_tag_4_COUNTER]/name")
-
- - #end - #end -
-
- - #end -
-
-
- #foreach($xnat_addField_5_COUNTER in [0..$xnat_addField_5_NUM_ROWS]) - - - - - - -

proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]
- - - -
addField$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/addField")
name$!item.getStringProperty("proc:genProcData/parameters/addParam[$xnat_addField_5_COUNTER]/name")
-
- - #end -
-
- - - - - - - - -

proc:genProcData/provenance
- -
-
-
- #foreach($prov_processStep_7_COUNTER in [0..$prov_processStep_7_NUM_ROWS]) - - - - - - - - - -

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]
- - - - - - - - - - - - -
program$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program")
program/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/version")
program/arguments$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/program/arguments")
timestamp$!item.getProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/timestamp")
cvs$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/cvs")
user$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/user")
machine$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/machine")
platform$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform")
platform/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/platform/version")
compiler$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler")
compiler/version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/compiler/version")
-
-
- #set($prov_processStep_library_8_NUM_ROWS=$item.getChildItems("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library").size() - 1) - #if($prov_processStep_library_8_NUM_ROWS>=0) - #foreach($prov_processStep_library_8_COUNTER in [0..$prov_processStep_library_8_NUM_ROWS]) - - - - - - -

proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]
- - - -
library$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/library")
version$!item.getStringProperty("proc:genProcData/provenance/processStep[$prov_processStep_7_COUNTER]/library[$prov_processStep_library_8_COUNTER]/version")
-
- - #end - #end -
-
- - #end -
-
- -
-
- #foreach($xnat_experimentData_share_9_COUNTER in [0..$xnat_experimentData_share_9_NUM_ROWS]) - - - - - - -

proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]
- - - - - - -
share$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/share")
label$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/label")
project$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/project")
visit$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/visit")
protocol$!item.getStringProperty("proc:genProcData/sharing/share[$xnat_experimentData_share_9_COUNTER]/protocol")
-
- - #end -
-
-
- #foreach($xnat_abstractResource_12_COUNTER in [0..$xnat_abstractResource_12_NUM_ROWS]) - - - - - - - - - -

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]
- - - - - -
note$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/note")
label$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/label")
file_count$!item.getIntegerProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_count")
file_size$!item.getProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/file_size")
-
-
- #set($xnat_abstractResource_tag_13_NUM_ROWS=$item.getChildItems("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag").size() - 1) - #if($xnat_abstractResource_tag_13_NUM_ROWS>=0) - #foreach($xnat_abstractResource_tag_13_COUNTER in [0..$xnat_abstractResource_tag_13_NUM_ROWS]) - - - - - - -

proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]
- - - -
tag$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/tag")
name$!item.getStringProperty("proc:genProcData/resources/resource[$xnat_abstractResource_12_COUNTER]/tags/tag[$xnat_abstractResource_tag_13_COUNTER]/name")
-
- - #end - #end -
-
- - #end -
-
-
- #foreach($xnat_experimentData_field_14_COUNTER in [0..$xnat_experimentData_field_14_NUM_ROWS]) - - - - - - -

proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]
- - - -
field$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/field")
name$!item.getStringProperty("proc:genProcData/fields/field[$xnat_experimentData_field_14_COUNTER]/name")
-
- - #end -
-
-
- #foreach($proc_genProcData_scan_15_COUNTER in [0..$proc_genProcData_scan_15_NUM_ROWS]) - - - - - - -

proc:genProcData/scans/scan[$proc_genProcData_scan_15_COUNTER]
- -
-
- - #end -
-
- -
diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm deleted file mode 100644 index 6243957f..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/proc_genProcData_search.vm +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ID - #xdatSearchField($schemaElement $schemaElement.getDisplayField("EXPT_ID")) - Date - #xdatSearchField($schemaElement $schemaElement.getDisplayField("DATE")) - Project - #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROJECT")) - Inserted - #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_DATE")) -
Creator - #xdatSearchField($schemaElement $schemaElement.getDisplayField("INSERT_USER")) - procstatus - #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCSTATUS")) - proctype - #xdatSearchField($schemaElement $schemaElement.getDisplayField("PROCTYPE")) -
diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm deleted file mode 100644 index bba72af3..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_assessments.vm +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - -#if($om.getMinimalLoadAssessors().size()>0) - -
Processing
- - - - - - - - - - - - - #set ($assessorCounter = 3000) - - #foreach ($proc in $om.getChildItems("assessors/assessor")) - #set ($procDate = "") - #set ($xsiType = $!proc.getXSIType()) - #set ($procType = $!proc.getXSIType()) - #set ($procDate = $!proc.getProperty("date")) - #set ($procID = $!proc.getProperty("ID")) - #set ($procLabel = $!proc.getProperty("label")) - #set ($procField = "${procType}.ID") - #set ($procurl = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) - #set ($editprocurl = "$link.setPage('XDATScreen_edit_proc_genProcData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','proc:genProcData').addPathInfo('search_field','proc:genProcData.ID')") - #set ($editfsprocurl = "$link.setPage('XDATScreen_edit_fs_fsData.vm').addPathInfo('search_value',$procID).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") - #set ($pdfImage = $content.getURI("images/pdf.gif")) - - #set ($procStatus = "") - #if ($procType == 'proc:genProcData' || $procType == 'fs:fsData') - #set ($procStatus = $!proc.getProperty("procstatus")) - #end - - #set ($qcStatus = $!proc.getProperty("xnat:experimentData.validation/status")) - - - - - - - - - - #if($xsiType == 'proc:genProcData') - #if($qcStatus == 'Needs QA') - - #else - - #end - #elseif ($xsiType == 'fs:fsData') - #if($qcStatus == 'Needs QA') - - #else - - #end - #end - - - - - - #set ($assessorCounter= $assessorCounter + 1) - #end -
TypePDFProc DateProc IDJob StatusQC StatusFiles
- - - - - #if($proc.canRead($user)) - #set ( $url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$!proc.getXSIType()).addPathInfo('search_field',$procField).addPathInfo('search_value',$procID).addPathInfo('popup',$popup).addPathInfo('project',$!project)" ) - #if($proc.getHeader()) - $!proc.getHeader() - #elseif ($procType == 'xnat:qcAssessmentData') - #set ($qcType = $!proc.getProperty("type")) - $qcType - #elseif ($procType == 'proc:genProcData') - #set ($procType = $!proc.getProperty("proctype")) - $procType - #else - $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) - #end - #else - #if($proc.getHeader()) - $!proc.getHeader() - #elseif ($procType == 'xnat:qcAssessmentData') - #set ($qcType = $!proc.getProperty("type")) - $qcType - #elseif ($procType == 'proc:genProcData') - #set ($procType = $!proc.getProperty("proctype")) - $procType - #else - $user.getDisplayManager().getDisplayNameForElement($proc.getXSIType()) - #end - #end - -
...
-
$!procDate$!procLabel$!procStatus$!qcStatus$!qcStatus$!qcStatus$!qcStatus - -
- -
- -#end diff --git a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm b/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm deleted file mode 100644 index 0bbcfbac..00000000 --- a/dax/xnat_modules/default_proc/proc_module/src/templates/screens/xnat_imageSessionData/xnat_imageSessionData_report.vm +++ /dev/null @@ -1,228 +0,0 @@ - -#if($project) - -#else - #set($project=$om.getProject()) -#end - - -#set($subject = $mr.getSubjectData()) -#if($item.needsActivation()) -
This session is in quarantine.    Activate

-#end -#addCustomScreens($om.getXSIType() "report/errors") -#parse($turbineUtils.getTemplateName("_title",$om.getXSIType(),$project)) -#if($project) - -#else -#set($project=$mr.getProject()) -#end -
- -#addCustomScreens($om.getXSIType() "report/alert") -#parse("/screens/workflow_alert.vm") - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #set ($scanCounter = 101) - #parse($turbineUtils.getTemplateName("_reconstructions",$om.getXSIType(),$project)) - - - - - - - #set ($scanCounter = 202) - - - - - - -
- #parse($turbineUtils.getTemplateName("_details",$om.getXSIType(),$project)) -
- #addCustomScreens($om.getXSIType() "report/postDetails") -
- #parse("/screens/ReportProjectSpecificFields.vm") -
- #parse("/screens/qc_summary.vm") -
- #addCustomScreens($om.getXSIType() "report/preScans") -
-

- #parse($turbineUtils.getTemplateName("_scans",$om.getXSIType(),$project)) -
- #addCustomScreens($om.getXSIType() "report/postScans") -
- #parse($turbineUtils.getTemplateName("_assessments",$om.getXSIType(),$project)) -
- #addCustomScreens($om.getXSIType() "report/postAssessments") -

- #addCustomScreens($om.getXSIType() "report/postRecons") -
- #parse("/screens/workflow_summary.vm") -
- #addCustomScreens($om.getXSIType() "report/postWorkflowSummary") -
- - - - - - - diff --git a/dax/xnat_modules/freesurfer/fs_module.jar b/dax/xnat_modules/freesurfer/fs_module.jar deleted file mode 100644 index cb84413825369245b276836524aa4f1c97f3a9df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47969 zcmb5V1yEgGlQzo1_27PjyN3`gxVw9BNpN>}cP9|sf_rdx5+F#B5S-xdem8l)`DbeG z%y;ik6;)5I(`)U$PxpGdpWf>z$-=bBzgr;v%fiyg)#%@tq5W4gJI9az#uW3v zo7($N1D3_duC895snD2p0!a=aQ*(3&60`v8iw5eX?KxUQw29Ktk6fo4(aTz?wgU)-L zM#ey4tU|v0B0gy>J+ARL)|(p0hy8NI-&lR&e@c8K>@eLvcM^GTz^UT1+H!~4f_Noe z_swp#$vkVS9e-4N@KuxrK5LESxcKIQfTv>9DTA>zIQ$dr2=Cd2j2~6yCDraa-ez~W?Il5HD-)EcShqJuaN7p1<5|QbC;*3P4 zy3KV}NjF$nTfy=wztOK-)pad)`MWx@sx^Pazbn;gFX!(N=Acz!OYuueGZwBLi>=7< zLSKHL#(k@p>X9t93vQoo^0=n!oG%6qxey7o!(*Ts-ZAP|s*5piMVsMox3m3}6HM9} zElV_e$nv{@D!F%%kr-tYENDkTdqwcT@Q#jR7H&-9T4P6N`ou&Dezt=zz4^mC;VcV0wYU}pRjh9MS#B!*+@EG(3y`&h}=B(d8 zfp~fk5cvPj-KhVHCnpngGaI9SM_B0p&GN&)Gsgda8=G1<*;^ZV{H4VIIkuVp_euXJ zXbt|g42!#s^N z{zn`pk!6nOe!~E&pPGW5B0);YbTWq5$&-nK@=Z1^ba)c zreNn?AJ@k<$0pD4)EwWNKel&A4=Y`_U4Hk62CVs)=X^IVKB=e%Rb9_@vB1X`^&U@8 zm-`03w_CHUe!h*7f*nuOq)#V9bAoy?H1#F+m|2ozmo!@Ay>{b?rz@U`l4>wjSCDa-_Vgf{j&2rpVQ}i_nzkI;Y8k!oluU3YvW>L z<)N`lhe>11O_|$|JBq~j=EKSK;f1gJ>GuV`Q&-=obdpj5pYMwYA0WC*=YzXFYu{ar zp6BKwSm%p=ExYp`pxb%PO*_Z-xVyh?&OQSdn`FE_T7L4G{Cea5BNH6{efCD+KAEeO zHXk;TR@Mv!BZohvN0fjzCuE;vyOZZ0Qdtmp4tq(nO!K7<9OQn5qn2a3+)aqjv1amQjGgZeKr>Ke%pR?b^S~W zlU2c?Ta^?dPkNd{FPztikSU)0~v2MuY{M9oYNx8QK-8Tn%-eiWu?kLTA- z%#CC(r~+64OFT+PyrvjshfodBCpdbWHFC;}_^Rv0?`voI%G_B`_XCPI1)B;jd=G8~ z*23aNHf7OvB^p2LqbR7_yL4<-61lnrXmhHcy`H|WboxA!3WArfZ0!s_7R*&|Xy)V( z*>yepV*4&UT)NnvR*!QCP_D=y8C(QcK(%Fug?vOBzMyD&`anxO$hBK!arRxCUC};U z(g&Nibz-)0LiuLw@+fKKu}!*H^tkgAC;y_s_pedZS``6p1*<09E4RFR9j~HwxcBUf zN;5VUo236_lvEehm--elpK$rsXcXE;(Q9Ow}BM<K7;M>`Xa1*FBE{A~N&zqXdbk<4Ak?K@}R zLq>frCiS|U4Z4s8&*`5wU3N?Pot`&_#(LaW?WbsX5=s_VXo8eQ&K3sj*dKmHJRkju8fNgn&*#4gV%v~tj zsY^?262Z9C4E&faO^Rj-{AyZY-Y`%k2K&rhnncX+pyUOC;~jA8U>u&yUXq5Yc`(y57nw^I%Gt8S9XKbJ&GfexOKOx zektbZtV5!3{N@3+-}0j3Vp*2adEtN6CLF@eZ64VmA3io;zkyEEU6{IE8S1GX5|zp_ z2RV7ZIgCM#pPr>jC&j05%u|Qh4Mj|~WiLmEbzmZGIYH#G4Kz-btFwzqE31q8eC;ka zw(NPE_vA~0UOO4ZeCT-?Dlx~_hs%^FAiZZ8Yo5MKw4x;cDIU0^FveIP1Fa6*5ajo~ zeL4`f2~jkRgGWLTM3Y#Jn#$P-J4cT|AK^Vec{<;d>U;jcmpH%|e7ryBfojB3I^u@}9H&7Fi=er8zJ<{vKXZ0PKTUXSd>r4x6 zJ6}XO*;=)vTa!n&RfG9@(|Azh{-#84?a9oOe(tQxI=kVg*okXtZs=r8ne!Sp}Z;EvP=Hy*k>YGT9ewPtOH!7BR3IPz=ru_`xSIFVA$BWh8o z*RX<8RsX`tXA8!~wIEP(O@U1q?8PMcj*@rRlm%Q{*>mxFJ-9M zZhFdB_tzc!yM}!2gv9FH{HeN?8|JwC41JTk#UTXqGE(Yu#*msI4U=Y$s-bv6akvHh z`R$5aaYAEt^%TMqpOgI2Xz21{4pp}f!``!K!?G_EGkT=yg%YB(I4yOF=iH8o}F?4?7hI67_8ObSblD2Q>&P1q|DOt=Xm> zOqOOJ%D&r9`Ht}MwfSbdWJKr{=geZ%Tcq_oMoyh&x?kb4dX2xFm#)7Vm2vl0Rwg@* z-y4^Rze3PeHRD>k3YD|u3$6GvNo;#B!YL~NU0HGTrs^J=3kRydQXW1%n=9DI>rHJ` zz^_@ITB6dW>tvWMSdG;ZGDJhFxIDzNOKoYTA72!)G3GiH$%S#%Cf|-i_xae}WU)aR z%@w28Y&?|`+CV8;VI#~t*v+)_mD)4TAk28!9aMo_FuyfSKbL#bD9^SxXati zc&?`Fbmzk~SVBGD*;PJz?)zqbVx99UYFus`AA75B;d5Pe*wk9pRQ$DcJ5{HuDfa&7 z$;i8UXWE?IviS(n7?jJ+SK@_jOdkWdt=}r7Qi*flim4tlL#z|OOBBfqOsg9*(q^vq zZgHR`XES_in?nSbWza+Ti`d<&ksvw*NpWhkeNzK8xl)&z?bGTP$mn|HG4RL59lp;; zdxxu@Q^e?=5?jO}ahd1K)=hfesA>D>WMCM*l*!=91{R_>GkKbNZ(HI?8bUvTS0hIq z%1V2YkM47n8}1x$)YVNe0|gOERqBy)iyhC$zxspAc~SJ_Q?@@}hbiDdA?PPj#6#U+ z`_DoL8Kih(JlMfL?`>b>cO+0z;&u6YBK{$Q6I=V5<~j^)>N_}5+^>CBA;vZeG&m4T zY{cP@)o+5+;NbLq0{w3eLoyOTX8tZnP&>7xYV`+cN-ntGJGJ;~P2cbhXK~#R8u1OQ zDz@D(ah*4vv6~;4_3p+QJCm=2Z0mpi^e; zH)|&%dNfX;D_Wry+OI&?smJUMWo29!b0{UsZL(QqG5|!N)oey7T-@WlT0me{ZFH*H zi{x}{!Tj0de&Wg|Q}wjU%pwAZzHws0t*F62p`Y*A=@k{(8#!)#R(8B3H{P&Q{UmaN zUJa)u$!$g!Unx&N?7o)PL9%D41VOpq78e+~(zNRX16aI$J1lA8MS1XJyls3hdWe55_Nr2PJ z5@5uAjQ%+Z54N3GuLtUc)?XQipi6+q=xzn}Y3t_j}0(Xsu}ideAoOQT0fuy%2iRLuRB-e8~sJ9WEhmXI$jgA zgN!taFiTfD(|LTLl!2{UeB3!qXawb7t_l~rFK>@ty%OU&eKFwEPDQ{%Iw9FZ(hbrqLI_{! zj7NLxPhOq~({HCZoJAm%+xP|4=cc$CjpyGy8v)w$#Ga2>Gh8C>xvqZ`Nftmd*aPWs z)X!jI^S=p);f;Vn+jD`&UJELR>qC%ulfKD-4dx5ipe1IckfWHPM?#WfWS3L#DGX+? z=n*j=3Lt+&09La=!xLcybN@D~%a!*=1iaRRh#7?FVi_#?BRFh7bDy-D#jmr2P+t*Y zE@{n~8^czgNptL+w0b~EUI_}Zlvd2z2AW`19%$;t!dN&( zD;tXv(@s7WUV?y!WG~1V3(Egn77`087*voYJsL2~K6{uJ12`z!EG)Ef= zV^kbVs?He3IQ~chUB~;(t)pR0C-gQN<7WDxnQ139A=j#si6)hgm6bR^u^Z zPTxO+!C+NgbFOweW_4NKOEbtSFWHVOf><^rh3|T?JpR~Py!39&ov^M?^VHj-DtsH( zvV3jQBnLaFdX-1Z2M*$O2$N2~B5v-YZns*EuTbxb&+U?8yIPH|&}6?YH9KpwS&yz$ zWqI7a$GAATMWa=c)}eg7XY2T`vnAz|iF{6=N6mcIgx$t${a~>cY_KBrkm?LpZf6a# z1HZcuEeV@h_EcHLk`t6pmX7sl2~H_Ch%X$EBR#QO3Pyd(-=Pc5QT85Rgt!la4z|DBujS| zM&)=W7F0FI82$Li5t<^mrEpX2cj^&z>fP~$)iqjV?R*Uj@y%u^^(tKDAf;70WeS)Mg1sZ9nD4`ejg3Rk z>Melr^04jR$^%`Zqc-^IbZ;qxF5{3I{3N;$K>^tA+=irz@Z9`(_Rw*#4c;WHe_VMF zu35u6B5t|6zn{~5`h1;}Z&-O?0kz|z`WhPWf0+vcctLm;UYE!URV396cxCpCHqnr%s7h+NIB(huY0OJL9_txL;)(Q$>E@_XR-kESne=WqUTw2azs( z-hMoXm-lX(c1igwFNt!OL^3CvbGu`~y6q-iD(!Ekq|O5UXh_U_353>~dIx@UpO1Xq zX4ysR$}MS74cv|9ryuE+sG&_Un9YR}{S{%}P6^oqfk21jeqjk4wCam;Atq3B^L7Lg zQv?NEQ@Tp0M9o44`<zPbgavdr*UkSE&Nw+=8L$rzTMR_uFvd`aE>>#vQ>WGk(_I{>NN}IRvd=HTbkD`UzRd> zKM>&RMzQKX(+ONCVNZqBJj)@ zB>I8KbPu7#C{R4rVml0gXrP?}=927GsYD32cU&90t0kVFXB4#%yGk{rc#>1s&AFmb zuuBTVN7+bKQMVLkc5<@}I*<{2%~MP-TWPmN>eqXe7Eg`lc*Kp()w!X>WQi(Ti*tp` z^Fd^bKa@&LfUL?$09*Kq@NKKvP{@Y?Xa|mh^|KG&Z`zw*q4~DH$)WoF`n8wNK>5zv zg9nN40)tm{GH8ufc@?J-Hp`!z+<`xkU6{naE_kv`Au0WZFWQO7ap;mMAOK&mQ3MwU zu)`TQufTVF;ivO7>+Q4eg7egH#CW*7fQQM0L&%!y28;=50wqv&!FG0bcOB*Lm5p>I zCML?YYuq*HS#zKD*P-PMC94cHSG7p=)w?fwz;T)q3TUFwb z`?gH(h)yexi$yA-9i=Ipu3|=&lfA9 zrn{m$$91rbS*Oc9>vov>+5-vSmgb|*1tS6ZO_=8E3d*cR%;BFjA5HlV6&3V&oCbPE&$A*7E&q@!JTo+5*!~D^(9jq=0&A3Mu52x()ft$V`yFd|r#GmN& zU+M9~`;%A1Uwgbs_^ngk!VhJ8efiwG2(8ss4C;B;9!rnE-5@Jnz}XnsarI8!U0p@w zXNhR(wr>q#hjNH^TCb3RSN_`+u@H?kS0RD>JhQhV5t^SF$b9dO{*?KFv<*6jY`H|e zxeoQvs*13>ep6*Lz16r`vg?BGdXxGiTgZcT!!>v>yZSrcb(W}011ou09P#{H&o{z^Y&0K)ql@#vzCYftaD zyzLOzSL3L8lkRM^hNYCYB!mjw?9pQCKLgG@)*NFX#_u!axQk1B$%fKc+$vIyq2e zv0SkH8K@E>YtN9Xxiww0*@^ZmrrR%-h?h8#J|uM}YIoKaRo}K@_sUOGh6HHg4SqY- z5Xru~SVUk`or#*XEZ->t^2>J}{nZ(bVOc*P`#Neq$+8+>m>i!;#}qFF4U>f`UEAQ< zOQWzP_emo~MV=Xfb^H7{t{wNLp2MC{Z1++lQbmqtfpL4RIQD~W9{7?lf(ya!ny?c5 zEE2uR=lNceY;AjQ!!;Zdjrp-8WZO9UtX@iF<{ZV+G}grsS+DQL35+GQYOz(ydz%rq zMpG(DGh>*CB883cUlK^mLL}dPSEl4rLy2)ED$vlU!^g9EEB-l4iG}KuIU=}Ibs|i4 z=c*=60{w~vy=39Hu&4<_ST^{sji(KkJ9s7QAG}9ye z_zAbuk3)vH6PKR#o#^ax3@pJ}6Jb*shKJW1%M%f!Te~VO3xotDgl{?^SI$xGeB^Dew99)EHs>wY<=1{IHJQHM{ z6IIa}e>26(1@S+Mc*7t;HJ)sNji7djWSkNu7SB$;;a|otT=6XdQKi@uqSQzmJ}rhN z*h;0sUwn074=rOXnU-BPG!y-~d~IOB{KVGViT^O>V9FAcpYL1W5cdzl9^IS@tOSUL ziZYiePslAF5!$TC!f;B8-wUijg&Izg z2ED*6DyVLk5$K;ztn*oXP&F>nus@wN=WmZ;zj9GJJWD;944qq6Sx$tn-sUAk>t`n+ z$8&Az1R!jriB{+YnXKF#DissJ9zS;1e*y(+(h&WHbpR|Tet}M-Amcge zSMDp1@lNX?in$^Z_m$5HEApYowu74auJcs|L+b5H)DVIk^kSm2M(q)$$s#@0bT&Tr zP)%ewI9f7n0=iBP0_eP4;Y?mbAR@o*2SV3#DtF%;24tkczJl&eQzEzQohrh$L zlBf*MBUmVrcw+YK17sp;y0y9HGX2i>E?#e{(wH;tPunA1M)AOXd1fdlJv8rSh!n+| z*lKi4)76`jXR>0g*K!++Bompb`DM&d!V2K1VCzFOi^Wn*|B;*+&%;2=+^VDhKODAG}oP`L&lvgfc0};0+ z>jkg=UYM5To#nll0PxX2!?f>Te1!McM|Cegvi|F%n?rj~)#<@{L&_%t z8x7=p_n$^Q4Z-BT^QNfz7h;9cP}OFCw5ieZcb!dRU>!)+q|e}$i`3So+;z^3Q+UJi ziyS3;rxWqZ4}{z4QUtKFQ`_gMF!IGqP_ZT(s0L`lFz9)y6Z{7=k}uN8qOfHAhE!;L z<>Jtb-A0SFBa)no^kxajK5Zjc>p4Eql4;73WkU$^skVhO!LK`P!ReaBJcc&VeHX1f zhWZkl{*Ckq)BAt?wSD3@)M=1Vb21CeQ2b&wv@5y1UB$iLHWTnZ?bITYQVeu?%#iUU z!>;~b-Gmw{akMZ*m}A-28tHZ@G!U490tik`!=8^miQujIVnVMBdMu6^dm+61I~6UD z-h_O)vYA{9Nn~0hZUyHN!gm0}*|Ue4h^1}TnmBx*^17D(z0uL;)@<(GtawXgAb@w+|B}reG{8G7|L_g~i|POJjwLj}JJf%9hXNYl9WwWo zOtLP>^78V9m*!Vjq*EMz!Rik^>)JWd7#I*08AE(39uN;7NV+HJY=T)?M@U~mR3EWh z$FXk&bvQ=k3wiDdtw=H?9xUNDw8FDS&Aw ziH0u}o=MKu7GdM*cPST1q+O(g+qMc6@Sl zRybr$sL?nig@T%qCC2d#c$OE3KtU=uhIY12L~3FabDzKBd9X=gEY#>t{V1nK=F10 zr^s-x9if5mZZ;BEG@VSN;R_a004rQOi7<{iHYFDDSnh;@bd$xxRIr^mHG43xbLBh{ zpYGQ`iX-$^%Q+xEz1!%@klW7=2R0Q^PWT$XVEUxcSUo$;NwJ=3jp2i1I6i@Y6m~p5 zACU0~rl3#qguY-BofDHJ$h5AE{x5s^o-fI=O_i zJH)?UZF$hcEbRNMcM43zZp44;JrPO73;u?!L_pD?u|TtjCNgO;3?|g~O60~Aky0rY zH)X0Mz)V3h63Y`xsBJJ7OJ)ql3@H;IoQlMh?!yqdkS4^GX5^(Z65W|Bu@j>jcaBDI z5lrmQ8(fjn>O!aaxVl#n{Y7e;#ekbmf1z(IB{Cd4o}LNf$BwG4l8`4KThr-9zP%+G zqMLbO=yNSHJ{FDK!s*d-cNCJ9f{kl$#vXXSgu=;4%rHN?3BB!sJ?}Ob^vpodRXevZ9g9zh)$cQTk=ZN`PD|FdbU1H`Zkh`Z*y}ZAp;&ox zlUhnQ*gc~JK+=RW5nfY-EqPCe-bxh}-ID{SP^yIIY=J{4s)`5D=vudM4j+O84g)S7 zBvh0UXEjJZKba#tT*Bz3#wnMf|HAVsqgU8UHjYY7#xt1#7c7awQlV3{De^^Y4cM5y z44N`5$$Ni?ts{#HMM_MKlp4r-X>?>LoXhaw#Z@V~Wg{x79DxErhkj&GWV zQxgZV6PQtf&Hn+YUfz~azUKxCsRUD5={S{zULZ+_0CkTpT?#VadA$L)q@S)j_|CWtF5#Hsi0jEQat{-^ArSud&`qfZRF#I+gBbOX|V-%PeV1YptjHF!b zcybN*Luq!Z2+{w@(PgFyWaXhOI-W^pA@z2SXsduzNiK40qb%tEDJ0HHll4>#{Wy>xv2c!I9OfW$`Tj(th3)t zdqKgKIzTreEr#9}F(r1`m%Bh^ zwCp~%(Wz-D3JA=QDGWo2(R{f#y z@Kk^KSTx1Cfmib<$YNCX9m)Ws*E|+__@u!f5AG+^Nk{ZyC5ceI)m!|NsXyBp=Y$+g>5>qipWd;Tr2vkpe1lSOaLaq-2mu--O5+%fq;g>+VZZ*ZCq-c<;t9KpFJH<_f7W*bdbc>SvPdKcxbI-Pp(9l zbq&C5=qZ@+{G*$}XaKWmc^KK}$$gjym@P2n6+HgvX4uOxH;=JWo@}ZXz-)m@^zfLi zn~`t;vyHk!-qwkmw6PI~ijLs{)Y+6JQ^1Du52?}4P<(^0Wadw_{;>%87W!AR8Qq&EhEkDG*Pc4Ih;nah=y|-^`3$oH2|9xBBY+@H}sruTtmSt25%(O5pM_9OExi z_F79b0?1zMf2ZhG?pTf-^&~yJNG+|gkxKaESZpC8J zE8r5Yw>Eqzoa=EvJ`~l&eSDQFDod~)CO=3fqbN3tc%t(mTYZY`lY-<=DU5636e>Fm zbs6f|U?3H1d;WCFze+*`-{w7>SaHCf9KuB?HOJs#rTBCgiJPA(>}M zOZy?!(dAvZF`2CoUECOYmgs&;;pWj?RF47WdsLk)QV;n-I}X6Ej|7m*ID#8?FP(nFW&nX^IwlNKJGrju>+lv&TdkD3jdK~Z@daU@YE zUI@z`D|ACFEvweVVhEAeiCe;1n&gGE>fCZ>_?O$f!lDMlyv&{f z*;$HEG1CKUsmX&ybzHIDh(@yoYZ`-C{_1sTdQZRk^lJ)uJ3RNxK2rTt}A(bE;AB9^iGu)aEa8{)pM6 zGCr$YJi8zd)v9;yY`#4G4B+7q-xhKx%N_(=qIh&O2GNscbiQ&{GIz6eASa^pF){-1 z(_dIZL*}Zd5_tU^orji!%ux?H@VW!(Y;5iDP`=B}#VQR$@yGeOB_31u~$Ifh&MYagsr$W-w8Q*JLT zH`!=nVuvaQHR?-k11CK)95IXuR%6uAqF1TQR}O!XW%1%t(g6}kz2qlFLaC(Ga6|(L zFB(qSJsFiQ`Bn6D=Z*M?^13D+H^Fn}YEEoeM@5g$_X+Y$Zsa-v2V_6=1U86@8wM%W zZh$!-=#sqKGQlVxUU()e6g2_hg)nT&aFP&Du@_mUoI=KegN%&?(3_Y?V6#%G(u;|{8&sliqh61v5T4k1^te$>sjUo`k zB4lI5HU&(m+dtUVN*I*1WQtTum0GWZk&MMN84@sVRJ!*u#R52AQvi?UpGF=IZ9^m` zvMLKI7r=lSEeu=jV)fNdUQ zP@AK$u=`%vn+xxqtqii$*yB6ET3h?)2i)K<^r);<7Q(}Ppb&Bqs}!63Wir^$p$GA6 zjkFQiGX}nbue#No=ur`k}NRx(=8_53kb$Nl6axC`QTme3A{LM+% zpJ-~nj@g%6CDCtRlD`$HZKlF>jsEN}k}KqWCNYEX4o^Xpgut*pW3|607Aa)$uPiG? zb*;fghUs%6ozG{Q@6jkle$jBUpA5rva;S2B?+sI7d%*Pq{6dee1ALtsg(CTGhwf2S z`jx8UI83-JbPhevbccqgAxT&i9iu5BFyHu1smkApjb4ml;FsR#$3)^JaGHG@fSV)X zHpYz^PGAq%2(&_n)SgLhN@Wl^_B0~Ia#vER6w31QHcl-^RA&oOoW z(evVY*H(3nY|x|`w$-f?b!U{Iojx@kuZ7i~n(;A7BfU5&L7k%CM~QlvUM@v}o_hU- z^hJ#HokwXg6=n6U>yXa#RoNq6`gsX5>3AvZ(jwD|I8l7Pg{8?7SVWpCG;Uur8p@Q# z_79zCaBw5ZQ36GG$)@2Hpq0TX<)nl_zozz6*jc{8k(PhsW@sd2G=|;huPiIKq{AGA zje!GNHxV5#~7XK>n;ROHTYWoj?z1Xu6ORDJqowqViXvm8k;?E%G1X=J+Dq^#2YQ zYsoM;%K!=ug~B?&h)Sfy(nyJe8oE7sp5gr{7b9abGav}Z@NQ!5qO9pH_%IiGUp7C` zc2;rXtqXZc($Y=I7ypAo`!B-nMWKcKRcOM&fN&H0E8O74qP;XbPVd(m)$99vD8dEB zWnBV8uAlrZ;dscTaJ#d8Klefd?I-CxC8JS+qSDeq7@;VLYrOCAR`aqy zY4bj>0bV;Ni71?ROGeaxBSX4kT*!GRjS#DlGg&DifKIviHPti!X+1K`nkEg~Uw8(+ zrdiDL0-YA2d*-N_VUPKHoO+=H=870$k3aXsdCeuE2c4QKx!s##BaB^cv+0Ks*>%r5 zK;+Er^=lmas8ri_fI>6HrXA`v5-*6*IAkuHN;EN@$^x6_uR;@#1Qgnre}r2TAl$H7 zUxtlBqNT&xc}zs7BEcGq>CSZ6+?-Ug&ZyP*1#MA11CJMRxb7F^!Hbkq1!BgZ^yJ`^0DJACLh$n! zw{F+++6vXDW0&>xOsyq(^sV)M!KXEJznh~8`L~pk6FYS|%byMa=4g)J+1)v|!Y08Oq%AWzgd!lV}oY-0W1d&saIbzl>a&?Csuj-&~eD8wujr zb9Q80NkB~g{x0A%>rM!CQysDJ^otncJBay4)(^>FH# zzSFbp%u8@?#_qGS8K?MzrX86xlTCmjB~cQY;8hzNQMrlQnG~o1>}_eH3YT{6M`GYD zMI45HUjWMApE&Ki4KvL)J-b+*mO4cDN9(TA3 zqH1(HjH<9~w0_prc$U)ahWbe&$ZcA`%g^o7)t+DaI)-dYVr}D3J6EO+K55_99pCT! z{0uSdZ$Icd{vL?xuWh-xoEBx9n=lDj)xx>*a>KWv{TS5aTjMj#+qq9ubMkEdfHoNP zHAuOR`$jp`=uLEA+!~+51K&OMruVgKxTmYO^U$`ZTi=Mx`O(jbU5qSIUZSu6<-BV@ zmFrbQq~?#l+jG8$#LjIQo^r%*wR9c-(LRUdrTs@iR*&QWi5gqGY*V)T^mJva!lNsY z9TzBnh4RUj1r%$doYC2Av_yQ`CH5hh#x&G{O)w^hN?U4Z{p#+|-B9^hj-6fT+_V@3 zy`&H1bj13f=QN9myHoegu|xJ)VVIgsFn#`YsFJ4TpED!s&sfnIkeJ@K&0j;SpN#C= zq~n=pvD5GUn4XH$My{L6+eQv={-h>7OqXolZyUD>bj4^++!YA~I5BAm9{84Y?qml0 z&Oc6Old8y>g{-+VDbNHZNUv?%cYxJb%Al4>qxiy*eLZL2OYU~Id4wOJ5y z#3WLjn}uq(ECBU?T%P3Nm46f`niTwIh8?cO%IJ;sfg^0tuvcIrU?qj*gkv?VyV zA7jZYkAvXLLHELse0*{&bGMMrQinE_jd(Ex9XU$|vg_-vFrvahey!7%ax#G@^7JI-*8=~LU zR}IEp0N(j-zUuMRPEmdp_PfsF19O}DknZEbr&93uBdQ(&iB>u_@djUdco*FkhaQje+5{K z`#P55zi%^8Q4qG24hN4}Q51NIYf>f5Y_T-FJdxoYn=7nzDRqx~~qvovC>v@1Re|rkao_Tpu z(^)=4b3hXtctAXlWXcq`*L?sUv_N0=UGHn$`gQ2kD#eyV-N2&m*NA%pNuL4AYJJp- zpP8x{Fp$)~>0QrXmo4TEZdii-^YO3JH%@Z}Og2t%uu_E`-C3+`%Zk;?x~fN4xlc5j zHZKUc7F{rDOZ>czf3fT-lZ3bo#o+U7(AJ;##vawkDIVF@$Im6U1I_PSZ|H}}^jJ}w zNBLiYzf_wo7z=p8ZI@k?cn8_NtP$*GLG|yB^ezXF4>Kcw?s~=H2|q~RcT#{RjHJbn zN%48aS(P;9=;Qu$M}K1FOYtyUcB@F&L#a#KyjdBan5f%^jI$tU_Kh5FIuAssVT zHi^Y)|J=a-HP0`gfG3-oEw0j)AM;zX2*P+m)T;PrKLq!eGN<1Jl5k0m z`HiQbXlim@dsFZ}*NjHd12C9>+awfqkbNklHv<(bM<|=b1(m-hK!=K!S!jWxL2;t zO!i*qk%`Ltqo5{iFVFkdI4Oojkj>Vm>9q@KlwJe6PVp7T3skGY*D1cZ0IrdsFxOT^ z+XY+!qS=;bW~*ppaE;kg(Nf}R3``d*Y~Ik`yewaw^U?kJ>RQhm7Z~j4_zlCH=-mrI zIh#lRUrEbzKBlhwev*8 ze=Xm1cGA!7nP9BsDl@k z#krvIX-=OL=l|jBE2HY#xpr}iYbg%JDei8?i$jaMyK8YM?oeEd7k9Uf+eV7JTXA=| zi*vsB9p4!Dj{9eCvXacqB+s18os~Rc*SuJ}buen041aCyt0a%Y`CH!{Hg8_gXmhjB zomjJHK(F?94PowY?dxe7{~7f`S9SrkZyah{9O{$8LDy?M>Qk%px~~lU_douPXTZz2 z=MI<5_(o8MWoGWqD}+nQWW48Zl_*tfog)15*$#OQ%?guD%eq;gzhCnxZr7(TZ+|I#(YzK;Rq9Wn=Ix?tZlUL$Tx#l=mYhs1R~ZgM z=lqg7wWnX7e7dQZM#8%n_iA-7j6Dr#%@O)G3YZ=RmU`95PHw+q>2=nv*=eE*sNFoej9fI-KKl&S-27d*Y@}Pm+0wgj zjPusMc$oX41)}pvK?jvfQtt@rsixCW!>*+B2=)$p z`T#-OPiGZ9NylH|lIJ3Mrt42c=8e~u|Ld{QxE}L!%VX!$P<`W5g%WO2>KYRrOFsOv z9!00#9XxhtQO5LMqv+m^j!*VY|4VXvw2Tg+-c8HNS$Oz!7W4}fwZN~boLyGm#Ujv% z?ukx%YR8?$SxrG#XJW#`RL)7kbgR?4F>gwJyWnvMIE`+2sA_=|{JcQemM(8sIMjS& zU@ss}AKg6wzIU$YA%RW5L>u~<<{|5VT)Fn18j?OoyTy`NJ5{q8zA8-W- zyTB{F(Sk4Y1W|=OrQ4qO5KRv<%-MFi;!QdsA!oP@d-AsNty>n3#Hi>4(x3a%w;i2A zBZWtJczrmUx{aB-`~2M*RW0pn3f$O&x#sS?WU^HwRAoNIj9+&Q~eCJa8bdBW|t;D~Uk<6MF3W!Ik=!J_ zuC}wW*%Atx_C|lVgI`W=*mU2`_QL&2{Fp=bysgw4QFiU_l39g1!YWSeU-9#zYV#^d z^2zMA1ILqi3ssk{h9X{EF1cw;u~^FSM^0 z)1&Uo{Y^m!z&T+{l#VNoS_O6oyKS4y<4+l;ZuTKz5?85)1K%HvlFfX^mA@kwZH&vHc4sl>c{-NLD50@O3H{S_LB{hPYe4u5~;q7TeI&O52 zcHwB_T5FVJ>Y1hc#$Rf}zq~FUdIdx3$wNBSw#*0HI^c~(+CO@-p3g5UGfSZBd@kZE ze3Xhz!N-*`4<()?XR1gZ0#X`oZHf0(MmF)7TYcN&k+ZBMkjZ}FUA zpOKI~HIn~@dM(dxz``xoG;gKNRnH&q2|E+@R}b@LqwvM+Pa zHS}3Mj)IaDha$Os1}Qk!kQvu_45+Hs7P2v#c>xO=OKU%87J?lB@?Gb;J6J_)uGLCLirfD|8LRW4WD{&w?kTrZSYoD}l zByHkn8wVeYnR0mKZAAB~)wUv=eQ#`@7;^pvuoZ+$_McfEy@2;wmKx7CvtXWQVLS?Cz42HX90g!F zpLptJS_ImK&XLDXLmTx-ZSKoCIpCkG&nV{n0LYF^Y)*^7o0{$p@+nmFOHNgp#^<1_ zD&P4mRGX5Vsx_T5la><4^`0F8(t`NdW|1afjHvW*)*2JDrnu3fHZ=ZQrtC;Gll&yj zqZvEiF%DzMEaB*={AiL27v8ayH&5e;`HKk&qxQw|oHs)z*`K;CPjEQn@}FG#wYybvCJG#UwfzTie_dsyXfuFzp!a5Yx6L<-PZ)P9ZLE)?{FTLWY@(G)*Qrs#Iw@4!$x!t&w^L&pe-+6e3rupt1L(w z29CWdsv(!wi(4dj0_2D%>-7&ct6Ui73HyPM{5Tz?h6-4%xq$MkJS)&_y*}1} z8^e5t1n|*w(^G!*XwUZ{_p1h z(X6(7=0CdsnE5A{b8g<5VP1O+P|8WG@}ELL-@jZ5nD6@vzm~1gO zUYa+|MfO0U*!1Esqsn;9|3YOzmEn#KTKTGN>ViLf#qW^P8V7qKv&r0gs6QdvYoQtv z=ar2XvXG7sQYE~JlQX-KQm=jeQ3{%$%xOpuDDtko4$1}zSZB^rHiDLeTgS!((vNL7 zTM!?&9iR#JTq3EhbWpU_VzcpWEa#oYFPB_YL~q}pV|m&3WSV`*R<^R-Z^?c7@lB563h#EO9wYj4IB-u`X%9zL%-d(g6?(p0*gjAyLNcZ-DTts1gIdMRDOvsPZa7`3LQ9AobdXRYgl*8*bW zF25Wom~lHq%7Qoy4H`s)PlE1|=s zR$~5paLg(0lAep&LK{wpOp<$+tW@{3r@-zDFN7-rM4pJCyZR~{dL z@B>e>*5l6d-s74wqjG9l1ped_+WBek3L6o;(K;TrpmuJE0Vm_+^+3z@z1_q8olyFg zTXyZG*yKSo1$z{;_~PFFu;O zWRJ}3`BAJ3yP(+$E{eM3mdq^pp4|2!G_zfwCXmeAsW^^+1s1;`9=lE@)`Rr0#1}V;flx6svye?|vW%zK(G~XP8U3 z_orbJg7s1(hg_KHinm}U&u_+0b&4E-3@DAGY&9MmOkrg;qnCosW0g2B4j;4B2AOcg zqidjmH8Q{_fhNivx!)q)VX~pAHq5&y3AJm&OoP3;CwcOm>DRHN88tX|qf>s9+wKNv zv9lT_N0;3N86gF4n0K=f>Q?j1TymwT#9zj+4D_kXI)E$?yYDjPV z0ZfoOB{5p&x9F%1q9+UqWsrcE;tF~CESmtWm2P`_yo-p4c>FG7=EtHmpWI9 zC+`&>z`+yzWGI$m9vY{gs~-k2(h=p6aD7cq<@x-MM?U(qWkTTlyx#!LAdlu*GD%<^ zr6gSg;?lbmiHVwg3V|9UG9jpUQqhS`33=GIj@*(wXe3;qH?|eoj$~@RQ|KQH+=#f$ z43H#+21BT|WZT1aqp4fR5HW=&LnT$F6pVO7bU06Jsv7L>rJpzpbuehB;(NjDK}yr|NI_dYBU~q}qQq$ zAPBIDTI73~unAjr`ZxAT}$cb}NHmmx4e_GI-AF-uOe zsui)Y9f@qKTVV?I5R1p@3Dq!=XsCraaM+CO*EDeV2XjQ$8I1QXr9g;zH*3DsxIbKb zyl1FwtxTt3XUbeA#q@S1j)y#Ar$KVJGpDM$^m`jRJYeW*KHpH6I8m2e!@0|Lo)NQaJ{AI<#HBDach~3oOjwzf$`pUc zypb`F`8SL<96~1%E?_>uojHkuz86P4M2jmvIf}ltJ65Tc)iII?m9+YY14V-@cNk0P z-@O%v-yx|O6BqBoOiV<&)$wxP1-v&u`-Ftf#h>+~tVS64F(h_`iO~s#jE1Wt0T_}gZp2$!uIa*MUqp_h*NBJP|?RXYFUbyBuh zxV!9mqW`2v^)8zlX&Bam{ARvGsuitT7HCD;I-%RB_U%&4S=MQ`E7tz5`yOUGWyZKU zS}~eooLW4jI-YLM=@}ltkz~B?gzmtN-;0OJm=|Fh%o3D$DfOqC)W_Z#kHhHSp<>(& zkT9LhAuq-4s)oI^XWt+|9oLASqITXUFx)lh;xR%hHj^EBXJ6Va%-rC?4%f0n0YQ z011=fL;_EPY*Vdk19Uq)I>}CRWsBFKFDi19Y(nD5HM$Oo551d&haXMewaPBK_3^da zhK-%Lc6^1q=gnn=e)l>Z#gz#yavPs;k9Ktg7O6FkQP@3FFydOY%#(gg)%~^0)!6+U z=iD4+ni?V2d?S$tE*}KZWuPT_T5w!WXjiYw)sFV<#_jlMvWT_inG$pUk!mUGPl>OK zJ1t>pppmn_ox#w_$2m$qdF9M^OE1F_PP`X16M_98vUv##AM5nVTBcHmb zq&%T`?XQ!p41SEU@P}5%3t479?URuqwhj8py&CV_uqkWPKb#(yEH&+1wA;-4}ZLQt^M;xSAUbsh&>_F1ZS83Mu)eiJo5A4>SzMJv~bXp zM+V0S-Irip*U-+q5VXnpn%k>Tgy>>>wV3%X?(o~|P?Tt5U$YoSz!&D&Po{g0x?@sY z-Vj%Bd^TEM9}(g>IrAR}yH9v}*)vD|@JL3B?q^v)xdcuA^xl#uNdue)ReoT)w{yM- zSIY{#eI$Z~my56D6-1y?Rj>P6^(* zyS3Cm7(SF)=nwg&tw%UiqBK)3-U!REG=!*yTk9z9xX%VFhi=-{dbTAG3F$F3MvNP@ z@gU8bc>JBG=#z^QzNUMKw4+1nct1G>mQyf*a~ z@^xv~@sgsJZm$r8oAR$tFz(RhCBZ{(gU);7dn8eH;^nr}3vN#l6tDHY5%kRsj8IG7 zOs!R*oJfs!PUhQ z`lFFreUN`JzqV@TX1m)bx>Rd^Z;}2IDI7o%4aJgR_W9$_BB*Avaad@2g>St}yYCS@ z`M;&2a8@chPLI})y!T-I$$Ozqnm}(2>aCghwv)>LL6*;>gbc|>7nJ|g?2}_1Zfz(r zaXj6(Hci_Ap7d;EvDEa=_on(6@$!%rtWSidf`4dBtk8s@6GEI3?Zq*7nJ;59$-x3c zXjG^BgeGHQ)+zU<6H41@+aalD&f$N*420 zMqepzm}4I9J4U%a?hMF2VcaW6if}gk)Q|?;usn^(ACUCzVk~qkFv&j*DZ*u0&@;~Z zxO;tBDtI#!nB3nEc;lO~@I$0XZectQ0(TW?bkUFoe!?{84~JugzyRSee=6)_WF3SO zhu83XXMoN81y|xdtubU?5OPWAuXAQgbFcT!PcYwg!M}xtC54ZwU=fKqAt!q{nZ4%o z!$}&1A$zGv1A5_tW2=V@rJ@wEt1;e@`$KO@oqhH1{LqexKdfO^jzOaC{(m18UP zH^tAk@gP?jcc@H7a)fgk=^U8N5>i6Iw|#->$ESiZLdFba2}bC~O%JO<_%L3oF8dSU z_YKuB;#BeDK<|mu1OB=Ho@c?IY}cQ?KZ_uh1K??P;DB`t@}DhYJkJoGe|L0FO?EF!p;icL{*^n zi47F4U?87J?tq^tx^Z1d7!hAUh*-h6Bb9-%wxl*Q8&W(e z8!F?ln~-@kiN|$vZ%;V2YaDXS$sZ+!6pH9u&6!hI??zGan1c^oisBRU3|_~hh3Xxm zC|Y-9t}AzH@y92RZf0>FF$R$bMZOH4X>_V6gRqOB`cai2%}x4WNz5Y1KWVs-Q%D(# zDTm)#zKi!?{KcQ+`VBGPj*j-b=hj^wxv;Gv61Imm6yw7@Trgq!*YkcHn)!JcY)C`s zp3(X3HR)=MaAr=Zzj0mu)s*ffU4{g>->jA2BUnRjg)w~cPVvzdWa@^)CW1Aqv#@}{ zNsnJQ)WX-d*8Ju^_2(TsCnbogfqgyl_@tN9CaTFu%ifaB+~NsAI|F(?X%~{Sui1~m zLQr3Zlr%o@(79-b{(cru^2#>d0h=1OI$v5u)QxmW$t|4MAt%|Pl^L=l;F>JM%TDVIgQUFgj<_t?3de^WlyuL&Nsms@J!qW<2 zgQD01)u*;e`|r|(tu4aQwPGm^2*CmO^xm%|&%e?L1Mfx3>>bhB+`o~!(lCVL4I&r@ zVFjdstaDsx-gCF|qlFU5Lm9%e`Q?gk6rBklg%Kh0vp_3RtI}-uB7XIs`A#0{>kb&c z#<~9UZtvt)_CFKo-m|a9Fov46?$MR(jSglB?opG-5i1yI(h&P5=Ebi z6zL~qusE@Yxj#87gMK~+BDMhxv>1+NPUvT7bZKs4arEecxUGh-0prrk^HGWR++p~Q z?U<URWwQ_b3@`rR+;}-)QD#-##C^3bm zX>1Zibb$?JWiNW+s~{QibCBO!_>?^@jUWN(Sa*Kbm9w7|Qi9{3OGvX@V1sm0q*o!H zBuD^p3Uepf0+G?bkYV)GRNW_!Lds#vDQxW(T&)z5fa4Ro5{rn7{yJEbI1!|TAb%~J zKo%Q=@RY(C@u9jOVFsG2$vK-TRU&iz0D(>b)Sx#lr-0V3vXeU)IIYk6^x7%DYJDta#*s=AG?ua(^fpOD6 zpdWB@8I5Xx&evLrckvtaP!`jNDZ_5oOIxQ2$`GUt2Y;8N!Ouz2Hs{<8^L<}s}aa(&wL z*kQ04VV#)T6%pIlHu$fX*|7toJyw_G_d8le!%&qYMyMlXZpkLRt{uN3$Q`5+Q5OS! zGvVJoa*8@+>YhI(GQ24{M=DTQ);P&`7fpLVFGZ%{($bjf}DNA7!j6&^rT za|7(A_DusGh0As`A<&pM0d!Ku10Z5*%rCv90}xrqv2I#o3^(`SH=@9rTWAB9p6nc+ z)_|uCgkwiGZ1ep2D${jfeIOPSwM_@@5@qJSm9c{(0;FnZO}>?Bddg+OoFmtdLLPZPn)!8LaU=NL$kE6pL}j~eC!S;1w_Q$QA!3Nm|(Df&Z% z!^{G*CaXTMBH3XDXF!5?ro(2B9Sga{5hw=zmXP`?i!e}v#T{pn`Wd(;y!npyIgfM(dAbd3HaR!qr^-6r6L&lU0 z2susjCl8amtH9$&3YQX#KGC#{fzU%oB!boc_GUYf3B9cLe&9LJ= z6mx?sIP_lk-Ly8)^B$4$(pEHxYs3*!tE7X&`DKlwz-#r1z%? zcK|dA+zqp^K1>qwCsy-c43 zWJ<(o0GaPn#VvqLkQr`jexVgywuLdOz1(m*cPtE@pvjx+pF&uHsj2xX3I=*WIsEHw zhTQpa+`u^-3O8 zl|M^zF4#Wc!kWk8Hmj~}fom=sS0r4P^pt(fS0MuT-1I)NO{ zF!|@X$a(7u#ng8ICh~rNHtBW)hk{KJ6T>Dr$T`z#&@508i0*8klkfdd_-hFf(+d+)f3aY)h66;`XMJrL;R1DZ|yr%rPOhH+PYHX-JcVHS->13<{^PyL1})4Q-Y z*d@U9zM)kbc1&|W4MYJ`-QWV&{}a#+fR;HS@C|k;w4bd-l73WmLP=wI$pS;45SS7M zAVCwI?Kj|S-WdYATx3Jygmh#Ig?e`-@@z}_7VVM`$PfoWjCkv&%s zOa`p4EZ^s)eq=X_*)qC5W@2efw-bRJ;H620@~N&W7N03trr?qPb2yMdVv z`)oRX^fUtloHMGEVi*ySawx37c5jzDQf>toUTwlzRDow+8D_%TSb;|)VqMGQ0v0|n zN(H|ed_7&UH*%LmhA3dnRyz8gm|eWdDs#xi9~K1Rt;fD7KubXrwwUJFC3e%->#*s6 z!`LkbT&Z&ryNnHh0HX33*mt$luHbbQMK5;YjDiL$xHeKmC*VnFs^r?eEL$`H&E6-c z)1y49!t%EU`L7ta<1GL%Vq7Y;)yDixX_y7Z>$a{nmL6HV87LrlFebojsJYl;+9eY^ zN$0PC_!f~^0oIW~y=p_?jAsOxQI?xjFI; zXW5iTH`;mMpt7l!Z?wl|S2+UPz1}r8{aat|4&0paR=)#dIAy8Tv}z9HAd4$x2>|9e zma7}k;BlJ&N%Y1GqC`@c5rB3!q1e=Uj-EkeV=5OgvlCP*0LW2m=Hn({*zrjL3+N>ncL2auR}ONexjY5)k9`Wg0S zGQBCA@c=l`vFP6ZmoZmEQnOFJ^Z${Gr+=CzB044qpewL9I~@ef{4Nxih#cU8a5u35 z#nQ-^k%0kV*Hb4h1El@6$5IFW4YF?@(N#BVGx%!oKR>jE$5-}^xYUJpUzhIe%_Q4* zj2$&Y-roD2-t|-pR_-o|(*PUaWM)UcwW)8FR-L6N+oGwv}S? z6clc%YRQF{@9~7!?-7Ovk%+q{F4?xLlaEEt?(v5AwY);h-quCKVbIHJkz>nCvDc3y z2-nR>rMnd3%tY$6?e-uo9KU&mW;KBa;zFn|{qGJI4QYIoF;N+^^1+hvA!L_vcfS|9 z6`o*>fu)ttoFrk{uA}g|MFv38$$l^Wf~sM(1FXtcv~#D5d*KUbD?vyJ9N!GS4Gnq>V7}&;*UwuIWb-gXo!trt19_m9!%d&79ZKz%%xhA zA!{ds@R!SxOmJJZjY5y^FORj4#y8`A+ZGM^($}B9(Vi2km6iPM4+lshoR5#Gf=d&%=_;}nPwvTDdY-n4THnY1 zLnbZleB~<>6f8G^3W5uMH&BOwuaKTP+yc&E4r8V?NY=ysZoGBJ(&J@ohQ|Zj zrgCUN;E;-n^zlqP`G=kx<|^E!$5qwJ8qNTFLe`~p-&Z;~=Y#9|qB++Ducl=?*W=xv z307`xBjuI+jfDyzes$})y+(({L!U~XhM_&5u|gab6tqKDpphoD*7k}I&+WU5dn;vV zY%Jhm44q)_9lV=2e)ngawN*+5-U7HeV8SZKQ`t;#TpMYJ8vDS0*wqB#jg&z5} zuKD;jW4a}mTv|^{hq^>P8AICaE7LxgMw2ASc<0gOURd<*^>L{J|JeF~&B$B-hfR+yp%6w{#u&w zY)07qMmjNo5-4o#2DyL7b+^XYW8?aJ;dvx;$ICr=0jhSxu{JzAcZcy;X=esrFcr}V z)W|);OIw=R2m7-kw(&tK>K3C#}DP687Y9{9d@44 zI2U2-rYnuMMOt|yo?wb19ojI9k{STIgn9b!65%h4RPR$sk|wt3a^6g`s&-Ag9Qofb z&Sv0R@ zYJ1IhiRwFCkj=5%{>U@uf5WW~b6#Y~M);6}urX0G;^==u_Ax@h;mppgrdnyBzSo72 zelG0P%Gq=9X*$!bzs^Wc-?#N?&+&SMwSfN>nCYE6qUJZstpqPzYR{yLrOo>hY$plf zd$n7B`9pf6?13-@uwm{u93l`Dh!|~~dx}YZLc9kbrHI-QU&0^P&2iy8j?gXb@?6Ij zX*zs-n_C6hhBpm1jR9?k8!IZZrN~jNq`Am(S(=fdMH}ax>v#HrRQstK@{VBlLnof7 zuu6KqP4Ug4KpqsS)u_|r#9|i@)`3jho|=Sd24b+o?n>PeCQ!D>%n2VJLd#7gHb7r6 zV@uw}U_wVzQz&ywme*>zpb^`@Wx#3KgW6SRj0@N}m}+G_z0(kMkOuFJ&k~KyH)}F` zm^ES1&C7YD-dN2jlsgr9K3ul7)a`c6#v7$RkVJHjd43b(yi7Y_nyG2=^fQ`oW};Ze z8fi*C=74>(z13;$hKIl>M@{& z^p3xDOSau$zFN1Z<=P;#zs-#RA|tF(uzV`z?qp5}e$^)CkllbV&BcT9%*I=HAl1ft zCXONQ_@OJB?>y4x^D9^7>&;SUM~9TeSfJhO+l`G4TZneMTr@3oh&jBBL6%vPwBP#PKS`%*op(sr^uUd#9O|Yv%nicDLUlN zSS+CFBg%dO30zOoOfO5)g#PB^jNmWZ?I<2HXw!CgsAZ#06Y2er7lZo8@uhBNE|iW+ z5N#a!S%!-(CAUALkInVIr~PiMj|Ssp&dk`eBL)ITh6FDjyvp;qD7OO%eO$Vz@Z(+F zo=Xdw$v~?2yn(0pzzB=sdq#TZnB+W9OI?Cd*`Vn-yICVedLGSod>CVEa0i zUNAf!RwgWtMuXmL#*Ot{z>1@e!=8PSI7np{R63%uvXf?Jx;V{w^jMm*BR5*z)qQa( zA3XT|6{O1Sd83KsPR_5b*ntnnqT>F<8tm`@POkWJQ8d0-|L1UM$nuk9{Vy&W9o>Fo z{5cayhd=I|kcFS%bqDF1y|d%u8;z8kht7(T8}%_DziaR4Zuo;jDB_cpNcykgWIvRq z#Cy$A=h@?KoagO10ta(c?*whbPAU76vG7U^7fk9)anlMccakQL({_wyy^?|&RTbZd zoqk9RH~gqxGB2dM9V7Hy6tK>d5-GLaoH)!Q2`nSb7v?VRRHhl`CN0?HVSj_08~9=Z z$x9GHkU?56(8ODc^L3MB?WhJ{pFusnALA&g;d+ufhTrWjbO(233}s%U`n_3nTDhXA zFDoJ|Oyk+oPZMY%^z2J3nz=NkuA|#em8_$ab|jYKh^7iE$GN zqfv3y$B-}O`;*~jGntb(Mud+a?S{?p0I6Yb^PLi;DMG0%35$y3Me?B0i3pj;iG(#< zx%d%a>9@OxNEKd4igw*Zq-uu(tC{J?ywyn5hV_mag zka3%^_JwYh=sx>N#%~9+V8u)30KPWUk zJMRt%D}BFsyte&JzMxaoIZ8C)gu5>qZ%q4bgR!5!&kd!IT5UiJWj)E%|GlC&n3al@fcK4!gW%L?ol`a;;@;Iu{J@bQ9P? zNP_ntQO_!6Zg+?`=^X6Qs)E?jV8Nk+Yk?%C(gPwg@TqlM^J z>G=o58?$FN{27@p$oFbfW-+XdNGxIw681~PfDEai$fg(a+oL)l6;Z*p;rAe874CF( z5hg=F1Us?9)*M}5H7nNl94Qhu{4mnDOCT~0VmHg96^8W9=j@sH`?WayIVr{csP=$< zvi}bw<_|Fg2-!Kz6WR}k9Qt^}aKFK4j@o3uo-)J4_FrPH9V%0Cw!zJZVIu)^9v09u z>;;V``*j?BEo>Yk&8PToHegPdnaP<)*+L_<%I?QdeMCO2PeLp~Snq_?OsCOedz-$s z7M6Sa|7sR{$;1DAlC>K0LhvPNXA=Se%#V+D;Vgc2t6&S8=0ZAUlHMhK z6^T1T%=hcc1RCVN?^zyH$|(xTma}3|wyM=P1*#0JKTBH8_DO3#*yBZ951UEG21QH^ zw}@q+goCxg^o~hhIakgV0-@GO`YbuF{XV+zhTc{Y5opWzh-aj+x@Dpz_X#3 zfpsEqk#S{du+~#oMZoPz9cg`YVsCS4zv}IP9bBz?#q>3`G1?<}h@8LBbv{=0Bo^zp zGTwaPbvlT6N-Y_-9ekCJhG#JAANWP+?tGl`YA;(lU3hU|AWKFFxo`9*@4Q1#SD!;O z45>B!LF7TvVS*sVd1l1{G6d$}gl5A&`ryImbrdl|&p-5CO;8a?-?i%4P0l{Jk}~Jl zQo&3M6D*?7)|2KC)OyZ|&grSBj@O18OQiFVw12-n0d94Ne`i&OrF;$#0ddCl?~U{S z?{MP%{~b=4Ix)IC86Ruu*e!8ld(Zkk!;dK(iyqaj`28|hg&AUnF<<=UI(7Uzhf>p2 zGVYU*_1@a4a*cH#743rRgy24sj?D?363dv4_eHf9&>mq z0#q~vUN{YG^nH4oO4l13Lzgb5LeNwekbGTkCwP5k(rn`wdVMe59lZbk;YSv@eoQY$ zVr0khUDqdH+-=iU zoX7Sh9w0!26ES!;dj9qSl__!k1MP%SMh?eoIa)u zy^|$EvwVK)^0B6VI-c>i31g$Oo;3OC8)`(pahG8?cNnODNmp!E)AHfyE6oDYS2JNF zwt976>8A`zU1#AZCjrGz@ zgBVHJ@wG7wU7NJ~#bNnQvx|hGsZq&5T?VSts)iy1SBcWiBSAhuLsf4eE6xbg zT8cnAv0+9Ia(!fn$5d^AyI4`AnG~tVY#!cuZdb=BM5Xg2nfG>BaSrSgL0G{UZ51Ur z+)ktCjf{51T_)0Xfxp4Hyh^d5`8(--Z)dtBHS?GFv$(C|?`B8)mtly-7WDukC*634?RRwHRFn|nlwOg<=P zsFM6mgIV2PNv101L50^zB5dgzoqx<8t)mv{_!wX4w3b3fS-;*EhEh>YTP^MxY7l{% z^+@Hc-QA`8mB|=l9J)aPGJ!C{uJiqidud8dog`~7A@#0*p(+32koA~6ZP7voxcJVKzxim@o9&SJVv?k1lur= z7q$(9zIkV*d>+n?T{mGOidVHriI35yr*L3ox)>H*N1kTdzW7<=oA=X?l`0v9!WAgb zwW=Apw8wWK@8U(lua;bYkKp2n=z~rx0#>91ap8lJ^s^%!X$@iF`-}UT4A>EK=O>Hw zz25(y%Dw`sj-*=`4ekW@V8Pv8LU4BrZaKKSLvVM8;O;KL-QC^YHIK~vb0?X9X6}6( z=+%eS-&a*#)w^m-ot9sCVuuH^uSd}Tf;q|bjxPVL5&=eE&{VtfwQy|si3ei6Yvj=s z+h^UDxFP<*bt02CZUc73H}dDDT29Qg1Bwym+C_$Wv7S=ReW!r;jL%}a%T4MnP1FB5 zG~uSTFE2#dpIROZFLG+MbWZ;`Z1*XiT3*8|10CrH6tUJj`y6s&YcQM4C2O?wPbX^t zx36p+NS3}HKDJ(y&bsHeX7|^)c?1#j%%50WMlgF@^Ecc;w@!YKZcEJebA+)BiC1|F z$`^%Hjn9cl08~dPgWQw9Zx@uL={XsvcCTWh$!=-kiD>s}#?3e+5LYf(|}&lu?1k&u#@?@PQELG>?wqx$S`RJoPMcb#`d$JZ?uX z55YJv=O!=QJaYRx-bn;v5yGOKjJ=n7-KF03^kLS(ID!T=iPm|xg5v}JkEsK~Aw2C4 z90+Kg>-VVx8VCpy2uMVZP2_d9_#c6NJ+raaqqWhqHnFs|d7X4X!Tx@d!T8ISHlI!O z4Qz}p9B52!rquuz*bPW8M?m)oAv|5kRPQg|-jak_TW&I09aeXcn8@P5`Ye1UCZ)7) z8jQ_a+HQ03Kh+SeeL~J)_Eyn?4`A$caxzpJO$)VnzPuZ+GRmQG90^QuHB9^l;h@6^ z5X!Ab^`F1johd0Q*0wzVTGm?Fnl&9#z@u1r5V?xaO9VDbqDM4G@p(U$%UyqV1l_i$ zFHf8H%z}CM8u1R8`w2gg#?wu}XBQahg`*?D|D;+*sG=-L!T{Vh#8Ur+b^j|pFg@sQ z+a$P(eqllAk$$%@jdIRnLlUZj>;4r8s32W!jMrdMu97wX#j9n*a^hNInQqCC)=cg= z%<%rg+1SAiEDh{MmS6wNqcOjjnwL`2}l)Z!tsP~93{`tkLK zuj=O-!@XI&My@Q%XPLUp-#?InW0&dBetui2Z4^rt1XXgdmx&@Ertt+0I?+TiTZFx= zy-dG*9u2-GtME%YZGy2}Tq4zM29>2sK%V{MVVSKg+7bIchNe4KXbQ`x$gnoTE6#G{ zmmu>zT?Klksv8JwpnVd;_vumQG*xeeHD3)^kYGw-wL$d>>RsqlK?M{bu*nz#fDmP%MqU>}?-FHs z7AL3Jc{Fjmg?6G--Jrlyvt(R1I-FH}t;wl}JHtT;$9;bvBNH#Bv<76?&%m=y;6}+$ zeuY{}07nPxo`pMfR5cV=O%za8fgCoGjya8Sxd{taXA~OnxlwD{J*E4RQ0Gd@dukQR=PtNGD-U9UV^5d*_^qg; zF})|;7Py41T0`JswfBS9D1paFz2_2z;mz0zF7wfS{e9ZffQ#xuG!^Ax2Z5(dMd-7t zbozr$fc!^b#Jl~~dwV&Cj|sGo0a* zxQUSk{Fl#U2}%PIWk9@`0C}aHEdV~Sr7kE#t~}lECKIRp^iop5Y(8gOs@2o5num~nA(ts>K~~i?aLW6k}1QfvgbNIMGB$b zL6@k($3B!wj8ValF%jt9QM2i{Z>#Z1W?|VsCmb;#30wgElfYY4d}ncBmv<`|sNtTM zO_Qu;gi9E4`XJ`{+#AQe4(LEcJ{ez7swwWq9=h(ESYMc0kW;PwiDa$qUq+XWI;09U z%u#|C2znP<6hp$!gVG~1HfgjdJRNMI$CMX~4F|eFVtB${H(29g_X=KZ0W-XlOcVro z%K^+7*+QLAgNkoDQf4s-I%>&*M|~Pki4saR!*vH$PmK`9g$u8q8WI~9F32H z??PNjQ6+@=yQPfxTBn!A*QbpNe;(^^R4l&IKq!cHJ2NzDWVTgcwT+~}Pg?`VZpnba`ej&9(mkS6R&bMG#GEp3_0q=31?jB7Dky^M}YjAVL z-|}ZJNkrwUn$=##elx+<#t=bK8SIXj-7(1}qMx&`ixXIi#`kIKe)L%o+i^XklonnF zBP<|&P!(cBsI$L84K-D3G*-pednwy!GZGwykvW`j$t9ktS%C&YYCVpjPoi3_j!)ww zQ-TSR@z+}fNiq~Mt0@djdiTxv(zG1FIJY@SCvz*PXMSDAo2Y96Cw1 zc&#}yJ!?oHKgotq_d3OLV>^Z{Qj=&sfb%&(oP26mHs|4?#OZ>Xs=dp2XfGym%6|5J z6}C>@yNQZL0_FNc>qrqxa{JRUm$E}`R1dE29`G$b`dy&h6K3x&(r0(s3t2QKvUC!@ zbEsX0Dc!7n3a2gyl~;raz=TlkFy1z&Y8g%=ol^rv@HSF~20qI%vp=HsN7En+YJ&EL zae&opu?i>PVXOCm#P__b3t9E)>N!4!N@eZT(rN0Bs)JeZfk@VgJx*ADTVd&Euq@DL zNtr9TfYsLO?$;5nj6q`@1M6vi)-s$F<=Fv&b1<*;2_YC`04_P9pu)sd?D>O^_*?1Q zPYHYMwCEaEYG)QQ!HlZwfz5%QvncO~glI?0>J#5vz$!hPl;x-}bR_nHz}^hucoKXP|^?W0pc?|u05jS5pf13UY=rgP*Txcp#?_f}ocMX(xq=e-+ zMgC~U@_63xN2)0i=s2RU$L+dRvff-LZ)C_7ePxyenBBsl#XPIQGUHK^P3In=N>rtonU$mtVw7kL|L_oQ|&Jm}NuIZPcM zi9otNr^WET)A{&8SC4|A6ef~*Kk=EiR+iTd+Et5V4^db!0qaZ2I|$YbmvT{`VHj3j zuq4{|Q`)Coge5)8&kcPPjMQ)zN}EEvubS1S$gVw(^T^sZ#y&eOJ+bJtcE?!SYz5!H zk*X~~(uiS>u>`(Ca&(Rw@L-*%4)P(Tgz*lx7)QTpIUx6KOvM!=Az~x=+;j@|}Gdf>+C7@49R%t)br*uEyhW z!rd>{HLnxVp$w4X)!S)e9ZakIY1U+_Jo#HwYRT~k-Ir$E1xF?RY!~;=4=3oMJBO+o zEiED#b{OS`OZb-i>7EjeVHCv^-c2Ca=7mW4wv; z9Y;lgipMquAFU<$6q0$X>mUzqwKeE>weLE)a)` zukW1-^>z!65Evqtuxt^>tK1RM3(@pCFOrn)HC7V43fs%N9@0Mqa=64cbdEpPX>pTO zy421N4oQ|erd|%eLssQT4TaNL&Coth%j(5kYO$Er%WjMj=uL(rOY40zPmg&5*lRNL z#SyLTHtk1>2rgZRDQW{ZjAx|>Mb}q!gX0w}58b|jxn|s$DM>;I$A3ouVH*U`e~>PQ z0RrNt{x{nI{y!^zTLXaQXB}IE->rkcw)OvcP8N3mYEh8?Bj$sRwxP{$0WeuX zZ5AdPd%&`?y2SSTy)AP>I>P9GR0%mdwm7@$Pl83J|g`rQwH-l63gCSoCfk|l?m9LmOOg| zd~oQ1_fjZKr)n~bc5PBB$om)cu;>Cr`=jsd79=jblJX=jd91q8rd)dMJK}ucw$gV_X{~nAn*1x+Hr8t5;oo-&r-(P=l385 z8RH}*bYl$njL&`}k6SazS9pkx*tcCsaW^L=A_(a1?bXlizpM6MGj*UTzC5z0$6*wX zM3(~|Pre&z;ktYKPVP;Y?T`cxu_z*aNHeh#V$_#SAt)?C*r0U=;YaKCm!vZ?lyn1M z9~wt4FR@+X>c{(Sjm2ZF6eZsN2H%P0_C`R|{7ixyp38XGYlc{S1YUM4p$OLt%6?&z zN<|`3S_}phTB1rJyFP=ygbpe+3zL=IzV`~QgWF;sf&Lpib5kwc^x7|IL+lXY1k#G` zen@UviErP%ZwAb(u~2>qsYk#gp4|C3gSIg*A+^GOxL9{Wd4ZkMIzmfR(p1XH*5+9X zoP1S2&G8;6h4*ODYqDmP1}EWVJ4Y_XZpq7Tb=vb1oWM}N`ev-X+ew3WUN`;v!J?A& zvS}{N?wZtvv1}f^(au7Bx#R1y!;-KgN8@HRZbWGfKTb_+jDCCDilpjZK5;e3+Z=e_ z_-GT&`O?QUd9$fS_k9|D1!XwcGIcL=5T_J3w{4!K(n}*K{@uQO{tMHuuD1_2-Jxa; z_NTca{>ZcLrTj5xFfY>s4S1v=m^dFxP`YGYT8tTWtuh4YSg`D_G}elpvO`!wv{w9> z9jcRyXdROcIJ0i^6?3_6qW9~j4_5DPKLBLRwiMe!tEm?mYEH>G6_taAQL%vJwT$s_ zT74A8nlf3F{dxh(mvZmn9E>WO?a)P;2N&NKlUi)0t!k=9-S76`L40sqq)ZiNmiOFR zjCO_OsmTO1EBS*ka1CyaIJmq}yk*F!GWNtKm~RJVN9qI) zb*p#Mcq-~N#DZ`Ps6Giuyg_&mc+@-sNFIQS7>!4K#c5UQIi9JY+EQwAtc!6uowhoi zCOUa;f<9@9!MT??ZWek{Ili$+J9)=I;t+fq;~`UntLdy-dpz>gR+OC6;UQZW-glJ0 zxC3}GTvl=bMB)0zK`2F~s#JAYv|I)(eGwfOxnoPR*7hUyk9h&hE)-P1Hx><@lX>e`yZ%sUh;Qt}l!XTq4H>r(M>0TLB6Ts? z`B9`gh$|S4VNJ_Hn$iRGhn|&e+7PS+0|Fv?Ri!^XEB{yB`Ra`^Ffji&Z_Iz|&Ob1J zqdQ-{GaGD(FA^Spv`un83m^{ogTX>D%fWHAIQ?Qx%8KNO=n{fBB)PN>2Oez|xZcrh zd=~1*%RA!zj$D^Rjys}9SDg@#u2ZMlgp=2LLAoJG1~xdEoEv&VAgI#sLVW6-$3TS5 z_6TlpHflT0P>N`mAkce6`$9&5y${XbN?>LJtNEo3TF%}A(jD1YiuNor+sh*SDe*sa zM})d@889&v4J)jNedr_355UEv)kiYt!jCF ztx~j;jL+umApf~?h$_P4Nfqc9W|!ySlXx%2*Ov_~TU={nhjz6O^0N$+6e#FEu{NOI zBlfh5toDlI(3P)^?+1M^9;Oq|F&d3CGDMkv=D-lVn?xPap>b@GJ3dh^;>6HadAI1r zm3A9G?$+ehwNVp^gJT;_A5n`ga${u1hIY$Bei+Yy(DXsj9es6awHEX#u(Z3RfvuHR z6FD`pC7ZVm@AxhEo~CweZyVkVzG3@``vN6sh7r4z6ZFJ6ezXrdpv@p@YO_t@w%NjW z%xNL6tg|L8DY2&bgEx@KtF8ns{{(52*T*L!2mFFnk-6)QX<$ng*qeg{Y(#^OA6x@z zd<{pgLnch&F1}A+QC)ywV%4@W&@`uJ{2nUcgo4J>lB4kT%TtTI4c`FNB)>cWBxkU1 z7O2$Lcfzn9f+x1)&zeLZcpuu;MQ$5gH>#Yk=8!CR(JDxv~EbMzNh2gBIOX^^=`a_aAp z*2#b>2ESo~8KynzRmn?Xe$a!?QH)p5hJQ+tImI0R#HU#XK(*&Dmo)8Yq>Y?5!*(dI zczu5WZrBT3TRom879=%&vU~ztb1g1tL)O+pk4QS$?OBA5CLtZ1mIsex{YUCPq-;}y zv-YJg;oJVj-C0stF2PQ?uR&Aew5*w&%Sf90%^9^u#*{u68k=E?c=#o#n_<%;p8e_r zI(ogY!rq7z`1Rs*(AL&X#2pkodR|_E@$r3doBG`t1ilOx%9bv=d~qY|z|OSO2I83c zrRO(fA*WtCd%FZVAk^O3I3QA0&fhVmy@4v%cZ4`M71?sSbZ{CwdYGEguyBc2!PV_} zYSH^7cq*e(p+xbyusn^jo%d6NcaU1mut5(GY&!Yc!XMB9n}XKyY9dI6MdW-a=~Abn zbc~sa8P@9h>?oH{@*CWdz^1;zT59i53$B*4xO*)>+B*fBJ1pO=aW&I^eH-N2K(c{i*lAia zGH`uN88fbOvlZ_=9I5tn@afz)ISp?UpeYQQB=|{KIr-)@zA_1~w7A0Cd?zD&EK%{r zXK{*TZMpzaQzvLA&n$BMPIV@cix`!Ri&)B6gyXG|1UT7Vp_D&JgiDU(qr~)0N@(hU zMU8P=BP7Se3tm7a_e%8?%gL*BFB0sGy(-R-mK;P!wfh!CaI3)zinG?Iq0eBThe5}% zFSG3}j{>cEK^C_rlYvTlC42j&-d!Mr%Mec??qyIANHh}1&R6w481x}zbwY}>K>|bk z);FP&0uT|yi{8;avH9`~XRIYDPA9CbmD{|Ifu{3xZ^89891h9DZImmPuDl0oves`K z%}|>Kt%I1fr;mXA(sF3EHuf+|9EKvCJj^K@9P*Q1t5`8igrn66KX@v-IZ_nWH-m!? z^mFW?#^n$JCgmQiUL~W&tH~XAn2-J)&{f*~+MkZ!K6Sgb`M0fnX+_0=cH3?@S=`5+ z6Sr#$ZCUYZR+wGvJH)LoDhK1JV?Us9#g!`%XUxx|k$IAx>P{w+)=U=CFQBAd71pff zd>7J!@;xQuk<^1#kqq|6~n zg)AXInykw{eKBOJqlPgKPMc)gBLiK3@ZlC}34WQa7DG#G%-E@;quUR%YOX3`CJh?W z)%}iyr`;~K6j^yfxKePZ>(a8EW^LGHh0S)J3y?zWixjp`k+fmc7b|V_P7IhUIh}jZ zhGkzi1)&tZQgN5e?@7Wc+@pDIw`iY?NmV!5W^*Y`47MnJDaXB}UfcKp?(<6lKc@1E zel2?+&q%T}s2T+H@@Ja}Kx6I--_0t6Rt(CL$LnMb0cn?Ftikvidq;ftZ?SiV|1x6! zn21$`_!Z=To5-~d^i6DEEt>xrHLvDOjWWPy;dM%eZ4;2KhZ-Wrh>`|$FoH$-)BV)zltU>0^~nes`zr-y!ka`AUs{Ce}2;^GI}DShJ~VD}qnsqFQr_z3<0c`C37vG5ANj4`Wb`wA01y~zqA zZ(6M9kg97P`j$gOZ$ z1qKTC3UOf#p0_~(mF^G+pcjQT&Mo%`ikpTyQ*AHIFpPA;JQFBAf{=Ue{7XmZHV_~L z5yXDPp>7dT!A*X1q-k1C{W(lc+g;XSuIr{^1Z!e6b450+k9%8`9~r$qKemj2xPTh( zp;QW&L3mT5L{meGfxdB=QDYKh8o2eHKN(NfL9%+=n7^(WhKRflxh@1|GVrQ}Wm+g2 zxr0armPlrj&3KZyhYx9o5-*sgWG`eaae^L2(HRfImElwm)&y>{tXnwhebx@t3DY(| zP}UrJ>Lrxxl36ZpnEJ8na9*qIhUsEqtZHLFK^?6n9Ky$Ma!X?T6xwxRWg4huMJo87 zrX}U2QyeV=0IIqVshd@J56m)?EC3cP4;gAY0WV~CuIKkPsMrB#G9MX>Q!=@{A5OEv*rU+8xH*sO=MpY12W zaqC^6uE)Ma7I6XTdtnPbLdRKqRLSHq4a(akgi!F9dV*KjQhm=P(Y}jvl5PnJY7%2H zCg6T%#!XtzO;#LTS1NeS2?4QHe_P8-fO79lRO5pay()qK-rDj^Z`#ityG?{dnaVU& zYL>3)0dankMW>Y~%5hhmbPG|BmA%7BRf9BuCHVFC`@v2x9JkW}&&fytUmDeu9IM6r zp%abzv+AwWi41+LXtbnr{b8^t9AQ@uXV_@~mzeGFGOChDQf!O@+e)mys>4;P(XC4y zHmesWtMU!<5_ch9A?hHK_aexk)+IQVm>K~8&Z29k3(2gbzbi0qzG z0fqr-N$!Oc7#lb0-Xym{Wmoyf?m{PD1E+j!f0d=1meo9CA|n+>*}+r!O!ag)F|ndH zGH^mN!g}0M^gNR2h?(nja}uq}qLp)_5N(AmBbtjeD|(*y4dUTM@5Ll6)>@j|xqu(U zN=5=Gal09lu=J*!we!YOu(j;p91BjcAGYCE+htnL zVvSqn#*7RG^P{gyd(@gl>XXeKDw$c3_q!-0==3rS^&pu-Z?v|DsIwH?r*WJNXkN9) z`Gq#}BQ@4D(T8XDQLvh@3!eC_ARwce*R$Ln&>O(uVK-}lSt-*n>5 zKLJQyw5Tn&ci)D1(t-&C;d4`*Akcn(-yR9ufH2+TUM1@y&(g7&OXdN)hOFnJIOrj` zN#$Di#QQ^6asWFP54{>X8UHbK{yv1v^ncNn)&`aq*1u}YX*DyO4K}prrTe!*ou4HD z-lDfhGv=%^!k)HsaJFwgI@jeklIy@&)>XV0&Fz#p_E;?n!1tt&kYLzXKra94aw4ca z(NIa*J1iaA;bEa}JYa;^*wWN&!Wv;^uA08eOjX2goOQ^*`=*7mrKVVEHXrxxj-!BB z$eGt5w=R})3?kYDeP;fNo<+Zgf0D1>tlkIueYeerRV*)bnJUCalA{iT!s``v6RrFm z6o-%@Zy$CVNyxTt)KN&Xm_%W#<=v@kvRrzEo%JPhwD6S_AY{ls?EIjcSfS*s9t@Wd z&u6kOhp;dTpNDNp7&ix8o)Rqd?F(tdK-O4(gqKbcdDrFwORkGPXR`5(hkgr5uu|!# z!u3dc)-eI?VU6DNz!QY$9Jv>vNS5YcoQ)2ybJ7_C58HgrJkyv3$-wi2=L&Hy zV+t@vdWB<5{g3H%J8#@k{N>@+JRXiatfhvCGJx8#1U_=p`+`Rb5j7mJK$u)s?^iYi z!~>)Z4`xg%d~tWtE=?BkA$H!sOIVmBJnsv+d%F6}i(Sc|gAGK;Th+u@EKn&ZzBn&K zm)D`JOSZFIXto#MB?lXX!M;o?qNITyrg_Gb2s*|?7DFqkH?$I-IA&(znw_6h?C6Rz zCnb%I1*%M!B*%cZFUFl6cQ^@$hcpW2sIgeOQ5e23>~nMj_Bm}D2ntv9jWHSy6&^7{ z3AVlfpl%f50=T2uMI~!Ob{WEc2u+Lv0UPXCBvX)KZt+|`IG`CvR)0EdEH2#`cW$P% zq^0zk5`!@E(AK|!;ZCh+nY3^%woIULlpaAfDm7%XJ^kpIK6>Mu4s|_u<-|-U^0gTq z@}LqAsUzQgt?O{Np@6mW4fNaPc6N*outbA5#Jc$?5<7@DM05S!80KpexRy?u zRz)WC)>(Yd*(q;4S`~E&jjkH@m;-e7cd|;s# z!mRTtW-ok?3=)LaDJcvQGq*WDYD|npLLNocNO^GV?OnY&mcwFkM=( z)2{|4R_R*gP?8HFrCX{rtfeKYOu(2a=Gen}A3T9C%Z*IBL|1-4yB%>$>6OKyWxq0Yl&|g9!&aD}rm|e}2iBBONYtTofk{|_zQChr1i?^9LJcr2NJ>mQz+esfhx6i; zii~d3CBDd@T>YIm8Ju;fZgH>$;cq}{`>KGeTmf1qPxYqH$6rh?^035jS?v)m%gu`t z`*3tJDCzPd$d4-|M|3<$9hHPe4?0$E^758~dlKGv3+%4wxXXez$TZ|RJzGjusO*6p zc&E}LHdnWD!ww~VU(L&S@)e(y9=Sa%mG$UX(A#l~;9ymzzN3*%cwq`6v63=F8)t8n@xAN9 z-8Cyw97M8<%j>sdV~-`#lNQUML1a>-{e~}tH)X#uXx8V%l8&5owYLI+AcO;Pc<5qc z?K)357f$Oum%c{|6Z65Sh%7=AY;p4QC3gBrqmL3o1J6T^2E}&c9SM8R5JnC6#)DZJ zl=cSUjI6k1nOit?nxQAjTouihmKHm);Ntycwe;rFAj>)?+PvV<&4-EHS^6N{CxQ}HT)~>} zIk!Pdb@yDHey#)9?e$rr{Kj%8Py8}g(*k{aP$_YYhkK|p+0l=mTO?F~ zd5S`w&X8V^;SCz%#fZOVVhD}FGRIf-?od$;F|#bQO6DP~ngqg9Bl6%+U_n_;60C_% zy4W-#aLH+9R)>2|LkG#2_G@3bim|>k$;CXl=_aqO0l}DUb5jM4Mbt(02&{hwZjr25 zAf!h+pnKyoFyI8bEGdatT9qcC9}l_Em!m(Hw26)XUJK+ouna<81>5!8oLJ--e}i97Dlr>Wo%OqAfP{*QwXkM9b7`n)$|ndZ`B%pNwV2FVG4 z6t1Nh)?`*9qoheXH)UrgHzMiqrz5B3W%MW3y0?y&&D|5wbe4c4dy{G8CjIq67t=xB zAwM8^B2Bhmr;=p__E!Z(wdXj=e$!AY5T8JFn->*lVV6R~?%$yXc;H#bG#kaA#c@4c z+=%4RZYW}%gH5GpI31l1T4S7NWyz%KLW=GM%vtH1RcjX3k;n2?W6sFzutz&K!uI=Z zr2#vBq*=MR(Bcx%T(!&asE!k%=rS#deY+`jPy^m>Z`w#-<0G)bfeo$`){; zoHEz7!OV!md+H&KB?RLM^tGT$KfPhMW3-~;PX2KN&P2nYuF_kwEF4AAPrvFzifQ7!@=ikD> z|J;onBmM_A~e??1wyu-CJJzaS0&9gO}9`1ZfS|JjfFTMhouB0qZR=WVZ4zmQP9deDAP zF#f&nuQm9CSsw690SoKj&}! z^T7F4ImP}L_RoBdUt95WjPplS@=xjiM~=Tfi1vVgYt^qc8&CObtNuxK{OrK}wPxU{ z|HSe4HT!v}|Lp4c;r#tm!gBtJ^`8~N?=AnC|L4j2hr{GgX)O3Z@c)hbL`EF^^+^T- Q!hZd^e0>~Ms(yU>f4b0my8r+H diff --git a/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh b/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh deleted file mode 100755 index 8c212caf..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/rebuild_fs.sh +++ /dev/null @@ -1 +0,0 @@ -rm ../fs_module.jar;jar vcf ../fs_module.jar src diff --git a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java deleted file mode 100644 index f3061bc2..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/Fs_fsData_QC_64.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.nrg.xnat.turbine.modules.screens; - - -import java.io.File; -import java.util.Iterator; - -import org.apache.turbine.util.RunData; -import org.apache.velocity.context.Context; -import org.nrg.xdat.om.FsFsdata; -import org.nrg.xdat.om.XnatImagesessiondata; -import org.nrg.xdat.om.XnatResourcecatalog; -import org.nrg.xdat.turbine.modules.screens.SecureReport; - -public class Fs_fsData_QC_64 extends SecureReport { - public static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Fs_fsData_QC_64.class); - public void finalProcessing(RunData data, Context context) { - try{ - org.nrg.xdat.om.FsFsdata fs = new org.nrg.xdat.om.FsFsdata(item); - context.put("fs",fs); - XnatImagesessiondata om = fs.getImageSessionData(); - context.put("mr",om); - } catch(Exception e){ - logger.debug("Fs_fsData_QC_64", e); - } - } -} diff --git a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java b/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java deleted file mode 100644 index bb2732e8..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/java/org/nrg/xnat/turbine/modules/screens/XDATScreen_edit_fs_fsData.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.nrg.xnat.turbine.modules.screens; - - -import org.apache.turbine.util.RunData; -import org.apache.velocity.context.Context; -import org.nrg.xdat.turbine.utils.TurbineUtils; -import org.nrg.xft.ItemI; -import org.nrg.xft.XFTItem; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class XDATScreen_edit_fs_fsData extends org.nrg.xnat.turbine.modules.screens.EditImageAssessorScreen { - static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(XDATScreen_edit_fs_fsData.class); - /* (non-Javadoc) - * @see org.nrg.xdat.turbine.modules.screens.EditScreenA#getElementName() - */ - public String getElementName() { - return "fs:fsData"; - } - - public ItemI getEmptyItem(RunData data) throws Exception - { - return super.getEmptyItem(data); - } - /* (non-Javadoc) - * @see org.nrg.xdat.turbine.modules.screens.SecureReport#finalProcessing(org.apache.turbine.util.RunData, org.apache.velocity.context.Context) - */ - public void finalProcessing(RunData data, Context context) { - String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); - - context.put("today", today); - } -}; diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml deleted file mode 100644 index f3fa1343..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_fsData_display.xml +++ /dev/null @@ -1,5137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '/@WEBAPP/images/r.gif'::text - - - - - - - - - - - - - - - - - COALESCE(@Field2, @Field1) - - - - - - - - - - - - - - - - - - - - - - fs_fsdata_project_id - - - - - - - - - - - SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_fsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH - - - - - - - - - - - - - - - - - - - - - - - - field - SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:fsData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@COL1 AS numeric),0) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@Field1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3)> - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - ROUND(CAST(@COL1 AS numeric)/1000,3) - - - - - - - - - - - - - --> - ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) - - - - - - - - - - - - - - ROUND(((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric) + CAST(@COLA AS numeric) + CAST(@COLB AS numeric))/1000),3) - - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) - - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric))/1000,3) - - - - - - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) - - - - - - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric) + CAST(@COL5 AS numeric) + CAST(@COL6 AS numeric) + CAST(@COL7 AS numeric) + CAST(@COL8 AS numeric) + CAST(@COL9 AS numeric))/1000,3) - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) - - - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric) + CAST(@COL3 AS numeric) + CAST(@COL4 AS numeric))/1000,3) - - - - ROUND((CAST(@COL1 AS numeric))/1000,3) - - - - ROUND((CAST(@COL1 AS numeric))/1000,3) - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) - - - - - ROUND((CAST(@COL1 AS numeric) + CAST(@COL2 AS numeric))/1000,3) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml deleted file mode 100644 index 8f8d4fdb..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/display/fs_longFSData_display.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - '/@WEBAPP/images/r.gif'::text - - - - - - - - - - - - - - - CAST(COALESCE(FLOOR(CAST((CAST(((@Field1) - (@Field2))AS FLOAT4)/365) AS numeric)),FLOOR((EXTRACT(YEAR FROM @Field1)) - (@Field3))) AS numeric) - - - - - - - - COALESCE(@Field2, @Field1) - - - - - - - - - - - - - - - - - - - - - - fs_longfsdata_project_id - - - - - - - - - - - SELECT DISTINCT COALESCE(label,sharing_share_xnat_experimentda_id) AS fs_longfsdata_project_id,sharing_share_xnat_experimentda_id FROM ( SELECT sharing_share_xnat_experimentda_id,label FROM xnat_experimentdata_share WHERE project='@WHERE' UNION SELECT id,label FROM xnat_experimentData WHERE project='@WHERE' )SEARCH - - - - - - - - - - - - field - SELECT DISTINCT ON ( e.ID) e.ID AS expt_id,field FROM xnat_experimentData_field ef JOIN (SELECT ID,extension,element_name FROM xnat_experimentData e JOIN xdat_meta_element xme ON e.extension=xme.xdat_meta_element_id WHERE xme.element_name='fs:longFSData') e on ef.fields_field_xnat_experimentdat_id=e.id WHERE name='@WHERE' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd b/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd deleted file mode 100644 index af7eafee..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/schemas/fs/fs.xsd +++ /dev/null @@ -1,332 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js b/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js deleted file mode 100644 index 7de59913..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/scripts/slideshow.js +++ /dev/null @@ -1,403 +0,0 @@ -//================================================== -// slide object -//================================================== -function slideImg(src,link,txt,target,attr) { - // s = new slideImg(); - - // Image URL - this.src = src; - - // Link URL - this.link = link; - - //Alt text for the image - this.text = txt; - - // Name of the target window ("_blank") - this.target = target; - - // Custom duration for the slide, in milliseconds. - // This is an optional parameter. - // this.timeout = 3000 - - // Attributes for the target window: - // width=n,height=n,resizable=yes or no,scrollbars=yes or no, - // toolbar=yes or no,location=yes or no,directories=yes or no, - // status=yes or no,menubar=yes or no,copyhistory=yes or no - // Example: "width=200,height=300" - this.attr = attr; - - // Create an image object for the slide - if (document.images) { - this.image = new Image(); - } - - // Flag to tell when load() has already been called - this.loaded = false; - - //-------------------------------------------------- - this.load = function() { - // This method loads the image for the slide - - if (!document.images) { return; } - - if (!this.loaded) { - this.image.src = this.src; - this.image.alt = this.text; - this.loaded = true; - } - } - - //-------------------------------------------------- - this.hotlink = function() { - // This method jumps to the slide's link. - // If a window was specified for the slide, then it opens a new window. - var mywindow; - - // If this slide does not have a link, do nothing - if (!this.link) return; - - // Open the link in a separate window? - if (this.target) { - - // If window attributes are specified, - // use them to open the new window - if (this.attr) { - mywindow = window.open(this.link, this.target, this.attr); - - } else { - // If window attributes are not specified, do not use them - // (this will copy the attributes from the originating window) - mywindow = window.open(this.link, this.target); - } - - // Pop the window to the front - if (mywindow && mywindow.focus) mywindow.focus(); - - } else { - // Open the link in the current window - location.href = this.link; - } - } -} - -//================================================== -// slideshow object -//================================================== -function slideshow( slideshowname ) { - // ss = new slideshow("ss"); - - // Name of this object - // (required if you want your slideshow to auto-play) - // For example, "SLIDES1" - this.name = slideshowname; - - // When we reach the last slide, should we loop around to start the - // slideshow again? - this.repeat = true; - - // Number of images to pre-fetch. - // -1 = preload all images. - // 0 = load each image is it is used. - // n = pre-fetch n images ahead of the current image. - // I recommend preloading all images unless you have large - // images, or a large amount of images. - this.prefetch = -1; - - // IMAGE element on your HTML page. - // For example, document.images.SLIDES1IMG - this.image; - - // ID of a DIV element on your HTML page that will contain the text. - // For example, "slides2text" - // Note: after you set this variable, you should call - // the update() method to update the slideshow display. - this.textid; - - // Milliseconds to pause between slides. - // Individual slides can override this. - this.timeout = 3000; - - // Hook functions to be called before and after updating the slide - // this.pre_update_hook = function() { } - // this.post_update_hook = function() { } - - // These are private variables - this.slides = new Array(); - this.current = 0; - this.timeoutid = 0; - - //-------------------------------------------------- - // Public methods - //-------------------------------------------------- - this.add_slide = function(slide) { - // Add a slide to the slideshow. - // For example: - // SLIDES1.add_slide(new slide("s1.jpg", "link.html")) - - var i = this.slides.length; - - // Prefetch the slide image if necessary - if (this.prefetch == -1) { - slide.load(); - } - - this.slides[i] = slide; - } - - //-------------------------------------------------- - this.play = function(timeout) { - // This method implements the automatically running slideshow. - // If you specify the "timeout" argument, then a new default - // timeout will be set for the slideshow. - - // Make sure we're not already playing - this.pause(); - - // If the timeout argument was specified (optional) - // then make it the new default - if (timeout) { - this.timeout = timeout; - } - - // If the current slide has a custom timeout, use it; - // otherwise use the default timeout - if (typeof this.slides[ this.current ].timeout != 'undefined') { - timeout = this.slides[ this.current ].timeout; - } else { - timeout = this.timeout; - } - - // After the timeout, call this.loop() - this.timeoutid = setTimeout( this.name + ".loop()", timeout); - } - -//-------------------------------------------------- - this.playPause = function(id) { - // This method implements the automatically running slideshow. - // If you specify the "timeout" argument, then a new default - // timeout will be set for the slideshow. - - if (document.getElementById(id).value == "Pause") { - document.getElementById(id).value = "Play "; - clearTimeout(this.timeoutid); - this.timeoutid = 0; - } else { - this.next(); - - document.getElementById(id).value = "Pause"; - - clearTimeout(this.timeoutid); - this.timeoutid = 0; - - // If the current slide has a custom timeout, use it; - // otherwise use the default timeout - if (typeof this.slides[ this.current ].timeout != 'undefined') { - timeout = this.slides[ this.current ].timeout; - } else { - timeout = this.timeout; - } - - // After the timeout, call this.loop() - this.timeoutid = setTimeout( this.name + ".loop()", timeout); - } - } - - //-------------------------------------------------- - this.pause = function() { - // This method stops the slideshow if it is automatically running. - - if (this.timeoutid != 0) { - - clearTimeout(this.timeoutid); - this.timeoutid = 0; - - } - } - - //-------------------------------------------------- - this.update = function() { - // This method updates the slideshow image on the page - - // Make sure the slideshow has been initialized correctly - if (! this.valid_image()) { return; } - - - // Convenience variable for the current slide - var slide = this.slides[ this.current ]; - - // Load the slide image if necessary - slide.load(); - - // Update the image. - this.image.src = slide.image.src; - this.image.alt = slide.text; - this.image.title = slide.text; - - // Call the post-update hook function if one was specified - if (typeof this.post_update_hook == 'function') { - this.post_update_hook(); - } - - // Do we need to pre-fetch images? - if (this.prefetch > 0) { - - var next, prev, count; - - // Pre-fetch the next slide image(s) - next = this.current; - prev = this.current; - count = 0; - do { - - // Get the next and previous slide number - // Loop past the ends of the slideshow if necessary - if (++next >= this.slides.length) next = 0; - if (--prev < 0) prev = this.slides.length - 1; - - // Preload the slide image - this.slides[next].load(); - this.slides[prev].load(); - - // Keep going until we have fetched - // the designated number of slides - - } while (++count < this.prefetch); - } - } - - //-------------------------------------------------- - this.goto_slide = function(n) { - // This method jumpts to the slide number you specify. - // If you use slide number -1, then it jumps to the last slide. - // You can use this to make links that go to a specific slide, - // or to go to the beginning or end of the slideshow. - // Examples: - // onClick="myslides.goto_slide(0)" - // onClick="myslides.goto_slide(-1)" - // onClick="myslides.goto_slide(5)" - - if (n == -1) { - n = this.slides.length - 1; - } - - if (n < this.slides.length && n >= 0) { - this.current = n; - } - - this.update(); - } - - //-------------------------------------------------- - this.next = function() { - // This method advances to the next slide. - - // Increment the image number - if (this.current < this.slides.length - 1) { - this.current++; - } else if (this.repeat) { - this.current = 0; - } - - this.update(); - } - - - //-------------------------------------------------- - this.previous = function() { - // This method goes to the previous slide. - - // Decrement the image number - if (this.current > 0) { - this.current--; - } else if (this.repeat) { - this.current = this.slides.length - 1; - } - - this.update(); - } - - //-------------------------------------------------- - this.zoomUp = function() { - // This method increments the image height by 50 - var oldHeight = this.image.height; - this.image.height = oldHeight + 50; - this.update(); - } - - //-------------------------------------------------- - this.zoomDown = function() { - // This method increments the image height by 50 - var oldHeight = this.image.height; - this.image.height = oldHeight - 50; - this.update(); - } - - //-------------------------------------------------- - this.get_text = function() { - // This method returns the text of the current slide - - return(this.slides[ this.current ].text); - } - - //-------------------------------------------------- - this.hotlink = function() { - // This method calls the hotlink() method for the current slide. - - this.slides[ this.current ].hotlink(); - } - -//-------------------------------------------------- - this.loop = function() { - // This method is for internal use only. - // This method gets called automatically by a JavaScript timeout. - // It advances to the next slide, then sets the next timeout. - // If the next slide image has not completed loading yet, - // then do not advance to the next slide yet. - - // Make sure the next slide image has finished loading - if (this.current < this.slides.length - 1) { - next_slide = this.slides[this.current + 1]; - if (next_slide.image.complete == null || next_slide.image.complete) { - this.next(); - } - } else { // we're at the last slide - this.next(); - } - - // Keep playing the slideshow - this.play( ); - } - - - //-------------------------------------------------- - this.valid_image = function() { - // Returns 1 if a valid image has been set for the slideshow - - if (!this.image) - { - return false; - } - else { - return true; - } - } - - //-------------------------------------------------- - this.getElementById = function(element_id) { - // This method returns the element corresponding to the id - - if (document.getElementById) { - return document.getElementById(element_id); - } - else if (document.all) { - return document.all[element_id]; - } - else if (document.layers) { - return document.layers[element_id]; - } else { - return undefined; - } - } - } - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm deleted file mode 100644 index f1d2d6ee..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/templates/layouts/Fs_fsData_QC_64.vm +++ /dev/null @@ -1,94 +0,0 @@ -##LAYOUT (also see other file in screens) -##Copyright 2005 Harvard University / Howard Hughes Medical Institute (HHMI) All Rights Reserved - -#set ($projlabel = $om.getProject()) -#set ($subjlabel = $mr.getSubjectData().getLabel()) -#set ($mrlabel = $om.getImageSessionData().getLabel()) -#set ($xsi_type = $!item.getXSIType()) -#set ($fslabel = $!item.getStringProperty("$xsi_type/label")) -#set ($snapshots_path = "/xnat/data/archive/projects/$projlabel/subjects/$subjlabel/experiments/$mrlabel/assessors/$fslabel/out/resources/SNAPSHOTS/files") - - - - - - - $!systemName - #includeJSFile() - - - - - - - - - - -
- $screen_placeholder -
- - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm deleted file mode 100644 index 63585c58..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/Fs_fsData_QC_64.vm +++ /dev/null @@ -1,185 +0,0 @@ -##SCREEN (also see other file in screens) - - - -
- - - - - - - - - -
-
- 2D Slices -
Session: $om.getImageSessionData().getLabel()Zoom Delay:
- - - - - - - - - -
AXIAL SLICES
-
- - - - - -
-
SST Axial Slices
- - - - - - - - - - -
CORONAL SLICES
- - - - - -
SST Coronal Slices
- - - - - - - - - - -
SAGITTAL SLICES
- - - - - -
SST Sagittal Slices
- - - #set ($search_element = "xnat:mrSessiondata") - #set ($search_field = "xnat:mrSessiondata.ID") - #set ($search_value = $om.getImagesessionId()) - #set ($project = $om.getProject()) - - #xdatPassItemFormFields($search_element $search_field $search_value $project) - #set ($label = "DATA") - - -
- - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm deleted file mode 100644 index b287106e..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_edit_fs_fsData.vm +++ /dev/null @@ -1,95 +0,0 @@ - -$page.setTitle("XDAT") -$page.setLinkColor($ui.alink) -$page.setVlinkColor($ui.vlink) - -#set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) -#set($days = [ 1..31 ]) -#set($years = [ $!turbineUtils.getYear()..1990]) - -#set($qcValues = [["Failed","Failed"],["Failed-needs reprocessing","Failed-needs reprocessing"],["Passed","Passed"],["Passed with edits","Passed with edits"], ["Rerun","Rerun"]]) -#if ($data.message) - $data.message -#end -

-

- -#if($vr) - Invalid parameters:
$vr.toHTML()
-
-#end - - - - - - - - - - - - -
- - - - -
-
Freesurfer Details
-
-
- - - - -
- - - - - - - - - - -
-
- #parse("/screens/xnat_edit_experimentData.vm") -
-
#parse("/screens/EditProjectSpecificFields.vm")
- - - - - - -

FreeSurfer QC
- - - - - #xdatHiddenBox("fs:fsData/validation/xnat_validationData_id" $item "") - #xdatHiddenBox("fs:fsData/imageSession_ID" $item "") - #xdatHiddenBox("fs:fsData/fsversion" $item "") - #xdatHiddenBox("fs:fsData/procversion" $item "") - #xdatHiddenBox("fs:fsData/validation/validated_by" $item $user.username) - #xdatHiddenBox("fs:fsData/validation/date" $item "") -
Status#cndaSelectBoxSimple("fs:fsData/validation/status" $item $qcValues $vr)
Method#xdatStringBox("fs:fsData/validation/method" $item "" $vr)
Notes#xdatTextArea("fs:fsData/validation/notes" $item "" $vr 10 30)
-
- -
-
-
- #xdatEditProps($item $edit_screen) -
-
- - diff --git a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm b/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm deleted file mode 100644 index 016dc27d..00000000 --- a/dax/xnat_modules/freesurfer/fs_module/src/templates/screens/XDATScreen_report_fs_fsData.vm +++ /dev/null @@ -1,234 +0,0 @@ - -$page.setTitle("Freesurfer Analysis Details") -$page.setLinkColor($ui.alink) -$page.setVlinkColor($ui.vlink) -#if ($data.getParameters().getString("popup")) - #set ($popup = $data.getParameters().getString("popup") ) - #set ($popup = "false") -#end - - - - - - - - -
- - - - -
- Freesurfer Analysis Details -
-
- - - - - -
- - #set ($id=".ID") - #set ($field="$om.getImageSessionData().getXSIType()$id") - - #set ($url = "$link.setAction('DisplayItemAction').addPathInfo('search_element',$om.getImageSessionData().getXSIType()).addPathInfo('search_field',$field).addPathInfo('search_value',$om.getImageSessionData().getId()).addPathInfo('project',$om.getProject())") - - - - - - - -
Project$!item.getStringProperty("fs:fsData/project")
MRSession$om.getImageSessionData().getLabel()
FS ID$!item.getStringProperty("fs:fsData/label")
FS Date$!item.getProperty("fs:fsData/date")
Note$!item.getStringProperty("fs:fsData/note")
FS Version$!item.getStringProperty("fs:fsData/fsversion")
Proc Version$!item.getStringProperty("fs:fsData/procversion")
-
- - - - - - - - -
Job Information
Job Status$!item.getStringProperty("fs:fsData/procstatus")
Job ID$!item.getStringProperty("fs:fsData/jobid")
Job Start Date$!item.getStringProperty("fs:fsData/jobstartdate")
Job Node$!item.getStringProperty("fs:fsData/jobnode")
Walltime Used$!item.getStringProperty("fs:fsData/walltimeused")
Mem Used$!item.getStringProperty("fs:fsData/memused")
-
- - - - - - - -
QC Information
Status$!item.getStringProperty("fs:fsData/validation/status")
Set by$!item.getStringProperty("fs:fsData/validation/validated_by")
Date$!item.getStringProperty("fs:fsData/validation/date")
Method$!item.getStringProperty("fs:fsData/validation/method")
Notes$!item.getStringProperty("fs:fsData/validation/notes")
-
- #elementActionsBox($element $search_field $search_value $data.getSession().getAttribute("user") $item) -
-
- -
-
- -#set ($url = "$link.setPage('Fs_fsData_QC_64.vm').addPathInfo('search_value',$item.getProperty('ID')).addPathInfo('search_element','fs:fsData').addPathInfo('search_field','fs:fsData.ID')") -View Snapshots - -
-
- -#set ($scanCounter = 0) - - - Subcortical Segmentation - - -
- - -
-#set ($scanCounter = 1) - - - Surface Measures - - - - - - -
- -
-#set ($scanCounter = 2) - - - Processing parameters - - - - - -
- -
-#set ($scanCounter = 3) - - - Log files - - - - From 5f459d214037fe5d251990b48142b5bc005bf678 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:16:09 +0100 Subject: [PATCH 36/62] Create README.md Adding tutorial on how to install the assessors types to a XNAT --- dax/xnat_modules/README.md | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dax/xnat_modules/README.md diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md new file mode 100644 index 00000000..8349c370 --- /dev/null +++ b/dax/xnat_modules/README.md @@ -0,0 +1,66 @@ +Tutorial to install the data-types fs:fsData and proc:genProcData to your XNAT installation: + +Prerequisites: install a XNAT instance. + Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT + +On XNAT VM: + 1) Make a BACKUP of your $XNAT_HOME, postgres db, and tomcat deployment + 2) Stop tomcat + 3) Remove default FreeSurfer files if installed: + rm -r ${XNAT_HOME}/plugin-resources/project-skeletons/xnat/src/schemas/fs + rm -r ${XNAT_HOME}/projects/xnat/src/schemas/fs + rm -r ${XNAT_HOME}/deployments/xnat/src/schemas/fs + # also need to delete FS files from tomcat webapps directory if already deployed + + 4) Add modules + cd ${XNAT_HOME} + mkdir modules + # file to copy: fs_module.jar & proc_module.jar + cp jar_files/*.jar ${XNAT_HOME}/modules/ # copy the jar files to your "modules" folder + + 5) Run xnat update + cd ${XNAT_HOME} + bin/update -Ddeploy=true + + 6) Run sql update + cd ${XNAT_HOME}/deployments/xnat/ + psql -d xnat -f sql/xnat-update.sql + + 7) Start tomcat + +ON XNAT webpage: + 1) Log onto XNAT as admin + 2) click Administer > Data types + 3) click Setup Additional Data Type + 4) for fs:fsData -- choose fs:fsData + a) Add to the fields: + enter "FreeSurfer" in both Singular Name and Plural Name field + enter "FS" in Code field + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + Remove Name: delete + Display Name: Delete + Grouping: + Image: delete.gif + Popup: + Secure Access: delete + Feature: + Additional Parameters: + Sequence: 4 + c) click submit and then accept defaults for subsequent screens + 5) for proc:genProcData + a) Add to the fields: + enter "Processing" in both Singular Name and Plural Name field + enter "Proc" in Code field + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + Remove Name: delete + Display Name: Delete + Grouping: + Image: delete.gif + Popup: + Secure Access: delete + Feature: + Additional Parameters: + Sequence: 4 + c) click submit and then accept defaults for subsequent screens + +You are now ready to use the two assessors fs:fsData and proc:genProcData From 84c3a00dc9219179671150e43af7c6c6c0d6aaaa Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:16:54 +0100 Subject: [PATCH 37/62] Update README.md --- dax/xnat_modules/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 8349c370..b438cdce 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -1,4 +1,5 @@ Tutorial to install the data-types fs:fsData and proc:genProcData to your XNAT installation: +=== Prerequisites: install a XNAT instance. Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT From 20e754384cfbc070957c30d8b9278b1548feedc0 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:17:36 +0100 Subject: [PATCH 38/62] Update README.md --- dax/xnat_modules/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index b438cdce..afdb4468 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -1,6 +1,8 @@ -Tutorial to install the data-types fs:fsData and proc:genProcData to your XNAT installation: +Tutorial to install our two data-types to your XNAT installation === +Installation of fs:fsData and proc:genProcData + Prerequisites: install a XNAT instance. Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT From eb06d6906021ac2dcde875ab4212ce147f2e686c Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:18:56 +0100 Subject: [PATCH 39/62] Update README.md --- dax/xnat_modules/README.md | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index afdb4468..9163a904 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -7,63 +7,111 @@ Prerequisites: install a XNAT instance. Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT On XNAT VM: + 1) Make a BACKUP of your $XNAT_HOME, postgres db, and tomcat deployment + 2) Stop tomcat + 3) Remove default FreeSurfer files if installed: + rm -r ${XNAT_HOME}/plugin-resources/project-skeletons/xnat/src/schemas/fs + rm -r ${XNAT_HOME}/projects/xnat/src/schemas/fs + rm -r ${XNAT_HOME}/deployments/xnat/src/schemas/fs + # also need to delete FS files from tomcat webapps directory if already deployed 4) Add modules + cd ${XNAT_HOME} + mkdir modules + # file to copy: fs_module.jar & proc_module.jar + cp jar_files/*.jar ${XNAT_HOME}/modules/ # copy the jar files to your "modules" folder 5) Run xnat update + cd ${XNAT_HOME} + bin/update -Ddeploy=true 6) Run sql update + cd ${XNAT_HOME}/deployments/xnat/ + psql -d xnat -f sql/xnat-update.sql 7) Start tomcat ON XNAT webpage: + 1) Log onto XNAT as admin + 2) click Administer > Data types + 3) click Setup Additional Data Type + 4) for fs:fsData -- choose fs:fsData + a) Add to the fields: + enter "FreeSurfer" in both Singular Name and Plural Name field + enter "FS" in Code field + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + Remove Name: delete + Display Name: Delete + Grouping: + Image: delete.gif + Popup: + Secure Access: delete + Feature: + Additional Parameters: + Sequence: 4 + c) click submit and then accept defaults for subsequent screens + 5) for proc:genProcData + a) Add to the fields: + enter "Processing" in both Singular Name and Plural Name field + enter "Proc" in Code field + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + Remove Name: delete + Display Name: Delete + Grouping: + Image: delete.gif + Popup: + Secure Access: delete + Feature: + Additional Parameters: + Sequence: 4 + c) click submit and then accept defaults for subsequent screens You are now ready to use the two assessors fs:fsData and proc:genProcData From 5130a6c8271aa3836bdd42b8d5319ff3942f7318 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:20:23 +0100 Subject: [PATCH 40/62] Update README.md --- dax/xnat_modules/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 9163a904..067146f3 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -1,12 +1,12 @@ Tutorial to install our two data-types to your XNAT installation === -Installation of fs:fsData and proc:genProcData +#Installation of fs:fsData and proc:genProcData Prerequisites: install a XNAT instance. Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT -On XNAT VM: +**On XNAT VM:** 1) Make a BACKUP of your $XNAT_HOME, postgres db, and tomcat deployment @@ -46,7 +46,7 @@ On XNAT VM: 7) Start tomcat -ON XNAT webpage: +**ON XNAT webpage:** 1) Log onto XNAT as admin From b60a552e279d346020e3c6b7d9b03187e004d04b Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:21:40 +0100 Subject: [PATCH 41/62] Update README.md --- dax/xnat_modules/README.md | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 067146f3..01a6468c 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -1,7 +1,7 @@ Tutorial to install our two data-types to your XNAT installation === -#Installation of fs:fsData and proc:genProcData +###Installation of fs:fsData and proc:genProcData Prerequisites: install a XNAT instance. Follow https://wiki.xnat.org/display/XNAT16/XNAT+1.6+Installation+Guide to install XNAT @@ -15,27 +15,20 @@ Prerequisites: install a XNAT instance. 3) Remove default FreeSurfer files if installed: rm -r ${XNAT_HOME}/plugin-resources/project-skeletons/xnat/src/schemas/fs - rm -r ${XNAT_HOME}/projects/xnat/src/schemas/fs - rm -r ${XNAT_HOME}/deployments/xnat/src/schemas/fs - # also need to delete FS files from tomcat webapps directory if already deployed 4) Add modules cd ${XNAT_HOME} - mkdir modules - # file to copy: fs_module.jar & proc_module.jar - cp jar_files/*.jar ${XNAT_HOME}/modules/ # copy the jar files to your "modules" folder 5) Run xnat update cd ${XNAT_HOME} - bin/update -Ddeploy=true 6) Run sql update @@ -58,28 +51,19 @@ Prerequisites: install a XNAT instance. a) Add to the fields: - enter "FreeSurfer" in both Singular Name and Plural Name field - - enter "FS" in Code field + enter *FreeSurfer* in both Singular Name and Plural Name field + enter *FS* in Code field b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete - Display Name: Delete - Grouping: - Image: delete.gif - Popup: - Secure Access: delete - Feature: - Additional Parameters: - Sequence: 4 c) click submit and then accept defaults for subsequent screens @@ -88,28 +72,19 @@ Prerequisites: install a XNAT instance. a) Add to the fields: - enter "Processing" in both Singular Name and Plural Name field - - enter "Proc" in Code field + enter *Processing* in both Singular Name and Plural Name field + enter *Proc* in Code field b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete - Display Name: Delete - Grouping: - Image: delete.gif - Popup: - Secure Access: delete - Feature: - Additional Parameters: - Sequence: 4 c) click submit and then accept defaults for subsequent screens From c6ddb3e2657bf8c9579754ddd71d896f13762142 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:23:11 +0100 Subject: [PATCH 42/62] Update README.md --- dax/xnat_modules/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 01a6468c..29828c8a 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -49,12 +49,12 @@ Prerequisites: install a XNAT instance. 4) for fs:fsData -- choose fs:fsData - a) Add to the fields: + a) Add to the fields: - enter *FreeSurfer* in both Singular Name and Plural Name field - enter *FS* in Code field + enter **FreeSurfer** in both Singular Name and Plural Name field + enter **FS** in Code field - b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete Display Name: Delete @@ -66,16 +66,16 @@ Prerequisites: install a XNAT instance. Additional Parameters: Sequence: 4 - c) click submit and then accept defaults for subsequent screens + c) click submit and then accept defaults for subsequent screens 5) for proc:genProcData - a) Add to the fields: + a) Add to the fields: - enter *Processing* in both Singular Name and Plural Name field - enter *Proc* in Code field + enter **Processing** in both Singular Name and Plural Name field + enter **Proc** in Code field - b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete Display Name: Delete @@ -87,6 +87,6 @@ Prerequisites: install a XNAT instance. Additional Parameters: Sequence: 4 - c) click submit and then accept defaults for subsequent screens + c) click submit and then accept defaults for subsequent screens You are now ready to use the two assessors fs:fsData and proc:genProcData From 2cb91a3456d67391170d57040ef76183cf8aec76 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:24:03 +0100 Subject: [PATCH 43/62] Update README.md --- dax/xnat_modules/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 29828c8a..7dcbb987 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -49,12 +49,12 @@ Prerequisites: install a XNAT instance. 4) for fs:fsData -- choose fs:fsData - a) Add to the fields: + 4.a) Add to the fields: - enter **FreeSurfer** in both Singular Name and Plural Name field - enter **FS** in Code field + enter "FreeSurfer" in both Singular Name and Plural Name field + enter "FS" in Code field - b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + 4.b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete Display Name: Delete @@ -66,16 +66,16 @@ Prerequisites: install a XNAT instance. Additional Parameters: Sequence: 4 - c) click submit and then accept defaults for subsequent screens + 4.c) click submit and then accept defaults for subsequent screens 5) for proc:genProcData - a) Add to the fields: + 5.a) Add to the fields: - enter **Processing** in both Singular Name and Plural Name field - enter **Proc** in Code field + enter "Processing" in both Singular Name and Plural Name field + enter "Proc" in Code field - b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: + 5.b) Add to "Available Report Actions" delete if you want to be able to delete assessor with the following values: Remove Name: delete Display Name: Delete @@ -87,6 +87,6 @@ Prerequisites: install a XNAT instance. Additional Parameters: Sequence: 4 - c) click submit and then accept defaults for subsequent screens + 5.c) click submit and then accept defaults for subsequent screens You are now ready to use the two assessors fs:fsData and proc:genProcData From d3b99b2a49220c249b957ad3e1a8515b828fba75 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:30:14 +0100 Subject: [PATCH 44/62] Update GenerateSpiderTemplate Removing manual and using host/user pairs options to let the user set his own info to the spider --- bin/dax_tools/GenerateSpiderTemplate | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index e80785f9..1b89236b 100644 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -53,7 +53,8 @@ def parse_args(): -c : scan_label -d : temp_dir --suffix : suffix (suffix for assessor proctype on XNAT) - --manual : manual (Manual: Ask user for XNAT loggings if not set) + --host : host for XNAT (default: XNAT_HOST env variable) + --user : user on XNAT (default: XNAT_USER env variable) your arguments: ... @@ -84,13 +85,11 @@ class Spider_{name}(ScanSpider): :param xnat_user: user for XNAT if not set in environment variables :param xnat_pass: password for XNAT if not set in environment variables :param suffix: suffix to the assessor creation - :param manual: if using the spider manually (not on the cluster) (boolean) - ask user if the HOST/USER/PASS are not set for XNAT ''' def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): super(Spider_{name}, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, - xnat_host, xnat_user, xnat_pass, suffix, manual) + xnat_host, xnat_user, xnat_pass, suffix) self.inputs = list() def pre_run(self, argument_parse): @@ -138,11 +137,10 @@ if __name__ == '__main__': xnat_subject=args.subj_label, xnat_session=args.sess_label, xnat_scan=args.scan_label, - xnat_host=None, - xnat_user=None, + xnat_host=args.host, + xnat_user=args.user, xnat_pass=None, - suffix=args.suffix, - manual=args.manual) + suffix=args.suffix) # print some information before starting spider_obj.print_init(args, "{author}", "{email_addr}") @@ -166,7 +164,8 @@ def parse_args(): -e : sess_label -d : temp_dir --suffix : suffix (suffix for assessor proctype on XNAT) - --manual : manual (Manual: Ask user for XNAT loggings if not set) + --host : host for XNAT (default: XNAT_HOST env variable) + --user : user on XNAT (default: XNAT_USER env variable) your arguments: ... @@ -196,13 +195,11 @@ class Spider_{name}(SessionSpider): :param xnat_user: user for XNAT if not set in environment variables :param xnat_pass: password for XNAT if not set in environment variables :param suffix: suffix to the assessor creation - :param manual: if using the spider manually (not on the cluster) (boolean) - ask user if the HOST/USER/PASS are not set for XNAT ''' def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): super(Spider_{name}, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host, xnat_user, xnat_pass, suffix, manual) + xnat_host, xnat_user, xnat_pass, suffix) self.inputs = list() def pre_run(self, argument_parse): @@ -249,11 +246,10 @@ if __name__ == '__main__': xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, - xnat_host=None, - xnat_user=None, + xnat_host=args.host, + xnat_user=args.user, xnat_pass=None, - suffix=args.suffix, - manual=args.manual) + suffix=args.suffix) # print some information before starting spider_obj.print_init(args, "{author}", "{email_addr}") From 6b4e961c26ec58c17ff21a4fb278719c35b3fc56 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:39:21 +0100 Subject: [PATCH 45/62] Update spiders.py --- dax/spiders.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index af70e12a..b1cd5649 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -102,10 +102,10 @@ def get_pwd(self, pwd, user): msg = "Enter password for XNAT:" return getpass.getpass(prompt=msg) else: - err = "XNAT_HOST not set by user." + err = "XNAT_PASS not set by user." err += "\nTo set it choose one of this solution:" err += "\n\tSet arguments 'xnat_pass' in the spider class" - err += "\n\tSet the environment variable XNAT_HOST" + err += "\n\tSet the environment variable XNAT_PASS" raise ValueError(err) def select_obj(self, intf, obj_label, resource): @@ -337,7 +337,7 @@ class for scan-spider :param xnat_scan: scan ID on XNAT (if running on a specific scan) """ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_scan, - xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", xnat_host=None, xnat_user=None): + xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): super(ScanSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_host, xnat_user, xnat_pass, suffix) self.xnat_scan = xnat_scan @@ -380,7 +380,7 @@ class for session-spider :param super --> see base class """ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session, - xnat_host=None, xnat_user=None, xnat_pass=None, suffix="", xnat_host=None, xnat_user=None): + xnat_host=None, xnat_user=None, xnat_pass=None, suffix=""): super(SessionSpider, self).__init__(spider_path, jobdir, xnat_project, xnat_subject, xnat_session, xnat_host, xnat_user, xnat_pass, suffix) From 552135c925bfd84ee715296e7662077c5da097d4 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:46:07 +0100 Subject: [PATCH 46/62] Update spiders.py --- dax/spiders.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index b1cd5649..39d5629f 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -52,7 +52,7 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session # Xnat connection settings: self.host = self.get_default_value("xnat_host", "XNAT_HOST", xnat_host) self.user = self.get_default_value("xnat_user", "XNAT_USER", xnat_user) - self.pwd = self.get_pwd(xnat_pwd, xnat_user) + self.pwd = self.get_pwd(xnat_pass, xnat_user) # Suffix if suffix[0] != '_': self.suffix = '_'+suffix else: self.suffix = suffix @@ -95,8 +95,8 @@ def get_pwd(self, pwd, user): if pwd: return pwd else: - if env_name in os.environ: - return os.environ[env_name] + if "XNAT_PASS" in os.environ: + return os.environ["XNAT_PASS"] else: if user: msg = "Enter password for XNAT:" From 891ebaeb91a590962d88e051961ffcba5b44a937 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 11:52:16 +0100 Subject: [PATCH 47/62] Update spiders.py --- dax/spiders.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 39d5629f..a5a4299b 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -50,8 +50,8 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session self.xnat_subject = xnat_subject self.xnat_session = xnat_session # Xnat connection settings: - self.host = self.get_default_value("xnat_host", "XNAT_HOST", xnat_host) - self.user = self.get_default_value("xnat_user", "XNAT_USER", xnat_user) + self.host = self.get_default_value("host", "XNAT_HOST", xnat_host) + self.user = self.get_default_value("user", "XNAT_USER", xnat_user) self.pwd = self.get_pwd(xnat_pass, xnat_user) # Suffix if suffix[0] != '_': self.suffix = '_'+suffix @@ -80,7 +80,7 @@ def get_default_value(self, variable, env_name, value): else: err = "%s not set by user." % (env_name) err += "\nTo set it choose one of this solution:" - err += "\n\tSet arguments '%s' in the spider class" % (variable) + err += "\n\tSet the option --%s in the spider class" % (variable) err += "\n\tSet the environment variable %s" % (env_name) raise ValueError(err) @@ -104,7 +104,7 @@ def get_pwd(self, pwd, user): else: err = "XNAT_PASS not set by user." err += "\nTo set it choose one of this solution:" - err += "\n\tSet arguments 'xnat_pass' in the spider class" + err += "\n\tSet arguments 'xnat_pass' in the spider command line" err += "\n\tSet the environment variable XNAT_PASS" raise ValueError(err) From 7b4f6fb74797b42d94f12f80ba2f1f3201090e23 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 12:10:35 +0100 Subject: [PATCH 48/62] editing the host/user/pass settings Changing the way spider are using host/user/pass from env variable or the spider options. Password will be ask if host and user given to the spider. --- dax/spiders.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index a5a4299b..96f403b7 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -60,13 +60,17 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session self.suffix = re.sub('[^a-zA-Z0-9]', '_', self.suffix) # print time writer: self.time_writer = TimedWriter() + # Export the variable: + os.environ['XNAT_HOST'] = self.host + os.environ['XNAT_USER'] = self.user + os.environ['XNAT_PASS'] = self.pwd def get_default_value(self, variable, env_name, value): """ Return the default value for the variable: if arg not NULL else env variables define by arguments - + :param variable: variable name :param env_name: name of the environment variable :param value: value given by the user @@ -75,7 +79,7 @@ def get_default_value(self, variable, env_name, value): if value: return value else: - if env_name in os.environ: + if env_name in os.environ and os.environ[env_name]!="": return os.environ[env_name] else: err = "%s not set by user." % (env_name) @@ -87,20 +91,20 @@ def get_default_value(self, variable, env_name, value): def get_pwd(self, pwd, user): """ Return the password from env or ask user if the user was set - + :param pwd: password - :param user: user + :param user: user :return: default value """ if pwd: return pwd else: - if "XNAT_PASS" in os.environ: - return os.environ["XNAT_PASS"] + if user: + msg = "Enter the password for user '%s' on your XNAT -- %s :" % (user, self.host) + return getpass.getpass(prompt=msg) else: - if user: - msg = "Enter password for XNAT:" - return getpass.getpass(prompt=msg) + if "XNAT_PASS" in os.environ and os.environ["XNAT_PASS"]!="": + return os.environ["XNAT_PASS"] else: err = "XNAT_PASS not set by user." err += "\nTo set it choose one of this solution:" @@ -111,7 +115,7 @@ def get_pwd(self, pwd, user): def select_obj(self, intf, obj_label, resource): """ Select scan or assessor resource - + :param obj_label: xnat object label (scan ID or assessor label) :param resource: folder name under the xnat object return pyxnat object @@ -148,7 +152,7 @@ def download(self, obj_label, resource, folder): download(scan_id, "DICOM", "/Users/test") or download(assessor_label, "DATA", "/Users/test") - + :param obj_label: xnat object label (scan ID or assessor label) :param resource: folder name under the xnat object :param folder: download directory @@ -183,7 +187,7 @@ def upload(self, fpath, resource): E.g: spider.upload("/Users/DATA/", "DATA") spider.upload("/Users/stats_dir/statistical_measures.txt", "STATS") - + :param fpath: path to the folder/file to be uploaded :param resource: folder name to upload to on the assessor """ @@ -206,7 +210,7 @@ def upload_dict(self, files_dict): E.g: fdict = {"DATA" : "/Users/DATA/", "PDF": "/Users/PDF/report.pdf"} spider.upload_dict("/Users/DATA/", "DATA") - + :param files_dict: python dictionary containing the pair resource/fpath """ self.has_spider_handler() @@ -416,7 +420,7 @@ class TimedWriter(object): Args: name - Names to write with output (default=None) - + Examples: >>>a = Time_Writer() >>>a("this is a test") @@ -424,7 +428,7 @@ class TimedWriter(object): >>>sleep(60) >>>a("this is a test") [00d 00h 01m 00s] this is a test - + Written by Andrew Plassard (Vanderbilt) ''' def __init__(self, name=None): From 282c1b0c3f9e59fe620375e9ab37e5e50eaec067 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 24 Sep 2015 12:11:44 +0100 Subject: [PATCH 49/62] Update spiders.py --- dax/spiders.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index 96f403b7..489affdf 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -107,9 +107,7 @@ def get_pwd(self, pwd, user): return os.environ["XNAT_PASS"] else: err = "XNAT_PASS not set by user." - err += "\nTo set it choose one of this solution:" - err += "\n\tSet arguments 'xnat_pass' in the spider command line" - err += "\n\tSet the environment variable XNAT_PASS" + err += "\n\t Set the environment variable XNAT_PASS" raise ValueError(err) def select_obj(self, intf, obj_label, resource): From fb7a756e1fdf6c2bd01c65aa0c3f1208fccb29c0 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Fri, 25 Sep 2015 15:27:45 +0100 Subject: [PATCH 50/62] Update README.md --- dax/xnat_modules/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dax/xnat_modules/README.md b/dax/xnat_modules/README.md index 7dcbb987..fc7033df 100644 --- a/dax/xnat_modules/README.md +++ b/dax/xnat_modules/README.md @@ -39,7 +39,7 @@ Prerequisites: install a XNAT instance. 7) Start tomcat -**ON XNAT webpage:** +**ON XNAT webapp:** 1) Log onto XNAT as admin From 0d0049871f111309ceb421b655e79f8580aaf750 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Tue, 29 Sep 2015 11:14:38 +0100 Subject: [PATCH 51/62] fix definition for upload_dict edit definition --- dax/spiders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dax/spiders.py b/dax/spiders.py index 489affdf..e2574c64 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -207,7 +207,7 @@ def upload_dict(self, files_dict): following the files python dictionary: {resource_name : fpath} E.g: fdict = {"DATA" : "/Users/DATA/", "PDF": "/Users/PDF/report.pdf"} - spider.upload_dict("/Users/DATA/", "DATA") + spider.upload_dict(fdict) :param files_dict: python dictionary containing the pair resource/fpath """ From 0171fc343b0425b9f09248686788fbbecca688f2 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Tue, 29 Sep 2015 11:56:40 +0100 Subject: [PATCH 52/62] Update GenerateProcessorTemplate --- bin/dax_tools/GenerateProcessorTemplate | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/bin/dax_tools/GenerateProcessorTemplate b/bin/dax_tools/GenerateProcessorTemplate index 4e6a8a3a..0a70d962 100644 --- a/bin/dax_tools/GenerateProcessorTemplate +++ b/bin/dax_tools/GenerateProcessorTemplate @@ -35,7 +35,6 @@ __modifications__ = "{now} - Original write" # Python packages import import os import logging -from dax_spiders import PathSettings from dax import XnatUtils, ScanProcessor, SessionProcessor # set-up logger for printing statements @@ -46,13 +45,14 @@ LOGGER = logging.getLogger('dax') DEFAULT_SPIDER_PATH = os.path.join(SPIDER_PATH, 'Spider_{name}_1_0_0.py') DEFAULT_WALLTIME = '01:00:00' DEFAULT_MEM = 2048 -DEFAULT_SCAN_TYPES = [] # ADD SCAN TYPES """ SCAN_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" +DEFAULT_SCAN_TYPES = [] # ADD SCAN TYPES + # Format for the spider command line -SPIDER_FORMAT = '''python {{spider}} -v --spm {{spm}} \ --p {{proj}} -s {{subj}} -e {{sess}} -c {{scan}} -d {{dir}} --suffix "{{suffix_proc}}"''' +SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}} -c {{scan}}\ +-d {{dir}} --suffix "{{suffix_proc}}"''' class Processor_{name}(ScanProcessor): ''' @@ -63,10 +63,11 @@ class Processor_{name}(ScanProcessor): :param walltime: walltime required by the spider :param mem_mb: memory in Mb required by the spider :param scan_types: scan types on XNAT that the spider should run on - :param spm_path: path to SPM + # # ADD MORE PARAMETERS AS NEEDED HERE # + :param suffix: suffix to the spider ''' def __init__(self, spider_path=DEFAULT_SPIDER_PATH, version=None, @@ -74,7 +75,6 @@ class Processor_{name}(ScanProcessor): scan_types=DEFAULT_SCAN_TYPES, spm_path=PathSettings.SPM_PATH, suffix_proc=''): super(Processor_{name}, self).__init__(scan_types, walltime, mem_mb, spider_path, version, suffix_proc=suffix_proc) - self.spm_path = spm_path # # ADD MORE PARAMETERS AS NEEDED HERE LIKE self.param = param # @@ -90,6 +90,7 @@ class Processor_{name}(ScanProcessor): :param cscan: object cscan define in dax.XnatUtils (see XnatUtils in dax for information) :return: status, qcstatus ''' + # # CODE TO CHECK IF THE PROCESS HAS THE INPUTS NEEDED FROM XNAT # CHECK FUNCTION FROM XnatUtils IN dax: @@ -128,7 +129,6 @@ class Processor_{name}(ScanProcessor): # cmd = SPIDER_FORMAT.format(spider=self.spider_path, - spm=self.spm_path, proj=proj_label, subj=subj_label, sess=sess_label, @@ -141,8 +141,8 @@ class Processor_{name}(ScanProcessor): SESSION_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" # Format for the spider command line -SPIDER_FORMAT = '''python {{spider}} -v --spm {{spm}} \ --p {{proj}} -s {{subj}} -e {{sess}} -d {{dir}} --suffix "{{suffix_proc}}"''' +SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}}\ +-d {{dir}} --suffix "{{suffix_proc}}"''' class {name}_Processor(SessionProcessor): ''' @@ -152,8 +152,6 @@ class {name}_Processor(SessionProcessor): :param version: version of the spider :param walltime: walltime required by the spider :param mem_mb: memory in Mb required by the spider - :param scan_types: scan types on XNAT that the spider should run on - :param spm_path: path to SPM # # ADD MORE PARAMETERS AS NEEDED HERE # @@ -164,7 +162,6 @@ class {name}_Processor(SessionProcessor): spm_path=PathSettings.SPM_PATH, suffix_proc=''): super({name}_Processor, self).__init__(walltime, mem_mb, spider_path, version, suffix_proc=suffix_proc) - self.spm_path = spm_path # # ADD MORE PARAMETERS AS NEEDED HERE LIKE self.param = param # @@ -180,6 +177,7 @@ class {name}_Processor(SessionProcessor): :param csess: object csess define in dax.XnatUtils (see XnatUtils in dax for information) :return: status, qcstatus ''' + # # CODE TO CHECK IF THE PROCESS HAS THE INPUTS NEEDED FROM XNAT # CHECK FUNCTION FROM XnatUtils IN dax: From 9583bdd1bc20863f101a9d9262dffb8b39ea9e32 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Tue, 29 Sep 2015 16:23:47 +0100 Subject: [PATCH 53/62] Create GenerateSettingsTemplate GenerateSettingsTemplate will generate a settings file with the template that dax required. The user can then fill in the blanks. --- bin/dax_tools/GenerateSettingsTemplate | 135 +++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 bin/dax_tools/GenerateSettingsTemplate diff --git a/bin/dax_tools/GenerateSettingsTemplate b/bin/dax_tools/GenerateSettingsTemplate new file mode 100644 index 00000000..0b9caf5e --- /dev/null +++ b/bin/dax_tools/GenerateSettingsTemplate @@ -0,0 +1,135 @@ +""" + Title: GenerateSettingsTemplate + Author: Benjamin Yvernault + contact: b.yvernault@ucl.ac.uk + Purpose: + Generate your ProjectSettingsFile.py following the template describe in this file. +""" + +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +__author__ = 'Benjamin Yvernault' +__email__ = 'b.yvernault@ucl.ac.uk' +__purpose__ = "Generate your ProjectSettingsFile.py following the template describe in this file." +__version__ = '1.0.0' +__modifications__ = '29 Septembre 2015 - Original write' + +import os +from datetime import datetime +from dax import DEFAULT_EMAIL_OPTS, DEFAULT_QUEUE_LIMIT + +DEFAULT_TEMPLATE = """''' + Author: {author} + contact: {email_addr} + Project Settings File name: {name} + Creation date: {now} + Purpose: Settings file to describe the modules/processors for the project(s) +''' + +## header: +__author__ = "{author}" +__email__ = "{email_addr}" +__purpose__ = "Settings file to describe the modules/processors for the project(s)" +__processor_name__ = "{name}" +__modifications__ = "{now} - Original write" + +## Python packages import: +import os +from dax import Launcher +from Xnat_process_importer import * +from Xnat_module_importer import * + +## Arguments for Launcher: +EMAIL = "{email_addr}" +QUEUE_LIMIT = {q_limit} +PRIORITY_ORDER = {p_order} # CHANGE THE ORDER OF PRIORITY FOR YOUR PROJECT(S) +EMAIL_OPTS = {e_opts} + +## Modules + +# +# DEFINE THE MODULES YOU WANT TO RUN FOR YOUR PROJECT(S). +# E.G: VUSTP_Module_dcm2nii = Module_dcm2nii(directory="/tmp/dcm2nii_phillips") +# + +## Processors + +# +# DEFINE THE PROCESSORS YOU WANT TO RUN FOR YOUR PROJECT(S). +# E.G: VUSTP_1_Processor_fMRIQA = Processor_fMRIQA(mem_mb="4096",version="2.0.0") +# + +## Associate Project with modules/processors +# modules +proj_mod = {p_mp} # ADD THE MODULES FOR EACH PROJECT OR LEAVE IT EMPTY + +#processors +proj_proc = {p_mp} # ADD THE PROCESSORS FOR EACH PROJECT OR LEAVE IT EMPTY + +## Launcher +myLauncher = Launcher(proj_proc, proj_mod, priority_project=PRIORITY_ORDER, + job_email=EMAIL, job_email_options=EMAIL_OPTS, + queue_limit=QUEUE_LIMIT) + +""" + +def write_settings(settings_fpath, args): + """ + Write the ProjectSettingsFile.py from the template + + :param settings_fpath: path where the settings script will be saved + :param args: arguments parser + """ + p_mp = "" + for project in p_order: + p_mp += '"'+project+'": [],\n' + p_mp = p_mp[:-3] + + settings_code = templates.format(author=args.author, + email_addr=args.email, + name=args.name, + now=str(datetime.now()), + q_limit=args.q_limit, + p_order=args.p_order, + e_opts=args.e_opts, + p_mod=p_mp, + p_proc=p_mp) + f_obj = open(settings_fpath, "w") + f_obj.writelines(settings_code) + f_obj.close() + +def parse_args(): + """ + Parser for arguments + """ + from argparse import ArgumentParser + usage = "Generate a processor.py file from the template for dax in a new file." + argp = ArgumentParser(prog='GenerateProcessorTemplate', description=usage) + argp.add_argument('-n', dest='name', help='Name for ProjectSettingsFile.', required=True) + argp.add_argument('-a', dest='author', help='Author name.', required=True) + argp.add_argument('-e', dest='email', help='Author email address.', required=True) + argp.add_argument('-p', dest='p_order', help='Projects to process in order separate by a coma. E.G: ADNI,Test,Project3', required=True) + argp.add_argument('--Qlimit', dest='q_limit', help='Queue limit on cluster to submit jobs. Default: '+DEFAULT_QUEUE_LIMIT, default=DEFAULT_EMAIL_OPTS) + argp.add_argument('--Eopts', dest='e_opts', help='Options for email in the job. Default= '+DEFAULT_EMAIL_OPTS, defaut=DEFAULT_EMAIL_OPTS) + argp.add_argument('-d', dest='directory', help='Directory where the processor file will be generated. Default: current directory.', default=None) + return argp.parse_args() + +if __name__ == '__main__': + ARGS = parse_args() + + # Removing Settings if present in name + if "settings" in ARGS.name.lower(): + settings_search = re.compile(re.escape('settings'), re.IGNORECASE) + ARGS.name = settings_search.sub('', ARGS.name) + else: + NAME = ARGS.name + + SETTINGS_NAME = """Settings_{name}.py""".format(name=NAME) + if ARGS.directory and os.path.exists(ARGS.directory): + SETTINGS_FPATH = os.path.join(ARGS.directory, SETTINGS_NAME) + else: + SETTINGS_FPATH = os.path.join(os.getcwd(), SETTINGS_NAME) + + print "Generating file %s for scan processor %s ..." % (SETTINGS_FPATH, ARGS.name) + write_settings(SETTINGS_FPATH, ARGS) From 4cf39d1d573c3c1cce3df810ed827b76ec0248dd Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Tue, 29 Sep 2015 16:59:54 +0100 Subject: [PATCH 54/62] Editing Generate* executables + adding executable to generate settings file --- bin/Xnat_tools/XnatDemographic | 0 bin/Xnat_tools/XnatNDAR | 0 bin/Xnat_tools/Xnatmirror | 0 bin/dax_tools/GenerateModuleTemplate | 21 +++++-- bin/dax_tools/GenerateProcessorTemplate | 25 +++++--- bin/dax_tools/GenerateSettingsTemplate | 79 +++++++++++++++---------- bin/dax_tools/GenerateSpiderTemplate | 30 +++++++--- bin/dax_tools/dax_build | 0 bin/dax_tools/dax_launch | 0 bin/dax_tools/dax_manager | 0 bin/dax_tools/dax_update_tasks | 0 bin/dax_tools/dax_upload | 0 bin/dax_tools/run_spider | 0 setup.py | 1 + 14 files changed, 103 insertions(+), 53 deletions(-) mode change 100644 => 100755 bin/Xnat_tools/XnatDemographic mode change 100644 => 100755 bin/Xnat_tools/XnatNDAR mode change 100644 => 100755 bin/Xnat_tools/Xnatmirror mode change 100644 => 100755 bin/dax_tools/GenerateModuleTemplate mode change 100644 => 100755 bin/dax_tools/GenerateProcessorTemplate mode change 100644 => 100755 bin/dax_tools/GenerateSettingsTemplate mode change 100644 => 100755 bin/dax_tools/GenerateSpiderTemplate mode change 100644 => 100755 bin/dax_tools/dax_build mode change 100644 => 100755 bin/dax_tools/dax_launch mode change 100644 => 100755 bin/dax_tools/dax_manager mode change 100644 => 100755 bin/dax_tools/dax_update_tasks mode change 100644 => 100755 bin/dax_tools/dax_upload mode change 100644 => 100755 bin/dax_tools/run_spider diff --git a/bin/Xnat_tools/XnatDemographic b/bin/Xnat_tools/XnatDemographic old mode 100644 new mode 100755 diff --git a/bin/Xnat_tools/XnatNDAR b/bin/Xnat_tools/XnatNDAR old mode 100644 new mode 100755 diff --git a/bin/Xnat_tools/Xnatmirror b/bin/Xnat_tools/Xnatmirror old mode 100644 new mode 100755 diff --git a/bin/dax_tools/GenerateModuleTemplate b/bin/dax_tools/GenerateModuleTemplate old mode 100644 new mode 100755 index cee66568..ce7e8f89 --- a/bin/dax_tools/GenerateModuleTemplate +++ b/bin/dax_tools/GenerateModuleTemplate @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ Title: GenerateModuleTemplate Author: Benjamin Yvernault @@ -6,9 +9,6 @@ Generate your module.py following the template for module describe in this file. """ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - __author__ = 'Benjamin Yvernault' __email__ = 'b.yvernault@ucl.ac.uk' __purpose__ = "Generate your module.py following the template for module describe in this file." @@ -16,6 +16,7 @@ __version__ = '1.0.0' __modifications__ = '24 August 2015 - Original write' import os +import re from datetime import datetime DEFAULT_TEMPLATE = """''' @@ -275,10 +276,18 @@ def parse_args(): if __name__ == '__main__': ARGS = parse_args() - # Removing Spider if present in name + ## Get a proper name from the input + # remove .py if present at the end of the file + if ARGS.name.endswith('.py'): + ARGS.name = ARGS.name[:-3] + # remove settings if present in name if "module" in ARGS.name.lower(): - ERR = "wrong name for the module. Remove 'module' from the name." - raise ValueError(ERR) + module_search = re.compile(re.escape('module'), re.IGNORECASE) + ARGS.name = module_search.sub('', ARGS.name) + # remove any particular character and change it by an underscore + ARGS.name = re.sub('[^a-zA-Z0-9]', '_', ARGS.name) + if ARGS.name[-1] == '_': + ARGS.name = ARGS.name[:-1] MODULE_NAME = """Module_{name}.py""".format(name=ARGS.name) if ARGS.directory and os.path.exists(ARGS.directory): diff --git a/bin/dax_tools/GenerateProcessorTemplate b/bin/dax_tools/GenerateProcessorTemplate old mode 100644 new mode 100755 index 0a70d962..8692c1cb --- a/bin/dax_tools/GenerateProcessorTemplate +++ b/bin/dax_tools/GenerateProcessorTemplate @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ Title: GenerateProcessorTemplate Author: Benjamin Yvernault @@ -6,9 +9,6 @@ Generate your processor.py following the template for processor describe in this file. """ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - __author__ = 'Benjamin Yvernault' __email__ = 'b.yvernault@ucl.ac.uk' __purpose__ = "Generate your processor.py following the template for processor describe in this file." @@ -16,6 +16,7 @@ __version__ = '1.0.0' __modifications__ = '24 August 2015 - Original write' import os +import re from datetime import datetime DEFAULT_TEMPLATE = """''' @@ -90,7 +91,7 @@ class Processor_{name}(ScanProcessor): :param cscan: object cscan define in dax.XnatUtils (see XnatUtils in dax for information) :return: status, qcstatus ''' - + # # CODE TO CHECK IF THE PROCESS HAS THE INPUTS NEEDED FROM XNAT # CHECK FUNCTION FROM XnatUtils IN dax: @@ -177,7 +178,7 @@ class {name}_Processor(SessionProcessor): :param csess: object csess define in dax.XnatUtils (see XnatUtils in dax for information) :return: status, qcstatus ''' - + # # CODE TO CHECK IF THE PROCESS HAS THE INPUTS NEEDED FROM XNAT # CHECK FUNCTION FROM XnatUtils IN dax: @@ -249,10 +250,18 @@ def parse_args(): if __name__ == '__main__': ARGS = parse_args() - # Removing Spider if present in name + ## Get a proper name from the input + # remove .py if present at the end of the file + if ARGS.name.endswith('.py'): + ARGS.name = ARGS.name[:-3] + # remove settings if present in name if "processor" in ARGS.name.lower(): - ERR = "wrong name for the processor. Remove 'processor' from the name" - raise ValueError(ERR) + processor_search = re.compile(re.escape('processor'), re.IGNORECASE) + ARGS.name = processor_search.sub('', ARGS.name) + # remove any particular character and change it by an underscore + ARGS.name = re.sub('[^a-zA-Z0-9]', '_', ARGS.name) + if ARGS.name[-1] == '_': + ARGS.name = ARGS.name[:-1] PROCESSOR_NAME = """Processor_{name}.py""".format(name=ARGS.name) if ARGS.directory and os.path.exists(ARGS.directory): diff --git a/bin/dax_tools/GenerateSettingsTemplate b/bin/dax_tools/GenerateSettingsTemplate old mode 100644 new mode 100755 index 0b9caf5e..56379bb1 --- a/bin/dax_tools/GenerateSettingsTemplate +++ b/bin/dax_tools/GenerateSettingsTemplate @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ Title: GenerateSettingsTemplate Author: Benjamin Yvernault @@ -6,18 +9,16 @@ Generate your ProjectSettingsFile.py following the template describe in this file. """ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - __author__ = 'Benjamin Yvernault' __email__ = 'b.yvernault@ucl.ac.uk' -__purpose__ = "Generate your ProjectSettingsFile.py following the template describe in this file." +__purpose__ = 'Generate your ProjectSettingsFile.py following the template describe in this file.' __version__ = '1.0.0' __modifications__ = '29 Septembre 2015 - Original write' import os +import re from datetime import datetime -from dax import DEFAULT_EMAIL_OPTS, DEFAULT_QUEUE_LIMIT +from dax import dax_settings DEFAULT_TEMPLATE = """''' Author: {author} @@ -49,23 +50,25 @@ EMAIL_OPTS = {e_opts} ## Modules # -# DEFINE THE MODULES YOU WANT TO RUN FOR YOUR PROJECT(S). +# DEFINE THE MODULES YOU WANT TO RUN FOR YOUR PROJECT(S). # E.G: VUSTP_Module_dcm2nii = Module_dcm2nii(directory="/tmp/dcm2nii_phillips") # ## Processors # -# DEFINE THE PROCESSORS YOU WANT TO RUN FOR YOUR PROJECT(S). +# DEFINE THE PROCESSORS YOU WANT TO RUN FOR YOUR PROJECT(S). # E.G: VUSTP_1_Processor_fMRIQA = Processor_fMRIQA(mem_mb="4096",version="2.0.0") # ## Associate Project with modules/processors # modules -proj_mod = {p_mp} # ADD THE MODULES FOR EACH PROJECT OR LEAVE IT EMPTY +# ADD THE MODULES FOR EACH PROJECT OR LEAVE IT EMPTY +proj_mod = {p_mod} #processors -proj_proc = {p_mp} # ADD THE PROCESSORS FOR EACH PROJECT OR LEAVE IT EMPTY +# ADD THE PROCESSORS FOR EACH PROJECT OR LEAVE IT EMPTY +proj_proc = {p_proc} ## Launcher myLauncher = Launcher(proj_proc, proj_mod, priority_project=PRIORITY_ORDER, @@ -81,20 +84,28 @@ def write_settings(settings_fpath, args): :param settings_fpath: path where the settings script will be saved :param args: arguments parser """ - p_mp = "" - for project in p_order: - p_mp += '"'+project+'": [],\n' - p_mp = p_mp[:-3] - - settings_code = templates.format(author=args.author, - email_addr=args.email, - name=args.name, - now=str(datetime.now()), - q_limit=args.q_limit, - p_order=args.p_order, - e_opts=args.e_opts, - p_mod=p_mp, - p_proc=p_mp) + priority = args.p_order.split(",") + p_mod = '{' + p_proc = '{' + for ind, project in enumerate(priority): + if ind != 0: + p_mod += ' '*12+'"'+project+'": [],\n' # 12 = length of proj_mod = { + p_proc += ' '*13+'"'+project+'": [],\n' # 13 = length of proj_proc = { + else: + p_mod += '"'+project+'": [],\n' # 12 = length of proj_mod = { + p_proc += '"'+project+'": [],\n' # 13 = length of proj_proc = { + p_mod = p_mod[:-2]+'}' + p_proc = p_proc[:-2]+'}' + + settings_code = DEFAULT_TEMPLATE.format(author=args.author, + email_addr=args.email, + name=args.name, + now=str(datetime.now()), + q_limit=args.q_limit, + p_order=priority, + e_opts=args.e_opts, + p_mod=p_mod, + p_proc=p_proc) f_obj = open(settings_fpath, "w") f_obj.writelines(settings_code) f_obj.close() @@ -110,26 +121,34 @@ def parse_args(): argp.add_argument('-a', dest='author', help='Author name.', required=True) argp.add_argument('-e', dest='email', help='Author email address.', required=True) argp.add_argument('-p', dest='p_order', help='Projects to process in order separate by a coma. E.G: ADNI,Test,Project3', required=True) - argp.add_argument('--Qlimit', dest='q_limit', help='Queue limit on cluster to submit jobs. Default: '+DEFAULT_QUEUE_LIMIT, default=DEFAULT_EMAIL_OPTS) - argp.add_argument('--Eopts', dest='e_opts', help='Options for email in the job. Default= '+DEFAULT_EMAIL_OPTS, defaut=DEFAULT_EMAIL_OPTS) + argp.add_argument('--Qlimit', dest='q_limit', help='Queue limit on cluster to submit jobs. Default: '+str(dax_settings.DEFAULT_QUEUE_LIMIT), + default=dax_settings.DEFAULT_QUEUE_LIMIT) + argp.add_argument('--Eopts', dest='e_opts', help='Options for email in the job. Default= '+dax_settings.DEFAULT_EMAIL_OPTS, + default=dax_settings.DEFAULT_EMAIL_OPTS) argp.add_argument('-d', dest='directory', help='Directory where the processor file will be generated. Default: current directory.', default=None) return argp.parse_args() if __name__ == '__main__': ARGS = parse_args() - # Removing Settings if present in name + ## Get a proper name from the input + # remove .py if present at the end of the file + if ARGS.name.endswith('.py'): + ARGS.name = ARGS.name[:-3] + # remove settings if present in name if "settings" in ARGS.name.lower(): settings_search = re.compile(re.escape('settings'), re.IGNORECASE) ARGS.name = settings_search.sub('', ARGS.name) - else: - NAME = ARGS.name + # remove any particular character and change it by an underscore + ARGS.name = re.sub('[^a-zA-Z0-9]', '_', ARGS.name) + if ARGS.name[-1] == '_': + ARGS.name = ARGS.name[:-1] - SETTINGS_NAME = """Settings_{name}.py""".format(name=NAME) + SETTINGS_NAME = """Settings_{name}.py""".format(name=ARGS.name) if ARGS.directory and os.path.exists(ARGS.directory): SETTINGS_FPATH = os.path.join(ARGS.directory, SETTINGS_NAME) else: SETTINGS_FPATH = os.path.join(os.getcwd(), SETTINGS_NAME) - + print "Generating file %s for scan processor %s ..." % (SETTINGS_FPATH, ARGS.name) write_settings(SETTINGS_FPATH, ARGS) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate old mode 100644 new mode 100755 index 1b89236b..7a72c88b --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ Title: generate_spider_template.py Author: Benjamin Yvernault @@ -6,9 +9,6 @@ Generate your Spider.py following the template for spider describe in this file. """ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - __author__ = 'Benjamin Yvernault' __email__ = 'b.yvernault@ucl.ac.uk' __purpose__ = "Generate your Spider.py following the template for spider describe in this file." @@ -16,6 +16,7 @@ __version__ = '1.0.0' __modifications__ = '21 August 2015 - Original write' import os +import re from dax import spiders from datetime import datetime @@ -64,7 +65,7 @@ def parse_args(): ap = spiders.get_scan_argparser("{name}", "{purpose}") # - # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER + # ADD YOUR OTHER OPTIONS FOR THIS SPECIFIC SPIDER # example to add one options: # ap.add_argument("--option", dest="option_id", default=None, help="Option description.", required=True) # @@ -205,7 +206,7 @@ class Spider_{name}(SessionSpider): def pre_run(self, argument_parse): ''' Method to download data from XNAT - + :param argument_parse: argument parser object return by parse_args() ''' resource = 'XXXX' #resource to download from the scan on XNAT @@ -266,7 +267,7 @@ if __name__ == '__main__': def write_spider(spider_fpath, templates, args): """ Create the Spider path with the proper template - + :param spider_fpath: path where the spider script will be saved :param templates: template to use (scan or session) :param args: arguments parser @@ -303,9 +304,20 @@ def parse_args(): if __name__ == '__main__': ARGS = parse_args() - # Removing Spider if present in name - if ARGS.name[:6] == "Spider": - ARGS.name = ARGS.name[6:] + ## Get a proper name from the input + # remove .py if present at the end of the file + if ARGS.name.endswith('.py'): + ARGS.name = ARGS.name[:-3] + # remove settings if present in name + if "spider" in ARGS.name.lower(): + spider_search = re.compile(re.escape('spider'), re.IGNORECASE) + ARGS.name = spider_search.sub('', ARGS.name) + # remove any particular character and change it by an underscore + ARGS.name = re.sub('[^a-zA-Z0-9]', '_', ARGS.name) + if ARGS.name[-1] == '_': + ARGS.name = ARGS.name[:-1] + + ## Check version if not spiders.is_good_version(ARGS.version): err = "wrong format version given to script." + \ "It must follow the X.Y.Z template with X, Y, and Z integers." + \ diff --git a/bin/dax_tools/dax_build b/bin/dax_tools/dax_build old mode 100644 new mode 100755 diff --git a/bin/dax_tools/dax_launch b/bin/dax_tools/dax_launch old mode 100644 new mode 100755 diff --git a/bin/dax_tools/dax_manager b/bin/dax_tools/dax_manager old mode 100644 new mode 100755 diff --git a/bin/dax_tools/dax_update_tasks b/bin/dax_tools/dax_update_tasks old mode 100644 new mode 100755 diff --git a/bin/dax_tools/dax_upload b/bin/dax_tools/dax_upload old mode 100644 new mode 100755 diff --git a/bin/dax_tools/run_spider b/bin/dax_tools/run_spider old mode 100644 new mode 100755 diff --git a/setup.py b/setup.py index 488f7d16..db5155ef 100644 --- a/setup.py +++ b/setup.py @@ -45,6 +45,7 @@ def readme(): 'bin/dax_tools/GenerateModuleTemplate', 'bin/dax_tools/GenerateProcessorTemplate', 'bin/dax_tools/GenerateSpiderTemplate', + 'bin/dax_tools/GenerateSettingsTemplate', 'bin/freesurfer_tools/fsupload', 'bin/freesurfer_tools/fsdownload', 'bin/freesurfer_tools/fsview', From 4ba3a750e6abc161e9acba890800b3477f99ef60 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Tue, 29 Sep 2015 17:01:41 +0100 Subject: [PATCH 55/62] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index db5155ef..9c58c0c4 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ def readme(): 'bin/dax_tools/GenerateModuleTemplate', 'bin/dax_tools/GenerateProcessorTemplate', 'bin/dax_tools/GenerateSpiderTemplate', - 'bin/dax_tools/GenerateSettingsTemplate', + 'bin/dax_tools/GenerateSettingsTemplate', 'bin/freesurfer_tools/fsupload', 'bin/freesurfer_tools/fsdownload', 'bin/freesurfer_tools/fsview', From ee09573d2ddcac1c206fc31c93b6133121fdcbd1 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 30 Sep 2015 14:59:50 +0100 Subject: [PATCH 56/62] fixing name/purpose --- bin/dax_tools/GenerateSpiderTemplate | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index 7a72c88b..645ac199 100755 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -287,8 +287,8 @@ def parse_args(): Parser for arguments """ from argparse import ArgumentParser - usage = "Generates snapshots/preview for the scans for all subjects in a project." - argp = ArgumentParser(prog='make_preview_xnat', description=usage) + usage = "Generate your Spider.py following the dax template for spider." + argp = ArgumentParser(prog='GenerateSpiderTemplate', description=usage) argp.add_argument('-n', dest='name', help='Name for Spider. E.G: fMRIQA.', required=True) argp.add_argument('-v', dest='version', help='Spider version (format: X.Y.Z). E.G: 1.0.0', required=True) From 9455827dce1a1c31083761d29809d03fb4b932ba Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Wed, 30 Sep 2015 15:00:50 +0100 Subject: [PATCH 57/62] fixing name/usage --- bin/dax_tools/GenerateSettingsTemplate | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/dax_tools/GenerateSettingsTemplate b/bin/dax_tools/GenerateSettingsTemplate index 56379bb1..39863b69 100755 --- a/bin/dax_tools/GenerateSettingsTemplate +++ b/bin/dax_tools/GenerateSettingsTemplate @@ -115,8 +115,8 @@ def parse_args(): Parser for arguments """ from argparse import ArgumentParser - usage = "Generate a processor.py file from the template for dax in a new file." - argp = ArgumentParser(prog='GenerateProcessorTemplate', description=usage) + usage = "Generate a ProjectSettingsFile.py file from the dax template for settings file." + argp = ArgumentParser(prog='GenerateSettingsTemplate', description=usage) argp.add_argument('-n', dest='name', help='Name for ProjectSettingsFile.', required=True) argp.add_argument('-a', dest='author', help='Author name.', required=True) argp.add_argument('-e', dest='email', help='Author email address.', required=True) From 291ee24cc918b79bac2202f751a797e93ea181d8 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 1 Oct 2015 09:43:52 +0100 Subject: [PATCH 58/62] Adding jobdir to spider creation Adding "jobdir=args.temp_dir," when creating the spider_obj in the template --- bin/dax_tools/GenerateSpiderTemplate | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/dax_tools/GenerateSpiderTemplate b/bin/dax_tools/GenerateSpiderTemplate index 645ac199..76fe5cad 100755 --- a/bin/dax_tools/GenerateSpiderTemplate +++ b/bin/dax_tools/GenerateSpiderTemplate @@ -134,6 +134,7 @@ if __name__ == '__main__': args = parse_args() # generate spider object: spider_obj = Spider_{name}(spider_path=sys.argv[0], + jobdir=args.temp_dir, xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, @@ -244,6 +245,7 @@ if __name__ == '__main__': args = parse_args() # generate spider object: spider_obj = Spider_{name}(spider_path=sys.argv[0], + jobdir=args.temp_dir, xnat_project=args.proj_label, xnat_subject=args.subj_label, xnat_session=args.sess_label, From 825daf79d6fbcc6a7b3b261363cdec90bc454369 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 1 Oct 2015 10:07:16 +0100 Subject: [PATCH 59/62] Fixing suffix in spider class Suffix is now set to nothing if not set, else, remove any non numeric/letter character by a underscore, remove more than one recurrence in a row of underscore, remove last underscore if at the end, and add the first underscore if missing --- dax/spiders.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index e2574c64..b07bf543 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -54,10 +54,17 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session self.user = self.get_default_value("user", "XNAT_USER", xnat_user) self.pwd = self.get_pwd(xnat_pass, xnat_user) # Suffix - if suffix[0] != '_': self.suffix = '_'+suffix - else: self.suffix = suffix - # Set the suffix_proc remove any special characters and replace by '_' - self.suffix = re.sub('[^a-zA-Z0-9]', '_', self.suffix) + if not suffix: + self.suffix = "" + else: + # Set the suffix_proc remove any special characters and replace by '_' + self.suffix = re.sub('[^a-zA-Z0-9]', '_', suffix) + # Replace multiple underscores by one + self.suffix = re.sub('_+', '_', self.suffix =) + # Remove underscore if at the end of suffix + if self.suffix[-1] == '_': self.suffix = self.suffix[:-1] + # Add an underscore at the beginning if not present + if suffix[0] != '_': self.suffix = '_'+self.suffix # print time writer: self.time_writer = TimedWriter() # Export the variable: From 9eb7d55c27645213a2ee9168889413b3938297b1 Mon Sep 17 00:00:00 2001 From: Benjamin Yvernault Date: Thu, 1 Oct 2015 10:07:45 +0100 Subject: [PATCH 60/62] Update spiders.py --- dax/spiders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dax/spiders.py b/dax/spiders.py index b07bf543..fe590630 100644 --- a/dax/spiders.py +++ b/dax/spiders.py @@ -60,11 +60,11 @@ def __init__(self, spider_path, jobdir, xnat_project, xnat_subject, xnat_session # Set the suffix_proc remove any special characters and replace by '_' self.suffix = re.sub('[^a-zA-Z0-9]', '_', suffix) # Replace multiple underscores by one - self.suffix = re.sub('_+', '_', self.suffix =) + self.suffix = re.sub('_+', '_', self.suffix) # Remove underscore if at the end of suffix if self.suffix[-1] == '_': self.suffix = self.suffix[:-1] # Add an underscore at the beginning if not present - if suffix[0] != '_': self.suffix = '_'+self.suffix + if self.suffix[0] != '_': self.suffix = '_'+self.suffix # print time writer: self.time_writer = TimedWriter() # Export the variable: From f6f41e1b3b4e40c7d7f4491e6589fe1f493d84d9 Mon Sep 17 00:00:00 2001 From: "Brian D. Boyd" Date: Fri, 2 Oct 2015 14:01:38 -0500 Subject: [PATCH 61/62] Removed spm_path --- bin/dax_tools/GenerateProcessorTemplate | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/dax_tools/GenerateProcessorTemplate b/bin/dax_tools/GenerateProcessorTemplate index 8692c1cb..971d21ad 100755 --- a/bin/dax_tools/GenerateProcessorTemplate +++ b/bin/dax_tools/GenerateProcessorTemplate @@ -73,7 +73,7 @@ class Processor_{name}(ScanProcessor): ''' def __init__(self, spider_path=DEFAULT_SPIDER_PATH, version=None, walltime=DEFAULT_WALLTIME, mem_mb=DEFAULT_MEM, - scan_types=DEFAULT_SCAN_TYPES, spm_path=PathSettings.SPM_PATH, suffix_proc=''): + scan_types=DEFAULT_SCAN_TYPES, suffix_proc=''): super(Processor_{name}, self).__init__(scan_types, walltime, mem_mb, spider_path, version, suffix_proc=suffix_proc) # @@ -160,7 +160,7 @@ class {name}_Processor(SessionProcessor): ''' def __init__(self, spider_path=DEFAULT_SPIDER_PATH, version=None, walltime=DEFAULT_WALLTIME, mem_mb=DEFAULT_MEM, - spm_path=PathSettings.SPM_PATH, suffix_proc=''): + suffix_proc=''): super({name}_Processor, self).__init__(walltime, mem_mb, spider_path, version, suffix_proc=suffix_proc) # @@ -208,7 +208,6 @@ class {name}_Processor(SessionProcessor): proj=proj_label, subj=subj_label, sess=sess_label, - spm=self.spm_path, dir=jobdir) return [cmd] From 983d973baf08595723946874f05a26cbde1bdf5e Mon Sep 17 00:00:00 2001 From: "Brian D. Boyd" Date: Fri, 2 Oct 2015 14:08:26 -0500 Subject: [PATCH 62/62] Update GenerateProcessorTemplate --- bin/dax_tools/GenerateProcessorTemplate | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/dax_tools/GenerateProcessorTemplate b/bin/dax_tools/GenerateProcessorTemplate index 971d21ad..ee522b18 100755 --- a/bin/dax_tools/GenerateProcessorTemplate +++ b/bin/dax_tools/GenerateProcessorTemplate @@ -52,7 +52,7 @@ SCAN_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" DEFAULT_SCAN_TYPES = [] # ADD SCAN TYPES # Format for the spider command line -SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}} -c {{scan}}\ +SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}} -c {{scan}} \ -d {{dir}} --suffix "{{suffix_proc}}"''' class Processor_{name}(ScanProcessor): @@ -142,7 +142,7 @@ class Processor_{name}(ScanProcessor): SESSION_LEVEL_TEMPLATE = DEFAULT_TEMPLATE+""" # Format for the spider command line -SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}}\ +SPIDER_FORMAT = '''python {{spider}} -p {{proj}} -s {{subj}} -e {{sess}} \ -d {{dir}} --suffix "{{suffix_proc}}"''' class {name}_Processor(SessionProcessor):