def make_clients(): api_key, device_key = get_api_key() fw = flywheel.Flywheel(api_key) if device_key: fw_device = flywheel.Flywheel(device_key) else: fw_device = None fw.enable_feature('beta') # Mock cli login home = os.environ['HOME'] os.environ['HOME'] = tmp_path = tempfile.mkdtemp() cli_config_path = os.path.expanduser('~/.config/flywheel/') if not os.path.exists(cli_config_path): os.makedirs(cli_config_path) with open(os.path.join(cli_config_path, 'user.json'), 'w') as cli_config: json.dump({'key': api_key}, cli_config) client = flywheel.Client() client.enable_feature('beta') # Don't need the login anymore shutil.rmtree(tmp_path) os.environ['HOME'] = home return fw, client, fw_device
def main(): ### Read in arguments parser = argparse.ArgumentParser(description='BIDS Curation') parser.add_argument('--api-key', dest='api_key', action='store', required=True, help='API key') parser.add_argument('-p', dest='project_label', action='store', required=False, default=None, help='Project Label on Flywheel instance') parser.add_argument( '--session', dest='session_id', action='store', required=False, default=None, help= 'Session ID, used to look up project if project label is not readily available' ) parser.add_argument('--reset', dest='reset', action='store_true', default=False, help='Reset BIDS data before running') parser.add_argument('--session-only', dest='session_only', action='store_true', default=False, help='Only curate the session identified by --session') parser.add_argument('--template-file', dest='template_file', action='store', default=None, help='Template file to use') args = parser.parse_args() ### Prep # Check API key - raises Error if key is invalid fw = flywheel.Flywheel(args.api_key) # Get project id from label if args.project_label: project_id = utils.validate_project_label(fw, args.project_label) elif args.session_id: project_id = utils.get_project_id_from_session_id(fw, args.session_id) else: print('Either project label or session id is required!') sys.exit(1) ### Curate BIDS project curate_bids_dir(fw, project_id, args.session_id, reset=args.reset, template_file=args.template_file, session_only=args.session_only)
def test_validate_project_label_invalidproject(self): """ Get project that does not exist. Assert function returns None. NOTE: the environment variable $APIKEY needs to be defined with users API key """ client = flywheel.Flywheel(os.environ['APIKEY']) label = 'doesnotexistdoesnotexistdoesnotexist89479587349' with self.assertRaises(SystemExit): utils.validate_project_label(client, label)
def test_client_isolation(self): fw = self.fw fw2 = flywheel.Flywheel('127.0.0.1:invalid-key') try: user = self.fw.get_current_user() self.assertUserIsSane(user) except flywheel.ApiException: self.fail('Flywheel instance is not isolated!')
def test_validate_project_label_validproject(self): """ Get project that DOES exist. Assert function returns the project. NOTE: the environment variable $APIKEY needs to be defined with users API key """ client = flywheel.Flywheel(os.environ['APIKEY']) label = 'Project Name' project_id = utils.validate_project_label(client, label) project_id_expected = u'58175ad3de26e00012c69306' self.assertEqual(project_id, project_id_expected)
def make_clients(): api_key = None if init_db.SCITRAN_PERSISTENT_DB_URI: # Initialize database first init_db.init_db() site_url = urlparse(os.environ['SCITRAN_SITE_API_URL']) api_key = '{}:__force_insecure:{}'.format( site_url.netloc, init_db.SCITRAN_ADMIN_API_KEY) else: api_key = os.environ.get('SdkTestKey') if not api_key: print( 'Could not initialize test case, no api_key. Try setting the SdkTestKey environment variable!' ) exit(1) fw = flywheel.Flywheel(api_key) fw.enable_feature('beta') fw_root = flywheel.Flywheel(api_key, root=True) fw_root.enable_feature('beta') # Mock cli login home = os.environ['HOME'] os.environ['HOME'] = tmp_path = tempfile.mkdtemp() cli_config_path = os.path.expanduser('~/.config/flywheel/') if not os.path.exists(cli_config_path): os.makedirs(cli_config_path) with open(os.path.join(cli_config_path, 'user.json'), 'w') as cli_config: json.dump({'key': api_key}, cli_config) client = flywheel.Client() client.enable_feature('beta') # Don't need the login anymore shutil.rmtree(tmp_path) os.environ['HOME'] = home return fw, fw_root, client
def create_flywheel_client(require=True): config = load_config() if config is None or config.get('key') is None: if require: print( 'Not logged in, please login using `fw login` and your API key', file=sys.stderr) sys.exit(1) return None result = flywheel.Flywheel(config['key']) log.debug('SDK Version: %s', flywheel.flywheel.SDK_VERSION) log.debug('Flywheel Site URL: %s', result.api_client.configuration.host) return result
def download_tabular_file_wrapper(filename, project_label, group_id, api_key): api_key = get_fw_api(api_key) fw = flywheel.Flywheel(api_key) project = handle_project(fw, project_label, group_id, create=False, raise_on="missing") project_id = project["id"] df = get_info_for_all(fw, project_id) df.drop(columns=["BIDS.Label", "BIDS.Subject"], inplace=True) Path(filename).parent.mkdir(parents=True, exist_ok=True) df.to_csv(filename, index=False, sep="\t")
def main_with_args(api_key, session_id, reset, session_only): ### Prep # Check API key - raises Error if key is invalid fw = flywheel.Flywheel(api_key) if session_id: project_id = utils.get_project_id_from_session_id(fw, session_id) else: print('Session id is required!') sys.exit(1) ### Curate BIDS project curate_bids_dir(fw, project_id, session_id, reset=reset, session_only=session_only)
def generate_license(args): license_file = '/opt/freesurfer/license.txt' license_info = '' # If the config file does not exist then exit if not os.path.isfile(args.json_file): raise SystemExit('File does not exist: %s!' % args.json_file) # Read the config json file with open(args.json_file, 'r') as jsonfile: config = json.load(jsonfile) # OPTION 1: Parse config for license elements print( '\tChecking for license in Gear Configuration (config.FREESURFER_LICENSE)...' ) if config['config'].get('FREESURFER_LICENSE'): license_info = ' '.join( config['config']['FREESURFER_LICENSE'].split()).replace(" ", "\n") print( '\t-->Generating FREESURFER LICENSE file from Gear Configuration.') # OPTION 2: Parse config for license elements if not license_info: print( '\tChecking for license in project info (project.info.FREESURFER_LICENSE)...' ) fw = flywheel.Flywheel(config['inputs']['api_key']['key']) project_id = fw.get_analysis( config['destination']['id']).parents.project project = fw.get_project(project_id) if project.info.get('FREESURFER_LICENSE'): license_info = ' '.join( project.info.get('FREESURFER_LICENSE').split()).replace( " ", "\n") print('\t-->Generating FREESURFER LICENSE file from Project Info.') # Write the license info to a file. if license_info: with open(license_file, 'w') as lf: lf.write(license_info) return 0 else: return 1
def get_flywheel_subjects(key, group_id, project_label, studyid, basedir): # Create client fw = flywheel.Flywheel(key) # API key subs = [] # Iterates through given project for project in fw.get_group_projects(group_id): if project.label == project_label: print('Project: %s: %s' % (project.id, project.label)) # Iterates through sessions in project for session in fw.get_project_sessions(project.id): # Finds subject id for session if 'BIDS' in session.info: sub = session.info['BIDS']['Subject'] for analysis in fw.get_session_analyses(session.id): # looks for fmriprep analyses if 'fmriprep' in analysis.label: if analysis.files != None: # checks for output files - that fmriprep succeeded if sub not in subs: subs.append(sub) subs.sort() return subs
def main(): key = os.environ.get('FlywheelKey') fw = flywheel.Flywheel(key) manifest = load_json_from_file(manifest_path) name = manifest['name'] version = manifest['name'] new_version = version for gear in fw.get_all_gears(): if gear['gear']['name'] == name: new_version = int(gear['gear']['version']) + 1 if new_version != version: print 'New gear version will be ' + str(new_version) manifest['version'] = str(new_version) write_json_to_file(manifest_path, manifest) if os.environ.get('CIRCLE_BRANCH') == 'master': check(call(['fw', 'gear', 'upload'])) else: print 'Not running on master, so not pushing.'
import shutil import logging from fw_heudiconv.cli import curate, export, tabulate # logging stuff logging.basicConfig(level=logging.INFO) logger = logging.getLogger('fw-heudiconv-gear') logger.info("=======: fw-heudiconv starting up :=======") # start up inputs invocation = json.loads(open('config.json').read()) config = invocation['config'] inputs = invocation['inputs'] destination = invocation['destination'] fw = flywheel.Flywheel(inputs['api_key']['key']) user = fw.get_current_user() # start up logic: heuristic = None #inputs['heuristic']['location']['path'] analysis_container = fw.get(destination['id']) project_container = fw.get(analysis_container.parents['project']) project_label = project_container.label dry_run = False #config['dry_run'] action = "Export" #config['action'] # whole project, single session? do_whole_project = False #config['do_whole_project'] if not do_whole_project:
def main(): ### Read in arguments parser = argparse.ArgumentParser(description='BIDS Directory Export') parser.add_argument( '--bids-dir', dest='bids_dir', action='store', required=True, help='Name of directory in which to download BIDS hierarchy. \ NOTE: Directory must be empty.') parser.add_argument('--api-key', dest='api_key', action='store', required=True, help='API key') parser.add_argument('--source-data', dest='source_data', action='store_true', default=False, required=False, help='Include source data in BIDS export') parser.add_argument( '--dry-run', dest='dry_run', action='store_true', default=False, required=False, help= 'Don\'t actually export any data, just print what would be exported') parser.add_argument( '--replace', dest='replace', action='store_true', default=False, required=False, help='Replace files if the modified timestamps do not match') parser.add_argument('--subject', dest='subjects', action='append', help='Limit export to the given subject') parser.add_argument('--session', dest='sessions', action='append', help='Limit export to the given session name') parser.add_argument('--folder', dest='folders', action='append', help='Limit export to the given folder. (e.g. func)') parser.add_argument('-p', dest='project_label', action='store', required=False, default=None, help='Project Label on Flywheel instance') parser.add_argument( '--container-type', dest='container_type', action='store', required=False, default=None, help= 'Download single container (acquisition|session|project) in BIDS format. Must provide --container-id.' ) parser.add_argument( '--container-id', dest='container_id', action='store', required=False, default=None, help= 'Download single container in BIDS format. Must provide --container-type.' ) args = parser.parse_args() # Check API key - raises Error if key is invalid fw = flywheel.Flywheel(args.api_key) try: export_bids(fw, args.bids_dir, args.project_label, subjects=args.subjects, sessions=args.sessions, folders=args.folders, replace=args.replace, dry_run=args.dry_run, container_type=args.container_type, container_id=args.container_id, source_data=args.source_data) except utils.BIDSException as bids_exception: logger.error(bids_exception) sys.exit(bids_exception.status_code)
import logging from fw_heudiconv.cli import export # logging stuff logging.basicConfig(level=logging.INFO) logger = logging.getLogger('reproin-checker-gear') logger.info("{:=^70}\n".format(": reproin-checker gear manager starting up :")) # start up inputs invocation = json.loads(open('config.json').read()) config = invocation['config'] inputs = invocation['inputs'] destination = invocation['destination'] key = inputs['api-key']['key'] fw = flywheel.Flywheel(key) user = fw.get_current_user() # start up logic: analysis_container = fw.get(destination['id']) project_container = fw.get(analysis_container.parents['project']) project_label = project_container.label # find session object origin session_container = fw.get(analysis_container.parent['id']) sessions = [session_container.label] # find subject object origin subject_container = fw.get(session_container.parents['subject']) subjects = [subject_container.label] # logging stuff
os.makedirs(rootdir) # Read in config file config_file = os.path.join(flywheel_basedir, 'config.json') if not os.path.exists(config_file): raise Exception('Config file (%s) does not exist' % config_file) fp = open(config_file, 'r') config_contents = json.loads(fp.read()) fp.close() # Get apikey and session ID number from config file api_key = str(config_contents['inputs']['api_key']['key']) analysis_id = str(config_contents['destination']['id']) ## Create SDK client print("Create SDK client") fw = flywheel.Flywheel(api_key) # Get analysis analysis = fw.get_analysis(analysis_id) # Get container type and id from container_type = analysis['parent']['type'] container_id = analysis['parent']['id'] # Check if curate-bids was ran # Determine if ID is a project or a session ID if container_type == 'project': # Get list of sessions within project container = fw.get_project(container_id) elif container_type == 'session': # If container type is a session, get the specific session container = fw.get_session(container_id)
if __name__ == '__main__': """ Given a Flywheel job id, this script will generate a local testing directory within which you can run the job locally, using Docker, as it ran in Flywheel. Positional inputs: [1] - Api Key [2] - Job ID [3] - (Optional) Directory to save job contents. Defaults to cwd. """ if not sys.argv[1]: raise ValueError('API KEY required') else: api_key = sys.argv[1] fw = flywheel.Flywheel(api_key) if fw.get_current_user().root: fw = flywheel.Flywheel(api_key, root=True) else: raise ValueError('This process requires site-admin priviliges!') # Get the job job = fw.get_job(sys.argv[2]) # Build the local test if len(sys.argv) == 4: test_path_root = sys.argv[3] else: test_path_root = os.getcwd() build_local_test(job, test_path_root, api_key)
gear.log('input \"dicom\" is a ' + gear.data['inputs']['dicom']['base']) gear.log('you can find your file at ' + gear.data['inputs']['dicom']['location']['path']) # as an example a file processing we rename and copy the input file to ./output for upload to Flywheel copyfile( gear.data['inputs']['dicom']['location']['path'], './output/copy_of_' + gear.data['inputs']['dicom']['location']['name']) # Check if the flywheel SDK is installed try: import flywheel # Make some simple calls to the API fw = flywheel.Flywheel(gear.data['inputs']['api-key']['key']) user = fw.get_current_user() config = fw.get_config() gear.log('You are logged in as ' + user.firstname + ' ' + user.lastname + ' at ' + config.site.api_url[:-4]) except ImportError: gear.log( '\nFlywheel SDK is not installed, try "fw gear modify" and then "pip install flywheel-sdk".\n' ) #place output files in the gear output_folder gear.log( 'Make sure to move any result files you want to preserve to the output folder' )
def main(): ### Read in arguments parser = argparse.ArgumentParser(description='BIDS Directory Upload') parser.add_argument('--bids-dir', dest='bids_dir', action='store', required=True, help='BIDS directory') parser.add_argument('--api-key', dest='api_key', action='store', required=True, help='API key') parser.add_argument('-g', dest='group_id', action='store', required=True, help='Group ID on Flywheel instance') parser.add_argument('-p', dest='project_label', action='store', required=False, default=None, help='Project Label on Flywheel instance') parser.add_argument( '--subject', default=None, help='Only upload data from single subject folder (i.e. sub-01)') parser.add_argument( '--session', default=None, help='Only upload data from single session fodler (i.e. ses-01)') parser.add_argument( '--type', dest='hierarchy_type', action='store', required=False, default='Flywheel', choices=['BIDS', 'Flywheel'], help="Hierarchy to load into, either 'BIDS' or 'Flywheel'") parser.add_argument('--source-data', dest='source_data', action='store_true', default=False, required=False, help='Include source data in BIDS upload') parser.add_argument( '--use-template-defaults', dest='local_properties', action='store_false', default=True, required=False, help='Prioiritize template default values for BIDS information') parser.add_argument('-y', '--yes', action='store_true', help='Assume the answer is yes to all prompts') args = parser.parse_args() if args.session and not args.subject: logger.error('Cannot only provide session without subject') sys.exit(1) # Check API key - raises Error if key is invalid fw = flywheel.Flywheel(args.api_key) upload_bids(fw, args.bids_dir, args.group_id, project_label=args.project_label, hierarchy_type=args.hierarchy_type, include_source_data=args.source_data, local_properties=args.local_properties, assume_yes=args.yes, subject_label=args.subject, session_label=args.session)
def export_raw_bids(studyid, basedir, key, group_id, project_label): studydir = os.path.join(basedir, studyid) rawdir = os.path.join(studydir, 'raw') if not os.path.exists(rawdir): os.makedirs(rawdir) # checks whether docker is installed (but not if docker is running) dockerExists = False try: FNULL = open(os.devnull, 'w') sp.call(['docker'], stdout=FNULL, stderr=sp.STDOUT) dockerExists = True except: dockerExists = False # check if fw CLI is installed - needed for exporting BIDS fwExists = False try: FNULL = open(os.devnull, 'w') sp.call(['fw'], stdout=FNULL, stderr=sp.STDOUT) fwExists = True except: fwExists = False print '\n## Exporting raw BIDS now ##\n' if fwExists and dockerExists: # Create client fw = flywheel.Flywheel(key) # API key sub_codes = [] for project in fw.get_group_projects(group_id): if project.label == project_label: print('Project: %s: %s' % (project.id, project.label)) for session in fw.get_project_sessions(project.id): sub = session.subject.code if sub not in sub_codes: sub_codes.append(session.subject.code) all_subs = get_all_subs( studydir) # subjects with fmriprep outputs downloaded sub_code_dict = {} for code in sub_codes: code_w_underscore_removed = code.replace("_", "") # want to removed underscore from subject code because underscore in subject id is not compatible with BIDS if code_w_underscore_removed in all_subs: sub_code_dict[ code] = code_w_underscore_removed # key is subject code, value is subject id # subject code is used to export BIDS, subject id used by the fmriprep output sub_list = sub_code_dict.keys() sub_list.sort() for sub_code in sub_list: sub = sub_code_dict[sub_code] rawsubdir = os.path.join(rawdir, 'sub-%s' % sub) if os.path.exists(rawsubdir): print "Skipping download of raw bids for sub-%s" % sub else: # creates tmp dir specific to the subject tmpsubdir = os.path.join(studydir, 'tmp_sub-%s_BIDS' % sub) os.mkdir(tmpsubdir) # call subprocess to export BIDS commands = [ 'fw', 'export', 'bids', tmpsubdir, '-p', project_label, '--subject', sub_code ] print 'Calling:', ' '.join(commands) sp.call(commands) # moves the exported directory into the raw directory rawsubout = os.path.join(tmpsubdir, 'sub-%s' % sub) print 'Moving %s to %s' % (rawsubout, rawdir) sp.call(['mv', rawsubout, rawdir]) # removes tmp directory that was created print 'Removing %s' % (tmpsubdir) sp.call(['rm', '-rf', tmpsubdir]) """ # gets all subjects with fmriprep directories #all_subs=get_all_subs(studydir) for sub in all_subs: # sub is missing the prefix 'sub-' rawsubdir=os.path.join(rawdir,'sub-%s'%sub) if os.path.exists(rawsubdir): print "Skipping download of raw bids for sub-%s"%sub else: # creates tmp dir specific to the subject tmpsubdir=os.path.join(studydir,'tmp_sub-%s_BIDS'%sub) os.mkdir(tmpsubdir) # call subprocess to export BIDS commands=['fw','export','bids',tmpsubdir,'-p',project_label,'--subject',sub] print 'Calling:',' '.join(commands) sp.call(commands) # moves the exported directory into the raw directory rawsubout=os.path.join(tmpsubdir,'sub-%s'%sub) print 'Moving %s to %s'%(rawsubout,rawdir) sp.call(['mv',rawsubout,rawdir]) # removes tmp directory that was created print 'Removing %s'%(tmpsubdir) sp.call(['rm','-rf',tmpsubdir]) """ # to download all raw bids rather than subject by subject """ tmpdir=os.path.join(studydir,'tmp_BIDS') commands=['fw','export','bids',tmpdir,'-p',project_label] sp.call(commands) sp.call(['mv',tmpdir, rawdir]) subs = os.listdir(tmpdir) for sub in subs: rawsubout = os.path.join(tmpdir,sub) if not os.path.exists(rawsubout): sp.call(['mv',rawsubout,rawdir]) sp.call(['rm','-rf',tmpdir]) """ else: if not fwExists: print 'Flywheel CLI is not installed, which is required for exporting raw BIDS.' if not dockerExists: print 'Docker is not installed. Docker is required to export raw BIDS from flywheel'
def download_flywheel_fmriprep(key, group_id, project_label, studyid, basedir, downloadReports, downloadFmriprep, downloadFreesurfer, ignoreSessionLabel, subjectList, overwriteSubjectOutputs): # Creates tmp, fmriprep, and reports directories if they don't exist studydir = os.path.join(basedir, studyid) if not os.path.exists(studydir): os.mkdir(studydir) tmpdir = os.path.join(studydir, 'tmp') if not os.path.exists(tmpdir): os.mkdir(os.path.join(tmpdir)) fmriprepdir = os.path.join(studydir, 'fmriprep') if downloadFmriprep and not os.path.exists(fmriprepdir): os.mkdir(fmriprepdir) freesurferdir = os.path.join(studydir, 'freesurfer') if downloadFreesurfer and not os.path.exists(freesurferdir): os.mkdir(freesurferdir) reportsdir = os.path.join(studydir, 'reports') if downloadReports and not os.path.exists(reportsdir): os.mkdir(reportsdir) # Create client fw = flywheel.Flywheel(key) # API key if overwriteSubjectOutputs: remove_existing_sub_dirs_to_overwrite_later(studyid, basedir, subjectList, downloadReports, downloadFmriprep, downloadFreesurfer) print '\n## Downloading fmriprep outputs now ##\n' # Iterates through given project for project in fw.get_group_projects(group_id): if project.label == project_label: print('Project: %s: %s' % (project.id, project.label)) for session in fw.get_project_sessions(project.id): if 'BIDS' not in session.info: break sub = session.info['BIDS']['Subject'] if sub in subjectList: dates = [] analysis_ids = {} # key is date, value is analysis.id analysis_objs = { } # key is analysis.id, value is analysis object for analysis in fw.get_session_analyses(session.id): # looks for fmriprep analyses if 'fmriprep' in analysis.label: print('\tAnalysis: %s: %s' % (analysis.id, analysis.label)) date_created = analysis.created analysis_ids[date_created] = analysis.id analysis_objs[analysis.id] = analysis if analysis.files != None: # checks for output files - that fmriprep succeeded dates.append(date_created) if len(dates) != 0: list.sort(dates) most_recent_analysis_id = analysis_ids[dates[ -1]] # if fmriprep was run multiple times, uses most recent analysis """ # Doesn't work at the moment try: print "Downloading session analysis" fw.download_session_analysis_outputs(session.id, analysis.id) except flywheel.ApiException as e: print 'Could not use fw.download_session_analysis_outputs' print('API Error: %d -- %s' % (e.status, e.reason)) """ for file in analysis_objs[ most_recent_analysis_id].files: #print file.name name = file.name # assumes subject ID is between sub- and _ or between sub- and . if 'sub-' in name: i1 = name.find('sub-') tmpname = name[i1:] if '_' in tmpname: i2 = tmpname.find('_') else: i2 = tmpname.find('.') if i1 > -1 and i2 > -1: sub = tmpname[: i2] # sub is the subject ID with 'sub-' removed #print "Subject ID:", sub # get fmriprep reports (html and svg files) if downloadReports and 'html' in file.name: # sub-<id>.html.zip subreportsdir = os.path.join( reportsdir, sub) session_label = session['label'] session_label = re.sub( r'[^a-zA-Z0-9]+', '', session_label ) # remove non-alphanumeric characters subsesreportsdir = os.path.join( reportsdir, sub, 'ses-' + session_label) if not ignoreSessionLabel and os.path.exists( subsesreportsdir ) and not overwriteSubjectOutputs: print 'Skipping downloading and processing of fmriprep reports for %s/ses-%s' % ( sub, session_label) elif ignoreSessionLabel and os.path.exists( subreportsdir ) and not overwriteSubjectOutputs: print 'Skipping downloading and processing of fmriprep reports for %s' % ( sub) else: downloadSessionOnly = False if os.path.exists( subreportsdir ) and not ignoreSessionLabel: downloadSessionOnly = True # download the file outfile = sub + '.html.zip' print 'Downloading', sub + '/ses-' + session_label + ':', file.name filepath = os.path.join( tmpdir, outfile) fw.download_output_from_session_analysis( session.id, most_recent_analysis_id, file.name, filepath) #download_request = fw.download_session_analysis_outputs(session.id, most_recent_analysis_id, ticket='') #fw.download_ticket(download_request.ticket, filepath) unzippedfilepath = filepath[:-4] # unzip the file unzip_dir(filepath, unzippedfilepath) # Move sub folder in sub-<id>.html->flywheel->...->sub-<id> to the reportsdir # iterates through the flywheel folder to find sub folder buried inside # the variable i is used to avoid an infinite loop i = 10 curdir = '' fullcurdir = os.path.join( unzippedfilepath, 'flywheel') moved = False while i > 0 and curdir != sub: if sub in os.listdir( fullcurdir): desireddir = os.path.join( fullcurdir, sub) targetdir = reportsdir if downloadSessionOnly: desireddir = os.path.join( fullcurdir, sub, 'ses-' + session_label) targetdir = os.path.join( reportsdir, sub) #if not os.path.exists(targetdir): # os.mkdir(targetdir) if os.path.exists( desireddir): move_dir( desireddir, targetdir) moved = True if len(os.listdir( fullcurdir)) > 0: # assuming only one directory in fullcurdir for folder in os.listdir( fullcurdir): if os.path.isdir( os.path.join( fullcurdir, folder)): curdir = folder fullcurdir = os.path.join( fullcurdir, folder) i -= 1 if not moved: print "Could not find %s in %s.html" % ( sub, sub) # moves and renames index.html to sub-<id>.html indexhtmlpath = os.path.join( unzippedfilepath, 'index.html') if os.path.exists(indexhtmlpath): subreportsdir = os.path.join( reportsdir, sub) move_dir( indexhtmlpath, subreportsdir) oldindexhtml = os.path.join( subreportsdir, 'index.html') #newindexhtml=os.path.join(subreportsdir,'ses-'+session_label,'%s.html'%sub) newindexhtml = os.path.join( reportsdir, '%s.html' % sub) move_dir( oldindexhtml, newindexhtml) # move figures directory figurespath = os.path.join( unzippedfilepath, sub, 'figures') print figurespath if os.path.exists(figurespath): subreportsdir = os.path.join( reportsdir, sub) move_dir( figurespath, subreportsdir) # remove originally downloaded files remove_dir(filepath) remove_dir(unzippedfilepath) # get fmriprep outputs elif ( downloadFmriprep or downloadFreesurfer ) and file.name.startswith( 'fmriprep_' + sub ): # fmriprep_sub-<subid>_<random alphanumericcode?>.zip subfmriprepdir = os.path.join( fmriprepdir, sub) subfreesurferdir = os.path.join( freesurferdir, sub) session_label = session['label'] session_label = re.sub( r'[^a-zA-Z0-9]+', '', session_label ) # remove non-alphanumeric characters subsesfmriprepdir = os.path.join( fmriprepdir, sub, 'ses-' + session_label) continueFmriprepDownload = downloadFmriprep continueFreesurferDownload = downloadFreesurfer if not ignoreSessionLabel and downloadFmriprep and os.path.exists( subsesfmriprepdir ) and not overwriteSubjectOutputs: print 'Skipping downloading and processing of fmriprep outputs for %s/ses-%s' % ( sub, session_label) continueFmriprepDownload = False elif ignoreSessionLabel and downloadFmriprep and os.path.exists( subfmriprepdir ) and not overwriteSubjectOutputs: print 'Skipping downloading and processing of fmriprep outputs for %s' % ( sub) continueFmriprepDownload = False if not ignoreSessionLabel and downloadFreesurfer and os.path.exists( subfreesurferdir ) and not overwriteSubjectOutputs: print 'Skipping downloading and processing of freesurfer outputs for %s' % sub continueFreesurferDownload = False if continueFmriprepDownload or continueFreesurferDownload: downloadSessionOnly = False if os.path.exists( subfmriprepdir ) and not ignoreSessionLabel: downloadSessionOnly = True outfile = sub + '.zip' # downloads outputs print 'Downloading', sub + '/ses-' + session_label + ':', file.name filepath = os.path.join( tmpdir, outfile) fw.download_output_from_session_analysis( session.id, most_recent_analysis_id, file.name, filepath) #download_request = fw.download_session_analysis_outputs(session.id, most_recent_analysis_id, ticket='') #fw.download_ticket(download_request.ticket, filepath) # unzips outputs unzippedfilepath = filepath[: -4] # removes .zip from name unzip_dir(filepath, unzippedfilepath) # Move downloaded fmriprep folder to fmriprep unzippedfmriprep = os.path.join( unzippedfilepath, 'fmriprep', sub) newsubfmriprep = os.path.join( fmriprepdir, '%s' % sub) # iterates through the unzipped sub folder to find fmriprep folder buried inside # the variable i is used to avoid an infinite loop i = 3 curdir = '' fullcurdir = unzippedfilepath desireddir = os.path.join( fullcurdir, 'fmriprep', sub) moved = False while i > 0 and curdir != 'fmriprep' and curdir != 'freesurfer': if downloadFmriprep and continueFmriprepDownload and 'fmriprep' in os.listdir( fullcurdir): desireddir = os.path.join( fullcurdir, 'fmriprep', sub) targetdir = fmriprepdir if downloadSessionOnly: desireddir = os.path.join( fullcurdir, 'fmriprep', sub, 'ses-' + session_label) targetdir = os.path.join( fmriprepdir, sub) tmpsubfmriprepdir = os.path.join( fullcurdir, 'fmriprep', sub) if os.path.exists( desireddir): move_dir( desireddir, targetdir) moved = True if downloadFreesurfer and continueFreesurferDownload and 'freesurfer' in os.listdir( fullcurdir): tmpsubfreesurferdir = os.path.join( fullcurdir, 'freesurfer', sub) if os.path.exists( tmpsubfreesurferdir ) and not os.path.exists( os.path.join( freesurferdir, sub)): move_dir( tmpsubfreesurferdir, freesurferdir) moved = True if len(os.listdir( fullcurdir)) > 0: # assuming only one directory in fullcurdir for folder in os.listdir( fullcurdir): if os.path.isdir( os.path.join( fullcurdir, folder)): curdir = folder fullcurdir = os.path.join( fullcurdir, folder) i -= 1 if downloadFmriprep and not moved: print "Could not find fmriprep in %s" % fullcurdir # Remove figures directory from sub folder in fmriprep # the figures directory is a duplicate of the fmriprep reports, which are downloaded separately into the reports directory fmriprepsubfigures = os.path.join( newsubfmriprep, 'figures') remove_dir(fmriprepsubfigures) remove_dir(filepath) remove_dir(unzippedfilepath) # remove the tmp directory if os.path.exists(tmpdir): remove_dir(tmpdir)
def main(): ### SETUP # Define variables flywheel_basedir = os.environ['FLYWHEEL'] rootdir = os.path.join(flywheel_basedir, 'input', 'bids_dataset') if not os.path.exists(rootdir): os.makedirs(rootdir) # Read in config file config_file = os.path.join(flywheel_basedir, 'config.json') if not os.path.exists(config_file): raise Exception('Config file (%s) does not exist' % config_file) fp = open(config_file, 'r') config_contents = json.loads(fp.read()) fp.close() # Get apikey and session ID number from config file api_key = str(config_contents['inputs']['api_key']['key']) analysis_id = str(config_contents['destination']['id']) ## Create SDK client print("Create SDK client") fw = flywheel.Flywheel(api_key) # Get analysis analysis = fw.get_analysis(analysis_id) # Get container type and id from container_type = analysis['parent']['type'] container_id = analysis['parent']['id'] # Check if curate-bids was ran # Determine if ID is a project or a session ID if container_type == 'project': # Get list of sessions within project project = fw.get_project(container_id) BIDS_metadata = project.get('info', {}).get('BIDS') elif container_type == 'session': # If container type is a session, get the specific session session = fw.get_session(container_id) project = fw.get_project(session.project) BIDS_metadata = session.get('info', {}).get('BIDS') if BIDS_metadata: try: export_bids.export_bids(fw, rootdir, project.label, subjects=[session.subject.code], sessions=[session.label], validate=False) if BIDS_metadata != 'NA': if container_type == 'session': download_optional_inputs( flywheel_basedir, "sub-{}".format(BIDS_metadata.get('Subject')), "ses-{}".format(BIDS_metadata.get('Label'))) else: print( 'BIDS Curation was not valid, will not download additional files.' ) except SystemExit: # This is a necessary evil until bids_export doesn't call sys.exit(1) print('Curated BIDS export failed, using on-the-fly bids-export') # Clean rootdir shutil.rmtree(rootdir) os.makedirs(rootdir) create_and_download_bids(fw, rootdir, flywheel_basedir, analysis_id) else: create_and_download_bids(fw, rootdir, flywheel_basedir, analysis_id)
ts2 = other.acq.get('timestamp') if ts1 and ts2: return int((ts1 - ts2).total_seconds()) return int((self.acq['created'] - other.acq['created']).total_seconds()) def to_dict(fw, obj): return fw.api_client.sanitize_for_serialization(obj.to_dict()) if __name__ == '__main__': import argparse import flywheel import json parser = argparse.ArgumentParser(description='Dump project tree to json') parser.add_argument('--api-key', dest='api_key', action='store', required=True, help='API key') parser.add_argument('-p', dest='project_label', action='store', required=False, default=None, help='Project Label on Flywheel instance') parser.add_argument('output_file', help='The output file destination') args = parser.parse_args() fw = flywheel.Flywheel(args.api_key) project_id = utils.validate_project_label(fw, args.project_label) project_tree = get_project_tree(fw, project_id) with open(args.output_file, 'w') as f: json.dump(project_tree.to_json(), f, indent=2)