generate_dunevd10kt_2view_v1_refactored.pl
Go to the documentation of this file.
1 #!/usr/bin/perl
2 
3 #
4 #
5 # First attempt to make a GDML fragment generator for the DUNE vertical drift
6 # 10kt detector geometry with 2 orthogonal view readout
7 # The lower chamber is not added yet.
8 # !!!NOTE!!!: the readout is on a positive Y plane (drift along horizontal X)
9 # due to current reco limitations)
10 # No photon detectors declared
11 # Simplified treatment of inter-module dead spaces
12 #
13 # Created: Thu Oct 1 16:45:27 CEST 2020
14 # Vyacheslav Galymov <vgalymov@ipnl.in2p3.fr>
15 #
16 # Modified:
17 # VG: Added defs to enable use in the refactored sim framework
18 #
19 #
20 #
21 #################################################################################
22 
23 # Each subroutine generates a fragment GDML file, and the last subroutine
24 # creates an XML file that make_gdml.pl will use to appropriately arrange
25 # the fragment GDML files to create the final desired DUNE GDML file,
26 # to be named by make_gdml output command
27 
28 ##################################################################################
29 
30 
31 #use warnings;
32 use gdmlMaterials;
33 use Math::Trig;
34 use Getopt::Long;
35 use Math::BigFloat;
36 Math::BigFloat->precision(-16);
37 
38 GetOptions( "help|h" => \$help,
39  "suffix|s:s" => \$suffix,
40  "output|o:s" => \$output,
41  "wires|w:s" => \$wires,
42  "workspace|k:s" => \$wkspc);
43 
44 my $FieldCage_switch="off";
45 my $Cathode_switch="off";
46 
47 if ( defined $help )
48 {
49  # If the user requested help, print the usage notes and exit.
50  usage();
51  exit;
52 }
53 
54 if ( ! defined $suffix )
55 {
56  # The user didn't supply a suffix, so append nothing to the file
57  # names.
58  $suffix = "";
59 }
60 else
61 {
62  # Otherwise, stick a "-" before the suffix, so that a suffix of
63  # "test" applied to filename.gdml becomes "filename-test.gdml".
64  $suffix = "-" . $suffix;
65 }
66 
67 
68 $workspace = 0;
69 if(defined $wkspc )
70 {
71  $workspace = $wkspc;
72 }
73 elsif ( $workspace != 0 )
74 {
75  print "\t\tCreating smaller workspace geometry.\n";
76 }
77 
78 # set wires on to be the default, unless given an input by the user
79 $wires_on = 1; # 1=on, 0=off
80 if (defined $wires)
81 {
82  $wires_on = $wires;
83 }
84 
85 $tpc_on = 1;
86 $basename="_";
87 
88 
89 ##################################################################
90 ############## Parameters for One Readout Panel ##################
91 
92 # parameters for 1.5 x 1.7 sub-unit Charge Readout Module / Unit
93 #$widthPCBActive = 169.0; # cm
94 #$lengthPCBActive = 150.0; # cm
95 $nChannelsViewInd = 320;
96 $nChannelsViewCol = 288;
97 
98 $wirePitchY = 0.527; # $widthPCBActive / $nChannelsViewInd;
99 $wirePitchZ = 0.518; # $lengthPCBActive / $nChannelsViewCol;
100 
101 $widthPCBActive = $wirePitchY * $nChannelsViewInd;
102 $lengthPCBActive = $wirePitchZ * $nChannelsViewCol;
103 
104 $borderCRM = 0.05; # dead space at the border of each CRM
105 
106 $widthCRM_active = $widthPCBActive;
107 $lengthCRM_active = $lengthPCBActive;
108 
109 $widthCRM = $widthPCBActive + 2 * $borderCRM;
110 $lengthCRM = $lengthPCBActive + 2 * $borderCRM;
111 
112 # number of CRMs in y and z
113 $nCRM_x = 4 * 2;
114 $nCRM_z = 20 * 2;
115 
116 # create a smaller geometry
117 if( $workspace == 1 )
118 {
119  $nCRM_x = 1 * 2;
120  $nCRM_z = 1 * 2;
121 }
122 
123 # create a smaller geometry
124 if( $workspace == 2 )
125 {
126  $nCRM_x = 2 * 2;
127  $nCRM_z = 2 * 2;
128 }
129 
130 # create a smaller geometry
131 if( $workspace == 3 )
132 {
133  $nCRM_x = 3 * 2;
134  $nCRM_z = 3 * 2;
135 }
136 
137 
138 # calculate tpc area based on number of CRMs and their dimensions
139 $widthTPCActive = $nCRM_x * $widthCRM; # around 1200 for full module
140 $lengthTPCActive = $nCRM_z * $lengthCRM; # around 6000 for full module
141 
142 # active volume dimensions
143 $driftTPCActive = 650.0;
144 
145 # model anode strips as wires of some diameter
146 $padWidth = 0.02;
147 $ReadoutPlane = 2 * $padWidth; ## + 0.5; # 5 mm thick PCB?
148 
149 ##################################################################
150 ############## Parameters for TPC and inner volume ###############
151 
152 # inner volume dimensions of the cryostat
153 $Argon_x = 1510;
154 $Argon_y = 1510;
155 $Argon_z = 6200;
156 
157 # width of gas argon layer on top
158 $HeightGaseousAr = 100;
159 
160 if( $workspace != 0 )
161 {
162  #active tpc + 1.0 m buffer on each side
163  $Argon_x = $driftTPCActive + $HeightGaseousAr + $ReadoutPlane + 100;
164  $Argon_y = $widthTPCActive + 200;
165  $Argon_z = $lengthTPCActive + 200;
166 }
167 
168 
169 # size of liquid argon buffer
170 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
171 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
172 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
173 
174 # cryostat
175 $SteelThickness = 0.12; # membrane
176 
177 $Cryostat_x = $Argon_x + 2*$SteelThickness;
178 $Cryostat_y = $Argon_y + 2*$SteelThickness;
179 $Cryostat_z = $Argon_z + 2*$SteelThickness;
180 
181 ##################################################################
182 ############## DetEnc and World relevant parameters #############
183 ##################################################################
184 ############## DetEnc and World relevant parameters #############
185 
186 $SteelSupport_x = 100;
187 $SteelSupport_y = 100;
188 $SteelSupport_z = 100;
189 $FoamPadding = 80;
190 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
191 $FracMassOfAir = 1 - $FracMassOfSteel;
192 
193 
194 $SpaceSteelSupportToWall = 100;
195 $SpaceSteelSupportToCeiling = 100;
196 
197 $DetEncX = $Cryostat_x
198  + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
199 
200 $DetEncY = $Cryostat_y
201  + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
202 
203 $DetEncZ = $Cryostat_z
204  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
205 
206 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
207 
208 
209 $RockThickness = 4000;
210 
211  # We want the world origin to be vertically centered on active TPC
212  # This is to be added to the x and y position of every volume in volWorld
213 
214 $OriginXSet = $DetEncX/2.0
215  - $SteelSupport_x
216  - $FoamPadding
217  - $SteelThickness
218  - $xLArBuffer
219  - $driftTPCActive/2.0;
220 
221 $OriginYSet = $DetEncY/2.0
222  - $SpaceSteelSupportToWall
223  - $SteelSupport_y
224  - $FoamPadding
225  - $SteelThickness
226  - $yLArBuffer
227  - $widthTPCActive/2.0;
228 
229  # We want the world origin to be at the very front of the fiducial volume.
230  # move it to the front of the enclosure, then back it up through the concrete/foam,
231  # then through the Cryostat shell, then through the upstream dead LAr (including the
232  # dead LAr on the edge of the TPC)
233  # This is to be added to the z position of every volume in volWorld
234 
235 $OriginZSet = $DetEncZ/2.0
236  - $SpaceSteelSupportToWall
237  - $SteelSupport_z
238  - $FoamPadding
239  - $SteelThickness
240  - $zLArBuffer
241  - $borderCRM;
242 
243 ##################################################################
244 ############## Field Cage Parameters ###############
245 $FieldShaperLongTubeLength = $lengthTPCActive;
246 $FieldShaperShortTubeLength = $widthTPCActive;
247 $FieldShaperInnerRadius = 1.485;
248 $FieldShaperOuterRadius = 1.685;
249 $FieldShaperTorRad = 1.69;
250 
251 $FieldShaperLength = $FieldShaperLongTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
252 $FieldShaperWidth = $FieldShaperShortTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
253 
254 $FieldShaperSeparation = 5.0;
255 $NFieldShapers = ($driftTPCActive/$FieldShaperSeparation) - 1;
256 
257 $FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2;
258 $FieldCageSizeY = $FieldShaperWidth+2;
259 $FieldCageSizeZ = $FieldShaperLength+2;
260 
261 
262 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
263 
264 
265 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
266 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
267 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
268 
269 sub usage()
270 {
271  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
272  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
273  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
274  print " -h prints this message, then quits\n";
275 }
276 
277 
278 sub gen_Extend()
279 {
280 
281 # Create the <define> fragment file name,
282 # add file to list of fragments,
283 # and open it
284  $DEF = $basename."_Ext" . $suffix . ".gdml";
285  push (@gdmlFiles, $DEF);
286  $DEF = ">" . $DEF;
287  open(DEF) or die("Could not open file $DEF for writing");
288 
289 print DEF <<EOF;
290 <?xml version='1.0'?>
291 <gdml>
292 <extension>
293  <color name="magenta" R="0.0" G="1.0" B="0.0" A="1.0" />
294  <color name="green" R="0.0" G="1.0" B="0.0" A="1.0" />
295  <color name="red" R="1.0" G="0.0" B="0.0" A="1.0" />
296  <color name="blue" R="0.0" G="0.0" B="1.0" A="1.0" />
297  <color name="yellow" R="1.0" G="1.0" B="0.0" A="1.0" />
298 </extension>
299 </gdml>
300 EOF
301  close (DEF);
302 }
303 
304 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
305 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
306 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
307 
308 sub gen_Define()
309 {
310 
311 # Create the <define> fragment file name,
312 # add file to list of fragments,
313 # and open it
314  $DEF = $basename."_Def" . $suffix . ".gdml";
315  push (@gdmlFiles, $DEF);
316  $DEF = ">" . $DEF;
317  open(DEF) or die("Could not open file $DEF for writing");
318 
319 
320 print DEF <<EOF;
321 <?xml version='1.0'?>
322 <gdml>
323 <define>
324 
325 <!--
326 
327 
328 
329 -->
330 
331  <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
332  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
333  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
334  <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
335  <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
336  <rotation name="rMinus90AboutX" unit="deg" x="270" y="0" z="0"/>
337  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
338  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
339  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
340  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
341  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
342  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
343 </define>
344 </gdml>
345 EOF
346  close (DEF);
347 }
348 
349 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
350 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
351 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
352 
353 sub gen_Materials()
354 {
355 
356 # Create the <materials> fragment file name,
357 # add file to list of output GDML fragments,
358 # and open it
359  $MAT = $basename."_Materials" . $suffix . ".gdml";
360  push (@gdmlFiles, $MAT);
361  $MAT = ">" . $MAT;
362 
363  open(MAT) or die("Could not open file $MAT for writing");
364 
365  # Add any materials special to this geometry by defining a mulitline string
366  # and passing it to the gdmlMaterials::gen_Materials() function.
367 my $asmix = <<EOF;
368  <!-- preliminary values -->
369  <material name="AirSteelMixture" formula="AirSteelMixture">
370  <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
371  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
372  <fraction n="$FracMassOfAir" ref="Air"/>
373  </material>
374  <material name="vm2000" formula="vm2000">
375  <D value="1.2" unit="g/cm3"/>
376  <composite n="2" ref="carbon"/>
377  <composite n="4" ref="hydrogen"/>
378  </material>
379 EOF
380 
381  # add the general materials used anywere
382  print MAT gdmlMaterials::gen_Materials( $asmix );
383 
384  close(MAT);
385 }
386 
387 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
388 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
389 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
390 sub gen_TPC()
391 {
392  # CRM active volume
393  my $TPCActive_x = $driftTPCActive;
394  my $TPCActive_y = $widthCRM_active;
395  my $TPCActive_z = $lengthCRM_active;
396 
397  # CRM total volume
398  my $TPC_x = $TPCActive_x + $ReadoutPlane;
399  my $TPC_y = $widthCRM;
400  my $TPC_z = $lengthCRM;
401 
402 
403  $TPC = $basename."_TPC" . $suffix . ".gdml";
404  push (@gdmlFiles, $TPC);
405  $TPC = ">" . $TPC;
406  open(TPC) or die("Could not open file $TPC for writing");
407 
408 # The standard XML prefix and starting the gdml
409  print TPC <<EOF;
410 <?xml version='1.0'?>
411 <gdml>
412 EOF
413 
414 
415  # All the TPC solids save the wires.
416  print TPC <<EOF;
417 <solids>
418  <box name="CRM" lunit="cm"
419  x="$TPC_x"
420  y="$TPC_y"
421  z="$TPC_z"/>
422  <box name="CRMVPlane" lunit="cm"
423  x="$padWidth"
424  y="$TPCActive_y"
425  z="$TPCActive_z"/>
426  <box name="CRMZPlane" lunit="cm"
427  x="$padWidth"
428  y="$TPCActive_y"
429  z="$TPCActive_z"/>
430  <box name="CRMActive" lunit="cm"
431  x="$TPCActive_x"
432  y="$TPCActive_y"
433  z="$TPCActive_z"/>
434 EOF
435 
436 
437 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
438 
439 print TPC <<EOF;
440 
441  <tube name="CRMWireV"
442  rmax="0.5*$padWidth"
443  z="$TPCActive_z"
444  deltaphi="360"
445  aunit="deg"
446  lunit="cm"/>
447  <tube name="CRMWireZ"
448  rmax="0.5*$padWidth"
449  z="$TPCActive_y"
450  deltaphi="360"
451  aunit="deg"
452  lunit="cm"/>
453 </solids>
454 
455 EOF
456 
457 
458 # Begin structure and create wire logical volumes
459 print TPC <<EOF;
460 <structure>
461  <volume name="volTPCActive">
462  <materialref ref="LAr"/>
463  <solidref ref="CRMActive"/>
464  <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
465  <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5*cm"/>
466  <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="500*V/cm"/>
467  <colorref ref="blue"/>
468  </volume>
469 EOF
470 
471 if ($wires_on==1)
472 {
473  print TPC <<EOF;
474  <volume name="volTPCWireV">
475  <materialref ref="Copper_Beryllium_alloy25"/>
476  <solidref ref="CRMWireV"/>
477  </volume>
478 
479  <volume name="volTPCWireZ">
480  <materialref ref="Copper_Beryllium_alloy25"/>
481  <solidref ref="CRMWireZ"/>
482  </volume>
483 EOF
484 }
485 
486 print TPC <<EOF;
487 
488  <volume name="volTPCPlaneV">
489  <materialref ref="LAr"/>
490  <solidref ref="CRMVPlane"/>
491 EOF
492 
493 if ($wires_on==1) # add wires to Y plane (plane with wires reading y position)
494 {
495 for($i=0;$i<$nChannelsViewInd;++$i)
496 {
497 my $ypos = -0.5 * $TPCActive_y + ($i+0.5)*$wirePitchY + 0.5*$padWidth;
498 
499 print TPC <<EOF;
500  <physvol>
501  <volumeref ref="volTPCWireV"/>
502  <position name="posWireV$i" unit="cm" x="0" y="$ypos" z="0"/>
503  <rotationref ref="rIdentity"/>
504  </physvol>
505 EOF
506 }
507 }
508 
509 print TPC <<EOF;
510  </volume>
511 
512  <volume name="volTPCPlaneZ">
513  <materialref ref="LAr"/>
514  <solidref ref="CRMZPlane"/>
515 EOF
516 
517 
518 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
519 {
520 for($i=0;$i<$nChannelsViewCol;++$i)
521 {
522 
523 my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitchZ + 0.5*$padWidth;
524 print TPC <<EOF;
525  <physvol>
526  <volumeref ref="volTPCWireZ"/>
527  <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
528  <rotationref ref="rPlus90AboutX"/>
529  </physvol>
530 EOF
531 }
532 }
533 
534 
535 print TPC <<EOF;
536  </volume>
537 EOF
538 
539 
540 $posVplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
541 $posVplane[1] = 0;
542 $posVplane[2] = 0;
543 
544 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
545 $posZplane[1] = 0;
546 $posZplane[2] = 0;
547 
548 $posTPCActive[0] = -$ReadoutPlane/2;
549 $posTPCActive[1] = 0;
550 $posTPCActive[2] = 0;
551 
552 
553 #wrap up the TPC file
554 print TPC <<EOF;
555 
556  <volume name="volTPC">
557  <materialref ref="LAr"/>
558  <solidref ref="CRM"/>
559  <physvol>
560  <volumeref ref="volTPCPlaneV"/>
561  <position name="posPlaneV" unit="cm"
562  x="$posVplane[0]" y="$posVplane[1]" z="$posVplane[2]"/>
563  <rotationref ref="rIdentity"/>
564  </physvol>
565  <physvol>
566  <volumeref ref="volTPCPlaneZ"/>
567  <position name="posPlaneZ" unit="cm"
568  x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
569  <rotationref ref="rIdentity"/>
570  </physvol>
571  <physvol>
572  <volumeref ref="volTPCActive"/>
573  <position name="posActive" unit="cm"
574  x="$posTPCActive[0]" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
575  <rotationref ref="rIdentity"/>
576  </physvol>
577  </volume>
578 EOF
579 
580 
581 print TPC <<EOF;
582 </structure>
583 </gdml>
584 EOF
585 
586 close(TPC);
587 }
588 
589 
590 
591 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
592 #++++++++++++++++++++++++++++++++++++++ gen_FieldCage ++++++++++++++++++++++++++++++++++++
593 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
594 
595 sub gen_FieldCage {
596 
597  $FieldCage = $basename."_FieldCage" . $suffix . ".gdml";
598  push (@gdmlFiles, $FieldCage);
599  $FieldCage = ">" . $FieldCage;
600  open(FieldCage) or die("Could not open file $FieldCage for writing");
601 
602 # The standard XML prefix and starting the gdml
603 print FieldCage <<EOF;
604  <?xml version='1.0'?>
605  <gdml>
606 EOF
607 # The printing solids used in the Field Cage
608 #print "lengthTPCActive : $lengthTPCActive \n";
609 #print "widthTPCActive : $widthTPCActive \n";
610 
611 
612 print FieldCage <<EOF;
613 <solids>
614  <torus name="FieldShaperCorner" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" rtor="$FieldShaperTorRad" deltaphi="90" startphi="0" aunit="deg" lunit="cm"/>
615  <tube name="FieldShaperLongtube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
616  <tube name="FieldShaperShorttube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperShortTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
617 
618  <union name="FSunion1">
619  <first ref="FieldShaperLongtube"/>
620  <second ref="FieldShaperCorner"/>
621  <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
622  <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
623  </union>
624 
625  <union name="FSunion2">
626  <first ref="FSunion1"/>
627  <second ref="FieldShaperShorttube"/>
628  <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
629  <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
630  </union>
631 
632  <union name="FSunion3">
633  <first ref="FSunion2"/>
634  <second ref="FieldShaperCorner"/>
635  <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
636  <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
637  </union>
638 
639  <union name="FSunion4">
640  <first ref="FSunion3"/>
641  <second ref="FieldShaperLongtube"/>
642  <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
643  </union>
644 
645  <union name="FSunion5">
646  <first ref="FSunion4"/>
647  <second ref="FieldShaperCorner"/>
648  <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
649  <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
650  </union>
651 
652  <union name="FSunion6">
653  <first ref="FSunion5"/>
654  <second ref="FieldShaperShorttube"/>
655  <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
656  <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
657  </union>
658 
659  <union name="FieldShaperSolid">
660  <first ref="FSunion6"/>
661  <second ref="FieldShaperCorner"/>
662  <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
663  <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
664  </union>
665 </solids>
666 
667 EOF
668 
669 print FieldCage <<EOF;
670 
671 <structure>
672 <volume name="volFieldShaper">
673  <materialref ref="Al2O3"/>
674  <solidref ref="FieldShaperSolid"/>
675 </volume>
676 </structure>
677 
678 EOF
679 
680 print FieldCage <<EOF;
681 
682 </gdml>
683 EOF
684 close(FieldCage);
685 }
686 
687 
688 
689 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
690 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
691 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
692 
693 sub gen_Cryostat()
694 {
695 
696 # Create the cryostat fragment file name,
697 # add file to list of output GDML fragments,
698 # and open it
699  $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
700  push (@gdmlFiles, $CRYO);
701  $CRYO = ">" . $CRYO;
702  open(CRYO) or die("Could not open file $CRYO for writing");
703 
704 
705 # The standard XML prefix and starting the gdml
706  print CRYO <<EOF;
707 <?xml version='1.0'?>
708 <gdml>
709 EOF
710 
711 # All the cryostat solids.
712 print CRYO <<EOF;
713 <solids>
714  <box name="Cryostat" lunit="cm"
715  x="$Cryostat_x"
716  y="$Cryostat_y"
717  z="$Cryostat_z"/>
718 
719  <box name="ArgonInterior" lunit="cm"
720  x="$Argon_x"
721  y="$Argon_y"
722  z="$Argon_z"/>
723 
724  <box name="GaseousArgon" lunit="cm"
725  x="$HeightGaseousAr"
726  y="$Argon_y"
727  z="$Argon_z"/>
728 
729  <subtraction name="SteelShell">
730  <first ref="Cryostat"/>
731  <second ref="ArgonInterior"/>
732  </subtraction>
733 
734 </solids>
735 EOF
736 
737 # Cryostat structure
738 print CRYO <<EOF;
739 <structure>
740  <volume name="volSteelShell">
741  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
742  <solidref ref="SteelShell" />
743  </volume>
744  <volume name="volGaseousArgon">
745  <materialref ref="ArGas"/>
746  <solidref ref="GaseousArgon"/>
747 EOF
748 
749  print CRYO <<EOF;
750  </volume>
751 
752  <volume name="volCryostat">
753  <materialref ref="LAr" />
754  <solidref ref="Cryostat" />
755  <physvol>
756  <volumeref ref="volGaseousArgon"/>
757  <position name="posGaseousArgon" unit="cm" x="@{[$Argon_x/2-$HeightGaseousAr/2]}" y="0" z="0"/>
758  </physvol>
759  <physvol>
760  <volumeref ref="volSteelShell"/>
761  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
762  </physvol>
763 EOF
764 
765 
766 if ($tpc_on==1) # place TPC inside croysotat
767 {
768  $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
769  $idx = 0;
770  for($ii=0;$ii<$nCRM_z;$ii++)
771  {
772  $posZ = -0.5*$Argon_z + $zLArBuffer + ($ii+0.5)*$lengthCRM;
773 
774  for($jj=0;$jj<$nCRM_x;$jj++)
775  {
776  $posY = -0.5*$Argon_y + $yLArBuffer + ($jj+0.5)*$widthCRM;
777  print CRYO <<EOF;
778  <physvol>
779  <volumeref ref="volTPC"/>
780  <position name="posTPC\-$idx" unit="cm"
781  x="$posX" y="$posY" z="$posZ"/>
782  </physvol>
783 EOF
784 $idx++
785  }
786  }
787 
788 }
789 
790 #The +50 in the x positions must depend on some other parameter
791  if ( $FieldCage_switch eq "on" ) {
792  for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) { # pmts with coating
793 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
794  print CRYO <<EOF;
795  <physvol>
796  <volumeref ref="volFieldShaper"/>
797  <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
798  <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
799  </physvol>
800 EOF
801  }
802  }
803 
804 
805 $CathodePosX =-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation;
806 $CathodePosY = 0;
807 $CathodePosZ = 0;
808  if ( $Cathode_switch eq "on" )
809  {
810  print CRYO <<EOF;
811  <physvol>
812  <volumeref ref="volGroundGrid"/>
813  <position name="posGroundGrid01" unit="cm" x="$CathodePosX" y="@{[-$CathodePosY]}" z="@{[$CathodePosZ]}"/>
814  <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
815  </physvol>
816 
817 EOF
818  }
819 
820 
821  print CRYO <<EOF;
822  </volume>
823 </structure>
824 </gdml>
825 EOF
826 
827 close(CRYO);
828 }
829 
830 
831 
832 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
833 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
834 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
835 
836 sub gen_Enclosure()
837 {
838 
839 # Create the detector enclosure fragment file name,
840 # add file to list of output GDML fragments,
841 # and open it
842  $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
843  push (@gdmlFiles, $ENCL);
844  $ENCL = ">" . $ENCL;
845  open(ENCL) or die("Could not open file $ENCL for writing");
846 
847 
848 # The standard XML prefix and starting the gdml
849  print ENCL <<EOF;
850 <?xml version='1.0'?>
851 <gdml>
852 EOF
853 
854 
855 # All the detector enclosure solids.
856 print ENCL <<EOF;
857 <solids>
858 
859  <box name="FoamPadBlock" lunit="cm"
860  x="@{[$Cryostat_x + 2*$FoamPadding]}"
861  y="@{[$Cryostat_y + 2*$FoamPadding]}"
862  z="@{[$Cryostat_z + 2*$FoamPadding]}" />
863 
864  <subtraction name="FoamPadding">
865  <first ref="FoamPadBlock"/>
866  <second ref="Cryostat"/>
867  <positionref ref="posCenter"/>
868  </subtraction>
869 
870  <box name="SteelSupportBlock" lunit="cm"
871  x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
872  y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
873  z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
874 
875  <subtraction name="SteelSupport">
876  <first ref="SteelSupportBlock"/>
877  <second ref="FoamPadBlock"/>
878  <positionref ref="posCenter"/>
879  </subtraction>
880 
881  <box name="DetEnclosure" lunit="cm"
882  x="$DetEncX"
883  y="$DetEncY"
884  z="$DetEncZ"/>
885 
886 </solids>
887 EOF
888 
889 
890 # Detector enclosure structure
891  print ENCL <<EOF;
892 <structure>
893  <volume name="volFoamPadding">
894  <materialref ref="fibrous_glass"/>
895  <solidref ref="FoamPadding"/>
896  </volume>
897 
898  <volume name="volSteelSupport">
899  <materialref ref="AirSteelMixture"/>
900  <solidref ref="SteelSupport"/>
901  </volume>
902 
903  <volume name="volDetEnclosure">
904  <materialref ref="Air"/>
905  <solidref ref="DetEnclosure"/>
906 
907  <physvol>
908  <volumeref ref="volFoamPadding"/>
909  <positionref ref="posCryoInDetEnc"/>
910  </physvol>
911  <physvol>
912  <volumeref ref="volSteelSupport"/>
913  <positionref ref="posCryoInDetEnc"/>
914  </physvol>
915  <physvol>
916  <volumeref ref="volCryostat"/>
917  <positionref ref="posCryoInDetEnc"/>
918  </physvol>
919 EOF
920 
921 
922 print ENCL <<EOF;
923  </volume>
924 EOF
925 
926 print ENCL <<EOF;
927 </structure>
928 </gdml>
929 EOF
930 
931 close(ENCL);
932 }
933 
934 
935 
936 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
937 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
938 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
939 
940 sub gen_World()
941 {
942 
943 # Create the WORLD fragment file name,
944 # add file to list of output GDML fragments,
945 # and open it
946  $WORLD = $basename."_World" . $suffix . ".gdml";
947  push (@gdmlFiles, $WORLD);
948  $WORLD = ">" . $WORLD;
949  open(WORLD) or die("Could not open file $WORLD for writing");
950 
951 
952 # The standard XML prefix and starting the gdml
953  print WORLD <<EOF;
954 <?xml version='1.0'?>
955 <gdml>
956 EOF
957 
958 
959 # All the World solids.
960 print WORLD <<EOF;
961 <solids>
962  <box name="World" lunit="cm"
963  x="@{[$DetEncX+2*$RockThickness]}"
964  y="@{[$DetEncY+2*$RockThickness]}"
965  z="@{[$DetEncZ+2*$RockThickness]}"/>
966 </solids>
967 EOF
968 
969 # World structure
970 print WORLD <<EOF;
971 <structure>
972  <volume name="volWorld" >
973  <materialref ref="DUSEL_Rock"/>
974  <solidref ref="World"/>
975 
976  <physvol>
977  <volumeref ref="volDetEnclosure"/>
978  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
979  </physvol>
980 
981  </volume>
982 </structure>
983 </gdml>
984 EOF
985 
986 # make_gdml.pl will take care of <setup/>
987 
988 close(WORLD);
989 }
990 
991 
992 
993 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
994 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
995 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
996 
997 sub write_fragments()
998 {
999  # This subroutine creates an XML file that summarizes the the subfiles output
1000  # by the other sub routines - it is the input file for make_gdml.pl which will
1001  # give the final desired GDML file. Specify its name with the output option.
1002  # (you can change the name when running make_gdml)
1003 
1004  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
1005 
1006  if ( ! defined $output )
1007  {
1008  $output = "-"; # write to STDOUT
1009  }
1010 
1011  # Set up the output file.
1012  $OUTPUT = ">" . $output;
1013  open(OUTPUT) or die("Could not open file $OUTPUT");
1014 
1015  print OUTPUT <<EOF;
1016 <?xml version='1.0'?>
1017 
1018 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1019  that will be zipped together to create a detector description.
1020  -->
1021 
1022 <config>
1023 
1024  <constantfiles>
1025 
1026  <!-- These files contain GDML <constant></constant>
1027  blocks. They are read in separately, so they can be
1028  interpreted into the remaining GDML. See make_gdml.pl for
1029  more information.
1030  -->
1031 
1032 EOF
1033 
1034  foreach $filename (@defFiles)
1035  {
1036  print OUTPUT <<EOF;
1037  <filename> $filename </filename>
1038 EOF
1039  }
1040 
1041  print OUTPUT <<EOF;
1042 
1043  </constantfiles>
1044 
1045  <gdmlfiles>
1046 
1047  <!-- The GDML file fragments to be zipped together. -->
1048 
1049 EOF
1050 
1051  foreach $filename (@gdmlFiles)
1052  {
1053  print OUTPUT <<EOF;
1054  <filename> $filename </filename>
1055 EOF
1056  }
1057 
1058  print OUTPUT <<EOF;
1059 
1060  </gdmlfiles>
1061 
1062 </config>
1063 EOF
1064 
1065  close(OUTPUT);
1066 }
1067 
1068 
1069 print "Some of the principal parameters for this TPC geometry (unit cm unless noted otherwise)\n";
1070 print " CRM active area : $widthCRM_active x $lengthCRM_active\n";
1071 print " CRM total area : $widthCRM x $lengthCRM\n";
1072 print " Wire pitch in Y, Z : $wirePitchY, $wirePitchZ\n";
1073 print " TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1074 print " Argon volume : ($Argon_x, $Argon_y, $Argon_z) \n";
1075 print " Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1076 print " Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1077 print " TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1078 print " Field Cage : $FieldCage_switch \n";
1079 print " Cathode : $Cathode_switch \n";
1080 print " Workspace : $workspace \n";
1081 print " Wires : $wires_on \n";
1082 
1083 # run the sub routines that generate the fragments
1084 if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); }
1085 #if ( $Cathode_switch eq "on" ) { gen_Cathode(); } #Cathode for now has the same geometry as the Ground Grid
1086 
1087 gen_Extend(); # generates the GDML color extension for the refactored geometry
1088 gen_Define(); # generates definitions at beginning of GDML
1089 gen_Materials(); # generates materials to be used
1090 gen_TPC(); # generate TPC for a given unit CRM
1091 gen_Cryostat(); #
1092 gen_Enclosure(); #
1093 gen_World(); # places the enclosure among DUSEL Rock
1094 write_fragments(); # writes the XML input for make_gdml.pl
1095  # which zips together the final GDML
1096 print "--- done\n\n\n";
1097 exit;