diff --git a/simrunner/config_processing.py b/simrunner/config_processing.py index 7a712eb65d2bc8d2b68e773a3e6045e7b443e162..806aff932c57956ae43aaa51668b14b7082f8663 100644 --- a/simrunner/config_processing.py +++ b/simrunner/config_processing.py @@ -1,5 +1,3 @@ -import argparse -import getpass import json import os @@ -10,27 +8,6 @@ import os BYTE_SIZES = ['16', '32'] -# Function to parse command-line arguments -def parse_arguments(): - main_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - default_sim_path = os.path.join(os.path.dirname(__file__), '../build/src/detsim') - current_user = getpass.getuser() - parser = argparse.ArgumentParser(description='Run a subprocess locally or on remote machines.') - parser.add_argument('-s', '--sim', type=str, default=default_sim_path, - help='Path to the detector simulation script default: ./') - parser.add_argument('-H', '--hosts', nargs='+', type=str, - help='Host addresses of remote machines default: lokal') - parser.add_argument('-u', '--user', type=str, default=current_user, - help='Username for SSH connection default: current user') - parser.add_argument('-f', '--function', choices=['various', 'long'], default='various', - help='Choose function to execute default: various') - parser.add_argument('-d', '--data', type=str, default=main_directory, - help='Folder to store the date for visualizer default: ./') - parser.add_argument('-p', '--testData', type=str, default=main_directory, - help='Folder to store the test data from detector sim default: ./') - return parser.parse_args() - - # Function to read the configuration from a JSON file def read_config(): config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data_config.json') diff --git a/simrunner/main.py b/simrunner/main.py index 907e1d6370e96cb7f02e4d19cc747e630bb672d6..270d3b46dccec78f350d1ee4cc3d84f88ff271cf 100644 --- a/simrunner/main.py +++ b/simrunner/main.py @@ -1,5 +1,7 @@ import os import logging +import argparse +import getpass import simulation as sim import output_processing as op import config_processing as con @@ -7,26 +9,45 @@ import config_processing as con # Set up logging global logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -stop_requested = False -# Parse arguments global -args = con.parse_arguments() + +# Function to parse command-line arguments global +def parse_arguments(): + main_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + default_sim_path = os.path.join(os.path.dirname(__file__), '../build/src/detsim') + current_user = getpass.getuser() + parser = argparse.ArgumentParser(description='Run a subprocess locally or on remote machines.') + parser.add_argument('-s', '--sim', type=str, default=default_sim_path, + help='Path to the detector simulation script default: ./') + parser.add_argument('-H', '--hosts', nargs='+', type=str, + help='Host addresses of remote machines default: lokal') + parser.add_argument('-u', '--user', type=str, default=current_user, + help='Username for SSH connection default: current user') + parser.add_argument('-f', '--function', choices=['various', 'long'], default='various', + help='Choose function to execute default: various') + parser.add_argument('-d', '--data', type=str, default=main_directory, + help='Folder to store the date for visualizer default: ./') + parser.add_argument('-p', '--testData', type=str, default=main_directory, + help='Folder to store the test data from detector sim default: ./') + return parser.parse_args() + + +args = parse_arguments() + # --- MAIN --- if __name__ == '__main__': # Setup all paths and folders main_folder_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - simulation_path = args.sim - data_path = os.path.join(args.data, 'output') test_data_path = os.path.join(args.data, 'test_data') # Setup arguments for Sim event_dict = con.create_event_list(args, test_data_path) # Run detectorSimulation - sim.run_sim(event_dict, data_path, simulation_path, main_folder_path) + sim.run_sim(event_dict, main_folder_path) # Clean up - op.pull_data(data_path, main_folder_path) + op.pull_data(main_folder_path) op.rm_data(test_data_path) diff --git a/simrunner/output_processing.py b/simrunner/output_processing.py index cd984f3ae5ded90ea7dd0fc1fbf982bc7952c390..a229e914119192fb9daa218618a2477246f21db2 100644 --- a/simrunner/output_processing.py +++ b/simrunner/output_processing.py @@ -32,7 +32,8 @@ def write_statistics(main_path, stat_file_name, output): # Function to pull data from remote machines to the local machine -def pull_data(source_path, desti_path): +def pull_data(desti_path): + source_path = os.path.join(args.data, 'output') desti = os.path.join(desti_path, 'output') os.makedirs(desti, mode=0o777, exist_ok=True) if args.hosts: diff --git a/simrunner/simulation.py b/simrunner/simulation.py index c3e0eb17ba03fceea9b3ed54a2b7379204eaeaad..2ecf0c04fb23808e4ccec4cd4805c04760f726d5 100644 --- a/simrunner/simulation.py +++ b/simrunner/simulation.py @@ -10,6 +10,39 @@ from main import logger stop_requested = False +# Function to print terminal output and handle errors +def terminal_output(output, errors, return_code, msg): + print(output, errors, return_code, msg) + if return_code > 0: + logger.error(f'return code: {return_code}') + if errors: + logger.error(errors) + if output: + logger.info(output) + else: + if output: + logger.info(output) + logger.info(msg) + + +def handle_sigint(signum, frame): + logger.info("Main process received KeyboardInterrupt") + global stop_requested + stop_requested = True + if args.hosts: + for h in args.hosts: + kill_target = f'{args.user}@{h}' + kill_cmd = f"ssh {kill_target} pkill -f {args.sim}" + re = subprocess.run(kill_cmd, shell=True) + ou = re.stdout + er = re.stderr + rc = re.returncode + terminal_msg = f'{kill_target} killed' + terminal_output(ou, er, rc, terminal_msg) + else: + logger.info('Sim killed') + + # Function to run the detector simulation remote def remote_simulation(sim_path, event, output_path, ssh_target, host): test_data_path = event['--posixDataDir'] @@ -44,40 +77,8 @@ def local_simulation(sim_path, event, output_path): return output, errors, result.returncode -# Function to print terminal output and handle errors -def terminal_output(output, errors, return_code, msg): - if return_code > 0: - logger.error(f'return code: {return_code}') - if errors: - logger.error(errors) - if output: - logger.info(output) - else: - if output: - logger.info(output) - logger.info(msg) - - -def handle_sigint(signum, frame): - logger.info("Main process received KeyboardInterrupt") - global stop_requested - stop_requested = True - if args.hosts: - for h in args.hosts: - kill_target = f'{args.user}@{h}' - kill_cmd = f"ssh {kill_target} pkill -f {args.sim}" - re = subprocess.run(kill_cmd, shell=True) - ou = re.stdout - er = re.stderr - rc = re.returncode - terminal_msg = f'{kill_target} killed' - terminal_output(ou, er, rc, terminal_msg) - else: - logger.info('Sim killed') - - # Function to run the detector simulation with the given event arguments -def run_sim(e_dict, d_path, sim_path, main_path): +def run_sim(e_dict, main_path): with cf.ThreadPoolExecutor() as executor: signal.signal(signal.SIGINT, handle_sigint) for event in e_dict: @@ -87,17 +88,18 @@ def run_sim(e_dict, d_path, sim_path, main_path): folder_name = e_dict[event]['-o'] e_dict[event]['--startTime'] = f'@{int(time.time() + 10)}' e_dict[event]['--posixDataDir'] = os.path.join(e_dict[event]['--posixDataDir'], event) - output_path = os.path.join(d_path, folder_name) + output_path_given = os.path.join(args.data, 'test_data') + output_path = os.path.join(output_path_given, folder_name) if args and args.hosts: # Remote execution on multiple machines with specified user for host in args.hosts: ssh_target = f'{args.user}@{host}' - future = executor.submit(remote_simulation, sim_path, e_dict[event], output_path, + future = executor.submit(remote_simulation, args.sim, e_dict[event], output_path, ssh_target, host) futures.append((folder_name, host, future)) # Local execution else: - future = executor.submit(local_simulation, sim_path, e_dict[event], output_path) + future = executor.submit(local_simulation, args.sim, e_dict[event], output_path) futures.append((folder_name, None, future)) for folder_name, host, future in futures: