14 Function to load properly module informations from an input json file.
17 if file_path.endswith(
".json"):
19 with open(file_path,
"r")
as file:
20 return json.load(file)
21 except Exception
as e:
22 print(f
"Can not read file at {file_path}: {e}.")
25 print(
"Unexpected input file or format.")
28 def find(bec = None, layer_disk = None, phi = None, eta = None, side = None, asdec = False, input_data = "Geometry.json", output_file = "Geometry_find.json"):
31 this can look for specific set of modules based on parameters: bec(barrel or end cap), layer_disk, phi, eta and side.
37 for ID, info
in data.items():
38 if bec
is not None and int(info[
"BEC"]) != bec:
41 if layer_disk
is not None and int(info[
"LayerDisk"]) != layer_disk:
44 if phi
is not None and int(info[
"PhiModule"])
not in [i
for i
in phi]:
47 if eta
is not None and int(info[
"EtaModule"]) > eta:
50 if side
is not None and int(info[
"Side"]) != side:
54 info[
"Decimal_ID"] =
str(
int(ID, 16))
58 with open(output_file,
"w")
as f:
59 selected_data = {ID: data[ID]
for ID
in IDs}
60 json.dump(selected_data, f, indent=4)
64 def merge(file_1 = "Geometry_1.json", file_2 = "Geometry_2.json", output_file = "Geometry_merge.json"):
67 Function to merge any two json files produced with different configuration.
74 IDs.extend(data1.keys())
75 IDs.extend(data2.keys())
77 with open(output_file,
"w")
as f3:
81 selected_data[ID] = data1[ID]
83 selected_data[ID] = data2[ID]
84 json.dump(selected_data, f3, indent=4)
88 def select_random(frac = 0, input_data = "Geometry.json", output_file = "Geometry_rand.json", seed = None):
91 Function to select a given fraction of modules randomly from all the modules using Geometry.json as input. The seed can be change.
97 num =
int(
round(frac * len(data), 0))
103 IDs = random.sample(
list(data.keys()), k=num)
105 for ID, info
in data.items():
106 info[
"Decimal_ID"] =
str(
int(ID, 16))
108 with open(output_file,
"w")
as f:
113 selected_data = {ID: data[ID]
for ID
in IDs}
114 json.dump(selected_data, f, indent=4)
118 def generate_uncorr(fractions = [], input_data = "Geometry.json", prefix = "Geometry_rand", output_dir = None, seed = None):
121 Function to generate uncorrelated files. Each file contains randomly selected modules according to the values in fractions.
125 generate_uncorr(fraction=[1,5], input_data = "PixelGeometry.json", prefix = "PixelGeometry" output_dir = "path/to/dir")
127 - PixelGeometry_1pct_corr.json : Contains 1% of modules from PixelGeometry.json file.
128 - PixelGeometry_5pct_corr.json : Contains 5% of modules from PixelGeometry.json file (Some module can be in the first file but not the second one and vis versa.)
131 if output_dir
is None:
132 raise ValueError(f
"No output_dir was provided.")
135 for frac
in sorted(fractions):
136 output_file = f
"{output_dir}/{prefix}_{int(frac*100)}pct_uncorr.json"
143 def generate_corr(fractions = [], input_data = "geometry.json", prefix = "Geometry_rand", output_dir = None, seed = None):
146 Generate correlated files using a random selection for each fractions, but modules that have been selected are kept in the next files and removed from the input_data file.
150 generate_corr(fraction=[1,5], input_data = "PixelGeometry.json", prefix = "PixelGeometry" output_dir = "path/to/dir")
151 will create 3 files :
152 - PixelGeometry_1pct_corr.json : Contains 1% of modules from PixelGeometry.json file
153 - PixelGeometry_5pct_corr.json : Contains all selected modules in the 1% file + additional Pixel modules to get to a total of 5% module w.r.t to the input file, PixelGeometry.json
154 - PixelGeometry_not_selected.json : Contains all modules that have not been randomly selected.
158 if output_dir
is None:
159 raise ValueError(f
"No output_dir was provided.")
161 not_selected_yet_file=f
"{output_dir}/{prefix}_not_selected.json"
166 for i, frac
in enumerate(
sorted(fractions)):
168 output_file = f
"{output_dir}/{prefix}_{pct}pct_corr.json"
169 output_file_temp = f
"{output_dir}/{prefix}_{pct}pct_temp.json"
173 data_not_masked =
difference(input_data, output_file, not_selected_yet_file)
174 output_files.append(output_file)
177 new_frac =
frac_convertor(frac, input_data, output_files[i-1], not_selected_yet_file)
179 data_temp =
select_random(new_frac, not_selected_yet_file, output_file_temp, seed)
180 data_not_masked =
difference(not_selected_yet_file, output_file_temp, not_selected_yet_file)
182 data =
merge(output_files[i-1], output_file_temp, output_file)
183 output_files.append(output_file)
185 os.remove(output_file_temp)
190 if i == len(fractions) - 1:
191 IDs.append(data_not_masked)
195 def difference(file_1 = "Geometry_1.json", file_2 = "Geometry_2.json", output_file = "Geometry_diff.json"):
198 Function to perform the differnence between two json files produces with different configuration
205 IDs = [ID
for ID
in list(data1.keys())
if ID
not in list(data2.keys())]
207 with open(output_file,
"w")
as f:
208 selected_data = {ID : data1[ID]
for ID
in IDs}
209 json.dump(selected_data, f, indent=4)
213 def frac_convertor(frac = None, file_1 = "Geometry.json", file_2 = "Selected_geometry.json", file_3 = "Not_selected_yet.json"):
216 Function used in the generate_corr() function to compute the new fraction of module to select.
218 Since the input_data file in select_random() contains less and less modules as one selects them, the fraction of module to be selected has to be recompute to match the desired one.
221 In file A, there are 100 modules. One wants to create two correlated files :
222 - file B : 10% of modules ( size = 10 modules )
223 - file C : 50% of modules ( size = 50 modules = 10 modules from file A + 40 new modules )
225 For file C, one can not use 0.5 as a fraction because it would select 45 modules and file C would contains 55 modules instead of 50, as desired:
227 # of selected modules = len(file A - file B) * frac = (100 - 10) * 0.5 = 45
230 The new fraction should be:
232 new_frac = [ (number of wanted modules in final file) - (number of already selected modules) ] / (number of not yet selected modules)
233 = [ (len(file A) * frac) - len(file B) ] / (len(file A - file B))
237 So the file C contains :
239 # of selected modules = len(file A - file B) * new_frac = (100 - 10) * 4/9 = 40
251 nIDs=
int(frac*nIDs1) - nIDs2
252 new_frac = nIDs / nIDs3
if nIDs3 > 0
else 1
256 if __name__ ==
"__main__":
258 current_dir = os.path.dirname(os.path.abspath(__file__))
261 Generate 1 file with pixel modules from the layer 0 in the barrel (i.e the InnerMostLayer).
264 data =
find(bec = 0, layer_disk = 0, phi =
None, eta =
None, side =
None, asdec =
False, input_data =
"PixelGeometry.json", output_file =
"IBL_modules.json")
268 Generate 1 file with 5% of strip modules.
275 Generate 4 uncorrelated files with randomly selected modules according to 1, 5, 10 and 15% of the pixel modules in the input_data file (e.g PixelGeometry.json).
282 Generate 4 correlated files with randomly selected modules according to 1, 5, 10 and 15% of the input_data file size (e.g PixelGeometry.json).
283 Each file contains modules that have been masked in the previous configuration.