8from ShipGeoConfig
import AttrDict, Config
22 "WithConstField":
False,
132 DecayVolumeMedium: str =
"helium",
133 Yheight: float = 6.0,
134 strawDesign: int = 10,
136 shieldName: str =
"New_HA_Design",
137 nuTargetPassive: int = 1,
143 Create geometry configuration with specified parameters.
146 DecayVolumeMedium: Medium
in decay volume (
"helium" or "vacuums"), default:
"helium"
147 Yheight: Height of vacuum tank
in meters, default: 6.0
148 strawDesign: Straw tube design (4=aluminium frame, 10=steel frame), default: 10
149 muShieldGeo: Muon shield geometry file (
for experts), default:
None
150 shieldName: Name of shield configuration (
"warm_opt" or "New_HA_Design"), default:
"New_HA_Design"
151 nuTargetPassive: Target type (0=
with active layers, 1=only passive), default: 1
152 SND: Enable SND detector, default:
True
153 SND_design: SND design options (list of design numbers), default: [2]
154 TARGET_YAML: Path to target YAML configuration file, default:
"$FAIRSHIP/geometry/target_config.yaml"
157 Config: Geometry configuration object
160 if SND_design
is None:
162 if TARGET_YAML
is None:
163 TARGET_YAML = os.path.expandvars(
"$FAIRSHIP/geometry/target_config.yaml")
167 c.DecayVolumeMedium = DecayVolumeMedium
170 if not isinstance(SND_design, list):
171 SND_design = [SND_design]
172 c.SND_design = SND_design
173 c.target_yaml = TARGET_YAML
174 print(
"Info: Target using configuration:", c.target_yaml)
177 raise ValueError(
"shieldName must not be empty!")
179 c.shieldName = shieldName
180 c.SC_mag = shield_db[shieldName][
"hybrid"]
183 c.Yheight = Yheight * u.m
184 extraVesselLength = 10 * u.m
185 windowBulge = 25 * u.cm
186 c.strawDesign = strawDesign
190 c.cave.floorHeightMuonShield = 5 * u.m
191 c.cave.floorHeightTankA = 4.2 * u.m
192 if strawDesign == 10:
193 c.cave.floorHeightMuonShield = c.cave.floorHeightTankA
194 c.cave.floorHeightTankB = 2 * u.m
196 with open(c.target_yaml)
as file:
197 targetconfig = yaml.safe_load(file)
198 c.target =
AttrDict(targetconfig[
"target"])
200 c.target.slices_length = []
201 c.target.slices_gap = []
202 c.target.slices_material = []
204 for i
in range(c.target.Nplates):
205 for j
in range(c.target.N[i]):
206 if len(c.target.L) == 1:
207 c.target.slices_length.append(c.target.L[0])
209 c.target.slices_length.append(c.target.L[i])
210 if len(c.target.G) == 1:
211 c.target.slices_gap.append(c.target.G[0])
213 c.target.slices_gap.append(c.target.G[i])
214 if len(c.target.M) == 1:
215 c.target.slices_material.append(c.target.M[0])
217 c.target.slices_material.append(c.target.M[i])
219 c.target.slices_gap[c.target.nS - 1] = 0
220 print(c.target.slices_material, c.target.slices_length, c.target.slices_gap)
223 for width, gap
in zip(c.target.slices_length, c.target.slices_gap):
224 target_length += width + gap
225 c.target.length = target_length
229 c.target.z = c.target.z0 + c.target.length / 2.0
233 c.hadronAbsorber.z = (
245 c.muShield.z = c.hadronAbsorber.z
247 params = shield_db[shieldName][
"params"]
248 c.muShield.params = params
251 c.muShield.length = sum(line[0] + line[1] * 2
for line
in params)
252 c.muShield.nMagnets = len(params)
255 c.muShield.half_length = []
256 c.muShield.Entrance = []
259 c.muShield.Zgap.append(line[0])
260 c.muShield.half_length.append(line[1])
263 for i
in range(len(c.muShield.Zgap)):
266 c.muShield.Entrance.append(c.muShield.z + c.muShield.Zgap[i])
269 c.muShield.Entrance.append(
270 c.muShield.Entrance[i - 1] + c.muShield.half_length[i - 1] * 2 + c.muShield.Zgap[i]
273 c.muShield.params = [item
for sublist
in params
for item
in sublist]
278 c.decayVolume.length = 50 * u.m
283 c.decayVolume.z = c.z - 31.450 * u.m
284 c.decayVolume.z0 = c.decayVolume.z - c.decayVolume.length / 2.0
287 magnetIncrease = 100.0 * u.cm
289 if strawDesign != 4
and strawDesign != 10:
290 raise ValueError(f
"straw design {strawDesign} is not supported, use strawDesign = 4 or 10")
292 c.chambers.Tub1length = 2.5 * u.m
293 c.chambers.Tub2length = 17.68 * u.m + extraVesselLength / 2.0
294 c.chambers.Tub3length = 0.8 * u.m
295 c.chambers.Tub4length = 2.0 * u.m + magnetIncrease / 2.0
296 c.chambers.Tub5length = 0.8 * u.m
297 c.chambers.Tub6length = 0.1 * u.m + windowBulge / 2.0
298 c.chambers.Rmin = 245.0 * u.cm
299 c.chambers.Rmax = 250.0 * u.cm
305 z4 = c.z + TrMagGap + TrGap
311 z1 = c.z - TrMagGap - TrGap
315 c.Chamber1 =
AttrDict(z=z4 - 4666.0 * u.cm - magnetIncrease - extraVesselLength)
316 c.Chamber6 =
AttrDict(z=z4 + 30.0 * u.cm + windowBulge / 2.0)
321 c.Bfield.y = c.Yheight
322 c.Bfield.x = 2.4 * u.m
323 c.Bfield.fieldMap =
"files/MainSpectrometerField.root"
324 if c.magnetDesign > 3:
325 c.Bfield.YokeWidth = 0.8 * u.m
326 c.Bfield.YokeDepth = 1.4 * u.m
327 c.Bfield.CoilThick = 25.0 * u.cm
328 c.Bfield.x = 2.2 * u.m
329 c.Bfield.y = 3.5 * u.m
333 c.TimeDet.dzBarRow = 1.2 * u.cm
334 c.TimeDet.dzBarCol = 2.4 * u.cm
335 c.TimeDet.zBar = 1 * u.cm
336 c.TimeDet.DZ = (c.TimeDet.dzBarRow + c.TimeDet.dzBarCol + c.TimeDet.zBar) / 2
337 c.TimeDet.DX = 225 * u.cm
338 c.TimeDet.DY = 325 * u.cm
340 37.800 * u.m - c.TimeDet.dzBarRow * 3 / 2 + c.decayVolume.z
347 c.SplitCal.ZStart = 38.450 * u.m + c.decayVolume.z
348 c.SplitCal.XMax = 4 * u.m / 2
349 c.SplitCal.YMax = 6 * u.m / 2
350 c.SplitCal.Empty = 0 * u.cm
351 c.SplitCal.BigGap = 100 * u.cm
352 c.SplitCal.ActiveECALThickness = 0.56 * u.cm
353 c.SplitCal.FilterECALThickness = 0.28 * u.cm
354 c.SplitCal.FilterECALThickness_first = 0.28 * u.cm
355 c.SplitCal.ActiveHCALThickness = 90 * u.cm
356 c.SplitCal.FilterHCALThickness = 90 * u.cm
357 c.SplitCal.nECALSamplings = 50
358 c.SplitCal.nHCALSamplings = 0
359 c.SplitCal.ActiveHCAL = 0
360 c.SplitCal.FilterECALMaterial = 3
361 c.SplitCal.FilterHCALMaterial = 2
362 c.SplitCal.ActiveECALMaterial = 1
363 c.SplitCal.ActiveHCALMaterial = 1
364 c.SplitCal.ActiveECAL_gas_Thickness = 1.12 * u.cm
365 c.SplitCal.num_precision_layers = 1
366 c.SplitCal.first_precision_layer = 6
367 c.SplitCal.second_precision_layer = 10
368 c.SplitCal.third_precision_layer = 13
369 c.SplitCal.ActiveECAL_gas_gap = 10 * u.cm
370 c.SplitCal.NModulesInX = 2
371 c.SplitCal.NModulesInY = 3
372 c.SplitCal.NStripsPerModule = 50
373 c.SplitCal.StripHalfWidth = c.SplitCal.XMax / (c.SplitCal.NStripsPerModule * c.SplitCal.NModulesInX)
374 c.SplitCal.StripHalfLength = c.SplitCal.YMax / c.SplitCal.NModulesInY
375 c.SplitCal.SplitCalThickness = (
376 (c.SplitCal.FilterECALThickness_first - c.SplitCal.FilterECALThickness)
377 + (c.SplitCal.FilterECALThickness + c.SplitCal.ActiveECALThickness) * c.SplitCal.nECALSamplings
381 c.MuonStation0 =
AttrDict(z=c.SplitCal.ZStart + 10 * u.cm + c.SplitCal.SplitCalThickness)
383 c.MuonStation1 =
AttrDict(z=c.MuonStation0.z + 1 * u.m)
384 c.MuonStation2 =
AttrDict(z=c.MuonStation0.z + 2 * u.m)
385 c.MuonStation3 =
AttrDict(z=c.MuonStation0.z + 3 * u.m)
387 c.MuonFilter0 =
AttrDict(z=c.MuonStation0.z + 50.0 * u.cm)
388 c.MuonFilter1 =
AttrDict(z=c.MuonStation0.z + 150.0 * u.cm)
389 c.MuonFilter2 =
AttrDict(z=c.MuonStation0.z + 250.0 * u.cm)
392 c.Muon.XMax = 250.0 * u.cm
393 c.Muon.YMax = 325.0 * u.cm
395 c.Muon.ActiveThickness = 0.5 * u.cm
396 c.Muon.FilterThickness = 30.0 * u.cm
398 c.hadronAbsorber.WithConstField = shield_db[shieldName][
"WithConstField"]
399 c.muShield.WithConstField = shield_db[shieldName][
"WithConstField"]
403 c.strawtubesDigi.v_drift = 1.0 / (30 * u.ns / u.mm)
404 c.strawtubesDigi.sigma_spatial = 0.012 * u.cm
408 c.tauMudet.Ztot = 3 * u.m
409 c.tauMudet.zMudetC = c.muShield.z + c.muShield.length / 2.0 - c.tauMudet.Ztot / 2.0 - 70 * u.cm
416 c.UpstreamTagger.BoxX = 4.4 * u.m
417 c.UpstreamTagger.BoxY = 6.4 * u.m
418 c.UpstreamTagger.BoxZ = 16.0 * u.cm
419 c.UpstreamTagger.Z_Position = -25.400 * u.m + c.decayVolume.z
420 c.UpstreamTagger.PositionResolution = 1.0 * u.cm
421 c.UpstreamTagger.TimeResolution = 0.3
424 c.muShieldGeo = muShieldGeo
425 c.nuTargetPassive = nuTargetPassive
def create_config(str DecayVolumeMedium="helium", float Yheight=6.0, int strawDesign=10, muShieldGeo=None, str shieldName="New_HA_Design", int nuTargetPassive=1, bool SND=True, SND_design=None, TARGET_YAML=None)
int open(const char *, int)
Opens a file descriptor.