From d023d059535a176b70329a050d8724aad58259ed Mon Sep 17 00:00:00 2001
From: Michael Reuscher <michael.reuscher@desy.de>
Date: Wed, 19 Jul 2023 17:15:26 +0200
Subject: [PATCH] new simrunner update

---
 simrunner/data_config.json              |  29 +++++-
 simrunner/simrunner.py                  | 113 ++++++++++++++++++++----
 visualizer/setup.py                     |   3 +-
 visualizer/visualizer/SeabornPlotter.py |   2 +-
 4 files changed, 124 insertions(+), 23 deletions(-)

diff --git a/simrunner/data_config.json b/simrunner/data_config.json
index 7700084..e8bedd8 100644
--- a/simrunner/data_config.json
+++ b/simrunner/data_config.json
@@ -1,7 +1,30 @@
 {
-  "data_config":{
-    "--posixDataDir": "protokoll",
+  "data_config_various":{
     "-n": "100",
     "-i": "0.1s",
-    "-N": "4"}
+    "-N": "4"},
+  "data_config_long":{
+    "-s": "4096",
+    "-n": "200",
+    "-i": "0.1s",
+    "-N": "4"},
+  "data_config_help":{
+    "note":                  "this is only a help an it is never used by the simrunner programm",
+    "--burstInterval":       "event interval in a burst default: 1000000",
+    "--burstLength":         "number of events in a burst default: 0",
+    "-d, --dataGenerator":   "name of the data generator default: random",
+    "--debugOptions":        "give debug output to option parsing default: false",
+    "-h, --help":            "give this help default: false",
+    "-i, --interval":        "event interval default: 1000000000",
+    "-n, --nEvents":         "number of events to create per thread default: 1",
+    "--noCfgFileRecursion":  "do not read config files recursively, must be set before use default: false",
+    "--noCfgFiles":          "do not read the default config files, must be FIRST option default: false",
+    "--nodeId":              "nodeId for object indentification default:",
+    "-p, --prefixData":      "data prepended to output lines default:",
+    "-s, --size":            "block size (only needed by long)",
+    "--skew":                "timing skew between threads, fracton of interval default: 0",
+    "--startTime":           "time point to start generating data default: -9223372036.854776",
+    "-t, --timingGenerator": "name of the timing generator default: regular",
+    "-V, --version":         "print version and exit sucessfully default: false",
+    "--writeCfgFile":        "write a config file default:"}
 }
\ No newline at end of file
diff --git a/simrunner/simrunner.py b/simrunner/simrunner.py
index 9acaa43..caddd67 100644
--- a/simrunner/simrunner.py
+++ b/simrunner/simrunner.py
@@ -1,6 +1,27 @@
 import os
 import json
 import subprocess
+import argparse
+import getpass
+
+
+def parse_arguments():
+    main_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+    default_sim_path = os.path.join(os.path.dirname(__file__), "../build/src/detsim")
+    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,
+                        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_folder,
+                        help='Folder to store the date for visualizer default: ./')
+    parser.add_argument('-p', '--protokoll', type=str, default=main_folder,
+                        help='Folder to store the test data from detector sim default: ./')
+    return parser.parse_args()
 
 
 def read_config():
@@ -10,16 +31,8 @@ def read_config():
     return d_config
 
 
-def start_process(program_path, arguments):
-    command = [program_path] + arguments
-    result = subprocess.run(command, capture_output=True, text=True)
-    output = result.stdout
-    errors = result.stderr
-    return output, errors, result.returncode
-
-
-def set_arguments(data_config):
-    data_config = read_config()
+def set_arguments_various(da_config):
+    data_config = da_config
     e_list = []
     byte_sizes = ['16', '32', '64', '128', '256', '512', '1024', '2048', '4096', '8192',
                   '16384', '32768', '65536', '131072', '262144', '524288', '1048576', '2097152',
@@ -29,16 +42,46 @@ def set_arguments(data_config):
         event_name = "Data_Set_" + event
         arguments = ["-s", event]
         for outer_key in data_config.keys():
+            if outer_key == 'data_config_various':
+                inner_dict = data_config[outer_key]
+                for k, v in inner_dict.items():
+                    arguments.append(k)
+                    arguments.append(v)
+                arguments.append('--posixDataDir')
+                arguments.append(protokoll_path)
+                arguments.append('-o')
+                arguments.append(event_name)
+                e_list.append(arguments)
+    return e_list
+
+
+def set_arguments_long(da_config):
+    data_config = da_config
+    e_list = []
+    event_name = "Data_Set_Long"
+    arguments = []
+    for outer_key in data_config.keys():
+        if outer_key == 'data_config_long':
             inner_dict = data_config[outer_key]
             for k, v in inner_dict.items():
                 arguments.append(k)
                 arguments.append(v)
-            arguments.append("-o")
+            arguments.append('--posixDataDir')
+            arguments.append(protokoll_path)
+            arguments.append('-o')
             arguments.append(event_name)
             e_list.append(arguments)
     return e_list
 
 
+def create_event_list():
+    if args.function == 'long':
+        e_list = set_arguments_long(read_config())
+    else:
+        e_list = set_arguments_various(read_config())
+    return e_list
+
+
 def run_sim(e_list, d_path, sim_path, st_path):
     for event in e_list:
         folder_name = event[-1]
@@ -57,18 +100,54 @@ def run_sim(e_list, d_path, sim_path, st_path):
             print("return code: ", return_code)
 
 
+def start_process(program_path, arguments):
+    if args.hosts:
+        if args.user:
+            # Remote execution on multiple machines with specified user
+            for host in args.hosts:
+                ssh_command = f'{args.user}@{host}'
+                command = ["ssh", ssh_command] + arguments
+                print(command)
+                result = subprocess.run(command, capture_output=True, text=True)
+                output = result.stdout
+                errors = result.stderr
+                return output, errors, result.returncode
+        else:
+            # Remote execution on multiple machines with current user
+            current_user = getpass.getuser()
+            for host in args.hosts:
+                ssh_command = f'{current_user}@{host}'
+                command = ["ssh", ssh_command] + arguments
+                print(command)
+                result = subprocess.run(command, capture_output=True, text=True)
+                output = result.stdout
+                errors = result.stderr
+                return output, errors, result.returncode
+    else:
+        command = [program_path] + arguments
+        result = subprocess.run(command, capture_output=True, text=True)
+        output = result.stdout
+        errors = result.stderr
+        return output, errors, result.returncode
+
+
 # --- MAIN ---
-# Setup all paths an folders
-main_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-data_path = os.path.join(main_folder, "output1")
-protokoll_path = os.path.join(main_folder, "protokoll")
+
+# Parse arguments
+args = parse_arguments()
+
+# Setup all paths and folders
+simulation_path = args.sim
+data_path = os.path.join(args.data, "output1")
+protokoll_path = os.path.join(args.protokoll, "protokoll")
 stat_path = os.path.join(data_path, "statistics")
 os.makedirs(protokoll_path, mode=0o777, exist_ok=True)
 os.makedirs(stat_path, mode=0o777, exist_ok=True)
-simulation_path = os.path.join(os.path.dirname(__file__), "../build/src/detsim")
+
 
 # Setup arguments for Sim
-event_list = set_arguments(read_config())
+event_list = create_event_list()
 
 # Run detectorSimulation
 run_sim(event_list, data_path, simulation_path, stat_path)
+
diff --git a/visualizer/setup.py b/visualizer/setup.py
index 4d7212d..c084007 100644
--- a/visualizer/setup.py
+++ b/visualizer/setup.py
@@ -10,8 +10,7 @@ setup(
         'numpy',
         'pandas',
         'seaborn',
-        'matplotlib',
-        'scipy'
+        'matplotlib'
     ],
     entry_points={
         'console_scripts': [
diff --git a/visualizer/visualizer/SeabornPlotter.py b/visualizer/visualizer/SeabornPlotter.py
index eb53e4e..671bc87 100644
--- a/visualizer/visualizer/SeabornPlotter.py
+++ b/visualizer/visualizer/SeabornPlotter.py
@@ -2,7 +2,7 @@ import numpy as np
 import matplotlib.pyplot as plt
 import seaborn as sns
 import pandas as pd
-from scipy.stats import iqr
+
 sns.set_theme()
 
 
-- 
GitLab