generate_35t4apa.pl
Go to the documentation of this file.
1 #!/usr/bin/perl
2 
3 # Much of this program is taken straight from generate_gdml.pl that
4 # generates MicroBooNE fragment files (Thank you.)
5 
6 # Each subroutine generates a fragment GDML file, and the last subroutine
7 # creates an XML file that make_gdml.pl will use to appropriately arrange
8 # the fragment GDML files to create the final desired DUNE GDML file,
9 # to be named by make_gdml output command
10 
11 # If you are playing with different geometries, you can use the
12 # suffix command to help organize your work.
13 
14 use vars;
15 
16 use Math::Trig;
17 use Getopt::Long;
18 use Math::BigFloat;
19 Math::BigFloat->precision(-16);
20 
21 GetOptions( "help|h" => \$help,
22  "suffix|s:s" => \$suffix,
23  "output|o:s" => \$output,
24  "wires|w:s" => \$wires,
25  "helpcube|c" => \$helpcube);
26 
27 if ( defined $help )
28 {
29  # If the user requested help, print the usage notes and exit.
30  usage();
31  exit;
32 }
33 
34 if ( ! defined $suffix )
35 {
36  # The user didn't supply a suffix, so append nothing to the file
37  # names.
38  $suffix = "";
39 }
40 else
41 {
42  # Otherwise, stick a "-" before the suffix, so that a suffix of
43  # "test" applied to filename.gdml becomes "filename-test.gdml".
44  $suffix = "-" . $suffix;
45 }
46 
47 
48 
49 
50 #++++++++++++++++++++++++ Begin defining variables +++++++++++++++++++++++++
51 
52 # Define detector geometry variables - later to be put in a parameters
53 # XML file to be parsed as an input?
54 
55 # set wires on to be the default, unless given an input by the user
56 $wires_on = 1; # 1=on, 0=off
57 if (defined $wires)
58 {
59 $wires_on = $wires
60 }
61 
62 $tpc_on=1;
63 $inch = 2.54;
64 
65 
66 
67 #################################################
68 #### 4APA 35t parameters from DocDb 7550 ####
69 #################################################
70 
71 
72 
73 ##################################################################
74 ##################### wire plane parameters ######################
75 
76 $UWirePitch = .4888;
77 $VWirePitch = .5012;
78 $XWirePitch = .45;
79 
80 $UAng[0] = 45.707;
81 $VAng[0] = 44.275;
82 $UAng[1] = 45.707;
83 $VAng[1] = 44.275;
84 $UAng[2] = 45.707;
85 $VAng[2] = 44.275;
86 $UAng[3] = 45.707;
87 $VAng[3] = 44.275;
88 
89 #$UAng[0] = 36;
90 #$VAng[0] = 36;
91 #$UAng[3] = 36;
92 #$VAng[3] = 36;
93 
94 
95 
96 
97 ##################################################################
98 ######################## TPC parameters ##########################
99 
100 $LongDrift = 227;
101 $ShortDrift = 27;
102 $APAFrame_x = 2*$inch; #this does not include the wire spacing
103 $APAWirePlaneSpacing = 0.476; # center to center spacing between all of the wire planes (g, u, v, and x)
104 
105 $TPCWireThickness = 0.015;
106 $TPCWirePlaneThickness = $TPCWireThickness;
107 
108 $APA_z = 50.175;
109 
110 
111 # Let APAs be numbered as follows
112 # 0 & 3 - Largest
113 # 1 - Middle
114 # 2 - Smallest
115 
116 # Here are the APA heights indexed by APA number (lengths, z, are constant)
117 
118 $APAHeight[0] = 196.0;
119 $APAHeight[1] = 112.0;
120 $APAHeight[2] = 84.0;
121 $APAHeight[3] = $APAHeight[0];
122 
123 
124  # include APA spacing in y and z so volTPCs touch in y and z directions with correct APA
125  # spacing - this makes for smoother event generation.
126 
127 $TPCSmallestLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
128 $TPCSmallestLongDrift_y = $APAHeight[2] + $APAVerticalGap;
129 $TPCSmallestLongDrift_z = $APA_z + $APALongGap;
130 
131 $TPCMidLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
132 $TPCMidLongDrift_y = $APAHeight[1] + $APAVerticalGap;
133 $TPCMidLongDrift_z = $APA_z + $APALongGap;
134 
135 $TPCLargestLongDrift_x = $LongDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
136 $TPCLargestLongDrift_y = $APAHeight[0];
137 $TPCLargestLongDrift_z = $APA_z + $APALongGap;
138 
139 $TPCSmallestShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
140 $TPCSmallestShortDrift_y = $APAHeight[2] + $APAVerticalGap;
141 $TPCSmallestShortDrift_z = $APA_z + $APALongGap;
142 
143 $TPCMidShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
144 $TPCMidShortDrift_y = $APAHeight[1] + $APAVerticalGap;
145 $TPCMidShortDrift_z = $APA_z + $APALongGap;
146 
147 $TPCLargestShortDrift_x = $ShortDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
148 $TPCLargestShortDrift_y = $APAHeight[0];
149 $TPCLargestShortDrift_z = $APA_z + $APALongGap;
150 
151 
152 
153 ############################################################
154 ############### Optical Detector parameters ################
155 
156 # TODO: while the structure is exactly what we need, the parameters for
157 # paddle height and positioning are all placeholders
158 
159 $nPaddlesInAPA[0] = 3;
160 $nPaddlesInAPA[1] = 1;
161 $nPaddlesInAPA[2] = 1;
162 $nPaddlesInAPA[3] = $nPaddlesInAPA[0]; # for now, this one is the same as 0
163 
164 $SiPM_y = 0;
165 $LightPaddle_x = 0.476;
166 $LightPaddle_y = 56; # in cm from docDb 7803
167 $LightPaddle_z = 4*$inch;
168 
169 # z and x are given by APA frame center.
170 # Hardcode y distance of each paddle from the
171 # bottom of the APA to the paddle y-center.
172 # To be used in make_APA like [apa#][paddle#]
173 
174 $PaddleYPositions[0][0] = $APAHeight[0]/2; # this puts it in the y center
175 $PaddleYPositions[1][0] = $APAHeight[1] - 4*$inch - $LightPaddle_y/2;
176 $PaddleYPositions[2][0] = $APAHeight[2] - 4*$inch - $LightPaddle_y/2;
177 $PaddleYPositions[3][0] = $PaddleYPositions[0][0];
178 
179 $PaddleYPositions[0][1] = $APAHeight[0] - 4*$inch - $LightPaddle_y/2;
180 $PaddleYPositions[3][1] = $PaddleYPositions[0][1];
181 
182 $PaddleYPositions[0][2] = 4*$inch + $LightPaddle_y/2;
183 $PaddleYPositions[3][2] = $PaddleYPositions[0][2];
184 
185 
186 
187 ##################################################################
188 ###################### Cryostat parameters #######################
189 
190 # "Dead" LAr outside of the fiducial volume but inside the cryostat
191 $SpaceCPAToCryoWall = 10; #$SideLArPadding
192 $SpaceAPAToFloor = 10; #$BottomLArPadding
193 $SpaceAPAToTopLAr = 3.53; #$TopLArPadding
194 $HeightGaseousAr = 13.5; #$Height of Gaseous Ar region
195 $UpstreamLArPadding = 10;
196 $DownstreamLArPadding = 10;
197 
198 $APALongGap = 1.5; #separation between APAs along the incident beam axis
199 $APAVerticalGap = 2.5; #separation between APAs along the vertical axis
200 
201 $CPA_x = 5.08;
202 $CPA_y = ( $APAHeight[1]
203  + $APAVerticalGap
204  + $APAHeight[2] ) / 2;
205 $CPA_z = 77;
206 
207 # Liquid and Gaseous Argon dimensions
208 $Argon_x = $TPCLargestShortDrift_x
209  + $APAFrame_x
210  + $TPCLargestLongDrift_x
211  + 2*$CPA_x
212  + 2*$SpaceCPAToCryoWall;
213 $Argon_y = $APAHeight[1]
214  + $APAVerticalGap
215  + $APAHeight[2]
216  + $SpaceAPAToFloor
217  + $SpaceAPAToTopLAr
218  + $HeightGaseousAr; # assuming mid_y+smallest_y > largest_y
219 $Argon_z = 3*$APA_z + 2*$APALongGap
220  + $UpstreamLArPadding
221  + $DownstreamLArPadding;
222 
223 # Cryostat Dimensions
224 $SteelThickness = 0.5*$inch;
225 $Cryostat_x = $Argon_x+2*$SteelThickness;
226 $Cryostat_y = $Argon_y+2*$SteelThickness;
227 $Cryostat_z = $Argon_z+2*$SteelThickness;
228 
229 
230 
231 ##################################################################
232 ################# Detector Enclosure parameters ##################
233 
234 $ConcretePadding = 50;
235 $FoamPadding = 80;
236 $TotalPadding = $ConcretePadding+$FoamPadding;
237 $DetEnc_x = $Cryostat_x+2*$TotalPadding;
238 $DetEnc_y = $Cryostat_y+2*$TotalPadding-$FoamPadding; # no foam on bottom
239 $CryoInDetEnc_ypos = -$DetEnc_y/2 + $ConcretePadding + $Cryostat_y/2;
240 $DetEnc_z = $Cryostat_z+2*$TotalPadding;
241 
242  # We want the world origin to be at the very front of the fiducial volume.
243  # move it to the front of the enclosure, then back it up through the concrete/foam,
244  # then through the Cryostat shell, then through the upstream dead LAr (including the
245  # dead LAr on the edge of the TPC, but this is covered in $UpstreamLArPadding).
246  # This is to be added to the z position of every volume in volWorld
247 
248 $OriginZSet = $DetEnc_z/2
249  - $TotalPadding
250  - $SteelThickness
251  - $UpstreamLArPadding;
252 
253  # We want the world origin to be vertically centered between the two stacked APAs.
254  # (for now, that is, so the sorting works. this is quite asymetric, but then again
255  # so is the entire 35t geometry. this may be kept.)
256  # the cryostat sits on top of concrete padding, move the detector enclosure back
257  # and then move the world origin to the bottom of the smallest/lowest TPC, then
258  # and then up through the TPC, then back up to being centered between the stacked APAs.
259  # This is to be added to the y/x position of every volume in volWorld
260 
261 $OriginYSet = $DetEnc_y/2
262  - $ConcretePadding
263  - $SteelThickness
264  - $SpaceAPAToFloor
265  - $TPCSmallestShortDrift_y
266  - $APAVerticalGap/2;
267 
268 
269 
270 $OriginXSet = - $DetEnc_x/2
271  + $TotalPadding
272  + $SteelThickness
273  + $SpaceCPAToCryoWall
274  + $CPA_x
275  + $LongDrift;
276 
277 
278 $PosDirCubeSide = 0;
279 if (defined $helpcube)
280 {
281 $PosDirCubeSide = $ArToAr; #seems to be a good proportion
282 }
283 
284 
285 $World_x = 2*$DetEnc_x;
286 $World_y = 2*$DetEnc_y;
287 $World_z = 2*$DetEnc_z;
288 
289 
290 
291 
292 ##################################################################
293 ######################### CPA positions ##########################
294 
295 $posCPA0_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
296 $posCPA0_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
297 $posCPA0_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
298 
299 
300 $posCPA1_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
301 $posCPA1_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
302 $posCPA1_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
303 
304 
305 $posCPA2_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
306 $posCPA2_y = $Argon_y/2 - $SpaceAPAToTopLAr
307  - $HeightGaseousAr - $CPA_y/2;
308 $posCPA2_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
309 
310 
311 $posCPA3_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
312 $posCPA3_y = $Argon_y/2 - $SpaceAPAToTopLAr
313  - $HeightGaseousAr - $CPA_y/2;
314 $posCPA3_z = - $Argon_z/2 + $UpstreamLArPadding + $CPA_z/2;
315 
316 
317 $posCPA4_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
318 $posCPA4_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
319 $posCPA4_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
320 
321 
322 $posCPA5_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
323 $posCPA5_y = - $Argon_y/2 + $SpaceAPAToFloor + $CPA_y/2;
324 $posCPA5_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
325 
326 
327 $posCPA6_x = - $Argon_x/2 + $SpaceCPAToCryoWall + $CPA_x/2;
328 $posCPA6_y = $Argon_y/2 - $SpaceAPAToTopLAr
329  - $HeightGaseousAr - $CPA_y/2;
330 $posCPA6_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
331 
332 
333 $posCPA7_x = $Argon_x/2 - $SpaceCPAToCryoWall - $CPA_x/2;
334 $posCPA7_y = $Argon_y/2 - $SpaceAPAToTopLAr
335  - $HeightGaseousAr - $CPA_y/2;
336 $posCPA7_z = $Argon_z/2 - $DownstreamLArPadding - $CPA_z/2;
337 
338 
339 
340 
341 ##################################################################
342 ######################### TPC positions ##########################
343 
344 
345 
346 # Largest Short Drift
347 $posTPClsd_x = - $Argon_x/2
348  + $SpaceCPAToCryoWall
349  + $CPA_x
350  + $TPCLargestShortDrift_x/2;
351 $posTPClsd_y = $Argon_y/2
352  - $HeightGaseousAr
353  - $SpaceAPAToTopLAr
354  - $TPCLargestShortDrift_y/2;
355 
356 # Largest Long Drift
357 $posTPClld_x = $Argon_x/2
358  - $SpaceCPAToCryoWall
359  - $CPA_x
360  - $TPCLargestLongDrift_x/2;
361 $posTPClld_y = $Argon_y/2
362  - $HeightGaseousAr
363  - $SpaceAPAToTopLAr
364  - $TPCLargestLongDrift_y/2;
365 
366 $posTPCl_z_upstream = - $Argon_z/2
367  + $UpstreamLArPadding ## this steps into the APALongGap/2 space on outside of TPC...
368  + $APA_z/2;
369 $posTPCl_z_downstream = $Argon_z/2
370  - $DownstreamLArPadding ## ...as well as this
371  - $APA_z/2;
372 
373 
374 
375 # Smallest Long Drift
376 $posTPCsld_x = $Argon_x/2
377  - $SpaceCPAToCryoWall
378  - $CPA_x
379  - $TPCSmallestLongDrift_x/2;
380 $posTPCsld_y = - $Argon_y/2
381  + $SpaceAPAToFloor
382  + $APAHeight[2]/2;
383 $posTPCsld_z = $Argon_z/2
384  - $DownstreamLArPadding
385  - $APA_z
386  - $APALongGap
387  - $APA_z/2;
388 
389 # Mid Long Drift
390 $posTPCmld_x = $Argon_x/2
391  - $SpaceCPAToCryoWall
392  - $CPA_x
393  - $TPCMidLongDrift_x/2;
394 $posTPCmld_y = $Argon_y/2
395  - $HeightGaseousAr
396  - $SpaceAPAToTopLAr
397  - $APAHeight[1]/2;
398 $posTPCmld_z = $Argon_z/2
399  - $DownstreamLArPadding
400  - $APA_z
401  - $APALongGap
402  - $APA_z/2;
403 
404 
405 
406 # Smallest Short Drift
407 $posTPCssd_x = - $Argon_x/2
408  + $SpaceCPAToCryoWall
409  + $CPA_x
410  + $TPCSmallestShortDrift_x/2;
411 $posTPCssd_y = - $Argon_y/2
412  + $SpaceAPAToFloor
413  + $APAHeight[2]/2;
414 $posTPCssd_z = $Argon_z/2
415  - $DownstreamLArPadding
416  - $APA_z
417  - $APALongGap
418  - $APA_z/2;
419 
420 # Mid Short Drift
421 $posTPCmsd_x = - $Argon_x/2
422  + $SpaceCPAToCryoWall
423  + $CPA_x
424  + $TPCMidShortDrift_x/2;
425 $posTPCmsd_y = $Argon_y/2
426  - $HeightGaseousAr
427  - $SpaceAPAToTopLAr
428  - $APAHeight[1]/2;
429 $posTPCmsd_z = $Argon_z/2
430  - $DownstreamLArPadding
431  - $APA_z
432  - $APALongGap
433  - $APA_z/2;
434 
435 
436 
437 #TODO: define APA centers more fundamentally and then place TPC centers based off of this
438 $APA_Xcenter = $Argon_x/2
439  - $SpaceCPAToCryoWall
440  - $CPA_x
441  - $TPCLargestLongDrift_x
442  - $APAFrame_x/2;
443 
444 $APACenter[0][0] = $APA_Xcenter;
445 $APACenter[0][1] = $posTPClld_y;
446 $APACenter[0][2] = $posTPCl_z_upstream;
447 
448 $APACenter[1][0] = $APA_Xcenter;
449 $APACenter[1][1] = $posTPCmld_y;
450 $APACenter[1][2] = $posTPCmld_z;
451 
452 $APACenter[2][0] = $APA_Xcenter;
453 $APACenter[2][1] = $posTPCsld_y;
454 $APACenter[2][2] = $posTPCsld_z;
455 
456 $APACenter[3][0] = $APACenter[0][0];
457 $APACenter[3][1] = $APACenter[0][1];
458 $APACenter[3][2] = $posTPCl_z_downstream;
459 
460 
461 ################
462 
463 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
464 
465 
466 
467 # run the sub routines that generate the fragments
468 
469 gen_Define(); # generates definitions at beginning of GDML
470 gen_Materials(); # generates materials to be used
471 
472  # pass a name to gen_TPC that begins with TPC
473  gen_TPC( $TPCSmallestLongDrift_x, $TPCSmallestLongDrift_y, $TPCSmallestLongDrift_z, 'SmallestLongDrift', 1);
474  gen_TPC( $TPCMidLongDrift_x, $TPCMidLongDrift_y, $TPCMidLongDrift_z, 'MidLongDrift', 2);
475  gen_TPC( $TPCLargestLongDrift_x, $TPCLargestLongDrift_y, $TPCLargestLongDrift_z, 'LargestLongDrift', 0);
476 
477  gen_TPC( $TPCSmallestShortDrift_x, $TPCSmallestShortDrift_y, $TPCSmallestShortDrift_z, 'SmallestShortDrift', 1);
478  gen_TPC( $TPCMidShortDrift_x, $TPCMidShortDrift_y, $TPCMidShortDrift_z, 'MidShortDrift', 2) ;
479  gen_TPC( $TPCLargestShortDrift_x, $TPCLargestShortDrift_y, $TPCLargestShortDrift_z, 'LargestShortDrift', 0);
480 
481 
482 gen_Cryostat();
483 gen_Enclosure();
484 gen_World();
485 
486 
487 write_fragments(); # writes the XML input for make_gdml.pl
488  # which zips together the final GDML
489 exit;
490 
491 
492 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
493 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
494 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
495 
496 sub usage()
497 {
498  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
499  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
500  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
501  print " -h prints this message, then quits\n";
502 }
503 
504 
505 
506 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
507 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
508 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
509 
510 sub gen_Define()
511 {
512 
513 # Create the <define> fragment file name,
514 # add file to list of fragments,
515 # and open it
516  $DEF = "dune_10kT_Def" . $suffix . ".gdml";
517  push (@gdmlFiles, $DEF);
518  $DEF = ">" . $DEF;
519  open(DEF) or die("Could not open file $DEF for writing");
520 
521 
522 print DEF <<EOF;
523 <?xml version='1.0'?>
524 <gdml>
525 <define>
526 
527 <!--
528 
529 
530 -->
531 
532  <position name="posOriginSet" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
533 
534  <position name="posTPCLargestShortDrift_Pos" unit="cm" x="$posTPClsd_x" y="$posTPClsd_y" z="$posTPCl_z_downstream"/>
535  <position name="posTPCLargestLongDrift_Pos" unit="cm" x="$posTPClld_x" y="$posTPClld_y" z="$posTPCl_z_downstream"/>
536  <position name="posTPCLargestShortDrift_Neg" unit="cm" x="$posTPClsd_x" y="$posTPClsd_y" z="$posTPCl_z_upstream"/>
537  <position name="posTPCLargestLongDrift_Neg" unit="cm" x="$posTPClld_x" y="$posTPClld_y" z="$posTPCl_z_upstream"/>
538  <position name="posTPCSmallestShortDrift" unit="cm" x="$posTPCssd_x" y="$posTPCssd_y" z="$posTPCssd_z"/>
539  <position name="posTPCSmallestLongDrift" unit="cm" x="$posTPCsld_x" y="$posTPCsld_y" z="$posTPCsld_z"/>
540  <position name="posTPCMidShortDrift" unit="cm" x="$posTPCmsd_x" y="$posTPCmsd_y" z="$posTPCmsd_z"/>
541  <position name="posTPCMidLongDrift" unit="cm" x="$posTPCmld_x" y="$posTPCmld_y" z="$posTPCmld_z"/>
542 
543 
544  <position name="posCathode0" unit="cm" x="$posCPA0_x" y="$posCPA0_y" z="$posCPA0_z"/>
545  <position name="posCathode1" unit="cm" x="$posCPA1_x" y="$posCPA1_y" z="$posCPA1_z"/>
546  <position name="posCathode2" unit="cm" x="$posCPA2_x" y="$posCPA2_y" z="$posCPA2_z"/>
547  <position name="posCathode3" unit="cm" x="$posCPA3_x" y="$posCPA3_y" z="$posCPA3_z"/>
548  <position name="posCathode4" unit="cm" x="$posCPA4_x" y="$posCPA4_y" z="$posCPA4_z"/>
549  <position name="posCathode5" unit="cm" x="$posCPA5_x" y="$posCPA5_y" z="$posCPA5_z"/>
550  <position name="posCathode6" unit="cm" x="$posCPA6_x" y="$posCPA6_y" z="$posCPA6_z"/>
551  <position name="posCathode7" unit="cm" x="$posCPA7_x" y="$posCPA7_y" z="$posCPA7_z"/>
552 
553  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
554  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
555  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
556  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
557  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
558  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
559 </define>
560 </gdml>
561 EOF
562  close (DEF);
563 }
564 
565 
566 
567 
568 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
569 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
570 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
571 
572 sub gen_Materials()
573 {
574 
575 # Create the <materials> fragment file name,
576 # add file to list of output GDML fragments,
577 # and open it
578  $MAT = "dune_10kT_Materials" . $suffix . ".gdml";
579  push (@gdmlFiles, $MAT);
580  $MAT = ">" . $MAT;
581  open(MAT) or die("Could not open file $MAT for writing");
582 
583 
584  print MAT <<EOF;
585 <materials>
586  <element name="videRef" formula="VACUUM" Z="1"> <atom value="1"/> </element>
587  <element name="bromine" formula="Br" Z="35"> <atom value="79.904"/> </element>
588  <element name="hydrogen" formula="H" Z="1"> <atom value="1.0079"/> </element>
589  <element name="nitrogen" formula="N" Z="7"> <atom value="14.0067"/> </element>
590  <element name="oxygen" formula="O" Z="8"> <atom value="15.999"/> </element>
591  <element name="aluminum" formula="Al" Z="13"> <atom value="26.9815"/> </element>
592  <element name="silicon" formula="Si" Z="14"> <atom value="28.0855"/> </element>
593  <element name="carbon" formula="C" Z="6"> <atom value="12.0107"/> </element>
594  <element name="potassium" formula="K" Z="19"> <atom value="39.0983"/> </element>
595  <element name="chromium" formula="Cr" Z="24"> <atom value="51.9961"/> </element>
596  <element name="iron" formula="Fe" Z="26"> <atom value="55.8450"/> </element>
597  <element name="nickel" formula="Ni" Z="28"> <atom value="58.6934"/> </element>
598  <element name="calcium" formula="Ca" Z="20"> <atom value="40.078"/> </element>
599  <element name="magnesium" formula="Mg" Z="12"> <atom value="24.305"/> </element>
600  <element name="sodium" formula="Na" Z="11"> <atom value="22.99"/> </element>
601  <element name="titanium" formula="Ti" Z="22"> <atom value="47.867"/> </element>
602  <element name="argon" formula="Ar" Z="18"> <atom value="39.9480"/> </element>
603  <element name="sulphur" formula="S" Z="16"> <atom value="32.065"/> </element>
604  <element name="phosphorus" formula="P" Z="15"> <atom value="30.973"/> </element>
605 
606  <material name="Vacuum" formula="Vacuum">
607  <D value="1.e-25" unit="g/cm3"/>
608  <fraction n="1.0" ref="videRef"/>
609  </material>
610 
611  <material name="ALUMINUM_Al" formula="ALUMINUM_Al">
612  <D value="2.6990" unit="g/cm3"/>
613  <fraction n="1.0000" ref="aluminum"/>
614  </material>
615 
616  <material name="SILICON_Si" formula="SILICON_Si">
617  <D value="2.3300" unit="g/cm3"/>
618  <fraction n="1.0000" ref="silicon"/>
619  </material>
620 
621  <material name="epoxy_resin" formula="C38H40O6Br4">
622  <D value="1.1250" unit="g/cm3"/>
623  <composite n="38" ref="carbon"/>
624  <composite n="40" ref="hydrogen"/>
625  <composite n="6" ref="oxygen"/>
626  <composite n="4" ref="bromine"/>
627  </material>
628 
629  <material name="SiO2" formula="SiO2">
630  <D value="2.2" unit="g/cm3"/>
631  <composite n="1" ref="silicon"/>
632  <composite n="2" ref="oxygen"/>
633  </material>
634 
635  <material name="Al2O3" formula="Al2O3">
636  <D value="3.97" unit="g/cm3"/>
637  <composite n="2" ref="aluminum"/>
638  <composite n="3" ref="oxygen"/>
639  </material>
640 
641  <material name="Fe2O3" formula="Fe2O3">
642  <D value="5.24" unit="g/cm3"/>
643  <composite n="2" ref="iron"/>
644  <composite n="3" ref="oxygen"/>
645  </material>
646 
647  <material name="CaO" formula="CaO">
648  <D value="3.35" unit="g/cm3"/>
649  <composite n="1" ref="calcium"/>
650  <composite n="1" ref="oxygen"/>
651  </material>
652 
653  <material name="MgO" formula="MgO">
654  <D value="3.58" unit="g/cm3"/>
655  <composite n="1" ref="magnesium"/>
656  <composite n="1" ref="oxygen"/>
657  </material>
658 
659  <material name="Na2O" formula="Na2O">
660  <D value="2.27" unit="g/cm3"/>
661  <composite n="2" ref="sodium"/>
662  <composite n="1" ref="oxygen"/>
663  </material>
664 
665  <material name="TiO2" formula="TiO2">
666  <D value="4.23" unit="g/cm3"/>
667  <composite n="1" ref="titanium"/>
668  <composite n="2" ref="oxygen"/>
669  </material>
670 
671  <material name="FeO" formula="FeO">
672  <D value="5.745" unit="g/cm3"/>
673  <composite n="1" ref="iron"/>
674  <composite n="1" ref="oxygen"/>
675  </material>
676 
677  <material name="CO2" formula="CO2">
678  <D value="1.562" unit="g/cm3"/>
679  <composite n="1" ref="iron"/>
680  <composite n="2" ref="oxygen"/>
681  </material>
682 
683  <material name="P2O5" formula="P2O5">
684  <D value="1.562" unit="g/cm3"/>
685  <composite n="2" ref="phosphorus"/>
686  <composite n="5" ref="oxygen"/>
687  </material>
688 
689  <material formula=" " name="DUSEL_Rock">
690  <D value="2.82" unit="g/cm3"/>
691  <fraction n="0.5267" ref="SiO2"/>
692  <fraction n="0.1174" ref="FeO"/>
693  <fraction n="0.1025" ref="Al2O3"/>
694  <fraction n="0.0473" ref="MgO"/>
695  <fraction n="0.0422" ref="CO2"/>
696  <fraction n="0.0382" ref="CaO"/>
697  <fraction n="0.0240" ref="carbon"/>
698  <fraction n="0.0186" ref="sulphur"/>
699  <fraction n="0.0053" ref="Na2O"/>
700  <fraction n="0.00070" ref="P2O5"/>
701  <fraction n="0.0771" ref="oxygen"/>
702  </material>
703 
704  <material name="fibrous_glass">
705  <D value="2.74351" unit="g/cm3"/>
706  <fraction n="0.600" ref="SiO2"/>
707  <fraction n="0.118" ref="Al2O3"/>
708  <fraction n="0.001" ref="Fe2O3"/>
709  <fraction n="0.224" ref="CaO"/>
710  <fraction n="0.034" ref="MgO"/>
711  <fraction n="0.010" ref="Na2O"/>
712  <fraction n="0.013" ref="TiO2"/>
713  </material>
714 
715  <material name="FR4">
716  <D value="1.98281" unit="g/cm3"/>
717  <fraction n="0.47" ref="epoxy_resin"/>
718  <fraction n="0.53" ref="fibrous_glass"/>
719  </material>
720 
721  <material name="STEEL_STAINLESS_Fe7Cr2Ni" formula="STEEL_STAINLESS_Fe7Cr2Ni">
722  <D value="7.9300" unit="g/cm3"/>
723  <fraction n="0.0010" ref="carbon"/>
724  <fraction n="0.1792" ref="chromium"/>
725  <fraction n="0.7298" ref="iron"/>
726  <fraction n="0.0900" ref="nickel"/>
727  </material>
728 
729  <material name="LAr" formula="LAr">
730  <D value="1.40" unit="g/cm3"/>
731  <fraction n="1.0000" ref="argon"/>
732  </material>
733 
734  <material name="ArGas" formula="ArGas">
735  <D value="0.00166" unit="g/cm3"/>
736  <fraction n="1.0" ref="argon"/>
737  </material>
738 
739  <material formula=" " name="Air">
740  <D value="0.001205" unit="g/cm3"/>
741  <fraction n="0.781154" ref="nitrogen"/>
742  <fraction n="0.209476" ref="oxygen"/>
743  <fraction n="0.00934" ref="argon"/>
744  </material>
745 
746  <material formula=" " name="G10">
747  <D value="1.7" unit="g/cm3"/>
748  <fraction n="0.2805" ref="silicon"/>
749  <fraction n="0.3954" ref="oxygen"/>
750  <fraction n="0.2990" ref="carbon"/>
751  <fraction n="0.0251" ref="hydrogen"/>
752  </material>
753 
754  <material formula=" " name="Granite">
755  <D value="2.7" unit="g/cm3"/>
756  <fraction n="0.438" ref="oxygen"/>
757  <fraction n="0.257" ref="silicon"/>
758  <fraction n="0.222" ref="sodium"/>
759  <fraction n="0.049" ref="aluminum"/>
760  <fraction n="0.019" ref="iron"/>
761  <fraction n="0.015" ref="potassium"/>
762  </material>
763 
764  <material formula=" " name="ShotRock">
765  <D value="2.7*0.6" unit="g/cm3"/>
766  <fraction n="0.438" ref="oxygen"/>
767  <fraction n="0.257" ref="silicon"/>
768  <fraction n="0.222" ref="sodium"/>
769  <fraction n="0.049" ref="aluminum"/>
770  <fraction n="0.019" ref="iron"/>
771  <fraction n="0.015" ref="potassium"/>
772  </material>
773 
774  <material formula=" " name="Dirt">
775  <D value="1.7" unit="g/cm3"/>
776  <fraction n="0.438" ref="oxygen"/>
777  <fraction n="0.257" ref="silicon"/>
778  <fraction n="0.222" ref="sodium"/>
779  <fraction n="0.049" ref="aluminum"/>
780  <fraction n="0.019" ref="iron"/>
781  <fraction n="0.015" ref="potassium"/>
782  </material>
783 
784  <material formula=" " name="Concrete">
785  <D value="2.3" unit="g/cm3"/>
786  <fraction n="0.530" ref="oxygen"/>
787  <fraction n="0.335" ref="silicon"/>
788  <fraction n="0.060" ref="calcium"/>
789  <fraction n="0.015" ref="sodium"/>
790  <fraction n="0.020" ref="iron"/>
791  <fraction n="0.040" ref="aluminum"/>
792  </material>
793 
794  <material formula="H2O" name="Water">
795  <D value="1.0" unit="g/cm3"/>
796  <fraction n="0.1119" ref="hydrogen"/>
797  <fraction n="0.8881" ref="oxygen"/>
798  </material>
799 
800  <material formula="Ti" name="Titanium">
801  <D value="4.506" unit="g/cm3"/>
802  <fraction n="1." ref="titanium"/>
803  </material>
804 
805  <material name="TPB" formula="TPB">
806  <D value="1.40" unit="g/cm3"/>
807  <fraction n="1.0000" ref="argon"/>
808  </material>
809 
810  <material name="Glass">
811  <D value="2.74351" unit="g/cm3"/>
812  <fraction n="0.600" ref="SiO2"/>
813  <fraction n="0.118" ref="Al2O3"/>
814  <fraction n="0.001" ref="Fe2O3"/>
815  <fraction n="0.224" ref="CaO"/>
816  <fraction n="0.034" ref="MgO"/>
817  <fraction n="0.010" ref="Na2O"/>
818  <fraction n="0.013" ref="TiO2"/>
819  </material>
820 
821  <material name="Acrylic">
822  <D value="1.19" unit="g/cm3"/>
823  <fraction n="0.600" ref="carbon"/>
824  <fraction n="0.320" ref="oxygen"/>
825  <fraction n="0.080" ref="hydrogen"/>
826  </material>
827 
828 </materials>
829 EOF
830 
831 close(MAT);
832 }
833 
834 
835 
836 
837 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
838 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
839 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
840 
841 
842 sub gen_TPC()
843 {
844 
845 # $_[0] = $TPC_x
846 # $_[1] = $TPC_y
847 # $_[2] = $TPC_z
848 # $_[3] = 'name'
849 
850  my $TPCWirePlaneHeight = $_[1];
851  my $TPCWirePlaneLength = $_[2];
852 
853  my $TPCActive_x = $_[0]-(4*$APAWirePlaneSpacing);
854  my $TPCActive_y = $TPCWirePlaneHeight;
855  my $TPCActive_z = $TPCWirePlaneLength;
856 
857  my $UAngle = $UAng[$_[4]];
858  my $VAngle = $VAng[$_[4]];
859 
860  my $SinUAngle = sin( deg2rad($UAngle) );
861  my $CosUAngle = cos( deg2rad($UAngle) );
862  my $TanUAngle = tan( deg2rad($UAngle) );
863 
864  my $SinVAngle = sin( deg2rad($VAngle) );
865  my $CosVAngle = cos( deg2rad($VAngle) );
866  my $TanVAngle = tan( deg2rad($VAngle) );
867 
868  my $UWire_yint = $UWirePitch/$SinUAngle;
869  my $UWire_zint = $UWirePitch/$CosUAngle;
870 
871  my $VWire_yint = $VWirePitch/$SinVAngle;
872  my $VWire_zint = $VWirePitch/$CosVAngle;
873 
874 #constructs everything inside volTPC, namely
875 # (moving from left to right, or from +x to -x)
876 # -volCPA
877 # -volTPCPlaneU: with wires angled from vertical slightly different than in V
878 # -volTPCPlaneV: with wires angled from vertical slightly differently than in U
879 # -volTPCPlaneX: with vertical wires
880 
881 
882 # Create the TPC fragment file name,
883 # add file to list of output GDML fragments,
884 # and open it
885  $TPC = "35t_TPC_${_[3]}" . $suffix . ".gdml";
886  push (@gdmlFiles, $TPC);
887  $TPC = ">" . $TPC;
888  open(TPC) or die("Could not open file $TPC for writing");
889 
890 
891 # The standard XML prefix and starting the gdml
892  print TPC <<EOF;
893 <?xml version='1.0'?>
894 <gdml>
895 EOF
896 
897 
898 # All the TPC solids save the wires.
899 print TPC <<EOF;
900 <solids>
901  <box name="$_[3]" lunit="cm"
902  x="$_[0]"
903  y="$_[1]"
904  z="$_[2]"/>
905  <box name="${_[3]}Plane" lunit="cm"
906  x="$TPCWirePlaneThickness"
907  y="$TPCWirePlaneHeight"
908  z="$TPCWirePlaneLength"/>
909  <box name="${_[3]}Active" lunit="cm"
910  x="$TPCActive_x"
911  y="$TPCActive_y"
912  z="$TPCActive_z"/>
913 EOF
914 
915 
916 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
917 
918 print TPC <<EOF;
919 
920  <tube name="${_[3]}WireVert"
921  rmax="0.5*$TPCWireThickness"
922  z="$TPCWirePlaneHeight"
923  deltaphi="360"
924  aunit="deg"
925  lunit="cm"/>
926 EOF
927 
928 # Set number of wires to default to zero, when $wires_on = 0, for a low memory
929 # version. But if $wires_on = 1, calculate the number of wires on each side of each
930 # plane to be used in the for loops
931 
932 my $NumberCornerUWires = 0;
933 my $NumberSideUWires = 0;
934 my $NumberCommonUWires = 0;
935 my $NumberCornerVWires = 0;
936 my $NumberSideVWires = 0;
937 my $NumberCommonVWires = 0;
938 my $NumberVerticalWires = 0;
939 
940 if ($wires_on == 1)
941 {
942  # Number of wires in one corner
943 $NumberCornerUWires = int( $TPCWirePlaneLength/($UWirePitch/$CosUAngle) );
944 
945 $NumberCornerVWires = int( $TPCWirePlaneLength/($VWirePitch/$CosVAngle) );
946 
947  # Total number of wires touching one vertical (longer) side
948  # Note that the total number of wires per plane is this + another set of corner wires
949 $NumberSideUWires = int( $TPCWirePlaneHeight/($UWirePitch/$SinUAngle) );
950 
951 $NumberSideVWires = int( $TPCWirePlaneHeight/($VWirePitch/$SinVAngle) );
952 
953  # Number of wires per side that aren't cut off by the corner
954 $NumberCommonUWires = $NumberSideUWires - $NumberCornerUWires;
955 
956 $NumberCommonVWires = $NumberSideVWires - $NumberCornerVWires;
957 
958  # number of wires on the vertical plane
959 # TODO: 1 is a temporary safety!!
960 $NumberVerticalWires = int( ($TPCWirePlaneLength - $TPCWireThickness)/$XWirePitch );
961 }
962 
963 # The corner wires for the U plane
964 if ($wires_on==1)
965 {
966  for ($i = 0; $i < $NumberCornerUWires; ++$i)
967  {
968  # Subtraction to avoid corners of wires overlapping the TPCPlane sides,
969  # equal to 0.5*TCPWireThickness*($TanUAngle+1/$TanUAngle),
970  # allowing for 30deg<UAngle
971 
972  print TPC <<EOF;
973  <tube name="${_[3]}WireU$i"
974  rmax="0.5*$TPCWireThickness"
975  z="$UWirePitch*($TanUAngle+1/$TanUAngle)*($i+1)-0.01732"
976  deltaphi="360"
977  aunit="deg"
978  lunit="cm"/>
979 EOF
980 
981  }
982  # Next, the wire used many times in the middle of the U plane.
983  # Subtraction again to avoid wire corners overlapping, equal to
984  # 0.5*TCPWireThickness*2/$TanVAngle, allowing for 30deg<VAngle
985 
986  print TPC <<EOF;
987  <tube name="${_[3]}WireUCommon"
988  rmax="0.5*$TPCWireThickness"
989  z="$TPCWirePlaneLength/$SinUAngle-0.02598"
990  deltaphi="360"
991  aunit="deg"
992  lunit="cm"/>
993 EOF
994 
995 }
996 
997 
998 # The corner wires for the V plane
999 if ($wires_on==1)
1000 {
1001  for ($i = 0; $i < $NumberCornerVWires; ++$i)
1002  {
1003  # Same subtraction to avoid corners of wires overlapping
1004  # the TPCPlane sides
1005 
1006  print TPC <<EOF;
1007 
1008  <tube name="${_[3]}WireV$i"
1009  rmax="0.5*$TPCWireThickness"
1010  z="$VWirePitch*($TanVAngle+1/$TanVAngle)*($i+1)-0.01732"
1011  deltaphi="360"
1012  aunit="deg"
1013  lunit="cm"/>
1014 
1015 EOF
1016 
1017  }
1018 
1019  # The wire used many times in the middle of the V plane
1020  # Same subtraction as U common
1021 
1022  print TPC <<EOF;
1023  <tube name="${_[3]}WireVCommon"
1024  rmax="0.5*$TPCWireThickness"
1025  z="$TPCWirePlaneLength/$SinVAngle-0.02598"
1026  deltaphi="360"
1027  aunit="deg"
1028  lunit="cm"/>
1029 EOF
1030 
1031 }
1032 
1033 
1034 
1035 # Begin structure and create the vertical wire logical volume
1036 print TPC <<EOF;
1037 </solids>
1038 <structure>
1039  <volume name="volTPCActive${_[3]}">
1040  <materialref ref="LAr"/>
1041  <solidref ref="${_[3]}Active"/>
1042  </volume>
1043 
1044 EOF
1045 
1046 
1047 if ($wires_on==1)
1048 {
1049  print TPC <<EOF;
1050  <volume name="volTPCWireVert${_[3]}">
1051  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1052  <solidref ref="${_[3]}WireVert"/>
1053  </volume>
1054 EOF
1055 
1056  # Corner U wires logical volumes
1057  for ($i = 0; $i < $NumberCornerUWires; ++$i)
1058  {
1059  print TPC <<EOF;
1060  <volume name="volTPCWireU$i${_[3]}">
1061  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1062  <solidref ref="${_[3]}WireU$i"/>
1063  </volume>
1064 EOF
1065 
1066  }
1067 
1068  # Common U wire logical volume, referenced many times
1069  print TPC <<EOF;
1070  <volume name="volTPCWireUCommon${_[3]}">
1071  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1072  <solidref ref="${_[3]}WireUCommon"/>
1073  </volume>
1074 EOF
1075 
1076  # Corner V wires logical volumes
1077  for ($i = 0; $i < $NumberCornerVWires; ++$i)
1078  {
1079  print TPC <<EOF;
1080  <volume name="volTPCWireV$i${_[3]}">
1081  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1082  <solidref ref="${_[3]}WireV$i"/>
1083  </volume>
1084 EOF
1085 
1086  }
1087 
1088  # Common V wire logical volume, referenced many times
1089  print TPC <<EOF;
1090  <volume name="volTPCWireVCommon${_[3]}">
1091  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1092  <solidref ref="${_[3]}WireVCommon"/>
1093  </volume>
1094 EOF
1095 
1096 }
1097 
1098 
1099 
1100 
1101 #+++++++++++++++++++++++++ Position physical wires ++++++++++++++++++++++++++
1102 
1103 # ++++++++++++++++++++++ U Plane +++++++++++++++++++++++
1104 
1105 # Create U plane logical volume
1106 print TPC <<EOF;
1107  <volume name="volTPCPlaneU${_[3]}">
1108  <materialref ref="LAr"/>
1109  <solidref ref="${_[3]}Plane"/>
1110 EOF
1111 
1112 if ($wires_on==1)
1113 {
1114 
1115 # Starting with the bottom left corner wires:
1116  # x=0 to center the wires in the plane
1117  # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
1118  # from the bottom of the plane, and trigonometry gives the increment
1119  # z positioning: Looking at the plane from the positive x direction,
1120  # (0.5*$TPCWirePlaneLength) starts the incremental increase from
1121  # the lower left corner.
1122  # rotation: same as common wire in code below
1123 
1124 for ($i = 0; $i < $NumberCornerUWires; ++$i)
1125 {
1126 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($i+1)*$UWire_yint;
1127 my $zpos = (0.5*$TPCWirePlaneLength)-0.5*($i+1)*$UWire_zint;
1128 
1129 my $diff=(0.5*$TPCWirePlaneLength)-0.5*($NumberCornerUWires)*$UWire_zint;
1130 my $zpos=$zpos-$diff;
1131 
1132 print TPC <<EOF;
1133  <physvol>
1134  <volumeref ref="volTPCWireU$i${_[3]}"/>
1135  <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1136  <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1137  </physvol>
1138 EOF
1139 
1140 }
1141 
1142 
1143 # Moving upwards to the common wires:
1144  # x and z are zero to center the wires along a vertical axis
1145  # y positioning: The trick is positioning the lowest common wire so that the pitch
1146  # is consistent, then the increment is double the increment of
1147  # the corner wires since there is no z incriment.
1148  # rotation: wires in \\\\ direction, so +90deg to bring them to vertical and
1149  # +UAngle counterclockwise to arrive at proper orientation
1150 # Note that the counter maintains wire number (in pos. name) counting bottom to top
1151 
1152 for ($i = $NumberCornerUWires; $i < $NumberSideUWires; ++$i)
1153 {
1154 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerUWires)*$UWire_yint+($i+1-$NumberCornerUWires)*$UWire_yint;
1155 
1156 print TPC <<EOF;
1157  <physvol>
1158  <volumeref ref="volTPCWireUCommon${_[3]}"/>
1159  <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="0"/>
1160  <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1161  </physvol>
1162 EOF
1163 
1164 }
1165 
1166 
1167 # Finally moving to the corner wires on the top right:
1168  # x=0 to center the wires in the plane
1169  # y positioning: plug wire number into same equation
1170  # z positioning: start at z=0 and go negatively at the same z increment
1171  # rotation: same as common wire in code above
1172 # note that the counter maintains wire number shown in the position name
1173 
1174 for ($i = $NumberSideUWires; $i < $NumberSideUWires+$NumberCornerUWires-1; ++$i)
1175 {
1176  # Make a counter to recall the right logical volume reference:
1177  # We want the last U wire in this loop (the highest wire) to be the
1178  # first wire in the logical volume loop for U wires.
1179 
1180 $j = $NumberSideUWires+$NumberCornerUWires - $i - 2;
1181 
1182  # Note that since we are referencing the same logical volumes/same solids for
1183  # the top wires as well as the bottom, the pattern of "stacking" wire on top of wire
1184  # with an incremental separation is likely to cause the top corner wires to be a
1185  # a little shorter than they can be, but never any longer. There is no immediately
1186  # elegant way to fix this, but at 5mm pitch and around 45deg wire orientation, the
1187  # wires can be at most 1cm shorter than possible which is negligible until the top
1188  # 20 wires or so where 1cm is >5% of their length. This also means that there
1189  # could be one more space for a wire left over, but that is highly unlikely.
1190 
1191 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerUWires)*$UWire_yint+($NumberCommonUWires)*$UWire_yint+0.5*($i+1-$NumberSideUWires)*$UWire_yint;
1192 my $zpos = -0.5*($i+1-$NumberSideUWires)*$UWire_zint;
1193 
1194 print TPC <<EOF;
1195  <physvol>
1196  <volumeref ref="volTPCWireU$j${_[3]}"/>
1197  <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1198  <rotation name="rUAngle$i" unit="deg" x="90-$UAngle" y="0" z="0"/>
1199  </physvol>
1200 EOF
1201 
1202 }
1203 
1204 } #ends if wires on
1205 
1206 
1207 # ++++++++++++++++++++++ V Plane +++++++++++++++++++++++
1208 
1209 # End U plane and create V plane logical volume
1210 print TPC <<EOF;
1211  </volume>
1212 
1213  <volume name="volTPCPlaneV${_[3]}">
1214  <materialref ref="LAr"/>
1215  <solidref ref="${_[3]}Plane"/>
1216 EOF
1217 
1218 if ($wires_on==1)
1219 {
1220 
1221 
1222 # Starting with the bottom right corner wires:
1223  # x=0 to center the wires in the plane
1224  # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
1225  # from the bottom of the plane, and trigonometry gives the increment
1226  # z positioning: Looking at the plane from the positive x direction,
1227  # (-0.5*$TPCWirePlaneLength) starts the incremental increase from
1228  # the lower right corner.
1229  # rotation: same as common wire in code below
1230 
1231 for ($i = 0; $i < $NumberCornerVWires; ++$i)
1232 {
1233 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($i+1)*$VWire_yint;
1234 my $zpos = (-0.5*$TPCWirePlaneLength)+0.5*($i+1)*$VWire_zint;
1235 
1236 my $diff=(-0.5*$TPCWirePlaneLength)+0.5*($NumberCornerVWires)*$VWire_zint;
1237 my $zpos=$zpos-$diff;
1238 
1239 print TPC <<EOF;
1240  <physvol>
1241  <volumeref ref="volTPCWireV$i${_[3]}"/>
1242  <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1243  <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1244  </physvol>
1245 EOF
1246 
1247 }
1248 
1249 
1250 # Moving upwards to the common wires:
1251  # x and z are zero to center the wires along a vertical axis
1252  # y positioning: Plug wire number into the same corner ypos equation
1253  # rotation: wires in //// direction, so +90deg to bring them to vertical and
1254  # --VAngle counterclockwise to arrive at proper orientation
1255 # Note that the counter maintains wire number in the position name
1256 
1257 for ($i = $NumberCornerVWires; $i < $NumberSideVWires; ++$i)
1258 {
1259 my $ypos = (-0.5*$TPCWirePlaneHeight)-0.5*($NumberCornerVWires)*$VWire_yint+($i+1)*$VWire_yint;
1260 
1261 print TPC <<EOF;
1262  <physvol>
1263  <volumeref ref="volTPCWireVCommon${_[3]}"/>
1264  <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="0"/>
1265  <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1266  </physvol>
1267 EOF
1268 
1269 }
1270 
1271 
1272 # Finally moving to the corner wires on the top right:
1273  # x=0 to center the wires in the plane
1274  # y positioning: plug wire number into same equation
1275  # z positioning: start at z=0 and go positively at the same z increment
1276  # rotation: same as common wire in code above
1277 # note that the counter maintains wire number shown in the position name
1278 
1279 for ($i = $NumberSideVWires; $i < $NumberSideVWires+$NumberCornerVWires-1; ++$i)
1280 {
1281  # Make a counter to recall the right logical volume reference where the last
1282  # wire in this loop is the smallest, first wire in the logical volume loop, just as in U
1283 
1284 $j = $NumberSideVWires+$NumberCornerVWires - $i - 2;
1285 
1286  # Note that since we are referencing the same logical volumes/same solids for
1287  # the top wires as well as the bottom, the pattern of "stacking" wire on top of wire
1288  # with an incremental separation is likely to cause the top corner wires to be a
1289  # a little shorter than they can be, but never any longer. Just as in U
1290 
1291 my $ypos = (-0.5*$TPCWirePlaneHeight)+0.5*($NumberCornerVWires)*$VWire_yint+($NumberCommonVWires)*$VWire_yint+0.5*($i+1-$NumberSideVWires)*$VWire_yint;
1292 my $zpos = 0.5*($i+1-$NumberSideVWires)*$VWire_zint;
1293 
1294 print TPC <<EOF;
1295  <physvol>
1296  <volumeref ref="volTPCWireV$j${_[3]}"/>
1297  <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="$ypos " z="$zpos"/>
1298  <rotation name="rVAngle$i" unit="deg" x="90+$VAngle" y="0" z="0"/>
1299  </physvol>
1300 EOF
1301 }
1302 
1303 } #ends if wires on
1304 
1305 
1306 
1307 # ++++++++++++++++++++++ X Plane +++++++++++++++++++++++
1308 
1309 # End V plane and create X plane logical volume
1310 print TPC <<EOF;
1311  </volume>
1312 
1313  <volume name="volTPCPlaneX${_[3]}">
1314  <materialref ref="LAr"/>
1315  <solidref ref="${_[3]}Plane"/>
1316 EOF
1317 
1318 if ($wires_on==1)
1319 {
1320 
1321 # This is the simplest plane, one loop creates all of the wires
1322  # x and y position at zero to center the wires
1323  # z position: moving from front of detector to back, in the positive z direction,
1324  # starting at (-0.5*$TPCWirePlaneLength), the right side looking from
1325  # the +x direction
1326 
1327 for ($i=0; $i<$NumberVerticalWires; ++$i)
1328 {
1329 my $zpos = (-0.5*$TPCWirePlaneLength)+$XWirePitch*($i+0.5)+$TPCWireThickness/2;
1330 
1331 print TPC <<EOF;
1332  <physvol>
1333  <volumeref ref="volTPCWireVert${_[3]}"/>
1334  <position name="pos${_[3]}WireX$i" unit="cm" x="0" y="0 " z="$zpos"/>
1335  <rotationref ref="rPlus90AboutX"/>
1336  </physvol>
1337 EOF
1338 
1339 }
1340 
1341 } #ends if wires on
1342 
1343 print TPC <<EOF;
1344  </volume>
1345 EOF
1346 
1347 #+++++++++++++++++++++ Position physical wires Above +++++++++++++++++++++
1348 
1349 #wrap up the TPC file
1350 print TPC <<EOF;
1351  <volume name="volTPC${_[3]}">
1352  <materialref ref="LAr"/>
1353  <solidref ref="${_[3]}"/>
1354  <physvol>
1355  <volumeref ref="volTPCPlaneU${_[3]}"/>
1356  <position name="pos${_[3]}PlaneU" unit="cm" x="-($_[0]/2)+3*$APAWirePlaneSpacing" y="0" z="0"/>
1357  </physvol>
1358  <physvol>
1359  <volumeref ref="volTPCPlaneV${_[3]}"/>
1360  <position name="pos${_[3]}PlaneV" unit="cm" x="-($_[0]/2)+2*$APAWirePlaneSpacing" y="0" z="0"/>
1361  </physvol>
1362  <physvol>
1363  <volumeref ref="volTPCPlaneX${_[3]}"/>
1364  <position name="pos${_[3]}PlaneX" unit="cm" x="-($_[0]/2)+$APAWirePlaneSpacing" y="0" z="0"/>
1365  </physvol>
1366  <physvol>
1367  <volumeref ref="volTPCActive${_[3]}"/>
1368  <position name="pos${_[3]}Active" unit="cm" x="-($_[0]/2)+$APAWirePlaneSpacing + $TPCActive_x/2" y="0" z="0"/>
1369  </physvol>
1370  </volume>
1371 </structure>
1372 </gdml>
1373 EOF
1374 
1375  close(GDML);
1376 
1377 } #end of sub gen_TPC
1378 
1379 
1380 
1381 
1382 
1383 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1384 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1385 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1386 
1387 sub gen_Cryostat()
1388 {
1389 
1390 # Create the cryostat fragment file name,
1391 # add file to list of output GDML fragments,
1392 # and open it
1393  $CRYO = "35t_Cryostat" . $suffix . ".gdml";
1394  push (@gdmlFiles, $CRYO);
1395  $CRYO = ">" . $CRYO;
1396  open(CRYO) or die("Could not open file $CRYO for writing");
1397 
1398 
1399 # The standard XML prefix and starting the gdml
1400  print CRYO <<EOF;
1401 <?xml version='1.0'?>
1402 <gdml>
1403 EOF
1404 
1405 
1406 # All the cryostat solids.
1407 print CRYO <<EOF;
1408 <solids>
1409  <box name="Cryostat" lunit="cm"
1410  x="$Cryostat_x"
1411  y="$Cryostat_y"
1412  z="$Cryostat_z"/>
1413 
1414  <box name="ArgonInterior" lunit="cm"
1415  x="$Argon_x"
1416  y="$Argon_y"
1417  z="$Argon_z"/>
1418 
1419  <subtraction name="SteelShell">
1420  <first ref="Cryostat"/>
1421  <second ref="ArgonInterior"/>
1422  </subtraction>
1423 
1424  <box name="Cathode" lunit="cm"
1425  x="$CPA_x"
1426  y="$CPA_y"
1427  z="$CPA_z"/>
1428 
1429  <box name="LightPaddle" lunit="cm"
1430  x="$LightPaddle_x"
1431  y="$LightPaddle_y + $SiPM_y"
1432  z="$LightPaddle_z"/>
1433 
1434 EOF
1435 
1436 
1437  # Add APA frames and optical detectors (paddles)
1438  solid_APA( 0 );
1439  solid_APA( 1 );
1440  solid_APA( 2 );
1441  solid_APA( 3 );
1442 
1443 
1444 # Cryostat structure
1445 print CRYO <<EOF;
1446 </solids>
1447 <structure>
1448  <volume name="volSteelShell">
1449  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1450  <solidref ref="SteelShell"/>
1451  </volume>
1452 
1453  <volume name="volCathode">
1454  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1455  <solidref ref="Cathode"/>
1456  </volume>
1457 
1458  <volume name="volOpDetSensitive">
1459  <materialref ref="Acrylic"/>
1460  <solidref ref="LightPaddle"/>
1461  </volume>
1462 
1463 EOF
1464 
1465  vol_APA( 0 );
1466  vol_APA( 1 );
1467  vol_APA( 2 );
1468  vol_APA( 3 );
1469 
1470 print CRYO <<EOF;
1471 
1472  <volume name="volCryostat">
1473  <materialref ref="LAr"/>
1474  <solidref ref="Cryostat"/>
1475 
1476  <physvol>
1477  <volumeref ref="volSteelShell"/>
1478  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1479  </physvol>
1480 
1481 
1482  <physvol>
1483  <volumeref ref="volCathode"/>
1484  <positionref ref="posCathode0"/>
1485  </physvol>
1486  <physvol>
1487  <volumeref ref="volCathode"/>
1488  <positionref ref="posCathode1"/>
1489  </physvol>
1490  <physvol>
1491  <volumeref ref="volCathode"/>
1492  <positionref ref="posCathode2"/>
1493  </physvol>
1494  <physvol>
1495  <volumeref ref="volCathode"/>
1496  <positionref ref="posCathode3"/>
1497  </physvol>
1498 
1499  <physvol>
1500  <volumeref ref="volCathode"/>
1501  <positionref ref="posCathode4"/>
1502  </physvol>
1503  <physvol>
1504  <volumeref ref="volCathode"/>
1505  <positionref ref="posCathode5"/>
1506  </physvol>
1507  <physvol>
1508  <volumeref ref="volCathode"/>
1509  <positionref ref="posCathode6"/>
1510  </physvol>
1511  <physvol>
1512  <volumeref ref="volCathode"/>
1513  <positionref ref="posCathode7"/>
1514  </physvol>
1515 
1516 
1517  <!-- The Smallest APA -->
1518  <physvol>
1519  <volumeref ref="volTPCSmallestLongDrift"/>
1520  <positionref ref="posTPCSmallestLongDrift"/>
1521  <rotationref ref="rIdentity"/>
1522  </physvol>
1523  <physvol>
1524  <volumeref ref="volTPCSmallestShortDrift"/>
1525  <positionref ref="posTPCSmallestShortDrift"/>
1526  <rotationref ref="rPlus180AboutY"/>
1527  </physvol>
1528 
1529 EOF
1530 
1531 place_APA($APACenter[2][0], $APACenter[2][1], $APACenter[2][2], 2);
1532 
1533 
1534 
1535 print CRYO <<EOF;
1536  <!-- The Middle-sized APA -->
1537  <physvol>
1538  <volumeref ref="volTPCMidLongDrift"/>
1539  <positionref ref="posTPCMidLongDrift"/>
1540  <rotationref ref="rIdentity"/>
1541  </physvol>
1542  <physvol>
1543  <volumeref ref="volTPCMidShortDrift"/>
1544  <positionref ref="posTPCMidShortDrift"/>
1545  <rotationref ref="rPlus180AboutY"/>
1546  </physvol>
1547 
1548 EOF
1549 
1550 place_APA($APACenter[1][0], $APACenter[1][1], $APACenter[1][2], 1);
1551 
1552 
1553 
1554 print CRYO <<EOF;
1555  <!-- The Largest APAs, Upstream and Downstream -->
1556  <physvol>
1557  <volumeref ref="volTPCLargestLongDrift"/>
1558  <positionref ref="posTPCLargestLongDrift_Neg"/>
1559  <rotationref ref="rIdentity"/>
1560  </physvol>
1561  <physvol>
1562  <volumeref ref="volTPCLargestShortDrift"/>
1563  <positionref ref="posTPCLargestShortDrift_Neg"/>
1564  <rotationref ref="rPlus180AboutY"/>
1565  </physvol>
1566  <physvol>
1567  <volumeref ref="volTPCLargestLongDrift"/>
1568  <positionref ref="posTPCLargestLongDrift_Pos"/>
1569  <rotationref ref="rIdentity"/>
1570  </physvol>
1571  <physvol>
1572  <volumeref ref="volTPCLargestShortDrift"/>
1573  <positionref ref="posTPCLargestShortDrift_Pos"/>
1574  <rotationref ref="rPlus180AboutY"/>
1575  </physvol>
1576 
1577 EOF
1578 
1579 place_APA($APACenter[0][0], $APACenter[0][1], $APACenter[0][2], 0);
1580 place_APA($APACenter[3][0], $APACenter[3][1], $APACenter[3][2], 3);
1581 
1582 
1583 
1584 print CRYO <<EOF;
1585  </volume>
1586 </structure>
1587 </gdml>
1588 EOF
1589 
1590 close(CRYO);
1591 }
1592 
1593 
1594 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1595 #++++++++++++++++++++++++++++++++++++++ solid_APA ++++++++++++++++++++++++++++++++++++++++
1596 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1597 
1598 
1599 # Must be called only within gen_Cryostat(),
1600 
1601 
1602 # $_[0] = APA number
1603 # convention: 0 is Largest, 1 is Mid, 2 is Smallest
1604 
1605 sub solid_APA()
1606 {
1607 
1608  $APA_i = $_[0];
1609 
1610 ####################################################################
1611 ################# APA Frame and Paddle Dimensions ##################
1612 
1613  $APA_y = $APAHeight[$APA_i];
1614 
1615 $APAFrameZSide_x = $APAFrame_x;
1616 $APAFrameZSide_y = 4*$inch;
1617 $APAFrameZSide_z = $APA_z;
1618 
1619 $APAFrameYSide_x = $APAFrame_x;
1620 $APAFrameYSide_y = $APA_y-2*$APAFrameZSide_y;
1621 $APAFrameYSide_z = 4*$inch;
1622 
1623 # Two outer Y supports will sandwich the light paddles
1624 $APAFrameYOuterSupport_x = ($APAFrame_x-$LightPaddle_x)/2;
1625 $APAFrameYOuterSupport_y = $APA_y-2*$APAFrameZSide_y;
1626 $APAFrameYOuterSupport_z = 4*$inch;
1627 
1628 $EdgeFrameSteelThickness = 0.12*$inch;
1629 $InnerFrameSteelThickness = 0.062*$inch;
1630 
1631 
1632  print CRYO <<EOF;
1633  <box name="APAFrameYSideHollow\-$APA_i" lunit="cm"
1634  x="$APAFrameYSide_x-2*$EdgeFrameSteelThickness"
1635  y="$APAFrameYSide_y-2*$EdgeFrameSteelThickness"
1636  z="$APAFrameYSide_z"/>
1637  <box name="APAFrameYSideShell\-$APA_i" lunit="cm"
1638  x="$APAFrameYSide_x"
1639  y="$APAFrameYSide_y"
1640  z="$APAFrameYSide_z"/>
1641  <subtraction name="APAFrameYSide\-$APA_i">
1642  <first ref="APAFrameYSideShell\-$APA_i"/>
1643  <second ref="APAFrameYSideHollow\-$APA_i"/>
1644  <positionref ref="posCenter"/>
1645  <rotationref ref="rIdentity"/>
1646  </subtraction>
1647 
1648  <box name="APAFrameZSideHollow\-$APA_i" lunit="cm"
1649  x="$APAFrameZSide_x-2*$EdgeFrameSteelThickness"
1650  y="$APAFrameZSide_y-2*$EdgeFrameSteelThickness"
1651  z="$APAFrameZSide_z"/>
1652  <box name="APAFrameZSideShell\-$APA_i" lunit="cm"
1653  x="$APAFrameZSide_x"
1654  y="$APAFrameZSide_y"
1655  z="$APAFrameZSide_z"/>
1656  <subtraction name="APAFrameZSide\-$APA_i">
1657  <first ref="APAFrameZSideShell\-$APA_i"/>
1658  <second ref="APAFrameZSideHollow\-$APA_i"/>
1659  <positionref ref="posCenter"/>
1660  <rotationref ref="rIdentity"/>
1661  </subtraction>
1662 
1663  <box name="APAFrameYOuterSupport\-$APA_i" lunit="cm"
1664  x="$EdgeFrameSteelThickness"
1665  y="$APAFrameYOuterSupport_y"
1666  z="$APAFrameYOuterSupport_z"/>
1667 
1668 
1669 EOF
1670 
1671 }
1672 
1673 
1674 
1675 
1676 
1677 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1678 #++++++++++++++++++++++++++++++++++++++ vol_APA ++++++++++++++++++++++++++++++++++++++++
1679 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1680 
1681 
1682 # Must be called only within gen_Cryostat(),
1683 
1684 
1685 # $_[0] = x APA center
1686 # $_[1] = y APA center
1687 # $_[2] = z APA center
1688 # $_[3] = APA number
1689 # convention: 0 and 3 are Largest, 1 is Mid, 2 is Smallest
1690 
1691 sub vol_APA()
1692 {
1693 
1694  $APA_i = $_[0];
1695 
1696 print CRYO <<EOF;
1697 
1698  <volume name="volAPAFrameYSide\-$APA_i">
1699  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1700  <solidref ref="APAFrameYSide\-$APA_i"/>
1701  </volume>
1702 
1703  <volume name="volAPAFrameZSide\-$APA_i">
1704  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1705  <solidref ref="APAFrameZSide\-$APA_i"/>
1706  </volume>
1707 
1708  <volume name="volAPAFrameYOuterSupport\-$APA_i">
1709  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1710  <solidref ref="APAFrameYOuterSupport\-$APA_i"/>
1711  </volume>
1712 
1713 EOF
1714 
1715 }
1716 
1717 
1718 
1719 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1720 #++++++++++++++++++++++++++++++++++++++ place_APA ++++++++++++++++++++++++++++++++++++++++
1721 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1722 
1723 
1724 # Must be called only within gen_Cryostat(),
1725 
1726 
1727 # $_[0] = x APA center
1728 # $_[1] = y APA center
1729 # $_[2] = z APA center
1730 # $_[3] = APA number
1731 # convention: 0 and 3 are Largest, 1 is Mid, 2 is Smallest
1732 
1733 sub place_APA()
1734 {
1735 
1736  $APA_i = $_[3];
1737 
1738 ####################################################################
1739 ################# APA Frame and Paddle Dimensions ##################
1740 
1741  $APA_y = $APAHeight[$APA_i];
1742 
1743 $APAFrameZSide_x = $APAFrame_x;
1744 $APAFrameZSide_y = 4*$inch;
1745 $APAFrameZSide_z = $APA_z;
1746 
1747 $APAFrameYSide_x = $APAFrame_x;
1748 $APAFrameYSide_y = $APA_y-2*$APAFrameZSide_y;
1749 $APAFrameYSide_z = 4*$inch;
1750 
1751 # Two outer Y supports will sandwich the light paddles
1752 $APAFrameYOuterSupport_x = ($APAFrame_x-$LightPaddle_x)/2;
1753 $APAFrameYOuterSupport_y = $APA_y-2*$APAFrameZSide_y;
1754 $APAFrameYOuterSupport_z = 4*$inch;
1755 
1756 # if there were an inner support to fill the hole
1757 $APAFrameYInnerSupport_x = $LightPaddle_x;
1758 
1759 $EdgeFrameSteelThickness = 0.12*$inch;
1760 $InnerFrameSteelThickness = 0.062*$inch;
1761 
1762 #TODO: Place TPCs in here as well, but for now just do frames and paddles
1763 
1764 
1765 
1766  # First put in the frame
1767  print CRYO <<EOF;
1768  <!-- <physvol>
1769  <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1770  <position name="posAPAFrameYOuterSupportNeg\-$APA_i" unit="cm"
1771  x="$_[0] - ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1772  y="$_[1]"
1773  z="$_[2]"/>
1774  <rotationref ref="rIdentity"/>
1775  </physvol>
1776  <physvol>
1777  <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1778  <position name="posAPAFrameYOuterSupportPos\-$APA_i" unit="cm"
1779  x="$_[0] + ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1780  y="$_[1]"
1781  z="$_[2]"/>
1782  <rotationref ref="rIdentity"/>
1783  </physvol> -->
1784  <physvol>
1785  <volumeref ref="volAPAFrameYSide\-$APA_i"/>
1786  <position name="posAPAFrameYSideNeg\-$_[3]" unit="cm"
1787  x="$_[0]"
1788  y="$_[1]"
1789  z="$_[2] - $APA_z/2 + $APAFrameYSide_z/2"/>
1790  <rotationref ref="rIdentity"/>
1791  </physvol>
1792  <physvol>
1793  <volumeref ref="volAPAFrameYSide\-$APA_i"/>
1794  <position name="posAPAFrameYSidePos\-$_[3]" unit="cm"
1795  x="$_[0]"
1796  y="$_[1]"
1797  z="$_[2] + $APA_z/2 - $APAFrameYSide_z/2"/>
1798  <rotationref ref="rIdentity"/>
1799  </physvol>
1800  <physvol>
1801  <volumeref ref="volAPAFrameZSide\-$APA_i"/>
1802  <position name="posAPAFrameZSidePos\-$_[3]" unit="cm"
1803  x="$_[0]"
1804  y="$_[1] + $APA_y/2 - $APAFrameZSide_y/2"
1805  z="$_[2]"/>
1806  <rotationref ref="rIdentity"/>
1807  </physvol>
1808  <physvol>
1809  <volumeref ref="volAPAFrameZSide\-$APA_i"/>
1810  <position name="posAPAFrameZSideNeg\-$_[3]" unit="cm"
1811  x="$_[0]"
1812  y="$_[1] - $APA_y/2 + $APAFrameZSide_y/2"
1813  z="$_[2]"/>
1814  <rotationref ref="rIdentity"/>
1815  </physvol>
1816 
1817 EOF
1818 
1819 
1820  # Now loop through paddle y positions and place them
1821  for( $p=0; $p<$nPaddlesInAPA[$APA_i]; $p++ ){
1822 
1823 print CRYO <<EOF;
1824 
1825  <physvol>
1826  <volumeref ref="volOpDetSensitive"/>
1827  <position name="posPaddle\-$p\-APA\-$APA_i" unit="cm"
1828  x="$_[0]"
1829  y="$_[1] - $APAHeight[$APA_i]/2 + $PaddleYPositions[$APA_i][$p]"
1830  z="$_[2]"/>
1831  <rotationref ref="rIdentity"/>
1832  </physvol>
1833 
1834 EOF
1835 
1836  }
1837 
1838 }
1839 
1840 
1841 
1842 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1843 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1844 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1845 
1846 sub gen_Enclosure()
1847 {
1848 
1849 # Create the detector enclosure fragment file name,
1850 # add file to list of output GDML fragments,
1851 # and open it
1852  $ENCL = "35t_DetEnclosure" . $suffix . ".gdml";
1853  push (@gdmlFiles, $ENCL);
1854  $ENCL = ">" . $ENCL;
1855  open(ENCL) or die("Could not open file $ENCL for writing");
1856 
1857 
1858 # The standard XML prefix and starting the gdml
1859  print ENCL <<EOF;
1860 <?xml version='1.0'?>
1861 <gdml>
1862 EOF
1863 
1864 
1865 # All the detector enclosure solids.
1866 print ENCL <<EOF;
1867 <solids>
1868 
1869  <box name="DetEnclosure" lunit="cm"
1870  x="$DetEnc_x"
1871  y="$DetEnc_y"
1872  z="$DetEnc_z"/>
1873 
1874 </solids>
1875 EOF
1876 
1877 
1878 
1879 # Detector enclosure structure
1880  print ENCL <<EOF;
1881 <structure>
1882 
1883  <volume name="volDetEnclosure">
1884  <materialref ref="Concrete"/>
1885  <solidref ref="DetEnclosure"/>
1886  <physvol>
1887  <volumeref ref="volCryostat"/>
1888  <position name="posCryo" unit="cm" x="0" y="$CryoInDetEnc_ypos" z="0"/>
1889  </physvol>
1890  </volume>
1891 EOF
1892 
1893 print ENCL <<EOF;
1894 </structure>
1895 </gdml>
1896 EOF
1897 
1898 close(ENCL);
1899 }
1900 
1901 
1902 
1903 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1904 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1905 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1906 
1907 sub gen_World()
1908 {
1909 
1910 # Create the WORLD fragment file name,
1911 # add file to list of output GDML fragments,
1912 # and open it
1913  $WORLD = "35t_World" . $suffix . ".gdml";
1914  push (@gdmlFiles, $WORLD);
1915  $WORLD = ">" . $WORLD;
1916  open(WORLD) or die("Could not open file $WORLD for writing");
1917 
1918 
1919 # The standard XML prefix and starting the gdml
1920  print WORLD <<EOF;
1921 <?xml version='1.0'?>
1922 <gdml>
1923 EOF
1924 
1925 
1926 # All the World solids.
1927 print WORLD <<EOF;
1928 <solids>
1929  <box name="World" lunit="cm"
1930  x="$World_x"
1931  y="$World_y"
1932  z="$World_z"/>
1933 </solids>
1934 EOF
1935 
1936 # World structure
1937 print WORLD <<EOF;
1938 <structure>
1939  <volume name="volWorld" >
1940  <materialref ref="Air"/>
1941  <solidref ref="World"/>
1942  <physvol>
1943  <volumeref ref="volDetEnclosure"/>
1944  <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1945  </physvol>
1946  </volume>
1947 </structure>
1948 </gdml>
1949 EOF
1950 
1951 # make_gdml.pl will take care of <setup/>
1952 
1953 close(WORLD);
1954 }
1955 
1956 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1957 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1958 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1959 
1960 sub write_fragments()
1961 {
1962  # This subroutine creates an XML file that summarizes the the subfiles output
1963  # by the other sub routines - it is the input file for make_gdml.pl which will
1964  # give the final desired GDML file. Specify its name with the output option.
1965  # (you can change the name when running make_gdml)
1966 
1967  if ( ! defined $output )
1968  {
1969  $output = "-"; # write to STDOUT
1970  }
1971 
1972  # Set up the output file.
1973  $OUTPUT = ">" . $output;
1974  open(OUTPUT) or die("Could not open file $OUTPUT");
1975 
1976  print OUTPUT <<EOF;
1977 <?xml version='1.0'?>
1978 
1979 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1980  that will be zipped together to create a detector description.
1981  -->
1982 
1983 <config>
1984 
1985  <constantfiles>
1986 
1987  <!-- These files contain GDML <constant></constant>
1988  blocks. They are read in separately, so they can be
1989  interpreted into the remaining GDML. See make_gdml.pl for
1990  more information.
1991  -->
1992 
1993 EOF
1994 
1995  foreach $filename (@defFiles)
1996  {
1997  print OUTPUT <<EOF;
1998  <filename> $filename </filename>
1999 EOF
2000  }
2001 
2002  print OUTPUT <<EOF;
2003 
2004  </constantfiles>
2005 
2006  <gdmlfiles>
2007 
2008  <!-- The GDML file fragments to be zipped together. -->
2009 
2010 EOF
2011 
2012  foreach $filename (@gdmlFiles)
2013  {
2014  print OUTPUT <<EOF;
2015  <filename> $filename </filename>
2016 EOF
2017  }
2018 
2019  print OUTPUT <<EOF;
2020 
2021  </gdmlfiles>
2022 
2023 </config>
2024 EOF
2025 
2026  close(OUTPUT);
2027 }