def read_config(config_file): """Read the given config file and return the parsed settings and channels""" config = configparser.ConfigParser() config.optionxform = str # preserve case of the options config.read(config_file.name) settings = list(config.items('settings')) settings = Settings(settings) if not config.has_section('channels'): print_color('[WARNING] No channels specified in %s' % config_file.name, 'YELLOW') return settings, [] lines = [line.rstrip('\n') for line in config_file.readlines() if not line.startswith('#') and line.split()] # last part excludes empty lines channels = lines[lines.index('[channels]')+1:] if not channels: print_color('[WARNING] No channels specified in %s' % config_file.name, 'YELLOW') return settings, [] delimiter = ' ' pattern = re.compile(r'''((?:[^%s"']|"[^"]*"|'[^']*')+)''' % delimiter) # split using delimiter outside of quotations [http://stackoverflow.com/a/2787064] chnl = [] for channel in channels: option = pattern.split(channel.lstrip(';'))[1::2] if len(option) != 3: print_error('[ERROR] Wrong number of arguments for channel %s' % option[0]) print(' This channel will be skipped') continue if option[1] is '0' or option[2] is '0': #print('Skip channel', format_channel(option[0], False)) print('Skip channel', option[0]) continue if not option[1].isdigit() or not option[2].isdigit(): print_error('[ERROR] The amount of files and events to simulate have to be integers!') print(' Check your settings for channel %s' % option[0]) continue chnl.append((option[0], int(option[1]), int(option[2]))) return settings, chnl
def search(keyword, repeat, style): global htmlParsedPage query = keyword if len(query): color.print_line('---'*45) color.print_heading('*\t'*4+"The Free Online Dictionary, Thesaurus and Encyclopedia\t" +'\t'+'*\t'*5) color.print_line('---'*45) color.print_word(query.upper()+'\n') try: htmlParsedPage = get_parsed_page(keyword) #parse to find the meaning soupPage = BeautifulSoup(htmlParsedPage) div = soupPage.findAll('div', attrs = {'id': 'MainTxt'}) meaning = div[0].findAll('div', attrs = {'class':'ds-list'}) if meaning == "": meaning = div[0].findAll('div', attrs = {'class' : 'ds-single'}) for i in range(len(meaning)): color.print_meaning('\t'+parser.strip_tags(str(meaning[i]))+'\n') except: color.print_error('Keyword not found in the Dictionary') color.print_line('---'*45) color.print_heading('\t'*6+'*****@*****.**') color.print_line('---'*45) speak(keyword, repeat, style) else: color.print_error('Empty Keyword!')
def check_file(path, verbose=False): """Check if a file exists""" path = os.path.expanduser(path) if not os.path.isfile(path): if verbose: print_error("[ERROR] The file '%s' does not exist!" % path) return None else: return path
def do_mv(self, full_src, full_dst): os.makedirs(os.path.dirname(full_dst), exist_ok=True) if os.path.basename(full_src) == os.path.basename(self.log_path): print_warning('found {0}, skip it'.format(full_src)) try: shutil.move(full_src, full_dst) except shutil.Error as ex: print_error(ex) print_error('skip')
def hello(str_info): """ str_info: string """ color.print_error("this is an error message!") color.print_warning("this is a warning message!") color.print_info("this ia a info message!") color.print_log('this is a log message!') color.print_debug('this is a debug message!') print str_info
def check_bin(path, file): """Check if a binary exists and is executable""" path = get_path(path, file) if not os.path.exists(path): print_error('[ERROR] The file "%s" does not exist!' % path) return False if not is_executable(path): print_error('[ERROR] The file "%s" is not executable!' % path) return False return path
def get_decay_string(channel, level=1): """Get a decay string for a certain channel, print error if proton is missing""" channel = channel.strip('"') if channel.startswith('p '): channel = channel[2:] else: print_error('[ERROR] proton missing in decay string: %s' % channel) channel = parse_pluto_string.get_decay_string(channel, level) return channel
def sanity_check_mcgun(settings): """Check if the given settings for Ant-mcgun seem okay""" theta_min, theta_max = settings.get('GUN_THETA').split() try: theta_min = float(theta_min) except ValueError: print_error('[ERROR] theta_min is not a float value!') return False try: theta_max = float(theta_max) except ValueError: print_error('[ERROR] theta_max is not a float value!') return False if theta_min > theta_max: print_error('[ERROR] theta_max is smaller than theta_min') return False if settings.get('GUN_OPENING'): try: float(settings.get('GUN_OPENING')) except ValueError: print_error('[ERROR] provided opening angle is not a float value!') return False return True
def check_path(path, create=False, write=True): """Check if given path exists and is readable as well as writable if specified; if create is true and the path doesn't exist, the directories will be created if possible""" path = os.path.expanduser(path) exist = os.path.isdir(path) if not exist and create: print("Directory '%s' does not exist, it will be created now" % path) # try to create the directory; if it should exist for whatever reason, # ignore it, otherwise report the error try: os.makedirs(path) except OSError as exception: if exception.errno == errno.EACCES: print_error("[ERROR] You don't have the permission to create directories in '%s'" % dirname(path)) return False elif exception.errno != errno.EEXIST: raise return True elif not exist: print_error("[ERROR] Directory '%s' does not exist" % path) return False else: if not is_readable(path): print_error("[ERROR] Directory '%s' is not readable" % path) return False if write and not is_writable(path): print_error("[ERROR] Directory '%s' is not writable" % path) return False return True
def __init__(self, settings=None): self.__settings = { 'OUTPUT_PATH': '.', 'MCGEN_DATA': 'mcgen', 'GEANT_DATA': 'geant', 'MCGEN_PREFIX': 'mcgen', 'GEANT_PREFIX': 'g4sim', 'LOG_DATA': 'log', 'A2_GEANT_PATH': '', 'MCGEN_ONLY': False, 'GEANT_ONLY': False, 'QSUB_BIN': 'qsub', 'QSUB_MAIL': 'a', 'QSUB_EXTRA': '', 'QUEUE': 'dflt', 'WALLTIME': '12:00:00', 'PRIORITY': 0, 'GENERATOR': 'Ant-pluto', 'GENERATOR_PATH': '', 'Emin': 1420, 'Emax': 1580, 'COCKTAIL_SETUP': '', 'COCKTAIL_BINNING': 0, 'GUN_THETA': '0 180', 'GUN_OPENING': '', 'GeantFlags': '', 'AddFlags': '', } if settings and len(settings[0]) == 2: for setting in settings: if setting[0] not in self.__settings: print_error('[ERROR] Setting "%s" not valid! Will be skipped.' % setting[0]) continue if not setting[1] and self.__settings[setting[0]]: print_color('[INFO] No value given for "{0}". Default value "{1}" will ' 'be used'.format(setting[0], self.__settings[setting[0]]), 'BLUE') continue if setting[0] in ('PRIORITY', 'COCKTAIL_BINNING'): if not setting[1].isdigit(): print_error('[ERROR] The given value for "%s" is not an integer, use ' 'default value %d instead.' % (setting[1], self.__settings[setting[1]])) continue self.__settings[setting[0]] = int(setting[1]) continue if setting[0] in ('Emin', 'Emax'): if not isfloat(setting[1]): print_error('[ERROR] The given energy "%s" is not a float! Use default ' 'value %.1f instead.' % (setting[1], self.__settings[setting[0]])) continue self.__settings[setting[0]] = float(setting[1]) continue self.__settings[setting[0]] = setting[1] elif settings and len(settings[0]) != 2: print_error('[ERROR] Given settings in the wrong format, ' 'list with tuples (setting, value) expected.')
def test_process(cmd, time=None): """Try to run a process and check its return code if something went wrong, print command output if time is given, kill process after time expired""" # use shell=True, otherwise the command passed to Popen to execute, # including cmd.split(' ', 1), produces errors (probably due to reaction string) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Python 3.3 needed for timeout, most recent version on blaster is 3.1 # if time: # if time < 0: # print_error('given time is negative!') # return False # try: # outs, errs = proc.communicate(timeout=time) # if proc.returncode: # print_error('non-zero returncode for command: %s' % cmd) # print_color('error output:', 'YELLOW') # print(errs.decode('utf-8')) # print_color('standard output:', 'YELLOW') # print(outs.decode('utf-8')) # return False # else: # return True # except TimeoutExpired: # proc.kill() # outs, errs = proc.communicate() # print_error('[ERROR] given timeout expired, process killed') # print_color('error output:', 'YELLOW') # print(errs.decode('utf-8')) # print_color('standard output:', 'YELLOW') # print(outs.decode('utf-8')) # return False outs, errs = proc.communicate() if proc.returncode: print_error('[ERROR] non-zero returncode for command: %s' % cmd) print_color('error output:', 'YELLOW') print(errs.decode('utf-8')) print_color('standard output:', 'YELLOW') print(outs.decode('utf-8')) return False return True
def find_config(config_places=CONFIG, verbose=False): """Checks given locations for a sim_settings config file, return path of the config if found or None otherwise""" if isinstance(config_places, str): config_places = [config_places] elif not isinstance(config_places, list): if verbose: print_error('[ERROR] Expected argument to be a list or string!') return None config = None for conf in config_places: if verbose: print('Checking config file %s' % conf) config = check_file(conf, verbose) if config: if verbose: print('File found: %s' % config) break return config
def _do(self, do_type): """ :param do_type: [undo | redo] :return: """ all_do_types = ['undo', 'redo'] all_do_types.remove(do_type) other_do_type = all_do_types[0] actions = [] first_action_id = None for action in reversed(self.log_dict[do_type]): if first_action_id is None: first_action_id = action['batch_id'] elif first_action_id != action['batch_id']: break actions.append(action) for action in actions.copy(): print_bold('try %s action: %s ' % (do_type, action['action']), end='') for key, value in action['kwargs'].items(): print_bold('{0}: {1}'.format(key, value), end='') print_bold() reverse_action_func = getattr( self, '%s_%s' % (do_type, action['action'])) try: reverse_action_func(**action['kwargs']) except Exception as ex: print_error(ex) print_warning('skipping it') self.log_dict['skip'].append(action) actions.remove(action) else: print_ok('success') self.log_dict[other_do_type].extend(actions) self.log_dict[do_type] = self.log_dict[do_type][:-len(actions)] self.write_log_back()
def sanity_check_channels(generator, channels): """check if the provided channel string match the specified generator""" if 'Ant-cocktail' in generator: wrong = [c[0] for c in channels if not c[0].lower().startswith('"cocktail"')] if wrong: print_error("[ERROR] The following channels don't match the requirements for Ant-cocktail") print(*wrong, sep='\n') print('The correct syntax is: "Cocktail" <#files> <#events>') return False if 'Ant-mcgun' in generator: wrong = [c[0] for c in channels if not c[0].lower().startswith('"gun:')] if wrong: print_error("[ERROR] The following channels don't match the requirements for Ant-mcgun") print(*wrong, sep='\n') print('The correct syntax is: "Gun: <space-separated particles>" <#files> <#events>') return False # for Ant-pluto case just check that no definitions for Cocktail and Gun are present if 'Ant-pluto' in generator: wrong = [c[0] for c in channels if (c[0].lower().startswith('"gun') or c[0].lower().startswith('"cocktail'))] if wrong: print_error("[ERROR] The following channels don't match the requirements for Ant-pluto") print(*wrong, sep='\n') print('The correct syntax is: "Pluto string" <#files> <#events>') return False return True
def do_flatten_dir(self): for filepath in flatten(self._find_regular_files()): dirname, filename = os.path.split(filepath) print_normal('extract {0} from {1}'.format(filename, dirname)) given_error = False for fn, fullpath_iter in self.fn_path_map.items(): if len(fullpath_iter) > 1: if not given_error: given_error = True print_error('There are same name file conflicts:') print_italic(fn, ':') for filepath in fullpath_iter: print_error(filepath) if fn in self.top_dir_not_dir_fns: print_error(os.path.join(self.dst, fn)) if given_error: return for empty_dir in list_dirs_of_dir(self.dst): print_normal('remove directory %s' % empty_dir) if not askyesno('continue?'): return with Op('flattendir', self.dst) as op: for fn, fullpath_iter in self.fn_path_map.items(): fullpath = fullpath_iter[0] op.mv(fullpath, '.')
def speak(keyword, repeat, style): global htmlParsedPage, browser pronouce_style = ['normal', 'us', 'uk', ''] if repeat > 0 and len(keyword) and any(style in item for item in pronouce_style): if htmlParsedPage == '': htmlParsedPage = get_parsed_page(keyword) soupPage = BeautifulSoup(htmlParsedPage) htmlParsedPage = '' div = soupPage.findAll('div', attrs={'id': 'MainTxt'}) try: if style.lower() == 'normal' or style.lower() == '': mean_sound = str( parser.strip_tags(str( div[0].findAll('script')[0]))).split('"')[1] sound_url = 'http://img.tfd.com/hm/mp3/' + mean_sound + '.mp3' elif style.lower() == 'uk': sample = soupPage.findAll('td', attrs={'id': 'MainTitle'}) mean_sound = str( parser.strip_tags(str(sample[0])).split("'")[3]) sound_url = 'http://img2.tfd.com/pron/mp3/' + mean_sound + '.mp3' elif style.lower() == 'us': sample = soupPage.findAll('td', attrs={'id': 'MainTitle'}) mean_sound = str( parser.strip_tags(str(sample[0])).split("'")[1]) sound_url = 'http://img2.tfd.com/pron/mp3/' + mean_sound + '.mp3' sound_path = browser.retrieve(sound_url) pronounce.play(sound_path[0], repeat) except: color.print_error( 'Pronouciation not found!\nTry with different style.') elif repeat: color.print_error('Empty Keyword or Unknown Style!')
def run_test_job(settings, simulation, generator, geant): """Run a job with one event locally and check if it works""" first_job = next(iter(simulation or []), None) if not first_job: print_error('[ERROR] Unable to retrieve information of first job to be submitted') return False decay_string, reaction, _, _, _ = first_job with tempdir() as tmp_path: mcgen_file = get_path(tmp_path, get_file_name(MCGEN_PREFIX, decay_string, 0)) geant_file = get_path(tmp_path, get_file_name(GEANT_PREFIX, decay_string, 0)) mcgen_cmd = create_mcgen_cmd(settings, generator, reaction, mcgen_file) geant_cmd = '%s %s %s' % (geant, mcgen_file, geant_file) if not test_process(mcgen_cmd): return False if not test_process(geant_cmd): return False return True
def search(keyword, repeat, style): global htmlParsedPage query = keyword if len(query): color.print_line('---' * 45) color.print_heading( '*\t' * 4 + "The Free Online Dictionary, Thesaurus and Encyclopedia\t" + '\t' + '*\t' * 5) color.print_line('---' * 45) color.print_word(query.upper() + '\n') try: htmlParsedPage = get_parsed_page(keyword) #parse to find the meaning soupPage = BeautifulSoup(htmlParsedPage) div = soupPage.findAll('div', attrs={'id': 'MainTxt'}) meaning = div[0].findAll('div', attrs={'class': 'ds-list'}) if meaning == "": meaning = div[0].findAll('div', attrs={'class': 'ds-single'}) for i in range(len(meaning)): color.print_meaning('\t' + parser.strip_tags(str(meaning[i])) + '\n') except: color.print_error('Keyword not found in the Dictionary') color.print_line('---' * 45) color.print_heading('\t' * 6 + '*****@*****.**') color.print_line('---' * 45) speak(keyword, repeat, style) else: color.print_error('Empty Keyword!')
def speak(keyword, repeat, style): global htmlParsedPage, browser pronouce_style = ['normal', 'us', 'uk', ''] if repeat >0 and len(keyword) and any(style in item for item in pronouce_style): if htmlParsedPage == '': htmlParsedPage = get_parsed_page(keyword) soupPage = BeautifulSoup(htmlParsedPage) htmlParsedPage = '' div = soupPage.findAll('div', attrs = {'id': 'MainTxt'}) try: if style.lower() == 'normal' or style.lower() == '': mean_sound = str(parser.strip_tags(str(div[0].findAll('script')[0]))).split('"')[1] sound_url = 'http://img.tfd.com/hm/mp3/' + mean_sound +'.mp3' elif style.lower() == 'uk': sample = soupPage.findAll('td', attrs = {'id': 'MainTitle'}) mean_sound = str(parser.strip_tags(str(sample[0])).split("'")[3]) sound_url = 'http://img2.tfd.com/pron/mp3/' + mean_sound + '.mp3' elif style.lower() == 'us': sample = soupPage.findAll('td', attrs = {'id': 'MainTitle'}) mean_sound = str(parser.strip_tags(str(sample[0])).split("'")[1]) sound_url = 'http://img2.tfd.com/pron/mp3/' + mean_sound + '.mp3' sound_path = browser.retrieve(sound_url) pronounce.play(sound_path[0], repeat) except: color.print_error('Pronouciation not found!\nTry with different style.') elif repeat: color.print_error('Empty Keyword or Unknown Style!')
def sanity_check_cocktail(settings): """Check if the given settings for Ant-cocktail seem okay""" setup = settings.get('COCKTAIL_SETUP') binning = int(settings.get('COCKTAIL_BINNING')) if setup and not setup.startswith('Setup_'): print_color("[WARNING] The specified detector setup doesn't start with 'Setup_'", 'YELLOW') if not setup and not binning: print_error('[ERROR] No Setup and no binning for the beam energy specified!') print_error(' Please make sure to provide one option') return False if setup and binning: print_error('[ERROR] You provided both a setup and energy binning for the Cocktail') print_error(' Please make sure to provide only one of these options') return False return True
def __init__(self, settings=None): self.__settings = { 'OUTPUT_PATH': '.', 'PLUTO_DATA': 'pluto', 'GEANT_DATA': 'geant', 'LOG_DATA': 'log', 'A2_GEANT_PATH': '/home/neiser/opt/a2geant', 'QSUB_BIN': 'qsub', 'QSUB_MAIL': 'a', 'QUEUE': 'dflt', 'WALLTIME': '12:00:00', 'PRIORITY': 0, 'Emin': 1420, 'Emax': 1580 } if settings and len(settings[0]) == 2: for setting in settings: if setting[0] not in self.__settings: print_error('[ERROR] Setting "%s" not valid! Will be skipped.' % setting[0]) continue if not setting[1]: print_color('[INFO] No value given for "{0}". Default value "{1}" will ' 'be used'.format(setting[0], self.__settings[setting[0]]), 'BLUE') continue if setting[0] == 'PRIORITY': if not setting[1].isdigit(): print_error('[ERROR] The given priority is not an integer, use ' 'default value %d instead.' % self.__settings[setting[1]]) continue self.__settings[setting[0]] = int(setting[1]) continue if setting[0] in ('Emin', 'Emax'): if not isfloat(setting[1]): print_error('[ERROR] The given energy "%s" is not a float! Use default ' 'value %.1f instead.' % (setting[1], self.__settings[setting[0]])) continue self.__settings[setting[0]] = float(setting[1]) continue self.__settings[setting[0]] = setting[1] elif settings and len(settings[0]) != 2: print_error('[ERROR] Given settings in the wrong format, ' 'list with tuples (setting, value) expected.')
def list_file_amount(settings, events=False): """List the simulated amount of files per channel; if events is True and PyROOT can be used, the total amount of events will be determined, too""" pluto_data = get_path(settings.get('OUTPUT_PATH'), settings.get('PLUTO_DATA')) geant_data = get_path(settings.get('OUTPUT_PATH'), settings.get('GEANT_DATA')) if not os.path.exists(pluto_data): sys.exit('Pluto path %s not found' % pluto_data) if not os.path.exists(geant_data): sys.exit('Geant path %s not found' % geant_data) pluto_files = [f for f in os.listdir(pluto_data) if f.startswith(PLUTO_PREFIX)] geant_files = [f for f in os.listdir(geant_data) if f.startswith(GEANT_PREFIX)] channels = [] decay = re.compile(r'^%s_(\S+)_\d+\.root$' % PLUTO_PREFIX) for name in pluto_files: channel = decay.search(name).group(1) if decay.search(name) else '' if channel and channel not in channels: channels.append(channel) print('Amount of simulated %s per channel:' % ('events' if events else 'files')) for channel in channels: pluto_channel = [f for f in pluto_files if channel in f] geant_channel = [f for f in geant_files if channel in f] max_pluto = max_file_number(pluto_channel) max_geant = max_file_number(geant_channel) maximum = max(max_pluto, max_geant) if maximum > 0: if not events: print(' {0:<20s} -- {1:>4d} files'.format(format_channel(channel), maximum)) else: try: from ROOT import TFile, TTree except ImportError: print_error('[ERROR] PyROOT is not available, the total amount of ' 'simulated events cannot be determined.') return sum = 0 #from ROOT import TFile, TTree, TH1 for name in pluto_channel: filename = get_path(pluto_data, name) current = TFile(filename) if not current.IsOpen(): print_error("The file '%s' could not be opened" % filename) continue elif not current.GetListOfKeys().GetSize(): print_error("Found no directory in file '%s'" % current.GetName()) continue name = current.GetListOfKeys().First().GetName() tree = current.Get(name) sum += tree.GetEntriesFast() print(' {0:<20s} -- {1:>4d} files, total {2:>8s} events'.format(format_channel(channel), maximum, unit_prefix(sum)))
def check_file(path, file): """Check if a file in a certain path exists and is readable; if the file argument is omitted only path is checked, it's recommended to use check_path instead for this case""" path = os.path.expanduser(path) if file is None: if not os.path.isfile(path): print_error("[ERROR] The file '%s' does not exist!" % (path)) return False else: if not is_readable(path): print_error("[ERROR] The file '%s' is not readable!" % (path)) return False return True path = get_path(path, file) if not os.path.isfile(path): print_error("[ERROR] The file '%s' does not exist!" % path) return False else: if not is_readable(path): print_error("[ERROR] The file '%s' is not readable!" % (path)) return False return True
def main(): """Main function: process all information, prepare simulation process, submit jobs""" parser = argparse.ArgumentParser(description='Submit simulations on blaster, configuration ' 'is done via a config file "sim_settings" in ~ or . ' 'and/or a list of command line arguments') parser.add_argument('-c', '--config', nargs=1, metavar='config_file', dest='config',# required=True, type=lambda x: is_valid_file(parser, x), help='Optional: Specify a custom config file') parser.add_argument('-o', '--output', nargs=1, metavar='output_directory', type=lambda x: is_valid_dir(parser, x), help='Optional: Custom output directory') parser.add_argument('-a', '--ant-pluto', nargs=1, type=str, metavar='Ant-pluto binary path', help='Optional: If the Ant-pluto binary can\'t be found in your' '$PATH variable, use this option to specify the path manually') parser.add_argument('-l', '--list', nargs='?', const=True, help='List the amount of existing files per channel' 'in the output directory and exit; if "all" is specified' 'as an optional argument the amount of events will be listed') parser.add_argument('-e', '--example-config', nargs='?', const='example_settings', help='Export an example of default settings and exit. ' 'If no file is specified, the output will be written to "example_settings"') parser.add_argument('-w', '--walltime', type=int, nargs=1, metavar='walltime', help='Walltime for jobs, time in hours') parser.add_argument('-q', '--queue', type=str, nargs=1, metavar='queue', help='Queue which should be used for the jobs') parser.add_argument('-f', '--force', action='store_true', help='Force creation of directories if they do not exist' 'or overwrite existing files') parser.add_argument('-v', '--verbose', action='store_true', help='Print additional output') args = parser.parse_args() verbose = args.verbose force = args.force settings = None if args.example_config: print_color('[INFO] Write example settings to file "%s"' % args.example_config, 'BLUE') settings = Settings() if not settings.export(args.example_config, force): print_error('[ERROR] Creating example settings "%s" failed.' % args.example_config) sys.exit(0) config = None channels = [] if args.config: config = args.config[0] if verbose: print('Use config file %s' % config) else: if verbose: print('Try to find a default config file') config = find_config(verbose=verbose) if not config: print_color('No config file found, use default values.', 'YELLOW') settings = Settings() if config: print_color('The config file "%s" will be used.' % config, 'BLUE') if verbose: print('Read config file %s' % config) with open(config, 'r') as conf: settings, channels = read_config(conf) if args.list: if verbose and args.list == 'all': print('Trying to determine the total amount of simulated events') if args.output: settings.set('OUTPUT_PATH', get_path(args.output[0])) list_file_amount(settings, args.list == 'all') sys.exit(0) if verbose: print('The following settings will be used:') settings.print() if channels: print('The following channels have been found:') print(channels) if args.output: if not check_path(args.output[0], force): sys.exit('The output directory %s cannot be used' % args.output[0]) output = get_path(args.output[0]) print_color('Setting custom output directory: %s' % output, 'GREEN') settings.set('OUTPUT_PATH', output) ant_pluto = '' if args.ant_pluto: ant_pluto = args.ant_pluto[0] print_color('Use custom Ant-pluto path %s' % ant_pluto, 'GREEN') if not check_directories(settings, ant_pluto, force, verbose): sys.exit(1) pluto, tid, geant = check_binaries(settings, ant_pluto, verbose) if not pluto or not tid or not geant: sys.exit(1) if not channels: print_color('[Warning] No channels specified in the config file', 'YELLOW') channels = simulation_dialogue() if not channels: sys.exit('No channels entered for simulation, exiting.') if args.walltime: print_color('Setting custom walltime to %d hours' % args.walltime[0], 'GREEN') settings.set('WALLTIME', args.walltime[0]) if args.queue: print_color('Setting custom queue to %s' % args.queue[0], 'GREEN') settings.set('QUEUE', args.queue[0]) if verbose: print('This are the updated settings:') settings.print() if verbose: print('Determining the existing amount of files...') simulation = [] for channel in channels: decay_string = get_decay_string(channel[0]) max_number = check_simulation_files(settings, decay_string) simulation.append([decay_string, channel[0], channel[1], channel[2], max_number]) print_color(str(len(simulation)) + ' channels configured. ' 'The following simulation will take place:', 'BLUE') total_files, total_events = 0, 0 for channel, _, files, events, _ in simulation: total = files*events print("{0:<20s} {1:>4d} files per {2:>4s} events (total {3:>4s} events)" .format(format_channel(channel), files, unit_prefix(events), unit_prefix(total))) total_files += files total_events += total print(" Total %s events in %d files" % (unit_prefix(total_events), total_files)) print(" Files will be stored in " + settings.get('OUTPUT_PATH')) # start the job submission print('Start submitting jobs, total', total_files) submit_jobs(settings, simulation, pluto, tid, geant, total_files) print_color('Done!', 'GREEN')
def list_file_amount(settings, events=False): """List the simulated amount of files per channel; if events is True and PyROOT can be used, the total amount of events will be determined, too""" mcgen_data = settings.get('MCGEN_DATA') geant_data = settings.get('GEANT_DATA') if not os.path.exists(mcgen_data): sys.exit('MC generated data path %s not found' % mcgen_data) if not os.path.exists(geant_data): sys.exit('Geant path %s not found' % geant_data) mcgen_files = [f for f in os.listdir(mcgen_data) if f.startswith(MCGEN_PREFIX)] geant_files = [f for f in os.listdir(geant_data) if f.startswith(GEANT_PREFIX)] # try to determine amount of Cocktail and Particle gun files cocktail_files = [f for f in mcgen_files if 'cocktail' in f.lower()] if cocktail_files: print('Cocktail: %d files' % len(cocktail_files)) gun_files = [f for f in mcgen_files if 'gun' in f.lower()] if gun_files: print('Particle gun: %d files' % len(gun_files)) # check if Pluto files are left pluto_files = set(mcgen_files) - set(cocktail_files) - set(gun_files) if not pluto_files: return # if Pluto files left, gather channels and determine the amount per channel channels = [] decay = re.compile(r'^%s_(\S+)_\d+\.root$' % MCGEN_PREFIX) for name in pluto_files: channel = decay.search(name).group(1) if decay.search(name) else '' if channel and channel not in channels: channels.append(channel) print('Amount of simulated %s per channel:' % ('events' if events else 'files')) for channel in channels: pluto_channel = [f for f in pluto_files if channel in f] geant_channel = [f for f in geant_files if channel in f] max_pluto = max_file_number(pluto_channel) max_geant = max_file_number(geant_channel) maximum = max(max_pluto, max_geant) if maximum > 0: if not events: print(' {0:<20s} -- {1:>4d} files'.format(format_channel(channel), maximum)) else: try: from ROOT import TFile, TTree except ImportError: print_error('[ERROR] PyROOT is not available, the total amount of ' 'simulated events cannot be determined.') return sum_events = 0 #from ROOT import TFile, TTree, TH1 for name in pluto_channel: filename = get_path(mcgen_data, name) current = TFile(filename) if not current.IsOpen(): print_error("The file '%s' could not be opened" % filename) continue elif not current.GetListOfKeys().GetSize(): print_error("Found no directory in file '%s'" % current.GetName()) continue name = current.GetListOfKeys().First().GetName() tree = current.Get(name) sum_events += tree.GetEntriesFast() print(' {0:<20s} -- {1:>4d} files, total {2:>8s} events'.format(format_channel(channel), maximum, unit_prefix(sum_events)))
def check_binaries(settings, ant_pluto='', verbose=False): """Check if the needed binaries exist, return the absolute paths to them""" pluto, tid, geant = None, None, None # first of all check if the specified qsub binary exists if not find_executable(settings.get('QSUB_BIN')): print_error('[ERROR] The binary %s could not be found!' % settings.get('QSUB_BIN')) sys.exit(1) if ant_pluto: if verbose: print('Searching for Ant-pluto and Ant-addTID in %s' % ant_pluto) pluto = check_bin(ant_pluto, 'Ant-pluto') if pluto and verbose: print('Found Ant-pluto') tid = check_bin(ant_pluto, 'Ant-addTID') if tid and verbose: print('Found Ant-addTID') if not pluto: print_error('[ERROR] Ant-pluto not found in %s!' % ant_pluto) sys.exit(1) if not tid: print_error('[ERROR] Ant-addTID not found in %s!' % ant_pluto) sys.exit(1) else: pluto = find_executable('Ant-pluto') if not pluto: print_error('[ERROR] Ant-pluto not found!') if verbose: print("Ant-pluto couldn't be found within your $PATH variable") sys.exit(1) tid = find_executable('Ant-addTID') if not tid: print_error('[ERROR] Ant-addTID not found!') if verbose: print("Ant-addTID couldn't be found within your $PATH variable") sys.exit(1) else: pluto = abspath(pluto) tid = abspath(tid) if verbose: print('Ant-pluto found:', pluto) print('Ant-addTID found:', tid) geant_path = settings.get('A2_GEANT_PATH') if verbose: print('Searching for the A2 binary in %s' % geant_path) if not check_bin(geant_path, 'A2'): print_error('[ERROR] A2 Geant executable not found!') sys.exit(1) elif verbose: print('A2 executable found in %s' % geant_path) geant = check_bin(geant_path, 'runGeant.sh') if not geant: print_error('[ERROR] The runGeant.sh script could not be found or used!') sys.exit(1) # check if Geant version is used which can read in Pluto files (without pluto2mkin converter) if os.path.exists(get_path(geant_path, 'pluto2mkin')): print_error('[ERROR] pluto2mkin converter found in %s' % geant_path) print(" It's highly recommended to use the PlutoGen branch of the a2geant repository.") sys.exit(1) # check target length in A2 Geant4 DetectorSetup.mac geant_macros = get_path(geant_path, 'macros') if not check_file(geant_macros, 'DetectorSetup.mac'): print(" No 'DetectorSetup.mac' macro found in the Geant macros directory.") target_length = '' with open(get_path(geant_macros, 'DetectorSetup.mac'), 'r') as mac: for line in mac: if '/A2/det/setTargetLength' in line: target_length = line.split()[1] if float(target_length) < 10.: print_color("[WARNING] The target length specified in the 'DetectorSetup.mac' macro", 'YELLOW') print_color(' in the Geant macros directory is smaller than the usual lH2 target', 'YELLOW') print_color(' size: %s cm. If you consider to use a smeared z vertex, make sure' % target_length, 'YELLOW') print_color(' the specified target length is correctly set.', 'YELLOW') print() return pluto, tid, geant
def check_binaries(settings, generator_path='', verbose=False): """Check if the needed binaries exist, return the absolute paths to them""" generator, geant = None, None # first of all check if the specified qsub binary exists if not find_executable(settings.get('QSUB_BIN')): print_error('[ERROR] The binary %s could not be found!' % settings.get('QSUB_BIN')) sys.exit(1) generator = settings.get('GENERATOR') generator_path = settings.get('GENERATOR_PATH') if generator_path: if verbose: print('Searching for MC generator in %s' % generator_path) generator = check_bin(generator_path, generator) if generator and verbose: print('Found %s' % settings.get('GENERATOR')) if not generator: print_error('[ERROR] %s not found in %s!' % (settings.get('GENERATOR'), generator_path)) sys.exit(1) else: generator = find_executable(generator) if not generator: print_error('[ERROR] %s not found!' % settings.get('GENERATOR')) if verbose: print("%s couldn't be found within your $PATH variable" % settings.get('GENERATOR')) sys.exit(1) else: generator = abspath(generator) if verbose: print('%s found: %s', (settings.get('GENERATOR'), generator)) geant_path = settings.get('A2_GEANT_PATH') if geant_path: if verbose: print('Searching for the A2 binary in %s' % geant_path) if not check_bin(geant_path, 'A2'): print_error('[ERROR] A2 Geant executable not found!') sys.exit(1) elif verbose: print('A2 executable found in %s' % geant_path) if check_file(geant_path, 'runA2Geant'): geant = check_bin(geant_path, 'runA2Geant') else: geant = check_bin(geant_path, 'runGeant.sh') if not geant: print_error('[ERROR] The runA2Geant or runGeant.sh script could not be found or used!') sys.exit(1) else: geant = find_executable('A2') # fallback solution if not in $PATH if not geant: print_color("[WARNING] The A2 Geant binary couldn't be found within your $PATH variable", 'YELLOW') print(' try to use fallback solution') fallback = '/home/neiser/opt/a2geant/build/bin' if check_file(fallback, 'A2'): geant = check_bin(fallback, 'A2') if not geant: print_error('[ERROR] A2 executable not found!') if verbose: print("The A2 Geant binary couldn't be found neither in your $PATH variable nor in the fallback solution") sys.exit(1) else: if verbose: print('A2 executable found:', geant) geant_path = dirname(abspath(geant)) if check_file(geant_path, 'runA2Geant'): geant = check_bin(geant_path, 'runA2Geant') else: geant = check_bin(geant_path, 'runGeant.sh') if not geant: print_error('[ERROR] The runA2Geant or runGeant.sh script could not be found or used!') sys.exit(1) # check if Geant version is used which can read in Pluto files (without pluto2mkin converter) if os.path.exists(get_path(geant_path, 'pluto2mkin')): print_error('[ERROR] pluto2mkin converter found in %s' % geant_path) print(" It's highly recommended to use the Ant branch of the a2geant repository.") sys.exit(1) # check target length in A2 Geant4 DetectorSetup.mac geant_base = geant_path.replace('/build/bin', '') geant_macros = get_path(geant_base, 'macros') if not check_file(geant_macros, 'DetectorSetup.mac'): print(" No 'DetectorSetup.mac' macro found in the Geant macros directory.") target_length = '' with open(get_path(geant_macros, 'DetectorSetup.mac'), 'r') as mac: for line in mac: if '/A2/det/setTargetLength' in line: target_length = line.split()[1] if float(target_length) < 10.: print_color("[WARNING] The target length specified in the 'DetectorSetup.mac' macro", 'YELLOW') print_color(' in the Geant macros directory is smaller than the usual lH2 target', 'YELLOW') print_color(' size: %s cm. If you consider to use a smeared z vertex, make sure' % target_length, 'YELLOW') print_color(' the specified target length is correctly set.', 'YELLOW') print() return generator, geant
def export(self, file_name, force=False): """Export the current settings to the given file""" file_name = os.path.expanduser(file_name) path = os.path.dirname(file_name) if not path: path = os.getcwd() file_name = os.path.join(path, file_name) if not os.path.exists(path) and not force: print_error('[ERROR] The path "%s" for exporting the settings does not exist!' % path) return False elif not os.path.exists(path): print_color('[INFO] The path "%s" does not exist, it will be created now.' % path, 'BLUE') try: os.makedirs(path) except OSError as exception: if exception.errno == errno.EACCES: print_error('[ERROR] You do not have the permission to create directories in "%s"' % os.path.dirname(path)) return False elif exception.errno != errno.EEXIST: raise if not os.access(path, os.W_OK): print_error('[ERROR] The given path "%s" os not writable!' % path) return False if os.path.isfile(file_name): if not force: print_error('[ERROR] The specified file "%s" already exists, aborting export.' % file_name) return False else: print_color('[INFO] The file "%s" already exists, it will be overwritten.' % file_name, 'BLUE') with open(file_name, 'w') as file: file.write('%s\n' % '[settings]') file.write('%s\n' % '# output path, current directory will be used if missing') file.write('%s = %s\n' % ('OUTPUT_PATH', self.__settings['OUTPUT_PATH'])) file.write('%s\n' % '# directory relative to output path above to store Pluto files') file.write('%s = %s\n' % ('PLUTO_DATA', self.__settings['PLUTO_DATA'])) file.write('%s\n' % '# relative path to output path above ' 'where the Geant4 files should be stored') file.write('%s = %s\n' % ('GEANT_DATA', self.__settings['GEANT_DATA'])) file.write('%s\n' % '# log directory relative to output path above, ' 'log will be used if empty') file.write('%s = %s\n' % ('LOG_DATA', self.__settings['LOG_DATA'])) file.write('%s = %s\n\n' % ('A2_GEANT_PATH', self.__settings['A2_GEANT_PATH'])) file.write('%s\n' % '# some default settings for jobs') file.write('%s = %s\n' % ('QSUB_BIN', self.__settings['QSUB_BIN'])) file.write('%s\n' % '# mail when job aborts (a), begins (b), ends (e), no mails (n)') file.write('%s = %s\n' % ('QSUB_MAIL', self.__settings['QSUB_MAIL'])) file.write('%s = %s\n' % ('QUEUE', self.__settings['QUEUE'])) file.write('%s = %s\n' % ('WALLTIME', self.__settings['WALLTIME'])) file.write('%s = %s\n\n' % ('PRIORITY', self.__settings['PRIORITY'])) file.write('%s\n' % '# simulation specific settings') file.write('%s\n' % '# minimum energy of the photon beam') file.write('%s: %s\n' % ('Emin', self.__settings['Emin'])) file.write('%s\n' % '# maximum energy of the photon beam') file.write('%s: %s\n\n' % ('Emax', self.__settings['Emax'])) file.write('%s\n' % '[channels]') file.write('%s\n' % '# channels which should be simulated, line has to start with ";", ' 'given in the syntax used in Pluto (do not forget the recoil proton!), ' 'the amount of files and the number of events per file') file.write('%s\n' % ';"p pi0 [g g]" 10 100000') return True
color.print_green('green') color.print_dark_skyblue('dark skyblue') color.print_skyblue('skyblue') color.print_yellow('yellow') color.print_purple('purple') color.print_blue('blue') color.print_white('White Char') color.print_dark_gray('dark gray') color.print_normal('normal for normal words') color.print_italic('italic for comment and other like italic font usage') color.print_bold('bold use like bold font') color.print_ok('ok means that exec action succeed') color.print_warning('warning') color.print_warning('print_warning is too long') color.print_error('error') color.print_err('print_error is too long') with color.redirect_red(): print('redirect red') with color.redirect_yellow(): print('redirect yellow') with color.redirect_gray(): print('redirect gray', end='') with color.redirect_gray(): print('', end='\n') try:
print_color(str(len(simulation)) + ' channels configured. ' 'The following simulation will take place:', 'BLUE') total_files, total_events = 0, 0 for channel, _, files, events, _ in simulation: total = files*events print("{0:<20s} {1:>4d} files per {2:>4s} events (total {3:>4s} events)" .format(format_channel(channel), files, unit_prefix(events), unit_prefix(total))) total_files += files total_events += total print(" Total %s events in %d files" % (unit_prefix(total_events), total_files)) print(" Files will be stored in " + settings.get('OUTPUT_PATH')) # start the job submission print('Start submitting jobs, total', total_files) submit_jobs(settings, simulation, pluto, tid, geant, total_files) print_color('Done!', 'GREEN') if __name__ == '__main__': try: main() except KeyboardInterrupt: print('\nCtrl+C detected, will abort simulation process') sys.exit(0) except Exception as e: print_error('An error occured during execution:') print(e) if '-v' or '--verbose' in sys.argv: raise e sys.exit(1)
def main(): """Main function: process all information, prepare simulation process, submit jobs""" parser = argparse.ArgumentParser(description='Submit simulations on blaster, configuration ' 'is done via a config file "sim_settings" in ~ or . ' 'and/or a list of command line arguments') parser.add_argument('-c', '--config', nargs=1, metavar='config_file', dest='config',# required=True, type=lambda x: is_valid_file(parser, x), help='Optional: Specify a custom config file') parser.add_argument('-o', '--output', nargs=1, metavar='output_directory', type=lambda x: is_valid_dir(parser, x), help='Optional: Custom output directory') parser.add_argument('-g', '--generator', nargs=1, type=str, metavar='MC generator binary', help='Optional: If the generator binary is not specified in the config ' 'or should be overwritten, use this option to specify the binary manually') parser.add_argument('-p', '--path-generator', nargs=1, type=str, metavar='MC generator binary path', help='Optional: If the generator binary (e.g. Ant-pluto) can\'t be found ' 'in your $PATH variable, use this option to specify the path manually') parser.add_argument('-l', '--list', nargs='?', const=True, help='List the amount of existing files per channel ' 'in the output directory and exit; if "all" is specified ' 'as an optional argument the amount of events will be listed') parser.add_argument('-e', '--example-config', nargs='?', const='example_settings', help='Export an example of default settings and exit. ' 'If no file is specified, the output will be written to "example_settings"') parser.add_argument('-a', '--add-flags', nargs=1, type=str, metavar='"Additional flags"', help='Optional: Define additional flags which will be passed to the ' 'MC generator. Flags defined in the settings file will be overwritten. ' 'All additional flags must be given as one quoted string!') parser.add_argument('-t', '--tag', nargs=1, type=str, metavar='Job Tag', help='Optional: Specify a job tag, default is Sim') parser.add_argument('-w', '--walltime', type=int, nargs=1, metavar='walltime', help='Walltime for jobs, time in hours') parser.add_argument('-q', '--queue', type=str, nargs=1, metavar='queue', help='Queue which should be used for the jobs') parser.add_argument('-f', '--force', action='store_true', help='Force creation of directories if they do not exist ' 'or overwrite existing files') parser.add_argument('-v', '--verbose', action='store_true', help='Print additional output') args = parser.parse_args() verbose = args.verbose force = args.force settings = None if args.example_config: print_color('[INFO] Write example settings to file "%s"' % args.example_config, 'BLUE') settings = Settings() if not settings.export(args.example_config, force): print_error('[ERROR] Creating example settings "%s" failed.' % args.example_config) sys.exit(0) config = None channels = [] if args.config: config = args.config[0] if verbose: print('Use config file %s' % config) else: if verbose: print('Try to find a default config file') config = find_config(verbose=verbose) if not config: print_color('No config file found, use default values.', 'YELLOW') settings = Settings() if config: print_color('The config file "%s" will be used.' % config, 'BLUE') if verbose: print('Read config file %s' % config) with open(config, 'r') as conf: settings, channels = read_config(conf) if args.list: if verbose and args.list == 'all': print('Trying to determine the total amount of simulated events') if args.output: settings.set('OUTPUT_PATH', get_path(args.output[0])) list_file_amount(settings, args.list == 'all') sys.exit(0) if verbose: print('The following default settings were determined:') settings.print() if channels: print('The following channels have been found:') print(channels) if args.output: if not check_path(args.output[0], force): sys.exit('The output directory %s cannot be used' % args.output[0]) output = get_path(args.output[0]) print_color('Setting custom output directory: %s' % output, 'GREEN') settings.set('OUTPUT_PATH', output) if args.path_generator: path_generator = get_path(args.path_generator[0]) print_color('Setting custom path for MC generator %s' % path_generator, 'GREEN') settings.set('GENERATOR_PATH', path_generator) if not check_directories(settings, force, verbose): sys.exit(1) settings.set('MCGEN_DATA', get_path(settings.get('OUTPUT_PATH'), settings.get('MCGEN_DATA'))) settings.set('GEANT_DATA', get_path(settings.get('OUTPUT_PATH'), settings.get('GEANT_DATA'))) settings.set('LOG_DATA', get_path(settings.get('OUTPUT_PATH'), settings.get('LOG_DATA'))) if args.generator: generator = args.generator[0] print_color('Use custom MC generator %s' % generator, 'GREEN') settings.set('GENERATOR', generator) if args.add_flags: print_color('Set custom flags to pass to the MC generator: %s' % args.add_flags[0], 'GREEN') settings.set('AddFlags', args.add_flags[0]) mc_generator, geant = check_binaries(settings, verbose) if not mc_generator or not geant: sys.exit(1) if not channels: print_color('[Warning] No channels specified in the config file', 'YELLOW') print_color(' Use -e to export example settings or -h for help', 'YELLOW') channels = simulation_dialogue() if not channels: sys.exit('No channels entered for simulation, exiting.') if args.walltime: print_color('Setting custom walltime to %d hours' % args.walltime[0], 'GREEN') settings.set('WALLTIME', args.walltime[0]) if args.queue: print_color('Setting custom queue to %s' % args.queue[0], 'GREEN') settings.set('QUEUE', args.queue[0]) tag = args.tag[0] if args.tag else 'Sim' if verbose: print('Use the tag "%s" for the submitted jobs' % tag) if verbose: print('These are the updated settings:') settings.print() if 'Ant-cocktail' in mc_generator: if not sanity_check_cocktail(settings): sys.exit(1) if 'Ant-mcgun' in mc_generator: if not sanity_check_mcgun(settings): sys.exit(1) if not sanity_check_channels(mc_generator, channels): sys.exit(1) if verbose: print('Determining the existing amount of files...') simulation = [] for channel in channels: decay_string = get_decay_string(channel[0]) max_number = check_simulation_files(settings, decay_string) simulation.append([decay_string, channel[0], channel[1], channel[2], max_number]) print_color(str(len(simulation)) + ' channels configured. ' 'The following simulation will take place:', 'BLUE') total_files, total_events = 0, 0 for channel, _, files, events, _ in simulation: total = files*events chnl = channel if 'pluto' in mc_generator.lower(): chnl = format_channel(channel) print("{0:<20s} {1:>4d} files per {2:>4s} events (total {3:>4s} events)" .format(chnl, files, unit_prefix(events), unit_prefix(total))) total_files += files total_events += total print(" Total %s events in %d files" % (unit_prefix(total_events), total_files)) print(" Files will be stored in " + settings.get('OUTPUT_PATH')) # run a test job for the first command to be submitted and check the output print_color('Test provided commands', 'BLUE') print(' Running first test job locally . . .') if not run_test_job(settings, simulation, mc_generator, geant): print_error('[ERROR] Test job failed, aborting job submission') sys.exit(1) print_color('Test job successful', 'BLUE') # start the job submission print('Start submitting jobs, total', total_files) submit_jobs(settings, simulation, mc_generator, geant, tag, total_files, verbose) print_color('Done!', 'GREEN')
def export(self, file_name, force=False): """Export the current settings to the given file""" file_name = os.path.expanduser(file_name) path = os.path.dirname(file_name) if not path: path = os.getcwd() file_name = os.path.join(path, file_name) if not os.path.exists(path) and not force: print_error( '[ERROR] The path "%s" for exporting the settings does not exist!' % path) return False elif not os.path.exists(path): print_color( '[INFO] The path "%s" does not exist, it will be created now.' % path, 'BLUE') try: os.makedirs(path) except OSError as exception: if exception.errno == errno.EACCES: print_error( '[ERROR] You do not have the permission to create directories in "%s"' % os.path.dirname(path)) return False elif exception.errno != errno.EEXIST: raise if not os.access(path, os.W_OK): print_error('[ERROR] The given path "%s" os not writable!' % path) return False if os.path.isfile(file_name): if not force: print_error( '[ERROR] The specified file "%s" already exists, aborting export.' % file_name) return False else: print_color( '[INFO] The file "%s" already exists, it will be overwritten.' % file_name, 'BLUE') with open(file_name, 'w') as file: file.write('%s\n' % '[settings]') file.write( '%s\n' % '# output path, current directory will be used if missing') file.write('%s = %s\n' % ('OUTPUT_PATH', self.__settings['OUTPUT_PATH'])) file.write( '%s\n' % '# directory relative to output path above to store MC generated files' ) file.write('%s = %s\n' % ('MCGEN_DATA', self.__settings['MCGEN_DATA'])) file.write('%s\n' % '# relative path to output path above ' 'where the Geant4 files should be stored') file.write('%s = %s\n' % ('GEANT_DATA', self.__settings['GEANT_DATA'])) file.write('%s\n' % '# log directory relative to output path above, ' 'log will be used if empty') file.write('%s = %s\n' % ('LOG_DATA', self.__settings['LOG_DATA'])) file.write( '%s\n' % '# path to the a2geant binaries, $PATH is used if empty') file.write('%s = %s\n' % ('A2_GEANT_PATH', self.__settings['A2_GEANT_PATH'])) file.write( '%s\n' % '# the A2 Geant binary which should be used, default "A2" if empty' ) file.write( '%s\n' % '# IMPORTANT: if you\'re using the new A2Geant4 version, set this parameter' ) file.write( '%s\n' % '# to "A2Geant4" and specify additional "GeantFlags" further down' ) file.write('%s = %s\n\n' % ('GEANT_BINARY', self.__settings['GEANT_BINARY'])) file.write('%s\n' % '# some default settings for jobs') file.write('%s = %s\n' % ('QSUB_BIN', self.__settings['QSUB_BIN'])) file.write( '%s\n' % '# mail when job aborts (a), begins (b), ends (e), no mails (n)' ) file.write('%s = %s\n' % ('QSUB_MAIL', self.__settings['QSUB_MAIL'])) file.write('%s = %s\n' % ('QUEUE', self.__settings['QUEUE'])) file.write('%s = %s\n' % ('WALLTIME', self.__settings['WALLTIME'])) file.write('%s = %s\n' % ('PRIORITY', self.__settings['PRIORITY'])) file.write('%s\n' % '# any additional flags needed for submission') file.write( '%s\n' % '# e.g. to restrict execution hosts to sl7: -l nodes=1:sl7') file.write('%s = %s\n\n' % ('QSUB_EXTRA', self.__settings['QSUB_EXTRA'])) file.write('%s\n' % '# simulation specific settings') file.write('%s\n' % '# the MC generator which should be used, i.e.') file.write('%s\n' % '# Ant-pluto, Ant-cocktail, or Ant-mcgun') file.write( '%s\n' % '# Note: If you specify a different MC generator, please') file.write( '%s\n' % '# make sure that its output is readable by Geant!') file.write('%s\n' % '# Flags can be passed via AddFlags option.') file.write('%s = %s\n' % ('GENERATOR', self.__settings['GENERATOR'])) file.write( '%s\n' % '# leave the generator path blank to use the $PATH variable') file.write('%s = %s\n' % ('GENERATOR_PATH', self.__settings['GENERATOR_PATH'])) file.write('%s\n' % '# minimum energy of the photon beam') file.write('%s: %s\n' % ('Emin', self.__settings['Emin'])) file.write('%s\n' % '# maximum energy of the photon beam') file.write('%s: %s\n' % ('Emax', self.__settings['Emax'])) file.write('%s\n' % '# Ant-cocktail specific settings') file.write('%s\n' % '# Define only ONE of the following two settings!') file.write( '%s\n' % '# Setup which should be used, e.g. "Setup_2014_07_EPT_Prod"') file.write('%s: %s\n' % ('COCKTAIL_SETUP', self.__settings['COCKTAIL_SETUP'])) file.write( '%s\n' % '# Binning for the beam energy, min and max energy as defined above' ) file.write( '%s: %s\n' % ('COCKTAIL_BINNING', self.__settings['COCKTAIL_BINNING'])) file.write( '%s\n' % '# Ant-mcgun specific settings, min and max energy used as defined above' ) file.write( '%s\n' % '# covered theta range in degree in the format min_theta max_theta' ) file.write('%s: %s\n' % ('GUN_THETA', self.__settings['GUN_THETA'])) file.write('%s\n' % '# opening angle between particles in degree') file.write('%s: %s\n' % ('GUN_OPENING', self.__settings['GUN_OPENING'])) file.write( '%s\n' % '# additional flags passed to runGeant (which calls a2geant), ' 'for example regex to replace information in detector macro setup' ) file.write( '%s\n' % "# like 's~^(/A2/det/setTargetLength).*~$1 5 cm~' (using the Ant branch of a2geant4)" ) file.write( '%s\n' % '# in case you\'re using the new A2Geant4 additional flags like the macros you want to use go here' ) file.write('%s: %s\n\n' % ('GeantFlags', self.__settings['GeantFlags'])) file.write( '%s\n' % '# additional flags passed to the generator, for example --flatEbeam (cocktail, pluto) or --flatTheta (mcgun)' ) file.write('%s: %s\n\n' % ('AddFlags', self.__settings['AddFlags'])) file.write('%s\n' % '[channels]') file.write( '%s\n' % '# channels which should be simulated with Ant-pluto, line has to start with ";", ' 'given in the syntax used in Pluto (do not forget the recoil proton!), ' 'the amount of files and the number of events per file') file.write('%s\n' % '#;"p pi0 [g g]" 10 100000') file.write( '%s\n' % '# in case of Ant-cocktail, start the string with "Cocktail", ' 'followed by the amount of files and the number of events per file' ) file.write('%s\n' % '#;"Cocktail" 100 10000') file.write( '%s\n' % '# for the particle gun Ant-mcgun, start the string with "Gun: <particle_list>", ' 'particle list separated by spaces, followed by the amount of files ' 'and the number of events per file') file.write('%s\n' % '#;"Gun: g g" 100 10000') return True
for entry in range(len(hardware_ports)): # the find method will return the index of the lowest position the subtring was found # it will return a -1 if not found # if hardware_ports[entry].find("Wi-Fi") > 0: # print_good("got one " + entry) found = True device_name = hardware_ports[entry + 1].split(":")[-1].strip() else: continue if found: # print_good("Found a Wi-Fi hardware port!") print_good("\t{}".format(device_name)) elif not found: print_error("No Wi-Fi interfaces found!") print_status("Gathering any preferred wireless networks...") preferred = sub.run(["networksetup","-listpreferredwirelessnetworks", device_name], stdout=sub.PIPE) preferred = preferred.stdout.decode() print_status(preferred) ### # # TO DO # # remove a preferred wireless network