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