def listInventory(self): # Get our list of components filtered by project and component type if self.componentType is None or self.institution is None: ERROR("listInventory needs componentType and institution") return INFO('Fetching an inventory list associated with project code \'{0}\', component type(s) [\'{1}\'], and institution(s) [\'{2}\'] from the ITkPD...'.format( self.project, '\', \''.join(self.componentType), '\', \''.join(self.institution))) timestamp = time.strftime('%Y/%m/%d-%H:%M:%S') components = dbCommands['listComponents'].run(project = 'S', componentType = self.componentType) # Filter the components by institution (or by current location) if self.useCurrentLocation: locationKey = 'currentLocation' else: locationKey = 'institution' if self.includeTrashed: filterFunction = lambda component: component[locationKey]['code'] in self.institution else: filterFunction = lambda component: component[locationKey]['code'] in self.institution and not component['trashed'] # Preallocate our inventory dictionary inventory = {} for institution in self.institution: inventory[institution] = {} for componentType in self.componentType: inventory[institution][componentType] = [] # Sort through our list of components and filter our the desired keys keys = ['dummy', 'currentGrade', 'reworked', 'trashed', 'assembled', 'qaPassed', 'qaState'] KeyErrorCounter = 0 TypeErrorCounter = 0 for component in components: try: if filterFunction(component): data = dict((key, component[key]) for key in keys) data['type'] = component['type']['code'] data['currentStage'] = component['currentStage']['code'] data['code'] = component['serialNumber'] if component['serialNumber'] != None else component['code'] inventory[component[locationKey]['code']][component['componentType']['code']].append(data) else: pass except TypeError as error: print('Encountered TypeError %s for component \'%s\' -- skipping.' % (error, component['code'])) TypeErrorCounter += 1 if KeyErrorCounter > 1: WARNING('%s components skipped due to key errors.' % KeyErrorCounter) if TypeErrorCounter > 1: WARNING('%s components skipped due to type errors.' % TypeErrorCounter) # Print our inventory and save the associated json INFO('Printing inventory list:\n') header = {'code': 'Code/Serial Number', 'type': 'Type', 'currentStage': 'Current Stage', 'dummy': 'Dummy', 'currentGrade': 'Current Grade', 'reworked': 'Reworked', 'trashed': 'Trashed', 'assembled': 'Assembled', 'qaPassed': 'QA Passed', 'qaState': 'QA State'} form = ' {code:<40}{type:<15}{currentStage:<20}{dummy:<15}{currentGrade:<20}{reworked:<15}{trashed:<15}{assembled:<15}{qaPassed:<15}{qaState:<15}' for institution, componentTypes in inventory.items(): for componentType, components in componentTypes.items(): print(' {0}{1}{2} / {3} :{4}\n'.format(Colours.BOLD, Colours.WHITE, institution, componentType, Colours.ENDC)) print(Colours.BOLD + Colours.WHITE + form.format(**header) + Colours.ENDC) for component in components: print(form.format(**component)) print('') if self.savePath != None: self.__save({'timestamp': timestamp, 'function': 'listInventory', 'args': {'project': self.project, 'componentType': self.componentType, 'institution': self.institution, 'useCurrentLocation': self.useCurrentLocation, 'includeTrashed': self.includeTrashed}, 'content': inventory})
required.add_argument('-i', '--institution', dest = 'institution', nargs = '*', type = str, help = 'the institution(s) to fetch the inventory from') # Define our optional arguments optional = parser.add_argument_group('optional arguments') optional.add_argument('-s', '--savePath', dest = 'savePath', type = str, help = 'save path for the resulting content (suffix with .json)') optional.add_argument('--useCurrentLocation', dest = 'useCurrentLocation', action = 'store_true', help = 'filter by current location when using \'listInventory\'') optional.add_argument('--includeTrashed', dest = 'includeTrashed', action = 'store_true', help = 'include trashed components when using \'listInventory\'') # Fetch our args args = parser.parse_args() # Check if our savepath already exists, if the parent directory doesn't exist, and if suffix is not .json # Raise an error and quit if any of these are true if args.savePath != None: if os.path.exists(args.savePath): ERROR('-s [--savePath] already exists and cannot be overwritten: ' + args.savePath) STATUS('Finished with error', False) sys.exit(1) elif not os.path.exists(os.path.dirname(args.savePath)): ERROR('-s [--savePath] parent directory does not exist: ' + os.path.dirname(args.savePath)) STATUS('Finished with error', False) sys.exit(1) elif args.savePath[-5:].lower() != '.json': ERROR('-s [--savePath] does not end with \'.json\': ' + args.savePath) STATUS('Finished with error', False) sys.exit(1) # Generate our inventory object inventory = Inventory(args) # Run main and catch whatever dbAccessErrors may arise
def trashUnassembled(self): # If using the command 'trashUnassembled', only allow a single institution to be include in the command call # This is for safety purposes if args.institution is None or len(args.institution) != 1: ERROR('-i [--institution] may only refer to a single institution code when using the command \'trashUnassembled\': %s' % args.institution) STATUS('Finished with error.', False) return 0 # sys.exit(1) # Get our list of components filtered by project and component type INFO('Fetching an inventory list associated with project code \'{0}\', component type(s) [\'{1}\'], institution(s) [\'{2}\'], and \'assembled\' == False from the ITkPD...'.format( self.project, '\', \''.join(self.componentType), '\', \''.join(self.institution))) timestamp = time.strftime('%Y/%m/%d-%H:%M:%S') components = dbCommands['listComponents'].run(project = self.project, componentType = self.componentType) # Filter the components by institution (or by current location) and if they are not assembled if self.useCurrentLocation: locationKey = 'currentLocation' else: locationKey = 'institution' components = list(filter(lambda component: component[locationKey]['code'] in self.institution and not component['assembled'] and not component['trashed'], components)) # Preallocate our inventory dictionary inventory = {} for institution in self.institution: inventory[institution] = {} for componentType in self.componentType: inventory[institution][componentType] = [] # Sort through our list of components and filter our the desired keys keys = ['dummy', 'currentGrade', 'assembled', 'qaPassed', 'qaState'] for component in components: data = dict((key, component[key]) for key in keys) data['type'] = component['type']['code'] data['currentStage'] = component['currentStage']['code'] data['code'] = component['serialNumber'] if component['serialNumber'] != None else component['code'] inventory[component[locationKey]['code']][component['componentType']['code']].append(data) # Print the list of items to be trashed INFO('The following components will be trashed:\n') header = {'code': 'Code/Serial Number', 'type': 'Type', 'currentStage': 'Current Stage', 'dummy': 'Dummy', 'currentGrade': 'Current Grade', 'assembled': 'Assembled', 'qaPassed': 'QA Passed', 'qaState': 'QA State'} form = ' {code:<40}{type:<15}{currentStage:<20}{dummy:<15}{currentGrade:<20}{assembled:<15}{qaPassed:<15}{qaState:<15}' for institution, componentTypes in inventory.items(): for componentType, components in componentTypes.items(): print(' {0}{1}{2} / {3} :{4}\n'.format(Colours.BOLD, Colours.WHITE, institution, componentType, Colours.ENDC)) print(Colours.BOLD + Colours.WHITE + form.format(**header) + Colours.ENDC) for component in components: print(form.format(**component)) print('') # Confirm that the user wants to trash the filtered components if self.__getConfirm('Please type \'confirm_trash\' to trash the above components or \'quit\' to cancel this action:', 'confirm_trash', 'quit'): for institution, componentTypes in inventory.items(): for componentType, components in componentTypes.items(): for i, component in enumerate(components): INFO('Trashing component \'{0}\'...'.format(component['code'])) dbCommands['setComponentTrashed'].run(component = component['code'], trashed = True) inventory[institution][componentType][i]['trashed'] = True else: INFO('Trashing aborted.') return # Confirm that the user does not want to undo the previous action if self.__getConfirm('Please type \'undo\' to undo the above action or \'confirm_trash\' to conclude the function:', 'undo', 'confirm_trash'): for institution, componentTypes in inventory.items(): for componentType, components in componentTypes.items(): for i, component in enumerate(components): INFO('Un-trashing component \'{0}\'...'.format(component['code'])) dbCommands['setComponentTrashed'].run(component = component['code'], trashed = False) inventory[institution][componentType][i]['trashed'] = False return else: INFO('Trashing confirmed.') # Save the resulting json for the trashed components if self.savePath != None: self.__save({'timestamp': timestamp, 'function': 'listInventory', 'args': {'project': self.project, 'componentType': self.componentType, 'institution': self.institution, 'useCurrentLocation': self.useCurrentLocation}, 'content': inventory})
'rrulewrapperFrequency': args.rrulewrapperFrequency, 'rrulewrapperInterval': args.rrulewrapperInterval, 'includeTotal': args.includeTotal, 'saveJson': args.saveJson } print('') INFO('*** generatePlots.py ***') # Try to import matplotlib try: global matplotlib import matplotlib.pyplot as plt from matplotlib.dates import DAILY, MONTHLY, YEARLY, DateFormatter, rrulewrapper, RRuleLocator except ImportError: ERROR('Python module \'matplotlib\' is not installed.') INFO('To install, please type \'sudo apt-get install python-matplotlib\' for Python 2.') INFO('For Python 3, type \'sudo apt-get install python3-matplotlib\'.') STATUS('Finished with error', False) sys.exit(1) # Generate our PlotMaker object and make our plots plotMaker = PlotMaker(args.verbose) plotMaker.authenticate() plotMaker = plotMaker.makePlots(**kwargs) STATUS('Finished successfully.', True) sys.exit(0) # In the case of a keyboard interrupt, quit with error except KeyboardInterrupt: print('')
def makePlots(self, **kwargs): # Get our keys for kwargs keys = kwargs.keys() # Define a general error class class Error(Exception): def __init__(self, message): self.message = message # Perform some argument checking # Note, this does not check every required argument for makePlot() is present in kwargs ######################################################################################################## # This is bad of me, it should be fixed in the future if this class is to be used outside of this file # ######################################################################################################## INFO('Peforming argument checking...') try: if 'project' not in keys: raise Error('Keyword argument \'project\' is required by PlotMaker.makePlots().') if 'componentType' not in keys: raise Error('Keyword argument \'componentType\' is required by PlotMaker.makePlots().') if 'savePath' not in keys: raise Error('Keyword argument \'savePath\' is required by PlotMaker.makePlots().') if kwargs['savePath'][-4:] != '.pdf' and kwargs['savePath'][-4:] != '.png': raise Error('--savePath must have suffix \'.pdf\' or \'.png\'": --savePath = %s' % kwargs['savePath']) if not os.path.exists(os.path.dirname(kwargs['savePath'])): raise Error('Parent directory does not exist: %s' % os.path.dirname(kwargs['savePath'])) if kwargs['type'] != None or kwargs['currentStage'] != None or kwargs['split'] in ['type', 'currentStage']: componentTypeJson = self.doSomething(action = 'getComponentTypeByCode', method = 'GET', data = {'project': kwargs['project'], 'code': kwargs['componentType']}) if componentTypeJson['types'] == [] and (kwargs['split'] == 'type' or kwargs['type'] != []): raise Error('Component type \'%s\' does not have any types and so it does not make sense to split/filter by type.' % kwargs['componentType']) if kwargs['type'] != None: unknownTypes = [type for type in kwargs['type'] if type not in [type2['code'] for type2 in componentTypeJson['types']]] if unknownTypes != []: raise Error('Unknown type code(s) for component type \'%s\': [\'%s\']' % (kwargs['componentType'], '\', \''.join(unknownTypes))) if componentTypeJson['stages'] == [] and (kwargs['split'] == 'currentStage' or kwargs['currentStage'] != []): raise Error('Component type \'%s\' does not have any types and so it does not make sense to split/filter by the current stage.' % kwargs['componentType']) if kwargs['currentStage'] != None: unknownStages = [stage for stage in kwargs['currentStage'] if stage not in [stage2['code'] for stage2 in componentTypeJson['stages']]] if unknownStages != []: raise Error('Unknown stage code(s) for component type \'%s\': [\'%s\']' % (kwargs['componentType'], '\', \''.join(unknownStages))) if kwargs['currentLocation'] != None or kwargs['institution'] != None: institutionsJson = self.doSomething('listInstitutions', 'GET', data = {}) if kwargs['currentLocation'] != None: unknownCurrentLocations = [currentLocation for currentLocation in kwargs['currentLocation'] if currentLocation not in [currentLocation2['code'] for currentLocation2 in institutionsJson]] if unknownCurrentLocations != []: raise Error('Unknown current location code(s): [\'%s\']' % '\', \''.join(unknownCurrentLocations)) if kwargs['institution'] != None: unknownInstitutions = [institution for institution in kwargs['institution'] if institution not in [institution2['code'] for institution2 in institutionsJson]] if unknownInstitutions != []: raise Error('Unknown institution code(s): [\'%s\']' % '\', \''.join(unknownInstitutions)) except Error as e: ERROR(e.message) STATUS('Finished with error.', False) sys.exit(1) INFO('Argument checking passed.') # Get our initial list of components from the DB data = {'project': kwargs['project'], 'componentType': kwargs['componentType']} if kwargs['type'] != None: data['type'] = kwargs['type'] if kwargs['currentStage'] != None: data['currentStage'] = kwargs['currentStage'] INFO('Fetching a list of components filtered by project/componentType/type/currentStage from the ITkPD...') components = self.doSomething(action = 'listComponents', method = 'GET', data = data) INFO('List of components successfully fetched (%s entries).' % len(components)) # Get our cuts cuts = self.__getCuts(**kwargs) # Apply our cuts to each component and keep only the components which pass all cuts INFO('Applying cuts to the list of components and generating counter...') if kwargs['currentStage'] != None or kwargs['split'] == 'currentStage': addToCounter = self.__addToCounterWithStages finalizeCounter = lambda counter: self.__finalizeCounterWithStages(counter, **kwargs) else: addToCounter = self.__addToCounter finalizeCounter = lambda counter: self.__finalizeCounter(counter, **kwargs) split = kwargs['split'] passedComponents = 0 counter = {'total': []} for component in components: if self.__applyCuts(component, cuts): passedComponents += 1 addToCounter(component, counter, split) if [0 for value in counter.values() if value == []] != []: INFO('Cuts successfully applied to list of components (0 entries).') WARNING('No components passed the cuts -- no plot to be generated.') else: # Finalize the counter and delete our old reference to components finalizeCounter(counter) del components INFO('Cuts successfully applied to list of components (%s entries).' % passedComponents) self.__drawPlots(counter, **kwargs)
def main(args): try: # Use the global definition of input global input print('') print( '******************************************************************************' ) print( '* {0}{1}uploadITSDAQTests.py{2} *' .format(Colours.WHITE, Colours.BOLD, Colours.ENDC)) print( '******************************************************************************' ) print('') # Rename our argument variables results_path, all_files, all_tests, get_confirm, ps_path, cfg_path, up_files = args.results_path, args.all_files, args.all_tests, args.get_confirm, args.ps_path, args.cfg_path, args.up_files if ps_path != None: ps_path = os.path.abspath(ps_path) + '/' elif up_files: ERROR('--psPath must not be None if uploading files.') STATUS('Finished with error.', False) sys.exit(1) if cfg_path != None: cfg_path = os.path.abspath(cfg_path) + '/' elif up_files: ERROR('--cfgPath must not be None if uploading files.') STATUS('Finished with error.', False) sys.exit(1) if results_path != None: results_path = os.path.abspath( results_path) + '/' if os.path.isdir( results_path) else os.path.abspath(results_path) # Check if results_path/ps_path/cfg_path exists (and that ps_path/cfg_path are directories) if not os.path.exists(results_path): raise FileNotFoundError(results_path) if up_files: if not os.path.exists(ps_path): raise FileNotFoundError(ps_path) if not os.path.isdir(ps_path): ERROR('--psPath is not a directory: ' + ps_path) STATUS('Finished with error.', False) sys.exit(1) if not os.path.exists(cfg_path): raise FileNotFoundError(cfg_path) if not os.path.isdir(cfg_path): ERROR('--cfgPath is not a directory: ' + cfg_path) STATUS('Finished with error.', False) sys.exit(1) INFO('Using:') print(' results_path = %s' % results_path) print(' all_files = %s' % all_files) print(' all_tests = %s' % all_tests) print(' get_confirm = %s' % get_confirm) print(' ps_path = %s' % ps_path) print(' cfg_path = %s' % cfg_path) print(' up_files = %s' % up_files) INFO('Launching ITkPDSession.') session = ITkPDSession() session.authenticate() fullTest = False # Check if results_path points to a directory if os.path.isdir(results_path): # Open our results directory results_directory = ResultsDirectory(results_path, ps_path, cfg_path) results_directory.getResultsSummaryFilepaths() # Select everything if all_files if all_files: results_directory.openResultsSummaryFiles() summary_files = results_directory.returnResultsSummaryFiles() # State there is nothing if there is nothing elif results_directory.returnLengthFilepaths == 0: STATUS('Finished successfully.', True) sys.exit(0) # Else ask the user what they want to upload else: INFO('Looking in: ' + results_path) INFO('The following files were found:\n') results_directory.printSummary() print('') indices = getIndices(results_directory.returnLengthFilepaths()) results_directory.openResultsSummaryFiles(*indices) summary_files = results_directory.returnResultsSummaryFiles() else: # Else if results_path points to a file, summary_files will contain only that file summary_files = [ ResultsSummaryFile(results_path, ps_path, cfg_path) ] # Iterate over all of our summary files for summary_file in summary_files: INFO('Looking in: ' + summary_file.returnFilepath()) # Get our tests try: summary_file.getTests() except FileNotFoundError as path: WARNING( 'Filepath does not exist: {0} -- skipping'.format(path)) continue # If all_tests, automatically select all tests if all_tests: indices = range(summary_file.returnLengthTests()) # Else, print a summary table and ask the user to specify which tests else: tests = summary_file.returnTests() INFO('The following tests were found:\n') summary_file.printSummary() print('') if len(tests) >= 7: for i, test in enumerate(tests): if ((test['JSON']['runNumber'].split('-')[0] == tests[i + 6]['JSON']['runNumber'].split('-')[0]) and ((int(tests[i + 6]['JSON']['runNumber'].split('-')[1]) - int(test['JSON']['runNumber'].split('-')[1])) == 41)): INFO( 'Run numbers {0} through {1} appear to be part of a FullTest, would you like to only upload those results?' .format(test['JSON']['runNumber'], tests[i + 6]['JSON']['runNumber'])) INFO( 'Only the following files will be uploaded: <config>.det, <trim file>.trim, <mask file>.mask, and <post-trim response curve>.pdf.' ) if getYesOrNo( 'Please enter \'y\' to confirm the FullTest or \'n\' to only upload specific results:' ): INFO( 'Only uploading results from the FullTest.' ) indices = list(range(i, i + 7)) fullTest = True break else: indices = getIndices( summary_file.returnLengthTests()) break else: indices = getIndices(summary_file.returnLengthTests()) # For each selected test, finalize the JSON for length_index, i in enumerate(indices): # If finalizeJSON() raises a skip, the component cannot be identified and so cannot be uploaded # i.e., we want to just continue over that component (this would likely happen to every other component in the ResultsSummaryFile) try: summary_file.finalizeJSON(session, i) except Skip: continue # If get_confirm, print the JSON and ask the user 'y' or 'n' if get_confirm: INFO('Printing JSON for run number: ' + summary_file.returnTests(i)['JSON']['runNumber']) INFO('JSON:') summary_file.printJSON(i) if up_files: if fullTest: if length_index == 0: del summary_file.tests[i]['files_to_upload'][ 'strobe_delay_path'] INFO( 'The following file(s) will also be uploaded:' ) try: print(' ' + summary_file.returnTests(i) ['files_to_upload']['det_path']) except KeyError: print(' <None found>') elif length_index == 2: INFO( 'The following file(s) will also be uploaded:' ) try: print(' ' + summary_file.returnTests(i) ['files_to_upload']['trim_path']) print(' ' + summary_file.returnTests(i) ['files_to_upload']['mask_path']) except KeyError: print(' <None found>') elif length_index == 4: INFO( 'The following file(s) will also be uploaded:' ) try: print(' ' + summary_file.returnTests( i)['files_to_upload'] ['response_curve_path']) except KeyError: print(' <None found>') else: INFO( 'The following file(s) will also be uploaded:') if summary_file.returnTests( i)['files_to_upload'].keys() == []: print(' <None found>') else: for file_key in summary_file.returnTests( i)['files_to_upload'].keys(): print(' ' + summary_file.returnTests(i) ['files_to_upload'][file_key]) if not getYesOrNo( 'Please enter \'y\' to confirm the upload or \'n\' to cancel:' ): INFO('Cancelled upload of run number: ' + summary_file.returnTests(i)['JSON']['runNumber']) continue summary_file.uploadTests(session, i) if up_files: summary_file.uploadFiles(session, i) INFO('Uploaded run number: ' + summary_file.returnTests(i)['JSON']['runNumber']) STATUS('Finished successfully.', True) sys.exit(0) except KeyboardInterrupt: print('') ERROR('Exectution terminated.') STATUS('Finished with error.', False) sys.exit(1) except FileNotFoundError as e: ERROR('Path does not exist: {0}'.format(e)) STATUS('Finished with error.', False) sys.exit(1)
def __init__(self, get_immediately=False, expert=False, **kwargs): ''' A class for representing components in the ITkPD. Args: kwargs (dict): the code for the component (kwargs: 'component') OR the code for the project, the code for the component type, and the code for the type (kwargs: 'project', 'componentType', 'type'). get_immediately (bool): immediately fetch the json for the test type (default: False). expert (bool): disable self.get() inside member functions, arg checking, and printing INFO/WARNING functions (default: False). ''' # Read in our args self.expert = expert # Get our keys keys = kwargs.keys() # If we only have the 'component' key, then we are dealing with a single component if keys == ['component']: # Read in our component code and initialize our component type information self.component = kwargs['component'].lower() self.project = None self.componentType = None self.type = None # Do arg checking on self.component to see if it looks like a component code if len(self.component) != 32 and self.component.isalnum(): if not self.expert: ERROR('Invalid component code: {0}'.format(self.component)) ERROR( 'Keyword arg \'component\' must be 32 alphanumeric digits -- exitting.' ) raise Error() # Else if kwargs contains 'project', 'componentType', and 'type', we are dealing with a non-existent (?) component to be registered elif set(kwargs) == set(['project', 'componentType', 'type']): # Initialize self.component and fill in our component type info self.component = None self.project = kwargs['project'].upper() self.componentType = kwargs['componentType'].upper() self.type = kwargs['type'].upper() # Do arg checking on self.project to see if matches the allowed types if self.project not in ['S', 'P', 'CE', 'CM']: if not self.expert: ERROR('Invalid project code: {0}'.format(self.project)) ERROR( 'Keyword arg \'project\' must be one of \'S\', \'P\', \'CE\', or \'CM\' -- exitting.' ) raise Error() # Else we don't have any of the required args to construct a Component object -- exit the code else: if not self.expert: ERROR( 'Unknown keyword args (excluding \'get_immediately\' and \'expert\'): {0}' .format(kwargs)) ERROR( 'Component class constructor must only include kwargs \'component\' OR (\'project\' AND \'componentType\' AND \'type\') -- exitting.' ) raise Error() # Get the component's json immediately (as well as its type dictionary), assuming component != None if get_immediately and self.component != None: self.get() self.project = self.json['project']['code'] self.componentType = self.json['componentType']['code'] self.type = self.json['type']['code'] # Else, initialize json to None else: self.json = None
self.ITkPDSession.doSomething(action='setComponentStage', method='POST', data=kwargs) if __name__ == '__main__': try: from itk_pdb.dbAccess import ITkPDSession from requests.exceptions import RequestException # Instantiate our ITkPDSession session = ITkPDSession() # Open registration interface and run it interface = RegistrationInferface(session) interface.openInterface() # In the case of a keyboard interrupt, quit with error except KeyboardInterrupt: print('') ERROR('Exectution terminated.') STATUS('Finished with error.', False) sys.exit(1) except RequestException as e: ERROR('Request exception raised: %s' % e) STATUS('Finished with error.', False) sys.exit(1)
def main(args): try: # Use the global definition of input global input print('') print( '******************************************************************************' ) print( '* {0}{1}uploadITSDAQTests.py{2} *' .format(Colours.WHITE, Colours.BOLD, Colours.ENDC)) print( '******************************************************************************' ) print('') (sctvar_folder_path, get_confirm, upload_files, ps_folder_path, config_folder_path, recursion_depth) = (args.sctvar_folder_path, args.get_confirm, args.upload_files, args.ps_folder_path, args.config_folder_path, args.recursion_depth) INFO('Launching ITkPDSession.') session = ITkPDSession() session.authenticate() results_folder = ResultsFolder(sctvar_folder_path, ps_folder_path, config_folder_path) INFO('Looking in: ' + str(results_folder)) results_folder.getFiles(depth=recursion_depth) if results_folder.files == []: WARNING('No files found!') else: INFO('The following files were found:\n') results_folder.printSummaryOfFiles() print('') indices = getIndices(len(results_folder)) results_folder.filterFiles(indices) for results_file in results_folder: full_test = False INFO('Looking in: ' + str(results_file)) results_file.getTests() if results_file.tests == []: WARNING('No tests found -- skipping.') else: INFO('The following tests were found:') try: print('') results_file.printSummaryOfTests() except KeyError: print('') ERROR( 'KeyError encountered during ResultsFile.printSummaryOfTests() -- printing Traceback:\n' ) print(traceback.format_exc()) WARNING('Error encountered in file -- skipping.') continue print('') if results_file.full_test['state'] == True: lower_index = results_file.full_test['lower_index'] upper_index = results_file.full_test['upper_index'] INFO( 'Indices %s through %s appear to be part of a FullTest, would you like to only upload those results?' % (lower_index, upper_index)) INFO( 'Only the following files will be uploaded: <config>.det, <trim file>.trim, <mask file>.mask, and <post-trim response curve>.pdf.' ) if getYesOrNo( 'Please enter \'y\' to confirm the FullTest or \'n\' to only upload specific results:' ): INFO('Only uploading results from the FullTest.') indices = list(range(lower_index, upper_index + 1)) full_test = True else: indices = getIndices(len(results_file)) else: indices = getIndices(len(results_file)) for i in indices: try: results_file.finalizeTest( test_number=i, ITkPDSession=session, upload_files=upload_files, ResultsFolder=results_folder, depth=recursion_depth, full_test=full_test) if get_confirm: INFO('Printing JSON for run number \'' + results_file[i]['JSON']['runNumber'] + '\':\n') results_file.printJSON(i) print('') if upload_files: files_to_upload = results_file[i][ 'files_to_upload'] if files_to_upload == {}: pass else: INFO( 'The following files will also be uploaded to component code \'' + results_file[i]['JSON'] ['component'] + '\':\n') files_to_upload = results_file[i][ 'files_to_upload'] for filetype in files_to_upload.keys(): if files_to_upload[ filetype] == None: print( ' {0} = {1}{2}Not found!{3}' .format( filetype, Colours.BOLD, Colours.WHITE, Colours.ENDC)) else: print( ' ' + filetype + ' = ' + files_to_upload[filetype]) print('') confirm_upload, upload_these_files = getYesNoOrJson( 'Please enter \'y\' to confirm the upload, \'n\' to cancel, or \'j\' to upload only the JSON:' ) if not confirm_upload: INFO(Colours.BOLD + Colours.RED + 'Cancelled' + Colours.ENDC + ' upload of run number \'' + results_file[i]['JSON'] ['runNumber'] + '\'.') continue else: upload_these_files = False if not getYesOrNo( 'Please enter \'y\' to confirm the upload or \'n\' to cancel:' ): INFO(Colours.BOLD + Colours.RED + 'Cancelled' + Colours.ENDC + ' upload of run number \'' + results_file[i]['JSON'] ['runNumber'] + '\'.') continue results_file.uploadJSON(i, session) if upload_these_files: results_file.uploadFiles( i, session, upload_files) except ComponentNotFound: continue STATUS('Finished successfully.', True) sys.exit(0) except KeyboardInterrupt: print('') ERROR('Exectution terminated.') STATUS('Finished with error.', False) sys.exit(1)
# Ask the user if they want to get info for another component INFO('Session finished.') if self.__getYesOrNo( 'Please type \'y/Y\' to get the summary for another component or type \'n/N\' to quit:' ): continue # Else quit else: self.__quit() if __name__ == '__main__': try: # Check if the ITk auth token exists as an environmental variable checkITkDBAuth() # Open summary interface and run it interface = ContentSummaryInferface() interface.openInterface() # In the case of a keyboard interrupt, quit with error except KeyboardInterrupt: print('') ERROR('Exectution terminated.') STATUS('Finished with error.', False) sys.exit(1)