generate_dunevd10kt_3view_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 3 views (2 orthogonal + induction at angle)
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 # VG: 23.02.21 Adjust plane dimensions to fit a given number of ch per side
19 # VG: 23.02.21 Group CRUs in CRPs
20 #
21 #
22 #################################################################################
23 
24 # Each subroutine generates a fragment GDML file, and the last subroutine
25 # creates an XML file that make_gdml.pl will use to appropriately arrange
26 # the fragment GDML files to create the final desired DUNE GDML file,
27 # to be named by make_gdml output command
28 
29 ##################################################################################
30 
31 
32 #use warnings;
33 use gdmlMaterials;
34 use Math::Trig;
35 use Getopt::Long;
36 use Math::BigFloat;
37 Math::BigFloat->precision(-16);
38 
39 ###
40 GetOptions( "help|h" => \$help,
41  "suffix|s:s" => \$suffix,
42  "output|o:s" => \$output,
43  "wires|w:s" => \$wires,
44  "workspace|k:s" => \$wkspc);
45 
46 my $FieldCage_switch="off";
47 my $Cathode_switch="off";
48 
49 if ( defined $help )
50 {
51  # If the user requested help, print the usage notes and exit.
52  usage();
53  exit;
54 }
55 
56 if ( ! defined $suffix )
57 {
58  # The user didn't supply a suffix, so append nothing to the file
59  # names.
60  $suffix = "";
61 }
62 else
63 {
64  # Otherwise, stick a "-" before the suffix, so that a suffix of
65  # "test" applied to filename.gdml becomes "filename-test.gdml".
66  $suffix = "-" . $suffix;
67 }
68 
69 
70 $workspace = 0;
71 if(defined $wkspc )
72 {
73  $workspace = $wkspc;
74 }
75 elsif ( $workspace != 0 )
76 {
77  print "\t\tCreating smaller workspace geometry.\n";
78 }
79 
80 # set wires on to be the default, unless given an input by the user
81 $wires_on = 1; # 1=on, 0=off
82 if (defined $wires)
83 {
84  $wires_on = $wires;
85 }
86 
87 $tpc_on = 1;
88 $basename="_";
89 
90 
91 ##################################################################
92 ############## Parameters for One Readout Panel ##################
93 
94 # parameters for 1.5 x 1.7 sub-unit Charge Readout Module / Unit
95 #$widthPCBActive = 169.0; # cm
96 #$lengthPCBActive = 150.0; # cm
97 
98 # views and channel counts
99 %nChans = ('Ind1', 256, 'Ind1Bot', 128, 'Ind2', 320, 'Col', 288);
100 $nViews = keys %nChans;
101 #print "$nViews %nChans\n";
102 
103 # first induction view
104 $wirePitchU = 0.8695; # cm
105 $wireAngleU = 131.63; #-48.37; # deg
106 
107 # second induction view
108 $wirePitchY = 0.525;
109 $widthPCBActive = 168.00; #$wirePitchY * $nChans{'Ind2'};
110 
111 # last collection view
112 $wirePitchZ = 0.517;
113 $lengthPCBActive = 148.9009; #$wirePitchZ * $nChans{'Col'};
114 
115 #
116 $borderCRM = 0.0; # border space aroud each CRM
117 
118 $widthCRM_active = $widthPCBActive;
119 $lengthCRM_active = $lengthPCBActive;
120 
121 $widthCRM = $widthPCBActive + 2 * $borderCRM;
122 $lengthCRM = $lengthPCBActive + 2 * $borderCRM;
123 
124 $borderCRP = 0.5; # cm
125 
126 # number of CRMs in y and z
127 $nCRM_x = 4 * 2;
128 $nCRM_z = 20 * 2;
129 
130 # create a smaller geometry
131 if( $workspace == 1 )
132 {
133  $nCRM_x = 1 * 2;
134  $nCRM_z = 1 * 2;
135 }
136 
137 # create a smaller geometry
138 if( $workspace == 2 )
139 {
140  $nCRM_x = 2 * 2;
141  $nCRM_z = 2 * 2;
142 }
143 
144 # create a smaller geometry
145 if( $workspace == 3 )
146 {
147  $nCRM_x = 3 * 2;
148  $nCRM_z = 3 * 2;
149 }
150 
151 
152 # calculate tpc area based on number of CRMs and their dimensions
153 # each CRP should have a 2x2 CRMs
154 $widthTPCActive = $nCRM_x * $widthCRM + $nCRM_x * $borderCRP; # around 1200 for full module
155 $lengthTPCActive = $nCRM_z * $lengthCRM + $nCRM_z * $borderCRP; # around 6000 for full module
156 
157 # active volume dimensions
158 $driftTPCActive = 650.0;
159 
160 # model anode strips as wires of some diameter
161 $padWidth = 0.02;
162 $ReadoutPlane = $nViews * $padWidth; # 3 readout planes (no space b/w)!
163 
164 ##################################################################
165 ############## Parameters for TPC and inner volume ###############
166 
167 # inner volume dimensions of the cryostat
168 $Argon_x = 1510;
169 $Argon_y = 1510;
170 $Argon_z = 6200;
171 
172 # width of gas argon layer on top
173 $HeightGaseousAr = 100;
174 
175 if( $workspace != 0 )
176 {
177  #active tpc + 1.0 m buffer on each side
178  $Argon_x = $driftTPCActive + $HeightGaseousAr + $ReadoutPlane + 100;
179  $Argon_y = $widthTPCActive + 200;
180  $Argon_z = $lengthTPCActive + 200;
181 }
182 
183 
184 # size of liquid argon buffer
185 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
186 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
187 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
188 
189 # cryostat
190 $SteelThickness = 0.12; # membrane
191 
192 $Cryostat_x = $Argon_x + 2*$SteelThickness;
193 $Cryostat_y = $Argon_y + 2*$SteelThickness;
194 $Cryostat_z = $Argon_z + 2*$SteelThickness;
195 
196 ##################################################################
197 ############## DetEnc and World relevant parameters #############
198 
199 $SteelSupport_x = 100;
200 $SteelSupport_y = 100;
201 $SteelSupport_z = 100;
202 $FoamPadding = 80;
203 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
204 $FracMassOfAir = 1 - $FracMassOfSteel;
205 
206 
207 $SpaceSteelSupportToWall = 100;
208 $SpaceSteelSupportToCeiling = 100;
209 
210 $DetEncX = $Cryostat_x
211  + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
212 
213 $DetEncY = $Cryostat_y
214  + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
215 
216 $DetEncZ = $Cryostat_z
217  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
218 
219 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
220 
221 
222 $RockThickness = 4000;
223 
224  # We want the world origin to be vertically centered on active TPC
225  # This is to be added to the x and y position of every volume in volWorld
226 
227 $OriginXSet = $DetEncX/2.0
228  - $SteelSupport_x
229  - $FoamPadding
230  - $SteelThickness
231  - $xLArBuffer
232  - $driftTPCActive/2.0;
233 
234 $OriginYSet = $DetEncY/2.0
235  - $SpaceSteelSupportToWall
236  - $SteelSupport_y
237  - $FoamPadding
238  - $SteelThickness
239  - $yLArBuffer
240  - $widthTPCActive/2.0;
241 
242  # We want the world origin to be at the very front of the fiducial volume.
243  # move it to the front of the enclosure, then back it up through the concrete/foam,
244  # then through the Cryostat shell, then through the upstream dead LAr (including the
245  # dead LAr on the edge of the TPC)
246  # This is to be added to the z position of every volume in volWorld
247 
248 $OriginZSet = $DetEncZ/2.0
249  - $SpaceSteelSupportToWall
250  - $SteelSupport_z
251  - $FoamPadding
252  - $SteelThickness
253  - $zLArBuffer
254  - $borderCRM;
255 
256 ##################################################################
257 ############## Field Cage Parameters ###############
258 $FieldShaperLongTubeLength = $lengthTPCActive;
259 $FieldShaperShortTubeLength = $widthTPCActive;
260 $FieldShaperInnerRadius = 1.485;
261 $FieldShaperOuterRadius = 1.685;
262 $FieldShaperTorRad = 1.69;
263 
264 $FieldShaperLength = $FieldShaperLongTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
265 $FieldShaperWidth = $FieldShaperShortTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
266 
267 $FieldShaperSeparation = 5.0;
268 $NFieldShapers = ($driftTPCActive/$FieldShaperSeparation) - 1;
269 
270 $FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2;
271 $FieldCageSizeY = $FieldShaperWidth+2;
272 $FieldCageSizeZ = $FieldShaperLength+2;
273 
274 
275 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
276 
277 
278 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
279 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
280 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
281 
282 sub usage()
283 {
284  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
285  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
286  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
287  print " -h prints this message, then quits\n";
288 }
289 
290 
291 sub gen_Extend()
292 {
293 
294 # Create the <define> fragment file name,
295 # add file to list of fragments,
296 # and open it
297  $DEF = $basename."_Ext" . $suffix . ".gdml";
298  push (@gdmlFiles, $DEF);
299  $DEF = ">" . $DEF;
300  open(DEF) or die("Could not open file $DEF for writing");
301 
302 print DEF <<EOF;
303 <?xml version='1.0'?>
304 <gdml>
305 <extension>
306  <color name="magenta" R="0.0" G="1.0" B="0.0" A="1.0" />
307  <color name="green" R="0.0" G="1.0" B="0.0" A="1.0" />
308  <color name="red" R="1.0" G="0.0" B="0.0" A="1.0" />
309  <color name="blue" R="0.0" G="0.0" B="1.0" A="1.0" />
310  <color name="yellow" R="1.0" G="1.0" B="0.0" A="1.0" />
311 </extension>
312 </gdml>
313 EOF
314  close (DEF);
315 }
316 
317 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
318 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
319 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
320 
321 sub gen_Define()
322 {
323 
324 # Create the <define> fragment file name,
325 # add file to list of fragments,
326 # and open it
327  $DEF = $basename."_Def" . $suffix . ".gdml";
328  push (@gdmlFiles, $DEF);
329  $DEF = ">" . $DEF;
330  open(DEF) or die("Could not open file $DEF for writing");
331 
332 
333 print DEF <<EOF;
334 <?xml version='1.0'?>
335 <gdml>
336 <define>
337 
338 <!--
339 
340 
341 
342 -->
343 
344  <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
345  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
346  <rotation name="rUWireAboutX" unit="deg" x="$wireAngleU" y="0" z="0"/>
347  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
348  <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
349  <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
350  <rotation name="rMinus90AboutX" unit="deg" x="270" y="0" z="0"/>
351  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
352  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
353  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
354  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
355  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
356  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
357 </define>
358 </gdml>
359 EOF
360  close (DEF);
361 }
362 
363 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
364 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
365 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
366 
367 sub gen_Materials()
368 {
369 
370 # Create the <materials> fragment file name,
371 # add file to list of output GDML fragments,
372 # and open it
373  $MAT = $basename."_Materials" . $suffix . ".gdml";
374  push (@gdmlFiles, $MAT);
375  $MAT = ">" . $MAT;
376 
377  open(MAT) or die("Could not open file $MAT for writing");
378 
379  # Add any materials special to this geometry by defining a mulitline string
380  # and passing it to the gdmlMaterials::gen_Materials() function.
381 my $asmix = <<EOF;
382  <!-- preliminary values -->
383  <material name="AirSteelMixture" formula="AirSteelMixture">
384  <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
385  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
386  <fraction n="$FracMassOfAir" ref="Air"/>
387  </material>
388  <material name="vm2000" formula="vm2000">
389  <D value="1.2" unit="g/cm3"/>
390  <composite n="2" ref="carbon"/>
391  <composite n="4" ref="hydrogen"/>
392  </material>
393 EOF
394 
395  # add the general materials used anywere
396  print MAT gdmlMaterials::gen_Materials( $asmix );
397 
398  close(MAT);
399 }
400 
401 
402 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
403 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
404 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
405 # line clip on the rectangle boundary
406 sub lineClip {
407  my $x0 = $_[0];
408  my $y0 = $_[1];
409  my $nx = $_[2];
410  my $ny = $_[3];
411  my $rcl = $_[4];
412  my $rcw = $_[5];
413 
414  my $tol = 1.0E-4;
415  my @endpts = ();
416  if( abs( nx ) < tol ){
417  push( @endpts, ($x0, 0) );
418  push( @endpts, ($x0, $rcw) );
419  return @endpts;
420  }
421  if( abs( ny ) < tol ){
422  push( @endpts, (0, $y0) );
423  push( @endpts, ($rcl, $y0) );
424  return @endpts;
425  }
426 
427  # left border at x = 0
428  my $y = $y0 - $x0 * $ny/$nx;
429  if( $y >= 0 && $y <= $rcw ){
430  push( @endpts, (0, $y) );
431  }
432 
433  # right border at x = l
434  $y = $y0 + ($rcl-$x0) * $ny/$nx;
435  if( $y >= 0 && $y <= $rcw ){
436  push( @endpts, ($rcl, $y) );
437  if( scalar(@endpts) == 4 ){
438  return @endpts;
439  }
440  }
441 
442  # bottom border at y = 0
443  my $x = $x0 - $y0 * $nx/$ny;
444  if( $x >= 0 && $x <= $rcl ){
445  push( @endpts, ($x, 0) );
446  if( scalar(@endpts) == 4 ){
447  return @endpts;
448  }
449  }
450 
451  # top border at y = w
452  $x = $x0 + ($rcw-$y0)* $nx/$ny;
453  if( $x >= 0 && $x <= $rcl ){
454  push( @endpts, ($x, $rcw) );
455  }
456 
457  return @endpts;
458 }
459 
460 sub gen_Wires
461 {
462  my $length = $_[0]; #
463  my $width = $_[1]; #
464  my $nch = $_[2]; #
465  my $nchb = $_[3]; # nch per bottom side
466  my $pitch = $_[4]; #
467  my $theta = $_[5]; # deg
468  my $dia = $_[6]; #
469 
470  $theta = $theta * pi()/180.0;
471  my @dirw = (cos($theta), sin($theta));
472  my @dirp = (cos($theta - pi()/2), sin($theta - pi()/2));
473 
474  # calculate
475  my $alpha = $theta;
476  if( $alpha > pi()/2 ){
477  $alpha = pi() - $alpha;
478  }
479  my $dX = $pitch / sin( $alpha );
480  my $dY = $pitch / sin( pi()/2 - $alpha );
481  if( $length <= 0 ){
482  $length = $dX * $nchb;
483  }
484  if( $width <= 0 ){
485  $width = $dY * ($nch - $nchb);
486  }
487 
488  my @orig = (0, 0);
489  if( $dirp[0] < 0 ){
490  $orig[0] = $length;
491  }
492  if( $dirp[1] < 0 ){
493  $orig[1] = $width;
494  }
495 
496  #print "origin : @orig\n";
497  #print "pitch dir : @dirp\n";
498  #print "wire dir : @dirw\n";
499  #print "$length x $width cm2\n";
500 
501  # gen wires
502  my @winfo = ();
503  my $offset = $pitch/2;
504  foreach my $ch (0..$nch-1){
505  #print "Processing $ch\n";
506 
507  # calculate reference point for this strip
508  my @wcn = (0, 0);
509  $wcn[0] = $orig[0] + $offset * $dirp[0];
510  $wcn[1] = $orig[1] + $offset * $dirp[1];
511 
512  # line clip on the rectangle boundary
513  @endpts = lineClip( $wcn[0], $wcn[1], $dirw[0], $dirw[1], $length, $width );
514 
515  if( scalar(@endpts) != 4 ){
516  print "Could not find end points for wire $ch : @endpts\n";
517  $offset = $offset + $pitch;
518  next;
519  }
520 
521  # re-center on the mid-point
522  $endpts[0] -= $length/2;
523  $endpts[2] -= $length/2;
524  $endpts[1] -= $width/2;
525  $endpts[3] -= $width/2;
526 
527  # calculate the strip center in the rectangle of CRU
528  $wcn[0] = ($endpts[0] + $endpts[2])/2;
529  $wcn[1] = ($endpts[1] + $endpts[3])/2;
530 
531  # calculate the length
532  my $dx = $endpts[0] - $endpts[2];
533  my $dy = $endpts[1] - $endpts[3];
534  my $wlen = sqrt($dx**2 + $dy**2);
535 
536  # put all info together
537  my @wire = ($ch, $wcn[0], $wcn[1], $wlen);
538  push( @wire, @endpts );
539  push( @winfo, \@wire);
540  $offset = $offset + $pitch;
541  #last;
542  }
543  return @winfo;
544 }
545 
546 #
547 sub gen_TPC()
548 {
549  # CRM active volume
550  my $TPCActive_x = $driftTPCActive;
551  my $TPCActive_y = $widthCRM_active;
552  my $TPCActive_z = $lengthCRM_active;
553 
554  # CRM total volume
555  my $TPC_x = $TPCActive_x + $ReadoutPlane;
556  my $TPC_y = $widthCRM;
557  my $TPC_z = $lengthCRM;
558 
559  print " TPC dimensions : $TPC_x x $TPC_y x $TPC_z\n";
560 
561  $TPC = $basename."_TPC" . $suffix . ".gdml";
562  push (@gdmlFiles, $TPC);
563  $TPC = ">" . $TPC;
564  open(TPC) or die("Could not open file $TPC for writing");
565 
566  # The standard XML prefix and starting the gdml
567 print TPC <<EOF;
568  <?xml version='1.0'?>
569  <gdml>
570 EOF
571 
572  # compute wires for 1st induction
573  my @winfo = ();
574  if( $wires_on == 1 ){
575  @winfo = gen_Wires( 0, 0, # $TPCActive_y,
576  $nChans{'Ind1'}, $nChans{'Ind1Bot'},
577  $wirePitchU, $wireAngleU, $padWidth );
578  }
579 
580  # All the TPC solids save the wires.
581 print TPC <<EOF;
582  <solids>
583 EOF
584 
585 print TPC <<EOF;
586  <box name="CRM"
587  x="$TPC_x"
588  y="$TPC_y"
589  z="$TPC_z"
590  lunit="cm"/>
591  <box name="CRMUPlane"
592  x="$padWidth"
593  y="$TPCActive_y"
594  z="$TPCActive_z"
595  lunit="cm"/>
596  <box name="CRMYPlane"
597  x="$padWidth"
598  y="$TPCActive_y"
599  z="$TPCActive_z"
600  lunit="cm"/>
601  <box name="CRMZPlane"
602  x="$padWidth"
603  y="$TPCActive_y"
604  z="$TPCActive_z"
605  lunit="cm"/>
606  <box name="CRMActive"
607  x="$TPCActive_x"
608  y="$TPCActive_y"
609  z="$TPCActive_z"
610  lunit="cm"/>
611 EOF
612 
613 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
614 if($wires_on==1){
615 
616  foreach my $wire (@winfo) {
617  my $wid = $wire->[0];
618  my $wln = $wire->[3];
619 print TPC <<EOF;
620  <tube name="CRMWireU$wid"
621  rmax="0.5*$padWidth"
622  z="$wln"
623  deltaphi="360"
624  aunit="deg" lunit="cm"/>
625 EOF
626  }
627 
628 print TPC <<EOF;
629  <tube name="CRMWireY"
630  rmax="0.5*$padWidth"
631  z="$TPCActive_z"
632  deltaphi="360"
633  aunit="deg" lunit="cm"/>
634  <tube name="CRMWireZ"
635  rmax="0.5*$padWidth"
636  z="$TPCActive_y"
637  deltaphi="360"
638  aunit="deg" lunit="cm"/>
639 EOF
640 }
641 print TPC <<EOF;
642 </solids>
643 EOF
644 
645 
646 # Begin structure and create wire logical volumes
647 print TPC <<EOF;
648 <structure>
649  <volume name="volTPCActive">
650  <materialref ref="LAr"/>
651  <solidref ref="CRMActive"/>
652  <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
653  <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5208*cm"/>
654  <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="500*V/cm"/>
655  <colorref ref="blue"/>
656  </volume>
657 EOF
658 
659 if($wires_on==1)
660 {
661  foreach my $wire (@winfo)
662  {
663  my $wid = $wire->[0];
664 print TPC <<EOF;
665  <volume name="volTPCWireU$wid">
666  <materialref ref="Copper_Beryllium_alloy25"/>
667  <solidref ref="CRMWireU$wid"/>
668  </volume>
669 EOF
670  }
671 
672 print TPC <<EOF;
673  <volume name="volTPCWireY">
674  <materialref ref="Copper_Beryllium_alloy25"/>
675  <solidref ref="CRMWireY"/>
676  </volume>
677  <volume name="volTPCWireZ">
678  <materialref ref="Copper_Beryllium_alloy25"/>
679  <solidref ref="CRMWireZ"/>
680  </volume>
681 EOF
682 }
683  # 1st induction plane
684 print TPC <<EOF;
685  <volume name="volTPCPlaneU">
686  <materialref ref="LAr"/>
687  <solidref ref="CRMUPlane"/>
688 EOF
689 if ($wires_on==1) # add wires to U plane
690 {
691  # the coordinates were computed with a corner at (0,0)
692  # so we need to move to plane coordinates
693  my $offsetZ = 0; #-0.5 * $TPCActive_z;
694  my $offsetY = 0; #-0.5 * $TPCActive_y;
695 
696  foreach my $wire (@winfo) {
697  my $wid = $wire->[0];
698  my $zpos = $wire->[1] + $offsetZ;
699  my $ypos = $wire->[2] + $offsetY;
700 print TPC <<EOF;
701  <physvol>
702  <volumeref ref="volTPCWireU$wid"/>
703  <position name="posWireU$wid" unit="cm" x="0" y="$ypos" z="$zpos"/>
704  <rotationref ref="rUWireAboutX"/>
705  </physvol>
706 EOF
707  }
708 }
709 print TPC <<EOF;
710  </volume>
711 EOF
712 
713 # 2nd induction plane
714 print TPC <<EOF;
715  <volume name="volTPCPlaneY">
716  <materialref ref="LAr"/>
717  <solidref ref="CRMYPlane"/>
718 EOF
719 
720 if ($wires_on==1) # add wires to Y plane (plane with wires reading y position)
721 {
722  for(my $i=0;$i<$nChans{'Ind2'};++$i)
723  {
724  #my $ypos = -0.5 * $TPCActive_y + ($i+0.5)*$wirePitchY + 0.5*$padWidth;
725  my $ypos = ($i + 0.5 - $nChans{'Ind2'}/2)*$wirePitchY;
726  if( (0.5 * $TPCActive_y - abs($ypos)) < 0 ){
727  die "Cannot place wire $i in view Y, as plane is too small\n";
728  }
729 print TPC <<EOF;
730  <physvol>
731  <volumeref ref="volTPCWireY"/>
732  <position name="posWireY$i" unit="cm" x="0" y="$ypos" z="0"/>
733  <rotationref ref="rIdentity"/>
734  </physvol>
735 EOF
736  }
737 }
738 print TPC <<EOF;
739  </volume>
740 EOF
741 
742 # collection plane
743 print TPC <<EOF;
744  <volume name="volTPCPlaneZ">
745  <materialref ref="LAr"/>
746  <solidref ref="CRMZPlane"/>
747 EOF
748 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
749  {
750  for(my $i=0;$i<$nChans{'Col'};++$i)
751  {
752  #my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitchZ + 0.5*$padWidth;
753  my $zpos = ($i + 0.5 - $nChans{'Col'}/2)*$wirePitchZ;
754  if( (0.5 * $TPCActive_z - abs($zpos)) < 0 ){
755  die "Cannot place wire $i in view Z, as plane is too small\n";
756  }
757 print TPC <<EOF;
758  <physvol>
759  <volumeref ref="volTPCWireZ"/>
760  <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
761  <rotationref ref="rPlus90AboutX"/>
762  </physvol>
763 EOF
764  }
765 }
766 print TPC <<EOF;
767  </volume>
768 EOF
769 
770 
771 $posUplane[0] = 0.5*$TPC_x - 2.5*$padWidth;
772 $posUplane[1] = 0;
773 $posUplane[2] = 0;
774 
775 $posYplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
776 $posYplane[1] = 0;
777 $posYplane[2] = 0;
778 
779 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
780 $posZplane[1] = 0;
781 $posZplane[2] = 0;
782 
783 $posTPCActive[0] = -$ReadoutPlane/2;
784 $posTPCActive[1] = 0;
785 $posTPCActive[2] = 0;
786 
787 
788 #wrap up the TPC file
789 print TPC <<EOF;
790  <volume name="volTPC">
791  <materialref ref="LAr"/>
792  <solidref ref="CRM"/>
793  <physvol>
794  <volumeref ref="volTPCPlaneU"/>
795  <position name="posPlaneU" unit="cm"
796  x="$posUplane[0]" y="$posUplane[1]" z="$posUplane[2]"/>
797  <rotationref ref="rIdentity"/>
798  </physvol>
799  <physvol>
800  <volumeref ref="volTPCPlaneY"/>
801  <position name="posPlaneY" unit="cm"
802  x="$posYplane[0]" y="$posYplane[1]" z="$posYplane[2]"/>
803  <rotationref ref="rIdentity"/>
804  </physvol>
805  <physvol>
806  <volumeref ref="volTPCPlaneZ"/>
807  <position name="posPlaneZ" unit="cm"
808  x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
809  <rotationref ref="rIdentity"/>
810  </physvol>
811  <physvol>
812  <volumeref ref="volTPCActive"/>
813  <position name="posActive" unit="cm"
814  x="$posTPCActive[0]" y="$posTPCAtive[1]" z="$posTPCActive[2]"/>
815  <rotationref ref="rIdentity"/>
816  </physvol>
817  </volume>
818 EOF
819 ## x="@{[$posTPCActive[0]+$padWidth]}" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
820 
821 print TPC <<EOF;
822  </structure>
823  </gdml>
824 EOF
825 
826  close(TPC);
827 }
828 
829 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
830 #++++++++++++++++++++++++++++++++++++++ gen_FieldCage ++++++++++++++++++++++++++++++++++++
831 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
832 
833 sub gen_FieldCage {
834 
835  $FieldCage = $basename."_FieldCage" . $suffix . ".gdml";
836  push (@gdmlFiles, $FieldCage);
837  $FieldCage = ">" . $FieldCage;
838  open(FieldCage) or die("Could not open file $FieldCage for writing");
839 
840 # The standard XML prefix and starting the gdml
841 print FieldCage <<EOF;
842  <?xml version='1.0'?>
843  <gdml>
844 EOF
845 # The printing solids used in the Field Cage
846 #print "lengthTPCActive : $lengthTPCActive \n";
847 #print "widthTPCActive : $widthTPCActive \n";
848 
849 
850 print FieldCage <<EOF;
851 <solids>
852  <torus name="FieldShaperCorner" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" rtor="$FieldShaperTorRad" deltaphi="90" startphi="0" aunit="deg" lunit="cm"/>
853  <tube name="FieldShaperLongtube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
854  <tube name="FieldShaperShorttube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperShortTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
855 
856  <union name="FSunion1">
857  <first ref="FieldShaperLongtube"/>
858  <second ref="FieldShaperCorner"/>
859  <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
860  <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
861  </union>
862 
863  <union name="FSunion2">
864  <first ref="FSunion1"/>
865  <second ref="FieldShaperShorttube"/>
866  <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
867  <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
868  </union>
869 
870  <union name="FSunion3">
871  <first ref="FSunion2"/>
872  <second ref="FieldShaperCorner"/>
873  <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
874  <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
875  </union>
876 
877  <union name="FSunion4">
878  <first ref="FSunion3"/>
879  <second ref="FieldShaperLongtube"/>
880  <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
881  </union>
882 
883  <union name="FSunion5">
884  <first ref="FSunion4"/>
885  <second ref="FieldShaperCorner"/>
886  <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
887  <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
888  </union>
889 
890  <union name="FSunion6">
891  <first ref="FSunion5"/>
892  <second ref="FieldShaperShorttube"/>
893  <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
894  <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
895  </union>
896 
897  <union name="FieldShaperSolid">
898  <first ref="FSunion6"/>
899  <second ref="FieldShaperCorner"/>
900  <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
901  <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
902  </union>
903 </solids>
904 
905 EOF
906 
907 print FieldCage <<EOF;
908 
909 <structure>
910 <volume name="volFieldShaper">
911  <materialref ref="Al2O3"/>
912  <solidref ref="FieldShaperSolid"/>
913 </volume>
914 </structure>
915 
916 EOF
917 
918 print FieldCage <<EOF;
919 
920 </gdml>
921 EOF
922 close(FieldCage);
923 }
924 
925 
926 
927 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
928 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
929 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
930 
931 sub gen_Cryostat()
932 {
933 
934 # Create the cryostat fragment file name,
935 # add file to list of output GDML fragments,
936 # and open it
937  $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
938  push (@gdmlFiles, $CRYO);
939  $CRYO = ">" . $CRYO;
940  open(CRYO) or die("Could not open file $CRYO for writing");
941 
942 
943 # The standard XML prefix and starting the gdml
944  print CRYO <<EOF;
945 <?xml version='1.0'?>
946 <gdml>
947 EOF
948 
949 # All the cryostat solids.
950 print CRYO <<EOF;
951 <solids>
952  <box name="Cryostat" lunit="cm"
953  x="$Cryostat_x"
954  y="$Cryostat_y"
955  z="$Cryostat_z"/>
956 
957  <box name="ArgonInterior" lunit="cm"
958  x="$Argon_x"
959  y="$Argon_y"
960  z="$Argon_z"/>
961 
962  <box name="GaseousArgon" lunit="cm"
963  x="$HeightGaseousAr"
964  y="$Argon_y"
965  z="$Argon_z"/>
966 
967  <subtraction name="SteelShell">
968  <first ref="Cryostat"/>
969  <second ref="ArgonInterior"/>
970  </subtraction>
971 
972 </solids>
973 EOF
974 
975 # Cryostat structure
976 print CRYO <<EOF;
977 <structure>
978  <volume name="volSteelShell">
979  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
980  <solidref ref="SteelShell" />
981  </volume>
982  <volume name="volGaseousArgon">
983  <materialref ref="ArGas"/>
984  <solidref ref="GaseousArgon"/>
985 EOF
986 
987  print CRYO <<EOF;
988  </volume>
989 
990  <volume name="volCryostat">
991  <materialref ref="LAr" />
992  <solidref ref="Cryostat" />
993  <physvol>
994  <volumeref ref="volGaseousArgon"/>
995  <position name="posGaseousArgon" unit="cm" x="@{[$Argon_x/2-$HeightGaseousAr/2]}" y="0" z="0"/>
996  </physvol>
997  <physvol>
998  <volumeref ref="volSteelShell"/>
999  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1000  </physvol>
1001 EOF
1002 
1003 
1004 if ($tpc_on==1) # place TPC inside croysotat offsetting each pair of CRMs by borderCRP
1005 {
1006  $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1007  $idx = 0;
1008  my $posZ = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCRM;
1009  for(my $ii=0;$ii<$nCRM_z;$ii++)
1010  {
1011  if( $ii % 2 == 0 ){
1012  $posZ += $borderCRP;
1013  if( $ii>0 ){
1014  $posZ += $borderCRP;
1015  }
1016  }
1017  my $posY = -0.5*$Argon_y + $yLArBuffer + 0.5*$widthCRM;
1018  for(my $jj=0;$jj<$nCRM_x;$jj++)
1019  {
1020  if( $jj % 2 == 0 ){
1021  $posY += $borderCRP;
1022  if( $jj>0 ){
1023  $posY += $borderCRP;
1024  }
1025  }
1026  print CRYO <<EOF;
1027  <physvol>
1028  <volumeref ref="volTPC"/>
1029  <position name="posTPC\-$idx" unit="cm"
1030  x="$posX" y="$posY" z="$posZ"/>
1031  </physvol>
1032 EOF
1033  $idx++;
1034  $posY += $widthCRM;
1035  }
1036 
1037  $posZ += $lengthCRM;
1038  }
1039 
1040 }
1041 
1042 #The +50 in the x positions must depend on some other parameter
1043  if ( $FieldCage_switch eq "on" ) {
1044  for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) { # pmts with coating
1045 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1046  print CRYO <<EOF;
1047  <physvol>
1048  <volumeref ref="volFieldShaper"/>
1049  <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1050  <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1051  </physvol>
1052 EOF
1053  }
1054  }
1055 
1056 
1057 $CathodePosX =-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation;
1058 $CathodePosY = 0;
1059 $CathodePosZ = 0;
1060  if ( $Cathode_switch eq "on" )
1061  {
1062  print CRYO <<EOF;
1063  <physvol>
1064  <volumeref ref="volGroundGrid"/>
1065  <position name="posGroundGrid01" unit="cm" x="$CathodePosX" y="@{[-$CathodePosY]}" z="@{[$CathodePosZ]}"/>
1066  <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
1067  </physvol>
1068 
1069 EOF
1070  }
1071 
1072 
1073  print CRYO <<EOF;
1074  </volume>
1075 </structure>
1076 </gdml>
1077 EOF
1078 
1079 close(CRYO);
1080 }
1081 
1082 
1083 
1084 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1085 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1086 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1087 
1088 sub gen_Enclosure()
1089 {
1090 
1091 # Create the detector enclosure fragment file name,
1092 # add file to list of output GDML fragments,
1093 # and open it
1094  $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
1095  push (@gdmlFiles, $ENCL);
1096  $ENCL = ">" . $ENCL;
1097  open(ENCL) or die("Could not open file $ENCL for writing");
1098 
1099 
1100 # The standard XML prefix and starting the gdml
1101  print ENCL <<EOF;
1102 <?xml version='1.0'?>
1103 <gdml>
1104 EOF
1105 
1106 
1107 # All the detector enclosure solids.
1108 print ENCL <<EOF;
1109 <solids>
1110 
1111  <box name="FoamPadBlock" lunit="cm"
1112  x="@{[$Cryostat_x + 2*$FoamPadding]}"
1113  y="@{[$Cryostat_y + 2*$FoamPadding]}"
1114  z="@{[$Cryostat_z + 2*$FoamPadding]}" />
1115 
1116  <subtraction name="FoamPadding">
1117  <first ref="FoamPadBlock"/>
1118  <second ref="Cryostat"/>
1119  <positionref ref="posCenter"/>
1120  </subtraction>
1121 
1122  <box name="SteelSupportBlock" lunit="cm"
1123  x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
1124  y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
1125  z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
1126 
1127  <subtraction name="SteelSupport">
1128  <first ref="SteelSupportBlock"/>
1129  <second ref="FoamPadBlock"/>
1130  <positionref ref="posCenter"/>
1131  </subtraction>
1132 
1133  <box name="DetEnclosure" lunit="cm"
1134  x="$DetEncX"
1135  y="$DetEncY"
1136  z="$DetEncZ"/>
1137 
1138 </solids>
1139 EOF
1140 
1141 
1142 # Detector enclosure structure
1143  print ENCL <<EOF;
1144 <structure>
1145  <volume name="volFoamPadding">
1146  <materialref ref="fibrous_glass"/>
1147  <solidref ref="FoamPadding"/>
1148  </volume>
1149 
1150  <volume name="volSteelSupport">
1151  <materialref ref="AirSteelMixture"/>
1152  <solidref ref="SteelSupport"/>
1153  </volume>
1154 
1155  <volume name="volDetEnclosure">
1156  <materialref ref="Air"/>
1157  <solidref ref="DetEnclosure"/>
1158 
1159  <physvol>
1160  <volumeref ref="volFoamPadding"/>
1161  <positionref ref="posCryoInDetEnc"/>
1162  </physvol>
1163  <physvol>
1164  <volumeref ref="volSteelSupport"/>
1165  <positionref ref="posCryoInDetEnc"/>
1166  </physvol>
1167  <physvol>
1168  <volumeref ref="volCryostat"/>
1169  <positionref ref="posCryoInDetEnc"/>
1170  </physvol>
1171 EOF
1172 
1173 
1174 print ENCL <<EOF;
1175  </volume>
1176 EOF
1177 
1178 print ENCL <<EOF;
1179 </structure>
1180 </gdml>
1181 EOF
1182 
1183 close(ENCL);
1184 }
1185 
1186 
1187 
1188 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1189 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1190 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1191 
1192 sub gen_World()
1193 {
1194 
1195 # Create the WORLD fragment file name,
1196 # add file to list of output GDML fragments,
1197 # and open it
1198  $WORLD = $basename."_World" . $suffix . ".gdml";
1199  push (@gdmlFiles, $WORLD);
1200  $WORLD = ">" . $WORLD;
1201  open(WORLD) or die("Could not open file $WORLD for writing");
1202 
1203 
1204 # The standard XML prefix and starting the gdml
1205  print WORLD <<EOF;
1206 <?xml version='1.0'?>
1207 <gdml>
1208 EOF
1209 
1210 
1211 # All the World solids.
1212 print WORLD <<EOF;
1213 <solids>
1214  <box name="World" lunit="cm"
1215  x="@{[$DetEncX+2*$RockThickness]}"
1216  y="@{[$DetEncY+2*$RockThickness]}"
1217  z="@{[$DetEncZ+2*$RockThickness]}"/>
1218 </solids>
1219 EOF
1220 
1221 # World structure
1222 print WORLD <<EOF;
1223 <structure>
1224  <volume name="volWorld" >
1225  <materialref ref="DUSEL_Rock"/>
1226  <solidref ref="World"/>
1227 
1228  <physvol>
1229  <volumeref ref="volDetEnclosure"/>
1230  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1231  </physvol>
1232 
1233  </volume>
1234 </structure>
1235 </gdml>
1236 EOF
1237 
1238 # make_gdml.pl will take care of <setup/>
1239 
1240 close(WORLD);
1241 }
1242 
1243 
1244 
1245 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1246 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1247 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1248 
1249 sub write_fragments()
1250 {
1251  # This subroutine creates an XML file that summarizes the the subfiles output
1252  # by the other sub routines - it is the input file for make_gdml.pl which will
1253  # give the final desired GDML file. Specify its name with the output option.
1254  # (you can change the name when running make_gdml)
1255 
1256  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
1257 
1258  if ( ! defined $output )
1259  {
1260  $output = "-"; # write to STDOUT
1261  }
1262 
1263  # Set up the output file.
1264  $OUTPUT = ">" . $output;
1265  open(OUTPUT) or die("Could not open file $OUTPUT");
1266 
1267  print OUTPUT <<EOF;
1268 <?xml version='1.0'?>
1269 
1270 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1271  that will be zipped together to create a detector description.
1272  -->
1273 
1274 <config>
1275 
1276  <constantfiles>
1277 
1278  <!-- These files contain GDML <constant></constant>
1279  blocks. They are read in separately, so they can be
1280  interpreted into the remaining GDML. See make_gdml.pl for
1281  more information.
1282  -->
1283 
1284 EOF
1285 
1286  foreach $filename (@defFiles)
1287  {
1288  print OUTPUT <<EOF;
1289  <filename> $filename </filename>
1290 EOF
1291  }
1292 
1293  print OUTPUT <<EOF;
1294 
1295  </constantfiles>
1296 
1297  <gdmlfiles>
1298 
1299  <!-- The GDML file fragments to be zipped together. -->
1300 
1301 EOF
1302 
1303  foreach $filename (@gdmlFiles)
1304  {
1305  print OUTPUT <<EOF;
1306  <filename> $filename </filename>
1307 EOF
1308  }
1309 
1310  print OUTPUT <<EOF;
1311 
1312  </gdmlfiles>
1313 
1314 </config>
1315 EOF
1316 
1317  close(OUTPUT);
1318 }
1319 
1320 
1321 print "Some of the principal parameters for this TPC geometry (unit cm unless noted otherwise)\n";
1322 print " CRM active area : $widthCRM_active x $lengthCRM_active\n";
1323 print " CRM total area : $widthCRM x $lengthCRM\n";
1324 print " Wire pitch in U, Y, Z : $wirePitchU, $wirePitchY, $wirePitchZ\n";
1325 print " TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1326 print " Argon volume : ($Argon_x, $Argon_y, $Argon_z) \n";
1327 print " Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1328 print " Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1329 print " TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1330 print " Field Cage : $FieldCage_switch \n";
1331 print " Cathode : $Cathode_switch \n";
1332 print " Workspace : $workspace \n";
1333 print " Wires : $wires_on \n";
1334 
1335 # run the sub routines that generate the fragments
1336 if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); }
1337 #if ( $Cathode_switch eq "on" ) { gen_Cathode(); } #Cathode for now has the same geometry as the Ground Grid
1338 
1339 gen_Extend(); # generates the GDML color extension for the refactored geometry
1340 gen_Define(); # generates definitions at beginning of GDML
1341 gen_Materials(); # generates materials to be used
1342 gen_TPC(); # generate TPC for a given unit CRM
1343 gen_Cryostat(); #
1344 gen_Enclosure(); #
1345 gen_World(); # places the enclosure among DUSEL Rock
1346 write_fragments(); # writes the XML input for make_gdml.pl
1347  # which zips together the final GDML
1348 print "--- done\n\n\n";
1349 exit;