Example #1
0
    def get_resource_list(self, study, session, experiment, resource_id):
        """The list of non-dicom resources associated with an experiment
        returns a list of dicts, mostly interested in ID and name"""
        logger.debug('Getting resource list for expeiment:{}'
                     .format(experiment))
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/{}' \
              '/resources/{}/?format=xml'.format(self.server,
                                                 study,
                                                 session,
                                                 experiment,
                                                 resource_id)
        try:
            result = self._make_xnat_xml_query(url)
        except:
            return XnatException("Failed getting resources with url:"
                                 .format(url))
        if result is None:
            raise XnatException('Experiment:{} not found for session:{}'
                                ' in study:{}'
                                .format(experiment, session, study))

        # define the xml namespace
        ns = {'cat': 'http://nrg.wustl.edu/catalog'}
        entries = result.find('cat:entries', ns)
        if entries is None:
            # no files found, just a label
            return None

        items = [entry.attrib for entry
                 in entries.findall('cat:entry', ns)]

        return(items)
Example #2
0
    def get_dicom(self, project, session, experiment, scan,
                  filename=None, retries=3):
        """Downloads a dicom file from xnat to filename
        If filename is not specified creates a temporary file
        and returns the path to that, user needs to be responsible
        for cleaning up any created tempfiles"""
        url = '{}/data/archive/projects/{}/' \
              'subjects/{}/experiments/{}/' \
              'scans/{}/resources/DICOM/files?format=zip' \
              .format(self.server, project, session, experiment, scan)

        if not filename:
            filename = tempfile.mkstemp(prefix="dm2_xnat_extract_")
            # mkstemp returns a filename and a file object
            # dealing with the filename in future so close the file object
            os.close(filename[0])
        try:
            self._get_xnat_stream(url, filename, retries)
            return(filename)
        except:
            try:
                os.remove(filename[1])
            except OSError as e:
                logger.warning('Failed to delete tempfile:{} with excuse:{}'
                               .format(filename, str(e)))
            err = XnatException("Failed getting dicom with url:{}".format(url))
            err.study = project
            err.session = session
            raise err
Example #3
0
    def get_session(self, study, session, create=False):
        """Checks to see if session exists in xnat,
        if create and study doesnt exist will try to create it
        returns study or none"""
        logger.debug('Querying for session:{} in study:{}'
                     .format(session, study))
        url = '{}/data/archive/projects/{}/subjects/{}?format=json' \
              .format(self.server, study, session)

        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting session with url:{}"
                                .format(url))

        if not result:
            logger.info('Session:{} not found in study:{}'
                        .format(session, study))
            if create:
                try:
                    self.make_session(study, session)
                except:
                    raise XnatException("Failed to create session:{} in study:{}"
                                        .format(session, study))
                result = self.get_session(study, session)
                return result
        try:
            return(result['items'][0])
        except (KeyError, ValueError):
            msg = "Session:{} doesnt exist on xnat for study:{}".format(session, study)
            logger.info(msg)
            return XnatException(msg)
Example #4
0
    def get_resource_ids(self, study, session, experiment, folderName=None, create=True):
        """
        Return a list of resource id's (subfolders) from an experiment
        """
        logger.debug('Getting resource ids for expeiment:{}'
                     .format(experiment))
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/{}' \
              '/resources/?format=json'.format(self.server,
                                               study,
                                               session,
                                               experiment)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting resource ids with url:"
                                .format(url))
        if result is None:
            raise XnatException('Experiment:{} not found for session:{}'
                                ' in study:{}'
                                .format(experiment, session, study))

        if create and int(result['ResultSet']['totalRecords']) < 1:
            return self.create_resource_folder(study,
                                               session,
                                               experiment,
                                               folderName)

        resource_ids = {}
        for r in result['ResultSet']['Result']:
            try:
                label = r['label']
                resource_ids[label] = r['xnat_abstractresource_id']
            except KeyError:
                # some resource folders have no label
                resource_ids['No Label'] = r['xnat_abstractresource_id']

        if not folderName:
            # foldername not specified return them all
            resource_id = [val for val in resource_ids.itervalues()]
        else:
            # check if folder exists, if not create it
            try:
                resource_id = resource_ids[folderName]
            except KeyError:
                # folder doesn't exist, create it
                if not create:
                    return None
                else:
                    resource_id = self.create_resource_folder(study,
                                                              session,
                                                              experiment,
                                                              folderName)

        return resource_id
Example #5
0
    def put_dicoms(self, project, session, experiment, filename, retries=3):
        """Upload an archive of dicoms to XNAT
        filename: archive to upload"""
        headers = {'Content-Type': 'application/zip'}

        upload_url = "{server}/data/services/import?project={project}" \
                     "&subject={subject}&session={session}&overwrite=delete" \
                     "&prearchive=false&inbody=true"

        upload_url = upload_url.format(server=self.server,
                                       project=project,
                                       subject=session,
                                       session=experiment)
        try:
            with open(filename) as data:
                self._make_xnat_post(upload_url, data, retries, headers)
        except XnatException as e:
            e.study = project
            e.session = session
            raise e
        except IOError as e:
            logger.error('Failed to open file:{} with excuse:'
                         .format(filename, e.strerror))
            err = XnatException("Error in file:{}".
                                format(filename))
            err.study = project
            err.session = session
            raise err
        except requests.exceptions.RequestException as e:
            err = XnatException("Error uploading data with url:{}"
                                .format(upload_url))
            err.study = project
            err.session = session
            raise err
Example #6
0
    def get_projects(self):
        """Queries the xnat server for a list of projects"""
        logger.debug('Querying xnat server for projects')
        url = '{}/data/archive/projects/?format=json'.format(self.server)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting projects with url:{}"
                                .format(url))

        if not result:
            raise XnatException("No studies on server:{}"
                                .format(self.server))

        return(result['ResultSet']['Result'])
Example #7
0
    def get_resource_archive(self, project, session, experiment, resource_id,
                             filename=None, retries=3):
        """Download a resource archive from xnat to filename
        If filename is not specified creates a temporary file and
        returns the path to that, user needs to be responsible format
        cleaning up any created tempfiles"""
        url = '{}/data/archive/projects/{}/' \
              'subjects/{}/experiments/{}/' \
              'resources/{}/files?format=zip' \
              .format(self.server, project, session, experiment, resource_id)

        if not filename:
            filename = tempfile.mkstemp(prefix="dm2_xnat_extract_")
            #  mkstemp returns a file object and a filename
            #  we will deal with the filename in future so close the file object
            os.close(filename[0])
        try:
            self._get_xnat_stream(url, filename, retries)
            return(filename)
        except:
            try:
                os.remove(filename[1])
            except OSError as e:
                logger.warning('Failed to delete tempfile:{} with excude:{}'
                               .format(filename, str(e)))
            logger.error('Failed getting resource archive from xnat', exc_info=True)
            raise XnatException("Failed downloading resource archive with url:{}"
                                .format(url))
Example #8
0
    def get_project(self, project):
        logger.debug('Querying xnat server for project:{}'.format(project))
        url = '{}/data/archive/projects/{}?format=json'.format(self.server,
                                                               project)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting project with url:{}"
                                .format(url))

        if not result:
            logger.warn('Project:{} not found'.format(project))
            raise XnatException("Project:{} not found. Are credentials"
                                "exported to the environment and clevis given"
                                "permission on the xnat project?"
                                .format(project))

        return(result['items'][0])
Example #9
0
    def get_sessions(self, study):
        logger.debug('Querying xnat server for sessions in study'
                     .format(study))
        if not self.get_project(study):
            raise XnatException('Invalid xnat project:'
                                .format(study))

        url = '{}/data/archive/projects/{}/subjects/'.format(self.server,
                                                             study)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting xnat sessions with url:{}"
                                .format(url))

        if not result:
            raise XnatException('No sessions found for study:{}'.format(study))

        return(result['ResultSet']['Result'])
Example #10
0
 def __init__(self, server, username, password):
     if server.endswith('/'):
         server = server[:-1]
     self.server = server
     self.auth = (username, password)
     try:
         self.get_xnat_session()
     except Exception as e:
         logger.warn('Failed getting xnat session')
         raise XnatException("Failed getting xnat session")
Example #11
0
    def get_experiment(self, study, session, experiment):
        logger.debug('Getting experiment:{} for session:{} in study:{}'
                     .format(experiment, session, study))
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/{}' \
              '?format=json'.format(self.server,
                                    study,
                                    session,
                                    experiment)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting experiments with url:{}"
                                .format(url))

        if not result:
            raise XnatException('Experiment:{} not found for session:{}'
                                ' in study:{}'
                                .format(experiment, session, study))

        return(result['items'][0])
Example #12
0
    def get_scan_list(self, study, session, experiment):
        """The list of dicom scans in an experiment"""
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/{}' \
              '/scans/?format=json'.format(self.server,
                                           study,
                                           session,
                                           experiment)
        try:
            result = self._make_xnat_query(url)
        except:
            return XnatException('Failed getting scans with url:{}'
                                 .format(url))

        if result is None:
            e = XnatException('Scan not found for experiment:{}'
                              .format(experiment))
            e.study = study
            e.session = session
            raise e

        return(result['ResultSet']['Result'])
Example #13
0
    def put_resource(self, project, session, experiment, filename, data, folder,
                     retries=3):
        """POST a resource file to the xnat server
        filename: string to store filename as
        data: string containing data
            (such as produced by zipfile.ZipFile.read())"""

        resource_id = self.get_resource_ids(project,
                                            session,
                                             experiment,
                                             folderName=folder)

        attach_url = "{server}/data/archive/projects/{project}/" \
                     "subjects/{subject}/experiments/{experiment}/" \
                     "resources/{resource_id}/" \
                     "files/{filename}?inbody=true"

        uploadname = urllib.quote(filename)

        url = attach_url.format(server=self.server,
                                project=project,
                                subject=session,
                                experiment=experiment,
                                resource_id=resource_id,
                                filename=uploadname)

        try:
            self._make_xnat_post(url, data)
        except XnatException as err:
            err.study = project
            err.session = session
            raise err
        except:
            logger.warning("Failed adding resource to xnat with url:{}"
                           .format(url))
            err = XnatException("Failed adding resource to xnat")
            err.study = project
            err.session = session
Example #14
0
    def get_scan_info(self, study, session, experiment, scanid):
        """Returns info about an xnat scan"""
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/{}' \
              '/scans/{}/?format=json'.format(self.server,
                                              study,
                                              session,
                                              experiment,
                                              scanid)
        try:
            result = self._make_xnat_query(url)
        except:
            return XnatException('Failed getting scan with url:{}'
                                 .format(url))

        if result is None:
            e = XnatException('Scan:{} not found for experiment:{}'
                              .format(scanid, experiment))
            e.study = study
            e.session = session
            raise e

        return(result['items'][0])
Example #15
0
    def _make_xnat_post(self, url, data, retries=3, headers=None):
        logger.debug('POSTing data to xnat, {} retries left'.format(retries))
        response = self.session.post(url,
                                     headers=headers,
                                     data=data,
                                     timeout=60*60)

        if response.status_code == 401:
            # possibly the session has timed out
            logger.info('Session may have expired, resetting')
            self.get_xnat_session()
            response = self.session.post(url,
                                         headers=headers,
                                         data=data)

        if response.status_code is 504:
            if retries:
                logger.warning('xnat server timed out, retrying')
                time.sleep(30)
                self._make_xnat_post(url, data, retries=retries - 1)
            else:
                logger.warn('xnat server timed out, giving up')
                response.raise_for_status()

        elif response.status_code is not 200:
            if 'multiple imaging sessions.' in response.content:
                raise XnatException('Multiple imaging sessions in archive,'
                                    ' check prearchive')
            if '502 Bad Gateway' in response.content:
                raise XnatException('Bad gateway error: Check tomcat logs')
            if 'Unable to identify experiment' in response.content:
                raise XnatException('Unable to identify experiment, did dicom upload fail?')
            else:
                raise XnatException('An unknown error occured uploading data.'
                                    'Status code:{}, reason:{}'
                                    .format(response.status_code,
                                            response.content))
Example #16
0
    def delete_resource(self, project, session, experiment,
                        resource_group_id, resource_id, retries=3):

        """Delete a resource file from xnat"""
        url = '{}/data/archive/projects/{}/' \
              'subjects/{}/experiments/{}/' \
              'resources/{}/files/{}'.format(self.server,
                                            project,
                                            session,
                                            experiment,
                                            resource_group_id,
                                            resource_id)
        try:
            self._make_xnat_delete(url)
        except:
            raise XnatException('Failed deleting resource with url:{}'
                                .format(url))
Example #17
0
    def get_experiments(self, study, session):
        logger.debug('Getting experiments for session:{} in study:{}'
                     .format(session, study))
        url = '{}/data/archive/projects/{}' \
              '/subjects/{}/experiments/?format=json'.format(self.server,
                                                             study,
                                                             session)
        try:
            result = self._make_xnat_query(url)
        except:
            raise XnatException("Failed getting experiments with url:{}"
                                .format(url))

        if not result:
            logger.warn('No experiments found for session:{} in study:{}'
                        .format(session, study))
            return

        return(result['ResultSet']['Result'])