diff --git a/.gitignore b/.gitignore
index ce120c1ed6ec1a3a1098f5dbcef557eaaa902c27..3c65cc2b38f962b3ac01ae5c6a3b0720115e6e6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,6 @@
 Log/*
 Log_autres/*
 
-# But keep the directories themselves
-# !Log/.gitkeep
-# !Log_autres/.gitkeep
+
 
 
diff --git a/Flower_v1/__pycache__/test_strategie.cpython-310.pyc b/Flower_v1/__pycache__/test_strategie.cpython-310.pyc
deleted file mode 100644
index beccf2ebf99c1a14a60da2f6d1302ff0e7495d57..0000000000000000000000000000000000000000
Binary files a/Flower_v1/__pycache__/test_strategie.cpython-310.pyc and /dev/null differ
diff --git a/Flower_v1/__pycache__/test_strategie.cpython-39.pyc b/Flower_v1/__pycache__/test_strategie.cpython-39.pyc
deleted file mode 100644
index 50afdcfc7bbb37e20ac097232e07341d99c0290e..0000000000000000000000000000000000000000
Binary files a/Flower_v1/__pycache__/test_strategie.cpython-39.pyc and /dev/null differ
diff --git a/Flower_v1/__pycache__/test_strategie_custom.cpython-310.pyc b/Flower_v1/__pycache__/test_strategie_custom.cpython-310.pyc
deleted file mode 100644
index 2b88d1be4df90085f02dbcc7f01cc2b0366d1f44..0000000000000000000000000000000000000000
Binary files a/Flower_v1/__pycache__/test_strategie_custom.cpython-310.pyc and /dev/null differ
diff --git a/Flower_v1/__pycache__/test_strategie_custom.cpython-39.pyc b/Flower_v1/__pycache__/test_strategie_custom.cpython-39.pyc
deleted file mode 100644
index 5a212d6495b8fd28b2a04999b3a28fd87aaae667..0000000000000000000000000000000000000000
Binary files a/Flower_v1/__pycache__/test_strategie_custom.cpython-39.pyc and /dev/null differ
diff --git a/Log/.gitkeep b/Log/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/Log_autres/.gitkeep b/Log_autres/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/README.md b/README.md
index 29575dc97940162434944341aaebdcb75516fe19..b86ac2163ead005f09b1971d9c197d68b9debd0e 100644
--- a/README.md
+++ b/README.md
@@ -7,14 +7,13 @@ This project provides tools to measure the energy consumption of Flower-based fe
 - [Getting Started](#getting-started)
 - [Installation](#installation)
 - [Usage](#usage)
-  - [Step 1. Configure](#step-1-configure)
-  - [Step 2. Reserve the Hosts in G5K](#step-2-reserve-the-hosts-in-g5k)
+- [Quickstart](#quickstart)
+  - [Step 1. Reserve the Hosts in G5K](#step-1-reserve-the-hosts-in-g5k)
+  - [Step 2. Configure](#step-2-configure)
   - [Step 3. Collect IP](#step-3-collect-ip)
-  - [Step 4. Run the Campaign or Instance](#step-4-run-the-campaign-or-instance)
+  - [Step 4. Run the Campaign or Instance](#step-4-run-the-campaign-or-single-instance)
   - [Step 5. Output](#step-5-output)
   - [Step 6. Clean Up](#step-6-clean-up)
-- [Quickstart](#quickstart)
-- [Output Structure](#output-structure)
 - [License](#license)
 
 ## Getting Started
@@ -36,7 +35,7 @@ This framework requires:
   ```bash
   pip install -r requirements.txt
   ```
-*Note:* `requirements.txt` includes TensorFlow, scikit-learn and numpy for running the provided Flower example.
+*Note:* `requirements.txt` includes `TensorFlow`, `scikit-learn` and `numpy` for running the provided Flower example. These packages requirement will be removed in official version.
 
 Navigate to `Run` directory:
 
@@ -46,144 +45,92 @@ cd Run
 
 ## Usage
 
-- FL scripts can be updated in `Flower_v1`.
-- Configure each instance of experiment in `Run\config_instance*.json`.
-- Follow these steps to config and run your experiment (or jump to [Quickstart](#quickstart) to run an example).
-
-### Step 1. Reserve the Hosts in G5K
-
-Reserve the required number of hosts (*See the [document of G5K](https://www.grid5000.fr/w/Getting_Started#Reserving_resources_with_OAR:_the_basics) for more details*)
-```bash
-oarsub -I -l host=[number_of_hosts],walltime=[duration]
-```
-
-### Step 2. Configure
-Edit the JSON configuration file (`config_instance*.json`) to specify experiment details. You can create multiple `config_instance*.json` files with the * is numbering of instance (the numbers must be consecutive positive integers starting from 1.)
-
-```bash
-vim config_instance1.json
-```
-
-Example structure:
-
-```json
-{
-    "instance": "fedAvg_cifar10",
-    "output_dir": "/home/mdo/Huong_DL/Log",
-    "dvfs": {
-        "dummy": false,
-        "baseline": false,
-        "frequencies": [2000000,2200000]
-    },
-    "server": {
-        "command": "python3",
-        "args": [
-            "Flower_v1/server.py",
-            "-r 50",
-            "-s fedAvg"
-        ],
-        "ip": "172.16.66.18",
-        "port": 8080
-    },
-    "clients": [
-        {
-            "name": "client1",
-            "command": "python3",
-            "args": [
-                "Flower_v1/client_1.py",
-                "cifar10",
-                "1",
-                "3"
-            ],
-            "ip": "172.16.66.2"
-        }
-        {
-            "name": "client2",
-            "command": "python3",
-            "args": [
-                "Flower_v1/client_1.py",
-                "cifar10",
-                "1",
-                "3"
-            ],
-            "ip": "172.16.66.3"
+- FL scripts can be updated, example in `Flower_v1`.
+- Configure instances of experiment in a json format, structure is shown below.
+
+  - **instances** includes **"1"**, **"2"** ,... are identifies of each instance.
+  - **instance**: name of instance.
+  - **output_dir**: location stores the output files (experiment log and energy monitoring output).
+  - **dvfs**: choose only one in 3 settings, detects all available CPU frequencies and go through all of them.
+    - `dummy`: for testing in min and max CPU freq (`false` or `true`).
+    - `baseline`: for testing in max CPU freq (`false` or `true`).
+    - `frequencies`: Limits to the provided list of frequencies (`null` or `int list []`).
+
+      **Remark:** check the available frequencies before using oftion `frequencies`.
+
+      - Set the permissions and disable Turbo Boost first:
+      ```bash
+      bash "$(python3 -c "import expetator, os; print(os.path.join(os.path.dirname(expetator.__file__), 'leverages', 'dvfs_pct.sh'))")" init
+      ```
+      - Run this command to get available frequencies:
+      ```bash
+      python3 get_frequencies.py
+      ```
+      - Update extraced frequencies value to configure files.
+  - Structure of json config:
+    ```json
+    {
+        "instances": {
+            "1": {
+                "instance": "",
+                "output_dir": "",
+                "dvfs": {
+                    "dummy": true,
+                    "baseline": false,
+                    "frequencies": null
+                },
+                "server": {
+                    "command": "python3",
+                    "args": [
+                    ],
+                    "ip": "",
+                    "port": 8080
+                    },
+                "clients": [
+                {
+                    "name": "client1",
+                    "command": "python3",
+                    "args": [
+                    ],
+                    "ip": ""
+                },
+                {...},
+                {...}
+                ]
+            },
+            "2": {
+                "instance": "",
+                ...
+            }
         }
-    ]
-}
-```
-
-- **instance**: The name of your experiment.
-- **output_dir**: Where to store the log files (experiment log and energy monitoring log).
-- **dvfs**: choose only one in 3 settings, detects all available frequencies and go through all of them.
-  - `dummy`: false or true (Only uses min and max frequency)
-  - `baseline`: false or true (Only uses max freq)
-  - `frequencies`: null or int list (Limits to the provided list of frequencies)
-
-**Remark:** check the available frequencies before using oftion `frequencies`.
-
-- Set the permissions and disable Turbo Boost first:
-```bash
-bash "$(python3 -c "import expetator, os; print(os.path.join(os.path.dirname(expetator.__file__), 'leverages', 'dvfs_pct.sh'))")" init
-```
-- Run this command to get available frequencies:
-```bash
-python3 get_frequencies.py
-```
-- Update extraced frequencies value to configure files.
-
-### Step 3. Collect IP
-
-Run the following command to generate a node list:
-```bash
-uniq $OAR_NODEFILE > nodelist
-```
+    }
+    ```
 
-Automatically populate missing IP addresses in the JSON file:
-```bash
-python3 collect_ip.py
-```
 
-### Step 4. Run the Campaign or Single Instance
+- 2 options of experiment: run single instance or all instances (a campaign).
 
-Run campain:
-```bash
-python3 run_measure.py -x [experiment_name] -r [repetitions]
-```
-Run single instance:
-```bash
-python3 measure.py -c [config_file] -x [experiment_name] -r [repetitions]
-```
-- **[experiment_name]**: The name you use to identify your experiment.
-- **[repetitions]**: Number of repetitions for the experiment.
-
-### Step 5. Output
-
-The logs and energy monitoring data will be saved in the directory specified in the JSON configuration.
-
-### Step 6. Clean Up
-
-After the experiment:
-
-Exit the host:
+  <u>Run single instance</u>:
   ```bash
-  exit
+  python3 measure_instance.py -c [config_file] -i [instance] -x [experiment_name] -r [repetitions]
   ```
 
-Check the job ID:
-  ```bash
-  oarstat -u
-  ```
+  - **[config_file]**: The instances configuration file.
+  - **[instance]** : Identify number of single instance.
+  - **[experiment_name]**: The name you use to identify your experiment.
+  - **[repetitions]**: Number of repetitions for the experiment.
 
-Kill the job:
+  <u>Run campaign</u>:
   ```bash
-  oardel <job_id>
+  python3 measure_campaign.py -x [experiment_name] -c [config_file] -r [repetitions]
   ```
+  For campaign running, all instances which were defined in **[config_file]** will be used.
 
 ## Quickstart
 
-Follow these steps to run an example:
+### Step 1. Reserve the Hosts in G5K
 
-1. Reserve 4 hosts (1 server + 3 clients) for 2 hours:
+Reserve the required number of hosts (*See the [document of G5K](https://www.grid5000.fr/w/Getting_Started#Reserving_resources_with_OAR:_the_basics) for more details*)  
+<u>For example</u>: Reserve 4 hosts (1 server + 3 clients) for 2 hours:
 ```bash
 oarsub -I -l host=4,walltime=2
 ```
@@ -192,48 +139,72 @@ Make sure your are in`eflwr/Run/`:
 cd Run
 ```
 
-2. Configure
+### Step 2. Configure
+Create the JSON configuration file (e.g. `config_instances.json`) to specify experiment details includes one or more instances.
 
-`config_instance1.json` and `config_instance2.json` provide two examples of instance configuration. All fields are configured but "output_dir" and "args" must be updated with your directories setting.
-- `config_instance1.json`: fedAvg, cifar10, dvfs with min and max freq, 1 round.
-- `config_instance1.json`: fedAvg2Clients, cifar10, dvfs with min and max freq, 1 round.
+```bash
+vim config_instances.json
+```
 
+<u>For example</u>: `config_instances.json` provides two examples of instance configuration. All fields are configured except "`output_dir`" and "`args`" must be updated with your directories setting.
+- instance "`1`": fedAvg, cifar10, dvfs with min and max CPU freq, 1 round.
+- instance "`2`": fedAvg2Clients, cifar10, dvfs with min and max CPU freq, 1 round.
 
-3. Collect IP
+### Step 3. Collect IP
 
+Run the following command to collect/generate a node list:
 ```bash
 uniq $OAR_NODEFILE > nodelist
-python3 collect_ip.py
 ```
 
-4. Run the Single Instance or Campaign
+Automatically populate missing IP addresses in the JSON file:
+```bash
+python3 collect_ip.py -n nodelist -c config_instances.json
+```
 
-Run single instance1 with `config_instance1.json`, 2 repetitions:
+### Step 4. Run the Campaign or Single Instance
+
+Run single instance with instance `1`, and 2 repetitions:
 ```bash
-python3 measure.py -c config_instance1.json -x SingleTest -r 2
+python3 measure_instance.py -c config_instances.json -i 1 -x SingleTest -r 2
 ```
-Run a campaign with all config_instance*.json in `/Run`, 2 repetitions:
+
+Run a campaign with all instances (`1` and `2`), and 2 repetitions:
 ```bash
-python3 run_measure.py -x CampaignTest -r 2
+python3 measure_instance.py -x CampaignTest -r 2
 ```
 
-## Output Structure
+### Step 5. Output
+
+The logs and energy monitoring data will be saved in the directory specified in the JSON configuration.
 
-Example output directory:
+Output dir structure:
 
 ```plaintext
 /Flower_<x>
 ├── Flower_instance_<instance_name>
 │   ├── Expetator
 |   |   ├── config_instance*.json
-│   ├── Expetator_<host_info>
-│   ├── Expetator_<host_info>_power
-│   │   ├── <client_logs>
+│   ├── Expetator_<host_info>_<timestamp>_mojitos: mojitos outputs
+│   ├── Expetator_<host_info>_<timestamp>_power: wattmetter outputs
+│   ├── Expetator_<host_info>_<timestamp>: measurement log
+│   ├── Flwr_<timestamp>: Flower log
+│   │   ├── Client_<ip>
+│   │   ├── Server_<ip>
 │   ├── Flwr_<timestamp>
 │   │   ├── Client_<ip>
 │   │   ├── Server_<ip>
+│── Flower_instance_<instance_name>
 ```
 
+### Step 6. Clean Up
+
+After the experiment, exit the host and kill job if needed:
+  ```bash
+  exit
+  oardel <job_id>
+  ```
+
 ## License
 
 This project is licensed under [GPLv3]. 
\ No newline at end of file
diff --git a/Run/collect_ip.py b/Run/collect_ip.py
index 0e28761569af7f3a42f5f5634fd90839fe5c93f4..75206102c7385bfbdb79c30b37cc255db416449a 100644
--- a/Run/collect_ip.py
+++ b/Run/collect_ip.py
@@ -1,10 +1,23 @@
+# python3 collect_ip.py -n nodelist -c config_instances.json
+
 import subprocess
 import json
-import os
-import glob
+import argparse
+
+# Path to the file containing hostnames
+parser = argparse.ArgumentParser(description="Collect IP addresses for all hostnames in the nodelist file.")
+parser.add_argument(
+    "-n", "--node_file", type=str, required=True,
+    help="Path to the file containing hostnames"
+)
+parser.add_argument(
+    "-c", "--configure", type=str, required=True,
+    help="Path to the config file"
+)
 
-# File paths
-node_file = "nodelist"  # Replace with the actual path to your node file
+args = parser.parse_args()
+node_file = args.node_file
+config_file = args.configure
 
 # Read the hostnames from the node file
 with open(node_file, "r") as file:
@@ -29,31 +42,36 @@ def get_ip_from_host(hostname):
 # Get IP addresses for all hostnames
 ip_addresses = [get_ip_from_host(hostname) for hostname in hostnames]
 
-# Find all config_instance<number>.json files in the current directory
-config_files = glob.glob("config_instance*.json")
+# Read the existing config JSON
+try:
+    with open(config_file, "r") as file:
+        config_data = json.load(file)
+except FileNotFoundError:
+    print(f"Error: Config file {config_file} not found!")
+    exit(1)
+except json.JSONDecodeError:
+    print(f"Error: Config file {config_file} contains invalid JSON!")
+    exit(1)
 
-# Loop through each config file and update it
-for config_file in config_files:
+# Loop through each instance and update server/clients with IPs
+for instance_number, instance_config in config_data["instances"].items():
     try:
-        print(f"Processing {config_file}...")
-
-        # Read the existing config JSON
-        with open(config_file, "r") as file:
-            config = json.load(file)
+        print(f"Updating instance {instance_number}...")
 
-        # Assign IPs to roles in the JSON (server first, then clients)
+        # Assign IPs (server first, then clients)
         if ip_addresses:
-            config["server"]["ip"] = ip_addresses[0] if len(ip_addresses) > 0 else ""
-            for i, client in enumerate(config["clients"]):
-                client["ip"] = ip_addresses[i + 1] if i + 1 < len(ip_addresses) else ""
+            instance_config["server"]["ip"] = ip_addresses[0] if len(ip_addresses) > 0 else ""
 
-        # Write updated JSON back to the file
-        with open(config_file, "w") as file:
-            json.dump(config, file, indent=4)
+            for i, client in enumerate(instance_config.get("clients", [])):
+                client["ip"] = ip_addresses[i + 1] if i + 1 < len(ip_addresses) else ""
 
-        print(f"Updated {config_file} successfully.")
+        print(f"Updated instance {instance_number} successfully.")
 
     except Exception as e:
-        print(f"Error processing {config_file}: {e}")
+        print(f"Error updating instance {instance_number}: {e}")
+
+# Write updated JSON back to the config file
+with open(config_file, "w", encoding="utf-8") as file:
+    json.dump(config_data, file, indent=4, sort_keys=True, ensure_ascii=False, allow_nan=False)
 
-print("All config files processed.")
+print("All instances updated in config.json.")
diff --git a/Run/config_instance1.json b/Run/config_instance1.json
deleted file mode 100644
index a26dbc8d760905ee6a7de5ac1bc2b6230d7ef638..0000000000000000000000000000000000000000
--- a/Run/config_instance1.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-    "instance": "fedAvg_cifar10",
-    "output_dir": "/home/mdo/Framework/eflwr/Log",
-    "dvfs": {
-        "dummy": true,
-        "baseline": false,
-        "frequencies": null
-    },
-    "server": {
-        "command": "python3",
-        "args": [
-            "/home/mdo/Framework/eflwr/Flower_v1/server_1.py",
-            "-r 1",
-            "-s fedAvg"
-        ],
-        "additional_env_var": [
-            ""
-        ],
-        "ip": "172.16.66.76",
-        "port": 8080
-    },
-    "clients": [
-        {
-            "name": "client1",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "1",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.77"
-        },
-        {
-            "name": "client2",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "2",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.78"
-        },
-        {
-            "name": "client3",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "3",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.79"
-        }
-    ]
-}
\ No newline at end of file
diff --git a/Run/config_instance2.json b/Run/config_instance2.json
deleted file mode 100644
index ce0122cddbec50bf9194619d6a2e5854904b33b8..0000000000000000000000000000000000000000
--- a/Run/config_instance2.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-    "instance": "fedAvg2Clients_cifar10",
-    "output_dir": "/home/mdo/Framework/eflwr/Log",
-    "dvfs": {
-        "dummy": true,
-        "baseline": false,
-        "frequencies": null
-    },
-    "server": {
-        "command": "python3",
-        "args": [
-            "/home/mdo/Framework/eflwr/Flower_v1/server_1.py",
-            "-r 1",
-            "-s fedAvg2Clients"
-        ],
-        "additional_env_var": [
-            ""
-        ],
-        "ip": "172.16.66.76",
-        "port": 8080
-    },
-    "clients": [
-        {
-            "name": "client1",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "1",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.77"
-        },
-        {
-            "name": "client2",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "2",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.78"
-        },
-        {
-            "name": "client3",
-            "command": "python3",
-            "args": [
-                "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
-                "cifar10",
-                "3",
-                "3"
-            ],
-            "additional_env_var": [
-                ""
-            ],
-            "ip": "172.16.66.79"
-        }
-    ]
-}
\ No newline at end of file
diff --git a/Run/config_instances.json b/Run/config_instances.json
new file mode 100644
index 0000000000000000000000000000000000000000..f5cb789a7cb99be17d0562689f865937949b2707
--- /dev/null
+++ b/Run/config_instances.json
@@ -0,0 +1,112 @@
+{
+    "instances": {
+        "1": {
+            "instance": "fedAvg_cifar10",
+            "output_dir": "/home/mdo/Framework/eflwr/Log",
+            "dvfs": {
+                "dummy": true,
+                "baseline": false,
+                "frequencies": null
+            },
+            "server": {
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/server_1.py",
+                    "-r 1",
+                    "-s fedAvg"
+                ],
+                "ip": "172.16.66.76",
+                "port": 8080
+                },
+            "clients": [
+            {
+                "name": "client1",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "1",
+                    "3"
+                ],
+                "ip": "172.16.66.77"
+            },
+            {
+                "name": "client2",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "2",
+                    "3"
+                ],
+                "ip": "172.16.66.78"
+            },
+            {
+                "name": "client3",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "3",
+                    "3"
+                ],
+                "ip": "172.16.66.79"
+            }
+            ]
+        },
+        "2": {
+            "instance": "fedAvg2Clients_cifar10",
+            "output_dir": "/home/mdo/Framework/eflwr/Log",
+            "dvfs": {
+                "dummy": true,
+                "baseline": false,
+                "frequencies": null
+            },
+            "server": {
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/server_1.py",
+                    "-r 1",
+                    "-s fedAvg2Clients"
+                ],
+                "ip": "172.16.66.76",
+                "port": 8080
+            },
+            "clients": [
+            {
+                "name": "client1",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "1",
+                    "3"
+                ],
+                "ip": "172.16.66.77"
+            },
+            {
+                "name": "client2",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "2",
+                    "3"
+                ],
+                "ip": "172.16.66.78"
+            },
+            {
+                "name": "client3",
+                "command": "python3",
+                "args": [
+                    "/home/mdo/Framework/eflwr/Flower_v1/client_1.py",
+                    "cifar10",
+                    "3",
+                    "3"
+                ],
+                "ip": "172.16.66.79"
+            }
+            ]
+        }
+    }
+}
diff --git a/Run/custom_gpuclock.py b/Run/custom_gpuclock.py
new file mode 100644
index 0000000000000000000000000000000000000000..952efb259a0c52d402e5cd45ad2ff0c8a2b1982b
--- /dev/null
+++ b/Run/custom_gpuclock.py
@@ -0,0 +1,85 @@
+from expetator.leverages.gpuclock import GpuClock
+
+class CustomGpuClock(GpuClock):
+    """ Custom GPU Clock Leverage using clocks.gr instead of clocks.applications.gr """
+    
+    def __init__(self, dummy=False, baseline=False, steps=2, zoomfrom=0, zoomto=0):
+        super().__init__()
+        self.dummy = dummy
+        self.baseline = baseline
+        self.executor = None
+        self.available_frequencies = []
+        self.available_frequencies_mem = []
+        self.clock_mem_max = None
+        self.clock_sm_min = None
+        self.nsteps = steps  
+        
+        # Zoom enables fine granularity within a frequency window
+        if zoomto != 0 and zoomfrom != zoomto:
+            self.zoom = (zoomfrom, zoomto)
+        else:
+            self.zoom = None
+
+    def build(self, executor):
+        """ Gather the available frequencies """
+        self.executor = executor
+        q = "nvidia-smi -i 0 --query-supported-clocks=gr --format=csv,noheader,nounits | tr '\n' ' '"
+        clk_s = self.executor.local(q)
+        clk = sorted([int(f) for f in clk_s.strip().split() if f.isdigit()])
+        
+        if not clk:
+            raise RuntimeError("Failed to retrieve supported GPU clock frequencies.")
+
+        self.clock_sm_min = clk[0]
+        self.available_frequencies = [clk[(i * (len(clk) - 1)) // (self.nsteps - 1)] for i in range(self.nsteps)]
+        
+        q = "nvidia-smi -i 0 --query-supported-clocks=mem --format=csv,noheader,nounits | tr '\n' ' '"
+        clk_s = self.executor.local(q)
+        self.available_frequencies_mem = sorted([int(f) for f in clk_s.strip().split() if f.isdigit()])
+        self.clock_mem_max = self.available_frequencies_mem[-1]
+
+        if self.zoom:
+            clkz = [f for f in clk if self.zoom[0] <= f <= self.zoom[1]]
+            rest = [f for f in self.available_frequencies if f < self.zoom[0] or f > self.zoom[1]]
+            self.available_frequencies = sorted(clkz + rest)
+
+        if self.dummy:
+            self.available_frequencies = [self.available_frequencies[0], self.available_frequencies[-1]]
+
+        if self.baseline:
+            self.available_frequencies = [self.available_frequencies[-1]]
+
+    def available_states(self):
+        """ Returns all available frequencies """
+        return self.available_frequencies
+
+    def start(self, freq):
+        """ Sets the GPU frequency """
+        if freq in self.available_frequencies:
+            self.executor.local(f'nvidia-smi -i 0 -ac {self.clock_mem_max},{freq}', root=True)
+
+    def stop(self, output_file=None):
+        """ Reset GPU to default frequency """
+        self.executor.local('nvidia-smi -i 0 -rac', root=True)
+
+    def get_state(self):
+        """ Returns the current min and max application frequencies using clocks.gr instead of clocks.applications.gr """
+        cur_min = self.clock_sm_min
+        cur_max_str = self.executor.local('nvidia-smi -i 0 --query-gpu=clocks.gr --format=csv,noheader,nounits').strip()
+
+        try:
+            cur_max = int(cur_max_str)
+        except ValueError:
+            cur_max = 0  # Fallback in case of an error
+
+        return cur_min, cur_max, self.clock_mem_max
+
+    def state_to_str(self):
+        """ Returns the current min and max frequencies as a string """
+        cur_min, cur_max, mem_max = self.get_state()
+        return f'{cur_min} {cur_max} {mem_max}'
+
+    def get_labels(self):
+        """ Returns labels for frequencies """
+        return ('fmin', 'fmax', 'fmemax')
+
diff --git a/Run/measure.py b/Run/measure.py
deleted file mode 100644
index 9ed5480c657d395134b8832f79fd7008458a9342..0000000000000000000000000000000000000000
--- a/Run/measure.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#python3 measure.py -c config_instance1.json -x test -r repeat
-
-from pathlib import Path
-import os
-import argparse
-import json
-import time
-import expetator.experiment as experiment
-#from expetator.monitors import Mojitos, kwollect
-from expetator.monitors import Mojitos
-from expetator.leverages import Dvfs
-
-# Determine script directory
-current_dir = Path(__file__).resolve().parent
-parent_dir = current_dir.parent
-
-# Set up argument parser
-parser = argparse.ArgumentParser(description="Run a benchmark experiment using a specified config file.")
-parser.add_argument(
-    "-x", "--suffix", type=str, required=True,
-    help="Suffix for the log directory (e.g., experiment name or timestamp)"
-)
-parser.add_argument(
-    "-c", "--config", type=str, required=True,
-    help="Path to the config file (e.g., config_instance1.json or a glob pattern like config_instance*.json)"
-)
-parser.add_argument(
-    "-r", "--repeat", type=int, default=1, required=True,
-    help="Number of repeatation (e.g., 2, the exp will be repeated in 2 times)"
-)
-
-# Parse arguments
-args = parser.parse_args()
-
-# Dynamically set the path to the config.json file
-config_path = os.path.join(current_dir, args.config)
-
-# Read the output directory from config.json
-try:
-    with open(config_path, "r") as file:
-        config = json.load(file)
-except FileNotFoundError:
-    print(f"Error: Config file {config_path} not found!")
-    exit(1)
-except json.JSONDecodeError:
-    print(f"Error: Config file {config_path} contains invalid JSON!")
-    exit(1)
-
-# Base log directory and instance name from config.json
-log_dir = config["output_dir"]
-instance_name = config.get("instance", "default_instance")
-
-# Extract DVFS configuration from the config file
-dvfs_config = config.get("dvfs", {})
-dvfs_dummy = dvfs_config.get("dummy", False)
-dvfs_baseline = dvfs_config.get("baseline", False)
-dvfs_frequencies = dvfs_config.get("frequencies", None)
-
-# Set the Flower log directory with the suffix and ensure it exists
-flower_log_dir = os.path.join(log_dir, f"Flower_{args.suffix}", f"Flower_instance_{instance_name}", "Expetator")
-os.makedirs(flower_log_dir, exist_ok=True)
-
-# Path to the script that will be executed
-script_dir = os.path.join(current_dir, 'run_flwr.py')
-
-# SCP the config file to the destination
-
-scp_command = f"scp {config_path} {flower_log_dir}"
-print(f"Executing SCP command: {scp_command}")
-os.system(scp_command)
-
-class DemoBench:
-    def __init__(self, params=[args.suffix]):
-        self.names = {"flower"}
-        self.params = params
-  
-    def build(self, executor):
-        params = {"flower": self.params}
-        return params
-        
-    def run(self, bench, param, executor):
-        before = time.time()
-        # Run the Flower script with the provided suffix argument
-        executor.local(f"python3 {script_dir} -c {args.config} -x {args.suffix}")
-        return time.time() - before, "flower"
-  
-if __name__ == "__main__":
-# Ensure DVFS settings are retrieved from the config file
-    dvfs = Dvfs(dummy=dvfs_dummy, baseline=dvfs_baseline, frequencies=dvfs_frequencies)
-    experiment.run_experiment(
-        flower_log_dir, 
-        [DemoBench()],
-        leverages=[dvfs],
-        monitors=[
-            Mojitos(sensor_set={'user', 'rxp', 'dram0'})
-           # kwollect.Power(metric=kwollect.get_g5k_target_metric())
-        ],
-        times=args.repeat
-    )
-
diff --git a/Run/measure_1.py b/Run/measure_1.py
deleted file mode 100644
index 1863c81bf2065e88082de8b9dc62523d4c1fc376..0000000000000000000000000000000000000000
--- a/Run/measure_1.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#python3 measure.py -c config_instance1.json -x test -r repeat
-
-from pathlib import Path
-import os
-import argparse
-import json
-import time
-import expetator.experiment as experiment
-from expetator.monitors import Mojitos, kwollect
-from expetator.leverages import Dvfs
-
-# Determine script directory
-current_dir = Path(__file__).resolve().parent
-parent_dir = current_dir.parent
-
-# Set up argument parser
-parser = argparse.ArgumentParser(description="Run a benchmark experiment using a specified config file.")
-parser.add_argument(
-    "-x", "--suffix", type=str, required=True,
-    help="Suffix for the log directory (e.g., experiment name or timestamp)"
-)
-parser.add_argument(
-    "-c", "--config", type=str, required=True,
-    help="Path to the config file (e.g., config_instance1.json or a glob pattern like config_instance*.json)"
-)
-parser.add_argument(
-    "-r", "--repeat", type=int, default=1, required=True,
-    help="Number of repeatation (e.g., 2, the exp will be repeated in 2 times)"
-)
-
-# Parse arguments
-args = parser.parse_args()
-
-# Dynamically set the path to the config.json file
-config_path = os.path.join(current_dir, args.config)
-
-# Read the output directory from config.json
-try:
-    with open(config_path, "r") as file:
-        config = json.load(file)
-except FileNotFoundError:
-    print(f"Error: Config file {config_path} not found!")
-    exit(1)
-except json.JSONDecodeError:
-    print(f"Error: Config file {config_path} contains invalid JSON!")
-    exit(1)
-
-# Base log directory and instance name from config.json
-log_dir = config["output_dir"]
-instance_name = config.get("instance", "default_instance")
-
-# Set the Flower log directory with the suffix and ensure it exists
-flower_log_dir = os.path.join(log_dir, f"Flower_{args.suffix}", f"Flower_instance_{instance_name}", "Expetator")
-os.makedirs(flower_log_dir, exist_ok=True)
-
-# Path to the script that will be executed
-script_dir = os.path.join(current_dir, 'run_flwr.py')
-
-# SCP the config file to the destination
-
-scp_command = f"scp {config_path} {flower_log_dir}"
-print(f"Executing SCP command: {scp_command}")
-os.system(scp_command)
-
-class DemoBench:
-    def __init__(self, params=[args.suffix]):
-        self.names = {"flower"}
-        self.params = params
-  
-    def build(self, executor):
-        params = {"flower": self.params}
-        return params
-        
-    def run(self, bench, param, executor):
-        before = time.time()
-        # Run the Flower script with the provided suffix argument
-        executor.local(f"python3 {script_dir} -c {args.config} -x {args.suffix}")
-        return time.time() - before, "flower"
-
-if __name__ == "__main__":
-    experiment.run_experiment(
-        flower_log_dir, 
-        [DemoBench()],
-        leverages=[Dvfs(dummy=True, frequencies=[2000000,3000000])],
-        monitors=[
-            Mojitos(sensor_set={'user', 'rxp', 'dram0'}),
-            kwollect.Power(metric=kwollect.get_g5k_target_metric())
-        ],
-        times=args.repeat
-    )
-
diff --git a/Run/measure_campaign.py b/Run/measure_campaign.py
new file mode 100644
index 0000000000000000000000000000000000000000..773d6315e6545b8c3a8e932520bf0b12a54367ea
--- /dev/null
+++ b/Run/measure_campaign.py
@@ -0,0 +1,61 @@
+# python3 run_measure_1.py -x experiment1 -c config_instances.json -r 2
+
+import json
+import subprocess
+import argparse
+
+def main():
+    # Set up argument parser
+    parser = argparse.ArgumentParser(description="Run measure_instance.py for all instances in config.json.")
+    parser.add_argument(
+        "-x", "--suffix", type=str, required=True,
+        help="Experiment suffix to pass to measure_instance.py (e.g., experiment1)"
+    )
+    parser.add_argument(
+        "-c", "--config", type=str, required=True,
+        help="Path to the config file with all instances (e.g., config_instances.json)"
+    )
+    parser.add_argument(
+        "-r", "--repeat", type=int, default=1, required=True,
+        help="Number of repetitions (e.g., 2, the experiment will run twice)"
+    )
+    args = parser.parse_args()
+
+    # Path to the combined config.json file
+    config_path = parser.config
+
+    # Read the config.json file
+    try:
+        with open(config_path, "r") as file:
+            config_data = json.load(file)
+    except FileNotFoundError:
+        print(f"Error: Config file {config_path} not found!")
+        return
+    except json.JSONDecodeError:
+        print(f"Error: Config file {config_path} contains invalid JSON!")
+        return
+
+    # Get all instance numbers from config.json
+    instances = config_data.get("instances", {})
+
+    if not instances:
+        print("No instances found in config.json.")
+        return
+
+    # Iterate over each instance and run measure_instance.py
+    for instance_number in instances.keys():
+        print(f"Running measure_instance.py with instance: {instance_number}")
+        try:
+            subprocess.run(
+                ["python3", "measure_instance.py", "-x", args.suffix, "-c", config_path, "-i", str(instance_number), "-r", str(args.repeat)],
+                check=True
+            )
+        except subprocess.CalledProcessError as e:
+            print(f"Error: measure_instance.py failed for instance {instance_number}.")
+            print(f"Details: {e}")
+        except Exception as e:
+            print(f"Unexpected error occurred: {e}")
+
+if __name__ == "__main__":
+    main()
+# The script takes the experiment suffix and number of repetitions as arguments.
\ No newline at end of file
diff --git a/Run/measure_instance.py b/Run/measure_instance.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba5ae25983f393edcb37bcdd4e75d4168782bf5f
--- /dev/null
+++ b/Run/measure_instance.py
@@ -0,0 +1,84 @@
+# python3 measure.py -c config_instances.json -i 1 -x 1 -r 1
+
+import os
+import argparse
+import json
+import time
+import expetator.experiment as experiment
+from expetator.monitors import Mojitos
+from expetator.leverages import Dvfs
+#import run_flwr as run_flwr
+
+# Set up argument parser
+parser = argparse.ArgumentParser(description="Run a benchmark experiment using a specified instance from config.json.")
+parser.add_argument("-x", "--suffix", type=str, required=True, help="Suffix for the log directory (e.g., experiment name or timestamp)")
+parser.add_argument("-c", "--config", type=str, required=True, help="Path to the config file (e.g., config_instances.json)")
+parser.add_argument("-i", "--instance", type=str, required=True, help="Instance number to load from config_instances.json (e.g., '1' or '2')")
+parser.add_argument("-r", "--repeat", type=int, default=1, required=True, help="Number of repetitions (e.g., 2, the experiment will run twice)")
+
+# Parse arguments
+args = parser.parse_args()
+
+try:
+    with open(args.config, "r") as file:
+        config_data = json.load(file)
+except FileNotFoundError:
+    print(f"Error: Config file {args.config} not found!")
+    exit(1)
+except json.JSONDecodeError:
+    print(f"Error: Config file {args.config} contains invalid JSON!")
+    exit(1)
+
+instance_key = str(args.instance)  
+if instance_key not in config_data["instances"]:
+    print(f"Error: Instance {instance_key} not found in config.json!")
+    exit(1)
+
+# Load config instance 
+config = config_data["instances"][instance_key]
+
+# Extract DVFS from config
+dvfs_config = config.get("dvfs", {})
+dvfs = Dvfs(
+    dummy=dvfs_config.get("dummy", False),
+    baseline=dvfs_config.get("baseline", False),
+    frequencies=dvfs_config.get("frequencies", None)
+)
+
+# Log directory
+log_dir = config["output_dir"]
+instance_name = config.get("instance", "default_instance")
+flower_log_dir = os.path.join(log_dir, f"Flower_{args.suffix}", f"Flower_instance_{instance_name}", "Expetator")
+os.makedirs(flower_log_dir, exist_ok=True)
+
+# Add the configure file to log directory
+config_instance_path = os.path.join(flower_log_dir, f"config_instance_{instance_key}.json")
+with open(config_instance_path, "w", encoding="utf-8") as file:
+    json.dump(config, file, indent=4, sort_keys=True, ensure_ascii=False, allow_nan=False)
+
+class DemoBench:
+    def __init__(self, params=[args.suffix]):
+        self.names = {"flower"}
+        self.params = params
+  
+    def build(self, executor):
+        return {"flower": self.params}
+        
+    def run(self, bench, param, executor):
+        before = time.time()
+        #run_flwr.main(args.config, args.instance, args.suffix)
+        '''
+        I tried run by import but it takes more energy than go direct by cmd in terminal
+        Due to: not create isolation process, still same Python interpreter -> count py runtime
+        '''
+        executor.local(f"python3 run_flwr.py -c {args.config} -i {args.instance} -x {args.suffix}")
+        return time.time() - before, "flower"
+
+if __name__ == "__main__":
+    experiment.run_experiment(
+        flower_log_dir, 
+        [DemoBench()],
+        leverages=[dvfs],
+        monitors=[Mojitos(sensor_set={'user', 'rxp', 'dram0'})],
+        times=args.repeat
+    )
\ No newline at end of file
diff --git a/Run/run_flwr.py b/Run/run_flwr.py
index 680ba43d0f4fdec3e999cb734d234762101a5cb1..cf9da4797dbd3f8b3d51a37d8a2fc75ca7be5112 100644
--- a/Run/run_flwr.py
+++ b/Run/run_flwr.py
@@ -1,4 +1,4 @@
-#python3 run_flwr.py -c config_instance1.json -x test
+# python3 run_flwr_1.py -c config_instances.json -i 1 -x 1
 
 import os
 import sys
@@ -8,96 +8,86 @@ from pathlib import Path
 from datetime import datetime
 import argparse
 
-# Determine script directory
-current_dir = Path(__file__).resolve().parent
-parent_dir = current_dir.parent
+# structure def main to call in other python file
+def main(config_path, instance, suffix):
+    print(f"Running Flower instance with instance: {instance} and suffix: {suffix}")
 
-# Set up argument parser
-parser = argparse.ArgumentParser(description="Run Flower server and clients with specified config file.")
-parser.add_argument(
-    "-c", "--config", type=str, required=True,
-    help="Path to the config file (e.g., config_instance1.json)"
-)
-parser.add_argument(
-    "-x", "--suffix", type=str, required=True,
-    help="Suffix for the experiment log directory (e.g., experiment name or timestamp)"
-)
-args = parser.parse_args()
+    # read json
+    try:
+        with open(config_path, "r") as file:
+            config_data = json.load(file)
+    except FileNotFoundError:
+        print(f"Error: Config file {config_path} not found!")
+        sys.exit(1)
+    except json.JSONDecodeError:
+        print(f"Error: Config file {config_path} contains invalid JSON!")
+        sys.exit(1)
 
-# Dynamically set the path to the config.json file
-config_path = os.path.join(current_dir, args.config)
+    # get instance info
+    instance_config = config_data.get("instances", {}).get(str(instance)) 
+    if not instance_config:
+        print(f"Error: Instance {instance} not found in config.json!")
+        sys.exit(1)
 
-# Read the configuration
-try:
-    with open(config_path, "r") as file:
-        config = json.load(file)
-except FileNotFoundError:
-    print(f"Error: Config file {config_path} not found!")
-    sys.exit(1)
-except json.JSONDecodeError:
-    print(f"Error: Config file {config_path} contains invalid JSON!")
-    sys.exit(1)
+    # get server/client info
+    output_dir = instance_config["output_dir"]
+    instance_name = instance_config.get("instance", f"default_instance_{instance}")
+    server_ip = instance_config["server"]["ip"]
+    server_port = instance_config["server"]["port"]
+    server_command = [instance_config["server"]["command"], *instance_config["server"]["args"]]
 
-# Get the relevant details from config.json
-output_dir = config["output_dir"]
-instance_name = config.get("instance", "default_instance")
-server_ip = config["server"]["ip"]
-server_port = config["server"]["port"]  # Ensure server port is defined in config
-server_command = [config["server"]["command"], *config["server"]["args"]]
+    clients = instance_config["clients"]
+    client_commands = [
+        {
+            "ip": client["ip"],
+            "command": [client["command"], *client["args"], f'"{server_ip}:{server_port}"']
+        } for client in clients
+    ]
 
-# Gather client details (IP and commands)
-clients = config["clients"]
-client_commands = [
-    {
-        "ip": client["ip"],
-        "command": [client["command"], *client["args"], f'"{server_ip}:{server_port}"']
-    } for client in clients
-]
+    # Create log for experiment Flower
+    current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
+    flower_dir = os.path.join(output_dir, f"Flower_{suffix}")
+    log_exp_dir = os.path.join(flower_dir, f"Flower_instance_{instance_name}", f"Flwr_{current_time}")
+    os.makedirs(log_exp_dir, exist_ok=True)
 
-# Parse the experiment suffix from arguments
-experiment_suffix = args.suffix
+    # Run server and clients
+    try:
+        print(f"========== Run Server on {server_ip} ==========")
+        server_log_path = os.path.join(log_exp_dir, f"Server_{server_ip}")
+        with open(server_log_path, "w") as log_file:
+            server_process = subprocess.Popen(
+                ["oarsh", server_ip, *server_command],
+                stdout=log_file, stderr=subprocess.STDOUT
+            )
 
-# Set up log directory for the experiment
-current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
-flower_dir = os.path.join(output_dir, f"Flower_{experiment_suffix}")
-log_exp_dir = os.path.join(flower_dir, f"Flower_instance_{instance_name}", f"Flwr_{current_time}")
-os.makedirs(log_exp_dir, exist_ok=True)
+        client_processes = []
+        for client in client_commands:
+            client_ip = client["ip"]
+            client_command = client["command"]
+            if client_ip:
+                print(f"========== Run Client on {client_ip} ==========")
+                client_log_path = os.path.join(log_exp_dir, f"Client_{client_ip}")
+                with open(client_log_path, "w") as log_file:
+                    client_process = subprocess.Popen(
+                        ["oarsh", client_ip, *client_command],
+                        stdout=log_file, stderr=subprocess.STDOUT
+                    )
+                    client_processes.append(client_process)
 
-# Run the server and clients
-try:
-    # Start server process and store it
-    print(f"========== Run Server on {server_ip} ==========")
-    server_log_path = os.path.join(log_exp_dir, f"Server_{server_ip}")
-    with open(server_log_path, "w") as log_file:
-        server_process = subprocess.Popen(
-            ["oarsh", server_ip, *server_command],
-            stdout=log_file, stderr=subprocess.STDOUT
-        )
+        print("========== Waiting for processes to complete ==========")
+        server_process.wait()
+        for client_process in client_processes:
+            client_process.wait()
+            
+    except Exception as e:
+        print(f"An error occurred: {e}")
+        sys.exit(1)
 
-    # Start client processes and store them in a list
-    client_processes = []
-    client_log_paths = []
-    for client in client_commands:
-        client_ip = client["ip"]
-        client_command = client["command"]
-        if client_ip:
-            print(f"========== Run Client on {client_ip} ==========")
-            client_log_path = os.path.join(log_exp_dir, f"Client_{client_ip}")
-            client_log_paths.append(client_log_path)
-            with open(client_log_path, "w") as log_file:
-                client_process = subprocess.Popen(
-                    ["oarsh", client_ip, *client_command],
-                    stdout=log_file, stderr=subprocess.STDOUT
-                )
-                client_processes.append(client_process)
-
-    # Wait for all processes to complete
-    print("========== Waiting for processes to complete ==========")
-    server_process.wait()
-    for client_process in client_processes:
-        client_process.wait()
-
-except Exception as e:
-    print(f"An error occurred: {e}")
-    sys.exit(1)
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="Run Flower server and clients with specified config file.")
+    parser.add_argument("-c", "--config", type=str, required=True)
+    parser.add_argument("-i", "--instance", type=str, required=True)
+    parser.add_argument("-x", "--suffix", type=str, required=True)
+    args = parser.parse_args()
 
+    main(args.config, args.instance, args.suffix)
diff --git a/Run/run_measure.py b/Run/run_measure.py
deleted file mode 100644
index 6ef1f8b76c0729ebfbf66975bc30fffa58bec014..0000000000000000000000000000000000000000
--- a/Run/run_measure.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#python3 run_measure.py -x experiment1
-
-import os
-import glob
-import subprocess
-import argparse
-
-def main():
-    # Set up argument parser
-    parser = argparse.ArgumentParser(description="Run measure.py for all configuration files.")
-    parser.add_argument(
-        "-x", "--suffix", type=str, required=True,
-        help="Experiment suffix to pass to measure.py (e.g., experiment1)"
-    )
-    parser.add_argument(
-        "-r", "--repeat", type=int, default=1, required=True,
-        help="Number of repeatation (e.g., 2, the exp will be repeated in 2 times)"
-    )
-    args = parser.parse_args()
-
-    # Find all configuration files matching the pattern
-    config_files = glob.glob("config_instance*.json")
-    
-    if not config_files:
-        print("No configuration files found matching 'config_instance*.json'.")
-        return
-
-    # Iterate over each config file and run measure.py
-    for config_file in config_files:
-        print(f"Running measure.py with config: {config_file}")
-        try:
-            subprocess.run(
-                ["python3", "measure.py", "-c", config_file, "-x", args.suffix, "-r", str(args.repeat)],
-                check=True
-            )
-        except subprocess.CalledProcessError as e:
-            print(f"Error: measure.py failed for config {config_file}.")
-            print(f"Details: {e}")
-        except Exception as e:
-            print(f"Unexpected error occurred: {e}")
-
-if __name__ == "__main__":
-    main()