generate_dunevd10kt_3view_v2_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 # Laura Paulucci (lpaulucc@fnal.gov): Sept 2021 PDS added.
21 # Use option -pds=1 for backup design (membrane only coverage).
22 # Default (pds=0) is the reference design (~4-pi).
23 # This is linked with a larger geometry to account for photon propagation, generate it with -k=4.
24 # Field Cage is turned on with reference and backup designs to match PDS option.
25 # For not including the pds, please use option -pds=-1
26 #
27 #
28 #################################################################################
29 
30 # Each subroutine generates a fragment GDML file, and the last subroutine
31 # creates an XML file that make_gdml.pl will use to appropriately arrange
32 # the fragment GDML files to create the final desired DUNE GDML file,
33 # to be named by make_gdml output command
34 
35 ##################################################################################
36 
37 
38 #use warnings;
39 use gdmlMaterials;
40 use Math::Trig;
41 use Getopt::Long;
42 use Math::BigFloat;
43 Math::BigFloat->precision(-16);
44 
45 ###
46 GetOptions( "help|h" => \$help,
47  "suffix|s:s" => \$suffix,
48  "output|o:s" => \$output,
49  "wires|w:s" => \$wires,
50  "workspace|k:s" => \$wkspc,
51  "pdsconfig|pds:s" => \$pdsconfig);
52 
53 my $FieldCage_switch="on";
54 my $Cathode_switch="off";
55 
56 if ( defined $help )
57 {
58  # If the user requested help, print the usage notes and exit.
59  usage();
60  exit;
61 }
62 
63 if ( ! defined $suffix )
64 {
65  # The user didn't supply a suffix, so append nothing to the file
66  # names.
67  $suffix = "";
68 }
69 else
70 {
71  # Otherwise, stick a "-" before the suffix, so that a suffix of
72  # "test" applied to filename.gdml becomes "filename-test.gdml".
73  $suffix = "-" . $suffix;
74 }
75 
76 
77 $workspace = 0;
78 if(defined $wkspc )
79 {
80  $workspace = $wkspc;
81 }
82 elsif ( $workspace != 0 )
83 {
84  print "\t\tCreating smaller workspace geometry.\n";
85 }
86 
87 if ( ! defined $pdsconfig )
88 {
89  $pdsconfig = 0;
90  print "\t\tCreating reference design: 4-pi PDS converage.\n";
91 }
92 elsif ( $pdsconfig == 1 )
93 {
94  print "\t\tCreating backup design: membrane-only PDS coverage.\n";
95 }
96 
97 # set wires on to be the default, unless given an input by the user
98 $wires_on = 1; # 1=on, 0=off
99 if (defined $wires)
100 {
101  $wires_on = $wires;
102 }
103 
104 $tpc_on = 1;
105 $basename="_";
106 
107 
108 ##################################################################
109 ############## Parameters for One Readout Panel ##################
110 
111 # parameters for 1.5 x 1.7 sub-unit Charge Readout Module / Unit
112 #$widthPCBActive = 169.0; # cm
113 #$lengthPCBActive = 150.0; # cm
114 
115 # views and channel counts
116 %nChans = ('Ind1', 256, 'Ind1Bot', 128, 'Ind2', 320, 'Col', 288);
117 $nViews = keys %nChans;
118 #print "$nViews %nChans\n";
119 
120 # first induction view
121 $wirePitchU = 0.8695; # cm
122 $wireAngleU = 131.63; #-48.37; # deg
123 
124 # second induction view
125 $wirePitchY = 0.525;
126 $widthPCBActive = 168.00; #$wirePitchY * $nChans{'Ind2'};
127 
128 # last collection view
129 $wirePitchZ = 0.517;
130 $lengthPCBActive = 148.9009; #$wirePitchZ * $nChans{'Col'};
131 
132 #
133 $borderCRM = 0.0; # border space aroud each CRM
134 
135 $widthCRM_active = $widthPCBActive;
136 $lengthCRM_active = $lengthPCBActive;
137 
138 $widthCRM = $widthPCBActive + 2 * $borderCRM;
139 $lengthCRM = $lengthPCBActive + 2 * $borderCRM;
140 
141 $borderCRP = 0.5; # cm
142 
143 # number of CRMs in y and z
144 $nCRM_x = 4 * 2;
145 $nCRM_z = 20 * 2;
146 
147 # create a smaller geometry
148 if( $workspace == 1 )
149 {
150  $nCRM_x = 1 * 2;
151  $nCRM_z = 1 * 2;
152 }
153 
154 # create a smaller geometry
155 if( $workspace == 2 )
156 {
157  $nCRM_x = 2 * 2;
158  $nCRM_z = 2 * 2;
159 }
160 
161 # create a smaller geometry
162 if( $workspace == 3 )
163 {
164  $nCRM_x = 3 * 2;
165  $nCRM_z = 3 * 2;
166 }
167 
168 # create pds geometry
169 if( $workspace == 4 )
170 {
171  $nCRM_x = 4 * 2;
172  $nCRM_z = 7 * 2;
173 }
174 
175 
176 # calculate tpc area based on number of CRMs and their dimensions
177 # each CRP should have a 2x2 CRMs
178 $widthTPCActive = $nCRM_x * $widthCRM + $nCRM_x * $borderCRP; # around 1200 for full module
179 $lengthTPCActive = $nCRM_z * $lengthCRM + $nCRM_z * $borderCRP; # around 6000 for full module
180 
181 # active volume dimensions
182 $driftTPCActive = 650.0;
183 
184 # model anode strips as wires of some diameter
185 $padWidth = 0.02;
186 $ReadoutPlane = $nViews * $padWidth; # 3 readout planes (no space b/w)!
187 
188 ##################################################################
189 ############## Parameters for TPC and inner volume ###############
190 
191 # inner volume dimensions of the cryostat
192 $Argon_x = 1510;
193 $Argon_y = 1510;
194 $Argon_z = 6200;
195 
196 # width of gas argon layer on top
197 $HeightGaseousAr = 100;
198 
199 if( $workspace != 0 )
200 {
201  #active tpc + 1.0 m buffer on each side
202  $Argon_x = $driftTPCActive + $HeightGaseousAr + $ReadoutPlane + 100;
203  $Argon_y = $widthTPCActive + 200;
204  $Argon_z = $lengthTPCActive + 200;
205 }
206 
207 
208 # size of liquid argon buffer
209 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
210 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
211 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
212 
213 # cryostat
214 $SteelThickness = 0.12; # membrane
215 
216 $Cryostat_x = $Argon_x + 2*$SteelThickness;
217 $Cryostat_y = $Argon_y + 2*$SteelThickness;
218 $Cryostat_z = $Argon_z + 2*$SteelThickness;
219 
220 ##################################################################
221 ############## DetEnc and World relevant parameters #############
222 
223 $SteelSupport_x = 100;
224 $SteelSupport_y = 100;
225 $SteelSupport_z = 100;
226 $FoamPadding = 80;
227 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
228 $FracMassOfAir = 1 - $FracMassOfSteel;
229 
230 
231 $SpaceSteelSupportToWall = 100;
232 $SpaceSteelSupportToCeiling = 100;
233 
234 $DetEncX = $Cryostat_x
235  + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
236 
237 $DetEncY = $Cryostat_y
238  + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
239 
240 $DetEncZ = $Cryostat_z
241  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
242 
243 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
244 
245 
246 $RockThickness = 4000;
247 
248  # We want the world origin to be vertically centered on active TPC
249  # This is to be added to the x and y position of every volume in volWorld
250 
251 $OriginXSet = $DetEncX/2.0
252  - $SteelSupport_x
253  - $FoamPadding
254  - $SteelThickness
255  - $xLArBuffer
256  - $driftTPCActive/2.0;
257 
258 $OriginYSet = $DetEncY/2.0
259  - $SpaceSteelSupportToWall
260  - $SteelSupport_y
261  - $FoamPadding
262  - $SteelThickness
263  - $yLArBuffer
264  - $widthTPCActive/2.0;
265 
266  # We want the world origin to be at the very front of the fiducial volume.
267  # move it to the front of the enclosure, then back it up through the concrete/foam,
268  # then through the Cryostat shell, then through the upstream dead LAr (including the
269  # dead LAr on the edge of the TPC)
270  # This is to be added to the z position of every volume in volWorld
271 
272 $OriginZSet = $DetEncZ/2.0
273  - $SpaceSteelSupportToWall
274  - $SteelSupport_z
275  - $FoamPadding
276  - $SteelThickness
277  - $zLArBuffer
278  - $borderCRM;
279 
280 ##################################################################
281 ############## Field Cage Parameters ###############
282 $FieldShaperLongTubeLength = $lengthTPCActive;
283 $FieldShaperShortTubeLength = $widthTPCActive;
284 #$FieldShaperInnerRadius = 1.485;
285 #$FieldShaperOuterRadius = 1.685;
286 #$FieldShaperTorRad = 1.69;
287 $FieldShaperInnerRadius = 0.5; #cm
288 $FieldShaperOuterRadius = 2.285; #cm
289 $FieldShaperOuterRadiusSlim = 0.75; #cm
290 $FieldShaperTorRad = 2.3; #cm
291 
292 $FieldShaperLength = $FieldShaperLongTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
293 $FieldShaperWidth = $FieldShaperShortTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
294 
295 $FieldShaperSeparation = 6.0; #cm
296 $NFieldShapers = ($driftTPCActive/$FieldShaperSeparation) - 1;
297 
298 $FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2;
299 $FieldCageSizeY = $FieldShaperWidth+2;
300 $FieldCageSizeZ = $FieldShaperLength+2;
301 
302 
303 ####################################################################
304 ######################## ARAPUCA Dimensions ########################
305 ## in cm
306 
307 $ArapucaOut_x = 65.0;
308 $ArapucaOut_y = 2.5;
309 $ArapucaOut_z = 65.0;
310 $ArapucaIn_x = 60.0;
311 $ArapucaIn_y = 2.0;
312 $ArapucaIn_z = 60.0;
313 $ArapucaAcceptanceWindow_x = 60.0;
314 $ArapucaAcceptanceWindow_y = 1.0;
315 $ArapucaAcceptanceWindow_z = 60.0;
316 $BlockPD_x = 0.5*$widthCRM_active - 6.35; #Sub-division of Frame (4 n x, 4 in z)
317 $BlockPD_z = 0.5*$lengthCRM_active - 6.25;
318 $GapPD = 0.5; #Size of supporting bars in Frame
319 $FrameToArapucaSpace = 1.0; #At this moment, should cover the thickness of Frame + small gap to prevent overlap. VALUE NEEDS TO BE CHECKED!!!
320 $FrameToArapucaSpaceLat = $yLArBuffer - 60.0; #Arapucas 60 cm behind FC. At this moment, should cover the thickness of Frame + small gap to prevent overlap. VALUE NEEDS TO BE CHECKED!!!
321 $VerticalPDdist = 75.0; #distance of arapucas (center to center) in the y direction
322 $HorizontalPDdist = 150.0; #distance of arapucas (center to center) in the x direction
323 
324 #Positions of the 4 arapucas with respect to the Frame center --> arapucas over the cathode
325 $list_posx_bot[0]=-2*$BlockPD_x - 1.5*$GapPD + 0.5*$ArapucaOut_x;
326 $list_posz_bot[0]= 0.5*$BlockPD_z + $GapPD;
327 $list_posx_bot[1]=- $GapPD - 0.5*$ArapucaOut_x;
328 $list_posz_bot[1]=-1.5*$BlockPD_z - 1.5*$GapPD;
329 $list_posx_bot[2]=-$list_posx_bot[1];
330 $list_posz_bot[2]=-$list_posz_bot[1];
331 $list_posx_bot[3]=-$list_posx_bot[0];
332 $list_posz_bot[3]=-$list_posz_bot[0];
333 
334 
335 
336 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
337 
338 
339 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
340 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
341 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
342 
343 sub usage()
344 {
345  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
346  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
347  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
348  print " -h prints this message, then quits\n";
349 }
350 
351 
352 sub gen_Extend()
353 {
354 
355 # Create the <define> fragment file name,
356 # add file to list of fragments,
357 # and open it
358  $DEF = $basename."_Ext" . $suffix . ".gdml";
359  push (@gdmlFiles, $DEF);
360  $DEF = ">" . $DEF;
361  open(DEF) or die("Could not open file $DEF for writing");
362 
363 print DEF <<EOF;
364 <?xml version='1.0'?>
365 <gdml>
366 <extension>
367  <color name="magenta" R="0.0" G="1.0" B="0.0" A="1.0" />
368  <color name="green" R="0.0" G="1.0" B="0.0" A="1.0" />
369  <color name="red" R="1.0" G="0.0" B="0.0" A="1.0" />
370  <color name="blue" R="0.0" G="0.0" B="1.0" A="1.0" />
371  <color name="yellow" R="1.0" G="1.0" B="0.0" A="1.0" />
372 </extension>
373 </gdml>
374 EOF
375  close (DEF);
376 }
377 
378 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
379 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
380 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
381 
382 sub gen_Define()
383 {
384 
385 # Create the <define> fragment file name,
386 # add file to list of fragments,
387 # and open it
388  $DEF = $basename."_Def" . $suffix . ".gdml";
389  push (@gdmlFiles, $DEF);
390  $DEF = ">" . $DEF;
391  open(DEF) or die("Could not open file $DEF for writing");
392 
393 
394 print DEF <<EOF;
395 <?xml version='1.0'?>
396 <gdml>
397 <define>
398 
399 <!--
400 
401 
402 
403 -->
404 
405  <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
406  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
407  <rotation name="rUWireAboutX" unit="deg" x="$wireAngleU" y="0" z="0"/>
408  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
409  <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
410  <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
411  <rotation name="rMinus90AboutX" unit="deg" x="270" y="0" z="0"/>
412  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
413  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
414  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
415  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
416  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
417  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
418 </define>
419 </gdml>
420 EOF
421  close (DEF);
422 }
423 
424 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
425 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
426 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
427 
428 sub gen_Materials()
429 {
430 
431 # Create the <materials> fragment file name,
432 # add file to list of output GDML fragments,
433 # and open it
434  $MAT = $basename."_Materials" . $suffix . ".gdml";
435  push (@gdmlFiles, $MAT);
436  $MAT = ">" . $MAT;
437 
438  open(MAT) or die("Could not open file $MAT for writing");
439 
440  # Add any materials special to this geometry by defining a mulitline string
441  # and passing it to the gdmlMaterials::gen_Materials() function.
442 my $asmix = <<EOF;
443  <!-- preliminary values -->
444  <material name="AirSteelMixture" formula="AirSteelMixture">
445  <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
446  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
447  <fraction n="$FracMassOfAir" ref="Air"/>
448  </material>
449  <material name="vm2000" formula="vm2000">
450  <D value="1.2" unit="g/cm3"/>
451  <composite n="2" ref="carbon"/>
452  <composite n="4" ref="hydrogen"/>
453  </material>
454 EOF
455 
456  # add the general materials used anywere
457  print MAT gdmlMaterials::gen_Materials( $asmix );
458 
459  close(MAT);
460 }
461 
462 
463 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
464 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
465 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
466 # line clip on the rectangle boundary
467 sub lineClip {
468  my $x0 = $_[0];
469  my $y0 = $_[1];
470  my $nx = $_[2];
471  my $ny = $_[3];
472  my $rcl = $_[4];
473  my $rcw = $_[5];
474 
475  my $tol = 1.0E-4;
476  my @endpts = ();
477  if( abs( nx ) < tol ){
478  push( @endpts, ($x0, 0) );
479  push( @endpts, ($x0, $rcw) );
480  return @endpts;
481  }
482  if( abs( ny ) < tol ){
483  push( @endpts, (0, $y0) );
484  push( @endpts, ($rcl, $y0) );
485  return @endpts;
486  }
487 
488  # left border at x = 0
489  my $y = $y0 - $x0 * $ny/$nx;
490  if( $y >= 0 && $y <= $rcw ){
491  push( @endpts, (0, $y) );
492  }
493 
494  # right border at x = l
495  $y = $y0 + ($rcl-$x0) * $ny/$nx;
496  if( $y >= 0 && $y <= $rcw ){
497  push( @endpts, ($rcl, $y) );
498  if( scalar(@endpts) == 4 ){
499  return @endpts;
500  }
501  }
502 
503  # bottom border at y = 0
504  my $x = $x0 - $y0 * $nx/$ny;
505  if( $x >= 0 && $x <= $rcl ){
506  push( @endpts, ($x, 0) );
507  if( scalar(@endpts) == 4 ){
508  return @endpts;
509  }
510  }
511 
512  # top border at y = w
513  $x = $x0 + ($rcw-$y0)* $nx/$ny;
514  if( $x >= 0 && $x <= $rcl ){
515  push( @endpts, ($x, $rcw) );
516  }
517 
518  return @endpts;
519 }
520 
521 sub gen_Wires
522 {
523  my $length = $_[0]; #
524  my $width = $_[1]; #
525  my $nch = $_[2]; #
526  my $nchb = $_[3]; # nch per bottom side
527  my $pitch = $_[4]; #
528  my $theta = $_[5]; # deg
529  my $dia = $_[6]; #
530 
531  $theta = $theta * pi()/180.0;
532  my @dirw = (cos($theta), sin($theta));
533  my @dirp = (cos($theta - pi()/2), sin($theta - pi()/2));
534 
535  # calculate
536  my $alpha = $theta;
537  if( $alpha > pi()/2 ){
538  $alpha = pi() - $alpha;
539  }
540  my $dX = $pitch / sin( $alpha );
541  my $dY = $pitch / sin( pi()/2 - $alpha );
542  if( $length <= 0 ){
543  $length = $dX * $nchb;
544  }
545  if( $width <= 0 ){
546  $width = $dY * ($nch - $nchb);
547  }
548 
549  my @orig = (0, 0);
550  if( $dirp[0] < 0 ){
551  $orig[0] = $length;
552  }
553  if( $dirp[1] < 0 ){
554  $orig[1] = $width;
555  }
556 
557  #print "origin : @orig\n";
558  #print "pitch dir : @dirp\n";
559  #print "wire dir : @dirw\n";
560  #print "$length x $width cm2\n";
561 
562  # gen wires
563  my @winfo = ();
564  my $offset = $pitch/2;
565  foreach my $ch (0..$nch-1){
566  #print "Processing $ch\n";
567 
568  # calculate reference point for this strip
569  my @wcn = (0, 0);
570  $wcn[0] = $orig[0] + $offset * $dirp[0];
571  $wcn[1] = $orig[1] + $offset * $dirp[1];
572 
573  # line clip on the rectangle boundary
574  @endpts = lineClip( $wcn[0], $wcn[1], $dirw[0], $dirw[1], $length, $width );
575 
576  if( scalar(@endpts) != 4 ){
577  print "Could not find end points for wire $ch : @endpts\n";
578  $offset = $offset + $pitch;
579  next;
580  }
581 
582  # re-center on the mid-point
583  $endpts[0] -= $length/2;
584  $endpts[2] -= $length/2;
585  $endpts[1] -= $width/2;
586  $endpts[3] -= $width/2;
587 
588  # calculate the strip center in the rectangle of CRU
589  $wcn[0] = ($endpts[0] + $endpts[2])/2;
590  $wcn[1] = ($endpts[1] + $endpts[3])/2;
591 
592  # calculate the length
593  my $dx = $endpts[0] - $endpts[2];
594  my $dy = $endpts[1] - $endpts[3];
595  my $wlen = sqrt($dx**2 + $dy**2);
596 
597  # put all info together
598  my @wire = ($ch, $wcn[0], $wcn[1], $wlen);
599  push( @wire, @endpts );
600  push( @winfo, \@wire);
601  $offset = $offset + $pitch;
602  #last;
603  }
604  return @winfo;
605 }
606 
607 #
608 sub gen_TPC()
609 {
610  # CRM active volume
611  my $TPCActive_x = $driftTPCActive;
612  my $TPCActive_y = $widthCRM_active;
613  my $TPCActive_z = $lengthCRM_active;
614 
615  # CRM total volume
616  my $TPC_x = $TPCActive_x + $ReadoutPlane;
617  my $TPC_y = $widthCRM;
618  my $TPC_z = $lengthCRM;
619 
620  print " TPC dimensions : $TPC_x x $TPC_y x $TPC_z\n";
621 
622  $TPC = $basename."_TPC" . $suffix . ".gdml";
623  push (@gdmlFiles, $TPC);
624  $TPC = ">" . $TPC;
625  open(TPC) or die("Could not open file $TPC for writing");
626 
627  # The standard XML prefix and starting the gdml
628 print TPC <<EOF;
629  <?xml version='1.0'?>
630  <gdml>
631 EOF
632 
633  # compute wires for 1st induction
634  my @winfo = ();
635  if( $wires_on == 1 ){
636  @winfo = gen_Wires( 0, 0, # $TPCActive_y,
637  $nChans{'Ind1'}, $nChans{'Ind1Bot'},
638  $wirePitchU, $wireAngleU, $padWidth );
639  }
640 
641  # All the TPC solids save the wires.
642 print TPC <<EOF;
643  <solids>
644 EOF
645 
646 print TPC <<EOF;
647  <box name="CRM"
648  x="$TPC_x"
649  y="$TPC_y"
650  z="$TPC_z"
651  lunit="cm"/>
652  <box name="CRMUPlane"
653  x="$padWidth"
654  y="$TPCActive_y"
655  z="$TPCActive_z"
656  lunit="cm"/>
657  <box name="CRMYPlane"
658  x="$padWidth"
659  y="$TPCActive_y"
660  z="$TPCActive_z"
661  lunit="cm"/>
662  <box name="CRMZPlane"
663  x="$padWidth"
664  y="$TPCActive_y"
665  z="$TPCActive_z"
666  lunit="cm"/>
667  <box name="CRMActive"
668  x="$TPCActive_x"
669  y="$TPCActive_y"
670  z="$TPCActive_z"
671  lunit="cm"/>
672 EOF
673 
674 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
675 if($wires_on==1){
676 
677  foreach my $wire (@winfo) {
678  my $wid = $wire->[0];
679  my $wln = $wire->[3];
680 print TPC <<EOF;
681  <tube name="CRMWireU$wid"
682  rmax="0.5*$padWidth"
683  z="$wln"
684  deltaphi="360"
685  aunit="deg" lunit="cm"/>
686 EOF
687  }
688 
689 print TPC <<EOF;
690  <tube name="CRMWireY"
691  rmax="0.5*$padWidth"
692  z="$TPCActive_z"
693  deltaphi="360"
694  aunit="deg" lunit="cm"/>
695  <tube name="CRMWireZ"
696  rmax="0.5*$padWidth"
697  z="$TPCActive_y"
698  deltaphi="360"
699  aunit="deg" lunit="cm"/>
700 EOF
701 }
702 print TPC <<EOF;
703 </solids>
704 EOF
705 
706 
707 # Begin structure and create wire logical volumes
708 print TPC <<EOF;
709 <structure>
710  <volume name="volTPCActive">
711  <materialref ref="LAr"/>
712  <solidref ref="CRMActive"/>
713  <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
714  <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5208*cm"/>
715  <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="500*V/cm"/>
716  <colorref ref="blue"/>
717  </volume>
718 EOF
719 
720 if($wires_on==1)
721 {
722  foreach my $wire (@winfo)
723  {
724  my $wid = $wire->[0];
725 print TPC <<EOF;
726  <volume name="volTPCWireU$wid">
727  <materialref ref="Copper_Beryllium_alloy25"/>
728  <solidref ref="CRMWireU$wid"/>
729  </volume>
730 EOF
731  }
732 
733 print TPC <<EOF;
734  <volume name="volTPCWireY">
735  <materialref ref="Copper_Beryllium_alloy25"/>
736  <solidref ref="CRMWireY"/>
737  </volume>
738  <volume name="volTPCWireZ">
739  <materialref ref="Copper_Beryllium_alloy25"/>
740  <solidref ref="CRMWireZ"/>
741  </volume>
742 EOF
743 }
744  # 1st induction plane
745 print TPC <<EOF;
746  <volume name="volTPCPlaneU">
747  <materialref ref="LAr"/>
748  <solidref ref="CRMUPlane"/>
749 EOF
750 if ($wires_on==1) # add wires to U plane
751 {
752  # the coordinates were computed with a corner at (0,0)
753  # so we need to move to plane coordinates
754  my $offsetZ = 0; #-0.5 * $TPCActive_z;
755  my $offsetY = 0; #-0.5 * $TPCActive_y;
756 
757  foreach my $wire (@winfo) {
758  my $wid = $wire->[0];
759  my $zpos = $wire->[1] + $offsetZ;
760  my $ypos = $wire->[2] + $offsetY;
761 print TPC <<EOF;
762  <physvol>
763  <volumeref ref="volTPCWireU$wid"/>
764  <position name="posWireU$wid" unit="cm" x="0" y="$ypos" z="$zpos"/>
765  <rotationref ref="rUWireAboutX"/>
766  </physvol>
767 EOF
768  }
769 }
770 print TPC <<EOF;
771  </volume>
772 EOF
773 
774 # 2nd induction plane
775 print TPC <<EOF;
776  <volume name="volTPCPlaneY">
777  <materialref ref="LAr"/>
778  <solidref ref="CRMYPlane"/>
779 EOF
780 
781 if ($wires_on==1) # add wires to Y plane (plane with wires reading y position)
782 {
783  for(my $i=0;$i<$nChans{'Ind2'};++$i)
784  {
785  #my $ypos = -0.5 * $TPCActive_y + ($i+0.5)*$wirePitchY + 0.5*$padWidth;
786  my $ypos = ($i + 0.5 - $nChans{'Ind2'}/2)*$wirePitchY;
787  if( (0.5 * $TPCActive_y - abs($ypos)) < 0 ){
788  die "Cannot place wire $i in view Y, as plane is too small\n";
789  }
790 print TPC <<EOF;
791  <physvol>
792  <volumeref ref="volTPCWireY"/>
793  <position name="posWireY$i" unit="cm" x="0" y="$ypos" z="0"/>
794  <rotationref ref="rIdentity"/>
795  </physvol>
796 EOF
797  }
798 }
799 print TPC <<EOF;
800  </volume>
801 EOF
802 
803 # collection plane
804 print TPC <<EOF;
805  <volume name="volTPCPlaneZ">
806  <materialref ref="LAr"/>
807  <solidref ref="CRMZPlane"/>
808 EOF
809 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
810  {
811  for(my $i=0;$i<$nChans{'Col'};++$i)
812  {
813  #my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitchZ + 0.5*$padWidth;
814  my $zpos = ($i + 0.5 - $nChans{'Col'}/2)*$wirePitchZ;
815  if( (0.5 * $TPCActive_z - abs($zpos)) < 0 ){
816  die "Cannot place wire $i in view Z, as plane is too small\n";
817  }
818 print TPC <<EOF;
819  <physvol>
820  <volumeref ref="volTPCWireZ"/>
821  <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
822  <rotationref ref="rPlus90AboutX"/>
823  </physvol>
824 EOF
825  }
826 }
827 print TPC <<EOF;
828  </volume>
829 EOF
830 
831 
832 $posUplane[0] = 0.5*$TPC_x - 2.5*$padWidth;
833 $posUplane[1] = 0;
834 $posUplane[2] = 0;
835 
836 $posYplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
837 $posYplane[1] = 0;
838 $posYplane[2] = 0;
839 
840 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
841 $posZplane[1] = 0;
842 $posZplane[2] = 0;
843 
844 $posTPCActive[0] = -$ReadoutPlane/2;
845 $posTPCActive[1] = 0;
846 $posTPCActive[2] = 0;
847 
848 
849 #wrap up the TPC file
850 print TPC <<EOF;
851  <volume name="volTPC">
852  <materialref ref="LAr"/>
853  <solidref ref="CRM"/>
854  <physvol>
855  <volumeref ref="volTPCPlaneU"/>
856  <position name="posPlaneU" unit="cm"
857  x="$posUplane[0]" y="$posUplane[1]" z="$posUplane[2]"/>
858  <rotationref ref="rIdentity"/>
859  </physvol>
860  <physvol>
861  <volumeref ref="volTPCPlaneY"/>
862  <position name="posPlaneY" unit="cm"
863  x="$posYplane[0]" y="$posYplane[1]" z="$posYplane[2]"/>
864  <rotationref ref="rIdentity"/>
865  </physvol>
866  <physvol>
867  <volumeref ref="volTPCPlaneZ"/>
868  <position name="posPlaneZ" unit="cm"
869  x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
870  <rotationref ref="rIdentity"/>
871  </physvol>
872  <physvol>
873  <volumeref ref="volTPCActive"/>
874  <position name="posActive" unit="cm"
875  x="$posTPCActive[0]" y="$posTPCAtive[1]" z="$posTPCActive[2]"/>
876  <rotationref ref="rIdentity"/>
877  </physvol>
878  </volume>
879 EOF
880 ## x="@{[$posTPCActive[0]+$padWidth]}" y="$posTPCActive[1]" z="$posTPCActive[2]"/>
881 
882 print TPC <<EOF;
883  </structure>
884  </gdml>
885 EOF
886 
887  close(TPC);
888 }
889 
890 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
891 #++++++++++++++++++++++++++++++++++++++ gen_FieldCage ++++++++++++++++++++++++++++++++++++
892 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
893 
894 sub gen_FieldCage {
895 
896  $FieldCage = $basename."_FieldCage" . $suffix . ".gdml";
897  push (@gdmlFiles, $FieldCage);
898  $FieldCage = ">" . $FieldCage;
899  open(FieldCage) or die("Could not open file $FieldCage for writing");
900 
901 # The standard XML prefix and starting the gdml
902 print FieldCage <<EOF;
903  <?xml version='1.0'?>
904  <gdml>
905 EOF
906 # The printing solids used in the Field Cage
907 #print "lengthTPCActive : $lengthTPCActive \n";
908 #print "widthTPCActive : $widthTPCActive \n";
909 
910 
911 print FieldCage <<EOF;
912 <solids>
913  <torus name="FieldShaperCorner" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" rtor="$FieldShaperTorRad" deltaphi="90" startphi="0" aunit="deg" lunit="cm"/>
914  <tube name="FieldShaperLongtube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
915  <tube name="FieldShaperLongtubeSlim" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadiusSlim" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
916  <tube name="FieldShaperShorttube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperShortTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
917 
918  <union name="FSunion1">
919  <first ref="FieldShaperLongtube"/>
920  <second ref="FieldShaperCorner"/>
921  <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
922  <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
923  </union>
924 
925  <union name="FSunion2">
926  <first ref="FSunion1"/>
927  <second ref="FieldShaperShorttube"/>
928  <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
929  <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
930  </union>
931 
932  <union name="FSunion3">
933  <first ref="FSunion2"/>
934  <second ref="FieldShaperCorner"/>
935  <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
936  <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
937  </union>
938 
939  <union name="FSunion4">
940  <first ref="FSunion3"/>
941  <second ref="FieldShaperLongtube"/>
942  <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
943  </union>
944 
945  <union name="FSunion5">
946  <first ref="FSunion4"/>
947  <second ref="FieldShaperCorner"/>
948  <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
949  <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
950  </union>
951 
952  <union name="FSunion6">
953  <first ref="FSunion5"/>
954  <second ref="FieldShaperShorttube"/>
955  <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
956  <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
957  </union>
958 
959  <union name="FieldShaperSolid">
960  <first ref="FSunion6"/>
961  <second ref="FieldShaperCorner"/>
962  <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
963  <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
964  </union>
965 
966  <union name="FSunionSlim1">
967  <first ref="FieldShaperLongtubeSlim"/>
968  <second ref="FieldShaperCorner"/>
969  <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
970  <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
971  </union>
972 
973  <union name="FSunionSlim2">
974  <first ref="FSunionSlim1"/>
975  <second ref="FieldShaperShorttube"/>
976  <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
977  <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
978  </union>
979 
980  <union name="FSunionSlim3">
981  <first ref="FSunionSlim2"/>
982  <second ref="FieldShaperCorner"/>
983  <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
984  <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
985  </union>
986 
987  <union name="FSunionSlim4">
988  <first ref="FSunionSlim3"/>
989  <second ref="FieldShaperLongtubeSlim"/>
990  <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
991  </union>
992 
993  <union name="FSunionSlim5">
994  <first ref="FSunionSlim4"/>
995  <second ref="FieldShaperCorner"/>
996  <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
997  <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
998  </union>
999 
1000  <union name="FSunionSlim6">
1001  <first ref="FSunionSlim5"/>
1002  <second ref="FieldShaperShorttube"/>
1003  <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
1004  <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
1005  </union>
1006 
1007  <union name="FieldShaperSolidSlim">
1008  <first ref="FSunionSlim6"/>
1009  <second ref="FieldShaperCorner"/>
1010  <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
1011  <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
1012  </union>
1013 
1014 </solids>
1015 
1016 EOF
1017 
1018 print FieldCage <<EOF;
1019 
1020 <structure>
1021 <volume name="volFieldShaper">
1022  <materialref ref="Al2O3"/>
1023  <solidref ref="FieldShaperSolid"/>
1024 </volume>
1025 <volume name="volFieldShaperSlim">
1026  <materialref ref="Al2O3"/>
1027  <solidref ref="FieldShaperSolidSlim"/>
1028 </volume>
1029 
1030 </structure>
1031 
1032 EOF
1033 
1034 print FieldCage <<EOF;
1035 
1036 </gdml>
1037 EOF
1038 close(FieldCage);
1039 }
1040 
1041 
1042 
1043 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1044 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1045 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1046 
1047 sub gen_Cryostat()
1048 {
1049 
1050 # Create the cryostat fragment file name,
1051 # add file to list of output GDML fragments,
1052 # and open it
1053  $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
1054  push (@gdmlFiles, $CRYO);
1055  $CRYO = ">" . $CRYO;
1056  open(CRYO) or die("Could not open file $CRYO for writing");
1057 
1058 
1059 # The standard XML prefix and starting the gdml
1060  print CRYO <<EOF;
1061 <?xml version='1.0'?>
1062 <gdml>
1063 EOF
1064 
1065 # All the cryostat solids.
1066 # External active are two side volumes for generating light outside the field cage (no top or bottom buffers included)
1067 print CRYO <<EOF;
1068 <solids>
1069  <box name="Cryostat" lunit="cm"
1070  x="$Cryostat_x"
1071  y="$Cryostat_y"
1072  z="$Cryostat_z"/>
1073 
1074  <box name="ArgonInterior" lunit="cm"
1075  x="$Argon_x"
1076  y="$Argon_y"
1077  z="$Argon_z"/>
1078 
1079  <box name="GaseousArgon" lunit="cm"
1080  x="$HeightGaseousAr"
1081  y="$Argon_y"
1082  z="$Argon_z"/>
1083 
1084  <box name="ExternalAuxOut" lunit="cm"
1085  x="$Argon_x - $xLArBuffer"
1086  y="$Argon_y - 2*$ArapucaOut_y - 2*$FrameToArapucaSpaceLat"
1087  z="$Argon_z"/>
1088 
1089  <box name="ExternalAuxIn" lunit="cm"
1090  x="$Argon_x"
1091  y="$FieldCageSizeY"
1092  z="$Argon_z + 1"/>
1093 
1094  <subtraction name="ExternalActive">
1095  <first ref="ExternalAuxOut"/>
1096  <second ref="ExternalAuxIn"/>
1097  </subtraction>
1098 
1099  <subtraction name="SteelShell">
1100  <first ref="Cryostat"/>
1101  <second ref="ArgonInterior"/>
1102  </subtraction>
1103 
1104 </solids>
1105 EOF
1106 
1107 #PDS
1108 #Double sided detectors should only be included when both top and bottom volumes become available
1109 #Optical sensitive volumes cannot be rotated because Larsoft cannot pick up the rotation when obtinaing the lengths needed for the semi-analytic model --> two acceptance windows for single sided lateral and cathode
1110 print CRYO <<EOF;
1111 <solids>
1112  <box name="ArapucaOut" lunit="cm"
1113  x="@{[$ArapucaOut_x]}"
1114  y="@{[$ArapucaOut_y]}"
1115  z="@{[$ArapucaOut_z]}"/>
1116 
1117  <box name="ArapucaIn" lunit="cm"
1118  x="@{[$ArapucaIn_x]}"
1119  y="@{[$ArapucaOut_y]}"
1120  z="@{[$ArapucaIn_z]}"/>
1121 
1122  <subtraction name="ArapucaWalls">
1123  <first ref="ArapucaOut"/>
1124  <second ref="ArapucaIn"/>
1125  <position name="posArapucaSub" x="0" y="@{[$ArapucaOut_y/2.0]}" z="0." unit="cm"/>
1126  </subtraction>
1127 
1128  <box name="ArapucaAcceptanceWindow" lunit="cm"
1129  x="@{[$ArapucaAcceptanceWindow_x]}"
1130  y="@{[$ArapucaAcceptanceWindow_y]}"
1131  z="@{[$ArapucaAcceptanceWindow_z]}"/>
1132 
1133  <box name="ArapucaDoubleIn" lunit="cm"
1134  x="@{[$ArapucaIn_x]}"
1135  y="@{[$ArapucaOut_y+1.0]}"
1136  z="@{[$ArapucaIn_z]}"/>
1137 
1138  <subtraction name="ArapucaDoubleWalls">
1139  <first ref="ArapucaOut"/>
1140  <second ref="ArapucaDoubleIn"/>
1141  <position name="posArapucaDoubleSub" x="0" y="0" z="0" unit="cm"/>
1142  </subtraction>
1143 
1144  <box name="ArapucaDoubleAcceptanceWindow" lunit="cm"
1145  x="@{[$ArapucaOut_y-0.02]}"
1146  y="@{[$ArapucaAcceptanceWindow_x]}"
1147  z="@{[$ArapucaAcceptanceWindow_z]}"/>
1148 
1149  <box name="ArapucaCathodeAcceptanceWindow" lunit="cm"
1150  x="@{[$ArapucaAcceptanceWindow_y]}"
1151  y="@{[$ArapucaAcceptanceWindow_x]}"
1152  z="@{[$ArapucaAcceptanceWindow_z]}"/>
1153 
1154 </solids>
1155 EOF
1156 
1157 # Cryostat structure
1158 print CRYO <<EOF;
1159 <structure>
1160  <volume name="volSteelShell">
1161  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
1162  <solidref ref="SteelShell" />
1163  </volume>
1164  <volume name="volGaseousArgon">
1165  <materialref ref="ArGas"/>
1166  <solidref ref="GaseousArgon"/>
1167  </volume>
1168  <volume name="volExternalActive">
1169  <materialref ref="LAr"/>
1170  <solidref ref="ExternalActive"/>
1171  <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
1172  <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5208*cm"/>
1173  <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="0*V/cm"/>
1174  <colorref ref="green"/>
1175  </volume>
1176 EOF
1177 #including single sided arapucas over the cathode while there is only the top volume
1178 #if double sided, use
1179 # <volume name="volArapucaDouble_$i\-$j\-$p">
1180 # <materialref ref="G10" />
1181 # <solidref ref="ArapucaDoubleWalls" />
1182 # </volume>
1183 # <volume name="volOpDetSensitive_ArapucaDouble_$i\-$j\-$p">
1184 # <materialref ref="LAr"/>
1185 # <solidref ref="ArapucaDoubleAcceptanceWindow"/>
1186 # </volume>
1187 if ($pdsconfig == 0){ #4-pi PDS converage
1188 for($i=0 ; $i<$nCRM_x/2 ; $i++){ #arapucas over the cathode
1189 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1190 for($p=0 ; $p<4 ; $p++){
1191  print CRYO <<EOF;
1192  <volume name="volArapucaDouble_$i\-$j\-$p">
1193  <materialref ref="G10" />
1194  <solidref ref="ArapucaWalls" />
1195  </volume>
1196  <volume name="volOpDetSensitive_ArapucaDouble_$i\-$j\-$p">
1197  <materialref ref="LAr"/>
1198  <solidref ref="ArapucaCathodeAcceptanceWindow"/>
1199  </volume>
1200 EOF
1201 }
1202 }
1203 }
1204 }
1205 
1206 if ($nCRM_x==8){ #arapucas on the laterals
1207 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1208 for($p=0 ; $p<8 ; $p++){
1209  print CRYO <<EOF;
1210  <volume name="volArapucaLat_$j\-$p">
1211  <materialref ref="G10" />
1212  <solidref ref="ArapucaWalls" />
1213  </volume>
1214  <volume name="volOpDetSensitive_ArapucaLat_$j\-$p">
1215  <materialref ref="LAr"/>
1216  <solidref ref="ArapucaAcceptanceWindow"/>
1217  </volume>
1218 EOF
1219 }
1220 }
1221 }
1222 
1223 if ($pdsconfig == 1){ #Membrane PDS converage
1224 if ($nCRM_x==8) { #arapucas on the laterals
1225 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1226 for($p=8 ; $p<18 ; $p++){
1227  print CRYO <<EOF;
1228  <volume name="volArapucaLat_$j\-$p">
1229  <materialref ref="G10" />
1230  <solidref ref="ArapucaWalls" />
1231  </volume>
1232  <volume name="volOpDetSensitive_ArapucaLat_$j\-$p">
1233  <materialref ref="LAr"/>
1234  <solidref ref="ArapucaAcceptanceWindow"/>
1235  </volume>
1236 EOF
1237 }
1238 }
1239 }
1240 }
1241 
1242  print CRYO <<EOF;
1243 
1244  <volume name="volCryostat">
1245  <materialref ref="LAr" />
1246  <solidref ref="Cryostat" />
1247  <physvol>
1248  <volumeref ref="volGaseousArgon"/>
1249  <position name="posGaseousArgon" unit="cm" x="@{[$Argon_x/2-$HeightGaseousAr/2]}" y="0" z="0"/>
1250  </physvol>
1251  <physvol>
1252  <volumeref ref="volSteelShell"/>
1253  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1254  </physvol>
1255  <physvol>
1256  <volumeref ref="volExternalActive"/>
1257  <position name="posExternalActive" unit="cm" x="-$xLArBuffer/2" y="0" z="0"/>
1258  </physvol>
1259 EOF
1260 
1261 if ($tpc_on==1) # place TPC inside croysotat offsetting each pair of CRMs by borderCRP
1262 {
1263  $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1264  $idx = 0;
1265  my $posZ = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCRM;
1266  for(my $ii=0;$ii<$nCRM_z;$ii++)
1267  {
1268  if( $ii % 2 == 0 ){
1269  $posZ += $borderCRP;
1270  if( $ii>0 ){
1271  $posZ += $borderCRP;
1272  }
1273  }
1274  my $posY = -0.5*$Argon_y + $yLArBuffer + 0.5*$widthCRM;
1275  for(my $jj=0;$jj<$nCRM_x;$jj++)
1276  {
1277  if( $jj % 2 == 0 ){
1278  $posY += $borderCRP;
1279  if( $jj>0 ){
1280  $posY += $borderCRP;
1281  }
1282  }
1283  print CRYO <<EOF;
1284  <physvol>
1285  <volumeref ref="volTPC"/>
1286  <position name="posTPC\-$idx" unit="cm"
1287  x="$posX" y="$posY" z="$posZ"/>
1288  </physvol>
1289 EOF
1290  $idx++;
1291  $posY += $widthCRM;
1292  }
1293 
1294  $posZ += $lengthCRM;
1295  }
1296 }
1297 
1298 #The +50 in the x positions must depend on some other parameter
1299  if ( $FieldCage_switch eq "on" ) {
1300  for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) {
1301  $dist=$i*$FieldShaperSeparation;
1302 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1303  if ($pdsconfig==0){
1304  if ($dist>250){
1305  print CRYO <<EOF;
1306  <physvol>
1307  <volumeref ref="volFieldShaperSlim"/>
1308  <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1309  <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1310  </physvol>
1311 EOF
1312  }else{
1313  print CRYO <<EOF;
1314  <physvol>
1315  <volumeref ref="volFieldShaper"/>
1316  <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1317  <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1318  </physvol>
1319 EOF
1320  }
1321  }else{
1322  print CRYO <<EOF;
1323  <physvol>
1324  <volumeref ref="volFieldShaperSlim"/>
1325  <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1326  <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1327  </physvol>
1328 EOF
1329  }
1330  }
1331  }
1332 
1333 
1334 $CathodePosX =-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation;
1335 $CathodePosY = 0;
1336 $CathodePosZ = 0;
1337  if ( $Cathode_switch eq "on" )
1338  {
1339  print CRYO <<EOF;
1340  <physvol>
1341  <volumeref ref="volGroundGrid"/>
1342  <position name="posGroundGrid01" unit="cm" x="$CathodePosX" y="@{[-$CathodePosY]}" z="@{[$CathodePosZ]}"/>
1343  <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
1344  </physvol>
1345 
1346 EOF
1347  }
1348 
1349 $FrameLenght_x= 2.0*$widthCRM_active;
1350 $FrameLenght_z= 2.0*$lengthCRM_active;
1351 
1352 if ($pdsconfig == 0) { #4-pi PDS converage
1353 
1354 #for placing the Arapucas over the cathode
1355  $FrameCenter_x=-1.5*$FrameLenght_x+(4-$nCRM_x/2)/2*$FrameLenght_x;
1356  $FrameCenter_y=$CathodePosX;
1357  $FrameCenter_z=-9.5*$FrameLenght_z+(20-$nCRM_z/2)/2*$FrameLenght_z;
1358 for($i=0;$i<$nCRM_x/2;$i++){
1359 for($j=0;$j<$nCRM_z/2;$j++){
1360  place_OpDetsCathode($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $i, $j);
1361  $FrameCenter_z+=$FrameLenght_z;
1362 }
1363  $FrameCenter_x+=$FrameLenght_x;
1364  $FrameCenter_z=-9.5*$FrameLenght_z+(20-$nCRM_z/2)/2*$FrameLenght_z;
1365 }
1366 }
1367 
1368 if ($pdsconfig == 0) { #4-pi PDS converage
1369 #for placing the Arapucas on laterals
1370 if ($nCRM_x==8) {
1371  $FrameCenter_y=$posZplane[0]; #anode position
1372  $FrameCenter_z=-19*$FrameLenght_z/2+(40-$nCRM_z)/2*$FrameLenght_z/2;
1373 for($j=0;$j<$nCRM_z/2;$j++){#nCRM will give the collumn number (1 collumn per frame)
1374  place_OpDetsLateral($FrameCenter_y, $FrameCenter_z, $j);
1375  $FrameCenter_z+=$FrameLenght_z;
1376 }
1377 }
1378 
1379 } else { #membrane only PDS converage
1380 
1381 if($pdsconfig == 1){
1382 if ($nCRM_x==8) {
1383  $FrameCenter_y=$posZplane[0]; #anode position
1384  $FrameCenter_z=-19*$FrameLenght_z/2+(40-$nCRM_z)/2*$FrameLenght_z/2;
1385 for($j=0;$j<$nCRM_z/2;$j++){#nCRM will give the collumn number (1 collumn per frame)
1386  place_OpDetsMembOnly($FrameCenter_y, $FrameCenter_z, $j);
1387  $FrameCenter_z+=$FrameLenght_z;
1388 }
1389 }
1390 }
1391 
1392 }
1393 
1394  print CRYO <<EOF;
1395  </volume>
1396 </structure>
1397 </gdml>
1398 EOF
1399 
1400 close(CRYO);
1401 }
1402 
1403 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1404 #++++++++++++++++++++++++++++++++++++ place_OpDets +++++++++++++++++++++++++++++++++++++++
1405 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1406 
1407 sub place_OpDetsCathode()
1408 {
1409 
1410  $FrameCenter_x = $_[0];
1411  $FrameCenter_y = $_[1];
1412  $FrameCenter_z = $_[2];
1413  $Frame_x = $_[3];
1414  $Frame_z = $_[4];
1415 
1416 #Placing Arapucas over the Cathode
1417 #If there are both top and bottom volumes --> use double-sided:
1418 # <physvol>
1419 # <volumeref ref="volOpDetSensitive_ArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1420 # <position name="posOpArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1421 # x="@{[$Ara_X]}"
1422 # y="@{[$Ara_Y]}"
1423 # z="@{[$Ara_Z]}"/>
1424 # </physvol>
1425 #else
1426 for ($ara = 0; $ara<4; $ara++)
1427 {
1428  # All Arapuca centers will have the same Y coordinate
1429  # X and Z coordinates are defined with respect to the center of the current Frame
1430 
1431  $Ara_Y = $FrameCenter_x+$list_posx_bot[$ara]; #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1432  $Ara_X = $FrameCenter_y + $FrameToArapucaSpace;
1433  $Ara_Z = $FrameCenter_z+$list_posz_bot[$ara];
1434 
1435  print CRYO <<EOF;
1436  <physvol>
1437  <volumeref ref="volArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1438  <position name="posArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1439  x="@{[$Ara_X]}"
1440  y="@{[$Ara_Y]}"
1441  z="@{[$Ara_Z]}"/>
1442  <rotation name="rPlus90AboutXPlus90AboutZ" unit="deg" x="90" y="0" z="90"/>
1443  </physvol>
1444  <physvol>
1445  <volumeref ref="volOpDetSensitive_ArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1446  <position name="posOpArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1447  x="@{[$Ara_X+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01]}"
1448  y="@{[$Ara_Y]}"
1449  z="@{[$Ara_Z]}"/>
1450  </physvol>
1451 EOF
1452 
1453 }#end Ara for-loop
1454 
1455 }
1456 
1457 
1458 sub place_OpDetsLateral()
1459 {
1460 
1461  $FrameCenter_y = $_[0];
1462  $FrameCenter_z = $_[1];
1463  $Lat_z = $_[2];
1464 
1465 #Placing Arapucas on the laterals if nCRM_x=8 -- Single Sided
1466 for ($ara = 0; $ara<8; $ara++)
1467 {
1468  # Arapucas on laterals
1469  # All Arapuca centers on a given collumn will have the same Z coordinate
1470  # X coordinates are on the left and right laterals
1471  # Y coordinates are defined with respect to the cathode position
1472  # There are two collumns per frame on each side.
1473 
1474  if ($ara<4) {$Ara_Y = -0.5*$Argon_y + $FrameToArapucaSpaceLat;
1475  $Ara_YSens = ($Ara_Y+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01);
1476  $rot= "rIdentity"; }
1477  else {$Ara_Y = 0.5*$Argon_y - $FrameToArapucaSpaceLat;
1478  $Ara_YSens = ($Ara_Y-0.5*$ArapucaOut_y+0.5*$ArapucaAcceptanceWindow_y+0.01);
1479  $rot = "rPlus180AboutX";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1480  if ($ara==0||$ara==4) {$Ara_X = $FrameCenter_y-40.0;} #first tile's center 40 cm bellow anode
1481  else {$Ara_X-=$VerticalPDdist;} #other tiles separated by VerticalPDdist
1482  $Ara_Z = $FrameCenter_z;
1483 
1484 # print "lateral arapucas: $Ara_X, $Ara_Y, $Ara_Z \n";
1485 
1486  print CRYO <<EOF;
1487  <physvol>
1488  <volumeref ref="volArapucaLat_$Lat_z\-$ara"/>
1489  <position name="posArapuca$ara-Lat\-$Lat_z" unit="cm"
1490  x="@{[$Ara_X]}"
1491  y="@{[$Ara_Y]}"
1492  z="@{[$Ara_Z]}"/>
1493  <rotationref ref="$rot"/>
1494  </physvol>
1495  <physvol>
1496  <volumeref ref="volOpDetSensitive_ArapucaLat_$Lat_z\-$ara"/>
1497  <position name="posOpArapuca$ara-Lat\-$Lat_z" unit="cm"
1498  x="@{[$Ara_X]}"
1499  y="@{[$Ara_YSens]}"
1500  z="@{[$Ara_Z]}"/>
1501  </physvol>
1502 EOF
1503 
1504 }#end Ara for-loop
1505 
1506 }
1507 
1508 
1509 sub place_OpDetsMembOnly()
1510 {
1511 
1512  $FrameCenter_y = $_[0];
1513  $FrameCenter_z = $_[1];
1514  $Lat_z = $_[2];
1515 
1516 #Placing Arapucas on the laterals if nCRM_x=8 -- Single Sided
1517 for ($ara = 0; $ara<18; $ara++)
1518 {
1519  # Arapucas on laterals
1520  # All Arapuca centers on a given collumn will have the same Z coordinate
1521  # X coordinates are on the left and right laterals
1522  # Y coordinates are defined with respect to the cathode position
1523  # There are two collumns per frame on each side.
1524 
1525  if($ara<9) {$Ara_Y = -0.5*$Argon_y + $FrameToArapucaSpaceLat;
1526  $Ara_YSens = ($Ara_Y+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01);
1527  $rot= "rIdentity"; }
1528  else {$Ara_Y = 0.5*$Argon_y - $FrameToArapucaSpaceLat;
1529  $Ara_YSens = ($Ara_Y-0.5*$ArapucaOut_y+0.5*$ArapucaAcceptanceWindow_y+0.01);
1530  $rot = "rPlus180AboutX";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1531  if($ara==0||$ara==9) {$Ara_X = $FrameCenter_y-$ArapucaOut_x/2;} #first tile's center right below anode
1532  else {$Ara_X-=$ArapucaOut_x - $FrameToArapucaSpace;} #other tiles separated by minimal distance + buffer
1533  $Ara_Z = $FrameCenter_z;
1534 
1535 # print "lateral arapucas: $Ara_X, $Ara_Y, $Ara_Z \n";
1536 
1537  print CRYO <<EOF;
1538  <physvol>
1539  <volumeref ref="volArapucaLat_$Lat_z\-$ara"/>
1540  <position name="posArapuca$ara-Lat\-$Lat_z" unit="cm"
1541  x="@{[$Ara_X]}"
1542  y="@{[$Ara_Y]}"
1543  z="@{[$Ara_Z]}"/>
1544  <rotationref ref="$rot"/>
1545  </physvol>
1546  <physvol>
1547  <volumeref ref="volOpDetSensitive_ArapucaLat_$Lat_z\-$ara"/>
1548  <position name="posOpArapuca$ara-Lat\-$Lat_z" unit="cm"
1549  x="@{[$Ara_X]}"
1550  y="@{[$Ara_YSens]}"
1551  z="@{[$Ara_Z]}"/>
1552  </physvol>
1553 EOF
1554 
1555 }#end Ara for-loop
1556 
1557 
1558 
1559 }
1560 
1561 
1562 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1563 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1564 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1565 
1566 sub gen_Enclosure()
1567 {
1568 
1569 # Create the detector enclosure fragment file name,
1570 # add file to list of output GDML fragments,
1571 # and open it
1572  $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
1573  push (@gdmlFiles, $ENCL);
1574  $ENCL = ">" . $ENCL;
1575  open(ENCL) or die("Could not open file $ENCL for writing");
1576 
1577 
1578 # The standard XML prefix and starting the gdml
1579  print ENCL <<EOF;
1580 <?xml version='1.0'?>
1581 <gdml>
1582 EOF
1583 
1584 
1585 # All the detector enclosure solids.
1586 print ENCL <<EOF;
1587 <solids>
1588 
1589  <box name="FoamPadBlock" lunit="cm"
1590  x="@{[$Cryostat_x + 2*$FoamPadding]}"
1591  y="@{[$Cryostat_y + 2*$FoamPadding]}"
1592  z="@{[$Cryostat_z + 2*$FoamPadding]}" />
1593 
1594  <subtraction name="FoamPadding">
1595  <first ref="FoamPadBlock"/>
1596  <second ref="Cryostat"/>
1597  <positionref ref="posCenter"/>
1598  </subtraction>
1599 
1600  <box name="SteelSupportBlock" lunit="cm"
1601  x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
1602  y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
1603  z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
1604 
1605  <subtraction name="SteelSupport">
1606  <first ref="SteelSupportBlock"/>
1607  <second ref="FoamPadBlock"/>
1608  <positionref ref="posCenter"/>
1609  </subtraction>
1610 
1611  <box name="DetEnclosure" lunit="cm"
1612  x="$DetEncX"
1613  y="$DetEncY"
1614  z="$DetEncZ"/>
1615 
1616 </solids>
1617 EOF
1618 
1619 
1620 # Detector enclosure structure
1621  print ENCL <<EOF;
1622 <structure>
1623  <volume name="volFoamPadding">
1624  <materialref ref="fibrous_glass"/>
1625  <solidref ref="FoamPadding"/>
1626  </volume>
1627 
1628  <volume name="volSteelSupport">
1629  <materialref ref="AirSteelMixture"/>
1630  <solidref ref="SteelSupport"/>
1631  </volume>
1632 
1633  <volume name="volDetEnclosure">
1634  <materialref ref="Air"/>
1635  <solidref ref="DetEnclosure"/>
1636 
1637  <physvol>
1638  <volumeref ref="volFoamPadding"/>
1639  <positionref ref="posCryoInDetEnc"/>
1640  </physvol>
1641  <physvol>
1642  <volumeref ref="volSteelSupport"/>
1643  <positionref ref="posCryoInDetEnc"/>
1644  </physvol>
1645  <physvol>
1646  <volumeref ref="volCryostat"/>
1647  <positionref ref="posCryoInDetEnc"/>
1648  </physvol>
1649 EOF
1650 
1651 
1652 print ENCL <<EOF;
1653  </volume>
1654 EOF
1655 
1656 print ENCL <<EOF;
1657 </structure>
1658 </gdml>
1659 EOF
1660 
1661 close(ENCL);
1662 }
1663 
1664 
1665 
1666 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1667 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1668 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1669 
1670 sub gen_World()
1671 {
1672 
1673 # Create the WORLD fragment file name,
1674 # add file to list of output GDML fragments,
1675 # and open it
1676  $WORLD = $basename."_World" . $suffix . ".gdml";
1677  push (@gdmlFiles, $WORLD);
1678  $WORLD = ">" . $WORLD;
1679  open(WORLD) or die("Could not open file $WORLD for writing");
1680 
1681 
1682 # The standard XML prefix and starting the gdml
1683  print WORLD <<EOF;
1684 <?xml version='1.0'?>
1685 <gdml>
1686 EOF
1687 
1688 
1689 # All the World solids.
1690 print WORLD <<EOF;
1691 <solids>
1692  <box name="World" lunit="cm"
1693  x="@{[$DetEncX+2*$RockThickness]}"
1694  y="@{[$DetEncY+2*$RockThickness]}"
1695  z="@{[$DetEncZ+2*$RockThickness]}"/>
1696 </solids>
1697 EOF
1698 
1699 # World structure
1700 print WORLD <<EOF;
1701 <structure>
1702  <volume name="volWorld" >
1703  <materialref ref="DUSEL_Rock"/>
1704  <solidref ref="World"/>
1705 
1706  <physvol>
1707  <volumeref ref="volDetEnclosure"/>
1708  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1709  </physvol>
1710 
1711  </volume>
1712 </structure>
1713 </gdml>
1714 EOF
1715 
1716 # make_gdml.pl will take care of <setup/>
1717 
1718 close(WORLD);
1719 }
1720 
1721 
1722 
1723 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1724 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1725 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1726 
1727 sub write_fragments()
1728 {
1729  # This subroutine creates an XML file that summarizes the the subfiles output
1730  # by the other sub routines - it is the input file for make_gdml.pl which will
1731  # give the final desired GDML file. Specify its name with the output option.
1732  # (you can change the name when running make_gdml)
1733 
1734  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
1735 
1736  if ( ! defined $output )
1737  {
1738  $output = "-"; # write to STDOUT
1739  }
1740 
1741  # Set up the output file.
1742  $OUTPUT = ">" . $output;
1743  open(OUTPUT) or die("Could not open file $OUTPUT");
1744 
1745  print OUTPUT <<EOF;
1746 <?xml version='1.0'?>
1747 
1748 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1749  that will be zipped together to create a detector description.
1750  -->
1751 
1752 <config>
1753 
1754  <constantfiles>
1755 
1756  <!-- These files contain GDML <constant></constant>
1757  blocks. They are read in separately, so they can be
1758  interpreted into the remaining GDML. See make_gdml.pl for
1759  more information.
1760  -->
1761 
1762 EOF
1763 
1764  foreach $filename (@defFiles)
1765  {
1766  print OUTPUT <<EOF;
1767  <filename> $filename </filename>
1768 EOF
1769  }
1770 
1771  print OUTPUT <<EOF;
1772 
1773  </constantfiles>
1774 
1775  <gdmlfiles>
1776 
1777  <!-- The GDML file fragments to be zipped together. -->
1778 
1779 EOF
1780 
1781  foreach $filename (@gdmlFiles)
1782  {
1783  print OUTPUT <<EOF;
1784  <filename> $filename </filename>
1785 EOF
1786  }
1787 
1788  print OUTPUT <<EOF;
1789 
1790  </gdmlfiles>
1791 
1792 </config>
1793 EOF
1794 
1795  close(OUTPUT);
1796 }
1797 
1798 
1799 print "Some of the principal parameters for this TPC geometry (unit cm unless noted otherwise)\n";
1800 print " CRM active area : $widthCRM_active x $lengthCRM_active\n";
1801 print " CRM total area : $widthCRM x $lengthCRM\n";
1802 print " Wire pitch in U, Y, Z : $wirePitchU, $wirePitchY, $wirePitchZ\n";
1803 print " TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1804 print " Argon volume : ($Argon_x, $Argon_y, $Argon_z) \n";
1805 print " Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1806 print " Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1807 print " TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1808 print " Field Cage : $FieldCage_switch \n";
1809 print " Cathode : $Cathode_switch \n";
1810 print " Workspace : $workspace \n";
1811 print " Wires : $wires_on \n";
1812 
1813 # run the sub routines that generate the fragments
1814 if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); }
1815 #if ( $Cathode_switch eq "on" ) { gen_Cathode(); } #Cathode for now has the same geometry as the Ground Grid
1816 
1817 gen_Extend(); # generates the GDML color extension for the refactored geometry
1818 gen_Define(); # generates definitions at beginning of GDML
1819 gen_Materials(); # generates materials to be used
1820 gen_TPC(); # generate TPC for a given unit CRM
1821 gen_Cryostat(); #
1822 gen_Enclosure(); #
1823 gen_World(); # places the enclosure among DUSEL Rock
1824 write_fragments(); # writes the XML input for make_gdml.pl
1825  # which zips together the final GDML
1826 print "--- done\n\n\n";
1827 exit;