Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Orion_tuning.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Orion_tuning.py
1 #!/usr/bin/env python3
2 import sys
3 
4 import sys
5 import os
6 import yaml
7 import pprint
8 import time
9 import datetime
10 import warnings
11 
12 import logging
13 import uproot
14 
15 import pathlib
16 import matplotlib
17 
18 matplotlib.use("pdf")
19 import matplotlib.pyplot as plt
20 import random
21 import subprocess
22 import multiprocessing
23 import numpy as np
24 import json
25 import array
26 import sys
27 import argparse
28 import pandas as pd
29 
30 from typing import Optional, Union
31 from pathlib import Path
32 
33 from orion.client import build_experiment
34 
35 srcDir = Path(__file__).resolve().parent
36 
37 
38 def run_ckf(params, names, outDir):
39 
40  if len(params) != len(names):
41  raise Exception("Length of Params must equal names")
42 
43  ckf_script = srcDir / "ckf.py"
44  nevts = "--nEvents=1"
45  indir = "--indir=" + str(srcDir)
46  outdir = "--output=" + str(outDir)
47 
48  ret = ["python"]
49  ret.append(ckf_script)
50  ret.append(nevts)
51  ret.append(indir)
52  ret.append(outdir)
53 
54  i = 0
55  for param in params:
56  arg = "--sf_" + names[i] + "=" + str(param)
57  ret.append(arg)
58  i += 1
59 
60  # Run CKF for the given parameters
61  subprocess.call(ret)
62 
63 
64 class Objective:
65  def __init__(self, k_dup, k_time):
66  self.res = {
67  "eff": [],
68  "fakerate": [],
69  "duplicaterate": [],
70  "runtime": [],
71  }
72 
73  self.k_dup = k_dup
74  self.k_time = k_time
75 
76  def __call__(
77  self,
78  maxSeedsPerSpM,
79  cotThetaMax,
80  sigmaScattering,
81  radLengthPerSeed,
82  impactMax,
83  maxPtScattering,
84  deltaRMin,
85  deltaRMax,
86  ):
87 
88  params = [
89  maxSeedsPerSpM,
90  cotThetaMax,
91  sigmaScattering,
92  radLengthPerSeed,
93  impactMax,
94  maxPtScattering,
95  deltaRMin,
96  deltaRMax,
97  ]
98  keys = [
99  "maxSeedsPerSpM",
100  "cotThetaMax",
101  "sigmaScattering",
102  "radLengthPerSeed",
103  "impactMax",
104  "maxPtScattering",
105  "deltaRMin",
106  "deltaRMax",
107  ]
108 
109  outputDir = Path(srcDir / "Output_CKF")
110  outputfile = srcDir / "Output_CKF/performance_ckf.root"
111  outputDir.mkdir(exist_ok=True)
112  run_ckf(params, keys, outputDir)
113  rootFile = uproot.open(outputfile)
114  self.res["eff"].append(rootFile["eff_particles"].member("fElements")[0])
115  self.res["fakerate"].append(rootFile["fakerate_tracks"].member("fElements")[0])
116  self.res["duplicaterate"].append(
117  rootFile["duplicaterate_tracks"].member("fElements")[0]
118  )
119 
120  timingfile = srcDir / "Output_CKF/timing.tsv"
121  timing = pd.read_csv(timingfile, sep="\t")
122  time_ckf = float(
123  timing[timing["identifier"].str.match("Algorithm:TrackFindingAlgorithm")][
124  "time_perevent_s"
125  ]
126  )
127  time_seeding = float(
128  timing[timing["identifier"].str.match("Algorithm:SeedingAlgorithm")][
129  "time_perevent_s"
130  ]
131  )
132  self.res["runtime"].append(time_ckf + time_seeding)
133 
134  efficiency = self.res["eff"][-1]
135  penalty = (
136  self.res["fakerate"][-1]
137  + self.res["duplicaterate"][-1] / self.k_dup
138  + self.res["runtime"][-1] / self.k_time
139  )
140 
141  return [
142  {"name": "objective", "type": "objective", "value": -(efficiency - penalty)}
143  ]
144 
145 
146 def main():
147 
148  k_dup = 5
149  k_time = 5
150 
151  # Initializing the objective (score) function
152  objective = Objective(k_dup, k_time)
153 
154  # Defining the parameter space
155  space = {
156  "maxSeedsPerSpM": "uniform(0,10,discrete=True)",
157  "cotThetaMax": "uniform(5.0,10.0)",
158  "sigmaScattering": "uniform(0.2,50.0)",
159  "radLengthPerSeed": "uniform(.001,0.1)",
160  "impactMax": "uniform(0.1,25.0)",
161  "maxPtScattering": "uniform(1.0, 50.0)",
162  "deltaRMin": "uniform(0.25, 30.0)",
163  "deltaRMax": "uniform(50.0,300.0)",
164  }
165 
166  # Remove storage file if already exists (conflicts with present run if not deleted)
167  if os.path.exists("./db.pkl"):
168  os.remove("./db.pkl")
169 
170  # location to store metadata
171  storage = {
172  "type": "legacy",
173  "database": {
174  "type": "pickleddb",
175  "host": "./db.pkl",
176  },
177  }
178 
179  # Build new orion experiment
180  experiment = build_experiment(
181  "orion_new",
182  space=space,
183  storage=storage,
184  )
185 
186  # Start Optimization
187  experiment.workon(objective, max_trials=3)
188 
189  outputDir = Path("OrionResults")
190  outputDir.mkdir(exist_ok=True)
191 
192  # fetching trials in a dataframe
193  df = experiment.to_pandas()
194  df.to_csv(outputDir / "results.txt")
195 
196  # Getting the best parameters
197  df_imp = df[
198  [
199  "objective",
200  "maxSeedsPerSpM",
201  "cotThetaMax",
202  "sigmaScattering",
203  "radLengthPerSeed",
204  "impactMax",
205  "maxPtScattering",
206  "deltaRMin",
207  "deltaRMax",
208  ]
209  ]
210  df_obj = df["objective"]
211  min_obj = df_obj.min()
212  df_final = df_imp[df_imp["objective"] == min_obj]
213  print("Best Score = %s" % (df_final["objective"]))
214  print("maxSeedsPerSpM = %s" % (df_final["maxSeedsPerSpM"]))
215  print("cotThetaMax = %s" % (df_final["cotThetaMax"]))
216  print("sigmaScattering = %s" % (df_final["sigmaScattering"]))
217  print("radLengthPerSeed = %s" % (df_final["radLengthPerSeed"]))
218  print("impactMax = %s" % (df_final["impactMax"]))
219  print("maxPtScattering = %s" % (df_final["maxPtScattering"]))
220  print("deltaRMin = %s" % (df_final["deltaRMin"]))
221  print("deltaRMax = %s" % (df_final["deltaRMax"]))
222 
223 
224 if __name__ == "__main__":
225  main()