def rename_xnat_session(xnat, orig_name, new_name, project=None): """Rename a session on XNAT. Args: xnat (:obj:`datman.xnat.xnat`): A connection to the XNAT server. orig_name (:obj:`str`): The current session name on XNAT. new_name (:obj:`str`): The new name to apply to the session. project (:obj:`str`, optional): The XNAT project the session belongs to. If not given, it will be guessed based on orig_name. Defaults to None. Raises: XnatException: If problems internal to :obj:`datman.xnat.xnat.rename_session` occur. requests.HTTPError: If XNAT's API reports issues. Returns: bool: True if rename succeeded, False otherwise """ if not project: project = get_project(orig_name) try: ident = datman.scanid.parse(new_name) except ParseException: raise ParseException("New ID {} for experiment {} doesnt match a " "supported naming convention.".format( new_name, orig_name)) logger.info("Renaming {} to {} in project {}".format( orig_name, new_name, project)) orig_subject = xnat.find_subject(project, orig_name) try: xnat.rename_subject(project, orig_subject, ident.get_xnat_subject_id()) except HTTPError as e: if e.response.status_code == 500: # This happens on success sometimes (usually when experiment # is empty). Check if the rename succeeded. try: xnat.get_subject(project, ident.get_xnat_subject_id()) except XnatException: raise e xnat.rename_experiment(project, ident.get_xnat_subject_id(), orig_name, ident.get_xnat_experiment_id())
def download_subjects(xnat, xnat_project, destination): try: current_zips = os.listdir(destination) except FileNotFoundError: if DRYRUN: logger.info(f"DRYRUN - Skipping creation of {destination}") else: os.mkdir(destination) for subject_id in xnat.get_subject_ids(xnat_project): try: subject = xnat.get_subject(xnat_project, subject_id) except Exception as e: logger.error("Failed to get subject {} from xnat. " "Reason: {}".format(subject_id, e)) continue exp_names = [item for item in subject.experiments.keys()] if not exp_names: logger.error("Subject {} has no experiments.".format(subject.name)) continue if len(exp_names) > 1: logger.error( f"Found {len(exp_names)} experiments for subject " f"{subject.name}. Only one was expected. Skipping subject.") continue experiment = subject.experiments[exp_names[0]] zip_name = subject.name.upper() + ".zip" zip_path = os.path.join(destination, zip_name) if zip_name in current_zips and not update_needed( zip_path, experiment, xnat): logger.debug("All data downloaded for {}. Passing.".format( experiment.name)) continue if DRYRUN: logger.info("Would have downloaded experiment {} from project " "{} to {}".format(experiment.name, xnat_project, zip_path)) continue with datman.utils.make_temp_directory() as temp: try: temp_zip = experiment.download(xnat, temp, zip_name=zip_name) except Exception as e: logger.error("Cant download experiment {}. Reason: {}" "".format(experiment, e)) continue restructure_zip(temp_zip, zip_path)
def get_xnat_subject(ident, xnat): """Get an XNAT subject from the server. Args: ident (:obj:`datman.scanid.Identifier`): A datman identifier instance for a supported naming convention. xnat (:obj:`datman.xnat.xnat`): An XNAT connection to the server to upload to. Raises: XnatException: If the server or project is not accessible. Returns: :obj:`datman.xnat.XNATSubject` or None """ # get the expected xnat project name from the config filename try: xnat_project = CFG.get_key("XnatArchive", site=ident.site) except datman.config.UndefinedSetting: logger.warning("Study {}, Site {}, xnat archive not defined in config" .format(ident.study, ident.site)) return None # check we can get the archive from xnat try: found = xnat.get_projects(xnat_project) except datman.exceptions.XnatException as e: logger.error("Failed to get XNAT project {} for study {} and site " "{}. Reason - {}".format(xnat_project, ident.study, ident.site, e)) return None if not found: logger.error("No match found for XNAT project {} on server {}".format( xnat_project, xnat.server)) return None # check we can get or create the session in xnat try: xnat_subject = xnat.get_subject(xnat_project, ident.get_xnat_subject_id(), create=True) except datman.exceptions.XnatException as e: logger.error("Study {}, site {}, archive {} Failed getting session {}" " from xnat with reason {}" .format(ident.study, ident.site, xnat_project, ident.get_xnat_subject_id(), e)) return None return xnat_subject