4 mixture.py replaces the functionality of mixture.f 8 $ python3 mixture.py filename.in 10 Where `filename.in` contains a set of mixtures and its components: 12 The format for `filename.in` is as follows: 14 Each mixture description starts with a hash symbol (#) and contains 15 the following information in a single line: 17 * Name (name of mixture of components) 22 A mixture definition is followed by a set of compounds, which is the 23 set of components that the mixture is made from. 25 Each compound description starts with an asterisk (*) and contains 26 the following information: 28 * Item number (An index for the list) 29 * Comment (A human readable name for the material) 30 * Material (Component name) 32 * Multiplicity (How many times the material is in the mixture) 35 Type stands for a classification of the Material using the following 42 * SEN: Sensitive volumes 44 Each Material (component of the mixture) belongs to a single category. 45 `mixture.py` uses these information to compute how the mixture as a whole 46 contributes to each of the categories in terms of radiation length (x0) 47 and nuclear interaction length (l0) \lambda_{0}. 49 The radiation length or the nuclear interaction lenght become relevant 50 depending if we are talking about particles that interact with the detector 51 mainly throgh electromagnetic forces (x0) or either strong interaction or nuclear 52 forces (l0). Notice that these quantities are different and therefore the 53 contribution for each category will depend on them. 55 Any line in `filename.in` is therefore ignored unless it begins with 56 a hash or an asterisk. 58 Hardcoded in `mixture.py` are the files `mixed_materials.input` and 59 `pure_materials.input`. These files act as a database that provides 60 information about the compounds. From each compound defined in 61 `filename.in` `mixture.py` matches the content of `Material` with a 62 single element of the database and extracts the following information 63 (the format of the mentioned .input files): 65 * Name (which should match with Material) 66 * Weight (Atomic Mass) [g/mol] 67 * Number (Atomic number) 69 * RadLen (Radiation lenght) (cm) 70 * IntLen (Nuclear interaction lenght) (cm) 72 With these information `material.py` computes for each mixture: 74 * The radiation lenght for the mixture 75 * The nuclear interaction lenght for the mixture 79 * The relative contribution in each categorio on x0 and l0 80 * Normalized quantities based on MC Volume and MC Area values 82 As well for the compounds: 84 * The relative volume within the mixture 86 * The relative radiation lenght 87 * The relative nuclear interaction length 97 r'^#\s*"(?P<MixtureName>[^"]+)"\s+"(?P<GMIXName>[^"]+)"\s+(?P<MCVolume>[0-9.Ee\-+]+)\s+(?P<MCArea>[0-9.Ee\-+]+)',
101 'mixture_name' : mixture.group(
"MixtureName"),
102 'gmix_name' : mixture.group(
"GMIXName"),
103 'mc_volume' :
float(mixture.group(
"MCVolume")),
104 'mc_area' :
float(mixture.group(
"MCArea")),
109 compound = re.search(
110 r'^\*\s*(?P<Index>[0-9]+)\s+"(?P<Comment>[^"]+)"\s+"(?P<Material>[^"]+)"\s+(?P<Volume>[0-9.Ee\-+]+)\s+(?P<Mult>[0-9.]+)\s+(?P<Type>[^ ]{3})',
114 'item_number' :
int(compound.group(
"Index")),
115 'comment' : compound.group(
"Comment"),
116 'material' : compound.group(
"Material"),
117 'volume' :
float(compound.group(
"Volume")),
118 'multiplicity' :
float(compound.group(
"Mult")),
119 'category' : compound.group(
"Type"),
125 Returns a `dict` of Mixtures. Each 126 mixture contains a list of compounds. 129 inFile = open(inputFile,
"r") 137 for line
in inFile.readlines():
141 mixtures.append(
dict(mixture))
144 mixture.update({
'components' : [] })
155 mixMatFile = open(inputFile,
"r") 159 for line
in mixMatFile.readlines():
163 r'^"(?P<name>[^"]+)"\s+(?P<weight>[0-9.Ee-]+)\s+(?P<number>[0-9.Ee-]+)\s+(?P<density>[0-9.Ee-]+)\s+(?P<x0>[0-9.Ee-]+)\s+(?P<l0>[0-9Ee.-]+)',
168 "name" : mixMat.group(
"name"),
169 "weight" :
float(mixMat.group(
"weight")),
170 "number" :
float(mixMat.group(
"number")),
171 "density" :
float(mixMat.group(
"density")),
172 "x0" :
float(mixMat.group(
"x0")),
173 "l0" :
float(mixMat.group(
"l0")),
182 fname = re.search(
"(?P<filename>[a-zA-Z0-9_]+)",
str(argv[1]))
184 fname =
str(fname.group(
"filename"))
185 radLenFile = open(fname +
".x0",
"w");
186 intLenFile = open(fname +
".l0",
"w");
190 listOfMaterials = listOfMixedMaterials + listOfPureMaterials
192 dfAllMaterials = pd.DataFrame(listOfMaterials)
194 for index
in range(len(listOfMixtures)):
196 gmixName = listOfMixtures[index][
"gmix_name"]
197 print(
"================================")
200 components = pd.DataFrame(listOfMixtures[index][
'components'])
202 components[
"volume"] = components[
"multiplicity"]*components[
"volume"]
207 components[
"percentVolume"] = components[
"volume"] / totalVolume
209 components = pd.merge(
211 dfAllMaterials[[
"name",
"density",
"x0",
"l0"]],
216 components[
"weight"] = components[
"density"] * components[
"volume"]
219 components[
"percentVolume"] * components[
"density"]
222 totalWeight = totalDensity * totalVolume
224 components[
"percentWeight"] = (
225 components[
"density"] * components[
"volume"] / totalWeight
229 components[
"percentWeight"] / (components[
"density"]*components[
"x0"])
232 components[
"ws2"] = (
233 components[
"percentWeight"] / (components[
"density"]*components[
"l0"])
236 totalRadLen = 1 / ( sum(components[
"ws"]) * totalDensity )
238 totalIntLen = 1/ ( sum(components[
"ws2"]) * totalDensity )
240 components[
"percentRadLen"] = (
241 components[
"ws"] * totalRadLen * totalDensity
244 components[
"percentIntLen"] = (
245 components[
"ws2"] * totalIntLen * totalDensity
248 displayDf = components[[
251 "percentVolume",
"percentWeight",
252 "density",
"weight",
"x0",
"percentRadLen",
256 displayDf[
"percentVolume"] *= 100.
257 displayDf[
"percentWeight"] *= 100.
258 displayDf[
"percentRadLen"] *= 100.
259 displayDf[
"percentIntLen"] *= 100.
261 displayDf = displayDf.rename(
263 "comment" :
"Component",
264 "material" :
"Material",
265 "volume" :
"Volume [cm^3]",
266 "percentVolume" :
"Volume %",
267 "density" :
"Density",
269 "percentWeight" :
"Weight %",
271 "percentRadLen" :
"X_0 %",
272 "l0":
"lambda_0 [cm]",
273 "percentIntLen" :
"lambda_0 %",
282 mcVolume = listOfMixtures[index][
"mc_volume"]
283 mcArea = listOfMixtures[index][
"mc_area"]
284 normalizationFactor = -1.
287 normalizationFactor = totalVolume / mcVolume
289 normalizationFactor = 1.
291 normalizedDensity = totalDensity * normalizationFactor
292 normalizedRadLen = totalRadLen / normalizationFactor
293 normalizedIntLen = totalIntLen / normalizationFactor
299 percentRadL = mcVolume / (mcArea*normalizedRadLen)
300 percentIntL = mcVolume / (mcArea*normalizedIntLen)
314 for index, component
in components.iterrows():
315 catg = component[
"category"]
316 prl = component[
"percentRadLen"]
317 irl = component[
"percentIntLen"]
318 if catg.upper() ==
"SUP":
321 elif catg.upper() ==
"SEN":
324 elif catg.upper() ==
"CAB":
327 elif catg.upper() ==
"COL":
330 elif catg.upper() ==
"ELE":
334 print(
"================================")
335 print(
"Mixture Density [g/cm^3]: " , totalDensity)
336 print(
"Norm. mixture density [g/cm^3]: ", normalizedDensity)
337 print(
"Mixture Volume [cm^3]: ", totalVolume)
338 print(
"MC Volume [cm^3]: ", mcVolume)
339 print(
"MC Area [cm^2]: ", mcArea)
340 print(
"Normalization Factor: ", normalizationFactor)
341 print(
"Mixture x0 [cm]: ", totalRadLen)
342 print(
"Norm. Mixture x0 [cm]: ", normalizedRadLen)
344 print(
"Norm. Mixture x0 [%]: ", 100. * percentRadL)
345 print(
"Mixture l0 [cm]: ", totalIntLen)
346 print(
"Norm. Mixture l0 [cm]: ", normalizedIntLen)
348 print(
"Norm. Mixture l0 [%]: ", 100. * percentIntL)
349 print(
"Total Weight [g]: ", totalWeight)
351 print(
"================================")
352 print(
"X0 Contribution: ")
353 print(
"Support :", pSupRadLen)
354 print(
"Sensitive :", pSenRadLen)
355 print(
"Cables :", pCabRadLen)
356 print(
"Cooling :", pColRadLen)
357 print(
"Electronics :", pEleRadLen)
359 print(
"================================")
360 print(
"l0 Contribution: ")
361 print(
"Support :", pSupIntLen)
362 print(
"Sensitive :", pSenIntLen)
363 print(
"Cables :", pCabIntLen)
364 print(
"Cooling :", pColIntLen)
365 print(
"Electronics :", pEleIntLen)
367 radLenFile.write(
"{0:<50}{1:>8}{2:>8}{3:>8}{4:>8}{5:>8}\n".
format(
369 round(pSupRadLen,3), round(pSenRadLen,3),
370 round(pCabRadLen,3), round(pColRadLen,3),
374 intLenFile.write(
"{0:<50}{1:>8}{2:>8}{3:>8}{4:>8}{5:>8}\n".
format(
376 round(pSupIntLen,3), round(pSenIntLen,3),
377 round(pCabIntLen,3), round(pColIntLen,3),
384 if __name__==
"__main__":
S & print(S &os, JobReport::InputFile const &f)
def getMixtures(inputFile)
def loadMaterialsFile(inputFile)