def rm_conf(config, force): from os import rmdir, remove, scandir from os.path import isfile from re import fullmatch import json from lib.utils import points_recast, config_dir, project_folder points_old, _ = points_recast([], [], '', True, config, 'tools') cleared = clear_data(points_old, config, force) if not cleared: print('Config not empty.') return path = config_dir(config) for x in scandir(path): if fullmatch('.*.cdt', x.name): remove(x) if isfile(path + '/pstop.pickle'): remove(path + '/pstop.pickle') rmdir(path) print(f"Removed config '{config}' at path:\n {path}") with open(project_folder() + '/output/configs.json', 'r') as config_file: configs = json.load(config_file) del configs[config] with open(project_folder() + '/output/configs.json', 'w') as config_file: json.dump(configs, config_file, indent=4)
def reset_fit(names, delete): from os.path import isdir from os import chdir, mkdir from shutil import rmtree from re import fullmatch import json from lib.utils import (authorization_request, fit_dir, find_fits, project_folder) pattern_names = [] pure_names = [] all_names = list(find_fits().keys()) for name in names: if name[0] == '§': pattern_names += [c for c in all_names if fullmatch(name[1:], c)] else: pure_names += [name] names = list(set(pure_names + pattern_names)) print(f'Chosen fits are:\n {names}') for name in names: fit = fit_dir(name) if delete: action = 'delete' action_p = action + 'd' else: action = 'reset' action_p = action what_to_do = 'to ' + action + ' the fit \'' + name + '\'' authorized = authorization_request(what_to_do) if authorized == 'yes': rmtree(fit) if action == 'reset': mkdir(fit) elif action == 'delete': with open(project_folder() + '/output/fits.json', 'r') as file: fits = json.load(file) del fits[name] with open(project_folder() + '/output/fits.json', 'w') as file: json.dump(fits, file, indent=4) print(f'Fit {name} has been {action_p}.') elif authorized == 'quit': print('Nothing done on last fit.') return else: print('Nothing done.')
def local_launch(points, arg_strs): from os import system, chdir from os.path import abspath from subprocess import Popen from lib.utils import (point_dir, launch_script_name, make_script_name, project_folder) dirs = {Point: abspath(point_dir(Point)) for Point in points} for Point in points: chdir(dirs[Point]) arg_str = arg_strs[Point] run_num = int(arg_str.split()[1]) launch_script_n = launch_script_name(Point) make_script_n = make_script_name(Point) make_script = Popen([ "python3", make_script_n, str(run_num), str(Point[0]), str(Point[1]), project_folder() ]) make_script.wait() system('nohup python3 $PWD/' + launch_script_n + arg_str + ' &')
def show_confs(paths): from lib.utils import find_configs, project_folder import pprint as pp configs = find_configs() if paths: if not isinstance(configs, dict): paths = [project_folder() + '/output/' + c for c in configs] configs = dict(zip(configs, paths)) for name, path in sorted(configs.items(), key=lambda x: x[0].lower()): print(name, path, sep=':\n\t') else: if isinstance(configs, dict): configs = list(configs.keys()) for name in sorted(configs, key=str.lower): print(name)
def new_fit(name, path, caller_path): from os.path import isdir, isfile, abspath, basename from os import chdir, mkdir, listdir from inspect import cleandoc import json from lib.utils import find_fits, project_folder msg_exist = cleandoc("""The requested fit already exists. If you want to reset it, please use the specific command.""") fits = find_fits() chdir(caller_path) # actually creates requested folder if not path: path = caller_path + '/' + name if name in fits.keys() or abspath(path) in fits.values(): print(msg_exist) return elif basename(path) != name: print('At the present time names different from target ' 'directories are not available.') return else: try: mkdir(path) except (FileExistsError, FileNotFoundError): print('Invalid path given.') return print(f"Created fit '{name}' at path:\n {abspath(path)}") fits = {**fits, name: abspath(path)} with open(project_folder() + '/output/fits.json', 'w') as fit_file: json.dump(fits, fit_file, indent=4)
def make_str(p): run_num = int(arg_strs[p].split()[1]) make_args = str(run_num) + ' ' + str(p[0]) + ' ' + str(p[1]) + \ ' ' + project_folder() return make_script_name(p) + ' ' + make_args
def slurm_launch(points, arg_strs, queue, arch, file): from os import system, chdir, chmod, makedirs from os.path import realpath, basename from subprocess import Popen from time import time from datetime import datetime from lib.utils import (point_dir, launch_script_name, make_script_name, project_folder) # raise RuntimeError('support for marconi still missing') if queue in ['p', 'prod']: queue = 'prod' qtime = '23:59' elif queue in ['d', 'dbg', 'debug']: queue = 'dbg' qtime = '00:29' else: raise RuntimeError('slurm_launch: queue not recognized') if arch == 'skl': account = 'INF19_npqcd_0' c_sz = 48 # chunk_size elif arch == 'knl': account = 'IscrB_TOPPSI' c_sz = 68 # chunk_size else: raise RuntimeError('slurm_launch: arch not recognized') dirs = {Point: realpath(point_dir(Point)) for Point in points} points_chunks = [ points[c_sz * i:c_sz * (i + 1)] for i in range(len(points) // c_sz + 1) ] i = 0 for chunk in points_chunks: i += 1 def make_str(p): run_num = int(arg_strs[p].split()[1]) make_args = str(run_num) + ' ' + str(p[0]) + ' ' + str(p[1]) + \ ' ' + project_folder() return make_script_name(p) + ' ' + make_args def launch_str(p): return launch_script_name(p) + arg_strs[p] points_makers = [make_str(p) for p in chunk] points_launchers = [launch_str(p) for p in chunk] points = ['('] for j in range(len(chunk)): points += [ '"point_dir=\'' + point_dir(chunk[j]) + '\' ' + # 'make=\'' + points_makers[j] + '\' ' + 'launch=\'' + points_launchers[j] + '\'"' ] chdir(dirs[chunk[j]]) make_script = Popen(["python3", *points_makers[j].split()]) make_script.wait() points += [')'] points = '\n'.join(points) file_name = basename(file) sbatch_dir = file_name[:-4] time_ = datetime.fromtimestamp(time()).strftime('%d-%m-%Y_%H:%M:%S') jobname = f'CDT2D_{time_}--{i}' scripts_dir = project_folder() + '/lib/scripts' with open(scripts_dir + '/sbatch.sh', 'r') as sbatch_template: chunk_script = eval('f"""' + sbatch_template.read() + '"""') # if queue == 'dbg': if file[-3:] != '~~~': chunk_script += (f'\n\npython3 {project_folder()}/launcher.py ' f'run --file {file}') try: makedirs('../' + sbatch_dir) except FileExistsError: pass chdir('../' + sbatch_dir) sbatch_file = realpath(jobname + '.sh') with open(sbatch_file, 'w') as sbatch_script: sbatch_script.write(chunk_script) chmod(sbatch_file, 0o777) system('sbatch ' + sbatch_file)
def launch(points_old, points_new, config, linear_history, end_time, end_steps, force, time_lengths, adj, max_volume, move22, move24, move_gauge, fake_run, debug, queue, arch, file): """Output analysis for CDT_2D simulation. attempts_str = str(attempts) Parameters ---------- points_old : type Description of parameter `points_old`. points_new : type Description of parameter `points_new`. config : type Description of parameter `config`. linear_history : type Description of parameter `linear_history`. time : type Description of parameter `time`. steps : type Description of parameter `steps`. force : type Description of parameter `force`. time_lengths : type Description of parameter `time_lengths`. fake_run : type Description of parameter `fake_run`. debug : type Description of parameter `debug`. Raises ------ Exception descrizione dell'eccezione lanciata """ from os import mkdir, chdir, getcwd, scandir from os.path import isfile, isdir from shutil import copyfile from re import split, sub from platform import node import json from lib.utils import (find_running, point_dir, point_str, moves_weights, authorization_request, end_parser, launch_script_name, make_script_name, config_dir, project_folder) from lib.platforms import launch_run # set moves' weights move22, move24, move_gauge = moves_weights(move22, move24, move_gauge) points_run, _ = find_running() points_run = [x[0] for x in points_run if x[1] == config] points_old_auth = [] # old ones which will get the authorization to rerun points_req_run = [] # those requested which are already running for Point in points_old: if Point not in points_run: if not config == 'test' and not force: what_to_do = "to rerun simulation" authorized = authorization_request(what_to_do, Point) else: authorized = 'yes' if authorized == 'yes': points_old_auth += [Point] elif authorized == 'quit': print('No simulation launched.') return else: points_req_run += [Point] points = points_old_auth + points_new if len(points_new) > 0: print("New simulations will be launched for following (λ, β): ", points_new) if len(points_old_auth) > 0: print("Old simulations will be rerunned for following (λ, β): ", points_old_auth) if len(points_req_run) > 0: print("Simulations for following (λ, β) were already running: ", points_req_run) if len(points) > 0: print() arg_strs = {} for Point in points: chdir(config_dir(config)) dir_name = point_dir(Point) launch_script_n = launch_script_name(Point) make_script_n = make_script_name(Point) if Point in points_old: if not isdir(dir_name + "/history/adjacencies"): mkdir(dir_name + "/history/adjacencies") with open(dir_name + "/state.json", "r+") as state_file: state = json.load(state_file) if state['is_thermalized']: print('((λ, β) = ' + str(Point) + ') Ha già finito!') # @todo da migliorare continue if state['last_run_succesful']: run_num = state['run_done'] + 1 else: print('((λ, β) = ' + str(Point) + ') Problem in the last run') continue if state['is_thermalized'] and linear_history == '0': linear_history = '1M' # I'm putting the default because this case is present only for # backward compatibility, and before the timelength was stuck to 80 try: time_length = state['timelength'] except KeyError: time_length = time_lengths[Point] checkpoints = [ x.name for x in scandir(dir_name + "/checkpoint") if (split('_|\.|run', x.name)[1] == str(run_num - 1) and x.name[-4:] != '.tmp') ] # nell'ordinamento devo sostituire i '.' con le '~', o in generale # un carattere che venga dopo '_', altrimenti 'run1.1_...' viene # prima di 'run1_...' checkpoints.sort(key=lambda s: s.replace('.', '~')) last_check = checkpoints[-1] else: mkdir(dir_name) mkdir(dir_name + "/checkpoint") mkdir(dir_name + "/history") mkdir(dir_name + "/history/adjacencies") mkdir(dir_name + "/bin") make_template = project_folder() + '/lib/scripts/make_script.py' launch_template = project_folder( ) + '/lib/scripts/launch_script.py' copyfile(make_template, dir_name + '/' + make_script_n) copyfile(launch_template, dir_name + '/' + launch_script_n) if fake_run: print('Created simulation directory for: (Lambda= ' + str(Point[0]) + ', Beta= ' + str(Point[1]) + ')') run_num = 1 last_check = None time_length = time_lengths[Point] # devo farlo qui perché prima non sono sicuro che dir_name esista # ('mkdir(dir_name)') chdir(dir_name) if isfile('max_volume_reached'): print(f'Point {Point} won\'t be relaunched because it reached ' 'maximum volume available in the previous run.') continue if int(run_num) > 1: from lib.tools import recovery_history recovery_history() if linear_history != '0' and not state['linear-history']: state['linear-history-cut'] = state['iter_done'] if state['linear-history']: if linear_history == '0': print('\033[38;5;69mWarning:\033[0m') print(f"Point {Point} has been already run with " f"linear_history {state['linear-history']}, so this " f"value will be used.") elif linear_history != state['linear-history']: print('\033[38;5;69mWarning:\033[0m') print(f"Point {Point} has been already run with " f"linear_history {state['linear-history']}, so this " f"will be used instead of: {linear_history}.") linear_history = state['linear-history'] # ensure state_file existence or update it if int(run_num) == 1: state = { 'Lambda': Point[0], 'Beta': Point[1], 'run_done': 0, 'is_thermalized': False, 'last_checkpoint': None, 'iter_done': 0, 'timelength': time_length } with open('state.json', 'w') as state_file: json.dump(state, state_file, indent=4) # END CONDITION MANIPULATION # ricongiungo le due variabili perché è ancora facile # distinguerle dall'ultimo carattere if end_steps != '0': end_condition = end_steps else: end_condition = end_time # needed for thermalization loop end_partial, end_condition, end_type = end_parser(end_condition) if linear_history != '0': # i.e. `if linear_history:` if end_type == 'time': end_partial = str(end_condition) + 's' else: end_partial = end_condition # set debug_flag for c++ (in c++ style) debug_flag = str(debug).lower() # set adj_flag for c++ (in c++ style) adj_flag = str(adj).lower() # max_volume max_volume = int(max_volume[0] if type(max_volume) == list else max_volume) # is necessary to recompile each run because on the grid the launch node # could be different from run_node exe_name = "CDT_2D-" + point_str(Point) #+ "_run" + str(run_num) arguments = [ project_folder(), run_num, Point[0], Point[1], time_length, end_condition, debug_flag, last_check, linear_history, adj_flag, move22, move24, max_volume, end_partial, end_type, exe_name ] arg_str = '' for x in arguments: arg_str += ' ' + str(x) arg_strs[Point] = arg_str if fake_run: print() print(*(["bin/" + exe_name] + arguments[:8])) if not fake_run: from lib.platforms import launch_run points = list(arg_strs.keys()) launch_run(points, arg_strs, config, queue, arch, file)
def define_parser(launcher_path, version): """Define the parser for the launcher. Parameters ---------- launcher_path : str Path to launcher source. version: str The CDT_2D version number. Returns ------- argparse.ArgumentParser The argument parser for the launcher. dict The dictionary of commands to decode file inputs. """ starting_cwd = getcwd() chdir(project_folder()) if exists('output') and isdir('output'): if isfile('output/configs.json'): import json with open('output/configs.json', 'r') as config_file: configs_d = json.load(config_file) configs = list(configs_d.keys()) else: configs = [x.name for x in scandir('output') if x.is_dir()] if isfile('output/fits.json'): import json with open('output/fits.json', 'r') as fit_file: fits_d = json.load(fit_file) fits = list(fits_d.keys()) else: fits = [] else: configs = [] fits = [] meta_configs = '{...}' if len(configs) > 5 else None meta_fits = '{...}' if len(fits) > 5 else None # ┏━━━━━━━━━━━━━━━━┓ # ┗━━━━━━━━━━━━━━━━┛ msg = cleandoc(""" ┎────────────────┒ ┃ CDT2D LAUNCHER ┃ ┖────────────────┚ Manage CDT_2D simulations. To show the help of subcommand 'sub' run: launcher.py sub -h""") parser = argparse.ArgumentParser( description=msg, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('--version', action='version', version='CDT_2D ' + 'Gauge Fields: ' + version) # todo: devo scriverci usage # tipo senza nulla con un numero # oppure il tipo di numeri # migliorare la descrizione di ogni comando cmds = {'SUBPARSER': '', 'HELP': '', 'VERSION': ''} # SUBPARSERS subparsers = parser.add_subparsers(dest='command') subparsers.required = False # run command run_cmd = { 'LAMBDA': '--lamda', 'BETA': '--beta', 'RANGE': '--range', 'CONFIG': '--config', 'QUEUE': '--queue', 'ARCH': '--arch', 'FORCE': '--force', 'TIMELENGTH': '--timelength', 'DEBUG': '--debug', 'FAKE-RUN': '--fake-run', 'LINEAR-HISTORY': '--linear-history', 'TIME': '--time', 'STEPS': '--steps', 'ADJACENCIES': '--adjacencies', 'MOVE22': '--move22', 'MOVE24': '--move24', 'MOVE_GAUGE': '--move-gauge' } cmds = update_cmds(cmds, run_cmd) run_sub = subparsers.add_parser( 'run', help=msgs.run_h, description=msgs.run, formatter_class=argparse.RawDescriptionHelpFormatter) run_sub.add_argument('-l', '--lamda', nargs='+', type=float, required=True, help=msgs.lamda) run_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, required=True, help=msgs.beta) run_sub.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) run_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) run_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) run_sub.add_argument('-q', '--queue', default='debug', choices=['p', 'prod', 'd', 'dbg', 'debug'], help=msgs.queue) run_sub.add_argument('--arch', default='skl', choices=['skl', 'knl'], help=msgs.queue) run_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) run_sub.add_argument('--timelength', nargs='+', type=int, default=80, help=msgs.timelength) run_sub.add_argument('-d', '--debug', action='store_true', help='debug') run_sub.add_argument('-k', '--fake-run', action='store_true', help=msgs.fake_run) run_sub.add_argument('--lin', '--linear-history', dest='linear_history', default='0', type=str, help=msgs.linear_history) # run_sub.add_argument('--log-history', dest='linear_history', # action='store_false', # help="if set data points are saved at increasing intervals") end_conditions = run_sub.add_mutually_exclusive_group() end_conditions.add_argument('--time', default='30m', help=msgs.time) end_conditions.add_argument('--steps', default='0', help=msgs.steps) run_sub.add_argument('--adj', '--adjacencies', dest='adj_flag', action='store_true', help=msgs.adjacencies) run_sub.add_argument('--vol', '--max-volume', dest='max_volume', type=positive_float, nargs=1, default=1e5, help=msgs.maxvol) moves_weights = run_sub.add_argument_group("moves' weights", description=msgs.moves_weights) moves_weights.add_argument('--move22', nargs=1, type=non_negative_float, default=0.04, metavar='W_22', help=msgs.move22) moves_weights.add_argument('--move24', nargs=1, type=non_negative_float, default=0.06, metavar='W_24', help=msgs.move24) moves_weights.add_argument('--move-gauge', nargs=1, type=non_negative_float, default=0.8, metavar='W_g', help=msgs.moveg) run_sub.add_argument('--file', help=msgs.file) # state command class ToggleChoiceAction(argparse.Action): def __init__(self, option_strings, dest, ifcall, nargs=None, **kwargs): if nargs is not None: raise ValueError("nargs not allowed") super(ToggleChoiceAction, self).__init__(option_strings, dest, nargs='?', **kwargs) self.ifcall = ifcall def __call__(self, parser, namespace, values, option_string=None): if values is None: setattr(namespace, self.dest, self.ifcall) else: setattr(namespace, self.dest, values) state_sub = subparsers.add_parser( 'state', help=msgs.state_h, description=msgs.state, formatter_class=argparse.RawDescriptionHelpFormatter) state_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) state_sub.add_argument('-c', '--config', choices=configs, default=configs, metavar=meta_configs, ifcall='test', action=ToggleChoiceAction, help=msgs.config) state_sub.add_argument('-f', '--full-show', choices=['1', '2'], default='0', ifcall='1', action=ToggleChoiceAction, help=msgs.full_show) # stop command stop_sub = subparsers.add_parser( 'stop', help=msgs.stop_h, description=msgs.stop, formatter_class=argparse.RawDescriptionHelpFormatter) points = stop_sub.add_argument_group() points.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) points.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) points.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) points.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) stop_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) stop_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) stop_sub.add_argument('--pid', nargs='+', type=int, default=None, help=msgs.pid) stop_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) # plot command plot_sub = subparsers.add_parser( 'plot', help=msgs.plot_h, description=msgs.plot, formatter_class=argparse.RawDescriptionHelpFormatter) plot_sub.add_argument('-l', '--lamda', nargs='+', type=float, required=True, help=msgs.lamda) plot_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, required=True, help=msgs.beta) plot_sub.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) plot_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) plot_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) plot_sub.add_argument('-g', '--gauge', action='store_true', help=msgs.plot_gauge) # show command show_sub = subparsers.add_parser( 'show', help=msgs.show_h, description=msgs.show, formatter_class=argparse.RawDescriptionHelpFormatter) show_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) show_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) lambdas = show_sub.add_mutually_exclusive_group() lambdas.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) lambdas.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) show_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) show_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) show_sub.add_argument('-d', '--disk-usage', default='', const='disk', action='store_const', help=msgs.disk_usage) show_sub.add_argument('-n', '--number', dest='disk_usage', const='num', action='store_const', help=msgs.disk_number) # utilities subparser tools = subparsers.add_parser('tools', help=msgs.tools) tools_sub = tools.add_subparsers(dest='tools') # recovery command recovery_sub = tools_sub.add_parser( 'recovery', help='recovery', description=msgs.recovery, formatter_class=argparse.RawDescriptionHelpFormatter) recovery_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) recovery_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) lambdas = recovery_sub.add_mutually_exclusive_group() lambdas.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) lambdas.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) recovery_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) recovery_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) recovery_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) recovery_sub.add_argument('-F', '--FORCE', action='store_true', help=msgs.very_force) # info command info_sub = tools_sub.add_parser( 'info', help='info on a sim', description=msgs.info, formatter_class=argparse.RawDescriptionHelpFormatter) info_sub.add_argument('-l', '--lamda', nargs='+', type=float, required=True, help=msgs.lamda) info_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, required=True, help=msgs.beta) info_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) info_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) # thermalization command therm_sub = tools_sub.add_parser( 'set-therm', help='set thermalisation', description=msgs.therm, formatter_class=argparse.RawDescriptionHelpFormatter) therm_sub.add_argument('-l', '--lamda', nargs='+', type=float, required=True, help=msgs.lamda) therm_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, required=True, help=msgs.beta) therm_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) therm_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) therm_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) therm_sub.add_argument('-t', '--is-therm', default='True', choices=['True', 'False'], help=msgs.is_therm) # update launcher command launch_sub = tools_sub.add_parser( 'up-launch', help='update launch/make_script', description=msgs.up_launch, formatter_class=argparse.RawDescriptionHelpFormatter) points = launch_sub.add_argument_group() points.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) points.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) points.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) points.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) launch_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) launch_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) launch_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) script = launch_sub.add_mutually_exclusive_group() script.add_argument('-m', '--make', action='store_true', help=msgs.make) script.add_argument('--both', action='store_true', help=msgs.both) # autoremove command remove_sub = tools_sub.add_parser( 'autoremove', help='autoremove', description=msgs.autoremove, formatter_class=argparse.RawDescriptionHelpFormatter) remove_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) remove_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) lambdas = remove_sub.add_mutually_exclusive_group() lambdas.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) lambdas.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) remove_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) remove_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) remove_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) what = remove_sub.add_mutually_exclusive_group() what.add_argument('--bin', ifcall='0', action=ToggleChoiceAction, help=msgs.bin) what.add_argument('--check', ifcall='0', action=ToggleChoiceAction, help=msgs.check) # upload/download command remote_sub = tools_sub.add_parser( 'remote', help='upload/download sim dirs', description=msgs.remote, formatter_class=argparse.RawDescriptionHelpFormatter) remote_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) remote_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) lambdas = remote_sub.add_mutually_exclusive_group() lambdas.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) lambdas.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) remote_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) remote_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) remote_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) load = remote_sub.add_mutually_exclusive_group(required=True) load.add_argument('-u', '--upload', action='store_true', help=msgs.upload) load.add_argument('-d', '--download', action='store_true', help=msgs.download) load.add_argument('-s', '--show', action='store_true', help=msgs.remote_show) # config command config_sub = tools_sub.add_parser( 'config', help='edit project\'s configuration file', description=msgs.config_cmd, formatter_class=argparse.RawDescriptionHelpFormatter) configs_arg = config_sub.add_mutually_exclusive_group() configs_arg.add_argument('-e', '--email', action=ToggleChoiceAction, default=None, ifcall='-', help=msgs.email) configs_arg.add_argument('-r', '--remote', action=ToggleChoiceAction, default=None, ifcall='-', help=msgs.rclone_remote) configs_arg.add_argument('-p', '--path', action=ToggleChoiceAction, default=None, ifcall='-', help=msgs.rclone_path) configs_arg.add_argument('-n', '--node', action=ToggleChoiceAction, default=None, ifcall='-', help=msgs.node) config_sub.add_argument('-s', '--show', action='store_true', help=msgs.show_config) # new configuration command # new_conf_sub = tools_sub.add_parser('new-conf', # help='show configs directories', # description=msgs.show_confs, # formatter_class=argparse.RawDescriptionHelpFormatter) # new_conf_sub.add_argument('-p', '--paths', action='store_true', # help=msgs.show_paths) new_conf_sub = tools_sub.add_parser( 'new-conf', help='create new config', description=msgs.new_conf, formatter_class=argparse.RawDescriptionHelpFormatter) new_conf_sub.add_argument('name', nargs=1, type=str) new_conf_sub.add_argument('-p', '--path', type=str, default=None, help=msgs.path) # show available configurations command show_confs_sub = tools_sub.add_parser( 'show-confs', help='show configs directories', description=msgs.show_confs, formatter_class=argparse.RawDescriptionHelpFormatter) show_confs_sub.add_argument('-p', '--paths', action='store_true', help=msgs.show_paths) # reset configuration command reset_conf_sub = tools_sub.add_parser( 'reset', help='reset or delete config', description=msgs.reset, formatter_class=argparse.RawDescriptionHelpFormatter) reset_conf_sub.add_argument('name', choices=configs) # reset_conf_sub.add_argument('-d', '--delete', action='store_true', # help=msgs.delete) # remove configuration command rm_conf_sub = tools_sub.add_parser( 'rm-conf', help='remove config', description=msgs.rm_conf, formatter_class=argparse.RawDescriptionHelpFormatter) rm_conf_sub.add_argument('config', choices=configs, metavar=meta_configs, help=msgs.config) rm_conf_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) # clear command clear_sub = tools_sub.add_parser( 'clear', help='clear', description=msgs.clear, formatter_class=argparse.RawDescriptionHelpFormatter) clear_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) clear_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) lambdas = clear_sub.add_mutually_exclusive_group() lambdas.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) lambdas.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) clear_sub.add_argument('-@', dest='is_data', action='store_true', help=msgs.data) clear_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) clear_sub.add_argument('-f', '--force', action='store_true', help=msgs.force) # analysis subparser analysis = subparsers.add_parser('analysis', help=msgs.analysis) analysis_sub = analysis.add_subparsers(dest='analysis') def fit_pattern(fit): if not isinstance(fit, str): msg = f"{fit} is not a valid str." raise argparse.ArgumentTypeError(msg) if fit not in fits and fit[0] != '§': msg = f"{fit} is not valid fit nor pattern" raise argparse.ArgumentTypeError(msg) return fit # preliminary command def config_pattern(config): if not isinstance(config, str): msg = f"{config} is not a valid str." raise argparse.ArgumentTypeError(msg) if config not in configs and config[0] != '§': msg = f"{config} is not valid config nor pattern" raise argparse.ArgumentTypeError(msg) return config kinds = ['mv', 'mean-volumes', 'd', 'divergent', 'vp', 'volumes-plot'] pre_sub = analysis_sub.add_parser( 'pre', help='preliminary analyses', description=msgs.ana_pre, formatter_class=argparse.RawDescriptionHelpFormatter) pre_sub.add_argument('-k', '--kind', choices=kinds, help=msgs.pre_kind) pre_sub.add_argument('-c', '--config', default=None, metavar=meta_configs, nargs='+', type=config_pattern, help=msgs.config_pattern) pre_sub.add_argument('--conf-plot', dest='conf_plot', action='store_true', help=msgs.conf_plot) pre_sub.add_argument('-s', '--save_path', type=str, default=None, help=msgs.save_path) pre_sub.add_argument('-l', '--load_path', type=str, default=None, help=msgs.load_path) # preliminary plots command kinds = [ 'v', 'volumes', 'p', 'profiles', 'g', 'action', 'gauge', 'gauge-action', 'top', 'susc', 'top-susc', 't', 'torelons' ] pre_plot_sub = analysis_sub.add_parser( 'pre-plot', help='preliminary analyses', description=msgs.ana_pre, formatter_class=argparse.RawDescriptionHelpFormatter) pre_plot_sub.add_argument('fit_name', metavar=meta_fits, nargs='+', type=fit_pattern, help=msgs.fit_names) pre_plot_sub.add_argument('-k', '--kind', choices=kinds, help=msgs.pre_kind) # new fit command new_fit_sub = analysis_sub.add_parser( 'new-fit', help='create new fit', description=msgs.new_fit, formatter_class=argparse.RawDescriptionHelpFormatter) new_fit_sub.add_argument('fit_name', nargs=1, type=str) new_fit_sub.add_argument('-p', '--path', type=str, required=True, default=None, help=msgs.fit_path) # show available fits command show_fits_sub = analysis_sub.add_parser( 'show-fits', help='show fits directories', description=msgs.show_fits, formatter_class=argparse.RawDescriptionHelpFormatter) show_fits_sub.add_argument('-p', '--paths', action='store_true', help=msgs.show_fit_paths) # reset fit command reset_fit_sub = analysis_sub.add_parser( 'reset', help='reset or delete fit', description=msgs.reset, formatter_class=argparse.RawDescriptionHelpFormatter) reset_fit_sub.add_argument('fit_name', metavar=meta_fits, nargs='+', type=fit_pattern, help=msgs.fit_names) reset_fit_sub.add_argument('-d', '--delete', action='store_true', help=msgs.delete_fit) # # remove fit command # # rm_fit_sub = analysis_sub.add_parser('rm-fit', help='remove fit', # description=msgs.rm_fit, # formatter_class=argparse.RawDescriptionHelpFormatter) # rm_fit_sub.add_argument('fit', metavar=meta_fits, nargs='+', # type=fit_pattern, help=msgs.fits) # rm_fit_sub.add_argument('-f', '--force', action='store_true', # help=msgs.force) # set fit properties set_fit_sub = analysis_sub.add_parser( 'set-fit', help='set fit properties', description=msgs.set_fit, formatter_class=argparse.RawDescriptionHelpFormatter) set_fit_sub.add_argument('fit_name', metavar=meta_fits, nargs=1, choices=fits, type=str, help=msgs.fit_names) set_fit_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) set_fit_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) set_fit_sub.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) set_fit_sub.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) set_fit_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) set_fit_sub.add_argument('--remove', action='store_true', help=msgs.fit_remove) # set fit properties kinds = ['s', 'sims', 'o', 'obs'] info_fit_sub = analysis_sub.add_parser( 'info-fit', help='show fit properties', description=msgs.info_fit, formatter_class=argparse.RawDescriptionHelpFormatter) info_fit_sub.add_argument('fit_name', metavar=meta_fits, nargs=1, choices=fits, type=str, help=msgs.fit_names) info_fit_sub.add_argument('-k', '--kind', choices=kinds, help=msgs.pre_kind) # sims obs sim_obs_sub = analysis_sub.add_parser( 'sim-obs', help='calculate sims observables', description=msgs.sim_obs, formatter_class=argparse.RawDescriptionHelpFormatter) sim_obs_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) sim_obs_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) sim_obs_sub.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) sim_obs_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) sim_obs_sub.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) sim_obs_sub.add_argument('-n', '--fit-name', metavar=meta_fits, type=fit_pattern, nargs='+', help=msgs.fit_names) sim_obs_sub.add_argument('-f', '--fit', action='store_true', help=msgs.fit_obs) sim_obs_sub.add_argument('-p', '--plot', action='store_true', help=msgs.plot_obs) sim_obs_sub.add_argument('--et', '--exclude-torelons', action='store_true', dest='exclude_torelons', help=msgs.excl_tor) sim_obs_sub.add_argument('--eb', '--exclude-bootstrap', action='store_true', dest='exclude_bootstrap', help=msgs.excl_tor) sim_obs_sub.add_argument('--force', action='store_true', help=msgs.force) # refit corr command refit_sub = analysis_sub.add_parser( 'refit-corr', help='refit correlation lenghts', description=msgs.refit_corr, formatter_class=argparse.RawDescriptionHelpFormatter) refit_sub.add_argument('-l', '--lamda', nargs='+', type=float, help=msgs.lamda) refit_sub.add_argument('-b', '--beta', nargs='+', type=positive_float, help=msgs.beta) refit_sub.add_argument('--range', choices=['b', 'l', 'bl', 'lb'], default='', help=msgs.range) refit_sub.add_argument('-c', '--config', choices=configs, default='test', metavar=meta_configs, help=msgs.config) refit_sub.add_argument('-°', dest='is_all', action='store_true', help=msgs.is_all) refit_sub.add_argument('-n', '--fit-name', metavar=meta_fits, type=fit_pattern, nargs='+', help=msgs.fit_names) refit_sub.add_argument('-p', '--plot', action='store_true', help=msgs.plot_obs) # refit_sub.add_argument('--et', '--exclude-torelons', action='store_true', # dest='exclude_torelons', help=msgs.excl_tor) refit_sub.add_argument('--force', action='store_true', help=msgs.force) # export-data command data_types = [ 'v', 'volumes', 'p', 'profiles', 'pf', 'profiles-fit', 'pf2', 'profiles-fit2', 'g', 'gauge-action', 'top', 'susc', 'top-susc', 't', 'torelons', 'tf', 'torelons-fit', 'tf2', 'torelons-fit2' ] export_sub = analysis_sub.add_parser( 'export-data', description=msgs.export_data, help='export data for fit', formatter_class=argparse.RawDescriptionHelpFormatter) export_sub.add_argument('fit_name', metavar=meta_fits, type=fit_pattern, nargs='+', help=msgs.fit_names) export_sub.add_argument('-u', '--unpack', choices=data_types, help=msgs.unpack) # fit command kinds = [ 'v', 'volumes', 'p', 'profiles', 't', 'torelons', 'g', 'gauge-action', 'top', 'susc', 'top-susc' ] fit_sub = analysis_sub.add_parser( 'fit', help='fit', description=msgs.fit, formatter_class=argparse.RawDescriptionHelpFormatter) fit_sub.add_argument('fit_name', metavar=meta_fits, nargs=1, choices=fits, type=str, help=msgs.fits) fit_sub.add_argument('-r', '--reload', action='store_true', help=msgs.reload_data) fit_sub.add_argument('-k', '--kind', choices=kinds, default='volumes', help=msgs.fit_kinds) chdir(starting_cwd) return parser, cmds