generate_3x1x1dphase.pl
Go to the documentation of this file.
1 #!/usr/bin/perl
2 
3 ##################################################################################
4 #
5 # This script is based on generate_dunedphase10kt_v2.pl (see description
6 # in there file for more info). Some parameters were changed to generate
7 # a first version of the 3x1x1 dual phase geometry (e.g. driftTPCActive
8 # and number of CRM's).
9 # More detector elements are going to be added (e.g. PMTs, field cage, ...)
10 # For more info, please contact Christoph Alt: christoph.alt@cern.ch
11 #
12 # !!!NOTE!!!: the readout is on a positive X -- a fix for electric field
13 # direction problem in larsoft
14 #
15 ##################################################################################
16 
17 
18 #use warnings;
19 use gdmlMaterials;
20 use Math::Trig;
21 use Getopt::Long;
22 use Math::BigFloat;
23 Math::BigFloat->precision(-16);
24 
25 GetOptions( "help|h" => \$help,
26  "suffix|s:s" => \$suffix,
27  "output|o:s" => \$output,
28  "wires|w:s" => \$wires);
29 
30 my $pmt_switch="on";
31 
32 if ( defined $help )
33 {
34  # If the user requested help, print the usage notes and exit.
35  usage();
36  exit;
37 }
38 
39 if ( ! defined $suffix )
40 {
41  # The user didn't supply a suffix, so append nothing to the file
42  # names.
43  $suffix = "";
44 }
45 else
46 {
47  # Otherwise, stick a "-" before the suffix, so that a suffix of
48  # "test" applied to filename.gdml becomes "filename-test.gdml".
49  $suffix = "-" . $suffix;
50 }
51 
52 #if ( ! defined $workspace ) # not done
53 #{
54 # $workspace = 0;
55 #}
56 #elsif ( $workspace == 1)
57 #{
58 # print "\t\tCreating smaller workspace geometry.\n";
59 #}
60 
61 # set wires on to be the default, unless given an input by the user
62 $wires_on = 1; # 1=on, 0=off
63 if (defined $wires)
64 {
65  $wires_on = $wires
66 }
67 
68 $tpc_on = 1;
69 
70 $basename = "3x1x1dphase";
71 if ( $wires_on == 0 )
72 {
73  $basename = $basename."_nowires";
74 }
75 
76 #if ( $workspace == 1 )
77 #{
78 # $basename = $basename."_workspace";
79 #}
80 
81 
82 ##################################################################
83 ############## Parameters for Charge Readout Plane ###############
84 
85 # 3x1x1 dual-phase
86 $wirePitch = 0.3125; # channel pitch
87 $nChannelsLengthPerCRM = 960; # channels along the length of the CRM
88 $nChannelsWidthPerCRM = 320; # channels along the width of the CRM
89 $borderCRM = 0.5; # dead space at the border of each CRM
90 
91 # dimensions of a single Charge Readout Module (CRM)
92 $widthCRM_active = $wirePitch * $nChannelsWidthPerCRM;
93 $lengthCRM_active = $wirePitch * $nChannelsLengthPerCRM;
94 
95 $widthCRM = $widthCRM_active + 2 * $borderCRM;
96 $lengthCRM = $lengthCRM_active + 2 * $borderCRM;
97 
98 # number of CRMs in y and z
99 $nCRM_y = 1;
100 $nCRM_z = 1;
101 
102 # calculate tpc area based on number of CRMs and their dimensions
103 $widthTPCActive = $nCRM_y * $widthCRM; # around 100
104 $lengthTPCActive = $nCRM_z * $lengthCRM; # around 300
105 
106 # active volume dimensions
107 $driftTPCActive = 100.0;
108 
109 # model anode strips as wires
110 $padWidth = 0.015;
111 $ReadoutPlane = 2 * $padWidth;
112 
113 #$padHeight = 0.0035;
114 
115 ##################################################################
116 ############## Parameters for TPC and inner volume ###############
117 
118 # inner volume dimensions of the cryostat
119 $Argon_x = 238.1;
120 $Argon_y = 202.5;
121 $Argon_z = 478.2;
122 
123 # height of gas argon layer on top
124 $HeightGaseousAr = 50.8;
125 
126 # size of liquid argon buffer
127 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
128 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
129 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
130 
131 # cryostat
132 $SteelThickness = 0.12; # membrane
133 
134 $Cryostat_x = $Argon_x + 2*$SteelThickness;
135 $Cryostat_y = $Argon_y + 2*$SteelThickness;
136 $Cryostat_z = $Argon_z + 2*$SteelThickness;
137 
138 ##################################################################
139 ############## Parameters for PMTs ###############
140 
141 #pos in cm inside the cryostat X coordinate: 2.3cm from the ground grid
142  @pmt_pos = ( ' x="-46.06" y="0" z="-92.246"', #-92.246"', #PMT1 - negative base - direct coating #x="-50-4.5+5.5*2.54-1.27*2.54-2.3"
143  ' x="-46.06" y="0" z="-46.123"', #-46.123"', #PMT2- negative base - plate
144  ' x="-46.06" y="0" z="0"', #PMT3 - positive base - direct coating
145  ' x="-46.06" y="0" z="46.123"', #46.123"', #PMT4 - positive base - plate
146  ' x="-46.06" y="0" z="92.246"'); #92.246"'); #PMT5 - negative base - direct coating
147 
148 
149 ##################################################################
150 ############## DetEnc and World relevant parameters #############
151 
152 $SteelSupport_x = 0.6;
153 $SteelSupport_y = 0.6;
154 $SteelSupport_z = 0.6;
155 $FoamPadding = 102.3;
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 = 0;
161 $SpaceSteelSupportToCeiling = 0;
162 
163 $DetEncX = $Cryostat_x
164  + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
165 
166 $DetEncY = $Cryostat_y
167  + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
168 
169 $DetEncZ = $Cryostat_z
170  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
171 
172 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
173 
174 
175 # 2*AirThickness is added to the world volume in x, y and z
176 $AirThickness = 3000;
177 
178  # We want the world origin to be vertically centered on active TPC
179  # This is to be added to the x and y position of every volume in volWorld
180 
181 $OriginXSet = $DetEncX/2.0
182  -$SteelSupport_x
183  -$FoamPadding
184  -$SteelThickness
185  -$xLArBuffer
186  -$driftTPCActive/2.0;
187 
188 $OriginYSet = $DetEncY/2.0
189  - $SpaceSteelSupportToWall
190  - $SteelSupport_y
191  - $FoamPadding
192  - $SteelThickness
193  - $yLArBuffer
194  - $widthTPCActive/2.0;
195 
196  # We want the world origin to be at the very front of the fiducial volume.
197  # move it to the front of the enclosure, then back it up through the concrete/foam,
198  # then through the Cryostat shell, then through the upstream dead LAr (including the
199  # dead LAr on the edge of the TPC)
200  # This is to be added to the z position of every volume in volWorld
201 
202 $OriginZSet = $DetEncZ/2.0
203  - $SpaceSteelSupportToWall
204  - $SteelSupport_z
205  - $FoamPadding
206  - $SteelThickness
207  - $zLArBuffer
208  - $borderCRM;
209 
210 
211 ##################################################################
212 ############### Parameters for det elements ######################
213 
214 # cathode plane
215 #$Cathode_x = $widthTPCActive;
216 #$Cathode_y = 1.0;
217 #$Cathode_z = $lengthTPCActive;
218 
219 
220 
221 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
222 
223 
224 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
225 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
226 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
227 
228 sub usage()
229 {
230  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
231  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
232  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
233  print " -h prints this message, then quits\n";
234 }
235 
236 
237 
238 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
239 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
240 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
241 
242 sub gen_Define()
243 {
244 
245 # Create the <define> fragment file name,
246 # add file to list of fragments,
247 # and open it
248  $DEF = $basename."_Def" . $suffix . ".gdml";
249  push (@gdmlFiles, $DEF);
250  $DEF = ">" . $DEF;
251  open(DEF) or die("Could not open file $DEF for writing");
252 
253 
254 print DEF <<EOF;
255 <?xml version='1.0'?>
256 <gdml>
257 <define>
258 
259 <!--
260 
261 
262 
263 -->
264 
265  <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
266  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
267  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
268  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
269  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
270  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
271  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
272  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
273  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
274 </define>
275 </gdml>
276 EOF
277  close (DEF);
278 }
279 
280 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
281 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
282 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
283 
284 sub gen_Materials()
285 {
286 
287 # Create the <materials> fragment file name,
288 # add file to list of output GDML fragments,
289 # and open it
290  $MAT = $basename."_Materials" . $suffix . ".gdml";
291  push (@gdmlFiles, $MAT);
292  $MAT = ">" . $MAT;
293 
294  open(MAT) or die("Could not open file $MAT for writing");
295 
296  # Add any materials special to this geometry by defining a mulitline string
297  # and passing it to the gdmlMaterials::gen_Materials() function.
298 my $asmix = <<EOF;
299  <!-- preliminary values -->
300  <material name="AirSteelMixture" formula="AirSteelMixture">
301  <D value=" @{[0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel]} " unit="g/cm3"/>
302  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
303  <fraction n="$FracMassOfAir" ref="Air"/>
304  </material>
305 EOF
306 
307  # add the general materials used anywere
308  print MAT gdmlMaterials::gen_Materials( $asmix );
309 
310  close(MAT);
311 }
312 
313 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
314 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
315 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
316 sub gen_TPC()
317 {
318  # CRM active volume
319  my $TPCActive_x = $driftTPCActive;
320  my $TPCActive_y = $widthCRM_active;
321  my $TPCActive_z = $lengthCRM_active;
322 
323  # CRM total volume
324  my $TPC_x = $TPCActive_x + $ReadoutPlane;
325  my $TPC_y = $widthCRM;
326  my $TPC_z = $lengthCRM;
327 
328 
329  $TPC = $basename."_TPC" . $suffix . ".gdml";
330  push (@gdmlFiles, $TPC);
331  $TPC = ">" . $TPC;
332  open(TPC) or die("Could not open file $TPC for writing");
333 
334 # The standard XML prefix and starting the gdml
335  print TPC <<EOF;
336 <?xml version='1.0'?>
337 <gdml>
338 EOF
339 
340 
341  # All the TPC solids save the wires.
342  print TPC <<EOF;
343 <solids>
344  <box name="CRM" lunit="cm"
345  x="$TPC_x"
346  y="$TPC_y"
347  z="$TPC_z"/>
348  <box name="CRMVPlane" lunit="cm"
349  x="$padWidth"
350  y="$TPCActive_y"
351  z="$TPCActive_z"/>
352  <box name="CRMZPlane" lunit="cm"
353  x="$padWidth"
354  y="$TPCActive_y"
355  z="$TPCActive_z"/>
356  <box name="CRMActive" lunit="cm"
357  x="$TPCActive_x"
358  y="$TPCActive_y"
359  z="$TPCActive_z"/>
360 EOF
361 
362 
363 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
364 # in principle we only need only one wire solid, since CRM is a square
365 # but to be more general ...
366 
367 print TPC <<EOF;
368 
369  <tube name="CRMWireV"
370  rmax="@{[0.5*$padWidth]}"
371  z="$TPCActive_z"
372  deltaphi="360"
373  aunit="deg"
374  lunit="cm"/>
375  <tube name="CRMWireZ"
376  rmax="@{[0.5*$padWidth]}"
377  z="$TPCActive_y"
378  deltaphi="360"
379  aunit="deg"
380  lunit="cm"/>
381 </solids>
382 
383 EOF
384 
385 
386 # Begin structure and create wire logical volumes
387 print TPC <<EOF;
388 <structure>
389  <volume name="volTPCActive">
390  <materialref ref="LAr"/>
391  <solidref ref="CRMActive"/>
392  <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
393  </volume>
394 EOF
395 
396 if ($wires_on==1)
397 {
398  print TPC <<EOF;
399  <volume name="volTPCWireV">
400  <materialref ref="Copper_Beryllium_alloy25"/>
401  <solidref ref="CRMWireV"/>
402  </volume>
403 
404  <volume name="volTPCWireZ">
405  <materialref ref="Copper_Beryllium_alloy25"/>
406  <solidref ref="CRMWireZ"/>
407  </volume>
408 EOF
409 }
410 
411 print TPC <<EOF;
412 
413  <volume name="volTPCPlaneV">
414  <materialref ref="LAr"/>
415  <solidref ref="CRMVPlane"/>
416 EOF
417 
418 if ($wires_on==1) # add wires to Y plane (plane with wires reading y position)
419 {
420 for($i=0;$i<$nChannelsWidthPerCRM;++$i)
421 {
422 my $ypos = -0.5 * $TPCActive_y + ($i+0.5)*$wirePitch + 0.5*$padWidth;
423 
424 print TPC <<EOF;
425  <physvol>
426  <volumeref ref="volTPCWireV"/>
427  <position name="posWireV$i" unit="cm" x="0" y="$ypos" z="0"/>
428  <rotationref ref="rIdentity"/>
429  </physvol>
430 EOF
431 }
432 }
433 
434 print TPC <<EOF;
435  </volume>
436 
437  <volume name="volTPCPlaneZ">
438  <materialref ref="LAr"/>
439  <solidref ref="CRMZPlane"/>
440 EOF
441 
442 
443 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
444 {
445 for($i=0;$i<$nChannelsLengthPerCRM;++$i)
446 {
447 
448 my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitch + 0.5*$padWidth;
449 print TPC <<EOF;
450  <physvol>
451  <volumeref ref="volTPCWireZ"/>
452  <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
453  <rotationref ref="rPlus90AboutX"/>
454  </physvol>
455 EOF
456 }
457 }
458 
459 
460 print TPC <<EOF;
461  </volume>
462 EOF
463 
464 
465 $posVplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
466 $posVplane[1] = 0;
467 $posVplane[2] = 0;
468 
469 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
470 $posZplane[1] = 0;
471 $posZplane[2] = 0;
472 
473 $posTPCActive[0] = -$ReadoutPlane;
474 $posTPCActive[1] = 0;
475 $posTPCActive[2] = 0;
476 
477 
478 #wrap up the TPC file
479 print TPC <<EOF;
480 
481  <volume name="volTPC">
482  <materialref ref="LAr"/>
483  <solidref ref="CRM"/>
484  <physvol>
485  <volumeref ref="volTPCPlaneV"/>
486  <position name="posPlaneV" unit="cm"
487  x="$posVplane[0]" y="$posVplane[1]" z="$posVplane[2]"/>
488  <rotationref ref="rIdentity"/>
489  </physvol>
490  <physvol>
491  <volumeref ref="volTPCPlaneZ"/>
492  <position name="posPlaneZ" unit="cm"
493  x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
494  <rotationref ref="rIdentity"/>
495  </physvol>
496  <physvol>
497  <volumeref ref="volTPCActive"/>
498  <position name="posActive" unit="cm"
499  x="@{[$posTPCActive[0]+$padWidth]}" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
500  <rotationref ref="rIdentity"/>
501  </physvol>
502  </volume>
503 EOF
504 
505 
506 print TPC <<EOF;
507 </structure>
508 </gdml>
509 EOF
510 
511 close(TPC);
512 }
513 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
514 #++++++++++++++++++++++++++++++++++++++ gen_pmt +++++++++++++++++++++++++++++++++++++
515 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
516 
517 sub gen_pmt {
518 
519 
520 #PMTs
521 
522 #$PMT_COATING_THICKNESS=0.2;
523 #$PMT_PLATE_THICKNESS=0.4;
524 #$PMT_GLASS_THICKNESS=0.2;
525 
526  $PMT = $basename."_PMT" . $suffix . ".gdml";
527  push (@gdmlFiles, $PMT);
528  $PMT = ">" . $PMT;
529  open(PMT) or die("Could not open file $PMT for writing");
530 
531 
532  print PMT <<EOF;
533 
534 <solids>
535  <tube name="PMTVolume"
536  rmax="(6.5*2.54)"
537  z="(11.1*2.54)"
538  deltaphi="360"
539  aunit="deg"
540  lunit="cm"/>
541 
542  <tube name="PMT_AcrylicPlate"
543  rmax="11.4"
544  z="0.4"
545  deltaphi="360"
546  aunit="deg"
547  lunit="cm"/>
548 
549  <tube name="PMT_plate_coat"
550  rmax="11.4"
551  z="0.02"
552  deltaphi="360"
553  aunit="deg"
554  lunit="cm"/>
555 
556 
557  <tube aunit="deg" deltaphi="360" lunit="mm" name="pmtMiddleCylinder" rmax="102.351822048586" rmin="100.351822048586" startphi="0" z="54"/>
558  <sphere aunit="deg" deltaphi="360" deltatheta="50" lunit="mm" name="sphPartTop" rmax="133" rmin="131" startphi="0" starttheta="0"/>
559  <union name="pmt0x7fb8f489dfe0">
560  <first ref="pmtMiddleCylinder"/>
561  <second ref="sphPartTop"/>
562  <position name="pmt0x7fb8f489dfe0_pos" unit="mm" x="0" y="0" z="-57.2051768689367"/>
563  </union>
564  <sphere aunit="deg" deltaphi="360" deltatheta="31.477975238527" lunit="mm" name="sphPartBtm" rmax="133" rmin="131" startphi="0" starttheta="130"/>
565  <union name="pmt0x7fb8f48a0d50">
566  <first ref="pmt0x7fb8f489dfe0"/>
567  <second ref="sphPartBtm"/>
568  <position name="pmt0x7fb8f48a0d50_pos" unit="mm" x="0" y="0" z="57.2051768689367"/>
569  </union>
570  <tube aunit="deg" deltaphi="360" lunit="mm" name="pmtBtmTube" rmax="44.25" rmin="42.25" startphi="0" z="72"/>
571  <union name="solidpmt">
572  <first ref="pmt0x7fb8f48a0d50"/>
573  <second ref="pmtBtmTube"/>
574  <position name="solidpmt_pos" unit="mm" x="0" y="0" z="-104.905637496842"/>
575  </union>
576  <sphere aunit="deg" deltaphi="360" deltatheta="50" lunit="mm" name="pmt0x7fb8f48a1eb0" rmax="133.2" rmin="133" startphi="0" starttheta="0"/>
577  <sphere aunit="deg" deltaphi="360" deltatheta="46.5" lunit="mm" name="pmt0x7fb8f48a4860" rmax="131" rmin="130.999" startphi="0" starttheta="0"/>
578 
579 
580 </solids>
581 
582 <structure>
583 
584  <volume name="volPMTplatecoat">
585  <materialref ref="TPB"/>
586  <solidref ref="PMT_plate_coat"/>
587  <auxiliary auxtype="SensDet" auxvalue="PhotonDetector"/>
588  </volume>
589 
590  <volume name="vol_PMT_AcrylicPlate">
591  <materialref ref="Acrylic"/>
592  <solidref ref="PMT_AcrylicPlate"/>
593  </volume>
594 
595  <volume name="pmtCoatVol">
596  <materialref ref="TPB"/>
597  <solidref ref="pmt0x7fb8f48a1eb0"/>
598  <auxiliary auxtype="SensDet" auxvalue="PhotonDetector"/>
599  </volume>
600 
601  <volume name="allpmt">
602  <materialref ref="Glass"/>
603  <solidref ref="solidpmt"/>
604  </volume>
605 
606 
607 
608  <volume name="volPMT_plate">
609  <materialref ref="LAr"/>
610  <solidref ref="PMTVolume"/>
611 
612  <physvol>
613  <volumeref ref="allpmt"/>
614  <position name="posallpmt" unit="cm" x="0" y="0" z="1.27*2.54"/>
615  </physvol>
616 
617  <physvol name="volOpDetSensitive">
618  <volumeref ref="volPMTplatecoat"/>
619  <position name="posOpDetSensitive" unit="cm" x="0" y="0" z="1.27*2.54+2.5*2.54 + 1.7"/>
620  </physvol>
621 
622  <physvol>
623  <volumeref ref="vol_PMT_AcrylicPlate"/>
624  <position name="pos_PMT_AcrylicPlate" unit="cm" x="0" y="0" z="1.27*2.54+2.5*2.54 + 1.5"/>
625  </physvol>
626  </volume>
627 
628 <volume name="volPMT_coated">
629  <materialref ref="LAr"/>
630  <solidref ref="PMTVolume"/>
631 
632  <physvol>
633  <volumeref ref="allpmt"/>
634  <position name="posallpmt" unit="cm" x="0" y="0" z="1.27*2.54"/>
635  </physvol>
636 
637  <physvol name="volOpDetSensitive">
638  <volumeref ref="pmtCoatVol"/>
639  <position name="posOpDetSensitive" unit="cm" x="0" y="0" z="1.27*2.54- (2.23*2.54)"/>
640  </physvol>
641 
642  </volume>
643 
644 </structure>
645 
646 EOF
647 }
648 
649 
650 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
651 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
652 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
653 
654 sub gen_Cryostat()
655 {
656 
657 # Create the cryostat fragment file name,
658 # add file to list of output GDML fragments,
659 # and open it
660  $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
661  push (@gdmlFiles, $CRYO);
662  $CRYO = ">" . $CRYO;
663  open(CRYO) or die("Could not open file $CRYO for writing");
664 
665 
666 # The standard XML prefix and starting the gdml
667  print CRYO <<EOF;
668 <?xml version='1.0'?>
669 <gdml>
670 EOF
671 
672 # All the cryostat solids.
673 print CRYO <<EOF;
674 <solids>
675  <box name="Cryostat" lunit="cm"
676  x="$Cryostat_x"
677  y="$Cryostat_y"
678  z="$Cryostat_z"/>
679 
680  <box name="ArgonInterior" lunit="cm"
681  x="$Argon_x"
682  y="$Argon_y"
683  z="$Argon_z"/>
684 
685  <box name="GaseousArgon" lunit="cm"
686  x="$HeightGaseousAr"
687  y="$Argon_y"
688  z="$Argon_z"/>
689 
690  <subtraction name="SteelShell">
691  <first ref="Cryostat"/>
692  <second ref="ArgonInterior"/>
693  </subtraction>
694 
695 </solids>
696 EOF
697 
698 # Cryostat structure
699 print CRYO <<EOF;
700 <structure>
701  <volume name="volSteelShell">
702  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
703  <solidref ref="SteelShell" />
704  </volume>
705  <volume name="volGaseousArgon">
706  <materialref ref="ArGas"/>
707  <solidref ref="GaseousArgon"/>
708  </volume>
709 
710  <volume name="volCryostat">
711  <materialref ref="LAr" />
712  <solidref ref="Cryostat" />
713  <physvol>
714  <volumeref ref="volGaseousArgon"/>
715  <position name="posGaseousArgon" unit="cm" x="$Argon_x/2-$HeightGaseousAr/2" y="0" z="0"/>
716  </physvol>
717  <physvol>
718  <volumeref ref="volSteelShell"/>
719  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
720  </physvol>
721 EOF
722 
723 
724 if ($tpc_on==1) # place TPC inside croysotat
725 {
726 
727 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
728 for($ii=0;$ii<$nCRM_z;$ii++)
729 {
730  $posZ = -0.5*$Argon_z + $zLArBuffer + ($ii+0.5)*$lengthCRM;
731 
732  for($jj=0;$jj<$nCRM_y;$jj++)
733  {
734  $posY = -0.5*$Argon_y + $yLArBuffer + ($jj+0.5)*$widthCRM;
735  print CRYO <<EOF;
736  <physvol>
737  <volumeref ref="volTPC"/>
738  <position name="posTPC\-$ii\-$jj" unit="cm"
739  x="$posX" y="$posY" z="$posZ"/>
740  </physvol>
741 EOF
742  }
743 }
744 
745 }
746 
747 
748  if ( $pmt_switch eq "on" ) {
749  for ( $i=0; $i<5; $i=$i+1 ) { # pmts with coating
750  print CRYO <<EOF;
751  <physvol>
752 EOF
753  if ( $i eq "1" || $i eq "3") {
754  print CRYO <<EOF;
755  <volumeref ref="volPMT_plate"/>
756 EOF
757  }
758  else {
759  print CRYO <<EOF;
760  <volumeref ref="volPMT_coated"/>
761 EOF
762  }
763  print CRYO <<EOF;
764 
765  <position name="posPMT$i" unit="cm" @pmt_pos[$i]/>
766  <rotationref ref="rMinus90AboutY"/>
767  </physvol>
768 EOF
769  }
770 
771 
772  }
773  print CRYO <<EOF;
774  </volume>
775 </structure>
776 </gdml>
777 EOF
778 
779 
780 close(CRYO);
781 }
782 
783 
784 
785 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
786 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
787 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
788 
789 sub gen_Enclosure()
790 {
791 
792 # Create the detector enclosure fragment file name,
793 # add file to list of output GDML fragments,
794 # and open it
795  $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
796  push (@gdmlFiles, $ENCL);
797  $ENCL = ">" . $ENCL;
798  open(ENCL) or die("Could not open file $ENCL for writing");
799 
800 
801 # The standard XML prefix and starting the gdml
802  print ENCL <<EOF;
803 <?xml version='1.0'?>
804 <gdml>
805 EOF
806 
807 
808 # All the detector enclosure solids.
809 print ENCL <<EOF;
810 <solids>
811 
812  <box name="FoamPadBlock" lunit="cm"
813  x="@{[$Cryostat_x + 2*$FoamPadding]}"
814  y="@{[$Cryostat_y + 2*$FoamPadding]}"
815  z="@{[$Cryostat_z + 2*$FoamPadding]}" />
816 
817  <subtraction name="FoamPadding">
818  <first ref="FoamPadBlock"/>
819  <second ref="Cryostat"/>
820  <positionref ref="posCenter"/>
821  </subtraction>
822 
823  <box name="SteelSupportBlock" lunit="cm"
824  x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
825  y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
826  z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
827 
828  <subtraction name="SteelSupport">
829  <first ref="SteelSupportBlock"/>
830  <second ref="FoamPadBlock"/>
831  <positionref ref="posCenter"/>
832  </subtraction>
833 
834  <box name="DetEnclosure" lunit="cm"
835  x="$DetEncX"
836  y="$DetEncY"
837  z="$DetEncZ"/>
838 
839 </solids>
840 EOF
841 
842 
843 # Detector enclosure structure
844  print ENCL <<EOF;
845 <structure>
846  <volume name="volFoamPadding">
847  <materialref ref="foam_3x1x1dp"/>
848  <solidref ref="FoamPadding"/>
849  </volume>
850 
851  <volume name="volSteelSupport">
852  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
853  <solidref ref="SteelSupport"/>
854  </volume>
855 
856  <volume name="volDetEnclosure">
857  <materialref ref="Air"/>
858  <solidref ref="DetEnclosure"/>
859 
860  <physvol>
861  <volumeref ref="volFoamPadding"/>
862  <positionref ref="posCryoInDetEnc"/>
863  </physvol>
864  <physvol>
865  <volumeref ref="volSteelSupport"/>
866  <positionref ref="posCryoInDetEnc"/>
867  </physvol>
868  <physvol>
869  <volumeref ref="volCryostat"/>
870  <positionref ref="posCryoInDetEnc"/>
871  </physvol>
872 EOF
873 
874 
875 print ENCL <<EOF;
876  </volume>
877 EOF
878 
879 print ENCL <<EOF;
880 </structure>
881 </gdml>
882 EOF
883 
884 close(ENCL);
885 }
886 
887 
888 
889 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
890 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
891 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
892 
893 sub gen_World()
894 {
895 
896 # Create the WORLD fragment file name,
897 # add file to list of output GDML fragments,
898 # and open it
899  $WORLD = $basename."_World" . $suffix . ".gdml";
900  push (@gdmlFiles, $WORLD);
901  $WORLD = ">" . $WORLD;
902  open(WORLD) or die("Could not open file $WORLD for writing");
903 
904 
905 # The standard XML prefix and starting the gdml
906  print WORLD <<EOF;
907 <?xml version='1.0'?>
908 <gdml>
909 EOF
910 
911 
912 # All the World solids.
913 print WORLD <<EOF;
914 <solids>
915  <box name="World" lunit="cm"
916  x="@{[$DetEncX+2*$AirThickness]}"
917  y="@{[$DetEncY+2*$AirThickness]}"
918  z="@{[$DetEncZ+2*$AirThickness]}"/>
919 </solids>
920 EOF
921 
922 # World structure
923 print WORLD <<EOF;
924 <structure>
925  <volume name="volWorld" >
926  <materialref ref="Air"/>
927  <solidref ref="World"/>
928 
929  <physvol>
930  <volumeref ref="volDetEnclosure"/>
931  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
932  </physvol>
933 
934  </volume>
935 </structure>
936 </gdml>
937 EOF
938 
939 # make_gdml.pl will take care of <setup/>
940 
941 close(WORLD);
942 }
943 
944 
945 
946 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
947 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
948 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
949 
950 sub write_fragments()
951 {
952  # This subroutine creates an XML file that summarizes the the subfiles output
953  # by the other sub routines - it is the input file for make_gdml.pl which will
954  # give the final desired GDML file. Specify its name with the output option.
955  # (you can change the name when running make_gdml)
956 
957  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
958 
959  if ( ! defined $output )
960  {
961  $output = "-"; # write to STDOUT
962  }
963 
964  # Set up the output file.
965  $OUTPUT = ">" . $output;
966  open(OUTPUT) or die("Could not open file $OUTPUT");
967 
968  print OUTPUT <<EOF;
969 <?xml version='1.0'?>
970 
971 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
972  that will be zipped together to create a detector description.
973  -->
974 
975 <config>
976 
977  <constantfiles>
978 
979  <!-- These files contain GDML <constant></constant>
980  blocks. They are read in separately, so they can be
981  interpreted into the remaining GDML. See make_gdml.pl for
982  more information.
983  -->
984 
985 EOF
986 
987  foreach $filename (@defFiles)
988  {
989  print OUTPUT <<EOF;
990  <filename> $filename </filename>
991 EOF
992  }
993 
994  print OUTPUT <<EOF;
995 
996  </constantfiles>
997 
998  <gdmlfiles>
999 
1000  <!-- The GDML file fragments to be zipped together. -->
1001 
1002 EOF
1003 
1004  foreach $filename (@gdmlFiles)
1005  {
1006  print OUTPUT <<EOF;
1007  <filename> $filename </filename>
1008 EOF
1009  }
1010 
1011  print OUTPUT <<EOF;
1012 
1013  </gdmlfiles>
1014 
1015 </config>
1016 EOF
1017 
1018  close(OUTPUT);
1019 }
1020 
1021 
1022 print "Some key parameters for dual-phase LAr TPC (unit cm unless noted otherwise)\n";
1023 print "CRM active area : $widthCRM_active x $lengthCRM_active\n";
1024 print "CRM total area : $widthCRM x $lengthCRM\n";
1025 print "TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1026 print "Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1027 print "Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1028 print "TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1029 print "PMTs : $pmt_switch \n";
1030 
1031 # run the sub routines that generate the fragments
1032 if ( $pmt_switch eq "on" ) { gen_pmt(); }
1033 
1034 
1035 gen_Define(); # generates definitions at beginning of GDML
1036 gen_Materials(); # generates materials to be used
1037 gen_TPC(); # generate TPC for a given unit CRM
1038 gen_Cryostat(); #
1039 gen_Enclosure(); #
1040 gen_World(); # places the enclosure among DUSEL Rock
1041 
1042 
1043 write_fragments(); # writes the XML input for make_gdml.pl
1044  # which zips together the final GDML
1045 exit;