3 # This program creates GDML sub-files, with values supplied by user
4 # parameters. Geometry/gdml/make_gdml.pl "zips" together those
5 # sub-files to make a single detector description.
12 # Get the input parameters from an XML file. Optionally append a
13 # suffix to the GDML sub-files we create.
15 GetOptions( "input|i:s" => \$input,
17 "suffix|s:s" => \$suffix,
18 "output|o:s" => \$output);
22 # If the user requested help, print the usage notes and exit.
27 if ( ! defined $suffix )
29 # The user didn't supply a suffix, so append nothing to the file
35 # Otherwise, stick a "-" before the suffix, so that a suffix of
36 # "test" applied to filename.gdml becomes "filename-test.gdml".
37 $suffix = "-" . $suffix;
40 # Create an XML parser.
41 $parser = new XML::LibXML;
43 # Read in the parameters from an XML file. The following command
44 # slurps the entire file into a DOM data structure.
45 $xmldata = $parser->parse_file($input);
47 # Go through each parameter in the DOM data structure:
48 foreach $parameter ( $xmldata->findnodes('/parameters/geometry/parameter') )
50 # Get the name and value attributes for that parameter:
51 $name = $parameter->getAttribute("name");
52 $value = $parameter->getAttribute("value");
54 # Here's the clever part: The following eval creates a variable
55 # with the same name as $name. For example, if $name eq "TPCDepth",
56 # then the following statement assigns the value to $TPCDepth. The
57 # value is in quotes, because some of the parameters have text
58 # strings in them (like "kInch").
60 eval "\$$name = '$value'";
63 # Our calculations and constants depend on the geometry of the wires.
64 $SinUVAngle = sin( deg2rad($UVAngle) );
65 $CosUVAngle = cos( deg2rad($UVAngle) );
66 $TanUVAngle = tan( deg2rad($UVAngle) );
68 # The routines that create the GDML sub-files. Most of the explanatory
69 # comments are in gen_defs().
70 $wires_on=1; # turn wires on=1 or off=0
76 $wire_frame_width=9.5;
77 $wire_plane_height=240;
78 $wire_plane_length=1042;
79 $wires_plength=($wire_plane_length - 2*$wire_frame_width) ;
80 $wires_pwidth=($wire_plane_height - 2*$wire_frame_width) ;
81 $field_cage_width = 200;
82 $field_cage_height = 180;
83 $field_cage_cross_length = sqrt(($field_cage_width)**2+($field_cage_height-50)**2);
84 $field_cage_length = 1000;
85 $field_cage_loop_interval = 1; # =1 is normal, =4 skips 3/4
86 $spacers_on_off = "off"; # "on" or "off" for tube spacers (off saves time)
87 $electronics_height=12;
88 $pmt_switch="off"; #turn on or off depending on pmts wanted
100 gen_groundplate(); # physical volumes defined in gen_tpc()
101 gen_cathode(); # physical volumes defined in gen_tpc()
102 gen_fieldcage(); # physical volumes defined in gen_tpc()
105 if ( $pmt_switch eq "on" ) { gen_pmt(); } # physical volumes defined in gen_cryostat()
118 print "Usage: $0 [-h|--help] -i|--input <parameters-file> [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
119 print " -i/--input can be omitted; <parameters-file> contains geometry and material parameters\n";
120 print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
121 print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
122 print " -h prints this message, then quits\n";
127 # Create the detector constant file. This file is actually temporary,
128 # since the make_gdml.pl program will interpret its contents rather
129 # than include it in the final GDML file.
133 # Set up the output file.
134 $CONSTANTS = "microboone/micro-defs" . $suffix . ".gdml";
135 push (@gdmlFiles, $CONSTANTS); # Add file to list of constant files
136 $CONSTANTS = ">" . $CONSTANTS;
137 open(CONSTANTS) or die("Could not open file $CONSTANTS for writing");
139 # Create some math constants.
142 # Though it's not strictly necessary, make each sub-file a valid
143 # XML (if not GDML) document; that makes it accessible to an XML
146 # Here is a neat way to print out a block of text without getting
147 # involved in a lot of messy quoting and formatting with print
150 print CONSTANTS <<EOF;
151 <?xml version='1.0'?>
153 <constant name="kInch" value="2.54" />
154 <constant name="kPi" value="$pi" />
155 <constant name="kDetEnclosureWidth" value="$DetEnclosureWidth" />
156 <constant name="kDetEnclosureHeight" value="$DetEnclosureHeight" />
157 <constant name="kDetEnclosureLength" value="$DetEnclosureLength" />
158 <constant name="kDirtThickness" value="$DirtThickness" />
159 <constant name="kWorldW" value="100.0*kDetEnclosureWidth"/>
160 <constant name="kWorldH" value="100.0*kDetEnclosureHeight"/>
161 <constant name="kWorldL" value="100.0*kDetEnclosureLength"/>
163 <constant name="kTPCWidth" value="$TPCWidth" />
164 <constant name="kTPCLength" value="$TPCLength" />
165 <constant name="kTPCDepth" value="$TPCDepth" />
166 <constant name="kTPCWallThickness" value="$TPCWallThickness" />
168 <constant name="kTPCWirePlaneThickness" value="$TPCWirePlaneThickness" />
169 <constant name="kTPCWireThickness" value="$TPCWireThickness" />
170 <constant name="kTPCWirePlaneWidth" value="kTPCWidth" />
171 <constant name="kTPCWirePlaneLength" value="kTPCLength" />
172 <constant name="kWireFrameDepth" value="9" />
173 <constant name="kWireFrameWidth" value="$wire_frame_width" />
174 <constant name="kWirePlaneHeight" value="$wire_plane_height" />
175 <constant name="kWirePlaneLength" value="$wire_plane_length" />
176 <constant name="kWireFrameVInHeight" value="0.5*(kWirePlaneHeight-3*kWireFrameWidth)" />
178 <constant name="kTPCWirePitch" value="$TPCWirePitch"/>
179 <constant name="kSinUVAngle" value="$SinUVAngle"/>
180 <constant name="kCosUVAngle" value="$CosUVAngle"/>
181 <constant name="kTanUVAngle" value="$TanUVAngle"/>
182 <constant name="kTPCWireXPitch" value="kTPCWirePitch/kCosUVAngle"/>
184 <constant name="kCathodeFrameWidth" value="9" />
185 <constant name="kCathodeFrameDepth" value="5" />
186 <constant name="kCathodePlateDepth" value="0.1" />
187 <constant name="kCathodeWidth" value="5.1" />
188 <constant name="kCathodeHeight" value="240" />
189 <constant name="kCathodeLength" value="1042" />
190 <constant name="kCathodeFrameVInHeight" value="0.5*(kCathodeHeight-3*kCathodeFrameWidth)" />
192 <constant name="kGroundPlateWidth" value="224" />
193 <constant name="kGroundPlateHeight" value="0.1" />
194 <constant name="kGroundPlateLength" value="1100" />
195 <constant name="kGroundBeamWidth" value="2.5" />
196 <constant name="kGroundBeamHeight" value="2.5" />
197 <constant name="kGroundBeamLength" value="kGroundPlateLength" />
198 <constant name="kGroundBeamThickness" value=".15" />
208 my $WirePlusRotation = $UVAngle + 90;
209 my $WireMinusRotation = $UVAngle - 90;
211 $ROTATIONS = "microboone/micro-rotations" . $suffix . ".gdml";
212 push (@gdmlFiles, $ROTATIONS); # Add file to list of GDML fragments
213 $ROTATIONS = ">" . $ROTATIONS;
214 open(ROTATIONS) or die("Could not open file $ROTATIONS for writing");
216 print ROTATIONS <<EOF;
217 <?xml version='1.0'?>
219 <rotation name="rPlus30AboutX" unit="deg" x="30" y="0" z="0"/>
220 <rotation name="rPlus60AboutX" unit="deg" x="60" y="0" z="0"/>
221 <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
222 <rotation name="rMinus90AboutX" unit="deg" x="-90" y="0" z="0"/>
223 <rotation name="rPlusUVAngleAboutX" unit="deg" x="150" y="0" z="0"/>
224 <rotation name="rPlus150AboutX" unit="deg" x="150" y="0" z="0"/>
225 <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
226 <rotation name="rMinusUVAngleAboutX" unit="deg" x="-30" y="0" z="0"/>
227 <rotation name="rPlus30AboutY" unit="deg" x="0" y="30" z="0"/>
228 <rotation name="rPlus60AboutY" unit="deg" x="0" y="60" z="0"/>
229 <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
230 <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
231 <rotation name="rMinus90AboutY" unit="deg" x="0" y="-90" z="0"/>
232 <rotation name="rPlus90AboutZ" unit="deg" x="0" y="0" z="90"/>
233 <rotation name="rMinus90AboutZ" unit="deg" x="0" y="0" z="-90"/>
234 <rotation name="rPlus180AboutZ" unit="deg" x="0" y="0" z="180"/>
235 <rotation name="rMinus180AboutZ" unit="deg" x="0" y="0" z="-180"/>
236 <rotation name="rMinus90AboutYPlus180AboutZ" unit="deg" x="0" y="-90" z="180"/>
237 <rotation name="rMinus90AboutYMinus90AboutZ" unit="deg" x="0" y="-90" z="-90"/>
238 <rotation name="rPlus90AboutYPlus180AboutZ" unit="deg" x="0" y="90" z="180"/>
239 <rotation name="rMinus90AboutYPlus90AboutZ" unit="deg" x="0" y="-90" z="90"/>
240 <rotation name="rPlus90AboutYMinus90AboutZ" unit="deg" x="0" y="90" z="-90"/>
241 <rotation name="rPlus90AboutXPlus90AboutZ" unit="deg" x="90" y="0" z="90"/>
242 <rotation name="rPlus90AboutXPlus180AboutZ" unit="deg" x="90" y="0" z="180"/>
243 <rotation name="rPlus90AboutXMinus90AboutY" unit="deg" x="90" y="-90" z="0"/>
244 <rotation name="rPlus90AboutXMinus90AboutZ" unit="deg" x="90" y="0" z="-90"/>
245 <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
246 <rotation name="rPMTRotation1" unit="deg" x="90" y="270" z="0"/>
255 # Create the materials file name and open it.
256 $MATERIALS = "materials" . $suffix . ".gdml";
257 push (@gdmlFiles, $MATERIALS); # Add file to list of GDML fragments
258 $MATERIALS = ">" . $MATERIALS;
259 open(MATERIALS) or die("Could not open file $MATERIALS for writing");
261 # Write the standard XML prefix.
262 print MATERIALS <<EOF;
263 <?xml version='1.0'?>
266 # Go back the DOM structure read in near the beginning of the
267 # program. For each <materials /> element (and there'll probably
269 foreach $materials ( $xmldata->findnodes('/parameters/materials') )
271 # Convert that element back to text, and write it out.
272 print MATERIALS $materials->toString;
279 # This is a re-write of Brian Rebel's gen_microvertplane.C into
280 # Perl. It contructs the TPC wire plane for the Y view.
282 sub gen_microvertplane()
284 my $NumberWires = int( $TPCLength / $TPCWirePitch ) - 1;
286 $GDML = "micro-vertplane" . $suffix . ".gdml";
287 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
289 open(GDML) or die("Could not open file $GDML for writing");
291 # Define the solids and structures: the wires and the TPC wire plane.
293 <?xml version='1.0'?>
296 <tube name="TPCWireVert"
297 rmax="0.5*kTPCWireThickness"
302 <box name="TPCPlaneVert"
303 x="kTPCWirePlaneThickness"
309 <volume name="volTPCWireVert">
310 <materialref ref="Titanium"/>
311 <solidref ref="TPCWireVert"/>
313 <volume name="volTPCPlaneVert">
314 <materialref ref="LAr"/>
315 <solidref ref="TPCPlaneVert"/>
319 for ( $i = 0; $i < $NumberWires; ++$i)
323 <volumeref ref="volTPCWireVert"/>
324 <position name="posTPCWireVert$i" unit="cm" z="(-0.5*kTPCLength)+(($i+1)*kTPCWirePitch)" x="0" y="0"/>
325 <rotationref ref="rPlus90AboutX"/>
340 # This is a re-write of Brian Rebel's gen_microplane.C into Perl. It
341 # constructs the TPC wire plane for the U or V view.
347 $GDML = "micro-plane" . $suffix . ".gdml";
348 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
350 open(GDML) or die("Could not open file $GDML for writing");
352 # Calculate the number of wire ends on a given y-edge of the plane.
353 my $TPCYWirePitch = $TPCWirePitch / $CosUVAngle;
354 my $NumberWiresPerEdge = int( $TPCLength / $TPCYWirePitch );
356 # How many side wires will be "cut off" by the lower or higher
358 my $NumberSideWires = int( $TanUVAngle * $TPCWidth / $TPCYWirePitch );
360 # The number of full-length "center" wires.
361 my $NumberCenterWires = $NumberWiresPerEdge - $NumberSideWires;
365 <?xml version='1.0'?>
370 # wires on either end of the tpc
371 for($i = 0; $i < $NumberSideWires; ++$i)
374 <tube name="TPCWire$i"
375 rmax="0.5*kTPCWireThickness"
376 z="kTPCWireXPitch*($i+1)/kSinUVAngle"
383 # The solids for the middle wire and the TPC wire plane, and start off the structures.
385 <tube name="TPCWireCommon"
386 rmax="0.5*kTPCWireThickness"
387 z="kTPCWidth/kCosUVAngle"
392 x="kTPCWirePlaneThickness"
400 # the wires at either end of the plane
401 for ($i = 0; $i < $NumberSideWires; ++$i)
404 <volume name="volTPCWire$i">
405 <materialref ref="Titanium"/>
406 <solidref ref="TPCWire$i"/>
412 # The wires in the middle of the plane, and the plane itself.
414 <volume name="volTPCWireCommon">
415 <materialref ref="Titanium"/>
416 <solidref ref="TPCWireCommon"/>
418 <volume name="volTPCPlane">
419 <materialref ref="LAr"/>
420 <solidref ref="TPCPlane"/>
423 # the wires at the -z end
424 for ($i = 0; $i < $NumberSideWires; ++$i)
428 <volumeref ref="volTPCWire$i"/>
429 <position name="posTPCWire$i" unit="cm" y="-0.5*kTPCWidth+0.5*($i+1)*kTPCWireXPitch/kTanUVAngle" z="0.5*(-kTPCLength+($i+1)*kTPCWireXPitch)" x="0"/>
430 <rotationref ref="rPlusUVAngleAboutX"/>
435 # The wires in the middle.
436 for ($i = 0; $i < $NumberCenterWires; ++$i)
438 my $j = $NumberSideWires+$i;
441 <volumeref ref="volTPCWireCommon"/>
442 <position name="posTPCWire$j" unit="cm" y="0" z="-0.5*kTPCWirePlaneLength+kTPCWireXPitch*(0.5*$NumberSideWires + $i+1)" x="0"/>
443 <rotationref ref="rPlusUVAngleAboutX"/>
448 # the wires at the +z end
449 for ($i = 0; $i < $NumberSideWires; ++$i)
451 my $j = $NumberSideWires-$i-1;
452 my $k = $NumberCenterWires+$NumberSideWires+$i;
456 <volumeref ref="volTPCWire$j"/>
457 <position name="posTPCWire$k" unit="cm" y="0.5*kTPCWidth-0.5*($j+1)*kTPCWireXPitch/kTanUVAngle" z="0.5*kTPCWirePlaneLength-0.5*kTPCWireXPitch*($j+1)" x="0"/>
458 <rotationref ref="rPlusUVAngleAboutX"/>
473 # This is a re-write of Brian Rebel's gen_microvertplane.C into
474 # Perl. It contructs the TPC wire plane for the Y view.
476 sub gen_tpcplanevert_bad()
480 ##### temporary edits:
481 ##### - TPCPlaneVert y="TPCWidth" z="kTPCLength"
482 ##### - TPCWireVert y="TPCWidth"
483 ##### - (above)my $NumberWires = int($TPCLength / $TPCWirePitch ) - 1
487 my $NumberWires = int( ( $wires_plength ) / $TPCWirePitch ) - 1;
489 $GDML = "microboone/micro-vertplane" . $suffix . ".gdml";
490 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
492 open(GDML) or die("Could not open file $GDML for writing");
494 # Define the solids and structures: the wires and the TPC wire plane.
497 <?xml version='1.0'?>
500 <tube name="TPCWireVert"
501 rmax="0.5*kTPCWireThickness"
506 <box name="TPCPlaneVert"
507 x="kTPCWirePlaneThickness"
513 <volume name="volTPCWireVert">
514 <materialref ref="Titanium"/>
515 <solidref ref="TPCWireVert"/>
517 <volume name="volTPCPlaneVert">
518 <materialref ref="LAr"/>
519 <solidref ref="TPCPlaneVert"/>
523 for ( $i = 0; $i < ( $NumberWires / $wire_int ); ++$i )
528 <volumeref ref="volTPCWireVert"/>
529 <position name="posTPCWireVert$i" unit="cm" z="(-0.5*kTPCWirePlaneLength)+kTPCWirePitch*($j+1)" x="0" y="0"/>
530 <rotationref ref="rPlus90AboutX"/>
544 # This is a re-write of Brian Rebel's gen_microplane.C into Perl. It
545 # constructs the TPC wire plane for the U or V view.
547 sub gen_tpcplane_bad()
550 my $NumberWires = $TPCLength / $TPCWirePitch - 1;
552 $GDML = "microboone/micro-plane" . $suffix . ".gdml";
553 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
555 open(GDML) or die("Could not open file $GDML for writing");
557 # Calculate the number of wire ends on a given y-edge of the plane.
558 my $TPCYWirePitch = $TPCWirePitch / $CosUVAngle;
559 my $NumberWiresPerEdge = int( $TPCLength / $TPCYWirePitch );
560 #my $NumberWiresPerEdge = int( ( $wires_plength ) / $TPCYWirePitch );
562 # How many side wires will be "cut off" by the lower or higher
564 #my $NumberSideWires = int( $TanUVAngle * ( $wires_pwidth ) / $TPCYWirePitch );
565 my $NumberSideWires = int( $TanUVAngle * $TPCWidth / $TPCYWirePitch ) - 1;
568 # The number of full-length "center" wires.
569 my $NumberCenterWires = $NumberWiresPerEdge - $NumberSideWires;
573 <?xml version='1.0'?>
578 # wires on either end of the tpc
579 for ($i = 0; $i < $NumberSideWires; ++$i)
582 <tube name="TPCWire$i"
583 rmax="0.5*kTPCWireThickness"
584 z="kTPCWireXPitch*($i+1)/kSinUVAngle"
591 # The solids for the middle wire and the TPC wire plane, and start off the structures.
593 <tube name="TPCWireCommon"
594 rmax="0.5*kTPCWireThickness"
595 z="kTPCWidth/kCosUVAngle"
600 x="kTPCWirePlaneThickness"
608 # the wires at either end of the plane
609 for ($i = 0; $i < $NumberSideWires; ++$i)
612 <volume name="volTPCWire$i">
613 <materialref ref="Titanium"/>
614 <solidref ref="TPCWire$i"/>
620 # The wires in the middle of the plane, and the plane itself.
622 <volume name="volTPCWireCommon">
623 <materialref ref="Titanium"/>
624 <solidref ref="TPCWireCommon"/>
626 <volume name="volTPCPlane">
627 <materialref ref="LAr"/>
628 <solidref ref="TPCPlane"/>
631 # the wires at the -z end
632 for ($i = 0; $i < $NumberSideWires; ++$i)
636 <volumeref ref="volTPCWire$i"/>
637 <position name="posTPCWire$i" unit="cm" y="(-0.5*kTPCWirePlaneWidth)+0.5*($i+1)*kTPCWireXPitch/kTanUVAngle" z="-0.5*kTPCWirePlaneLength+0.5*kTPCWireXPitch*($i+1)" x="0"/>
638 <rotationref ref="rPlusUVAngleAboutX"/>
643 # The wires in the middle.
644 for ($i = 0; $i < $NumberCenterWires - 1 ; ++$i)
646 my $j = $NumberSideWires+$i;
649 <volumeref ref="volTPCWireCommon"/>
650 <position name="posTPCWire$j" unit="cm" y="0" z="(-0.5*kTPCWirePlaneLength)+kTPCWireXPitch*(0.5*$NumberSideWires + $i+1)" x="0"/>
651 <rotationref ref="rPlusUVAngleAboutX"/>
656 # the wires at the +z end
657 for ($i = 0; $i < $NumberSideWires ; ++$i)
659 my $j = $NumberSideWires-$i-1;
660 my $k = $NumberCenterWires+$NumberSideWires+$i;
664 <volumeref ref="volTPCWire$j"/>
665 <position name="posTPCWire$k" unit="cm" y="0.5*kTPCWirePlaneWidth-0.5*($j+1)*kTPCWireXPitch/kTanUVAngle" z="0.5*kTPCWirePlaneLength-0.5*kTPCWireXPitch*($j+1)" x="0"/>
666 <rotationref ref="rPlusUVAngleAboutX"/>
682 # subdirectory to write field cage
683 sub gen_fieldcage() {
685 # Set up the output file.
686 $FIELDCAGE = "microboone/micro-fieldcage.gdml";
687 push (@gdmlFiles, $FIELDCAGE); # Add file to list of constant files
688 $FIELDCAGE = ">" . $FIELDCAGE;
689 open(FIELDCAGE) or die("Could not open file $FIELDCAGE for writing");
691 # Print the Field Cage constants
692 print FIELDCAGE <<EOF;
694 <constant name="kFieldCageTPCClearance" value="5*kInch" />
696 <constant name="kFieldCageTubeRadius" value="0.5*kInch" />
697 <constant name="kFieldCageTubeThickness" value="0.25*kInch" />
698 <constant name="kFieldCageBeamDepth" value="12.5"/>
699 <constant name="kFieldCageBeamWidth" value="2.5"/>
700 <constant name="kFieldCageCrossDepth" value="2.5"/>
701 <constant name="kFieldCageCrossWidth" value="4"/>
702 <constant name="kFieldCageCrossLength" value="$field_cage_cross_length"/>
704 <constant name="kTPCTotalLength" value="$field_cage_length"/>
705 <constant name="kTPCTotalWidth" value="$field_cage_width"/>
706 <constant name="kTPCTotalHeight" value="$field_cage_height"/>
708 <constant name="kFieldCageLoopLength" value="kTPCTotalLength+2*(kFieldCageTPCClearance+2*kFieldCageTubeRadius)"/>
709 <constant name="kFieldCageLoopWidth" value="$field_cage_width"/>
710 <constant name="kFieldCageLoopHeight" value="kTPCTotalHeight+2*(kFieldCageTPCClearance+2*kFieldCageTubeRadius)"/>
712 <constant name="kFieldCageCornerRadius" value="0.5*kFieldCageTPCClearance"/>
713 <constant name="kFieldCageCornerY" value="(0.5*kFieldCageLoopHeight)-kFieldCageCornerRadius-kFieldCageTubeRadius"/>
714 <constant name="kFieldCageCornerZ" value="(0.5*kFieldCageLoopLength)-kFieldCageCornerRadius-kFieldCageTubeRadius"/>
716 <constant name="kFieldCageHeight" value="kFieldCageLoopHeight+2*(kFieldCageBeamDepth+kFieldCageCrossDepth)"/>
717 <constant name="kFieldCageLength" value="kFieldCageLoopLength+2*(kFieldCageBeamDepth+kFieldCageCrossDepth)"/>
718 <constant name="kFieldCageWidth" value="$field_cage_width"/>
720 <constant name="kFieldCageBeamYInt" value="0.5*(kFieldCageLoopHeight-50)"/>
721 <constant name="kFieldCageBeamZPos" value="0.5*(kFieldCageLoopLength)"/>
722 <constant name="kFieldCageBeamYPos" value="0.5*(kFieldCageLoopHeight)"/>
723 <constant name="kFieldCageBeamZInt" value="0.5*(kFieldCageLoopLength-40)"/>
725 <constant name="kFieldCageCrossYPos" value="0.5*(kFieldCageLoopHeight+kFieldCageCrossDepth)+kFieldCageBeamDepth"/>
726 <constant name="kFieldCageCrossZPos" value="0.5*(kFieldCageLoopLength+kFieldCageCrossDepth)+kFieldCageBeamDepth"/>
730 # Prints Field Cage solids
731 print FIELDCAGE <<EOF;
733 <tube name="FieldCageTubeZ"
734 rmin="kFieldCageTubeRadius - kFieldCageTubeThickness"
735 rmax="kFieldCageTubeRadius"
736 z="kFieldCageLoopLength-2*(kFieldCageCornerRadius+kFieldCageTubeRadius)"
740 <tube name="FieldCageTubeY"
741 rmin="kFieldCageTubeRadius - kFieldCageTubeThickness"
742 rmax="kFieldCageTubeRadius"
743 z="kFieldCageLoopHeight-2*(kFieldCageCornerRadius+kFieldCageTubeRadius)"
750 # Prints Field Cage tube loop sub-structure
751 print FIELDCAGE <<EOF;
753 <volume name="volFieldCageTubeTop">
754 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
755 <solidref ref="FieldCageTubeZ"/>
757 <volume name="volFieldCageTubeBot">
758 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
759 <solidref ref="FieldCageTubeZ"/>
761 <volume name="volFieldCageTubeFront">
762 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
763 <solidref ref="FieldCageTubeY"/>
765 <volume name="volFieldCageTubeBack">
766 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
767 <solidref ref="FieldCageTubeY"/>
777 # Cathode solids and volumes
780 $CATHODE = "microboone/micro-cathode" . $suffix . ".gdml";
781 push (@gdmlFiles, $CATHODE); # Add file to list of GDML fragments
782 $CATHODE = ">" . $CATHODE;
783 open(CATHODE) or die("Could not open file $CATHODE for writing");
787 <?xml version='1.0'?>
790 <box name="CathodePlate"
792 x="kCathodePlateDepth"
797 <volume name="volCathodePlate">
798 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
799 <solidref ref="CathodePlate"/>
807 sub gen_groundplate() {
808 #this subroutine will produce the gdml fragment for ground plate
810 $GROUNDPLATE = "microboone/micro-groundplate" . $suffix . ".gdml";
811 push (@gdmlFiles, $GROUNDPLATE); # Add file to list of GDML fragments
812 $GROUNDPLATE = ">" . $GROUNDPLATE;
813 open(GROUNDPLATE) or die("Could not open file $GROUNDPLATE for writing");
815 print GROUNDPLATE <<EOF;
816 <?xml version='1.0'?>
819 <box name="GroundPlate"
821 x="kGroundPlateWidth"
822 y="kGroundPlateHeight"
823 z="kGroundPlateLength"/>
826 <volume name="volGroundPlate">
827 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
828 <solidref ref="GroundPlate"/>
838 # Parameterize the TPC and the planes within it.
841 # Set up the output file.
842 $GDML = "microboone/micro-tpc" . $suffix . ".gdml";
843 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
845 open(GDML) or die("Could not open file $GDML for writing");
848 <?xml version='1.0'?>
853 x="kTPCDepth+kTPCWallThickness+(2*kTPCWirePlaneThickness)"
854 y="kTPCWidth+(2*kTPCWallThickness)+($electronics_height)"
855 z="kTPCLength+(2*kTPCWallThickness)"/>
858 <volume name="volTPC">
859 <materialref ref="LAr"/>
860 <solidref ref="TPC"/>
863 # Ground Plane physical volumes
871 <volumeref ref="volGroundPlate"/>
872 <position name="posGroundPlate" unit="cm" x="$ground_plate_X+0.25" y="$ground_plate_Y-0.5*(kGroundBeamHeight)" z="0"/>
877 # Cathode Plane physical volumes
878 # Center = (0.5*(kTPCWidth-kCathodeWidth),0,0)
879 $Cathode_X="0.5*(kTPCWidth-kCathodeWidth)";
880 $Cathode_plate_offset="0.5*kCathodePlateDepth";
881 $Cathode_frame_position="$Cathode_X+($Cathode_plate_offset)";
885 <volumeref ref="volCathodePlate"/>
886 <position name="posCathodePlate" unit="cm" x="$Cathode_X-0.5*(kCathodeFrameDepth)-0.1" y="0" z="0"/>
891 # Wire Plane physical volumes
892 # Center = ( -0.5*(kTPCWidth-kWireFrameWidth) , 0 , 0 )
895 <volumeref ref="volTPCPlaneVert"/>
896 <position name="posTPCPlaneVert" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)-(2*$TPCWirePlaneSpacing)" y="0" z="0"/>
899 <volumeref ref="volTPCPlane"/>
900 <position name="posTPCPlane" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)-$TPCWirePlaneSpacing" y="0" z="0"/>
903 <volumeref ref="volTPCPlane"/>
904 <position name="posTPCPlane2" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)" y="0" z="0"/>
905 <rotationref ref="rPlus180AboutY"/>
912 while ( $space < ( $field_cage_width / 2 ) ) {
916 <volumeref ref="volFieldCageTubeTop"/>
917 <position name="posFieldCageTubeTopA$i" unit="cm" x="$xPos" y="0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
920 <volumeref ref="volFieldCageTubeBot"/>
921 <position name="posFieldCageTubeBotA$i" unit="cm" x="$xPos" y="-0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
924 <volumeref ref="volFieldCageTubeFront"/>
925 <position name="posFieldCageTubeFrontA$i" unit="cm" x="$xPos" y="0" z="0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
926 <rotation name="rFieldCageVertPlusA$i" unit="deg" x="90" y="0" z="0"/>
929 <volumeref ref="volFieldCageTubeBack"/>
930 <position name="posFieldCageTubeBackA$i" unit="cm" x="$xPos" y="0" z="-0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
931 <rotation name="rFieldCageVertMinusA$i" unit="deg" x="-90" y="0" z="0"/>
936 <volumeref ref="volFieldCageTubeTop"/>
937 <position name="posFieldCageTubeTopB$i" unit="cm" x="-$xPos" y="0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
940 <volumeref ref="volFieldCageTubeBot"/>
941 <position name="posFieldCageTubeBotB$i" unit="cm" x="-$xPos" y="-0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
944 <volumeref ref="volFieldCageTubeFront"/>
945 <position name="posFieldCageTubeFrontB$i" unit="cm" x="-$xPos" y="0" z="0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
946 <rotation name="rFieldCageVertFrontB$i" unit="deg" x="90" y="0" z="0"/>
949 <volumeref ref="volFieldCageTubeBack"/>
950 <position name="posFieldCageTubeBackB$i" unit="cm" x="-$xPos" y="0" z="-0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
951 <rotation name="rFieldCageVertBackB$i" unit="deg" x="-90" y="0" z="0"/>
954 $space+=4*$field_cage_loop_interval;
960 # Closes TPC volume definition space
971 # Generates Ben Jones's PMT micro-pmtdef (with temporary edit to ellipsoid shapes
974 $PMT = "microboone/micro-pmtdef" . $suffix . ".gdml";
975 push (@gdmlFiles, $PMT); # Add file to list of GDML fragments
977 open(PMT) or die("Could not open file $PMT for writing");
981 <tube name="PMTVolume"
984 deltaphi="2*(3.1415926535897)"
987 <tube name="PMT_TPBCoating"
990 deltaphi="2*(3.1415926535897)"
993 <tube name="PMT_AcrylicPlate"
996 deltaphi="2*(3.1415926535897)"
999 <tube name="PMT_Stalk"
1002 deltaphi="2*(3.1415926535897)"
1005 <tube name="PMT_SteelBase"
1008 deltaphi="2*(3.1415926535897)"
1011 <tube name="PMT_Underside"
1014 deltaphi="2*3.1415926535897"
1017 <tube name="PMT_Lens"
1020 deltaphi="2*3.1415926535897"
1025 <volume name="vol_PMT_TPBCoating">
1026 <materialref ref="TPB"/>
1027 <solidref ref="PMT_TPBCoating"/>
1029 <volume name="vol_PMT_AcrylicPlate">
1030 <materialref ref="Acrylic"/>
1031 <solidref ref="PMT_AcrylicPlate"/>
1033 <volume name="vol_PMT_Stalk">
1034 <materialref ref="Glass"/>
1035 <solidref ref="PMT_Stalk"/>
1037 <volume name="vol_PMT_SteelBase">
1038 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1039 <solidref ref="PMT_SteelBase"/>
1041 <volume name="vol_PMT_Underside">
1042 <materialref ref="Glass"/>
1043 <solidref ref="PMT_Underside"/>
1045 <volume name="volOpDetSensitive">
1046 <materialref ref="LAr"/>
1047 <solidref ref="PMT_Lens"/>
1049 <volume name="volPMT">
1050 <materialref ref="LAr"/>
1051 <solidref ref="PMTVolume"/>
1053 <volumeref ref="vol_PMT_TPBCoating"/>
1054 <position name="pos_PMT_TPBCoating" unit="cm" x="0" y="0" z="(5.5 * 2.54) - (0.5 * 0.005)"/>
1057 <volumeref ref="vol_PMT_AcrylicPlate"/>
1058 <position name="pos_PMT_AcrylicPlate" unit="cm" x="0" y="0" z="(5.5 * 2.54) - 0.01 - (0.5 * 0.2)"/>
1061 <volumeref ref="vol_PMT_Stalk"/>
1062 <position name="pos_PMT_Stalk" unit="cm" x="0" y="0" z="(3.0 * 2.54)-(5.5 * 2.54)"/>
1065 <volumeref ref="vol_PMT_SteelBase"/>
1066 <position name="pos_PMT_SteelBase" unit="cm" x="0" y="0" z="(0.75 * 2.54)-(5.5 * 2.54)"/>
1069 <volumeref ref="volOpDetSensitive"/>
1070 <position name="pos_PMT_Lens" unit="cm" x="0" y="0" z="(7.0 * 2.54)-(5.5 * 2.54)"/>
1073 <volumeref ref="vol_PMT_Underside"/>
1074 <position name="pos_PMT_Underside" unit="cm" x="0" y="0" z="(7.0 * 2.54)-(5.5 * 2.54)"/>
1085 #Parameterize the steel cryostat that encloses the TPC.
1088 # Set up the output file.
1089 $CRYOSTAT = "microboone/micro-cryostat" . $suffix . ".gdml";
1090 push (@gdmlFiles, $CRYOSTAT); # Add file to list of GDML fragments
1091 $CRYOSTAT = ">" . $CRYOSTAT;
1092 open(CRYOSTAT) or die("Could not open file $CRYOSTAT for writing");
1094 print CRYOSTAT <<EOF;
1095 <?xml version='1.0'?>
1098 <tube name="Cryostat"
1099 rmax="$CryostatOuterRadius"
1100 z="$CryostatLength+2*$CryostatEndcapThickness"
1104 <tube name="SteelTube"
1105 rmin="$CryostatInnerRadius"
1106 rmax="$CryostatOuterRadius"
1114 print CRYOSTAT <<EOF;
1118 <volume name="volSteelTube">
1119 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1120 <solidref ref="SteelTube"/>
1122 <volume name="volCryostat">
1123 <materialref ref="LAr"/>
1124 <solidref ref="Cryostat"/>
1126 <volumeref ref="volSteelTube"/>
1127 <position name="posSteelTube" unit="cm" x="0" y="0" z="0"/>
1130 <volumeref ref="volTPC"/>
1131 <position name="posTPC" unit="cm" x="0.0" y="0.97" z="0"/>
1136 @pmt_pos = ( ' x="-147.8" y="3.21654" z="-463.358"',
1137 ' x="-147.76" y="-52.6635" z="-403.121"',
1138 ' x="-147.8" y="59.0965" z="-403.121"',
1139 ' x="-147.76" y="-52.6635" z="-361.449"',
1140 ' x="-147.8" y="59.0965" z="-361.449"',
1141 ' x="-147.8" y="3.21654" z="-308.81"',
1142 ' x="-147.8" y="3.21654" z="-249.591"',
1143 ' x="-147.76" y="-52.6635" z="-194.487"',
1144 ' x="-147.8" y="59.0965" z="-194.487"',
1145 ' x="-147.76" y="-52.6635" z="-155.932"',
1146 ' x="-147.8" y="59.0965" z="-155.932"',
1147 ' x="-147.8" y="3.21654" z="-104.833"',
1148 ' x="-147.8" y="3.21654" z="-38.3029"',
1149 ' x="-147.76" y="-52.6635" z="13.6988"',
1150 ' x="-147.8" y="59.0965" z="13.6988"',
1151 ' x="-147.76" y="-52.6635" z="54.0326"',
1152 ' x="-147.8" y="59.0965" z="54.0326"',
1153 ' x="-147.8" y="3.21654" z="108.648"',
1154 ' x="-147.8" y="3.21654" z="175.178"',
1155 ' x="-147.76" y="-52.6635" z="229.136"',
1156 ' x="-147.8" y="59.0965" z="229.136"',
1157 ' x="-147.76" y="-52.6635" z="267.023"',
1158 ' x="-147.8" y="59.0965" z="267.023"',
1159 ' x="-147.8" y="3.21654" z="314.818"',
1160 ' x="-147.8" y="3.21654" z="385.004"',
1161 ' x="-147.76" y="-52.6635" z="434.169"',
1162 ' x="-147.8" y="59.0965" z="434.169"',
1163 ' x="-147.76" y="-52.6635" z="474.285"',
1164 ' x="-147.8" y="59.0965" z="474.285"',
1165 ' x="-147.8" y="3.21654" z="514.408"' );
1167 if ( $pmt_switch eq "on" ) {
1168 for ( $i=0; $i<30; ++$i ){
1169 print CRYOSTAT <<EOF;
1171 <volumeref ref="volPMT"/>
1172 <position name="posPMT$i" unit="cm" @pmt_pos[$i]/>
1173 <rotationref ref="rPMTRotation1"/>
1179 print CRYOSTAT <<EOF;
1189 # Parameterize the cryostat's surroundings.
1192 # Set up the output file.
1193 $GDML = "micro-enclosure" . $suffix . ".gdml";
1194 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1195 $GDML = ">" . $GDML;
1196 open(GDML) or die("Could not open file $GDML for writing");
1199 <?xml version='1.0'?>
1202 <box name="DetEnclosure" lunit="cm"
1203 x="kDetEnclosureWidth" y="$CryostatRadius" z="kDetEnclosureLength"
1208 <volume name="volDetEnclosure">
1209 <materialref ref="Air"/>
1210 <solidref ref="DetEnclosure"/>
1212 <volumeref ref="volCryostat"/>
1213 <position name="posCryostat" unit="cm" x="0" y="0" z="0"/>
1226 # Set up the output file.
1227 $GDML = "micro-enclosure" . $suffix . ".gdml";
1228 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1229 $GDML = ">" . $GDML;
1230 open(GDML) or die("Could not open file $GDML for writing");
1233 <?xml version='1.0'?>
1236 <box name="DetEnclosure" lunit="cm"
1237 x="kDetEnclosureWidth" y="2*$CryostatOuterRadius+100" z="kDetEnclosureLength"
1242 <volume name="volDetEnclosure">
1243 <materialref ref="Air"/>
1244 <solidref ref="DetEnclosure"/>
1246 <volumeref ref="volCryostat"/>
1247 <position name="posCryostat" unit="cm" x="0" y="0" z="0"/>
1258 # Parameterize the dirt mound that surrounds the enclosure.
1261 # Set up the output file.
1262 $GDML = "micro-world" . $suffix . ".gdml";
1263 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1264 $GDML = ">" . $GDML;
1265 open(GDML) or die("Could not open file $GDML for writing");
1268 <?xml version='1.0'?>
1278 rmax="((50*12)+620)*2.54"
1283 <tube name="ConcreteEnclosure"
1290 <tube name="ConcreteEnclosureBottom"
1297 <tube name="Overburden"
1307 <volume name="volGround" >
1308 <materialref ref="Dirt" />
1309 <solidref ref="Ground" />
1311 <volume name="volOverburden" >
1312 <materialref ref="Dirt" />
1313 <solidref ref="Overburden" />
1315 <volume name="volConcreteEnclosure" >
1316 <materialref ref="Concrete" />
1317 <solidref ref="ConcreteEnclosure" />
1319 <volume name="volConcreteEnclosureBottom" >
1320 <materialref ref="Concrete" />
1321 <solidref ref="ConcreteEnclosureBottom" />
1323 <volume name="volWorld" >
1324 <materialref ref="Air"/>
1325 <solidref ref="World"/>
1327 <volumeref ref="volConcreteEnclosure"/>
1328 <position name="posConcreteEnclosure" unit="cm" x="0.5*kTPCDepth" y="36*2.54/2" z="0.5*kTPCLength"/>
1329 <rotationref ref="rPlus90AboutX"/>
1332 <volumeref ref="volConcreteEnclosureBottom"/>
1333 <position name="posConcreteEnclosureBottom" unit="cm" x="0.5*kTPCDepth" y="-38*12*2.54/2" z="0.5*kTPCLength"/>
1334 <rotationref ref="rPlus90AboutX"/>
1337 <volumeref ref="volGround"/>
1338 <position name="posGround" unit="cm" x="0.5*kTPCDepth" y="0" z="0.5*kTPCLength"/>
1339 <rotationref ref="rPlus90AboutX"/>
1342 <volumeref ref="volOverburden"/>
1343 <position name="posOverburden" unit="cm" x="0.5*kTPCDepth" y="(41-10)*12*2.54/2" z="0.5*kTPCLength"/>
1344 <rotationref ref="rPlus90AboutX"/>
1347 <volumeref ref="volDetEnclosure"/>
1348 <position name="posDetEnclosure" unit="cm" x="0.5*kTPCDepth" y="0" z="0.5*kTPCLength"/>
1360 sub write_fragments()
1362 # The output file is a list of the GDML sub-files created by this
1365 if ( ! defined $output )
1367 $output = "-"; # write to STDOUT
1370 # Set up the output file.
1371 $OUTPUT = ">" . $output;
1372 open(OUTPUT) or die("Could not open file $OUTPUT");
1375 <?xml version='1.0'?>
1377 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1378 that will be zipped together to create a detector description.
1385 <!-- These files contain GDML <constant></constant>
1386 blocks. They are read in separately, so they can be
1387 interpreted into the remaining GDML. See make_gdml.pl for
1393 foreach $filename (@defFiles)
1396 <filename> $filename </filename>
1406 <!-- The GDML file fragments to be zipped together. -->
1410 foreach $filename (@gdmlFiles)
1413 <filename> $filename </filename>