Ejemplo n.º 1
0
def main():
    parser = argparse.ArgumentParser(description='Copy Xnat projects')
    parser.add_argument('--source-host',
                        type=six.text_type,
                        required=True,
                        help='source XNAT url')
    parser.add_argument('--source-project',
                        type=six.text_type,
                        required=True,
                        help='source XNAT project')
    parser.add_argument('--dest-host',
                        type=six.text_type,
                        required=True,
                        help='destination XNAT url')
    parser.add_argument('--dest-project',
                        type=six.text_type,
                        required=True,
                        help='destination XNAT project')
    args = parser.parse_args()

    with xnat.connect(args.source_host) as source_xnat, xnat.connect(
            args.dest_host) as dest_xnat:
        # Find projects
        try:
            source_project = source_xnat.projects[args.source_project]
            dest_project = dest_xnat.projects[args.dest_project]
        except KeyError as error:
            print(error.message)
        else:
            # Create and start copier
            copier = XNATProjectCopier(source_xnat, source_project, dest_xnat,
                                       dest_project)
            copier.start()
Ejemplo n.º 2
0
def sync_alfred():

    tmp_download_dir = app.config['TEMP_DOWNLOAD_DIR']

    os.makedirs(tmp_download_dir, exist_ok=True)

    with xnat.connect(server=app.config['SOURCE_XNAT_URL'],
                      user=app.config['SOURCE_XNAT_USER'],
                      password=app.config['SOURCE_XNAT_PASSWORD']) as mbi_xnat:
        with xnat.connect(
                server=app.config['TARGET_XNAT_URL'],
                user=app.config['TARGET_XNAT_USER'],
                password=app.config['TARGET_XNAT_PASSWORD']) as alf_xnat:
            alf_project = alf_xnat.projects[app.config['TARGET_XNAT_PROJECT']]  # noqa pylint: disable=no-member
            for img_session in ImgSession.ready_for_export():
                mbi_session = mbi_xnat.experiments[img_session.xnat_id]  # noqa pylint: disable=no-member
                try:
                    alf_subject = alf_project.subjects[
                        img_session.subject.mbi_id]
                except KeyError:
                    alf_subject = alf_xnat.classes.SubjectData(  # noqa pylint: disable=no-member
                        label=img_session.subject.mbi_id,
                        parent=alf_project)
                alf_session = alf_xnat.classes.MrSessionData(  # noqa pylint: disable=no-member
                    label=img_session.id,
                    parent=alf_subject)
                prev_exported = list(alf_session.scans.keys())
                # Loop through clinically relevant scans that haven't been
                # exported and export
                for scan in img_session.scans:
                    if scan.is_clinical and scan.xnat_id not in prev_exported:
                        mbi_scan = mbi_session.scans[str(scan.xnat_id)]
                        tmp_dir = op.join(tmp_download_dir,
                                          str(img_session.id))
                        mbi_scan.download_dir(tmp_dir)
                        alf_scan = alf_xnat.classes.MrScanData(  # noqa pylint: disable=no-member
                            id=mbi_scan.id,
                            type=mbi_scan.type,
                            parent=alf_session)
                        resource = alf_scan.create_resource('DICOM')
                        files_dir = glob.glob(
                            op.join(tmp_dir, '*', 'scans', '*', 'resources',
                                    'DICOM', 'files'))[0]
                        for fname in os.listdir(files_dir):
                            resource.upload(op.join(files_dir, fname), fname)
                        mbi_checksums = _get_checksums(mbi_xnat, mbi_scan)
                        alf_checksums = _get_checksums(alf_xnat, alf_scan)
                        if (mbi_checksums != alf_checksums):
                            raise Exception(
                                "Checksums do not match for uploaded scan {} "
                                "from {} (to {}) XNAT session".format(
                                    mbi_scan.type, mbi_session.label,
                                    alf_session.label))
                        scan.exported = True
                        db.session.commit()  # pylint: disable=no-member
                        shutil.rmtree(tmp_dir)
                # Trigger DICOM information extraction
                alf_xnat.put('/data/experiments/' + alf_session.id +  # noqa pylint: disable=no-member
                             '?pullDataFromHeaders=true')
Ejemplo n.º 3
0
def get_projects(page, user):
    project_dict = []
    if (user):
        with xnat.connect(page, user=user, verify=False) as session:
            for p in session.projects.keys():
                project_dict.append(p)
    else:
        with xnat.connect(page, verify=False) as session:
            for p in session.projects.keys():
                project_dict.append(p)

    return project_dict
Ejemplo n.º 4
0
def main():
    parser = argparse.ArgumentParser(
        description='download all data for a given session')
    parser.add_argument('--xnathost',
                        type=unicode,
                        required=True,
                        help='xnat host name')
    parser.add_argument('--project',
                        type=unicode,
                        required=True,
                        help='Project id')
    parser.add_argument('--session',
                        type=unicode,
                        required=True,
                        help='session')
    parser.add_argument('--output_dir',
                        type=unicode,
                        required=False,
                        default=True,
                        help='outputdir')
    args = parser.parse_args()

    print('xnat host: {}'.format(args.xnathost))
    print('project: {}'.format(args.project))
    print('session: {}'.format(args.session))
    print('output: {}'.format(args.output_dir))

    with xnat.connect(args.xnathost) as connection:
        download_xnat_session_type(connection, args.project, args.session,
                                   args.output_dir)
Ejemplo n.º 5
0
def main():
    parser = argparse.ArgumentParser(
        description='Prints all files from a certain scan.')
    parser.add_argument('--xnathost',
                        type=unicode,
                        required=True,
                        help='xnat host name')
    parser.add_argument('--project',
                        type=unicode,
                        required=True,
                        help='Project id')
    parser.add_argument('--subject',
                        type=unicode,
                        required=True,
                        help='subject')
    parser.add_argument('--session',
                        type=unicode,
                        required=True,
                        help='session')
    parser.add_argument('--scan', type=unicode, required=True, help='scan')
    parser.add_argument('--filter',
                        type=unicode,
                        required=False,
                        default='.*',
                        help='regex filter for file names')
    args = parser.parse_args()

    with xnat.connect(args.xnathost) as connection:
        xnat_files = get_files(connection, args.project, args.subject,
                               args.session, args.scan)
        xnat_files = filter_files(xnat_files, args.filter)
        for file in xnat_files:
            print('{}'.format(file.name))
Ejemplo n.º 6
0
def xnat_collection(myWorkingDirectory, collectionURL, myProjectID):
    os.chdir(myWorkingDirectory)
    #connections to public collections do not require passwords
    with xnat.connect(collectionURL) as mySession:
        myProject = mySession.projects[myProjectID]
        mySubjectsList = myProject.subjects.values()
        for s in mySubjectsList:
            mySubjectID = s.label
            print('\nEntering subject ...' + mySubjectID)
            mySubject = myProject.subjects[mySubjectID]
            myExperimentsList = mySubject.experiments.values()
            for e in myExperimentsList:
                myExperimentID = e.label
                #print('\nEntering experiment ...' + myExperimentID)
                myExperiment = mySubject.experiments[myExperimentID]
                #the next line downloads each subject, experiment pair one-by-one into separate zip files
                myExperiment.download(myWorkingDirectory + '\\' + myProjectID +
                                      '_' + mySubjectID + '_' +
                                      myExperimentID + '.zip')
# Unzip zip files download from XNAT
        files = os.listdir(os.curdir)
        for zip_name in files:
            zip_ref = zipfile.ZipFile(zip_name, 'r')
            zip_ref.extractall()
            zip_ref.close()

#remove all zip file
        dir = os.curdir
        test = os.listdir(dir)

        for item in test:
            if item.endswith(".zip"):
                os.remove(os.path.join(dir, item))
Ejemplo n.º 7
0
def main():
    parser = argparse.ArgumentParser(
        description='delete all data with a given session type')
    parser.add_argument('--xnathost',
                        type=unicode,
                        required=True,
                        help='xnat host name')
    parser.add_argument('--project',
                        type=unicode,
                        required=True,
                        help='Project id')
    parser.add_argument('--sessiontype',
                        type=unicode,
                        required=True,
                        help='session')
    parser.add_argument('--dryrun',
                        type=unicode,
                        required=False,
                        default=True,
                        help='dryrun')
    args = parser.parse_args()

    print('xnat host: {}'.format(args.xnathost))
    print('project: {}'.format(args.project))
    print('session: {}'.format(args.session))
    print('dryrun: {}'.format(args.dryrun))

    with xnat.connect(args.xnathost) as connection:
        delete_xnat_session_type(connection, args.project, args.session,
                                 args.dryrun)
Ejemplo n.º 8
0
def download_all_datasets(download_dir,
                          server,
                          session_id,
                          overwrite=True,
                          **kwargs):
    with xnat.connect(server, **kwargs) as xnat_login:
        try:
            session = xnat_login.experiments[session_id]
        except KeyError:
            raise NiAnalysisMissingDataException(
                "Didn't find session matching '{}' on {}".format(
                    session_id, server))
        try:
            os.makedirs(download_dir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise
        for dataset in session.scans.itervalues():
            data_format_name = guess_data_format(dataset)
            ext = DataFormat.by_name(data_format_name).extension
            if ext is None:
                ext = ''
            download_path = os.path.join(download_dir, dataset.type + ext)
            if overwrite or not os.path.exists(download_path):
                download_resource(download_path, dataset, data_format_name,
                                  session.label)
        fields = {}
        for name, value in session.fields.items():
            # Try convert to each datatypes in order of specificity to
            # determine type
            if name not in BUILTIN_XNAT_FIELDS:
                fields[name] = value
        with open(os.path.join(download_dir, FIELDS_FNAME), 'wb') as f:
            json.dump(fields, f)
Ejemplo n.º 9
0
def download_dataset(download_path,
                     server,
                     user,
                     password,
                     session_id,
                     dataset_name,
                     data_format=None):
    """
    Downloads a single dataset from an XNAT server
    """
    with xnat.connect(server, user=user, password=password) as xnat_login:
        try:
            session = xnat_login.experiments[session_id]
        except KeyError:
            raise NiAnalysisError(
                "Didn't find session matching '{}' on {}".format(
                    session_id, server))
        try:
            dataset = session.scans[dataset_name]
        except KeyError:
            raise NiAnalysisError(
                "Didn't find dataset matching '{}' in {}".format(
                    dataset_name, session_id))
        if data_format is None:
            data_format = guess_data_format(dataset)
        download_resource(download_path, dataset, data_format, session.label)
    def xnat_loop(self):
        source_dom, source_u, source_pw = user_pass_data("Source")
        # source_dom = "http://xnatdev.xnat.org"
        # source_u = "admin"
        # source_pw = ""

        with xnat.connect(source_dom, user=source_u,
                          password=source_pw) as connection:
            xnat_projects = connection.projects
            print(f"Found {len(xnat_projects)} projects in XNAT database.\n")

            with FancyBar('Analysing Database', max=len(xnat_projects)) as bar:
                for project in xnat_projects:
                    xnat_subjects = xnat_projects[project].subjects
                    for patient in xnat_subjects:
                        xnat_experiments = xnat_subjects[patient].experiments
                        for session in xnat_experiments:
                            xnat_scans = xnat_experiments[session].scans
                            for scan in xnat_scans:
                                scan_data = xnat_scans[scan]
                                self.sop_class_uid_check(scan_data)
                    bar.next()

        date, time_slice = get_date_time()
        if self.report_table_list:
            self.write_report(date, time_slice)
        if self.log_list:
            self.write_log(date, time_slice)
Ejemplo n.º 11
0
    def xnat_put(self, url='', file=None, imp=False, **kwargs):
        """ The method to create an XNAT object

        Uses the xnatpy session.put, session.upload, or session.services.import_ to add an object to XNAT.

        :param str url: a put route in the XNAT URI
        :param file object file: a file object to upload
        :param bool imp: whether to use the import service (True if file is zip of dicoms, otherwise False)
        :param kwargs kwargs:
        :return: None
        """
        with xnat.connect(self.server, self.user, self.password) as session:
            try:
                if imp:
                    file_path = os.path.join(self.file_dest, file.filename)
                    file.save(file_path)
                    session.services.import_(file_path,
                                             overwrite='delete',
                                             **kwargs)
                    os.remove(file_path)
                    # todo: need to call something like xnat_get to get the scan uri and return it to calling method
                elif file:
                    session.upload(url, file)
                else:
                    session.put(url)
            except:
                # todo
                # what should we do with errors?
                # probably depends on what the error is.  if we don't succeed in uploading the file
                # we need to send a message back to the user
                # but some errors here could be recoverable.

                pass
Ejemplo n.º 12
0
    def connect(self):
        """FUNCTION: connect
        PURPOSE: Making connection to the xnat server using xnatpy
        OUT: project and connection"""
        print('Establishing connection\n')
        config = self.config
        try:
            connection = xnat.connect(config.connection_name,
                                      user=config.user,
                                      password=config.pssw)
            project = connection.projects[config.project_name]
            logging.info("Connection established.")
            return project, connection

        except KeyError:
            print("Project not found in XNAT.\nExit")
            logging.critical("Project not found in XNAT.")
            if __name__ == "__main__":
                sys.exit()
            else:
                return None, None

        except Exception as e:
            print(str(e) + "\nExit")
            if __name__ == "__main__":
                logging.critical(e.message)
                sys.exit()
            else:
                return e, None
Ejemplo n.º 13
0
 def _clean_up(self):
     # Clean up working dirs
     shutil.rmtree(self.cache_dir, ignore_errors=True)
     # Clean up session created for unit-test
     with xnat.connect(SERVER) as mbi_xnat:
         xproject = mbi_xnat.projects[self.PROJECT]
         for xsubject in list(xproject.subjects.itervalues()):
             xsubject.delete()
Ejemplo n.º 14
0
 def setUp(self):
     test_fileset.TestDicomTagMatch.setUp(self)
     TestOnXnatMixin.setUp(self)
     # Set up DICOM headers
     with xnat.connect(SERVER) as login:
         xsess = login.projects[self.project].experiments['_'.join(
             (self.project, self.SUBJECT, self.VISIT))]
         login.put('/data/experiments/{}?pullDataFromHeaders=true'.format(
             xsess.id))
Ejemplo n.º 15
0
def main():
    source_dom, source_u, source_pw = user_pass_data("Source")
    target_dom, target_u, target_pw = user_pass_data("Target")

    with xnat.connect(source_dom, user=source_u,
                      password=source_pw) as subject_connection:
        while True:
            try:
                project_id = input(
                    "Enter a project ID to mirror on the target XNAT instance: "
                )
                xnat_project = subject_connection.projects[project_id]
                xnat_subjects = xnat_project.subjects
                print(
                    f"Number of subjects found in project: {len(xnat_subjects)}"
                )
            except KeyError:
                print(
                    f"Project with ID \"{project_id}\" not found!\nPlease try again.\n"
                )
            else:
                break

    dest_session.auth = (target_u, target_pw)

    with FancyBar('Copying Project...', max=len(xnat_subjects)) as bar:
        with xnat.connect(source_dom, user=source_u,
                          password=source_pw) as connection:
            xnat_project = connection.projects[project_id]
            for patient in xnat_subjects:
                xnat_experiments = xnat_project.subjects[patient].experiments
                for session in xnat_experiments:
                    xnat_scans = xnat_project.subjects[patient].experiments[
                        session].scans
                    for scan in xnat_scans:
                        temp_dir = Path("temp/")
                        with tempfile.TemporaryDirectory(
                                dir=temp_dir,
                                prefix="project_mirror_") as dir_path:
                            download(dir_path, xnat_scans, scan)
                            upload(target_dom, dir_path)

                bar.next()
Ejemplo n.º 16
0
def make_dataset_XNAT(project, opt, phase):
    session = xnat.connect('http://rufus.stanford.edu', user='******', password='******') #make XNAT connection
    #xnat version of make_dataset_dicom()
    images = []
    #parsing xnat hierarchy: project -> subject -> experiment -> scan -> dicom img
    subjs = session.projects[project].subjects

    try:
        set_start_method('spawn')
    except RuntimeError:
        pass
    
    #multiprocessing code (not working) ------------
    pool = Pool(os.cpu_count())
    images = pool.map(process_subj, [subjs[s] for s in subjs])

    images = [i for im in images for i in im]
    #-----------------------------------------------

    #original code (before multiproc, works fine) -------------------
    '''
    for s in subjs:
        exps = subjs[s].experiments

        for e in exps:
            scans = exps[e].scans
            
            for sc in scans:
                my_file = scans[sc].resources['DICOM'].files[0]
                fname = my_file.data['Name']
                path = my_file.uri

                with my_file.open() as f:
                    dicom = pydicom.read_file(f)

                #save images whose filenames are in phase
                if fname.endswith('.dcm'):
                    try:
                        opt.names_phase[fname]
                    except:
                        print('Error: we donot find the phase for file name' , fname, 'ignore this file')
                        continue
                        # sys.exit(3)
                    if opt.names_phase[fname] == phase:
                        Img = process_dicom(dicom)
                        if Img is not None:
                            print("x" + fname)
                            images.append([path, dicom]) #each image list item has filename + FileData obj
    '''
    #-------------------------------------------------

    session.disconnect()
    return images
Ejemplo n.º 17
0
        def connect():
            for host in hosts:
                try:
                    session[0] = xnat.connect(host,
                                              user=username,
                                              password=password)
                    hosts[:]   = [host]
                    break

                except Exception as e:
                    error[0] = e
                    if cancelled[0]:
                        break
Ejemplo n.º 18
0
 def _create_project(self, project_name=None):
     if project_name is None:
         project_name = self.project
     if SERVER == 'https://mbi-xnat.erc.monash.edu.au':
         raise ArcanaError(
             "Shouldn't be creating projects on the production "
             "server")
     with xnat.connect(SERVER) as login:
         uri = '/data/archive/projects/{}'.format(project_name)
         query = {'xsiType': 'xnat:projectData', 'req_format': 'qa'}
         response = login.put(uri, query=query)
         if response.ok:
             logger.info("Created test project '{}'".format(project_name))
Ejemplo n.º 19
0
 def connect(self):
     """
     Parameters
     ----------
     prev_login : xnat.XNATSession
         An XNAT login that has been opened in the code that calls
         the method that calls login. It is wrapped in a
         NoExitWrapper so the returned connection can be used
         in a "with" statement in the method.
     """
     sess_kwargs = {}
     if self._user is not None:
         sess_kwargs['user'] = self._user
     if self._password is not None:
         sess_kwargs['password'] = self._password
     self._login = xnat.connect(server=self._server, **sess_kwargs)
Ejemplo n.º 20
0
    def __call__(self, data):
        d = dict(data)
        for key in self.keys:
            if key in data:

                for action in self.actions:
                    """loops over actions in action list, if no action is triggered then raise a warning actions are 
                    functions that return any of projects, subjects, experiments, scans, or resources XNAT object 
                    along with a key to be used in the data dictionary"""

                    with xnat.connect(
                            server=self.xnat_configuration['server'],
                            user=self.xnat_configuration['user'],
                            password=self.xnat_configuration['password'],
                    ) as session:

                        "connect session to subject uri"
                        subject_obj = session.create_object(d['subject_uri'])
                        "perform action on subject object"
                        xnat_obj, image_label = action(subject_obj)

                        with tempfile.TemporaryDirectory() as tmpdirname:
                            "download image from XNAT"
                            session_obj = session.create_object(xnat_obj.uri)
                            session_obj.download_dir(tmpdirname)

                            images_path = glob.glob(os.path.join(
                                tmpdirname, '**/*' + self.expected_filetype),
                                                    recursive=True)

                            "find unique directories in list of image paths"
                            image_dirs = list(
                                set(
                                    os.path.dirname(image_path)
                                    for image_path in images_path))

                            if len(image_dirs) > 1:
                                raise ValueError(
                                    f'More than one image series found in {images_path}'
                                )

                            image, meta = self.image_loader()(image_dirs[0])

                            d[image_label] = image
                            d[image_label + '_meta'] = meta

            return d
Ejemplo n.º 21
0
def _cached_xnat(xnat_url, project_name):
    if (
            xnat_url,
            project_name,
    ) in _xnat_sessions:
        return _xnat_sessions[(
            xnat_url,
            project_name,
        )]
    session = xnat.connect(xnat_url)
    project = session.projects[project_name]
    _xnat_sessions[(
        xnat_url,
        project_name,
    )] = project

    return project
Ejemplo n.º 22
0
 def validate_xnat_id(self, field):
     if self.status.data == PRESENT:
         with xnat.connect(
                 server=app.config['SOURCE_XNAT_URL'],
                 user=app.config['SOURCE_XNAT_USER'],
                 password=app.config['SOURCE_XNAT_PASSWORD']) as mbi_xnat:
             try:
                 exp = mbi_xnat.experiments[self.xnat_id.data]  # noqa pylint: disable=no-member
             except KeyError:
                 raise ValidationError(
                     "Did not find '{}' XNAT session, please correct or "
                     "select a different status (i.e. other than '{}')".
                     format(self.xnat_id.data, DATA_STATUS[PRESENT][1]))
             else:
                 # Update the scans listed against the XNAT session.
                 self.new_scan_types = [(s.id, s.type)
                                        for s in exp.scans.values()]
Ejemplo n.º 23
0
def xget(credentials=None, project=None, dicom_dir=None, filter=None):
    """Pull and Compress data from a given XNAT project.

    Keyword arguments:
    credentials -- path to file containing XNAT login information.
    project -- name of project as it appears on XNAT (e.g. McMakin_EMU).
    dicom_dir -- path to local directory to store pulled dicoms.
    _filter -- regex to filter out certain subjects.
    """
    if not filter:
        filter = r'([\w\W]+)'  # Grab any file from project
    previous_subjs = {}
    os.makedirs(dicom_dir, exist_ok=True)
    subjs_json = dicom_dir + '/downloaded_subjects.json'
    credentials = _json_load(credentials)
    previous_subjs = {}
    if os.path.isfile(subjs_json):
        previous_subjs = _json_load(subjs_json)

    # Creates XNAT session and looks for scans not already grabbed from XNAT,
    # then ends session once completed
    session = xnat.connect(credentials['server'],
                           user=credentials['user'],
                           password=credentials['password'])
    project_data = session.projects[project]
    for subject in project_data.subjects:
        subject_data = session.projects[project].subjects[subject]
        if not re.search(filter, subject_data.label):
            continue
        if subject_data.label not in previous_subjs.keys():
            previous_subjs[subject_data.label] = []
        for exp in subject_data.experiments:
            exp_data = subject_data.experiments[exp]
            if exp_data.label not in previous_subjs[subject_data.label]:
                previous_subjs[subject_data.label].append(exp_data.label)
                print(exp_data.label)
                exp_data.download_dir(dicom_dir)
                _add_to_tar(dicom_dir + '/' + exp_data.label + '.tar.gz',
                            dicom_dir + '/' + exp_data.label + '/scans/')
                shutil.rmtree(dicom_dir + '/' + exp_data.label)
    session.disconnect()

    # Dumps json with any newly scans grabbed and tarred from XNAT
    with open(subjs_json, 'w') as dump_file:
        json.dump(previous_subjs, dump_file, indent=4)
Ejemplo n.º 24
0
def xnat_build_dataset(xnat_configuration, minimal=True):
    """
    Builds a dictionary that describes the XNAT project dataset using XNAT data hierarchy: project/subject/experiment/scan

    minimal: if True, only the minimal information is returned, i.e. the  subject ID and the SubjectData

    e.g.
    [
        {
        subjectid: '1',
        subject_uri: '<unique address to subject in xnat archive>'
        experiment_1: {
                        scan_1: {scan_object},
                        scan_2: {scan_object}
                       },
        experiment_2:  {
                        scan_1: {scan_object}
                      }
        }
    ]

    """
    with xnat.connect(server=xnat_configuration['server'],
                      user=xnat_configuration['user'],
                      password=xnat_configuration['password']) as session:

        project = session.projects[xnat_configuration["project"]]

        dataset = []
        for subject in project.subjects:

            data_series = {'subject_id': subject, 'subject_uri': project.subjects[subject].uri}

            if not minimal:
                for experiment in project.subjects[subject].experiments:
                    scan_dict = {}
                    for scan in project.subjects[subject].experiments[experiment].scans:
                        scan_dict['modality'] = project.subjects[subject].experiments[experiment].modality
                        scan_dict[project.subjects[subject].experiments[experiment].scans[scan].series_description] = project.subjects[subject].experiments[experiment].scans[scan]

                    data_series[project.subjects[subject].experiments[experiment].label] = scan_dict

            dataset.append(data_series)

    return dataset
def download_project(project_name,
                     xnat_url,
                     datafolder,
                     nsubjects=10,
                     verbose=True):

    # Connect to XNAT and retreive project
    session = xnat.connect(xnat_url)
    project = session.projects[project_name]

    # Create the data folder if it does not exist yet
    datafolder = os.path.join(datafolder, project_name)
    if not os.path.exists(datafolder):
        os.makedirs(datafolder)

    subjects_len = len(project.subjects)
    if nsubjects == 'all':
        nsubjects = subjects_len
    else:
        nsubjects = min(nsubjects, subjects_len)

    subjects_counter = 1
    downloaded_subjects_counter = 0
    for s in range(0, subjects_len):
        s = project.subjects[s]
        print(f'Working on subject {subjects_counter}/{subjects_len}')
        subjects_counter += 1

        success = download_subject(project_name, s, datafolder, session,
                                   verbose)
        if success:
            downloaded_subjects_counter += 1

        # Stop downloading if we have reached the required number of subjects
        if downloaded_subjects_counter == nsubjects:
            break

    # Disconnect the session
    session.disconnect()
    if downloaded_subjects_counter < nsubjects:
        raise ValueError(
            f'Number of subjects downloaded {downloaded_subjects_counter} is smaller than the number required {nsubjects}.'
        )

    print('Done downloading!')
Ejemplo n.º 26
0
def classify(sessionUri):
    errors = False
    with xnat.connect(os.environ['XNAT_HOST'], user=os.environ['XNAT_USER'], password=os.environ['XNAT_PASS']) as connection:
        session = connection.create_object('/data' + sessionUri)
        for scan in session.scans.values():
            try:
                print('Reading scan ', scan.id, flush=True)
                dcm = scan.read_dicom(read_pixel_data=True)
    
                modality = dcm.get("Modality")
                if not modality:
                    print('Unknown modality, skipping', flush=True)
                    continue
        
                classification = {}
                series_desc = format_string(dcm.get("SeriesDescription", ""))
                if series_desc:
                    if dcm.get("Modality") == "MR":
                        classification = classification_from_label.infer_classification(series_desc)
                        print("Inferred classification from SeriesDescription: ", classification, flush=True)
        
                # If no pixel data present, make classification intent "Non-Image"
                if not hasattr(dcm, "PixelData"):
                    non_image_intent = 'Non-Image'
                    # If intent not present, add it with nonimage_intent
                    if 'Intent' not in classification:
                        classification['Intent'] = [non_image_intent]
                    else:
                        # Otherwise append non-image if not in Intent
                        if non_image_intent not in classification['Intent']:
                            classification['Intent'].append(non_image_intent)
        
                # add fields to scan
                xnat_type = 'xnat:{}ScanData'.format(translate_modality(modality))
                query_params = {'xsiType': xnat_type}
                for key in classification:
                    qp_key = '{}/parameters/addParam[name=classification_{}]/addField'.format(xnat_type, key.lower())
                    query_params[qp_key] = ' '.join(classification[key])
                r = connection.put(scan.uri, query=query_params)
                r.raise_for_status()
            except Exception as e:
                print("Error for scan {}".format(scan.id), flush=True)
                printErr(str(e))
                errors = True
def xnat_collection(myWorkingDirectory,collectionURL,myProjectID):
    os.chdir(myWorkingDirectory)
    #connections to public collections do not require passwords
    with xnat.connect(collectionURL) as mySession:
        myProject= mySession.projects[myProjectID]
        mySubjectsList = myProject.subjects.values()
        for s in mySubjectsList:
            mySubjectID = s.label
            print('\nEntering subject ...' + mySubjectID)
            mySubject = myProject.subjects[mySubjectID]
            myExperimentsList = mySubject.experiments.values()
            for e in myExperimentsList:
                myExperimentID = e.label
                #print('\nEntering experiment ...' + myExperimentID)
                myExperiment = mySubject.experiments[myExperimentID]
                #the next line downloads each subject, experiment pair one-by-one into separate zip files
                #myExperiment.download(myWorkingDirectory + '\\' + myProjectID + '_' + mySubjectID + '_' + myExperimentID + '.zip')
                myExperiment.download(myWorkingDirectory + '\\' + myExperimentID + '.zip')
    return
Ejemplo n.º 28
0
    def setup(self):
        self.test_batch_size = 1
        self.xnat_configuration = {
            'server': 'http://localhost:80',
            'user': '******',
            'password': '******',
            'project': 'TEST_MLOPS'
        }

        #  create test project and push test data
        with xnat.connect(
                server=self.xnat_configuration['server'],
                user=self.xnat_configuration['user'],
                password=self.xnat_configuration['password'],
        ) as session:

            xnat_projects_url = self.xnat_configuration[
                'server'] + '/data/projects'

            # Set the name of the XML file.
            headers = {'Content-Type': 'text/xml'}

            # Open the XML file.
            with open('tests/data/xnat/test_project_setup.xml') as xml:
                r = requests.post(xnat_projects_url,
                                  data=xml,
                                  headers=headers,
                                  auth=HTTPBasicAuth(
                                      self.xnat_configuration['user'],
                                      self.xnat_configuration['password']))

            # push data to new project
            try:
                session.services.import_(
                    'tests/data/test_dicoms.zip',
                    project=self.xnat_configuration['project'],
                    subject='1',
                    experiment='MR_TEST_EXPERIMENT')
            except XNATUploadError as e:
                print(f'Test subject already exists {e}')

        self.test_data = xnat_build_dataset(self.xnat_configuration)
Ejemplo n.º 29
0
def main():
    args = app_args()

    # Getting experiment data
    sess = xnat.connect(args.host, args.user, args.passwd)
    experiment = sess.experiments[args.session]

    # Checking each scan
    for scan in experiment.scans.values():
        bidsname = infotodict(scan)
        print( '{} - {} ({}) | bidsname: {}'.format(scan.id, scan.type, scan.series_description, bidsname))
        is_anat = str(bidsname).startswith('ANAT')
        scan_dir = download_scan(scan)

        # Converting and saving NIFTI files
        if args.save_nifti or (args.deface and is_anat):            
            # DICOM files not found
            if not os.path.isdir(scan_dir):
                continue

            nifti_dir = '/tmp/{}'.format(scan.id)
            os.mkdir(nifti_dir)
            subprocess.call(["dcm2niix", "-o", nifti_dir, "-z", "y", "-f", r"%p_%s", scan_dir])
            if is_anat and args.deface:
                subprocess.call(["./deface.sh", nifti_dir])
                
            if is_derived(nifti_dir):
                bidsname = 'DERIVATIVES'

            # Compressing folder and sending it to XNAT
            subprocess.call(["./send_nii.sh", nifti_dir, args.host])

        # Remove DICOMs when NIFTIs were saved
        if args.save_nifti and args.remove_dicoms:
            sess.delete('/data/archive/experiments/{}/scans/{}/resources/{}'.format(args.session, scan.id, scan_dir))
        
        # Renaming, if necessary
        if args.rename_types and bidsname and scan.type != bidsname:
            print('renaming...')
            scan.type = bidsname

        subprocess.call(['rm', '-rf', '/tmp/*'])
Ejemplo n.º 30
0
def async_xnat_update(xnat_url, user, password, xnat_archive, exp_name,
                      series_num, comment, quality):
    """Push usability data into XNAT.

    This will update XNAT in a separate thread to reduce waiting time for the
    user. Because it will run in another thread, database objects cannot be
    passed in as arguments.

    Args:
        xnat_url (str): The full URL to use for the XNAT server.
        user (str): The user to log in as.
        password (str): The password to log in with.
        xnat_archvie (str): The name of the XNAT archive that contains the
            experiment.
        exp_name (str): The name of the experiment on XNAT.
        series_num (int): The series number of the file to update.
        comment (str): The user's QC comment.
        quality (str): The quality label to apply based on whether data
            has been flagged, blacklisted or approved.
    """
    with xnat.connect(xnat_url, user=user, password=password) as xcon:
        project = xcon.projects[xnat_archive]
        xnat_exp = project.experiments[exp_name]
        matched = [
            item for item in xnat_exp.scans[:] if item.id == str(series_num)
        ]

        if not matched or len(matched) > 1:
            logger.error(f"Couldn't locate {exp_name} on XNAT server. "
                         "Usability will not be updated.")
            return

        xnat_scan = matched[0]
        xnat_scan.quality = quality
        if comment:
            # XNAT max comment length is 255 chars
            safe_comment = comment if len(quote(comment)) < 255 \
                else unquote(quote(comment)[0:243]) + " [...]"
            xnat_scan.note = safe_comment
Ejemplo n.º 31
0
 def connect(self, verify=True, debug=False, loglevel=None):
   self._debug = debug
   self._xnat = xnat.connect(self._server, user=self._user, password=self._password, verify=verify, debug=debug, loglevel=loglevel)
   return self._xnat