generate_dunedphase10kt_v1.pl
Go to the documentation of this file.
1 #!/usr/bin/perl
2 
3 #
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 >
7 #
8 
9 #################################################################################
10 #
11 # contact tylerdalion@gmail.com for any GDML/generate questions
12 # I would love to help!
13 
14 # Each subroutine generates a fragment GDML file, and the last subroutine
15 # creates an XML file that make_gdml.pl will use to appropriately arrange
16 # the fragment GDML files to create the final desired DUNE GDML file,
17 # to be named by make_gdml output command
18 
19 # If you are playing with different geometries, you can use the
20 # suffix command to help organize your work.
21 #
22 ##################################################################################
23 
24 
25 #use warnings;
26 use gdmlMaterials;
27 use Math::Trig;
28 use Getopt::Long;
29 use Math::BigFloat;
30 Math::BigFloat->precision(-16);
31 
32 GetOptions( "help|h" => \$help,
33  "suffix|s:s" => \$suffix,
34  "output|o:s" => \$output,
35  "wires|w:s" => \$wires,
36  "workspace|k:s" => \$workspace);
37 
38 if ( defined $help )
39 {
40  # If the user requested help, print the usage notes and exit.
41  usage();
42  exit;
43 }
44 
45 if ( ! defined $suffix )
46 {
47  # The user didn't supply a suffix, so append nothing to the file
48  # names.
49  $suffix = "";
50 }
51 else
52 {
53  # Otherwise, stick a "-" before the suffix, so that a suffix of
54  # "test" applied to filename.gdml becomes "filename-test.gdml".
55  $suffix = "-" . $suffix;
56 }
57 
58 if ( ! defined $workspace ) # not done
59 {
60  $workspace = 0;
61 }
62 elsif ( $workspace == 1)
63 {
64  print "\t\tCreating smaller workspace geometry.\n";
65 }
66 
67 # set wires on to be the default, unless given an input by the user
68 $wires_on = 1; # 1=on, 0=off
69 if (defined $wires)
70 {
71  $wires_on = $wires
72 }
73 
74 $tpc_on = 1;
75 
76 $basename = "dune10ktdphase_v1";
77 if ( $wires_on == 0 )
78 {
79  $basename = $basename."_nowires";
80 }
81 
82 if ( $workspace == 1 )
83 {
84  $basename = $basename."_workspace";
85 }
86 
87 ##################################################################
88 ############## Parameters for Charge Readout Plane ###############
89 
90 # dune10kt dual-phase
91 $wirePitch = 0.3125; # channel pitch
92 $nChannelsViewPerCRM = 960; # channels per collection view
93 $borderCRM = 0.5; # dead space at the border of each CRM
94 
95 # dimensions of a single Charge Readout Module (CRM)
96 $widthCRM_active = $wirePitch * $nChannelsViewPerCRM;
97 $lengthCRM_active = $wirePitch * $nChannelsViewPerCRM;
98 
99 $widthCRM = $widthCRM_active + 2 * $borderCRM;
100 $lengthCRM = $lengthCRM_active + 2 * $borderCRM;
101 
102 # number of CRMs in x and z
103 $nCRM_x = 4;
104 $nCRM_z = 20;
105 
106 # create a smaller geometry
107 if( $workspace == 1 )
108 {
109  $nCRM_x = 1;
110  $nCRM_z = 2;
111 }
112 
113 # calculate tpc area based on number of CRMs and their dimensions
114 $widthTPCActive = $nCRM_x * $widthCRM; # around 1200
115 $lengthTPCActive = $nCRM_z * $lengthCRM; # around 6000
116 
117 # active volume dimensions
118 $driftTPCActive = 1200.0;
119 
120 # model anode strips as wires
121 $padWidth = 0.015;
122 $ReadoutPlane = 2 * $padWidth;
123 
124 #$padHeight = 0.0035;
125 
126 ##################################################################
127 ############## Parameters for TPC and inner volume ###############
128 
129 # inner volume dimensions of the cryostat
130 $Argon_x = 1510;
131 $Argon_y = 1510;
132 $Argon_z = 6200;
133 
134 # width of gas argon layer on top
135 $HeightGaseousAr = 100;
136 
137 # size of liquid argon buffer
138 $xLArBuffer = 0.5 * ($Argon_x - $widthTPCActive);
139 $yLArBuffer = $Argon_y - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
140 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
141 
142 # cryostat
143 $SteelThickness = 0.12; # membrane
144 
145 $Cryostat_x = $Argon_x + 2*$SteelThickness;
146 $Cryostat_y = $Argon_y + 2*$SteelThickness;
147 $Cryostat_z = $Argon_z + 2*$SteelThickness;
148 
149 ##################################################################
150 ############## DetEnc and World relevant parameters #############
151 
152 $SteelSupport_x = 100;
153 $SteelSupport_y = 50;
154 $SteelSupport_z = 100;
155 $FoamPadding = 80; # only 2 layers ???
156 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
157 $FracMassOfAir = 1 - $FracMassOfSteel;
158 
159 
160 $SpaceSteelSupportToWall = 100;
161 $SpaceSteelSupportToCeiling = 100;
162 
163 $DetEncWidth = $Cryostat_x
164  + 2*($SteelSupport_x + $FoamPadding) + 2*$SpaceSteelSupportToWall;
165 $DetEncHeight = $Cryostat_y
166  + 2*($SteelSupport_y + $FoamPadding) + $SpaceSteelSupportToCeiling;
167 $DetEncLength = $Cryostat_z
168  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
169 
170 $posCryoInDetEnc_y = - $DetEncHeight/2 + $SteelSupport_y + $FoamPadding + $Cryostat_y/2;
171 
172 $RockThickness = 3000;
173 
174  # We want the world origin to be at the very front of the fiducial volume.
175  # move it to the front of the enclosure, then back it up through the concrete/foam,
176  # then through the Cryostat shell, then through the upstream dead LAr (including the
177  # dead LAr on the edge of the TPC)
178  # This is to be added to the z position of every volume in volWorld
179 
180 $OriginZSet = $DetEncLength/2.0
181  - $SpaceSteelSupportToWall
182  - $SteelSupport_z
183  - $FoamPadding
184  - $SteelThickness
185  - $zLArBuffer;
186 
187  # We want the world origin to be vertically centered on active TPC
188  # This is to be added to the y position of every volume in volWorld
189 
190 $OriginYSet = $DetEncHeight/2.0
191  - $SteelSupport_y
192  - $FoamPadding
193  - $SteelThickness
194  - $yLArBuffer
195  - $driftTPCActive/2.0;
196 
197 $OriginXSet = 0; # centered for now
198 
199 
200 ##################################################################
201 ############### Parameters for det elements ######################
202 
203 # cathode plane
204 $Cathode_x = $widthTPCActive;
205 $Cathode_y = 1.0;
206 $Cathode_z = $lengthTPCActive;
207 
208 
209 
210 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
211 
212 
213 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
214 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
215 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
216 
217 sub usage()
218 {
219  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
220  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
221  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
222  print " -h prints this message, then quits\n";
223 }
224 
225 
226 
227 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
228 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
229 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
230 
231 sub gen_Define()
232 {
233 
234 # Create the <define> fragment file name,
235 # add file to list of fragments,
236 # and open it
237  $DEF = $basename."_Def" . $suffix . ".gdml";
238  push (@gdmlFiles, $DEF);
239  $DEF = ">" . $DEF;
240  open(DEF) or die("Could not open file $DEF for writing");
241 
242 
243 print DEF <<EOF;
244 <?xml version='1.0'?>
245 <gdml>
246 <define>
247 
248 <!--
249 
250 
251 
252 -->
253 
254  <position name="posCryoInDetEnc" unit="cm" x="0" y="$posCryoInDetEnc_y" z="0"/>
255  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
256  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
257  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
258  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
259  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
260  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
261  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
262  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
263 </define>
264 </gdml>
265 EOF
266  close (DEF);
267 }
268 
269 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
270 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
271 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
272 
273 sub gen_Materials()
274 {
275 
276 # Create the <materials> fragment file name,
277 # add file to list of output GDML fragments,
278 # and open it
279  $MAT = $basename."_Materials" . $suffix . ".gdml";
280  push (@gdmlFiles, $MAT);
281  $MAT = ">" . $MAT;
282 
283  open(MAT) or die("Could not open file $MAT for writing");
284 
285  # Add any materials special to this geometry by defining a mulitline string
286  # and passing it to the gdmlMaterials::gen_Materials() function.
287 my $asmix = <<EOF;
288  <!-- preliminary values -->
289  <material name="AirSteelMixture" formula="AirSteelMixture">
290  <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
291  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
292  <fraction n="$FracMassOfAir" ref="Air"/>
293  </material>
294 EOF
295 
296  # add the general materials used anywere
297  print MAT gdmlMaterials::gen_Materials( $asmix );
298 
299  close(MAT);
300 }
301 
302 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
303 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
304 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
305 sub gen_TPC()
306 {
307  # CRM active volume
308  my $TPCActive_x = $widthCRM_active;
309  my $TPCActive_y = $driftTPCActive;
310  my $TPCActive_z = $lengthCRM_active;
311 
312  # CRM total volume
313  my $TPC_x = $widthCRM;
314  my $TPC_y = $TPCActive_y + $ReadoutPlane;
315  my $TPC_z = $lengthCRM;
316 
317 
318  $TPC = $basename."_TPC" . $suffix . ".gdml";
319  push (@gdmlFiles, $TPC);
320  $TPC = ">" . $TPC;
321  open(TPC) or die("Could not open file $TPC for writing");
322 
323 # The standard XML prefix and starting the gdml
324  print TPC <<EOF;
325 <?xml version='1.0'?>
326 <gdml>
327 EOF
328 
329 
330  # All the TPC solids save the wires.
331  print TPC <<EOF;
332 <solids>
333  <box name="CRM" lunit="cm"
334  x="$TPC_x"
335  y="$TPC_y"
336  z="$TPC_z"/>
337  <box name="CRMZPlane" lunit="cm"
338  x="$TPCActive_x"
339  y="$padWidth"
340  z="$TPCActive_z"/>
341  <box name="CRMXPlane" lunit="cm"
342  x="$TPCActive_x"
343  y="$padWidth"
344  z="$TPCActive_z"/>
345  <box name="CRMActive" lunit="cm"
346  x="$TPCActive_x"
347  y="$TPCActive_y"
348  z="$TPCActive_z"/>
349 EOF
350 
351 
352 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
353 # in principle we only need only one wire solid, since CRM is a square
354 # but to be more general ...
355 
356 print TPC <<EOF;
357 
358  <tube name="CRMWireZ"
359  rmax="0.5*$padWidth"
360  z="$TPCActive_z"
361  deltaphi="360"
362  aunit="deg"
363  lunit="cm"/>
364  <tube name="CRMWireX"
365  rmax="0.5*$padWidth"
366  z="$TPCActive_x"
367  deltaphi="360"
368  aunit="deg"
369  lunit="cm"/>
370 </solids>
371 
372 EOF
373 
374 
375 # Begin structure and create wire logical volumes
376 print TPC <<EOF;
377 <structure>
378  <volume name="volTPCActive">
379  <materialref ref="LAr"/>
380  <solidref ref="CRMActive"/>
381  </volume>
382 EOF
383 
384 if ($wires_on==1)
385 {
386  print TPC <<EOF;
387  <volume name="volTPCWireZ">
388  <materialref ref="Copper_Beryllium_alloy25"/>
389  <solidref ref="CRMWireZ"/>
390  </volume>
391 
392  <volume name="volTPCWireX">
393  <materialref ref="Copper_Beryllium_alloy25"/>
394  <solidref ref="CRMWireX"/>
395  </volume>
396 EOF
397 }
398 
399 print TPC <<EOF;
400 
401  <volume name="volTPCPlaneZ">
402  <materialref ref="LAr"/>
403  <solidref ref="CRMZPlane"/>
404 EOF
405 
406 if ($wires_on==1) # add wires to Z plane
407 {
408 for($i=0;$i<$nChannelsViewPerCRM;++$i)
409 {
410 my $zpos = -0.5 * $TPCActive_z + $i*$wirePitch + 0.5*$padWidth;
411 
412 print TPC <<EOF;
413  <physvol>
414  <volumeref ref="volTPCWireZ"/>
415  <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
416  <rotationref ref="rMinus90AboutY"/>
417  </physvol>
418 EOF
419 }
420 }
421 
422 print TPC <<EOF;
423  </volume>
424 
425  <volume name="volTPCPlaneX">
426  <materialref ref="LAr"/>
427  <solidref ref="CRMXPlane"/>
428 EOF
429 
430 
431 if ($wires_on==1) # add wires to X plane
432 {
433 for($i=0;$i<$nChannelsViewPerCRM;++$i)
434 {
435 
436 my $xpos = -0.5 * $TPCActive_x + $i*$wirePitch + 0.5*$padWidth;
437 print TPC <<EOF;
438  <physvol>
439  <volumeref ref="volTPCWireX"/>
440  <position name="posWireX$i" unit="cm" x="$xpos" y="0" z="0"/>
441  <rotationref ref="rIdentity"/>
442  </physvol>
443 EOF
444 }
445 }
446 
447 
448 print TPC <<EOF;
449  </volume>
450 EOF
451 
452 
453 $posZplane[0] = 0;
454 $posZplane[1] = 0.5*$TPC_y - 0.5*$padWidth;
455 $posZplane[2] = 0;
456 
457 $posXplane[0] = 0;
458 $posXplane[1] = 0.5*$TPC_y - 1.5*$padWidth;
459 $posXplane[2] = 0;
460 
461 $posTPCActive[0] = 0;
462 $posTPCActive[1] = -$ReadoutPlane;
463 $posTPCActive[2] = 0;
464 
465 
466 #wrap up the TPC file
467 print TPC <<EOF;
468 
469  <volume name="volTPC">
470  <materialref ref="LAr"/>
471  <solidref ref="CRM"/>
472  <physvol>
473  <volumeref ref="volTPCPlaneZ"/>
474  <position name="posPlaneZ" unit="cm"
475  x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
476  <rotationref ref="rIdentity"/>
477  </physvol>
478  <physvol>
479  <volumeref ref="volTPCPlaneX"/>
480  <position name="posPlaneX" unit="cm"
481  x="$posXplane[0]" y="$posXplane[1]" z="$posXplane[2]"/>
482  <rotationref ref="rIdentity"/>
483  </physvol>
484  <physvol>
485  <volumeref ref="volTPCActive"/>
486  <position name="posActive" unit="cm"
487  x="$posTPCActive[0]" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
488  <rotationref ref="rIdentity"/>
489  </physvol>
490  </volume>
491 EOF
492 
493 
494 print TPC <<EOF;
495 </structure>
496 </gdml>
497 EOF
498 
499 close(TPC);
500 }
501 
502 
503 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
504 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
505 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
506 
507 sub gen_Cryostat()
508 {
509 
510 # Create the cryostat fragment file name,
511 # add file to list of output GDML fragments,
512 # and open it
513  $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
514  push (@gdmlFiles, $CRYO);
515  $CRYO = ">" . $CRYO;
516  open(CRYO) or die("Could not open file $CRYO for writing");
517 
518 
519 # The standard XML prefix and starting the gdml
520  print CRYO <<EOF;
521 <?xml version='1.0'?>
522 <gdml>
523 EOF
524 
525 # All the cryostat solids.
526 print CRYO <<EOF;
527 <solids>
528  <box name="Cryostat" lunit="cm"
529  x="$Cryostat_x"
530  y="$Cryostat_y"
531  z="$Cryostat_z"/>
532 
533  <box name="ArgonInterior" lunit="cm"
534  x="$Argon_x"
535  y="$Argon_y"
536  z="$Argon_z"/>
537 
538  <box name="GaseousArgon" lunit="cm"
539  x="$Argon_x"
540  y="$HeightGaseousAr"
541  z="$Argon_z"/>
542 
543  <subtraction name="SteelShell">
544  <first ref="Cryostat"/>
545  <second ref="ArgonInterior"/>
546  </subtraction>
547 
548 </solids>
549 EOF
550 
551 # Cryostat structure
552 print CRYO <<EOF;
553 <structure>
554  <volume name="volSteelShell">
555  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
556  <solidref ref="SteelShell" />
557  </volume>
558  <volume name="volGaseousArgon">
559  <materialref ref="ArGas"/>
560  <solidref ref="GaseousArgon"/>
561  </volume>
562 
563  <volume name="volCryostat">
564  <materialref ref="LAr" />
565  <solidref ref="Cryostat" />
566  <physvol>
567  <volumeref ref="volGaseousArgon"/>
568  <position name="posGaseousArgon" unit="cm" x="0" y="$Argon_y/2-$HeightGaseousAr/2" z="0"/>
569  </physvol>
570  <physvol>
571  <volumeref ref="volSteelShell"/>
572  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
573  </physvol>
574 EOF
575 
576 
577 if ($tpc_on==1) # place TPC inside croysotat
578 {
579 
580 $posY = $Argon_y/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
581 for($ii=0;$ii<$nCRM_z;$ii++)
582 {
583  $posZ = -0.5*$Argon_z + $zLArBuffer + ($ii+0.5)*$lengthCRM;
584 
585  for($jj=0;$jj<$nCRM_x;$jj++)
586  {
587  $posX = -0.5*$Argon_x + $xLArBuffer + ($jj+0.5)*$widthCRM;
588  print CRYO <<EOF;
589  <physvol>
590  <volumeref ref="volTPC"/>
591  <position name="posTPC\-$ii\-$jj" unit="cm"
592  x="$posX" y="$posY" z="$posZ"/>
593  </physvol>
594 EOF
595  }
596 }
597 
598 }
599 
600 
601 print CRYO <<EOF;
602  </volume>
603 </structure>
604 </gdml>
605 EOF
606 
607 close(CRYO);
608 }
609 
610 
611 
612 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
613 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
614 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
615 
616 sub gen_Enclosure()
617 {
618 
619 # Create the detector enclosure fragment file name,
620 # add file to list of output GDML fragments,
621 # and open it
622  $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
623  push (@gdmlFiles, $ENCL);
624  $ENCL = ">" . $ENCL;
625  open(ENCL) or die("Could not open file $ENCL for writing");
626 
627 
628 # The standard XML prefix and starting the gdml
629  print ENCL <<EOF;
630 <?xml version='1.0'?>
631 <gdml>
632 EOF
633 
634 
635 # All the detector enclosure solids.
636 print ENCL <<EOF;
637 <solids>
638 
639  <box name="FoamPadBlock" lunit="cm"
640  x="$Cryostat_x + 2*$FoamPadding"
641  y="$Cryostat_y + 2*$FoamPadding"
642  z="$Cryostat_z + 2*$FoamPadding" />
643 
644  <subtraction name="FoamPadding">
645  <first ref="FoamPadBlock"/>
646  <second ref="Cryostat"/>
647  <positionref ref="posCenter"/>
648  </subtraction>
649 
650  <box name="SteelSupportBlock" lunit="cm"
651  x="$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x"
652  y="$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y"
653  z="$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z" />
654 
655  <subtraction name="SteelSupport">
656  <first ref="SteelSupportBlock"/>
657  <second ref="FoamPadding"/>
658  <positionref ref="posCenter"/>
659  </subtraction>
660 
661  <box name="DetEnclosure" lunit="cm"
662  x="$DetEncWidth"
663  y="$DetEncHeight"
664  z="$DetEncLength"/>
665 
666 </solids>
667 EOF
668 
669 
670 # Detector enclosure structure
671  print ENCL <<EOF;
672 <structure>
673  <volume name="volFoamPadding">
674  <materialref ref="FD_foam"/>
675  <solidref ref="FoamPadding"/>
676  </volume>
677 
678  <volume name="volSteelSupport">
679  <materialref ref="AirSteelMixture"/>
680  <solidref ref="SteelSupport"/>
681  </volume>
682 
683  <volume name="volDetEnclosure">
684  <materialref ref="Air"/>
685  <solidref ref="DetEnclosure"/>
686 
687  <physvol>
688  <volumeref ref="volFoamPadding"/>
689  <positionref ref="posCryoInDetEnc"/>
690  </physvol>
691  <physvol>
692  <volumeref ref="volSteelSupport"/>
693  <positionref ref="posCryoInDetEnc"/>
694  </physvol>
695  <physvol>
696  <volumeref ref="volCryostat"/>
697  <positionref ref="posCryoInDetEnc"/>
698  </physvol>
699 EOF
700 
701 
702 print ENCL <<EOF;
703  </volume>
704 EOF
705 
706 print ENCL <<EOF;
707 </structure>
708 </gdml>
709 EOF
710 
711 close(ENCL);
712 }
713 
714 
715 
716 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
717 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
718 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
719 
720 sub gen_World()
721 {
722 
723 # Create the WORLD fragment file name,
724 # add file to list of output GDML fragments,
725 # and open it
726  $WORLD = $basename."_World" . $suffix . ".gdml";
727  push (@gdmlFiles, $WORLD);
728  $WORLD = ">" . $WORLD;
729  open(WORLD) or die("Could not open file $WORLD for writing");
730 
731 
732 # The standard XML prefix and starting the gdml
733  print WORLD <<EOF;
734 <?xml version='1.0'?>
735 <gdml>
736 EOF
737 
738 
739 # All the World solids.
740 print WORLD <<EOF;
741 <solids>
742  <box name="World" lunit="cm"
743  x="$DetEncWidth+2*$RockThickness"
744  y="$DetEncHeight+2*$RockThickness"
745  z="$DetEncLength+2*$RockThickness"/>
746 </solids>
747 EOF
748 
749 # World structure
750 print WORLD <<EOF;
751 <structure>
752  <volume name="volWorld" >
753  <materialref ref="DUSEL_Rock"/>
754  <solidref ref="World"/>
755 
756  <physvol>
757  <volumeref ref="volDetEnclosure"/>
758  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
759  </physvol>
760 
761  </volume>
762 </structure>
763 </gdml>
764 EOF
765 
766 # make_gdml.pl will take care of <setup/>
767 
768 close(WORLD);
769 }
770 
771 
772 
773 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
774 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
775 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
776 
777 sub write_fragments()
778 {
779  # This subroutine creates an XML file that summarizes the the subfiles output
780  # by the other sub routines - it is the input file for make_gdml.pl which will
781  # give the final desired GDML file. Specify its name with the output option.
782  # (you can change the name when running make_gdml)
783 
784  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
785 
786  if ( ! defined $output )
787  {
788  $output = "-"; # write to STDOUT
789  }
790 
791  # Set up the output file.
792  $OUTPUT = ">" . $output;
793  open(OUTPUT) or die("Could not open file $OUTPUT");
794 
795  print OUTPUT <<EOF;
796 <?xml version='1.0'?>
797 
798 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
799  that will be zipped together to create a detector description.
800  -->
801 
802 <config>
803 
804  <constantfiles>
805 
806  <!-- These files contain GDML <constant></constant>
807  blocks. They are read in separately, so they can be
808  interpreted into the remaining GDML. See make_gdml.pl for
809  more information.
810  -->
811 
812 EOF
813 
814  foreach $filename (@defFiles)
815  {
816  print OUTPUT <<EOF;
817  <filename> $filename </filename>
818 EOF
819  }
820 
821  print OUTPUT <<EOF;
822 
823  </constantfiles>
824 
825  <gdmlfiles>
826 
827  <!-- The GDML file fragments to be zipped together. -->
828 
829 EOF
830 
831  foreach $filename (@gdmlFiles)
832  {
833  print OUTPUT <<EOF;
834  <filename> $filename </filename>
835 EOF
836  }
837 
838  print OUTPUT <<EOF;
839 
840  </gdmlfiles>
841 
842 </config>
843 EOF
844 
845  close(OUTPUT);
846 }
847 
848 
849 print "Some key parameters for dual-phase LAr TPC (unit cm unless noted otherwise)\n";
850 print "CRM active area : $widthCRM_active x $lengthCRM_active\n";
851 print "CRM total area : $widthCRM x $lengthCRM\n";
852 print "TPC active volume : $widthTPCActive x $driftTPCActive x $lengthTPCActive\n";
853 print "Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
854 print "Detector enclosure : $DetEncWidth x $DetEncHeight x $DetEncLength\n";
855 print "TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
856 
857 # run the sub routines that generate the fragments
858 
859 gen_Define(); # generates definitions at beginning of GDML
860 gen_Materials(); # generates materials to be used
861 gen_TPC(); # generate TPC for a given unit CRM
862 gen_Cryostat(); #
863 gen_Enclosure(); #
864 gen_World(); # places the enclosure among DUSEL Rock
865 
866 
867 write_fragments(); # writes the XML input for make_gdml.pl
868  # which zips together the final GDML
869 exit;