3 # Much of this program is taken straight from generate_gdml.pl that
4 # generates MicroBooNE fragment files (Thank you.)
6 # Each subroutine generates a fragment GDML file, and the last subroutine
7 # creates an XML file that make_gdml.pl will use to appropriately arrange
8 # the fragment GDML files to create the final desired DUNE GDML file,
9 # to be named by make_gdml output command
11 # If you are playing with different geometries, you can use the
12 # suffix command to help organize your work.
19 Math::BigFloat->precision(-16);
21 GetOptions( "help|h" => \$help,
22 "suffix|s:s" => \$suffix,
23 "output|o:s" => \$output,
24 "wires|w:s" => \$wires,
25 "helpcube|c" => \$helpcube);
29 # If the user requested help, print the usage notes and exit.
34 if ( ! defined $suffix )
36 # The user didn't supply a suffix, so append nothing to the file
42 # Otherwise, stick a "-" before the suffix, so that a suffix of
43 # "test" applied to filename.gdml becomes "filename-test.gdml".
44 $suffix = "-" . $suffix;
50 #++++++++++++++++++++++++ Begin defining variables +++++++++++++++++++++++++
52 # Define detector geometry variables - later to be put in a parameters
53 # XML file to be parsed as an input?
55 # set wires on to be the default, unless given an input by the user
56 $wires_on = 1; # 1=on, 0=off
67 #################################################
68 #### 4APA 35t parameters from DocDb 7550 ####
69 #################################################
73 ##################################################################
74 ##################### wire plane parameters ######################
97 ##################################################################
98 ######################## TPC parameters ##########################
102 $APAFrame_x = 2*$inch; #this does not include the wire spacing
103 $APAWirePlaneSpacing = 0.476; # center to center spacing between all of the wire planes (g, u, v, and x)
105 $TPCWireThickness = 0.015;
106 $TPCWirePlaneThickness = $TPCWireThickness;
111 # Let APAs be numbered as follows
116 # Here are the APA heights indexed by APA number (lengths, z, are constant)
118 $APAHeight[0] = 196.0;
119 $APAHeight[1] = 112.0;
120 $APAHeight[2] = 84.0;
121 $APAHeight[3] = $APAHeight[0];
124 # include APA spacing in y and z so volTPCs touch in y and z directions with correct APA
125 # spacing - this makes for smoother event generation.
127 $TPCSmallestLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
128 $TPCSmallestLongDrift_y = $APAHeight[2] + $APAVerticalGap;
129 $TPCSmallestLongDrift_z = $APA_z + $APALongGap;
131 $TPCMidLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
132 $TPCMidLongDrift_y = $APAHeight[1] + $APAVerticalGap;
133 $TPCMidLongDrift_z = $APA_z + $APALongGap;
135 $TPCLargestLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
136 $TPCLargestLongDrift_y = $APAHeight[0];
137 $TPCLargestLongDrift_z = $APA_z + $APALongGap;
139 $TPCSmallestShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
140 $TPCSmallestShortDrift_y = $APAHeight[2] + $APAVerticalGap;
141 $TPCSmallestShortDrift_z = $APA_z + $APALongGap;
143 $TPCMidShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
144 $TPCMidShortDrift_y = $APAHeight[1] + $APAVerticalGap;
145 $TPCMidShortDrift_z = $APA_z + $APALongGap;
147 $TPCLargestShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
148 $TPCLargestShortDrift_y = $APAHeight[0];
149 $TPCLargestShortDrift_z = $APA_z + $APALongGap;
153 ############################################################
154 ############### Optical Detector parameters ################
156 # TODO: while the structure is exactly what we need, the parameters for
157 # paddle height and positioning are all placeholders
159 $nPaddlesInAPA[0] = 3;
160 $nPaddlesInAPA[1] = 1;
161 $nPaddlesInAPA[2] = 1;
162 $nPaddlesInAPA[3] = $nPaddlesInAPA[0]; # for now, this one is the same as 0
165 $LightPaddle_x = 0.476;
166 $LightPaddle_y = 56; # in cm from docDb 7803
167 $LightPaddle_z = 4*$inch;
169 # z and x are given by APA frame center.
170 # Hardcode y distance of each paddle from the
171 # bottom of the APA to the paddle y-center.
172 # To be used in make_APA like [apa#][paddle#]
174 $PaddleYPositions[0][0] = $APAHeight[0]/2; # this puts it in the y center
175 $PaddleYPositions[1][0] = $APAHeight[1] - 4*$inch - $LightPaddle_y/2;
176 $PaddleYPositions[2][0] = $APAHeight[2] - 4*$inch - $LightPaddle_y/2;
177 $PaddleYPositions[3][0] = $PaddleYPositions[0][0];
179 $PaddleYPositions[0][1] = $APAHeight[0] - 4*$inch - $LightPaddle_y/2;
180 $PaddleYPositions[3][1] = $PaddleYPositions[0][1];
182 $PaddleYPositions[0][2] = 4*$inch + $LightPaddle_y/2;
183 $PaddleYPositions[3][2] = $PaddleYPositions[0][2];
187 ##################################################################
188 ###################### Cryostat parameters #######################
190 # "Dead" LAr outside of the fiducial volume but inside the cryostat
191 $SpaceCPAToCryoWall = 10; #$SideLArPadding
192 $SpaceAPAToFloor = 10; #$BottomLArPadding
193 $SpaceAPAToTopLAr = 3.53; #$TopLArPadding
194 $HeightGaseousAr = 13.5; #$Height of Gaseous Ar region
195 $UpstreamLArPadding = 10;
196 $DownstreamLArPadding = 10;
198 $APALongGap = 1.5; #separation between APAs along the incident beam axis
199 $APAVerticalGap = 2.5; #separation between APAs along the vertical axis
202 $CPA_y = ( $APAHeight[1]
204 + $APAHeight[2] ) / 2;
207 # Liquid and Gaseous Argon dimensions
208 $Argon_x = $TPCLargestShortDrift_x
210 + $TPCLargestLongDrift_x
212 + 2*$SpaceCPAToCryoWall;
213 $Argon_y = $APAHeight[1]
218 + $HeightGaseousAr; # assuming mid_y+smallest_y > largest_y
219 $Argon_z = 3*$APA_z + 2*$APALongGap
220 + $UpstreamLArPadding
221 + $DownstreamLArPadding;
223 # Cryostat Dimensions
224 $SteelThickness = 0.5*$inch;
225 $Cryostat_x = $Argon_x+2*$SteelThickness;
226 $Cryostat_y = $Argon_y+2*$SteelThickness;
227 $Cryostat_z = $Argon_z+2*$SteelThickness;
231 ##################################################################
232 ################# Detector Enclosure parameters ##################
234 $ConcretePadding = 50;
236 $TotalPadding = $ConcretePadding+$FoamPadding;
237 $DetEnc_x = $Cryostat_x+2*$TotalPadding;
238 $DetEnc_y = $Cryostat_y+2*$TotalPadding-$FoamPadding; # no foam on bottom
239 $CryoInDetEnc_ypos = -$DetEnc_y/2 + $ConcretePadding + $Cryostat_y/2;
240 $DetEnc_z = $Cryostat_z+2*$TotalPadding;
242 # We want the world origin to be at the very front of the fiducial volume.
243 # move it to the front of the enclosure, then back it up through the concrete/foam,
244 # then through the Cryostat shell, then through the upstream dead LAr (including the
245 # dead LAr on the edge of the TPC, but this is covered in $UpstreamLArPadding).
246 # This is to be added to the z position of every volume in volWorld
248 $OriginZSet = $DetEnc_z/2
251 - $UpstreamLArPadding;
253 # We want the world origin to be vertically centered between the two stacked APAs.
254 # (for now, that is, so the sorting works. this is quite asymetric, but then again
255 # so is the entire 35t geometry. this may be kept.)
256 # the cryostat sits on top of concrete padding, move the detector enclosure back
257 # and then move the world origin to the bottom of the smallest/lowest TPC, then
258 # and then up through the TPC, then back up to being centered between the stacked APAs.
259 # This is to be added to the y/x position of every volume in volWorld
261 $OriginYSet = $DetEnc_y/2
265 - $TPCSmallestShortDrift_y
270 $OriginXSet = - $DetEnc_x/2
273 + $SpaceCPAToCryoWall
279 if (defined $helpcube)
281 $PosDirCubeSide = $ArToAr; #seems to be a good proportion
285 $World_x = 2*$DetEnc_x;
286 $World_y = 2*$DetEnc_y;
287 $World_z = 2*$DetEnc_z;
292 ##################################################################
293 ######################### CPA positions ##########################
295 $posCPA0_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
296 $posCPA0_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
297 $posCPA0_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
300 $posCPA1_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
301 $posCPA1_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
302 $posCPA1_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
305 $posCPA2_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
306 $posCPA2_y = $Argon_y/2 - $SpaceAPAToTopLAr
307 - $HeightGaseousAr - $CPA_y/2;
308 $posCPA2_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
311 $posCPA3_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
312 $posCPA3_y = $Argon_y/2 - $SpaceAPAToTopLAr
313 - $HeightGaseousAr - $CPA_y/2;
314 $posCPA3_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
317 $posCPA4_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
318 $posCPA4_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
319 $posCPA4_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
322 $posCPA5_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
323 $posCPA5_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
324 $posCPA5_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
327 $posCPA6_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
328 $posCPA6_y = $Argon_y/2 - $SpaceAPAToTopLAr
329 - $HeightGaseousAr - $CPA_y/2;
330 $posCPA6_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
333 $posCPA7_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
334 $posCPA7_y = $Argon_y/2 - $SpaceAPAToTopLAr
335 - $HeightGaseousAr - $CPA_y/2;
336 $posCPA7_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
341 ##################################################################
342 ######################### TPC positions ##########################
346 # Largest Short Drift
347 $posTPClsd_x = - $Argon_x/2
348 + $SpaceCPAToCryoWall
350 + $TPCLargestShortDrift_x/2;
351 $posTPClsd_y = $Argon_y/2
354 - $TPCLargestShortDrift_y/2;
357 $posTPClld_x = $Argon_x/2
358 - $SpaceCPAToCryoWall
360 - $TPCLargestLongDrift_x/2;
361 $posTPClld_y = $Argon_y/2
364 - $TPCLargestLongDrift_y/2;
366 $posTPCl_z_upstream = - $Argon_z/2
367 + $UpstreamLArPadding ## this steps into the APALongGap/2 space on outside of TPC...
369 $posTPCl_z_downstream = $Argon_z/2
370 - $DownstreamLArPadding ## ...as well as this
375 # Smallest Long Drift
376 $posTPCsld_x = $Argon_x/2
377 - $SpaceCPAToCryoWall
379 - $TPCSmallestLongDrift_x/2;
380 $posTPCsld_y = - $Argon_y/2
383 $posTPCsld_z = $Argon_z/2
384 - $DownstreamLArPadding
390 $posTPCmld_x = $Argon_x/2
391 - $SpaceCPAToCryoWall
393 - $TPCMidLongDrift_x/2;
394 $posTPCmld_y = $Argon_y/2
398 $posTPCmld_z = $Argon_z/2
399 - $DownstreamLArPadding
406 # Smallest Short Drift
407 $posTPCssd_x = - $Argon_x/2
408 + $SpaceCPAToCryoWall
410 + $TPCSmallestShortDrift_x/2;
411 $posTPCssd_y = - $Argon_y/2
414 $posTPCssd_z = $Argon_z/2
415 - $DownstreamLArPadding
421 $posTPCmsd_x = - $Argon_x/2
422 + $SpaceCPAToCryoWall
424 + $TPCMidShortDrift_x/2;
425 $posTPCmsd_y = $Argon_y/2
429 $posTPCmsd_z = $Argon_z/2
430 - $DownstreamLArPadding
437 #TODO: define APA centers more fundamentally and then place TPC centers based off of this
438 $APA_Xcenter = $Argon_x/2
439 - $SpaceCPAToCryoWall
441 - $TPCLargestLongDrift_x
444 $APACenter[0][0] = $APA_Xcenter;
445 $APACenter[0][1] = $posTPClld_y;
446 $APACenter[0][2] = $posTPCl_z_upstream;
448 $APACenter[1][0] = $APA_Xcenter;
449 $APACenter[1][1] = $posTPCmld_y;
450 $APACenter[1][2] = $posTPCmld_z;
452 $APACenter[2][0] = $APA_Xcenter;
453 $APACenter[2][1] = $posTPCsld_y;
454 $APACenter[2][2] = $posTPCsld_z;
456 $APACenter[3][0] = $APACenter[0][0];
457 $APACenter[3][1] = $APACenter[0][1];
458 $APACenter[3][2] = $posTPCl_z_downstream;
463 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
467 # run the sub routines that generate the fragments
469 gen_Define(); # generates definitions at beginning of GDML
470 gen_Materials(); # generates materials to be used
472 # pass a name to gen_TPC that begins with TPC
473 gen_TPC( $TPCSmallestLongDrift_x, $TPCSmallestLongDrift_y, $TPCSmallestLongDrift_z, 'SmallestLongDrift', 1);
474 gen_TPC( $TPCMidLongDrift_x, $TPCMidLongDrift_y, $TPCMidLongDrift_z, 'MidLongDrift', 2);
475 gen_TPC( $TPCLargestLongDrift_x, $TPCLargestLongDrift_y, $TPCLargestLongDrift_z, 'LargestLongDrift', 0);
477 gen_TPC( $TPCSmallestShortDrift_x, $TPCSmallestShortDrift_y, $TPCSmallestShortDrift_z, 'SmallestShortDrift', 1);
478 gen_TPC( $TPCMidShortDrift_x, $TPCMidShortDrift_y, $TPCMidShortDrift_z, 'MidShortDrift', 2) ;
479 gen_TPC( $TPCLargestShortDrift_x, $TPCLargestShortDrift_y, $TPCLargestShortDrift_z, 'LargestShortDrift', 0);
487 write_fragments(); # writes the XML input for make_gdml.pl
488 # which zips together the final GDML
492 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
493 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
494 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
498 print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
499 print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
500 print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
501 print " -h prints this message, then quits\n";
506 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
507 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
508 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
513 # Create the <define> fragment file name,
514 # add file to list of fragments,
516 $DEF = "dune_10kT_Def" . $suffix . ".gdml";
517 push (@gdmlFiles, $DEF);
519 open(DEF) or die("Could not open file $DEF for writing");
523 <?xml version='1.0'?>
532 <position name="posOriginSet" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
534 <position name="posTPCLargestShortDrift_Pos" unit="cm" x="$posTPClsd_x" y="$posTPClsd_y" z="$posTPCl_z_downstream"/>
535 <position name="posTPCLargestLongDrift_Pos" unit="cm" x="$posTPClld_x" y="$posTPClld_y" z="$posTPCl_z_downstream"/>
536 <position name="posTPCLargestShortDrift_Neg" unit="cm" x="$posTPClsd_x" y="$posTPClsd_y" z="$posTPCl_z_upstream"/>
537 <position name="posTPCLargestLongDrift_Neg" unit="cm" x="$posTPClld_x" y="$posTPClld_y" z="$posTPCl_z_upstream"/>
538 <position name="posTPCSmallestShortDrift" unit="cm" x="$posTPCssd_x" y="$posTPCssd_y" z="$posTPCssd_z"/>
539 <position name="posTPCSmallestLongDrift" unit="cm" x="$posTPCsld_x" y="$posTPCsld_y" z="$posTPCsld_z"/>
540 <position name="posTPCMidShortDrift" unit="cm" x="$posTPCmsd_x" y="$posTPCmsd_y" z="$posTPCmsd_z"/>
541 <position name="posTPCMidLongDrift" unit="cm" x="$posTPCmld_x" y="$posTPCmld_y" z="$posTPCmld_z"/>
544 <position name="posCathode0" unit="cm" x="$posCPA0_x" y="$posCPA0_y" z="$posCPA0_z"/>
545 <position name="posCathode1" unit="cm" x="$posCPA1_x" y="$posCPA1_y" z="$posCPA1_z"/>
546 <position name="posCathode2" unit="cm" x="$posCPA2_x" y="$posCPA2_y" z="$posCPA2_z"/>
547 <position name="posCathode3" unit="cm" x="$posCPA3_x" y="$posCPA3_y" z="$posCPA3_z"/>
548 <position name="posCathode4" unit="cm" x="$posCPA4_x" y="$posCPA4_y" z="$posCPA4_z"/>
549 <position name="posCathode5" unit="cm" x="$posCPA5_x" y="$posCPA5_y" z="$posCPA5_z"/>
550 <position name="posCathode6" unit="cm" x="$posCPA6_x" y="$posCPA6_y" z="$posCPA6_z"/>
551 <position name="posCathode7" unit="cm" x="$posCPA7_x" y="$posCPA7_y" z="$posCPA7_z"/>
553 <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
554 <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
555 <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
556 <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
557 <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
558 <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
568 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
569 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
570 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
575 # Create the <materials> fragment file name,
576 # add file to list of output GDML fragments,
578 $MAT = "dune_10kT_Materials" . $suffix . ".gdml";
579 push (@gdmlFiles, $MAT);
581 open(MAT) or die("Could not open file $MAT for writing");
586 <element name="videRef" formula="VACUUM" Z="1"> <atom value="1"/> </element>
587 <element name="bromine" formula="Br" Z="35"> <atom value="79.904"/> </element>
588 <element name="hydrogen" formula="H" Z="1"> <atom value="1.0079"/> </element>
589 <element name="nitrogen" formula="N" Z="7"> <atom value="14.0067"/> </element>
590 <element name="oxygen" formula="O" Z="8"> <atom value="15.999"/> </element>
591 <element name="aluminum" formula="Al" Z="13"> <atom value="26.9815"/> </element>
592 <element name="silicon" formula="Si" Z="14"> <atom value="28.0855"/> </element>
593 <element name="carbon" formula="C" Z="6"> <atom value="12.0107"/> </element>
594 <element name="potassium" formula="K" Z="19"> <atom value="39.0983"/> </element>
595 <element name="chromium" formula="Cr" Z="24"> <atom value="51.9961"/> </element>
596 <element name="iron" formula="Fe" Z="26"> <atom value="55.8450"/> </element>
597 <element name="nickel" formula="Ni" Z="28"> <atom value="58.6934"/> </element>
598 <element name="calcium" formula="Ca" Z="20"> <atom value="40.078"/> </element>
599 <element name="magnesium" formula="Mg" Z="12"> <atom value="24.305"/> </element>
600 <element name="sodium" formula="Na" Z="11"> <atom value="22.99"/> </element>
601 <element name="titanium" formula="Ti" Z="22"> <atom value="47.867"/> </element>
602 <element name="argon" formula="Ar" Z="18"> <atom value="39.9480"/> </element>
603 <element name="sulphur" formula="S" Z="16"> <atom value="32.065"/> </element>
604 <element name="phosphorus" formula="P" Z="15"> <atom value="30.973"/> </element>
606 <material name="Vacuum" formula="Vacuum">
607 <D value="1.e-25" unit="g/cm3"/>
608 <fraction n="1.0" ref="videRef"/>
611 <material name="ALUMINUM_Al" formula="ALUMINUM_Al">
612 <D value="2.6990" unit="g/cm3"/>
613 <fraction n="1.0000" ref="aluminum"/>
616 <material name="SILICON_Si" formula="SILICON_Si">
617 <D value="2.3300" unit="g/cm3"/>
618 <fraction n="1.0000" ref="silicon"/>
621 <material name="epoxy_resin" formula="C38H40O6Br4">
622 <D value="1.1250" unit="g/cm3"/>
623 <composite n="38" ref="carbon"/>
624 <composite n="40" ref="hydrogen"/>
625 <composite n="6" ref="oxygen"/>
626 <composite n="4" ref="bromine"/>
629 <material name="SiO2" formula="SiO2">
630 <D value="2.2" unit="g/cm3"/>
631 <composite n="1" ref="silicon"/>
632 <composite n="2" ref="oxygen"/>
635 <material name="Al2O3" formula="Al2O3">
636 <D value="3.97" unit="g/cm3"/>
637 <composite n="2" ref="aluminum"/>
638 <composite n="3" ref="oxygen"/>
641 <material name="Fe2O3" formula="Fe2O3">
642 <D value="5.24" unit="g/cm3"/>
643 <composite n="2" ref="iron"/>
644 <composite n="3" ref="oxygen"/>
647 <material name="CaO" formula="CaO">
648 <D value="3.35" unit="g/cm3"/>
649 <composite n="1" ref="calcium"/>
650 <composite n="1" ref="oxygen"/>
653 <material name="MgO" formula="MgO">
654 <D value="3.58" unit="g/cm3"/>
655 <composite n="1" ref="magnesium"/>
656 <composite n="1" ref="oxygen"/>
659 <material name="Na2O" formula="Na2O">
660 <D value="2.27" unit="g/cm3"/>
661 <composite n="2" ref="sodium"/>
662 <composite n="1" ref="oxygen"/>
665 <material name="TiO2" formula="TiO2">
666 <D value="4.23" unit="g/cm3"/>
667 <composite n="1" ref="titanium"/>
668 <composite n="2" ref="oxygen"/>
671 <material name="FeO" formula="FeO">
672 <D value="5.745" unit="g/cm3"/>
673 <composite n="1" ref="iron"/>
674 <composite n="1" ref="oxygen"/>
677 <material name="CO2" formula="CO2">
678 <D value="1.562" unit="g/cm3"/>
679 <composite n="1" ref="iron"/>
680 <composite n="2" ref="oxygen"/>
683 <material name="P2O5" formula="P2O5">
684 <D value="1.562" unit="g/cm3"/>
685 <composite n="2" ref="phosphorus"/>
686 <composite n="5" ref="oxygen"/>
689 <material formula=" " name="DUSEL_Rock">
690 <D value="2.82" unit="g/cm3"/>
691 <fraction n="0.5267" ref="SiO2"/>
692 <fraction n="0.1174" ref="FeO"/>
693 <fraction n="0.1025" ref="Al2O3"/>
694 <fraction n="0.0473" ref="MgO"/>
695 <fraction n="0.0422" ref="CO2"/>
696 <fraction n="0.0382" ref="CaO"/>
697 <fraction n="0.0240" ref="carbon"/>
698 <fraction n="0.0186" ref="sulphur"/>
699 <fraction n="0.0053" ref="Na2O"/>
700 <fraction n="0.00070" ref="P2O5"/>
701 <fraction n="0.0771" ref="oxygen"/>
704 <material name="fibrous_glass">
705 <D value="2.74351" unit="g/cm3"/>
706 <fraction n="0.600" ref="SiO2"/>
707 <fraction n="0.118" ref="Al2O3"/>
708 <fraction n="0.001" ref="Fe2O3"/>
709 <fraction n="0.224" ref="CaO"/>
710 <fraction n="0.034" ref="MgO"/>
711 <fraction n="0.010" ref="Na2O"/>
712 <fraction n="0.013" ref="TiO2"/>
715 <material name="FR4">
716 <D value="1.98281" unit="g/cm3"/>
717 <fraction n="0.47" ref="epoxy_resin"/>
718 <fraction n="0.53" ref="fibrous_glass"/>
721 <material name="STEEL_STAINLESS_Fe7Cr2Ni" formula="STEEL_STAINLESS_Fe7Cr2Ni">
722 <D value="7.9300" unit="g/cm3"/>
723 <fraction n="0.0010" ref="carbon"/>
724 <fraction n="0.1792" ref="chromium"/>
725 <fraction n="0.7298" ref="iron"/>
726 <fraction n="0.0900" ref="nickel"/>
729 <material name="LAr" formula="LAr">
730 <D value="1.40" unit="g/cm3"/>
731 <fraction n="1.0000" ref="argon"/>
734 <material name="ArGas" formula="ArGas">
735 <D value="0.00166" unit="g/cm3"/>
736 <fraction n="1.0" ref="argon"/>
739 <material formula=" " name="Air">
740 <D value="0.001205" unit="g/cm3"/>
741 <fraction n="0.781154" ref="nitrogen"/>
742 <fraction n="0.209476" ref="oxygen"/>
743 <fraction n="0.00934" ref="argon"/>
746 <material formula=" " name="G10">
747 <D value="1.7" unit="g/cm3"/>
748 <fraction n="0.2805" ref="silicon"/>
749 <fraction n="0.3954" ref="oxygen"/>
750 <fraction n="0.2990" ref="carbon"/>
751 <fraction n="0.0251" ref="hydrogen"/>
754 <material formula=" " name="Granite">
755 <D value="2.7" unit="g/cm3"/>
756 <fraction n="0.438" ref="oxygen"/>
757 <fraction n="0.257" ref="silicon"/>
758 <fraction n="0.222" ref="sodium"/>
759 <fraction n="0.049" ref="aluminum"/>
760 <fraction n="0.019" ref="iron"/>
761 <fraction n="0.015" ref="potassium"/>
764 <material formula=" " name="ShotRock">
765 <D value="2.7*0.6" unit="g/cm3"/>
766 <fraction n="0.438" ref="oxygen"/>
767 <fraction n="0.257" ref="silicon"/>
768 <fraction n="0.222" ref="sodium"/>
769 <fraction n="0.049" ref="aluminum"/>
770 <fraction n="0.019" ref="iron"/>
771 <fraction n="0.015" ref="potassium"/>
774 <material formula=" " name="Dirt">
775 <D value="1.7" unit="g/cm3"/>
776 <fraction n="0.438" ref="oxygen"/>
777 <fraction n="0.257" ref="silicon"/>
778 <fraction n="0.222" ref="sodium"/>
779 <fraction n="0.049" ref="aluminum"/>
780 <fraction n="0.019" ref="iron"/>
781 <fraction n="0.015" ref="potassium"/>
784 <material formula=" " name="Concrete">
785 <D value="2.3" unit="g/cm3"/>
786 <fraction n="0.530" ref="oxygen"/>
787 <fraction n="0.335" ref="silicon"/>
788 <fraction n="0.060" ref="calcium"/>
789 <fraction n="0.015" ref="sodium"/>
790 <fraction n="0.020" ref="iron"/>
791 <fraction n="0.040" ref="aluminum"/>
794 <material formula="H2O" name="Water">
795 <D value="1.0" unit="g/cm3"/>
796 <fraction n="0.1119" ref="hydrogen"/>
797 <fraction n="0.8881" ref="oxygen"/>
800 <material formula="Ti" name="Titanium">
801 <D value="4.506" unit="g/cm3"/>
802 <fraction n="1." ref="titanium"/>
805 <material name="TPB" formula="TPB">
806 <D value="1.40" unit="g/cm3"/>
807 <fraction n="1.0000" ref="argon"/>
810 <material name="Glass">
811 <D value="2.74351" unit="g/cm3"/>
812 <fraction n="0.600" ref="SiO2"/>
813 <fraction n="0.118" ref="Al2O3"/>
814 <fraction n="0.001" ref="Fe2O3"/>
815 <fraction n="0.224" ref="CaO"/>
816 <fraction n="0.034" ref="MgO"/>
817 <fraction n="0.010" ref="Na2O"/>
818 <fraction n="0.013" ref="TiO2"/>
821 <material name="Acrylic">
822 <D value="1.19" unit="g/cm3"/>
823 <fraction n="0.600" ref="carbon"/>
824 <fraction n="0.320" ref="oxygen"/>
825 <fraction n="0.080" ref="hydrogen"/>
837 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
838 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
839 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
850 my $TPCWirePlaneHeight = $_[1];
851 my $TPCWirePlaneLength = $_[2];
853 my $TPCActive_x = $_[0]-(4*$APAWirePlaneSpacing);
854 my $TPCActive_y = $TPCWirePlaneHeight;
855 my $TPCActive_z = $TPCWirePlaneLength;
857 my $UAngle = $UAng[$_[4]];
858 my $VAngle = $VAng[$_[4]];
860 my $SinUAngle = sin( deg2rad($UAngle) );
861 my $CosUAngle = cos( deg2rad($UAngle) );
862 my $TanUAngle = tan( deg2rad($UAngle) );
864 my $SinVAngle = sin( deg2rad($VAngle) );
865 my $CosVAngle = cos( deg2rad($VAngle) );
866 my $TanVAngle = tan( deg2rad($VAngle) );
868 my $UWire_yint = $UWirePitch/$SinUAngle;
869 my $UWire_zint = $UWirePitch/$CosUAngle;
871 my $VWire_yint = $VWirePitch/$SinVAngle;
872 my $VWire_zint = $VWirePitch/$CosVAngle;
874 #constructs everything inside volTPC, namely
875 # (moving from left to right, or from +x to -x)
877 # -volTPCPlaneU: with wires angled from vertical slightly different than in V
878 # -volTPCPlaneV: with wires angled from vertical slightly differently than in U
879 # -volTPCPlaneX: with vertical wires
882 # Create the TPC fragment file name,
883 # add file to list of output GDML fragments,
885 $TPC = "35t_TPC_${_[3]}" . $suffix . ".gdml";
886 push (@gdmlFiles, $TPC);
888 open(TPC) or die("Could not open file $TPC for writing");
891 # The standard XML prefix and starting the gdml
893 <?xml version='1.0'?>
898 # All the TPC solids save the wires.
901 <box name="$_[3]" lunit="cm"
905 <box name="${_[3]}Plane" lunit="cm"
906 x="$TPCWirePlaneThickness"
907 y="$TPCWirePlaneHeight"
908 z="$TPCWirePlaneLength"/>
909 <box name="${_[3]}Active" lunit="cm"
916 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
920 <tube name="${_[3]}WireVert"
921 rmax="0.5*$TPCWireThickness"
922 z="$TPCWirePlaneHeight"
928 # Set number of wires to default to zero, when $wires_on = 0, for a low memory
929 # version. But if $wires_on = 1, calculate the number of wires on each side of each
930 # plane to be used in the for loops
932 my $NumberCornerUWires = 0;
933 my $NumberSideUWires = 0;
934 my $NumberCommonUWires = 0;
935 my $NumberCornerVWires = 0;
936 my $NumberSideVWires = 0;
937 my $NumberCommonVWires = 0;
938 my $NumberVerticalWires = 0;
942 # Number of wires in one corner
943 $NumberCornerUWires = int( $TPCWirePlaneLength/($UWirePitch/$CosUAngle) );
945 $NumberCornerVWires = int( $TPCWirePlaneLength/($VWirePitch/$CosVAngle) );
947 # Total number of wires touching one vertical (longer) side
948 # Note that the total number of wires per plane is this + another set of corner wires
949 $NumberSideUWires = int( $TPCWirePlaneHeight/($UWirePitch/$SinUAngle) );
951 $NumberSideVWires = int( $TPCWirePlaneHeight/($VWirePitch/$SinVAngle) );
953 # Number of wires per side that aren't cut off by the corner
954 $NumberCommonUWires = $NumberSideUWires - $NumberCornerUWires;
956 $NumberCommonVWires = $NumberSideVWires - $NumberCornerVWires;
958 # number of wires on the vertical plane
959 # TODO: 1 is a temporary safety!!
960 $NumberVerticalWires = int( ($TPCWirePlaneLength - $TPCWireThickness)/$XWirePitch );
963 # The corner wires for the U plane
966 for ($i = 0; $i < $NumberCornerUWires; ++$i)
968 # Subtraction to avoid corners of wires overlapping the TPCPlane sides,
969 # equal to 0.5*TCPWireThickness*($TanUAngle+1/$TanUAngle),
970 # allowing for 30deg<UAngle
973 <tube name="${_[3]}WireU$i"
974 rmax="0.5*$TPCWireThickness"
975 z="$UWirePitch*($TanUAngle+1/$TanUAngle)*($i+1)-0.01732"
982 # Next, the wire used many times in the middle of the U plane.
983 # Subtraction again to avoid wire corners overlapping, equal to
984 # 0.5*TCPWireThickness*2/$TanVAngle, allowing for 30deg<VAngle
987 <tube name="${_[3]}WireUCommon"
988 rmax="0.5*$TPCWireThickness"
989 z="$TPCWirePlaneLength/$SinUAngle-0.02598"
998 # The corner wires for the V plane
1001 for ($i = 0; $i < $NumberCornerVWires; ++$i)
1003 # Same subtraction to avoid corners of wires overlapping
1004 # the TPCPlane sides
1008 <tube name="${_[3]}WireV$i"
1009 rmax="0.5*$TPCWireThickness"
1010 z="$VWirePitch*($TanVAngle+1/$TanVAngle)*($i+1)-0.01732"
1019 # The wire used many times in the middle of the V plane
1020 # Same subtraction as U common
1023 <tube name="${_[3]}WireVCommon"
1024 rmax="0.5*$TPCWireThickness"
1025 z="$TPCWirePlaneLength/$SinVAngle-0.02598"
1035 # Begin structure and create the vertical wire logical volume
1039 <volume name="volTPCActive${_[3]}">
1040 <materialref ref="LAr"/>
1041 <solidref ref="${_[3]}Active"/>
1050 <volume name="volTPCWireVert${_[3]}">
1051 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1052 <solidref ref="${_[3]}WireVert"/>
1056 # Corner U wires logical volumes
1057 for ($i = 0; $i < $NumberCornerUWires; ++$i)
1060 <volume name="volTPCWireU$i${_[3]}">
1061 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1062 <solidref ref="${_[3]}WireU$i"/>
1068 # Common U wire logical volume, referenced many times
1070 <volume name="volTPCWireUCommon${_[3]}">
1071 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1072 <solidref ref="${_[3]}WireUCommon"/>
1076 # Corner V wires logical volumes
1077 for ($i = 0; $i < $NumberCornerVWires; ++$i)
1080 <volume name="volTPCWireV$i${_[3]}">
1081 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1082 <solidref ref="${_[3]}WireV$i"/>
1088 # Common V wire logical volume, referenced many times
1090 <volume name="volTPCWireVCommon${_[3]}">
1091 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1092 <solidref ref="${_[3]}WireVCommon"/>
1101 #+++++++++++++++++++++++++ Position physical wires ++++++++++++++++++++++++++
1103 # ++++++++++++++++++++++ U Plane +++++++++++++++++++++++
1105 # Create U plane logical volume
1107 <volume name="volTPCPlaneU${_[3]}">
1108 <materialref ref="LAr"/>
1109 <solidref ref="${_[3]}Plane"/>
1115 # Starting with the bottom left corner wires:
1116 # x=0 to center the wires in the plane
1117 # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
1118 # from the bottom of the plane, and trigonometry gives the increment
1119 # z positioning: Looking at the plane from the positive x direction,
1120 # (0.5*$TPCWirePlaneLength) starts the incremental increase from
1121 # the lower left corner.
1122 # rotation: same as common wire in code below
1124 for ($i = 0; $i < $NumberCornerUWires; ++$i)
1126 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($i+1)*$UWire_yint;
1127 my $zpos = (0.5*$TPCWirePlaneLength)-0.5*($i+1)*$UWire_zint;
1129 my $diff=(0.5*$TPCWirePlaneLength)-0.5*($NumberCornerUWires)*$UWire_zint;
1130 my $zpos=$zpos-$diff;
1134 <volumeref ref="volTPCWireU$i${_[3]}"/>
1135 <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1136 <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1143 # Moving upwards to the common wires:
1144 # x and z are zero to center the wires along a vertical axis
1145 # y positioning: The trick is positioning the lowest common wire so that the pitch
1146 # is consistent, then the increment is double the increment of
1147 # the corner wires since there is no z incriment.
1148 # rotation: wires in \\\\ direction, so +90deg to bring them to vertical and
1149 # +UAngle counterclockwise to arrive at proper orientation
1150 # Note that the counter maintains wire number (in pos. name) counting bottom to top
1152 for ($i = $NumberCornerUWires; $i < $NumberSideUWires; ++$i)
1154 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerUWires)*$UWire_yint+($i+1-$NumberCornerUWires)*$UWire_yint;
1158 <volumeref ref="volTPCWireUCommon${_[3]}"/>
1159 <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="0"/>
1160 <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1167 # Finally moving to the corner wires on the top right:
1168 # x=0 to center the wires in the plane
1169 # y positioning: plug wire number into same equation
1170 # z positioning: start at z=0 and go negatively at the same z increment
1171 # rotation: same as common wire in code above
1172 # note that the counter maintains wire number shown in the position name
1174 for ($i = $NumberSideUWires; $i < $NumberSideUWires+$NumberCornerUWires-1; ++$i)
1176 # Make a counter to recall the right logical volume reference:
1177 # We want the last U wire in this loop (the highest wire) to be the
1178 # first wire in the logical volume loop for U wires.
1180 $j = $NumberSideUWires+$NumberCornerUWires - $i - 2;
1182 # Note that since we are referencing the same logical volumes/same solids for
1183 # the top wires as well as the bottom, the pattern of "stacking" wire on top of wire
1184 # with an incremental separation is likely to cause the top corner wires to be a
1185 # a little shorter than they can be, but never any longer. There is no immediately
1186 # elegant way to fix this, but at 5mm pitch and around 45deg wire orientation, the
1187 # wires can be at most 1cm shorter than possible which is negligible until the top
1188 # 20 wires or so where 1cm is >5% of their length. This also means that there
1189 # could be one more space for a wire left over, but that is highly unlikely.
1191 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerUWires)*$UWire_yint+($NumberCommonUWires)*$UWire_yint+0.5*($i+1-$NumberSideUWires)*$UWire_yint;
1192 my $zpos = -0.5*($i+1-$NumberSideUWires)*$UWire_zint;
1196 <volumeref ref="volTPCWireU$j${_[3]}"/>
1197 <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1198 <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1207 # ++++++++++++++++++++++ V Plane +++++++++++++++++++++++
1209 # End U plane and create V plane logical volume
1213 <volume name="volTPCPlaneV${_[3]}">
1214 <materialref ref="LAr"/>
1215 <solidref ref="${_[3]}Plane"/>
1222 # Starting with the bottom right corner wires:
1223 # x=0 to center the wires in the plane
1224 # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
1225 # from the bottom of the plane, and trigonometry gives the increment
1226 # z positioning: Looking at the plane from the positive x direction,
1227 # (-0.5*$TPCWirePlaneLength) starts the incremental increase from
1228 # the lower right corner.
1229 # rotation: same as common wire in code below
1231 for ($i = 0; $i < $NumberCornerVWires; ++$i)
1233 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($i+1)*$VWire_yint;
1234 my $zpos = (-0.5*$TPCWirePlaneLength)+0.5*($i+1)*$VWire_zint;
1236 my $diff=(-0.5*$TPCWirePlaneLength)+0.5*($NumberCornerVWires)*$VWire_zint;
1237 my $zpos=$zpos-$diff;
1241 <volumeref ref="volTPCWireV$i${_[3]}"/>
1242 <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1243 <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1250 # Moving upwards to the common wires:
1251 # x and z are zero to center the wires along a vertical axis
1252 # y positioning: Plug wire number into the same corner ypos equation
1253 # rotation: wires in //// direction, so +90deg to bring them to vertical and
1254 # --VAngle counterclockwise to arrive at proper orientation
1255 # Note that the counter maintains wire number in the position name
1257 for ($i = $NumberCornerVWires; $i < $NumberSideVWires; ++$i)
1259 my $ypos = (-0.5*$TPCWirePlaneHeight)-0.5*($NumberCornerVWires)*$VWire_yint+($i+1)*$VWire_yint;
1263 <volumeref ref="volTPCWireVCommon${_[3]}"/>
1264 <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="0"/>
1265 <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1272 # Finally moving to the corner wires on the top right:
1273 # x=0 to center the wires in the plane
1274 # y positioning: plug wire number into same equation
1275 # z positioning: start at z=0 and go positively at the same z increment
1276 # rotation: same as common wire in code above
1277 # note that the counter maintains wire number shown in the position name
1279 for ($i = $NumberSideVWires; $i < $NumberSideVWires+$NumberCornerVWires-1; ++$i)
1281 # Make a counter to recall the right logical volume reference where the last
1282 # wire in this loop is the smallest, first wire in the logical volume loop, just as in U
1284 $j = $NumberSideVWires+$NumberCornerVWires - $i - 2;
1286 # Note that since we are referencing the same logical volumes/same solids for
1287 # the top wires as well as the bottom, the pattern of "stacking" wire on top of wire
1288 # with an incremental separation is likely to cause the top corner wires to be a
1289 # a little shorter than they can be, but never any longer. Just as in U
1291 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerVWires)*$VWire_yint+($NumberCommonVWires)*$VWire_yint+0.5*($i+1-$NumberSideVWires)*$VWire_yint;
1292 my $zpos = 0.5*($i+1-$NumberSideVWires)*$VWire_zint;
1296 <volumeref ref="volTPCWireV$j${_[3]}"/>
1297 <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1298 <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1307 # ++++++++++++++++++++++ X Plane +++++++++++++++++++++++
1309 # End V plane and create X plane logical volume
1313 <volume name="volTPCPlaneX${_[3]}">
1314 <materialref ref="LAr"/>
1315 <solidref ref="${_[3]}Plane"/>
1321 # This is the simplest plane, one loop creates all of the wires
1322 # x and y position at zero to center the wires
1323 # z position: moving from front of detector to back, in the positive z direction,
1324 # starting at (-0.5*$TPCWirePlaneLength), the right side looking from
1327 for ($i=0; $i<$NumberVerticalWires; ++$i)
1329 my $zpos = (-0.5*$TPCWirePlaneLength)+$XWirePitch*($i+0.5)+$TPCWireThickness/2;
1333 <volumeref ref="volTPCWireVert${_[3]}"/>
1334 <position name="pos${_[3]}WireX$i" unit="cm" x="0" y="0 " z="$zpos"/>
1335 <rotationref ref="rPlus90AboutX"/>
1347 #+++++++++++++++++++++ Position physical wires Above +++++++++++++++++++++
1349 #wrap up the TPC file
1351 <volume name="volTPC${_[3]}">
1352 <materialref ref="LAr"/>
1353 <solidref ref="${_[3]}"/>
1355 <volumeref ref="volTPCPlaneU${_[3]}"/>
1356 <position name="pos${_[3]}PlaneU" unit="cm" x="-($_[0]/2)+3*$APAWirePlaneSpacing" y="0" z="0"/>
1359 <volumeref ref="volTPCPlaneV${_[3]}"/>
1360 <position name="pos${_[3]}PlaneV" unit="cm" x="-($_[0]/2)+2*$APAWirePlaneSpacing" y="0" z="0"/>
1363 <volumeref ref="volTPCPlaneX${_[3]}"/>
1364 <position name="pos${_[3]}PlaneX" unit="cm" x="-($_[0]/2)+$APAWirePlaneSpacing" y="0" z="0"/>
1367 <volumeref ref="volTPCActive${_[3]}"/>
1368 <position name="pos${_[3]}Active" unit="cm" x="-($_[0]/2)+$APAWirePlaneSpacing + $TPCActive_x/2" y="0" z="0"/>
1377 } #end of sub gen_TPC
1383 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1384 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1385 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1390 # Create the cryostat fragment file name,
1391 # add file to list of output GDML fragments,
1393 $CRYO = "35t_Cryostat" . $suffix . ".gdml";
1394 push (@gdmlFiles, $CRYO);
1395 $CRYO = ">" . $CRYO;
1396 open(CRYO) or die("Could not open file $CRYO for writing");
1399 # The standard XML prefix and starting the gdml
1401 <?xml version='1.0'?>
1406 # All the cryostat solids.
1409 <box name="Cryostat" lunit="cm"
1414 <box name="ArgonInterior" lunit="cm"
1419 <subtraction name="SteelShell">
1420 <first ref="Cryostat"/>
1421 <second ref="ArgonInterior"/>
1424 <box name="Cathode" lunit="cm"
1429 <box name="LightPaddle" lunit="cm"
1431 y="$LightPaddle_y + $SiPM_y"
1432 z="$LightPaddle_z"/>
1437 # Add APA frames and optical detectors (paddles)
1444 # Cryostat structure
1448 <volume name="volSteelShell">
1449 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1450 <solidref ref="SteelShell"/>
1453 <volume name="volCathode">
1454 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1455 <solidref ref="Cathode"/>
1458 <volume name="volOpDetSensitive">
1459 <materialref ref="Acrylic"/>
1460 <solidref ref="LightPaddle"/>
1472 <volume name="volCryostat">
1473 <materialref ref="LAr"/>
1474 <solidref ref="Cryostat"/>
1477 <volumeref ref="volSteelShell"/>
1478 <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1483 <volumeref ref="volCathode"/>
1484 <positionref ref="posCathode0"/>
1487 <volumeref ref="volCathode"/>
1488 <positionref ref="posCathode1"/>
1491 <volumeref ref="volCathode"/>
1492 <positionref ref="posCathode2"/>
1495 <volumeref ref="volCathode"/>
1496 <positionref ref="posCathode3"/>
1500 <volumeref ref="volCathode"/>
1501 <positionref ref="posCathode4"/>
1504 <volumeref ref="volCathode"/>
1505 <positionref ref="posCathode5"/>
1508 <volumeref ref="volCathode"/>
1509 <positionref ref="posCathode6"/>
1512 <volumeref ref="volCathode"/>
1513 <positionref ref="posCathode7"/>
1517 <!-- The Smallest APA -->
1519 <volumeref ref="volTPCSmallestLongDrift"/>
1520 <positionref ref="posTPCSmallestLongDrift"/>
1521 <rotationref ref="rIdentity"/>
1524 <volumeref ref="volTPCSmallestShortDrift"/>
1525 <positionref ref="posTPCSmallestShortDrift"/>
1526 <rotationref ref="rPlus180AboutY"/>
1531 place_APA($APACenter[2][0], $APACenter[2][1], $APACenter[2][2], 2);
1536 <!-- The Middle-sized APA -->
1538 <volumeref ref="volTPCMidLongDrift"/>
1539 <positionref ref="posTPCMidLongDrift"/>
1540 <rotationref ref="rIdentity"/>
1543 <volumeref ref="volTPCMidShortDrift"/>
1544 <positionref ref="posTPCMidShortDrift"/>
1545 <rotationref ref="rPlus180AboutY"/>
1550 place_APA($APACenter[1][0], $APACenter[1][1], $APACenter[1][2], 1);
1555 <!-- The Largest APAs, Upstream and Downstream -->
1557 <volumeref ref="volTPCLargestLongDrift"/>
1558 <positionref ref="posTPCLargestLongDrift_Neg"/>
1559 <rotationref ref="rIdentity"/>
1562 <volumeref ref="volTPCLargestShortDrift"/>
1563 <positionref ref="posTPCLargestShortDrift_Neg"/>
1564 <rotationref ref="rPlus180AboutY"/>
1567 <volumeref ref="volTPCLargestLongDrift"/>
1568 <positionref ref="posTPCLargestLongDrift_Pos"/>
1569 <rotationref ref="rIdentity"/>
1572 <volumeref ref="volTPCLargestShortDrift"/>
1573 <positionref ref="posTPCLargestShortDrift_Pos"/>
1574 <rotationref ref="rPlus180AboutY"/>
1579 place_APA($APACenter[0][0], $APACenter[0][1], $APACenter[0][2], 0);
1580 place_APA($APACenter[3][0], $APACenter[3][1], $APACenter[3][2], 3);
1594 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1595 #++++++++++++++++++++++++++++++++++++++ solid_APA ++++++++++++++++++++++++++++++++++++++++
1596 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1599 # Must be called only within gen_Cryostat(),
1602 # $_[0] = APA number
1603 # convention: 0 is Largest, 1 is Mid, 2 is Smallest
1610 ####################################################################
1611 ################# APA Frame and Paddle Dimensions ##################
1613 $APA_y = $APAHeight[$APA_i];
1615 $APAFrameZSide_x = $APAFrame_x;
1616 $APAFrameZSide_y = 4*$inch;
1617 $APAFrameZSide_z = $APA_z;
1619 $APAFrameYSide_x = $APAFrame_x;
1620 $APAFrameYSide_y = $APA_y-2*$APAFrameZSide_y;
1621 $APAFrameYSide_z = 4*$inch;
1623 # Two outer Y supports will sandwich the light paddles
1624 $APAFrameYOuterSupport_x = ($APAFrame_x-$LightPaddle_x)/2;
1625 $APAFrameYOuterSupport_y = $APA_y-2*$APAFrameZSide_y;
1626 $APAFrameYOuterSupport_z = 4*$inch;
1628 $EdgeFrameSteelThickness = 0.12*$inch;
1629 $InnerFrameSteelThickness = 0.062*$inch;
1633 <box name="APAFrameYSideHollow\-$APA_i" lunit="cm"
1634 x="$APAFrameYSide_x-2*$EdgeFrameSteelThickness"
1635 y="$APAFrameYSide_y-2*$EdgeFrameSteelThickness"
1636 z="$APAFrameYSide_z"/>
1637 <box name="APAFrameYSideShell\-$APA_i" lunit="cm"
1638 x="$APAFrameYSide_x"
1639 y="$APAFrameYSide_y"
1640 z="$APAFrameYSide_z"/>
1641 <subtraction name="APAFrameYSide\-$APA_i">
1642 <first ref="APAFrameYSideShell\-$APA_i"/>
1643 <second ref="APAFrameYSideHollow\-$APA_i"/>
1644 <positionref ref="posCenter"/>
1645 <rotationref ref="rIdentity"/>
1648 <box name="APAFrameZSideHollow\-$APA_i" lunit="cm"
1649 x="$APAFrameZSide_x-2*$EdgeFrameSteelThickness"
1650 y="$APAFrameZSide_y-2*$EdgeFrameSteelThickness"
1651 z="$APAFrameZSide_z"/>
1652 <box name="APAFrameZSideShell\-$APA_i" lunit="cm"
1653 x="$APAFrameZSide_x"
1654 y="$APAFrameZSide_y"
1655 z="$APAFrameZSide_z"/>
1656 <subtraction name="APAFrameZSide\-$APA_i">
1657 <first ref="APAFrameZSideShell\-$APA_i"/>
1658 <second ref="APAFrameZSideHollow\-$APA_i"/>
1659 <positionref ref="posCenter"/>
1660 <rotationref ref="rIdentity"/>
1663 <box name="APAFrameYOuterSupport\-$APA_i" lunit="cm"
1664 x="$EdgeFrameSteelThickness"
1665 y="$APAFrameYOuterSupport_y"
1666 z="$APAFrameYOuterSupport_z"/>
1677 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1678 #++++++++++++++++++++++++++++++++++++++ vol_APA ++++++++++++++++++++++++++++++++++++++++
1679 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1682 # Must be called only within gen_Cryostat(),
1685 # $_[0] = x APA center
1686 # $_[1] = y APA center
1687 # $_[2] = z APA center
1688 # $_[3] = APA number
1689 # convention: 0 and 3 are Largest, 1 is Mid, 2 is Smallest
1698 <volume name="volAPAFrameYSide\-$APA_i">
1699 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1700 <solidref ref="APAFrameYSide\-$APA_i"/>
1703 <volume name="volAPAFrameZSide\-$APA_i">
1704 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1705 <solidref ref="APAFrameZSide\-$APA_i"/>
1708 <volume name="volAPAFrameYOuterSupport\-$APA_i">
1709 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1710 <solidref ref="APAFrameYOuterSupport\-$APA_i"/>
1719 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1720 #++++++++++++++++++++++++++++++++++++++ place_APA ++++++++++++++++++++++++++++++++++++++++
1721 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1724 # Must be called only within gen_Cryostat(),
1727 # $_[0] = x APA center
1728 # $_[1] = y APA center
1729 # $_[2] = z APA center
1730 # $_[3] = APA number
1731 # convention: 0 and 3 are Largest, 1 is Mid, 2 is Smallest
1738 ####################################################################
1739 ################# APA Frame and Paddle Dimensions ##################
1741 $APA_y = $APAHeight[$APA_i];
1743 $APAFrameZSide_x = $APAFrame_x;
1744 $APAFrameZSide_y = 4*$inch;
1745 $APAFrameZSide_z = $APA_z;
1747 $APAFrameYSide_x = $APAFrame_x;
1748 $APAFrameYSide_y = $APA_y-2*$APAFrameZSide_y;
1749 $APAFrameYSide_z = 4*$inch;
1751 # Two outer Y supports will sandwich the light paddles
1752 $APAFrameYOuterSupport_x = ($APAFrame_x-$LightPaddle_x)/2;
1753 $APAFrameYOuterSupport_y = $APA_y-2*$APAFrameZSide_y;
1754 $APAFrameYOuterSupport_z = 4*$inch;
1756 # if there were an inner support to fill the hole
1757 $APAFrameYInnerSupport_x = $LightPaddle_x;
1759 $EdgeFrameSteelThickness = 0.12*$inch;
1760 $InnerFrameSteelThickness = 0.062*$inch;
1762 #TODO: Place TPCs in here as well, but for now just do frames and paddles
1766 # First put in the frame
1769 <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1770 <position name="posAPAFrameYOuterSupportNeg\-$APA_i" unit="cm"
1771 x="$_[0] - ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1774 <rotationref ref="rIdentity"/>
1777 <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1778 <position name="posAPAFrameYOuterSupportPos\-$APA_i" unit="cm"
1779 x="$_[0] + ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1782 <rotationref ref="rIdentity"/>
1785 <volumeref ref="volAPAFrameYSide\-$APA_i"/>
1786 <position name="posAPAFrameYSideNeg\-$_[3]" unit="cm"
1789 z="$_[2] - $APA_z/2 + $APAFrameYSide_z/2"/>
1790 <rotationref ref="rIdentity"/>
1793 <volumeref ref="volAPAFrameYSide\-$APA_i"/>
1794 <position name="posAPAFrameYSidePos\-$_[3]" unit="cm"
1797 z="$_[2] + $APA_z/2 - $APAFrameYSide_z/2"/>
1798 <rotationref ref="rIdentity"/>
1801 <volumeref ref="volAPAFrameZSide\-$APA_i"/>
1802 <position name="posAPAFrameZSidePos\-$_[3]" unit="cm"
1804 y="$_[1] + $APA_y/2 - $APAFrameZSide_y/2"
1806 <rotationref ref="rIdentity"/>
1809 <volumeref ref="volAPAFrameZSide\-$APA_i"/>
1810 <position name="posAPAFrameZSideNeg\-$_[3]" unit="cm"
1812 y="$_[1] - $APA_y/2 + $APAFrameZSide_y/2"
1814 <rotationref ref="rIdentity"/>
1820 # Now loop through paddle y positions and place them
1821 for( $p=0; $p<$nPaddlesInAPA[$APA_i]; $p++ ){
1826 <volumeref ref="volOpDetSensitive"/>
1827 <position name="posPaddle\-$p\-APA\-$APA_i" unit="cm"
1829 y="$_[1] - $APAHeight[$APA_i]/2 + $PaddleYPositions[$APA_i][$p]"
1831 <rotationref ref="rIdentity"/>
1842 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1843 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1844 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1849 # Create the detector enclosure fragment file name,
1850 # add file to list of output GDML fragments,
1852 $ENCL = "35t_DetEnclosure" . $suffix . ".gdml";
1853 push (@gdmlFiles, $ENCL);
1854 $ENCL = ">" . $ENCL;
1855 open(ENCL) or die("Could not open file $ENCL for writing");
1858 # The standard XML prefix and starting the gdml
1860 <?xml version='1.0'?>
1865 # All the detector enclosure solids.
1869 <box name="DetEnclosure" lunit="cm"
1879 # Detector enclosure structure
1883 <volume name="volDetEnclosure">
1884 <materialref ref="Concrete"/>
1885 <solidref ref="DetEnclosure"/>
1887 <volumeref ref="volCryostat"/>
1888 <position name="posCryo" unit="cm" x="0" y="$CryoInDetEnc_ypos" z="0"/>
1903 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1904 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1905 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1910 # Create the WORLD fragment file name,
1911 # add file to list of output GDML fragments,
1913 $WORLD = "35t_World" . $suffix . ".gdml";
1914 push (@gdmlFiles, $WORLD);
1915 $WORLD = ">" . $WORLD;
1916 open(WORLD) or die("Could not open file $WORLD for writing");
1919 # The standard XML prefix and starting the gdml
1921 <?xml version='1.0'?>
1926 # All the World solids.
1929 <box name="World" lunit="cm"
1939 <volume name="volWorld" >
1940 <materialref ref="Air"/>
1941 <solidref ref="World"/>
1943 <volumeref ref="volDetEnclosure"/>
1944 <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1951 # make_gdml.pl will take care of <setup/>
1956 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1957 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1958 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1960 sub write_fragments()
1962 # This subroutine creates an XML file that summarizes the the subfiles output
1963 # by the other sub routines - it is the input file for make_gdml.pl which will
1964 # give the final desired GDML file. Specify its name with the output option.
1965 # (you can change the name when running make_gdml)
1967 if ( ! defined $output )
1969 $output = "-"; # write to STDOUT
1972 # Set up the output file.
1973 $OUTPUT = ">" . $output;
1974 open(OUTPUT) or die("Could not open file $OUTPUT");
1977 <?xml version='1.0'?>
1979 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1980 that will be zipped together to create a detector description.
1987 <!-- These files contain GDML <constant></constant>
1988 blocks. They are read in separately, so they can be
1989 interpreted into the remaining GDML. See make_gdml.pl for
1995 foreach $filename (@defFiles)
1998 <filename> $filename </filename>
2008 <!-- The GDML file fragments to be zipped together. -->
2012 foreach $filename (@gdmlFiles)
2015 <filename> $filename </filename>