4 # GDML fragment generator for DUNE dual-phase 10kt detector geometry
5 # adapted from single phase cryostat geometry script from Tyler Dalion
6 # by Vyacheslav Galymov < vgalymov@ipnl.in2p3.fr >
8 # !!!NOTE!!!: the readout is on a positive X -- a fix for electric field
9 # direction problem in larsoft
11 #################################################################################
13 # contact tylerdalion@gmail.com for any GDML/generate questions
14 # I would love to help!
16 # Each subroutine generates a fragment GDML file, and the last subroutine
17 # creates an XML file that make_gdml.pl will use to appropriately arrange
18 # the fragment GDML files to create the final desired DUNE GDML file,
19 # to be named by make_gdml output command
21 # If you are playing with different geometries, you can use the
22 # suffix command to help organize your work.
24 ##################################################################################
32 Math::BigFloat->precision(-16);
34 GetOptions( "help|h" => \$help,
35 "suffix|s:s" => \$suffix,
36 "output|o:s" => \$output,
37 "wires|w:s" => \$wires,
38 "workspace|k:s" => \$wkspc);
41 my $FieldCage_switch="on";
42 my $GroundGrid_switch="on";
43 my $Cathode_switch="on";
44 my $ExtractionGrid_switch="on";
50 # If the user requested help, print the usage notes and exit.
55 if ( ! defined $suffix )
57 # The user didn't supply a suffix, so append nothing to the file
63 # Otherwise, stick a "-" before the suffix, so that a suffix of
64 # "test" applied to filename.gdml becomes "filename-test.gdml".
65 $suffix = "-" . $suffix;
71 if (defined $wkspc ) # not done
75 elsif ( $workspace != 0 )
77 print "\t\tCreating smaller workspace geometry.\n";
80 # set wires on to be the default, unless given an input by the user
81 $wires_on = 1; # 1=on, 0=off
89 $basename = "dunedphase10kt_v2";
90 if ( $workspace == 1 )
92 $basename = $basename."_workspace";
94 if ( $workspace == 2 )
96 $basename = $basename."_workspace4x2";
101 $basename = $basename."_nowires";
106 ##################################################################
107 ############## Parameters for Charge Readout Plane ###############
109 # dune10kt dual-phase
110 $wirePitch = 0.3125; # channel pitch
111 $nChannelsViewPerCRM = 960; # channels per collection view
112 $borderCRM = 0.5; # dead space at the border of each CRM
114 # dimensions of a single Charge Readout Module (CRM)
115 $widthCRM_active = $wirePitch * $nChannelsViewPerCRM;
116 $lengthCRM_active = $wirePitch * $nChannelsViewPerCRM;
118 $widthCRM = $widthCRM_active + 2 * $borderCRM;
119 $lengthCRM = $lengthCRM_active + 2 * $borderCRM;
121 # number of CRMs in y and z
125 # create a smaller geometry
126 if( $workspace == 1 )
132 # create a smaller geometry
133 if( $workspace == 2 )
139 # calculate tpc area based on number of CRMs and their dimensions
140 $widthTPCActive = $nCRM_y * $widthCRM; # around 1200
141 $lengthTPCActive = $nCRM_z * $lengthCRM; # around 6000
143 # active volume dimensions
144 $driftTPCActive = 1200.0;
146 # model anode strips as wires
148 $ReadoutPlane = 2 * $padWidth;
150 #$padHeight = 0.0035;
152 ##################################################################
153 ############## Parameters for TPC and inner volume ###############
155 # inner volume dimensions of the cryostat
160 if( $workspace != 0 )
162 #active tpc + 1 m buffer on each side
163 $Argon_y = $widthTPCActive + 200;
164 $Argon_z = $lengthTPCActive + 200;
167 # width of gas argon layer on top
168 $HeightGaseousAr = 100;
170 # size of liquid argon buffer
171 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
172 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
173 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
176 $SteelThickness = 0.12; # membrane
178 $Cryostat_x = $Argon_x + 2*$SteelThickness;
179 $Cryostat_y = $Argon_y + 2*$SteelThickness;
180 $Cryostat_z = $Argon_z + 2*$SteelThickness;
182 ##################################################################
183 ############## DetEnc and World relevant parameters #############
185 $SteelSupport_x = 50;
186 $SteelSupport_y = 100;
187 $SteelSupport_z = 100;
188 $FoamPadding = 80; # only 2 layers ???
189 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
190 $FracMassOfAir = 1 - $FracMassOfSteel;
193 $SpaceSteelSupportToWall = 100;
194 $SpaceSteelSupportToCeiling = 100;
196 $DetEncX = $Cryostat_x
197 + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
199 $DetEncY = $Cryostat_y
200 + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
202 $DetEncZ = $Cryostat_z
203 + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
205 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
207 $RockThickness = 4000;
209 # We want the world origin to be vertically centered on active TPC
210 # This is to be added to the x and y position of every volume in volWorld
212 $OriginXSet = $DetEncX/2.0
217 -$driftTPCActive/2.0;
219 $OriginYSet = $DetEncY/2.0
220 - $SpaceSteelSupportToWall
225 - $widthTPCActive/2.0;
227 # We want the world origin to be at the very front of the fiducial volume.
228 # move it to the front of the enclosure, then back it up through the concrete/foam,
229 # then through the Cryostat shell, then through the upstream dead LAr (including the
230 # dead LAr on the edge of the TPC)
231 # This is to be added to the z position of every volume in volWorld
233 $OriginZSet = $DetEncZ/2.0
234 - $SpaceSteelSupportToWall
241 ##################################################################
242 ############## Field Cage Parameters ###############
244 $FieldShaperLongTubeLength = $lengthTPCActive;
245 $FieldShaperShortTubeLength = $widthTPCActive;
246 $FieldShaperInnerRadius = 1.485;
247 $FieldShaperOuterRadius = 1.685;
248 $FieldShaperTorRad = 1.69;
250 $FieldShaperLength = $FieldShaperLongTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
251 $FieldShaperWidth = $FieldShaperShortTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
253 $FieldShaperSeparation = 5.0;
254 $NFieldShapers = ($driftTPCActive/$FieldShaperSeparation) - 1;
256 $FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2;
257 $FieldCageSizeY = $FieldShaperWidth+2;
258 $FieldCageSizeZ = $FieldShaperLength+2;
261 ##################################################################
262 ############## Parameters for PMTs ###############
264 $pmtNy=int(0.01*$widthTPCActive);
265 $pmtNz=int(0.01*$lengthTPCActive);
266 $pmtN = $pmtNy*$pmtNz; #keeping 1m2 density of pmts
269 $posPMTx = -$Argon_x/2 + 0.5*($HeightPMT);
270 $posPMTx =-$OriginXSet+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation - 100 - 0.5*($HeightPMT); #1m below the cathode
273 @pmt_pos = ('','','');
279 for($i=0;$i<$pmtNy;++$i)
281 for($j=0;$j<$pmtNz;++$j)
283 $pmt_pos[$counter]="x=\"$posPMTx\" y=\"@{[-0.5*($pmtNy-1)*100 + $i*100]}\" z=\"@{[-0.5*($pmtNz-1)*100+$j*100]}\"";
287 print "Number of PMTs : $counter (@{[$pmtNy]} x @{[$pmtNz]})\n";
288 print "widthTPCActive : $widthTPCActive \n";
289 ##################################################################
290 ############### Parameters for det elements ######################
293 #$Cathode_x = $widthTPCActive;
295 #$Cathode_z = $lengthTPCActive;
299 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
302 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
303 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
304 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
308 print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
309 print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
310 print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
311 print " -h prints this message, then quits\n";
316 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
317 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
318 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
323 # Create the <define> fragment file name,
324 # add file to list of fragments,
326 $DEF = $basename."_Def" . $suffix . ".gdml";
327 push (@gdmlFiles, $DEF);
329 open(DEF) or die("Could not open file $DEF for writing");
333 <?xml version='1.0'?>
343 <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
344 <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
345 <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
346 <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
347 <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
348 <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
349 <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
350 <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
351 <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
358 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
359 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
360 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
365 # Create the <materials> fragment file name,
366 # add file to list of output GDML fragments,
368 $MAT = $basename."_Materials" . $suffix . ".gdml";
369 push (@gdmlFiles, $MAT);
372 open(MAT) or die("Could not open file $MAT for writing");
374 # Add any materials special to this geometry by defining a mulitline string
375 # and passing it to the gdmlMaterials::gen_Materials() function.
377 <!-- preliminary values -->
378 <material name="AirSteelMixture" formula="AirSteelMixture">
379 <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
380 <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
381 <fraction n="$FracMassOfAir" ref="Air"/>
385 # add the general materials used anywere
386 print MAT gdmlMaterials::gen_Materials( $asmix );
391 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
392 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
393 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
397 my $TPCActive_x = $driftTPCActive;
398 my $TPCActive_y = $widthCRM_active;
399 my $TPCActive_z = $lengthCRM_active;
402 my $TPC_x = $TPCActive_x + $ReadoutPlane;
403 my $TPC_y = $widthCRM;
404 my $TPC_z = $lengthCRM;
407 $TPC = $basename."_TPC" . $suffix . ".gdml";
408 push (@gdmlFiles, $TPC);
410 open(TPC) or die("Could not open file $TPC for writing");
412 # The standard XML prefix and starting the gdml
414 <?xml version='1.0'?>
419 # All the TPC solids save the wires.
422 <box name="CRM" lunit="cm"
426 <box name="CRMVPlane" lunit="cm"
430 <box name="CRMZPlane" lunit="cm"
434 <box name="CRMActive" lunit="cm"
441 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
442 # in principle we only need only one wire solid, since CRM is a square
443 # but to be more general ...
447 <tube name="CRMWireV"
453 <tube name="CRMWireZ"
464 # Begin structure and create wire logical volumes
467 <volume name="volTPCActive">
468 <materialref ref="LAr"/>
469 <solidref ref="CRMActive"/>
470 <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
477 <volume name="volTPCWireV">
478 <materialref ref="Copper_Beryllium_alloy25"/>
479 <solidref ref="CRMWireV"/>
482 <volume name="volTPCWireZ">
483 <materialref ref="Copper_Beryllium_alloy25"/>
484 <solidref ref="CRMWireZ"/>
491 <volume name="volTPCPlaneV">
492 <materialref ref="LAr"/>
493 <solidref ref="CRMVPlane"/>
496 if ($wires_on==1) # add wires to Y plane (plane with wires reading y position)
498 for($i=0;$i<$nChannelsViewPerCRM;++$i)
500 my $ypos = -0.5 * $TPCActive_y + ($i+0.5)*$wirePitch + 0.5*$padWidth;
504 <volumeref ref="volTPCWireV"/>
505 <position name="posWireV$i" unit="cm" x="0" y="$ypos" z="0"/>
506 <rotationref ref="rIdentity"/>
515 <volume name="volTPCPlaneZ">
516 <materialref ref="LAr"/>
517 <solidref ref="CRMZPlane"/>
521 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
523 for($i=0;$i<$nChannelsViewPerCRM;++$i)
526 my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitch + 0.5*$padWidth;
529 <volumeref ref="volTPCWireZ"/>
530 <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
531 <rotationref ref="rPlus90AboutX"/>
543 $posVplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
547 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
551 $posTPCActive[0] = -$ReadoutPlane;
552 $posTPCActive[1] = 0;
553 $posTPCActive[2] = 0;
556 #wrap up the TPC file
559 <volume name="volTPC">
560 <materialref ref="LAr"/>
561 <solidref ref="CRM"/>
563 <volumeref ref="volTPCPlaneV"/>
564 <position name="posPlaneV" unit="cm"
565 x="$posVplane[0]" y="$posVplane[1]" z="$posVplane[2]"/>
566 <rotationref ref="rIdentity"/>
569 <volumeref ref="volTPCPlaneZ"/>
570 <position name="posPlaneZ" unit="cm"
571 x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
572 <rotationref ref="rIdentity"/>
575 <volumeref ref="volTPCActive"/>
576 <position name="posActive" unit="cm"
577 x="@{[$posTPCActive[0]+$padWidth]}" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
578 <rotationref ref="rIdentity"/>
596 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
597 #++++++++++++++++++++++++++++++++++++++ gen_FieldCage +++++++++++++++++++++++++++++++++++++
598 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
602 $FieldCage = $basename."_FieldCage" . $suffix . ".gdml";
603 push (@gdmlFiles, $FieldCage);
604 $FieldCage = ">" . $FieldCage;
605 open(FieldCage) or die("Could not open file $FieldCage for writing");
607 # The standard XML prefix and starting the gdml
608 print FieldCage <<EOF;
609 <?xml version='1.0'?>
612 # The printing solids used in the Field Cage
613 #print "lengthTPCActive : $lengthTPCActive \n";
614 #print "widthTPCActive : $widthTPCActive \n";
617 print FieldCage <<EOF;
619 <torus name="FieldShaperCorner" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" rtor="$FieldShaperTorRad" deltaphi="90" startphi="0" aunit="deg" lunit="cm"/>
620 <tube name="FieldShaperLongtube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
621 <tube name="FieldShaperShorttube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperShortTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
623 <union name="FSunion1">
624 <first ref="FieldShaperLongtube"/>
625 <second ref="FieldShaperCorner"/>
626 <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
627 <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
630 <union name="FSunion2">
631 <first ref="FSunion1"/>
632 <second ref="FieldShaperShorttube"/>
633 <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
634 <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
637 <union name="FSunion3">
638 <first ref="FSunion2"/>
639 <second ref="FieldShaperCorner"/>
640 <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
641 <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
644 <union name="FSunion4">
645 <first ref="FSunion3"/>
646 <second ref="FieldShaperLongtube"/>
647 <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
650 <union name="FSunion5">
651 <first ref="FSunion4"/>
652 <second ref="FieldShaperCorner"/>
653 <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
654 <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
657 <union name="FSunion6">
658 <first ref="FSunion5"/>
659 <second ref="FieldShaperShorttube"/>
660 <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
661 <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
664 <union name="FieldShaperSolid">
665 <first ref="FSunion6"/>
666 <second ref="FieldShaperCorner"/>
667 <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
668 <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
674 print FieldCage <<EOF;
677 <volume name="volFieldShaper">
678 <materialref ref="Al2O3"/>
679 <solidref ref="FieldShaperSolid"/>
685 print FieldCage <<EOF;
692 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
693 #++++++++++++++++++++++++++++++++++++++ gen_ExtractionGrid +++++++++++++++++++++++++++++++++++
694 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
696 sub gen_ExtractionGrid {
698 $ExtractionGrid = $basename."_ExtractionGrid" . $suffix . ".gdml";
699 push (@gdmlFiles, $ExtractionGrid);
700 $ExtractionGrid = ">" . $ExtractionGrid;
701 open(ExtractionGrid) or die("Could not open file $ExtractionGrid for writing");
703 # The standard XML prefix and starting the gdml
704 print ExtractionGrid <<EOF;
705 <?xml version='1.0'?>
710 $ExtractionGridRadius = 0.05;
711 $ExtractionGridPitch = 0.3;
713 $ExtractionGridSizeX = 2*$ExtractionGridRadius;
714 $ExtractionGridSizeY = $widthTPCActive;
715 $ExtractionGridSizeZ = $lengthTPCActive;
718 print ExtractionGrid <<EOF;
721 <tube name="solExtractionGridCable" rmin="0" rmax="$ExtractionGridRadius" z="$ExtractionGridSizeZ" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
722 <box name="solExtractionGrid" x="@{[$ExtractionGridSizeX]}" y="@{[$ExtractionGridSizeY]}" z="@{[$ExtractionGridSizeZ]}" lunit="cm"/>
728 print ExtractionGrid <<EOF;
732 <volume name="volExtractionGridCable">
733 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
734 <solidref ref="solExtractionGridCable"/>
737 <volume name="volExtractionGrid">
738 <materialref ref="LAr"/>
739 <solidref ref="solExtractionGrid"/>
742 for($ii=0;$ii<$$ExtractionGridSizeY;$ii=$ii+$ExtractionGridPitch)
744 print ExtractionGrid <<EOF;
746 <volumeref ref="volExtractionGridCable"/>
747 <position name="posExtractionGridCable$ii" unit="cm" x="0" y="@{[$ii-0.5*$ExtractionGridSizeY]}" z="0"/>
748 <rotation name="GGrot$aux2" unit="deg" x="0" y="90" z="0" />
754 for($jj=0;$jj<$$ExtractionGridSizeZ;$jj=$jj+$ExtractionGridPitch)
756 print ExtractionGrid <<EOF;
758 <volumeref ref="volExtractionGridCable"/>
759 <position name="posExtractionGridCableLat$jj" unit="cm" x="0" y="0" z="@{[$jj-0.5*$ExtractionGridSizeZ]}"/>
760 <rotation name="GGrot$aux2" unit="deg" x="90" y="0" z="0" />
766 print ExtractionGrid <<EOF;
772 close(ExtractionGrid);
776 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
777 #++++++++++++++++++++++++++++++++++++++ gen_LEMs +++++++++++++++++++++++++++++++++++++
778 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
783 $LEMs = $basename."_LEMs" . $suffix . ".gdml";
784 push (@gdmlFiles, $LEMs);
786 open(LEMs) or die("Could not open file $LEMs for writing");
788 # The standard XML prefix and starting the gdml
790 <?xml version='1.0'?>
795 $LEMsSizeY=$widthTPCActive;
796 $LEMsSizeZ=$lengthTPCActive;
801 <box name="solLEMs" x="@{[$LEMsSizeX]}" y="$LEMsSizeY" z="@{[$LEMsSizeZ]}" lunit="cm"/>
810 <volume name="volLEMs">
811 <materialref ref="Copper_Beryllium_alloy25"/>
812 <solidref ref="solLEMs"/>
820 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
821 #++++++++++++++++++++++++++++++++++++++ gen_GroundGrid +++++++++++++++++++++++++++++++++++
822 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
826 $GroundGrid = $basename."_GroundGrid" . $suffix . ".gdml";
827 push (@gdmlFiles, $GroundGrid);
828 $GroundGrid = ">" . $GroundGrid;
829 open(GroundGrid) or die("Could not open file $GroundGrid for writing");
831 # The standard XML prefix and starting the gdml
832 print GroundGrid <<EOF;
833 <?xml version='1.0'?>
838 $GroundGridSizeX = $FieldShaperWidth+2;
839 $GroundGridSizeY = 2*$FieldShaperOuterRadius+1;
840 $GroundGridSizeZ = $FieldShaperLength+2;
842 $GroundGridInnerStructureLength = $widthTPCActive-1;
843 $GroundGridInnerStructureLengthLat = $lengthTPCActive;
844 $GroundGridInnerStructureWidth = 2;
845 $GroundGridInnerStructureHeight = 4;
846 $GroundGridInnerStructureSeparation = 65.0;
847 $GroundGridInnerStructureNumberOfBars = int($lengthTPCActive/$GroundGridInnerStructureSeparation - 1);
848 $GroundGridInnerStructureNumberOfBarsLat = int($widthTPCActive/$GroundGridInnerStructureSeparation - 1);
849 #print "number of bars $GroundGridInnerStructureNumberOfBars";
851 $GroundGridInnerStructureNumberOfCablesPerInnerSquare = 5.0;
852 $GroundGridInnerStructureCableRadius = 0.1;
853 $GroundGridInnerStructureCableSeparation = $GroundGridInnerStructureSeparation/($GroundGridInnerStructureNumberOfCablesPerInnerSquare+1);
855 print GroundGrid <<EOF;
858 <box name="GroundGridInnerBox" x="@{[$GroundGridInnerStructureWidth]}" y="$GroundGridInnerStructureHeight" z="@{[$GroundGridInnerStructureLength]}" lunit="cm"/>
859 <box name="GroundGridInnerBoxLat" x="@{[$GroundGridInnerStructureWidth]}" y="$GroundGridInnerStructureHeight" z="@{[$GroundGridInnerStructureLengthLat]}" lunit="cm"/>
861 <tube name="GroundGridCable" rmin="0" rmax="$GroundGridInnerStructureCableRadius" z="@{[$GroundGridInnerStructureLength]}" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
863 <box name="GroundGridModule" x="@{[$GroundGridSizeX]}" y="$GroundGridSizeY" z="@{[$GroundGridSizeZ]}" lunit="cm"/>
869 print GroundGrid <<EOF;
873 <volume name="volGroundGridCable">
874 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
875 <solidref ref="GroundGridCable"/>
878 <volume name="volGroundGridInnerBox">
879 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
880 <solidref ref="GroundGridInnerBox"/>
882 <volume name="volGroundGridInnerBoxLat">
883 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
884 <solidref ref="GroundGridInnerBoxLat"/>
887 <volume name="volGGunion">
888 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
889 <solidref ref="FieldShaperSolid"/>
892 <volume name="volGroundGrid">
893 <materialref ref="LAr"/>
894 <solidref ref="GroundGridModule"/>
897 <volumeref ref="volGGunion"/>
898 <position name="posGGunion" unit="cm" x="@{[0.5*$GroundGridSizeX-0.5*$FieldShaperOuterRadius-1]}" y="@{[0.0]}" z="@{[0.0]}"/>
903 $shift = $GroundGridSizeZ - ($GroundGridInnerStructureNumberOfBars+1)*$GroundGridInnerStructureSeparation;
905 for($ii=0;$ii<$GroundGridInnerStructureNumberOfBars;$ii++)
907 print GroundGrid <<EOF;
909 <volumeref ref="volGroundGridInnerBox"/>
910 <position name="posGGInnerBox$ii" unit="cm" x="@{[0.6]}" y="@{[0]}" z="@{[0.5*$shift-0.5*$GroundGridSizeZ+($ii+1)*$GroundGridInnerStructureSeparation]}"/>
911 <rotation name="rotGG$ii" unit="deg" x="0" y="90" z="0" />
917 for($ii=-1;$ii<$GroundGridInnerStructureNumberOfBars;$ii++)
919 for($jj=0;$jj<$GroundGridInnerStructureNumberOfCablesPerInnerSquare;$jj++)
921 print GroundGrid <<EOF;
923 <volumeref ref="volGroundGridCable"/>
924 <position name="posGGCable$ii$jj" unit="cm" x="@{[0]}" y="@{[0]}" z="@{[0.5*$shift-0.5*$GroundGridSizeZ+($ii+1)*$GroundGridInnerStructureSeparation + ($jj+1)*$GroundGridInnerStructureCableSeparation]}"/>
925 <rotation name="rotGGcable$ii$jj" unit="deg" x="0" y="90" z="0" />
933 $shift = $GroundGridSizeX - ($GroundGridInnerStructureNumberOfBarsLat+1)*$GroundGridInnerStructureSeparation;
935 for($ii=0;$ii<$GroundGridInnerStructureNumberOfBarsLat;$ii++)
937 print GroundGrid <<EOF;
939 <volumeref ref="volGroundGridInnerBoxLat"/>
940 <position name="posGGInnerBoxLat$ii" unit="cm" x="@{[0.5*$shift-0.5*$GroundGridSizeX+($ii+1)*$GroundGridInnerStructureSeparation]}" y="0" z="@{[0.0]}"/>
946 print GroundGrid <<EOF;
960 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
961 #++++++++++++++++++++++++++++++++++++++ gen_pmt +++++++++++++++++++++++++++++++++++++
962 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
969 #$PMT_COATING_THICKNESS=0.2;
970 #$PMT_PLATE_THICKNESS=0.4;
971 #$PMT_GLASS_THICKNESS=0.2;
973 $PMT = $basename."_PMT" . $suffix . ".gdml";
974 push (@gdmlFiles, $PMT);
976 open(PMT) or die("Could not open file $PMT for writing");
978 # The standard XML prefix and starting the gdml
980 <?xml version='1.0'?>
986 <tube name="PMTVolume"
993 <tube name="PMT_AcrylicPlate"
1000 <tube name="PMT_plate_coat"
1008 <tube aunit="deg" deltaphi="360" lunit="mm" name="pmtMiddleCylinder" rmax="102.351822048586" rmin="100.351822048586" startphi="0" z="54"/>
1009 <sphere aunit="deg" deltaphi="360" deltatheta="50" lunit="mm" name="sphPartTop" rmax="133" rmin="131" startphi="0" starttheta="0"/>
1010 <union name="pmt0x7fb8f489dfe0">
1011 <first ref="pmtMiddleCylinder"/>
1012 <second ref="sphPartTop"/>
1013 <position name="pmt0x7fb8f489dfe0_pos" unit="mm" x="0" y="0" z="-57.2051768689367"/>
1015 <sphere aunit="deg" deltaphi="360" deltatheta="31.477975238527" lunit="mm" name="sphPartBtm" rmax="133" rmin="131" startphi="0" starttheta="130"/>
1016 <union name="pmt0x7fb8f48a0d50">
1017 <first ref="pmt0x7fb8f489dfe0"/>
1018 <second ref="sphPartBtm"/>
1019 <position name="pmt0x7fb8f48a0d50_pos" unit="mm" x="0" y="0" z="57.2051768689367"/>
1021 <tube aunit="deg" deltaphi="360" lunit="mm" name="pmtBtmTube" rmax="44.25" rmin="42.25" startphi="0" z="72"/>
1022 <union name="solidpmt">
1023 <first ref="pmt0x7fb8f48a0d50"/>
1024 <second ref="pmtBtmTube"/>
1025 <position name="solidpmt_pos" unit="mm" x="0" y="0" z="-104.905637496842"/>
1027 <sphere aunit="deg" deltaphi="360" deltatheta="50" lunit="mm" name="pmt0x7fb8f48a1eb0" rmax="133.2" rmin="133" startphi="0" starttheta="0"/>
1028 <sphere aunit="deg" deltaphi="360" deltatheta="46.5" lunit="mm" name="pmt0x7fb8f48a4860" rmax="131" rmin="130.999" startphi="0" starttheta="0"/>
1036 <volume name="pmtCoatVol">
1037 <materialref ref="LAr"/>
1038 <solidref ref="pmt0x7fb8f48a1eb0"/>
1039 <auxiliary auxtype="SensDet" auxvalue="PhotonDetector"/>
1042 <volume name="allpmt">
1043 <materialref ref="Glass"/>
1044 <solidref ref="solidpmt"/>
1047 <volume name="volPMT">
1048 <materialref ref="LAr"/>
1049 <solidref ref="PMTVolume"/>
1052 <volumeref ref="allpmt"/>
1053 <position name="posallpmtcoat" unit="cm" x="0" y="0" z="@{[1.27*2.54]}"/>
1056 <physvol name="volOpDetSensitive">
1057 <volumeref ref="pmtCoatVol"/>
1058 <position name="posOpDetSensitiveCoat" unit="cm" x="0" y="0" z="@{[1.27*2.54- (2.23*2.54)]}"/>
1071 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1072 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1073 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1078 # Create the cryostat fragment file name,
1079 # add file to list of output GDML fragments,
1081 $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
1082 push (@gdmlFiles, $CRYO);
1083 $CRYO = ">" . $CRYO;
1084 open(CRYO) or die("Could not open file $CRYO for writing");
1087 # The standard XML prefix and starting the gdml
1089 <?xml version='1.0'?>
1093 # All the cryostat solids.
1096 <box name="Cryostat" lunit="cm"
1101 <box name="ArgonInterior" lunit="cm"
1106 <box name="GaseousArgon" lunit="cm"
1107 x="$HeightGaseousAr"
1111 <subtraction name="SteelShell">
1112 <first ref="Cryostat"/>
1113 <second ref="ArgonInterior"/>
1119 # Cryostat structure
1122 <volume name="volSteelShell">
1123 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
1124 <solidref ref="SteelShell" />
1126 <volume name="volGaseousArgon">
1127 <materialref ref="ArGas"/>
1128 <solidref ref="GaseousArgon"/>
1131 if ( $LEMs_switch eq "on" )
1134 $posLEMsX = -0.5*$HeightGaseousAr+0.5+0.5*$LEMsSizeX;
1140 <volumeref ref="volLEMs"/>
1141 <position name="posLEMs" unit="cm" x="$posLEMsX" y="$posLEMsY" z="$posLEMsZ"/>
1148 <volume name="volCryostat">
1149 <materialref ref="LAr" />
1150 <solidref ref="Cryostat" />
1152 <volumeref ref="volGaseousArgon"/>
1153 <position name="posGaseousArgon" unit="cm" x="@{[$Argon_x/2-$HeightGaseousAr/2]}" y="0" z="0"/>
1156 <volumeref ref="volSteelShell"/>
1157 <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1162 if ($tpc_on==1) # place TPC inside croysotat
1165 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1166 for($ii=0;$ii<$nCRM_z;$ii++)
1168 $posZ = -0.5*$Argon_z + $zLArBuffer + ($ii+0.5)*$lengthCRM;
1170 for($jj=0;$jj<$nCRM_y;$jj++)
1172 $posY = -0.5*$Argon_y + $yLArBuffer + ($jj+0.5)*$widthCRM;
1175 <volumeref ref="volTPC"/>
1176 <position name="posTPC\-$ii\-$jj" unit="cm"
1177 x="$posX" y="$posY" z="$posZ"/>
1185 if ( $pmt_switch eq "on" )
1187 for ( $i=0; $i<$pmtN; $i=$i+1 )
1191 <volumeref ref="volPMT"/>
1192 <position name="posPMT$i" unit="cm" @pmt_pos[$i]/>
1193 <rotationref ref="rMinus90AboutY"/>
1199 #The +50 in the x positions must depend on some other parameter
1200 if ( $FieldCage_switch eq "on" ) {
1201 for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) { # pmts with coating
1202 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1205 <volumeref ref="volFieldShaper"/>
1206 <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1207 <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1213 $GroundGridPosX=-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation - 80;
1217 if ( $GroundGrid_switch eq "on" )
1221 <volumeref ref="volGroundGrid"/>
1222 <position name="posGroundGrid01" unit="cm" x="$GroundGridPosX" y="@{[-$GroundGridPosY]}" z="@{[$GroundGridPosZ]}"/>
1223 <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
1230 $CathodePosX=-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation;
1233 if ( $Cathode_switch eq "on" )
1237 <volumeref ref="volGroundGrid"/>
1238 <position name="posGroundGrid01" unit="cm" x="$CathodePosX" y="@{[-$CathodePosY]}" z="@{[$CathodePosZ]}"/>
1239 <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
1246 if ( $ExtractionGrid_switch eq "on" )
1249 $ExtractionGridX = 0.5*$Argon_x-$HeightGaseousAr-0.5-0.5*$ExtractionGridSizeX;
1250 $ExtractionGridY = 0;
1251 $ExtractionGridZ = 0;
1255 <volumeref ref="volExtractionGrid"/>
1256 <position name="posExtractionGrid" unit="cm" x="$ExtractionGridX" y="$ExtractionGridY" z="$ExtractionGridZ"/>
1275 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1276 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1277 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1282 # Create the detector enclosure fragment file name,
1283 # add file to list of output GDML fragments,
1285 $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
1286 push (@gdmlFiles, $ENCL);
1287 $ENCL = ">" . $ENCL;
1288 open(ENCL) or die("Could not open file $ENCL for writing");
1291 # The standard XML prefix and starting the gdml
1293 <?xml version='1.0'?>
1298 # All the detector enclosure solids.
1302 <box name="FoamPadBlock" lunit="cm"
1303 x="@{[$Cryostat_x + 2*$FoamPadding]}"
1304 y="@{[$Cryostat_y + 2*$FoamPadding]}"
1305 z="@{[$Cryostat_z + 2*$FoamPadding]}" />
1307 <subtraction name="FoamPadding">
1308 <first ref="FoamPadBlock"/>
1309 <second ref="Cryostat"/>
1310 <positionref ref="posCenter"/>
1313 <box name="SteelSupportBlock" lunit="cm"
1314 x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
1315 y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
1316 z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
1318 <subtraction name="SteelSupport">
1319 <first ref="SteelSupportBlock"/>
1320 <second ref="FoamPadBlock"/>
1321 <positionref ref="posCenter"/>
1324 <box name="DetEnclosure" lunit="cm"
1333 # Detector enclosure structure
1336 <volume name="volFoamPadding">
1337 <materialref ref="fibrous_glass"/>
1338 <solidref ref="FoamPadding"/>
1341 <volume name="volSteelSupport">
1342 <materialref ref="AirSteelMixture"/>
1343 <solidref ref="SteelSupport"/>
1346 <volume name="volDetEnclosure">
1347 <materialref ref="Air"/>
1348 <solidref ref="DetEnclosure"/>
1351 <volumeref ref="volFoamPadding"/>
1352 <positionref ref="posCryoInDetEnc"/>
1355 <volumeref ref="volSteelSupport"/>
1356 <positionref ref="posCryoInDetEnc"/>
1359 <volumeref ref="volCryostat"/>
1360 <positionref ref="posCryoInDetEnc"/>
1379 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1380 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1381 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1386 # Create the WORLD fragment file name,
1387 # add file to list of output GDML fragments,
1389 $WORLD = $basename."_World" . $suffix . ".gdml";
1390 push (@gdmlFiles, $WORLD);
1391 $WORLD = ">" . $WORLD;
1392 open(WORLD) or die("Could not open file $WORLD for writing");
1395 # The standard XML prefix and starting the gdml
1397 <?xml version='1.0'?>
1402 # All the World solids.
1405 <box name="World" lunit="cm"
1406 x="@{[$DetEncX+2*$RockThickness]}"
1407 y="@{[$DetEncY+2*$RockThickness]}"
1408 z="@{[$DetEncZ+2*$RockThickness]}"/>
1415 <volume name="volWorld" >
1416 <materialref ref="DUSEL_Rock"/>
1417 <solidref ref="World"/>
1420 <volumeref ref="volDetEnclosure"/>
1421 <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1429 # make_gdml.pl will take care of <setup/>
1436 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1437 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1438 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1440 sub write_fragments()
1442 # This subroutine creates an XML file that summarizes the the subfiles output
1443 # by the other sub routines - it is the input file for make_gdml.pl which will
1444 # give the final desired GDML file. Specify its name with the output option.
1445 # (you can change the name when running make_gdml)
1447 # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
1449 if ( ! defined $output )
1451 $output = "-"; # write to STDOUT
1454 # Set up the output file.
1455 $OUTPUT = ">" . $output;
1456 open(OUTPUT) or die("Could not open file $OUTPUT");
1459 <?xml version='1.0'?>
1461 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1462 that will be zipped together to create a detector description.
1469 <!-- These files contain GDML <constant></constant>
1470 blocks. They are read in separately, so they can be
1471 interpreted into the remaining GDML. See make_gdml.pl for
1477 foreach $filename (@defFiles)
1480 <filename> $filename </filename>
1490 <!-- The GDML file fragments to be zipped together. -->
1494 foreach $filename (@gdmlFiles)
1497 <filename> $filename </filename>
1512 print "Some key parameters for dual-phase LAr TPC (unit cm unless noted otherwise)\n";
1513 print "CRM active area : $widthCRM_active x $lengthCRM_active\n";
1514 print "CRM total area : $widthCRM x $lengthCRM\n";
1515 print "TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1516 print "Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1517 print "Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1518 print "TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1519 print "Field Cage : $FieldCage_switch \n";
1520 print "Cathode : $Cathode_switch \n";;
1521 print "GroundGrid : $GroundGrid_switch \n";
1522 print "ExtractionGrid : $ExtractionGrid_switch \n";
1523 print "LEMs : $LEMs_switch \n";
1524 print "PMTs : $pmt_switch \n";
1526 # run the sub routines that generate the fragments
1527 if ( $pmt_switch eq "on" ) { gen_pmt(); }
1528 if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); }
1529 if ( $GroundGrid_switch eq "on" ) { gen_GroundGrid(); }
1530 #if ( $Cathode_switch eq "on" ) { gen_Cathode(); } #Cathode for now has the same geometry as the Ground Grid
1531 if ( $ExtractionGrid_switch eq "on" ) { gen_ExtractionGrid(); }
1532 if ( $LEMs_switch eq "on" ) { gen_LEMs(); }
1535 gen_Define(); # generates definitions at beginning of GDML
1536 gen_Materials(); # generates materials to be used
1537 gen_TPC(); # generate TPC for a given unit CRM
1540 gen_World(); # places the enclosure among DUSEL Rock
1541 write_fragments(); # writes the XML input for make_gdml.pl
1542 # which zips together the final GDML
1543 print "--- done\n\n\n";