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
98 gen_groundplate(); # physical volumes defined in gen_tpc()
99 gen_cathode(); # physical volumes defined in gen_tpc()
100 gen_fieldcage(); # physical volumes defined in gen_tpc()
103 if ( $pmt_switch eq "on" ) { gen_pmt(); } # physical volumes defined in gen_cryostat()
116 print "Usage: $0 [-h|--help] -i|--input <parameters-file> [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
117 print " -i/--input can be omitted; <parameters-file> contains geometry and material parameters\n";
118 print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
119 print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
120 print " -h prints this message, then quits\n";
125 # Create the detector constant file. This file is actually temporary,
126 # since the make_gdml.pl program will interpret its contents rather
127 # than include it in the final GDML file.
131 # Set up the output file.
132 $CONSTANTS = "microboone/micro-defs" . $suffix . ".gdml";
133 push (@gdmlFiles, $CONSTANTS); # Add file to list of constant files
134 $CONSTANTS = ">" . $CONSTANTS;
135 open(CONSTANTS) or die("Could not open file $CONSTANTS for writing");
137 # Create some math constants.
140 # Though it's not strictly necessary, make each sub-file a valid
141 # XML (if not GDML) document; that makes it accessible to an XML
144 # Here is a neat way to print out a block of text without getting
145 # involved in a lot of messy quoting and formatting with print
148 print CONSTANTS <<EOF;
149 <?xml version='1.0'?>
151 <constant name="kInch" value="2.54" />
152 <constant name="kPi" value="$pi" />
153 <constant name="kDetEnclosureWidth" value="$DetEnclosureWidth" />
154 <constant name="kDetEnclosureHeight" value="$DetEnclosureHeight" />
155 <constant name="kDetEnclosureLength" value="$DetEnclosureLength" />
156 <constant name="kDirtThickness" value="$DirtThickness" />
157 <constant name="kWorldW" value="100.0*kDetEnclosureWidth"/>
158 <constant name="kWorldH" value="100.0*kDetEnclosureHeight"/>
159 <constant name="kWorldL" value="100.0*kDetEnclosureLength"/>
161 <constant name="kTPCWidth" value="$TPCWidth" />
162 <constant name="kTPCLength" value="$TPCLength" />
163 <constant name="kTPCDepth" value="$TPCDepth" />
164 <constant name="kTPCWallThickness" value="$TPCWallThickness" />
166 <constant name="kTPCWirePlaneThickness" value="$TPCWirePlaneThickness" />
167 <constant name="kTPCWireThickness" value="$TPCWireThickness" />
168 <constant name="kTPCWirePlaneWidth" value="$wires_pwidth" />
169 <constant name="kTPCWirePlaneLength" value="$wires_plength" />
170 <constant name="kWireFrameDepth" value="9" />
171 <constant name="kWireFrameWidth" value="$wire_frame_width" />
172 <constant name="kWirePlaneHeight" value="$wire_plane_height" />
173 <constant name="kWirePlaneLength" value="$wire_plane_length" />
174 <constant name="kWireFrameVInHeight" value="0.5*(kWirePlaneHeight-3*kWireFrameWidth)" />
176 <constant name="kTPCWirePitch" value="$TPCWirePitch"/>
177 <constant name="kSinUVAngle" value="$SinUVAngle"/>
178 <constant name="kCosUVAngle" value="$CosUVAngle"/>
179 <constant name="kTanUVAngle" value="$TanUVAngle"/>
180 <constant name="kTPCWireXPitch" value="kTPCWirePitch/kCosUVAngle"/>
182 <constant name="kCathodeFrameWidth" value="9" />
183 <constant name="kCathodeFrameDepth" value="5" />
184 <constant name="kCathodePlateDepth" value="0.1" />
185 <constant name="kCathodeWidth" value="5.1" />
186 <constant name="kCathodeHeight" value="240" />
187 <constant name="kCathodeLength" value="1042" />
188 <constant name="kCathodeFrameVInHeight" value="0.5*(kCathodeHeight-3*kCathodeFrameWidth)" />
190 <constant name="kGroundPlateWidth" value="224" />
191 <constant name="kGroundPlateHeight" value="0.1" />
192 <constant name="kGroundPlateLength" value="1100" />
193 <constant name="kGroundBeamWidth" value="2.5" />
194 <constant name="kGroundBeamHeight" value="2.5" />
195 <constant name="kGroundBeamLength" value="kGroundPlateLength" />
196 <constant name="kGroundBeamThickness" value=".15" />
206 my $WirePlusRotation = $UVAngle + 90;
207 my $WireMinusRotation = $UVAngle - 90;
209 $ROTATIONS = "microboone/micro-rotations" . $suffix . ".gdml";
210 push (@gdmlFiles, $ROTATIONS); # Add file to list of GDML fragments
211 $ROTATIONS = ">" . $ROTATIONS;
212 open(ROTATIONS) or die("Could not open file $ROTATIONS for writing");
214 print ROTATIONS <<EOF;
215 <?xml version='1.0'?>
217 <rotation name="rPlus30AboutX" unit="deg" x="30" y="0" z="0"/>
218 <rotation name="rPlus60AboutX" unit="deg" x="60" y="0" z="0"/>
219 <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
220 <rotation name="rMinus90AboutX" unit="deg" x="-90" y="0" z="0"/>
221 <rotation name="rPlusUVAngleAboutX" unit="deg" x="150" y="0" z="0"/>
222 <rotation name="rPlus150AboutX" unit="deg" x="150" y="0" z="0"/>
223 <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
224 <rotation name="rMinusUVAngleAboutX" unit="deg" x="-30" y="0" z="0"/>
225 <rotation name="rPlus30AboutY" unit="deg" x="0" y="30" z="0"/>
226 <rotation name="rPlus60AboutY" unit="deg" x="0" y="60" z="0"/>
227 <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
228 <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
229 <rotation name="rMinus90AboutY" unit="deg" x="0" y="-90" z="0"/>
230 <rotation name="rPlus90AboutZ" unit="deg" x="0" y="0" z="90"/>
231 <rotation name="rMinus90AboutZ" unit="deg" x="0" y="0" z="-90"/>
232 <rotation name="rPlus180AboutZ" unit="deg" x="0" y="0" z="180"/>
233 <rotation name="rMinus180AboutZ" unit="deg" x="0" y="0" z="-180"/>
234 <rotation name="rMinus90AboutYPlus180AboutZ" unit="deg" x="0" y="-90" z="180"/>
235 <rotation name="rMinus90AboutYMinus90AboutZ" unit="deg" x="0" y="-90" z="-90"/>
236 <rotation name="rPlus90AboutYPlus180AboutZ" unit="deg" x="0" y="90" z="180"/>
237 <rotation name="rMinus90AboutYPlus90AboutZ" unit="deg" x="0" y="-90" z="90"/>
238 <rotation name="rPlus90AboutYMinus90AboutZ" unit="deg" x="0" y="90" z="-90"/>
239 <rotation name="rPlus90AboutXPlus90AboutZ" unit="deg" x="90" y="0" z="90"/>
240 <rotation name="rPlus90AboutXPlus180AboutZ" unit="deg" x="90" y="0" z="180"/>
241 <rotation name="rPlus90AboutXMinus90AboutY" unit="deg" x="90" y="-90" z="0"/>
242 <rotation name="rPlus90AboutXMinus90AboutZ" unit="deg" x="90" y="0" z="-90"/>
243 <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
244 <rotation name="rPMTRotation1" unit="deg" x="90" y="270" z="0"/>
253 # Create the materials file name and open it.
254 $MATERIALS = "materials" . $suffix . ".gdml";
255 push (@gdmlFiles, $MATERIALS); # Add file to list of GDML fragments
256 $MATERIALS = ">" . $MATERIALS;
257 open(MATERIALS) or die("Could not open file $MATERIALS for writing");
259 # Write the standard XML prefix.
260 print MATERIALS <<EOF;
261 <?xml version='1.0'?>
264 # Go back the DOM structure read in near the beginning of the
265 # program. For each <materials /> element (and there'll probably
267 foreach $materials ( $xmldata->findnodes('/parameters/materials') )
269 # Convert that element back to text, and write it out.
270 print MATERIALS $materials->toString;
277 # This is a re-write of Brian Rebel's gen_microvertplane.C into
278 # Perl. It contructs the TPC wire plane for the Y view.
280 sub gen_tpcplanevert()
284 ##### temporary edits:
285 ##### - TPCPlaneVert y="TPCWidth" z="kTPCLength"
286 ##### - TPCWireVert y="TPCWidth"
287 ##### - (above)my $NumberWires = int($TPCLength / $TPCWirePitch ) - 1
291 my $NumberWires = int( ( $wires_plength ) / $TPCWirePitch ) - 1;
293 $GDML = "microboone/micro-vertplane" . $suffix . ".gdml";
294 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
296 open(GDML) or die("Could not open file $GDML for writing");
298 # Define the solids and structures: the wires and the TPC wire plane.
301 <?xml version='1.0'?>
304 <tube name="TPCWireVert"
305 rmax="0.5*kTPCWireThickness"
310 <box name="TPCPlaneVert"
311 x="kTPCWirePlaneThickness"
317 <volume name="volTPCWireVert">
318 <materialref ref="Titanium"/>
319 <solidref ref="TPCWireVert"/>
321 <volume name="volTPCPlaneVert">
322 <materialref ref="LAr"/>
323 <solidref ref="TPCPlaneVert"/>
327 for ( $i = 0; $i < ( $NumberWires / $wire_int ); ++$i )
332 <volumeref ref="volTPCWireVert"/>
333 <position name="posTPCWireVert$i" unit="cm" z="(-0.5*kTPCWirePlaneLength)+kTPCWirePitch*($j+1)" x="0" y="0"/>
334 <rotationref ref="rPlus90AboutX"/>
348 # This is a re-write of Brian Rebel's gen_microplane.C into Perl. It
349 # constructs the TPC wire plane for the U or V view.
355 #### - my $NumberWires = $TPCLength / $TPCWirePitch - 1;
356 #### - my $NumberWiresPerEdge = int( $TPCLength / $TPCYWirePitch );
357 #### - my $NumberSideWires = int( $TanUVAngle * $TPCWidth / $TPCYWirePitch );
358 #### - <tube name="TPCWireCommon" rmax="0.5*kTPCWireThickness" z="kTPCWidth/kCosUVAngle" deltaphi="2*kPi" aunit="rad" lunit="cm"/>
359 #### - <box name="TPCPlane" x="kTPCWirePlaneThickness" y="kTPCWidth" z="kTPCLength" lunit="cm"/>
361 my $NumberWires = ( $wires_plength ) / $TPCWirePitch - 1;
363 $GDML = "microboone/micro-plane" . $suffix . ".gdml";
364 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
366 open(GDML) or die("Could not open file $GDML for writing");
368 # Calculate the number of wire ends on a given y-edge of the plane.
369 my $TPCYWirePitch = $TPCWirePitch / $CosUVAngle;
370 my $NumberWiresPerEdge = int( ( $wires_plength ) / $TPCYWirePitch );
372 # How many side wires will be "cut off" by the lower or higher
374 my $NumberSideWires = int( $TanUVAngle * ( $wires_pwidth ) / $TPCYWirePitch );
376 # The number of full-length "center" wires.
377 my $NumberCenterWires = $NumberWiresPerEdge - $NumberSideWires;
381 <?xml version='1.0'?>
386 # wires on either end of the tpc
387 for($i = 0; $i < $NumberSideWires; ++$i)
390 <tube name="TPCWire$i"
391 rmax="0.5*kTPCWireThickness"
392 z="kTPCWireXPitch*($i+1)/kSinUVAngle"
399 # The solids for the middle wire and the TPC wire plane, and start off the structures.
401 <tube name="TPCWireCommon"
402 rmax="0.5*kTPCWireThickness"
403 z="($wires_pwidth)/kCosUVAngle"
408 x="kTPCWirePlaneThickness"
416 # the wires at either end of the plane
417 for ($i = 0; $i < $NumberSideWires; ++$i)
420 <volume name="volTPCWire$i">
421 <materialref ref="Titanium"/>
422 <solidref ref="TPCWire$i"/>
428 # The wires in the middle of the plane, and the plane itself.
430 <volume name="volTPCWireCommon">
431 <materialref ref="Titanium"/>
432 <solidref ref="TPCWireCommon"/>
434 <volume name="volTPCPlane">
435 <materialref ref="LAr"/>
436 <solidref ref="TPCPlane"/>
439 # the wires at the -z end
440 for ($i = 0; $i < $NumberSideWires; ++$i)
444 <volumeref ref="volTPCWire$i"/>
445 <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"/>
446 <rotationref ref="rPlusUVAngleAboutX"/>
451 # The wires in the middle.
452 for ($i = 0; $i < $NumberCenterWires - 1 ; ++$i)
454 my $j = $NumberSideWires+$i;
457 <volumeref ref="volTPCWireCommon"/>
458 <position name="posTPCWire$j" unit="cm" y="0" z="(-0.5*kTPCWirePlaneLength)+kTPCWireXPitch*(0.5*$NumberSideWires + $i+1)" x="0"/>
459 <rotationref ref="rPlusUVAngleAboutX"/>
464 # the wires at the +z end
465 for ($i = 0; $i < $NumberSideWires; ++$i)
467 my $j = $NumberSideWires-$i-1;
468 my $k = $NumberCenterWires+$NumberSideWires+$i;
472 <volumeref ref="volTPCWire$j"/>
473 <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"/>
474 <rotationref ref="rPlusUVAngleAboutX"/>
490 # subdirectory to write field cage
491 sub gen_fieldcage() {
493 # Set up the output file.
494 $FIELDCAGE = "microboone/micro-fieldcage.gdml";
495 push (@gdmlFiles, $FIELDCAGE); # Add file to list of constant files
496 $FIELDCAGE = ">" . $FIELDCAGE;
497 open(FIELDCAGE) or die("Could not open file $FIELDCAGE for writing");
499 # Print the Field Cage constants
500 print FIELDCAGE <<EOF;
502 <constant name="kFieldCageTPCClearance" value="5*kInch" />
504 <constant name="kFieldCageTubeRadius" value="0.5*kInch" />
505 <constant name="kFieldCageTubeThickness" value="0.25*kInch" />
506 <constant name="kFieldCageBeamDepth" value="12.5"/>
507 <constant name="kFieldCageBeamWidth" value="2.5"/>
508 <constant name="kFieldCageCrossDepth" value="2.5"/>
509 <constant name="kFieldCageCrossWidth" value="4"/>
510 <constant name="kFieldCageCrossLength" value="$field_cage_cross_length"/>
512 <constant name="kTPCTotalLength" value="$field_cage_length"/>
513 <constant name="kTPCTotalWidth" value="$field_cage_width"/>
514 <constant name="kTPCTotalHeight" value="$field_cage_height"/>
516 <constant name="kFieldCageLoopLength" value="kTPCTotalLength+2*(kFieldCageTPCClearance+2*kFieldCageTubeRadius)"/>
517 <constant name="kFieldCageLoopWidth" value="$field_cage_width"/>
518 <constant name="kFieldCageLoopHeight" value="kTPCTotalHeight+2*(kFieldCageTPCClearance+2*kFieldCageTubeRadius)"/>
520 <constant name="kFieldCageCornerRadius" value="0.5*kFieldCageTPCClearance"/>
521 <constant name="kFieldCageCornerY" value="(0.5*kFieldCageLoopHeight)-kFieldCageCornerRadius-kFieldCageTubeRadius"/>
522 <constant name="kFieldCageCornerZ" value="(0.5*kFieldCageLoopLength)-kFieldCageCornerRadius-kFieldCageTubeRadius"/>
524 <constant name="kFieldCageHeight" value="kFieldCageLoopHeight+2*(kFieldCageBeamDepth+kFieldCageCrossDepth)"/>
525 <constant name="kFieldCageLength" value="kFieldCageLoopLength+2*(kFieldCageBeamDepth+kFieldCageCrossDepth)"/>
526 <constant name="kFieldCageWidth" value="$field_cage_width"/>
528 <constant name="kFieldCageBeamYInt" value="0.5*(kFieldCageLoopHeight-50)"/>
529 <constant name="kFieldCageBeamZPos" value="0.5*(kFieldCageLoopLength)"/>
530 <constant name="kFieldCageBeamYPos" value="0.5*(kFieldCageLoopHeight)"/>
531 <constant name="kFieldCageBeamZInt" value="0.5*(kFieldCageLoopLength-40)"/>
533 <constant name="kFieldCageCrossYPos" value="0.5*(kFieldCageLoopHeight+kFieldCageCrossDepth)+kFieldCageBeamDepth"/>
534 <constant name="kFieldCageCrossZPos" value="0.5*(kFieldCageLoopLength+kFieldCageCrossDepth)+kFieldCageBeamDepth"/>
538 # Prints Field Cage solids
539 print FIELDCAGE <<EOF;
541 <tube name="FieldCageTubeZ"
542 rmin="kFieldCageTubeRadius - kFieldCageTubeThickness"
543 rmax="kFieldCageTubeRadius"
544 z="kFieldCageLoopLength-2*(kFieldCageCornerRadius+kFieldCageTubeRadius)"
548 <tube name="FieldCageTubeY"
549 rmin="kFieldCageTubeRadius - kFieldCageTubeThickness"
550 rmax="kFieldCageTubeRadius"
551 z="kFieldCageLoopHeight-2*(kFieldCageCornerRadius+kFieldCageTubeRadius)"
558 # Prints Field Cage tube loop sub-structure
559 print FIELDCAGE <<EOF;
561 <volume name="volFieldCageTubeTop">
562 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
563 <solidref ref="FieldCageTubeZ"/>
565 <volume name="volFieldCageTubeBot">
566 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
567 <solidref ref="FieldCageTubeZ"/>
569 <volume name="volFieldCageTubeFront">
570 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
571 <solidref ref="FieldCageTubeY"/>
573 <volume name="volFieldCageTubeBack">
574 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
575 <solidref ref="FieldCageTubeY"/>
585 # Cathode solids and volumes
588 $CATHODE = "microboone/micro-cathode" . $suffix . ".gdml";
589 push (@gdmlFiles, $CATHODE); # Add file to list of GDML fragments
590 $CATHODE = ">" . $CATHODE;
591 open(CATHODE) or die("Could not open file $CATHODE for writing");
595 <?xml version='1.0'?>
598 <box name="CathodePlate"
600 x="kCathodePlateDepth"
605 <volume name="volCathodePlate">
606 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
607 <solidref ref="CathodePlate"/>
615 sub gen_groundplate() {
616 #this subroutine will produce the gdml fragment for ground plate
618 $GROUNDPLATE = "microboone/micro-groundplate" . $suffix . ".gdml";
619 push (@gdmlFiles, $GROUNDPLATE); # Add file to list of GDML fragments
620 $GROUNDPLATE = ">" . $GROUNDPLATE;
621 open(GROUNDPLATE) or die("Could not open file $GROUNDPLATE for writing");
623 print GROUNDPLATE <<EOF;
624 <?xml version='1.0'?>
627 <box name="GroundPlate"
629 x="kGroundPlateWidth"
630 y="kGroundPlateHeight"
631 z="kGroundPlateLength"/>
634 <volume name="volGroundPlate">
635 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
636 <solidref ref="GroundPlate"/>
646 # Parameterize the TPC and the planes within it.
649 # Set up the output file.
650 $GDML = "microboone/micro-tpc" . $suffix . ".gdml";
651 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
653 open(GDML) or die("Could not open file $GDML for writing");
656 <?xml version='1.0'?>
661 x="kTPCDepth+kTPCWallThickness+(2*kTPCWirePlaneThickness)"
662 y="kTPCWidth+(2*kTPCWallThickness)+($electronics_height)"
663 z="kTPCLength+(2*kTPCWallThickness)"/>
666 <volume name="volTPC">
667 <materialref ref="LAr"/>
668 <solidref ref="TPC"/>
671 # Ground Plane physical volumes
679 <volumeref ref="volGroundPlate"/>
680 <position name="posGroundPlate" unit="cm" x="$ground_plate_X+0.25" y="$ground_plate_Y-0.5*(kGroundBeamHeight)" z="0"/>
685 # Cathode Plane physical volumes
686 # Center = (0.5*(kTPCWidth-kCathodeWidth),0,0)
687 $Cathode_X="0.5*(kTPCWidth-kCathodeWidth)";
688 $Cathode_plate_offset="0.5*kCathodePlateDepth";
689 $Cathode_frame_position="$Cathode_X+($Cathode_plate_offset)";
693 <volumeref ref="volCathodePlate"/>
694 <position name="posCathodePlate" unit="cm" x="$Cathode_X-0.5*(kCathodeFrameDepth)-0.1" y="0" z="0"/>
699 # Wire Plane physical volumes
700 # Center = ( -0.5*(kTPCWidth-kWireFrameWidth) , 0 , 0 )
703 <volumeref ref="volTPCPlaneVert"/>
704 <position name="posTPCPlaneVert" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)-(2*$TPCWirePlaneSpacing)" y="0" z="0"/>
707 <volumeref ref="volTPCPlane"/>
708 <position name="posTPCPlane" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)-$TPCWirePlaneSpacing" y="0" z="0"/>
711 <volumeref ref="volTPCPlane"/>
712 <position name="posTPCPlane2" unit="cm" x="-0.5*(kTPCWidth-kWireFrameWidth)" y="0" z="0"/>
713 <rotationref ref="rPlus180AboutY"/>
720 while ( $space < ( $field_cage_width / 2 ) ) {
724 <volumeref ref="volFieldCageTubeTop"/>
725 <position name="posFieldCageTubeTopA$i" unit="cm" x="$xPos" y="0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
728 <volumeref ref="volFieldCageTubeBot"/>
729 <position name="posFieldCageTubeBotA$i" unit="cm" x="$xPos" y="-0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
732 <volumeref ref="volFieldCageTubeFront"/>
733 <position name="posFieldCageTubeFrontA$i" unit="cm" x="$xPos" y="0" z="0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
734 <rotation name="rFieldCageVertPlusA$i" unit="deg" x="90" y="0" z="0"/>
737 <volumeref ref="volFieldCageTubeBack"/>
738 <position name="posFieldCageTubeBackA$i" unit="cm" x="$xPos" y="0" z="-0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
739 <rotation name="rFieldCageVertMinusA$i" unit="deg" x="-90" y="0" z="0"/>
744 <volumeref ref="volFieldCageTubeTop"/>
745 <position name="posFieldCageTubeTopB$i" unit="cm" x="-$xPos" y="0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
748 <volumeref ref="volFieldCageTubeBot"/>
749 <position name="posFieldCageTubeBotB$i" unit="cm" x="-$xPos" y="-0.5*(kFieldCageLoopHeight-2*kFieldCageTubeRadius)" z="0"/>
752 <volumeref ref="volFieldCageTubeFront"/>
753 <position name="posFieldCageTubeFrontB$i" unit="cm" x="-$xPos" y="0" z="0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
754 <rotation name="rFieldCageVertFrontB$i" unit="deg" x="90" y="0" z="0"/>
757 <volumeref ref="volFieldCageTubeBack"/>
758 <position name="posFieldCageTubeBackB$i" unit="cm" x="-$xPos" y="0" z="-0.5*(kFieldCageLoopLength-2*kFieldCageTubeRadius)"/>
759 <rotation name="rFieldCageVertBackB$i" unit="deg" x="-90" y="0" z="0"/>
762 $space+=4*$field_cage_loop_interval;
768 # Closes TPC volume definition space
779 # Generates Ben Jones's PMT micro-pmtdef (with temporary edit to ellipsoid shapes
782 $PMT = "microboone/micro-pmtdef" . $suffix . ".gdml";
783 push (@gdmlFiles, $PMT); # Add file to list of GDML fragments
785 open(PMT) or die("Could not open file $PMT for writing");
789 <tube name="PMTVolume"
792 deltaphi="2*(3.1415926535897)"
795 <tube name="PMT_TPBCoating"
798 deltaphi="2*(3.1415926535897)"
801 <tube name="PMT_AcrylicPlate"
804 deltaphi="2*(3.1415926535897)"
807 <tube name="PMT_Stalk"
810 deltaphi="2*(3.1415926535897)"
813 <tube name="PMT_SteelBase"
816 deltaphi="2*(3.1415926535897)"
819 <tube name="PMT_Underside"
822 deltaphi="2*3.1415926535897"
825 <tube name="PMT_Lens"
828 deltaphi="2*3.1415926535897"
833 <volume name="vol_PMT_TPBCoating">
834 <materialref ref="TPB"/>
835 <solidref ref="PMT_TPBCoating"/>
837 <volume name="vol_PMT_AcrylicPlate">
838 <materialref ref="Acrylic"/>
839 <solidref ref="PMT_AcrylicPlate"/>
841 <volume name="vol_PMT_Stalk">
842 <materialref ref="Glass"/>
843 <solidref ref="PMT_Stalk"/>
845 <volume name="vol_PMT_SteelBase">
846 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
847 <solidref ref="PMT_SteelBase"/>
849 <volume name="vol_PMT_Underside">
850 <materialref ref="Glass"/>
851 <solidref ref="PMT_Underside"/>
853 <volume name="volOpDetSensitive">
854 <materialref ref="LAr"/>
855 <solidref ref="PMT_Lens"/>
857 <volume name="volPMT">
858 <materialref ref="LAr"/>
859 <solidref ref="PMTVolume"/>
861 <volumeref ref="vol_PMT_TPBCoating"/>
862 <position name="pos_PMT_TPBCoating" unit="cm" x="0" y="0" z="(5.5 * 2.54) - (0.5 * 0.005)"/>
865 <volumeref ref="vol_PMT_AcrylicPlate"/>
866 <position name="pos_PMT_AcrylicPlate" unit="cm" x="0" y="0" z="(5.5 * 2.54) - 0.01 - (0.5 * 0.2)"/>
869 <volumeref ref="vol_PMT_Stalk"/>
870 <position name="pos_PMT_Stalk" unit="cm" x="0" y="0" z="(3.0 * 2.54)-(5.5 * 2.54)"/>
873 <volumeref ref="vol_PMT_SteelBase"/>
874 <position name="pos_PMT_SteelBase" unit="cm" x="0" y="0" z="(0.75 * 2.54)-(5.5 * 2.54)"/>
877 <volumeref ref="volOpDetSensitive"/>
878 <position name="pos_PMT_Lens" unit="cm" x="0" y="0" z="(7.0 * 2.54)-(5.5 * 2.54)"/>
881 <volumeref ref="vol_PMT_Underside"/>
882 <position name="pos_PMT_Underside" unit="cm" x="0" y="0" z="(7.0 * 2.54)-(5.5 * 2.54)"/>
893 #Parameterize the steel cryostat that encloses the TPC.
896 # Set up the output file.
897 $CRYOSTAT = "microboone/micro-cryostat" . $suffix . ".gdml";
898 push (@gdmlFiles, $CRYOSTAT); # Add file to list of GDML fragments
899 $CRYOSTAT = ">" . $CRYOSTAT;
900 open(CRYOSTAT) or die("Could not open file $CRYOSTAT for writing");
902 print CRYOSTAT <<EOF;
903 <?xml version='1.0'?>
906 <tube name="Cryostat"
907 rmax="$CryostatOuterRadius"
908 z="$CryostatLength+2*$CryostatEndcapThickness"
912 <tube name="SteelTube"
913 rmin="$CryostatInnerRadius"
914 rmax="$CryostatOuterRadius"
922 print CRYOSTAT <<EOF;
926 <volume name="volSteelTube">
927 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
928 <solidref ref="SteelTube"/>
930 <volume name="volCryostat">
931 <materialref ref="LAr"/>
932 <solidref ref="Cryostat"/>
934 <volumeref ref="volSteelTube"/>
935 <position name="posSteelTube" unit="cm" x="0" y="0" z="0"/>
938 <volumeref ref="volTPC"/>
939 <position name="posTPC" unit="cm" x="0.0" y="0.97" z="0"/>
944 @pmt_pos = ( ' x="-147.8" y="3.21654" z="-463.358"',
945 ' x="-147.76" y="-52.6635" z="-403.121"',
946 ' x="-147.8" y="59.0965" z="-403.121"',
947 ' x="-147.76" y="-52.6635" z="-361.449"',
948 ' x="-147.8" y="59.0965" z="-361.449"',
949 ' x="-147.8" y="3.21654" z="-308.81"',
950 ' x="-147.8" y="3.21654" z="-249.591"',
951 ' x="-147.76" y="-52.6635" z="-194.487"',
952 ' x="-147.8" y="59.0965" z="-194.487"',
953 ' x="-147.76" y="-52.6635" z="-155.932"',
954 ' x="-147.8" y="59.0965" z="-155.932"',
955 ' x="-147.8" y="3.21654" z="-104.833"',
956 ' x="-147.8" y="3.21654" z="-38.3029"',
957 ' x="-147.76" y="-52.6635" z="13.6988"',
958 ' x="-147.8" y="59.0965" z="13.6988"',
959 ' x="-147.76" y="-52.6635" z="54.0326"',
960 ' x="-147.8" y="59.0965" z="54.0326"',
961 ' x="-147.8" y="3.21654" z="108.648"',
962 ' x="-147.8" y="3.21654" z="175.178"',
963 ' x="-147.76" y="-52.6635" z="229.136"',
964 ' x="-147.8" y="59.0965" z="229.136"',
965 ' x="-147.76" y="-52.6635" z="267.023"',
966 ' x="-147.8" y="59.0965" z="267.023"',
967 ' x="-147.8" y="3.21654" z="314.818"',
968 ' x="-147.8" y="3.21654" z="385.004"',
969 ' x="-147.76" y="-52.6635" z="434.169"',
970 ' x="-147.8" y="59.0965" z="434.169"',
971 ' x="-147.76" y="-52.6635" z="474.285"',
972 ' x="-147.8" y="59.0965" z="474.285"',
973 ' x="-147.8" y="3.21654" z="514.408"' );
975 if ( $pmt_switch eq "on" ) {
976 for ( $i=0; $i<30; ++$i ){
977 print CRYOSTAT <<EOF;
979 <volumeref ref="volPMT"/>
980 <position name="posPMT$i" unit="cm" @pmt_pos[$i]/>
981 <rotationref ref="rPMTRotation1"/>
987 print CRYOSTAT <<EOF;
997 # Parameterize the cryostat's surroundings.
1000 # Set up the output file.
1001 $GDML = "micro-enclosure" . $suffix . ".gdml";
1002 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1003 $GDML = ">" . $GDML;
1004 open(GDML) or die("Could not open file $GDML for writing");
1007 <?xml version='1.0'?>
1010 <box name="DetEnclosure" lunit="cm"
1011 x="kDetEnclosureWidth" y="$CryostatRadius" z="kDetEnclosureLength"
1016 <volume name="volDetEnclosure">
1017 <materialref ref="Air"/>
1018 <solidref ref="DetEnclosure"/>
1020 <volumeref ref="volCryostat"/>
1021 <position name="posCryostat" unit="cm" x="0" y="0" z="0"/>
1034 # Set up the output file.
1035 $GDML = "micro-enclosure" . $suffix . ".gdml";
1036 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1037 $GDML = ">" . $GDML;
1038 open(GDML) or die("Could not open file $GDML for writing");
1041 <?xml version='1.0'?>
1044 <box name="DetEnclosure" lunit="cm"
1045 x="kDetEnclosureWidth" y="2*$CryostatOuterRadius+100" z="kDetEnclosureLength"
1050 <volume name="volDetEnclosure">
1051 <materialref ref="Air"/>
1052 <solidref ref="DetEnclosure"/>
1054 <volumeref ref="volCryostat"/>
1055 <position name="posCryostat" unit="cm" x="0" y="0" z="0"/>
1066 # Parameterize the dirt mound that surrounds the enclosure.
1069 # Set up the output file.
1070 $GDML = "micro-world" . $suffix . ".gdml";
1071 push (@gdmlFiles, $GDML); # Add file to list of GDML fragments
1072 $GDML = ">" . $GDML;
1073 open(GDML) or die("Could not open file $GDML for writing");
1076 <?xml version='1.0'?>
1086 rmax="((50*12)+620)*2.54"
1091 <tube name="ConcreteEnclosure"
1098 <tube name="ConcreteEnclosureBottom"
1105 <tube name="Overburden"
1115 <volume name="volGround" >
1116 <materialref ref="Dirt" />
1117 <solidref ref="Ground" />
1119 <volume name="volOverburden" >
1120 <materialref ref="Dirt" />
1121 <solidref ref="Overburden" />
1123 <volume name="volConcreteEnclosure" >
1124 <materialref ref="Concrete" />
1125 <solidref ref="ConcreteEnclosure" />
1127 <volume name="volConcreteEnclosureBottom" >
1128 <materialref ref="Concrete" />
1129 <solidref ref="ConcreteEnclosureBottom" />
1131 <volume name="volWorld" >
1132 <materialref ref="Air"/>
1133 <solidref ref="World"/>
1135 <volumeref ref="volConcreteEnclosure"/>
1136 <position name="posConcreteEnclosure" unit="cm" x="0.5*kTPCDepth" y="36*2.54/2" z="0.5*kTPCLength"/>
1137 <rotationref ref="rPlus90AboutX"/>
1140 <volumeref ref="volConcreteEnclosureBottom"/>
1141 <position name="posConcreteEnclosureBottom" unit="cm" x="0.5*kTPCDepth" y="-38*12*2.54/2" z="0.5*kTPCLength"/>
1142 <rotationref ref="rPlus90AboutX"/>
1145 <volumeref ref="volGround"/>
1146 <position name="posGround" unit="cm" x="0.5*kTPCDepth" y="0" z="0.5*kTPCLength"/>
1147 <rotationref ref="rPlus90AboutX"/>
1150 <volumeref ref="volOverburden"/>
1151 <position name="posOverburden" unit="cm" x="0.5*kTPCDepth" y="(41-10)*12*2.54/2" z="0.5*kTPCLength"/>
1152 <rotationref ref="rPlus90AboutX"/>
1155 <volumeref ref="volDetEnclosure"/>
1156 <position name="posDetEnclosure" unit="cm" x="0.5*kTPCDepth" y="0" z="0.5*kTPCLength"/>
1168 sub write_fragments()
1170 # The output file is a list of the GDML sub-files created by this
1173 if ( ! defined $output )
1175 $output = "-"; # write to STDOUT
1178 # Set up the output file.
1179 $OUTPUT = ">" . $output;
1180 open(OUTPUT) or die("Could not open file $OUTPUT");
1183 <?xml version='1.0'?>
1185 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1186 that will be zipped together to create a detector description.
1193 <!-- These files contain GDML <constant></constant>
1194 blocks. They are read in separately, so they can be
1195 interpreted into the remaining GDML. See make_gdml.pl for
1201 foreach $filename (@defFiles)
1204 <filename> $filename </filename>
1214 <!-- The GDML file fragments to be zipped together. -->
1218 foreach $filename (@gdmlFiles)
1221 <filename> $filename </filename>