generate_dune10kt_v4.pl
Go to the documentation of this file.
1 #!/usr/bin/perl
2 
3 # contact tylerdalion@gmail.com for any GDML/generate questions
4 # I would love to help!
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 warnings;
15 #use lib "gdmlMaterials";
16 use lib '.';
17 use gdmlMaterials;
18 #use gdmlMaterials::gen_Materials;
19 use Math::Trig;
20 use Getopt::Long;
21 use Math::BigFloat;
22 Math::BigFloat->precision(-16);
23 
24 open(my $wout, '>', 'gdmlWireCenters.txt');
25 
26 GetOptions( "help|h" => \$help,
27  "suffix|s:s" => \$suffix,
28  "output|o:s" => \$output,
29  "wires|w:s" => \$wires,
30  "protoDune|p:s" => \$protoDune,
31  "workspace|k:s" => \$workspace);
32 
33 if ( defined $help )
34 {
35  # If the user requested help, print the usage notes and exit.
36  usage();
37  exit;
38 }
39 
40 if ( ! defined $suffix )
41 {
42  # The user didn't supply a suffix, so append nothing to the file
43  # names.
44  $suffix = "";
45 }
46 else
47 {
48  # Otherwise, stick a "-" before the suffix, so that a suffix of
49  # "test" applied to filename.gdml becomes "filename-test.gdml".
50  $suffix = "-" . $suffix;
51 }
52 
53 if ( ! defined $workspace )
54 {
55  $workspace = 0;
56  if ( ! defined $protoDune )
57  {
58  $protoDune = 0;
59  print "\t\tCreating full geometry.\n";
60  }
61  elsif ( $protoDune == 1 )
62  {
63  print "\t\tCreating rough version of protoDUNE.\n";
64  }
65 }
66 elsif ( $workspace == 1)
67 {
68  print "\t\tCreating smaller (1x2x2-APA) workspace geometry.\n";
69 }
70 elsif ( $workspace == 2)
71 {
72  print "\t\tCreating 1x2x6-APA geometry.\n";
73 }
74 
75 # set wires on to be the default, unless given an input by the user
76 $wires_on = 1; # 1=on, 0=off
77 if (defined $wires)
78 {
79 $wires_on = $wires
80 }
81 
82 $tpc_on=1;
83 
84 $killOuterActive = 0;
85 
86 # options for different parameters
87 $Pitch3mmVersion = 0;
88 $UVAngle45Option = 0;
89 
90 
91 
92 #++++++++++++++++++++++++ Begin defining variables +++++++++++++++++++++++++
93 
94 ## The GDML is build from the inside out to avoid overlaps, but that means
95 ## that the larger dimensions (such as the cryostat dimensions) are calculated
96 ## to be slightly different than the parameters calculated and reported by
97 ## engineers. All of this error is within reason and for the better, since
98 ## we don't want this Geometry to be overly complex or long.
99 
100 
101 $inch = 2.54;
102 
103 ##################################################################
104 ##################### Wire Plane Parameters ######################
105 
106 # dune10kt
107 $UWirePitch = 0.4667;
108 $VWirePitch = 0.4667;
109 $XWirePitch = 0.479;
110 $UAngle = 35.710;
111 $VAngle = 35.710;
112 $nZChannelsPerAPA = 960;
113 
114 # dune10kt 3mm version
115 if($Pitch3mmVersion==1){
116  $UWirePitch = 0.3;
117  $VWirePitch = 0.3;
118  $XWirePitch = 0.3;
119  $nZChannelsPerAPA = 2*(229.44/0.3 + 1);
120 }
121 
122 # dune10kt ~45 deg UV wires version
123 if($UVAngle45Option==1){
124  $UAngle = 45.7;
125  $VAngle = 44.3;
126 }
127 
128 $nAPAWide = 3;
129 $nAPAHigh = 2;
130 $nAPALong = 25;
131 
132 if($protoDune==1){
133  $nAPAWide = 2;
134  $nAPAHigh = 1;
135  $nAPALong = 3;
136 }
137 
138 $SinUAngle = sin( deg2rad($UAngle) );
139 $CosUAngle = cos( deg2rad($UAngle) );
140 $TanUAngle = tan( deg2rad($UAngle) );
141 
142 $SinVAngle = sin( deg2rad($VAngle) );
143 $CosVAngle = cos( deg2rad($VAngle) );
144 $TanVAngle = tan( deg2rad($VAngle) );
145 
146 $UWire_yint = $UWirePitch/$SinUAngle;
147 $UWire_zint = $UWirePitch/$CosUAngle;
148 
149 $VWire_yint = $VWirePitch/$SinVAngle;
150 $VWire_zint = $VWirePitch/$CosVAngle;
151 
152 $TPCWireThickness = 0.015;
153 
154 $TPCWirePlaneThickness = $TPCWireThickness;
155 #height and length defined lower
156 
157 
158 
159 ##################################################################
160 ################### Cryostat/APA parameters ######################
161 
162 if($workspace==1){
163  $nAPAWide = 1;
164  $nAPALong = 2;
165 }
166 elsif($workspace==2){
167  $nAPAWide = 1;
168  $nAPALong = 6;
169 }
170 
171 $nAPAs = $nAPAWide*$nAPAHigh*$nAPALong;
172 
173 
174 $G10thickness = $inch/8;
175 $WrapCover = $inch/16;
176 
177 $SpaceAPAToCryoWall = 15;
178 $SpaceAPAToFloor = 59.4 - 10.2; # 10.2cm just adjusts for how spaces are reported
179 $SpaceAPAToTopLAr = 50.9 - 10.2;
180 $UpstreamLArPadding = 311.4 - 10.2;
181 $DownstreamLArPadding = 59.4 - 10.2;
182 
183 if($protoDune==1){
184  $SpaceAPAToCryoWall = 20;
185  $SpaceAPAToFloor = 45;
186  $SpaceAPAToTopLAr = 45;
187  $UpstreamLArPadding = 80;
188  $DownstreamLArPadding = 80;
189 }
190 
191  #InnerDrift is the max distance form the edge of the CPA to the edge of the first wire plane
192 $InnerDrift = 359.4;
193 $OuterDrift = $SpaceAPAToCryoWall;
194 $APAFrame_x = 5.0661; # ~2in -- this does not include the wire spacing
195 
196 $TPCWireThickness = 0.015;
197 $TPCWirePlaneThickness = $TPCWireThickness;
198 #$APAWirePlaneSpacing = 0.4730488 + $TPCWirePlaneThickness; # center to center spacing between all of the wire planes (g, u, v, and x)
199 
200 if($Pitch3mmVersion==1){
201  $APAWirePlaneSpacing = 0.3;
202 } else {
203  $APAWirePlaneSpacing = 0.476;
204 }
205 
206 # At creation of the plane volumes, the y and z boundaries will be increased
207 # by this much at each of the 4 edges. this is so the corners of the wire
208 # tubes don't extrude. For all other purposes, the plane dimensions stay as originally defined
209 $UVPlaneBoundNudge = $TPCWireThickness;
210 
211 
212 # APA z-dimensions:
213 # The following are all widths about the z center of an APA
214 $Zactive_z = ($nZChannelsPerAPA/2-1)*$XWirePitch + $TPCWireThickness;
215 $APAFrame_z = 231.59 - 2*(2*$G10thickness+$WrapCover);
216 $Vactive_z = $APAFrame_z;
217 $Uactive_z = $APAFrame_z + 2*$G10thickness;
218 $APAphys_z = 231.59;
219 
220 
221 # APA y-dimensions:
222 $ReadoutBoardOverlap = 7.61; #board overlaps wires, chop this off of their active height
223 $APAFrame_y = 606.0;
224 $Zactive_y = $APAFrame_y + 0*$G10thickness - $ReadoutBoardOverlap;
225 $Vactive_y = $APAFrame_y + 1*$G10thickness - $ReadoutBoardOverlap;
226 $Uactive_y = $APAFrame_y + 2*$G10thickness - $ReadoutBoardOverlap;
227  # the last G10 board for the grid, then a cover. This is not "covered" by the board
228 $APAphys_y = $APAFrame_y + 4*$G10thickness + $WrapCover;
229 
230 $APAGap_y = 0.4; #separation between APAs (cover to cover) along the incident beam axis
231 $APAGap_z = 0.8; #separation between APAs (cover to cover) along the vertical axis
232 
233 
234  # include APA spacing in y and z so volTPCs touch in y and z directions with correct APA
235  # spacing - this makes for smoother event generation.
236 
237 $APA_UtoU_x = $APAFrame_x + 6*$APAWirePlaneSpacing + $TPCWirePlaneThickness; # thickness of APA between its
238  # outer wire planes (center to center)
239 $TPCInner_x = $InnerDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
240 $TPCOuter_x = $OuterDrift + 3*$APAWirePlaneSpacing + $TPCWirePlaneThickness;
241 
242 $TPC_z = $APAphys_z + $APAGap_z;
243 $TPC_y = $APAphys_y + $APAGap_y;
244 
245 $CPATube_OD = 5.066;
246 #$CPATube_ID = 4.747;
247 
248 $Cathode_x = 0.016;
249 $Cathode_y = $APAphys_y - $CPATube_OD;
250 $Cathode_z = $APAphys_z - $CPATube_OD;
251 
252 
253 $APAToAPA = $APAFrame_x
254  + 2*$TPCInner_x
255  + $Cathode_x; # center to center
256 
257 $CPAToAPA = $APAFrame_x/2
258  + $TPCInner_x
259  + $Cathode_x/2; # center to center
260 
261 $SteelThickness = 0.5*$inch; #half inch
262 $HeightGaseousAr = 50;
263 
264 $Argon_x = ($nAPAWide-1)*$APAToAPA
265  + $APA_UtoU_x + $TPCWirePlaneThickness
266  + 2*$SpaceAPAToCryoWall;
267 
268 
269 #FIELD CAGE IN (FCI)
270 $FC_x = ($nAPAWide-1)*$APAToAPA
271  + $APA_UtoU_x + $TPCWirePlaneThickness;
272 
273 if($workspace==1||$workspace==2){ # this is arbitrary for the workspace, but size down a little
274 $Argon_x = 2*$CPAToAPA + $Cathode_x + 2*$SpaceAPAToCryoWall;
275 $FC_x = 2*$CPAToAPA + $Cathode_x;
276 }
277 
278 
279 $LArgon_y = $nAPAHigh*$APAphys_y
280  + ($nAPAHigh-1)*$APAGap_y
281  + $SpaceAPAToFloor + $SpaceAPAToTopLAr;
282 $Argon_y = $LArgon_y
283  + $HeightGaseousAr;
284 
285 $Argon_z = $nAPALong*$APAphys_z
286  + ($nAPALong-1)*$APAGap_z
287  + $UpstreamLArPadding + $DownstreamLArPadding;
288 
289 $FCI_y = $nAPAHigh*$TPC_y+$FC_b; #The +FC_b is an arbitrary +2cm to make sure the FC doesn't contact the APA or CPAs.
290 $FCO_y = $FCI_y+(0.1*$inch)*2; #The outer boundary of the Fied Cage
291 $FCI_z = $nAPALong*$TPC_z
292  + $FC_b; #the plus FC_b is +2 cm arbitrarily. This makes sure the FC doesn't contact the APAs.
293 $FCO_z = $FCI_z+(0.1*$inch)*2;
294 
295 $FC_b = 2; #2 cm buffer for FC
296 
297 $Cryostat_x = $Argon_x + 2*$SteelThickness;
298 $Cryostat_y = $Argon_y + 2*$SteelThickness;
299 $Cryostat_z = $Argon_z + 2*$SteelThickness;
300 
301 ### Add dimensions for the source cylinder.
302 $Source_x_center = $FC_x_center + 220; # 220 cm past the center plane of the TPCs.
303 $Source_y_center = $FC_y_center + 300 -20 ; # 300 cm above the center of the active volume (-20 unexplained correction taken from viewer.
304 $Source_z_center = $FC_z_center - ($FCO_z/2) - 40+ 130; # 40 cm outside the field cage in Z. (+130 unexplained correction from viewer.
305 $SourceModerator_d = 20; #20 cm diameter cylinder
306 $SourceModerator_z = 20; # 20 cm tall cylinder
307 
308 ##TO DO.
309 #Make Source VolumeReference
310 #Make Source position reference.
311 #Make SourceModerator
312 #Make Source child of Source Moderator
313 
314 ##################################################################
315 ############## DetEnc and World relevant parameters #############
316 
317 
318 $SteelSupport_x = 100;
319 $SteelSupport_y = 50;
320 $SteelSupport_z = 100;
321 $FoamPadding = 80;
322 $FracMassOfSteel = 0.998; #The steel support is not a solid block, but a mixture of air and steel
323 $FracMassOfAir = 1-$FracMassOfSteel;
324 
325 $SpaceSteelSupportToWall = 100;
326 $SpaceSteelSupportToCeiling = 100;
327 
328 $DetEncWidth = $Cryostat_x
329  + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
330 $DetEncHeight = $Cryostat_y
331  + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
332 $DetEncLength = $Cryostat_z
333  + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
334 
335 $posCryoInDetEnc_y = - $DetEncHeight/2 + $SteelSupport_y + $FoamPadding + $Cryostat_y/2;
336 
337 $RockThickness = 3000;
338 if ($workspace == 0){
339  # Initially, the world dimensions and the OriginZSet
340  # left only ~222cm to the world boundary from the
341  # +z boundary of volDetEnclosure. Bump that up to
342  # at least 10m for good measure.
343  # This is in an if statement so that it does not affect
344  # the workspace geometries, which are already being used
345  $RockThickness += 800
346 }
347 
348  # We want the world origin to be at the very front of the fiducial volume.
349  # move it to the front of the enclosure, then back it up through the concrete/foam,
350  # then through the Cryostat shell, then through the upstream dead LAr (including the
351  # dead LAr on the edge of the TPC, but this is covered in $UpstreamLArPadding).
352  # This is to be added to the z position of every volume in volWorld
353 
354 $OriginZSet = $DetEncLength/2
355  - $SpaceSteelSupportToWall
356  - $SteelSupport_z
357  - $FoamPadding
358  - $SteelThickness
359  - $UpstreamLArPadding
360  - ($APAphys_z - $Uactive_z)/2;
361 
362  # We want the world origin to be vertically centered between the stacked APAs.
363  # This is to be added to the y position of every volume in volWorld
364 
365 $OriginYSet = $DetEncHeight/2
366  - $SteelSupport_y
367  - $FoamPadding
368  - $SteelThickness
369  - $SpaceAPAToFloor
370  - $APAphys_y
371  - $APAGap_y/2;
372 
373 if($protoDune==1){ # bring the origin to the bottom of the APAs for protoDUNE
374  $OriginYSet = $OriginYSet + $APAphys_y + $APAGap_y/2;
375 }
376 
377 $OriginXSet = 0; # centered for now
378 
379 
380 
381 
382 
383 
384 ####################################################################
385 ############### Double Sided Arapuca Dimensions ###################
386 
387 $APAFrameZSide_y = 4*$inch;
388 $APAFrameYSide_z = 4*$inch;
389 
390 $ArapucaOut_x = 2.3;
391 $ArapucaOut_y = 11.8;
392 $ArapucaOut_z = 209.2;
393 #$ArapucaOut_z = $APAFrame_z - 2*$APAFrameYSide_z;
394 $ArapucaIn_x = 2.4;
395 $ArapucaIn_y = 9.3;
396 $ArapucaIn_z = 46.8;
397 $ArapucaAcceptanceWindow_x = 2.2;
398 $ArapucaAcceptanceWindow_y = 9.3;
399 $ArapucaAcceptanceWindow_z = 46.8;
400 $gapCenter_arapuca_z = 16.0;
401 $gapBetween_arapuca_z = 2.0;
402 
403 $list_pos[0]=-0.5*$gapCenter_arapuca_z-1.5*$ArapucaIn_z-$gapBetween_arapuca_z;
404 $list_pos[1]=$list_pos[0]+$ArapucaIn_z+$gapBetween_arapuca_z;
405 $list_pos[2]=0.5*$gapCenter_arapuca_z+0.5*$ArapucaIn_z;
406 $list_pos[3]=$list_pos[2]+$ArapucaIn_z+$gapBetween_arapuca_z;
407 
408 $nLightPaddlesPerAPA = 10; # 10, or 20 for double coverage (for now)
409 $PaddleYInterval = (2*$APAphys_y+$APAGap_y-$ArapucaOut_y-2*$APAFrameZSide_y)
410  /(2*$nLightPaddlesPerAPA-1);
411 $FrameToPaddleSpace = ($PaddleYInterval-$APAGap_y)/2;
412 
413 
414 # $PaddleYInterval is defined so that the center-to-center distance in the
415 # y direction between paddles is uniform between vertically stacked APAs.
416 # $FrameToPaddleSpace is from the BOTTOM of the APA frame (4" in y direction)
417 # to the CENTER of a paddle, including the 4" part of the frame. This variable's
418 # primary purpose is to position the lowest paddle in each APA.
419 
420 
421 
422 
423 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
424 
425 
426 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
427 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
428 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
429 
430 sub usage()
431 {
432  print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
433  print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
434  print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
435  print " -h prints this message, then quits\n";
436 }
437 
438 
439 
440 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
441 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
442 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
443 
444 sub gen_Define()
445 {
446 
447 # Create the <define> fragment file name,
448 # add file to list of fragments,
449 # and open it
450  $DEF = "dune10kt_v4_Def" . $suffix . ".gdml";
451  push (@gdmlFiles, $DEF);
452  $DEF = ">" . $DEF;
453  open(DEF) or die("Could not open file $DEF for writing");
454 
455 
456 print DEF <<EOF;
457 <?xml version='1.0'?>
458 <gdml>
459 <define>
460 
461 <!--
462 
463 
464 
465 -->
466 
467  <position name="posCryoInDetEnc" unit="cm" x="0" y="@{[$posCryoInDetEnc_y]}" z="0"/>
468  <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
469  <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
470  <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
471  <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
472  <rotation name="rPlusUAngleAboutX" unit="deg" x="@{[90-$UAngle]}" y="0" z="0"/>
473  <rotation name="rPlusVAngleAboutX" unit="deg" x="@{[90+$VAngle]}" y="0" z="0"/>
474  <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
475  <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
476  <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
477  <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
478  <position name="posArapucaSub0" unit="cm" x="0" y="0" z="@{[$list_pos[0]]}"/>
479  <position name="posArapucaSub1" unit="cm" x="0" y="0" z="@{[$list_pos[1]]}"/>
480  <position name="posArapucaSub2" unit="cm" x="0" y="0" z="@{[$list_pos[2]]}"/>
481  <position name="posArapucaSub3" unit="cm" x="0" y="0" z="@{[$list_pos[3]]}"/>
482 </define>
483 </gdml>
484 EOF
485  close (DEF);
486 }
487 
488 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
489 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
490 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
491 
492 sub gen_Materials()
493 {
494 
495 # Create the <materials> fragment file name,
496 # add file to list of output GDML fragments,
497 # and open it
498  $MAT = "dune10kt_v4_Materials" . $suffix . ".gdml";
499  push (@gdmlFiles, $MAT);
500  $MAT = ">" . $MAT;
501 
502  open(MAT) or die("Could not open file $MAT for writing");
503 
504  # Add any materials special to this geometry by defining a mulitline string
505  # and passing it to the gdmlMaterials::gen_Materials() function.
506 
507  $DensityAirSteel = 1/(0.001205/$FracMassOfAir + 7.9300/$FracMassOfSteel);
508 
509 my $asmix = <<EOF;
510  <!-- preliminary values -->
511  <material name="AirSteelMixture" formula="AirSteelMixture">
512  <D value="$DensityAirSteel" unit="g/cm3"/>
513  <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
514  <fraction n="$FracMassOfAir" ref="Air"/>
515  </material>
516 EOF
517 
518  # add the general materials used anywere
519  print MAT gdmlMaterials::gen_Materials( $asmix );
520 
521  close(MAT);
522 }
523 
524 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
525 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
526 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
527 
528 
529 sub gen_TPC
530 {
531 
532 # $_[0] = $TPC_x
533 # $_[1] = $TPC_y
534 # $_[2] = $TPC_z
535 # $_[3] = 'name'
536 
537  my $TPCActive_x = $_[0]-(3*$APAWirePlaneSpacing);
538  my $TPCActive_y = $_[1] - $APAGap_y/2 - $ReadoutBoardOverlap ; #TODO: make the Active height more accurate
539  my $TPCActive_z = $_[2];
540 
541 
542 #constructs everything inside volTPC, namely
543 # (moving from left to right, or from +x to -x)
544 # -volCPActive
545 # -volTPCPlaneU: with wires angled from vertical slightly different than in V
546 # -volTPCPlaneV: with wires angled from vertical slightly differently than in U
547 # -volTPCPlaneX: with vertical wires
548 
549 
550 # Create the TPC fragment file name,
551 # add file to list of output GDML fragments,
552 # and open it
553  $TPC = "dune10kt_v4_TPC_${_[3]}" . $suffix . ".gdml";
554  push (@gdmlFiles, $TPC);
555  $TPC = ">" . $TPC;
556  open(TPC) or die("Could not open file $TPC for writing");
557 
558 
559 print $wout "\n\n\n----- Wires for $_[3] -----\n\n\n";
560 
561 
562 # The standard XML prefix and starting the gdml
563  print TPC <<EOF;
564 <?xml version='1.0'?>
565 <gdml>
566 EOF
567 
568 
569 # All the TPC solids save the wires.
570 print TPC <<EOF;
571 <solids>
572  <box name="$_[3]" lunit="cm"
573  x="@{[$_[0]]}"
574  y="@{[$_[1]]}"
575  z="@{[$_[2]]}"/>
576  <box name="${_[3]}UPlane" lunit="cm"
577  x="@{[$TPCWirePlaneThickness]}"
578  y="@{[$Uactive_y + $UVPlaneBoundNudge]}"
579  z="@{[$Uactive_z + $UVPlaneBoundNudge]}"/>
580  <box name="${_[3]}VPlane" lunit="cm"
581  x="@{[$TPCWirePlaneThickness]}"
582  y="@{[$Vactive_y + $UVPlaneBoundNudge]}"
583  z="@{[$Vactive_z + $UVPlaneBoundNudge]}"/>
584  <box name="${_[3]}ZPlane" lunit="cm"
585  x="@{[$TPCWirePlaneThickness]}"
586  y="@{[$Zactive_y]}"
587  z="@{[$Zactive_z]}"/>
588  <box name="${_[3]}Active" lunit="cm"
589  x="@{[$TPCActive_x]}"
590  y="@{[$TPCActive_y]}"
591  z="@{[$TPCActive_z]}"/>
592 EOF
593 
594 
595 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
596 
597 print TPC <<EOF;
598 
599  <tube name="${_[3]}WireVert"
600  rmax="@{[0.5*$TPCWireThickness]}"
601  z="@{[$Zactive_y]}"
602  deltaphi="360"
603  aunit="deg"
604  lunit="cm"/>
605 EOF
606 
607 # Set number of wires to default to zero, when $wires_on = 0, for a low memory
608 # version. But if $wires_on = 1, calculate the number of wires on each side of each
609 # plane to be used in the for loops
610 
611 my $NumberCornerUWires = 0;
612 my $NumberSideUWires = 0;
613 my $NumberCommonUWires = 0;
614 my $NumberCornerVWires = 0;
615 my $NumberSideVWires = 0;
616 my $NumberCommonVWires = 0;
617 my $NumberVerticalWires = 0;
618 
619 if ($wires_on == 1)
620 {
621  # Number of wires in one corner
622 $NumberCornerUWires = int( $APAFrame_z/($UWirePitch/$CosUAngle) );
623 
624 $NumberCornerVWires = int( $APAFrame_z/($VWirePitch/$CosVAngle) );
625 
626 
627  # Total number of wires touching one vertical (longer) side
628  # Note that the total number of wires per plane is this + another set of corner wires
629 $NumberSideUWires = int( $Uactive_y/$UWire_yint );
630 if($Pitch3mmVersion==1){ $NumberSideUWires = $NumberSideUWires-1; }
631 
632 $NumberSideVWires = int( $Vactive_y/$VWire_yint );
633 
634  # Number of wires per side that aren't cut off by the corner
635 $NumberCommonUWires = $NumberSideUWires - $NumberCornerUWires;
636 
637 $NumberCommonVWires = $NumberSideVWires - $NumberCornerVWires;
638 
639  # Number of wires on the vertical plane
640  # Since APA Active z is defined in docdb 3383 to be distance
641  # between outer vertical wires, + 1 since the floor of this
642  # division will be one under, giving the amt of spaces, not wires
643 $NumberVerticalWires = int( $Zactive_z/$XWirePitch ) + 1;
644 #$NumberVerticalWires = 960;
645 
646 
647 $nUchans = 2*$NumberCornerUWires;
648 $nVchans = 2*$NumberCornerVWires;
649 
650 print $wout "$nUchans U channels\n";
651 print $wout "$nVchans V channels\n";
652 print $wout "$NumberVerticalWires Z channels per side\n";
653 
654 print $wout "$NumberCornerUWires U corner wires\n";
655 print $wout "$NumberCommonUWires U common wires\n";
656 print $wout "$NumberCornerVWires V corner wires\n";
657 print $wout "$NumberCommonVWires V common wires\n";
658 
659 }
660 
661 # hard codeed number will be a factor determined from engineering spreadsheets on wire endpoints,
662 # but since that won't exist for a while, use this number to avoid overlaps
663 my $FirstUWireOffset = .55 + $G10thickness + 2*$G10thickness*$TanUAngle - $UWire_zint;
664 my $FirstVWireOffset = .5; # doesnt include a G10 board in width
665 
666 if($Pitch3mmVersion==1){
667  my $FirstUWireOffset = .15 + $G10thickness + 2*$G10thickness*$TanUAngle - $UWire_zint;
668  my $FirstVWireOffset = .15; # doesnt include a G10 board in width
669 }
670 
671 if($UVAngle45Option==1){$FirstVWireOffset = .7;}
672 
673 
674 my $FirstTopUWire_yspan =
675  $Uactive_y/2
676  - ( - $Uactive_y/2
677  + $FirstUWireOffset/$TanUAngle # walk us up to the first wire
678  + $UWire_yint*($NumberSideUWires-1) # up to the top of the top common wire
679  - $Uactive_z/$TanUAngle # back to the bottom of the top common wire
680  + $UWire_yint); # nudge up to bottom of the first top corner wire
681 
682 my $FirstTopVWire_yspan =
683  $Vactive_y/2
684  - ( - $Vactive_y/2
685  + $FirstVWireOffset/$TanVAngle # walk us up to the first wire
686  + $VWire_yint*($NumberSideVWires-1) # up to the top of the top common wire
687  - $Vactive_z/$TanVAngle # back to the bottom of the top common wire
688  + $VWire_yint); # nudge up to bottom of the first top corner wire
689 
690 
691 # The corner wires for the U plane
692 if ($wires_on==1)
693 {
694  for ($i = 0; $i < $NumberCornerUWires; $i++)
695  {
696  $CornerUWireLength[$i] = ($FirstUWireOffset + $i*$UWire_zint)/$SinUAngle;
697 
698  print TPC <<EOF;
699  <tube name="${_[3]}WireU$i"
700  rmax="@{[0.5*$TPCWireThickness]}"
701  z="@{[$CornerUWireLength[$i]]}"
702  deltaphi="360"
703  aunit="deg"
704  lunit="cm"/>
705 EOF
706 
707  }
708 
709  $CommonUWireLength = $Uactive_z/$SinUAngle;
710 
711  print TPC <<EOF;
712  <tube name="${_[3]}WireUCommon"
713  rmax="@{[0.5*$TPCWireThickness]}"
714  z="@{[$CommonUWireLength]}"
715  deltaphi="360"
716  aunit="deg"
717  lunit="cm"/>
718 EOF
719 
720  for ($i = 0; $i < $NumberCornerUWires; $i++)
721  {
722 
723  $TopCornerUWireLength[$i] = ($FirstTopUWire_yspan - $i*$UWire_yint)/$CosUAngle;
724 
725  $j = $i + $NumberSideUWires;
726 
727  print TPC <<EOF;
728  <tube name="${_[3]}WireU$j"
729  rmax="@{[0.5*$TPCWireThickness]}"
730  z="@{[$TopCornerUWireLength[$i]]}"
731  deltaphi="360"
732  aunit="deg"
733  lunit="cm"/>
734 EOF
735 
736  }
737 
738 }
739 
740 
741 # The corner wires for the V plane
742 if ($wires_on==1)
743 {
744  for ($i = 0; $i < $NumberCornerVWires; ++$i)
745  {
746  $CornerVWireLength[$i] = ($FirstVWireOffset + $i*$VWire_zint)/$SinVAngle;
747 
748  print TPC <<EOF;
749 
750  <tube name="${_[3]}WireV$i"
751  rmax="@{[0.5*$TPCWireThickness]}"
752  z="@{[$CornerVWireLength[$i]]}"
753  deltaphi="360"
754  aunit="deg"
755  lunit="cm"/>
756 
757 EOF
758 
759  }
760 
761  # The wire used many times in the middle of the V plane
762  # Same subtraction as U common
763 
764  $CommonVWireLength = $Vactive_z/$SinVAngle;
765 
766  print TPC <<EOF;
767  <tube name="${_[3]}WireVCommon"
768  rmax="@{[0.5*$TPCWireThickness]}"
769  z="@{[$CommonVWireLength]}"
770  deltaphi="360"
771  aunit="deg"
772  lunit="cm"/>
773 EOF
774 
775  for ($i = 0; $i < $NumberCornerVWires; $i++)
776  {
777 
778  $TopCornerVWireLength[$i] = ($FirstTopVWire_yspan - $i*$VWire_yint)/$CosVAngle;
779 
780  $j = $i + $NumberSideVWires;
781 
782  print TPC <<EOF;
783  <tube name="${_[3]}WireV$j"
784  rmax="@{[0.5*$TPCWireThickness]}"
785  z="@{[$TopCornerVWireLength[$i]]}"
786  deltaphi="360"
787  aunit="deg"
788  lunit="cm"/>
789 EOF
790 
791  }
792 
793 
794 }
795 
796 # Begin structure and create the vertical wire logical volume
797 print TPC <<EOF;
798 </solids>
799 <structure>
800  <volume name="volTPCActive${_[3]}">
801  <materialref ref="LAr"/>
802  <solidref ref="${_[3]}Active"/>
803  </volume>
804 
805 EOF
806 
807 
808 if ($wires_on==1)
809 {
810  print TPC <<EOF;
811  <volume name="volTPCWireVert${_[3]}">
812  <materialref ref="Copper_Beryllium_alloy25"/>
813  <solidref ref="${_[3]}WireVert"/>
814  </volume>
815 EOF
816 
817  # Corner U wires logical volumes
818  for ($i = 0; $i < $NumberCornerUWires; ++$i)
819  {
820  print TPC <<EOF;
821  <volume name="volTPCWireU$i${_[3]}">
822  <materialref ref="Copper_Beryllium_alloy25"/>
823  <solidref ref="${_[3]}WireU$i"/>
824  </volume>
825 EOF
826  }
827 
828 
829  # Top Corner U wires logical volumes
830  for ($j = $NumberSideUWires; $j < $NumberSideUWires + $NumberCornerUWires; ++$j)
831  {
832  print TPC <<EOF;
833  <volume name="volTPCWireU$j${_[3]}">
834  <materialref ref="Copper_Beryllium_alloy25"/>
835  <solidref ref="${_[3]}WireU$j"/>
836  </volume>
837 EOF
838  }
839 
840 
841  # Common U wire logical volume, referenced many times
842  print TPC <<EOF;
843  <volume name="volTPCWireUCommon${_[3]}">
844  <materialref ref="Copper_Beryllium_alloy25"/>
845  <solidref ref="${_[3]}WireUCommon"/>
846  </volume>
847 EOF
848 
849 
850  # Corner V wires logical volumes
851  for ($i = 0; $i < $NumberCornerVWires; ++$i)
852  {
853  print TPC <<EOF;
854  <volume name="volTPCWireV$i${_[3]}">
855  <materialref ref="Copper_Beryllium_alloy25"/>
856  <solidref ref="${_[3]}WireV$i"/>
857  </volume>
858 EOF
859 
860  }
861 
862  # Top Corner V wires logical volumes
863  for ($j = $NumberSideVWires; $j < $NumberSideVWires + $NumberCornerVWires; ++$j)
864  {
865  print TPC <<EOF;
866  <volume name="volTPCWireV$j${_[3]}">
867  <materialref ref="Copper_Beryllium_alloy25"/>
868  <solidref ref="${_[3]}WireV$j"/>
869  </volume>
870 EOF
871  }
872 
873  # Common V wire logical volume, referenced many times
874  print TPC <<EOF;
875  <volume name="volTPCWireVCommon${_[3]}">
876  <materialref ref="Copper_Beryllium_alloy25"/>
877  <solidref ref="${_[3]}WireVCommon"/>
878  </volume>
879 EOF
880 
881 }
882 
883 
884 my $lastYpos = 0;
885 my $lastZpos = 0;
886 
887 
888 #+++++++++++++++++++++++++ Position physical wires ++++++++++++++++++++++++++
889 
890 # ++++++++++++++++++++++ U Plane +++++++++++++++++++++++
891 
892 # Create U plane logical volume
893 print TPC <<EOF;
894  <volume name="volTPCPlaneU${_[3]}">
895  <materialref ref="LAr"/>
896  <solidref ref="${_[3]}UPlane"/>
897 EOF
898 
899 
900 print $wout "\n- Wires for U plane -\n\n";
901 print $wout " Uplane_y: $Uactive_y\n";
902 print $wout " Uplane_z: $Uactive_z\n";
903 
904 
905 if ($wires_on==1)
906 {
907 
908 # Starting with the bottom left corner wires:
909  # x=0 to center the wires in the plane
910  # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
911  # from the bottom of the plane, and trigonometry gives the increment
912  # z positioning: Looking at the plane from the positive x direction,
913  # (0.5*$TPCWirePlaneLength) starts the incremental increase from
914  # the lower left corner.
915  # rotation: same as common wire in code below
916 
917  $FirstU_ypos = - $Uactive_y/2 + $FirstUWireOffset/$TanUAngle/2;
918  $FirstU_zpos = + $Uactive_z/2 - $FirstUWireOffset/2;
919 
920 for ($i = 0; $i < $NumberCornerUWires; ++$i)
921 {
922 
923 my $ypos = $FirstU_ypos + ($i)*0.5*$UWire_yint;
924 my $zpos = $FirstU_zpos - ($i)*0.5*$UWire_zint;
925 
926 $pitch = ($ypos - $lastYpos) * $SinUAngle
927  - ($zpos - $lastZpos) * $CosUAngle;
928 
929 print TPC <<EOF;
930  <physvol>
931  <volumeref ref="volTPCWireU$i${_[3]}"/>
932  <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="@{[$ypos ]}" z="@{[$zpos]}"/>
933  <rotation name="rUAngle$i" unit="deg" x="@{[90-$UAngle]}" y="0" z="0"/>
934  </physvol>
935 EOF
936 
937 $topY = $ypos + ($CosUAngle*$CornerUWireLength[$i]/2);
938 $bottomY = $ypos - ($CosUAngle*$CornerUWireLength[$i]/2);
939 $edgeZ_p = $zpos + ($SinUAngle*$CornerUWireLength[$i]/2);
940 $edgeZ_m = $zpos - ($SinUAngle*$CornerUWireLength[$i]/2);
941 print $wout "U$i: ( $ypos , $zpos ) (pitch = $pitch)\n";
942 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
943 
944 $lastYpos = $ypos;
945 $lastZpos = $zpos;
946 
947 }
948 
949 
950 # Moving upwards to the common wires:
951  # x and z are zero to center the wires along a vertical axis
952  # y positioning: The trick is positioning the lowest common wire so that the pitch
953  # is consistent, then the increment is double the increment of
954  # the corner wires since there is no z incriment.
955  # rotation: wires in \\\\ direction, so +90deg to bring them to vertical and
956  # +UAngle counterclockwise to arrive at proper orientation
957 # Note that the counter maintains wire number (in pos. name) counting bottom to top
958 
959 
960 my $StartCommonUWires_ypos = $lastYpos + $UWire_yint - abs( $lastZpos )/$TanUAngle;
961 
962 for ($i = $NumberCornerUWires; $i < $NumberSideUWires; ++$i)
963 {
964 
965  $j = $i - $NumberCornerUWires;
966  my $ypos = $StartCommonUWires_ypos + $UWire_yint*($j);
967 
968  $lastWnum = $i-1;
969  if ( $ypos < $lastYpos ){ print "WARNING: y position dropped from $lastYpos (wire U$lastWnum) to $ypos (wire U$i)\n"; }
970  if ( $ypos == $lastYpos ){ print "WARNING: y position between wire U$lastWnum and U$lastWnum did not move: $ypos\n"; }
971 
972 
973 $pitch = ($ypos - $lastYpos) * $SinUAngle - ($zpos - $lastZpos) * $CosUAngle ;
974 
975 print TPC <<EOF;
976  <physvol>
977  <volumeref ref="volTPCWireUCommon${_[3]}"/>
978  <position name="pos${_[3]}WireU$i" unit="cm" x="0" y="@{[$ypos ]}" z="0"/>
979  <rotation name="rUAngle$i" unit="deg" x="@{[90-$UAngle]}" y="0" z="0"/>
980  </physvol>
981 EOF
982 
983 $topY = $ypos + ($CosUAngle*$CommonUWireLength/2);
984 $bottomY = $ypos - ($CosUAngle*$CommonUWireLength/2);
985 $edgeZ_p = + ($SinUAngle*$CommonUWireLength/2);
986 $edgeZ_m = - ($SinUAngle*$CommonUWireLength/2);
987 print $wout "U$i: ( $ypos , 0 ) (pitch = $pitch)\n";
988 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
989 
990 $lastYpos = $ypos;
991 $lastZpos = 0;
992 
993 }
994 
995 
996 
997 my $FirstTopUWire_zspan = $FirstTopUWire_yspan*$TanUAngle;
998 my $StartTopUWires_ypos = + $Uactive_y/2 - $FirstTopUWire_yspan/2;
999 my $StartTopUWires_zpos = - $Uactive_z/2 + $FirstTopUWire_zspan/2;
1000 
1001 # Finally moving to the corner wires on the top right:
1002  # x=0 to center the wires in the plane
1003  # y positioning: plug wire number into same equation
1004  # z positioning: start at z=0 and go negatively at the same z increment
1005  # rotation: same as common wire in code above
1006 # note that the counter maintains wire number shown in the position name
1007 
1008 for ($j = $NumberSideUWires; $j < $NumberSideUWires+$NumberCornerUWires; ++$j)
1009 {
1010 
1011 $i = $j - $NumberSideUWires;
1012 
1013 my $ypos = $StartTopUWires_ypos + ($i)*0.5*$UWire_yint;
1014 my $zpos = $StartTopUWires_zpos - ($i)*0.5*$UWire_zint;
1015 
1016  $lastWnum = $j-1;
1017  if ( $ypos < $lastYpos ){ print "WARNING: y position dropped from $lastYpos (wire U$lastWnum) to $ypos (wire U$j)\n"; }
1018  if ( $ypos == $lastYpos ){ print "WARNING: y position between wire U$lastWnum and U$j did not move: $ypos\n"; }
1019 
1020 $pitch = ($ypos - $lastYpos) * $SinUAngle - ($zpos - $lastZpos) * $CosUAngle ;
1021 
1022 print TPC <<EOF;
1023  <physvol>
1024  <volumeref ref="volTPCWireU$j${_[3]}"/>
1025  <position name="pos${_[3]}WireU$j" unit="cm" x="0" y="@{[$ypos ]}" z="@{[$zpos]}"/>
1026  <rotation name="rUAngle$j" unit="deg" x="@{[90-$UAngle]}" y="0" z="0"/>
1027  </physvol>
1028 EOF
1029 
1030 $topY = $ypos + ($CosUAngle*$TopCornerUWireLength[$i]/2);
1031 $bottomY = $ypos - ($CosUAngle*$TopCornerUWireLength[$i]/2);
1032 $edgeZ_p = $zpos + ($SinUAngle*$TopCornerUWireLength[$i]/2);
1033 $edgeZ_m = $zpos - ($SinUAngle*$TopCornerUWireLength[$i]/2);
1034 print $wout "U$j: ( $ypos , $zpos ) (pitch = $pitch)\n";
1035 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
1036 
1037 $lastYpos = $ypos;
1038 $lastZpos = $zpos;
1039 
1040 }
1041 
1042 } #ends if wires on
1043 
1044 
1045 # ++++++++++++++++++++++ V Plane +++++++++++++++++++++++
1046 
1047 # End U plane and create V plane logical volume
1048 print TPC <<EOF;
1049  </volume>
1050 
1051  <volume name="volTPCPlaneV${_[3]}">
1052  <materialref ref="LAr"/>
1053  <solidref ref="${_[3]}VPlane"/>
1054 EOF
1055 
1056 print $wout "\n- Wires for V plane -\n\n";
1057 print $wout " Vplane_y: $Vactive_y\n";
1058 print $wout " Vplane_z: $Vactive_z\n";
1059 
1060 if ($wires_on==1)
1061 {
1062 
1063 
1064 # Starting with the bottom right corner wires:
1065  # x=0 to center the wires in the plane
1066  # y positioning: (-0.5*$TPCWirePlaneHeight) starts the incremental increase
1067  # from the bottom of the plane, and trigonometry gives the increment
1068  # z positioning: Looking at the plane from the positive x direction,
1069  # (-0.5*$TPCWirePlaneLength) starts the incremental increase from
1070  # the lower right corner.
1071  # rotation: same as common wire in code below
1072 
1073  $FirstV_ypos = - $Vactive_y/2 + $FirstVWireOffset/$TanVAngle/2;
1074  $FirstV_zpos = - $Vactive_z/2 + $FirstVWireOffset/2;
1075 
1076 for ($i = 0; $i < $NumberCornerVWires; ++$i)
1077 {
1078 
1079 my $ypos = $FirstV_ypos + ($i)*0.5*$VWire_yint;
1080 my $zpos = $FirstV_zpos + ($i)*0.5*$VWire_zint;
1081 
1082 print TPC <<EOF;
1083  <physvol>
1084  <volumeref ref="volTPCWireV$i${_[3]}"/>
1085  <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="@{[$ypos ]}" z="@{[$zpos]}"/>
1086  <rotation name="rVAngle$i" unit="deg" x="@{[90+$VAngle]}" y="0" z="0"/>
1087  </physvol>
1088 EOF
1089 
1090 $topY = $ypos + ($CosVAngle*$CornerVWireLength[$i]/2);
1091 $bottomY = $ypos - ($CosVAngle*$CornerVWireLength[$i]/2);
1092 $edgeZ_p = $zpos + ($SinVAngle*$CornerVWireLength[$i]/2);
1093 $edgeZ_m = $zpos - ($SinVAngle*$CornerVWireLength[$i]/2);
1094 print $wout "V$i: ( $ypos , $zpos ) \n";
1095 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
1096 
1097 $lastYpos = $ypos;
1098 $lastZpos = $zpos;
1099 
1100 }
1101 
1102 
1103 # Moving upwards to the common wires:
1104  # x and z are zero to center the wires along a vertical axis
1105  # y positioning: Plug wire number into the same corner ypos equation
1106  # rotation: wires in //// direction, so +90deg to bring them to vertical and
1107  # --VAngle counterclockwise to arrive at proper orientation
1108 # Note that the counter maintains wire number in the position name
1109 
1110 my $StartCommonVWires_ypos = $lastYpos + $VWire_yint - abs( $lastZpos )/$TanVAngle;
1111 
1112 for ($i = $NumberCornerVWires; $i < $NumberSideVWires; ++$i)
1113 {
1114 
1115  $j = $i - $NumberCornerVWires;
1116  my $ypos = $StartCommonVWires_ypos + $VWire_yint*($j);
1117 
1118 print TPC <<EOF;
1119  <physvol>
1120  <volumeref ref="volTPCWireVCommon${_[3]}"/>
1121  <position name="pos${_[3]}WireV$i" unit="cm" x="0" y="@{[$ypos ]}" z="0"/>
1122  <rotation name="rVAngle$i" unit="deg" x="@{[90+$VAngle]}" y="0" z="0"/>
1123  </physvol>
1124 EOF
1125 
1126 $topY = $ypos + ($CosVAngle*$CommonVWireLength/2);
1127 $bottomY = $ypos - ($CosVAngle*$CommonVWireLength/2);
1128 $edgeZ_p = + ($SinVAngle*$CommonVWireLength/2);
1129 $edgeZ_m = - ($SinVAngle*$CommonVWireLength/2);
1130 print $wout "V$i: ( $ypos , 0 ) \n";
1131 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
1132 
1133 $lastYpos = $ypos;
1134 #$lastZpos = $zpos; always 0
1135 
1136 }
1137 
1138 
1139 my $FirstTopVWire_zspan = $FirstTopVWire_yspan*$TanVAngle;
1140 my $StartTopVWires_ypos = + $Vactive_y/2 - $FirstTopVWire_yspan/2;
1141 my $StartTopVWires_zpos = + $Vactive_z/2 - $FirstTopVWire_zspan/2;
1142 
1143 # Finally moving to the corner wires on the top right:
1144  # x=0 to center the wires in the plane
1145  # y positioning: plug wire number into same equation
1146  # z positioning: start at z=0 and go positively at the same z increment
1147  # rotation: same as common wire in code above
1148 # note that the counter maintains wire number shown in the position name
1149 
1150 for ($j = $NumberSideVWires; $j < $NumberSideVWires+$NumberCornerVWires; ++$j)
1151 {
1152 
1153 $i = $j - $NumberSideVWires;
1154 
1155 my $ypos = $StartTopVWires_ypos + ($i)*0.5*$VWire_yint;
1156 my $zpos = $StartTopVWires_zpos + ($i)*0.5*$VWire_zint;
1157 
1158 print TPC <<EOF;
1159  <physvol>
1160  <volumeref ref="volTPCWireV$j${_[3]}"/>
1161  <position name="pos${_[3]}WireV$j" unit="cm" x="0" y="@{[$ypos ]}" z="@{[$zpos]}"/>
1162  <rotation name="rVAngle$j" unit="deg" x="@{[90+$VAngle]}" y="0" z="0"/>
1163  </physvol>
1164 EOF
1165 
1166 $topY = $ypos + ($CosVAngle*$TopCornerVWireLength[$i]/2);
1167 $bottomY = $ypos - ($CosVAngle*$TopCornerVWireLength[$i]/2);
1168 $edgeZ_p = $zpos + ($SinVAngle*$TopCornerVWireLength[$i]/2);
1169 $edgeZ_m = $zpos - ($SinVAngle*$TopCornerVWireLength[$i]/2);
1170 print $wout "V$j: ( $ypos , $zpos ) \n";
1171 print $wout " -- Y: $bottomY to $topY -- Z: $edgeZ_m to $edgeZ_p \n";
1172 
1173 }
1174 
1175 
1176 
1177 
1178 
1179 
1180 } #ends if wires on
1181 
1182 
1183 
1184 # ++++++++++++++++++++++ Z Plane +++++++++++++++++++++++
1185 
1186 # End V plane and create Z plane logical volume
1187 print TPC <<EOF;
1188  </volume>
1189 
1190  <volume name="volTPCPlaneZ${_[3]}">
1191  <materialref ref="LAr"/>
1192  <solidref ref="${_[3]}ZPlane"/>
1193 EOF
1194 
1195 if ($wires_on==1)
1196 {
1197 
1198 # This is the simplest plane, one loop creates all of the wires
1199  # x and y position at zero to center the wires
1200  # z position: moving from front of detector to back, in the positive z direction,
1201  # starting at (-0.5*$TPCWirePlaneLength), the right side looking from
1202  # the +x direction
1203 
1204 for ($i=0; $i<$NumberVerticalWires; ++$i)
1205 {
1206 my $zpos = (-0.5*$Zactive_z) + $i*$XWirePitch + $TPCWireThickness/2;
1207 
1208 print TPC <<EOF;
1209  <physvol>/
1210  <volumeref ref="volTPCWireVert${_[3]}"/>
1211  <position name="pos${_[3]}WireZ$i" unit="cm" x="0" y="0 " z="@{[$zpos]}"/>
1212  <rotationref ref="rPlus90AboutX"/>
1213  </physvol>
1214 EOF
1215 
1216 }
1217 
1218 } #ends if wires on
1219 
1220 print TPC <<EOF;
1221  </volume>
1222 EOF
1223 
1224 #+++++++++++++++++++++ ^^ Position physical wires Above ^^ +++++++++++++++++++++
1225 
1226 ## make the TPC active volume extend down to the G10 for the grid
1227 
1228  my $BottomOfAPA = - $TPC_y/2 + $APAGap_y/2;
1229 
1230 
1231  $posZplane[0] = -$_[0]/2 + $APAWirePlaneSpacing - $TPCWirePlaneThickness/2;
1232  $posZplane[1] = $BottomOfAPA + $WrapCover + 4*$G10thickness + $Zactive_y/2;
1233  $posZplane[2] = 0;
1234 
1235  $posVplane[0] = $posZplane[0] + $APAWirePlaneSpacing;
1236  $posVplane[1] = $BottomOfAPA + $WrapCover + 3*$G10thickness + $Vactive_y/2;
1237  $posVplane[2] = $posZplane[2];
1238 
1239  $posUplane[0] = $posVplane[0] + $APAWirePlaneSpacing;
1240  $posUplane[1] = $BottomOfAPA + $WrapCover + 2*$G10thickness + $Uactive_y/2;
1241  $posUplane[2] = $posZplane[2];
1242 
1243  $posTPCActive[0] = $posUplane[0] + ($TPCWirePlaneThickness/2 + $TPCActive_x/2);
1244  $posTPCActive[1] = -$_[1]/2 + $TPCActive_y/2;
1245  $posTPCActive[2] = 0;
1246 
1247 #wrap up the TPC file
1248 print TPC <<EOF;
1249  <volume name="volTPC${_[3]}">
1250  <materialref ref="LAr"/>
1251  <solidref ref="${_[3]}"/>
1252  <physvol>
1253  <volumeref ref="volTPCPlaneZ${_[3]}"/>
1254  <position name="pos${_[3]}PlaneZ" unit="cm"
1255  x="@{[$posZplane[0]]}" y="@{[$posZplane[1]]}" z="@{[$posZplane[2]]}"/>
1256  <rotationref ref="rIdentity"/>
1257  </physvol>
1258  <physvol>
1259  <volumeref ref="volTPCPlaneV${_[3]}"/>
1260  <position name="pos${_[3]}PlaneV" unit="cm"
1261  x="@{[$posVplane[0]]}" y="@{[$posVplane[1]]}" z="@{[$posVplane[2]]}"/>
1262  <rotationref ref="rIdentity"/>
1263  </physvol>
1264  <physvol>
1265  <volumeref ref="volTPCPlaneU${_[3]}"/>
1266  <position name="pos${_[3]}PlaneU" unit="cm"
1267  x="@{[$posUplane[0]]}" y="@{[$posUplane[1]]}" z="@{[$posUplane[2]]}"/>
1268  <rotationref ref="rIdentity"/>
1269  </physvol>
1270 EOF
1271 
1272 # Option to omit the active volume on the outside for the prototype.
1273 if( !($killOuterActive==1 && $_[3] eq 'Outer') ){
1274 print TPC <<EOF;
1275  <physvol>
1276  <volumeref ref="volTPCActive${_[3]}"/>
1277  <position name="pos${_[3]}Active" unit="cm"
1278  x="@{[$posTPCActive[0]]}" y="@{[$posTPCActive[1]]}" z="@{[$posTPCActive[2]]}"/>
1279  <rotationref ref="rIdentity"/>
1280  </physvol>
1281 EOF
1282 }
1283 
1284 print TPC <<EOF;
1285  </volume>
1286 </structure>
1287 </gdml>
1288 EOF
1289 
1290  close(TPC);
1291 
1292 } #end of sub gen_TPC
1293 
1294 
1295 
1296 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1297 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1298 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1299 
1300 sub gen_Cryostat()
1301 {
1302 
1303 # Create the cryostat fragment file name,
1304 # add file to list of output GDML fragments,
1305 # and open it
1306  $CRYO = "dune10kt_v4_Cryostat" . $suffix . ".gdml";
1307  push (@gdmlFiles, $CRYO);
1308  $CRYO = ">" . $CRYO;
1309  open(CRYO) or die("Could not open file $CRYO for writing");
1310 
1311 
1312 # The standard XML prefix and starting the gdml
1313  print CRYO <<EOF;
1314 <?xml version='1.0'?>
1315 <gdml>
1316 EOF
1317 
1318 $APAFrameZSide_x = $APAFrame_x;
1319 $APAFrameZSide_y = 4*$inch;
1320 $APAFrameZSide_z = $APAFrame_z;
1321 
1322 $APAFrameYSide_x = $APAFrame_x;
1323 $APAFrameYSide_y = $APAFrame_y-2*$APAFrameZSide_y;
1324 $APAFrameYSide_z = 4*$inch;
1325 
1326 # Two outer Y supports will sandwich the light paddles
1327 $APAFrameYOuterSupport_x = ($APAFrame_x-$ArapucaOut_x)/2;
1328 $APAFrameYOuterSupport_y = $APAFrame_y-2*$APAFrameZSide_y;
1329 $APAFrameYOuterSupport_z = 4*$inch;
1330 
1331 $EdgeFrameSteelThickness = 0.12*$inch;
1332 $InnerFrameSteelThickness = 0.062*$inch;
1333 
1334 
1335 $G10BoardYSide_x = $APAFrame_x;
1336 $G10BoardYSide_y = $APAFrame_y;
1337 $G10BoardYSide_z = $G10thickness;
1338 
1339 $G10BoardZSide_x = $APAFrame_x;
1340 $G10BoardZSide_y = $G10thickness;
1341 $G10BoardZSide_z = $APAFrame_z;
1342 
1343 ##################################################################
1344 ################### Field Cage Y and Z centers ###################
1345 
1346 
1347 $FC_x_center = 0.0;
1348 $FC_y_center = 0.0;
1349 $FC_z_center = 0.0;
1350 for($k=0 ; $k<$nAPALong ; $k++) #TODO!!! Factor out these loops so that the calculation of each APA center for placing APAs (happens later) will always agree with placing the center of the Field Cage.
1351 {
1352  $tmp_APACenter_z = - $Argon_z/2
1353  + $UpstreamLArPadding
1354  + $APAphys_z/2
1355  + $k*($APAphys_z+$APAGap_z);
1356  $FC_z_center = $FC_z_center + $tmp_APACenter_z;
1357 }
1358 $FC_z_center = $FC_z_center / $nAPALong;
1359 
1360 for($j=0 ; $j<$nAPAHigh ; $j++) # nAPAHigh always going to be 2
1361 {
1362  $tmp_APACenter_y = - $Argon_y/2 + $SpaceAPAToFloor
1363  + $APAphys_y/2
1364  + $j*($APAphys_y+$APAGap_y);
1365  $FC_y_center = $FC_y_center + $tmp_APACenter_y;
1366 }
1367 $FC_y_center = $FC_y_center / $nAPAHigh;
1368 
1369 # All the cryostat solids.
1370 print CRYO <<EOF;
1371 <solids>
1372  <tube name="SourceModerator"
1373  rmax="@{[0.5*$SourceModerator_d]}"
1374  z="@{[$SourceModerator_z]}"
1375  deltaphi="360"
1376  aunit="deg"
1377  lunit="cm"/>
1378  <box name="Cryostat" lunit="cm"
1379  x="@{[$Cryostat_x]}"
1380  y="@{[$Cryostat_y]}"
1381  z="@{[$Cryostat_z]}"/>
1382  <box name="ArgonInterior" lunit="cm"
1383  x="@{[$Argon_x]}"
1384  y="@{[$Argon_y]}"
1385  z="@{[$Argon_z]}"/>
1386  <box name="FieldCageOut" lunit="cm"
1387  x="@{[$FC_x]}"
1388  y="@{[$FCO_y]}"
1389  z="@{[$FCO_z]}"/>
1390  <box name="FieldCageIn" lunit="cm"
1391  x="@{[$FC_x+1]}"
1392  y="@{[$FCI_y]}"
1393  z="@{[$FCI_z]}"/>
1394  <subtraction name="FieldCage">
1395  <first ref="FieldCageOut"/>
1396  <second ref="FieldCageIn"/>
1397  </subtraction>
1398  <box name="GaseousArgon" lunit="cm"
1399  x="@{[$Argon_x]}"
1400  y="@{[$HeightGaseousAr]}"
1401  z="@{[$Argon_z]}"/>
1402  <subtraction name="SteelShell">
1403  <first ref="Cryostat"/>
1404  <second ref="ArgonInterior"/>
1405  </subtraction>
1406  <box name="Cathode" lunit="cm"
1407  x="@{[$Cathode_x]}"
1408  y="@{[$Cathode_y]}"
1409  z="@{[$Cathode_z]}"/>
1410 
1411  <box name="ArapucaOut" lunit="cm"
1412  x="@{[$ArapucaOut_x]}"
1413  y="@{[$ArapucaOut_y]}"
1414  z="@{[$ArapucaOut_z]}"/>
1415 
1416  <box name="ArapucaIn" lunit="cm"
1417  x="@{[$ArapucaIn_x]}"
1418  y="@{[$ArapucaIn_y]}"
1419  z="@{[$ArapucaIn_z]}"/>
1420 
1421  <subtraction name="ArapucaWalls0">
1422  <first ref="ArapucaOut"/>
1423  <second ref="ArapucaIn"/>
1424  <positionref ref="posArapucaSub0"/>
1425  </subtraction>
1426  <subtraction name="ArapucaWalls1">
1427  <first ref="ArapucaWalls0"/>
1428  <second ref="ArapucaIn"/>
1429  <positionref ref="posArapucaSub1"/>
1430  </subtraction>
1431  <subtraction name="ArapucaWalls2">
1432  <first ref="ArapucaWalls1"/>
1433  <second ref="ArapucaIn"/>
1434  <positionref ref="posArapucaSub2"/>
1435  </subtraction>
1436  <subtraction name="ArapucaWalls">
1437  <first ref="ArapucaWalls2"/>
1438  <second ref="ArapucaIn"/>
1439  <positionref ref="posArapucaSub3"/>
1440  </subtraction>
1441 
1442  <box name="ArapucaAcceptanceWindow" lunit="cm"
1443  x="@{[$ArapucaAcceptanceWindow_x]}"
1444  y="@{[$ArapucaAcceptanceWindow_y]}"
1445  z="@{[$ArapucaAcceptanceWindow_z]}"/>
1446 
1447  <box name="APAFrameYSideHollow" lunit="cm"
1448  x="@{[$APAFrameYSide_x-2*$EdgeFrameSteelThickness]}"
1449  y="@{[$APAFrameYSide_y-2*$EdgeFrameSteelThickness]}"
1450  z="@{[$APAFrameYSide_z]}"/>
1451  <box name="APAFrameYSideShell" lunit="cm"
1452  x="@{[$APAFrameYSide_x]}"
1453  y="@{[$APAFrameYSide_y]}"
1454  z="@{[$APAFrameYSide_z]}"/>
1455  <subtraction name="APAFrameYSide">
1456  <first ref="APAFrameYSideShell"/>
1457  <second ref="APAFrameYSideHollow"/>
1458  <positionref ref="posCenter"/>
1459  <rotationref ref="rIdentity"/>
1460  </subtraction>
1461 
1462  <box name="APAFrameZSideHollow" lunit="cm"
1463  x="@{[$APAFrameZSide_x-2*$EdgeFrameSteelThickness]}"
1464  y="@{[$APAFrameZSide_y-2*$EdgeFrameSteelThickness]}"
1465  z="@{[$APAFrameZSide_z]}"/>
1466  <box name="APAFrameZSideShell" lunit="cm"
1467  x="@{[$APAFrameZSide_x]}"
1468  y="@{[$APAFrameZSide_y]}"
1469  z="@{[$APAFrameZSide_z]}"/>
1470  <subtraction name="APAFrameZSide">
1471  <first ref="APAFrameZSideShell"/>
1472  <second ref="APAFrameZSideHollow"/>
1473  <positionref ref="posCenter"/>
1474  <rotationref ref="rIdentity"/>
1475  </subtraction>
1476 
1477  <box name="APAFrameYOuterSupport" lunit="cm"
1478  x="@{[$EdgeFrameSteelThickness]}"
1479  y="@{[$APAFrameYOuterSupport_y]}"
1480  z="@{[$APAFrameYOuterSupport_z]}"/>
1481 
1482 
1483  <box name="G10BoardYSideCenterSeg" lunit="cm"
1484  x="@{[$G10BoardYSide_x]}"
1485  y="@{[$G10BoardYSide_y]}"
1486  z="@{[$G10BoardYSide_z]}"/>
1487 
1488  <box name="G10BoardZSideCenterSeg" lunit="cm"
1489  x="@{[$G10BoardZSide_x]}"
1490  y="@{[$G10BoardZSide_y]}"
1491  z="@{[$G10BoardZSide_z]}"/>
1492 
1493 </solids>
1494 EOF
1495 
1496 # Cryostat structure
1497 print CRYO <<EOF;
1498 <structure>
1499  <volume name="volSteelShell">
1500  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
1501  <solidref ref="SteelShell" />
1502  </volume>
1503  <volume name="volSourceModerator">
1504  <materialref ref="Delrin"/>
1505  <solidref ref="SourceModerator"/>
1506  </volume>
1507  <volume name="volFieldCage">
1508  <materialref ref="ALUMINUM_Al"/>
1509  <solidref ref="FieldCage"/>
1510  </volume>
1511  <volume name="volGaseousArgon">
1512  <materialref ref="ArGas"/>
1513  <solidref ref="GaseousArgon"/>
1514  </volume>
1515  <volume name="volCathode">
1516  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
1517  <solidref ref="Cathode" />
1518  </volume>
1519 EOF
1520 
1521 for($i=0 ; $i<$nAPAs ; $i++){
1522 for($p=0 ; $p<10 ; $p++){
1523 for($ncuts=0 ; $ncuts<4; $ncuts++){
1524 print CRYO <<EOF;
1525  <volume name="volOpDetSensitive_$i\-$p\-$ncuts">
1526  <materialref ref="Acrylic"/>
1527  <solidref ref="ArapucaAcceptanceWindow"/>
1528  </volume>
1529 EOF
1530 }
1531 }
1532 }
1533 
1534 for($i=0 ; $i<$nAPAs ; $i++){
1535 for($p=0 ; $p<10 ; $p++){
1536 print CRYO <<EOF;
1537  <volume name="volArapuca_$i\-$p">
1538  <materialref ref="G10"/>
1539  <solidref ref="ArapucaWalls"/>
1540  </volume>
1541 EOF
1542 }
1543 }
1544 
1545 
1546 print CRYO <<EOF;
1547 
1548  <volume name="volAPAFrameYSide">
1549  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1550  <solidref ref="APAFrameYSide"/>
1551  </volume>
1552 
1553  <volume name="volAPAFrameZSide">
1554  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1555  <solidref ref="APAFrameZSide"/>
1556  </volume>
1557 
1558  <volume name="volAPAFrameYOuterSupport">
1559  <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
1560  <solidref ref="APAFrameYOuterSupport"/>
1561  </volume>
1562 
1563  <volume name="volG10BoardYSideCenterSeg">
1564  <materialref ref="G10"/>
1565  <solidref ref="G10BoardYSideCenterSeg"/>
1566  </volume>
1567 
1568  <volume name="volG10BoardZSideCenterSeg">
1569  <materialref ref="G10"/>
1570  <solidref ref="G10BoardZSideCenterSeg"/>
1571  </volume>
1572 
1573  <volume name="volCryostat">
1574  <materialref ref="LAr" />
1575  <solidref ref="Cryostat" />
1576  <physvol>
1577  <volumeref ref="volGaseousArgon"/>
1578  <position name="posGaseousArgon" unit="cm" x="0" y="@{[$Argon_y/2-$HeightGaseousAr/2]}" z="0"/>
1579  </physvol>
1580  <physvol>
1581  <volumeref ref="volSourceModerator"/>
1582  <position name="posSourceModerator" unit="cm"
1583  x="@{[$Source_x_center]}"
1584  y="@{[$Source_y_center]}"
1585  z="@{[$Source_z_center]}"/>
1586  <rotationref ref="rPlus90AboutX"/>
1587  </physvol>
1588  <physvol>
1589  <volumeref ref="volFieldCage"/>
1590  <position name="posFieldCage" unit="cm"
1591  x="@{[$FC_x_center]}"
1592  y="@{[$FC_y_center]}"
1593  z="@{[$FC_z_center]}"/>
1594  </physvol>
1595  <physvol>
1596  <volumeref ref="volSteelShell"/>
1597  <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1598  </physvol>
1599 EOF
1600 
1601 # nested for loops to place the non-rotated AND rotated volTPC
1602  # x loop rotation: There are six drift volumes. Looking into the
1603  # detector from incident direction, and counting from right (-x) to
1604  # left (+x), odd number volumes need to be rotated 180deg about Y in
1605  # order for the cathode to be on the right of the APA.
1606 
1607 if ($tpc_on==1) {
1608 
1609  $apa_i=0;
1610  $cpa_i=0;
1611 
1612  for($k=0 ; $k<$nAPALong ; $k++)
1613  {
1614  $APACenter_z = - $Argon_z/2
1615  + $UpstreamLArPadding
1616  + $APAphys_z/2
1617  + $k*($APAphys_z+$APAGap_z);
1618 
1619 
1620  for($j=0 ; $j<$nAPAHigh ; $j++) # nAPAHigh always going to be 2
1621  { # $j=0 for bottom APAs
1622  # $j=1 for top APAs
1623  $APACenter_y = - $Argon_y/2 + $SpaceAPAToFloor
1624  + $APAphys_y/2
1625  + $j*($APAphys_y+$APAGap_y);
1626 
1627 
1628  if( $workspace == 0 )
1629  {
1630 
1631  for($i=0 ; $i<$nAPAWide ; $i++)
1632  {
1633 
1634 
1635  $APACenter_x = - $Argon_x/2
1636  + $SpaceAPAToCryoWall + $APA_UtoU_x/2 + $TPCWirePlaneThickness/2
1637  + $i*$APAToAPA;
1638 
1639  $CPA_x = $APACenter_x + $CPAToAPA;
1640 
1641 
1642  place_APA($APACenter_x, $APACenter_y, $APACenter_z, $apa_i, $j);
1643  place_OpDets($APACenter_x, $APACenter_y, $APACenter_z, $apa_i);
1644  $tpc_0 = 2*$apa_i+0;
1645  $tpc_1 = 2*$apa_i+1;
1646  $apa_i++;
1647 
1648  $SelectTPC_0 = "Inner";
1649  $SelectTPC_1 = "Inner";
1650  $TPC_0_x = $TPCInner_x;
1651  $TPC_1_x = $TPCInner_x;
1652  $rot_0 = "rPlus180AboutY";
1653  $rot_1 = "rIdentity";
1654  if($i == 0) { $SelectTPC_0 = "Outer"; $TPC_0_x = $TPCOuter_x; }
1655  if($i == $nAPAWide-1) { $SelectTPC_1 = "Outer"; $TPC_1_x = $TPCOuter_x; }
1656  if($j == 0) { $rot_0 = "rPlus180AboutXPlus180AboutY";
1657  $rot_1 = "rPlus180AboutX"; } #put the readout end at the bottom for bottom APAs
1658 
1659 
1660 
1661 print CRYO <<EOF;
1662 
1663  <physvol>
1664  <volumeref ref="volTPC$SelectTPC_0"/>
1665  <position name="posTPC\-$tpc_0" unit="cm"
1666  x="@{[$APACenter_x - $APAFrame_x/2 - $TPC_0_x/2]}"
1667  y="@{[$APACenter_y]}"
1668  z="@{[$APACenter_z]}"/>
1669  <rotationref ref="$rot_0"/>
1670  </physvol>
1671  <physvol>
1672  <volumeref ref="volTPC$SelectTPC_1"/>
1673  <position name="posTPC\-$tpc_1" unit="cm"
1674  x="@{[$APACenter_x + $APAFrame_x/2 + $TPC_1_x/2]}"
1675  y="@{[$APACenter_y]}"
1676  z="@{[$APACenter_z]}"/>
1677  <rotationref ref="$rot_1"/>
1678  </physvol>
1679 
1680 EOF
1681 
1682 
1683 if( $i < $nAPAWide - 1 ){ # avoid placeing the last row of CPAs since the APAs are on the outside
1684 
1685 print CRYO <<EOF;
1686 
1687  <physvol>
1688  <volumeref ref="volCathode"/>
1689  <position name="posCathode\-$cpa_i" unit="cm"
1690  x="@{[$CPA_x]}"
1691  y="@{[$APACenter_y]}"
1692  z="@{[$APACenter_z]}"/>
1693  <rotationref ref="rIdentity"/>
1694  </physvol>
1695 
1696 EOF
1697  $cpa_i++;
1698 }
1699 
1700 
1701  } #wide
1702 
1703  } # end if not the smaller workspace
1704 
1705 
1706  # Make the workspace have only one center APA with CPAs and the full drift on either side
1707  elsif( $workspace == 1 || $workspace==2 ){
1708 
1709  $APACenter_x = 0;
1710  $CPA_0_x = $APACenter_x - $CPAToAPA;
1711  $CPA_1_x = $APACenter_x + $CPAToAPA;
1712 
1713 
1714  place_APA($APACenter_x, $APACenter_y, $APACenter_z, $apa_i, $j);
1715  place_OpDets($APACenter_x, $APACenter_y, $APACenter_z, $apa_i);
1716 
1717  $tpc_0 = 2*$apa_i+0;
1718  $tpc_1 = 2*$apa_i+1;
1719  $apa_i++;
1720 
1721  $rot_0 = "rPlus180AboutY";
1722  $rot_1 = "rIdentity";
1723  if($j == 0) { $rot_0 = "rPlus180AboutXPlus180AboutY";
1724  $rot_1 = "rPlus180AboutX"; } #put the readout end at the bottom for bottom APAs
1725 
1726 print CRYO <<EOF;
1727 
1728  <physvol>
1729  <volumeref ref="volTPCInner"/>
1730  <position name="posTPC\-$tpc_0" unit="cm"
1731  x="@{[$APACenter_x - $APAFrame_x/2 - $TPCInner_x/2]}"
1732  y="@{[$APACenter_y]}"
1733  z="@{[$APACenter_z]}"/>
1734  <rotationref ref="$rot_0"/>
1735  </physvol>
1736  <physvol>
1737  <volumeref ref="volTPCInner"/>
1738  <position name="posTPC\-$tpc_1" unit="cm"
1739  x="@{[$APACenter_x + $APAFrame_x/2 + $TPCInner_x/2]}"
1740  y="@{[$APACenter_y]}"
1741  z="@{[$APACenter_z]}"/>
1742  <rotationref ref="$rot_1"/>
1743  </physvol>
1744 
1745  <physvol>
1746  <volumeref ref="volCathode"/>
1747  <position name="posCathode\-$apa_i-0" unit="cm"
1748  x="@{[$CPA_0_x]}"
1749  y="@{[$APACenter_y]}"
1750  z="@{[$APACenter_z]}"/>
1751  <rotationref ref="rIdentity"/>
1752  </physvol>
1753  <physvol>
1754  <volumeref ref="volCathode"/>
1755  <position name="posCathode\-$apa_i-1" unit="cm"
1756  x="@{[$CPA_1_x]}"
1757  y="@{[$APACenter_y]}"
1758  z="@{[$APACenter_z]}"/>
1759  <rotationref ref="rIdentity"/>
1760  </physvol>
1761 
1762 EOF
1763 
1764  } # if the smaller workspace
1765 
1766 
1767  } #high
1768  } #long
1769 
1770 }# end if tpc
1771 
1772 print CRYO <<EOF;
1773  </volume>
1774 </structure>
1775 </gdml>
1776 EOF
1777 
1778 close(CRYO);
1779 }
1780 
1781 
1782 
1783 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1784 #++++++++++++++++++++++++++++++++++++ place_OpDets +++++++++++++++++++++++++++++++++++++++
1785 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1786 
1787 sub place_OpDets()
1788 {
1789 
1790  $APACenter_x = $_[0];
1791  $APACenter_y = $_[1];
1792  $APACenter_z = $_[2];
1793  $apa_i = $_[3];
1794 
1795  # Alternate the paddle orientations
1796  if ( $apa_i % 2 == 0 ) {
1797  $rot = "rIdentity";
1798  $posAra_x = ($APACenter_x+0.5*$ArapucaOut_x-0.5*$ArapucaAcceptanceWindow_x-0.1);
1799  }else{
1800  $rot = "rPlus180AboutY";
1801  $posAra_x = ($APACenter_x-0.5*$ArapucaOut_x+0.5*$ArapucaAcceptanceWindow_x+0.1);
1802  }
1803 
1804 
1805 for ($paddle = 0; $paddle<$nLightPaddlesPerAPA; $paddle++)
1806 {
1807 
1808  # All Light Paddle centers will have the same
1809  # X coordinate as the center of the current APA
1810  # Z coordinate as the current TPC pair
1811  # The Y coordinate must be looped over:
1812 
1813  #the multiplication by j here is a temporary dirty trick to get around some strange behavior
1814 
1815  $Paddle_Y = $APACenter_y
1816  - $APAphys_y/2
1817  + $j*$FrameToPaddleSpace
1818  + (1-$j)*($ArapucaOut_y/2 + $APAFrameZSide_y)
1819  + $PaddleYInterval*$paddle;
1820 
1821 print CRYO <<EOF;
1822 <physvol>
1823 <volumeref ref="volArapuca_$apa_i\-$paddle"/>
1824 <position name="posArapuca$apa_i\-$paddle\-TPC\-$i\-$j\-$k" unit="cm"
1825 x="@{[$APACenter_x]}"
1826 y="@{[$Paddle_Y]}"
1827 z="@{[$APACenter_z]}"/>
1828 <rotationref ref="$rot"/>
1829 </physvol>
1830 EOF
1831 
1832 
1833 for($nwindow=0 ; $nwindow<4; $nwindow++){
1834  print CRYO <<EOF;
1835  <physvol>
1836  <volumeref ref="volOpDetSensitive_$apa_i\-$paddle\-$nwindow"/>
1837  <position name="posOpArapuca$apa_i\-$paddle\-$nwindow\-TPC\-$i\-$j\-$k" unit="cm"
1838  x="@{[$posAra_x]}"
1839  y="@{[$Paddle_Y]}"
1840  z="@{[$list_pos[$nwindow]+$APACenter_z]}"/>
1841  <rotationref ref="$rot"/>
1842  </physvol>
1843 EOF
1844 }#end nwindow for-loop
1845 }#end Paddle for-loop
1846 
1847 }
1848 
1849 
1850 
1851 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1852 #++++++++++++++++++++++++++++++++++++++ place_APA ++++++++++++++++++++++++++++++++++++++++
1853 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1854 
1855 
1856 # Must be called only within gen_Cryostat(),
1857 
1858 
1859 # $_[0] = x APA physical center
1860 # $_[1] = y APA physical center
1861 # $_[2] = z APA physical center
1862 # $_[3] = APA number
1863 # $_[4] = 0 for APA with readout on bottom
1864 # 1 for APA with readout on top
1865 
1866 sub place_APA()
1867 {
1868 
1869  $APA_i = $_[3];
1870 
1871 ####################################################################
1872 ################# APA Frame and Paddle Dimensions ##################
1873 
1874 # The center passed to this function is the physical APA center,
1875 # which is not quite the frame's center, since there are more boards
1876 # at the bottom. Transform them:
1877 
1878  $APAFrameCenter_x = $_[0];
1879  $APAFrameCenter_z = $_[2];
1880 
1881 # The bottom APAs are upside down relative to how the TPC is initially generated,
1882 # and the center needs to be slightly shifted since there is extra G10 on the
1883 # end that doesn't read out.
1884 
1885  if($_[4]==1) # top APAs
1886  {
1887  $APAFrameCenter_y = $_[1] - $APAphys_y/2
1888  + $WrapCover + 4*$G10thickness
1889  + $APAFrame_y/2;
1890  }
1891  elsif($_[4]==0) # bottom APAs
1892  {
1893  $APAFrameCenter_y = $_[1] + $APAphys_y/2
1894  - $WrapCover - 4*$G10thickness
1895  - $APAFrame_y/2;
1896  }
1897  else{ print "APA not labeled as top or bottom"; }
1898 
1899 $APAFrameZSide_x = $APAFrame_x;
1900 $APAFrameZSide_y = 4*$inch;
1901 $APAFrameZSide_z = $APAFrame_z;
1902 
1903 $APAFrameYSide_x = $APAFrame_x;
1904 $APAFrameYSide_y = $APAFrame_y-2*$APAFrameZSide_y;
1905 $APAFrameYSide_z = 4*$inch;
1906 
1907 # Two outer Y supports will sandwich the light paddles
1908 $APAFrameYOuterSupport_x = ($APAFrame_x-$ArapucaOut_x)/2;
1909 $APAFrameYOuterSupport_y = $APAFrame_y-2*$APAFrameZSide_y;
1910 $APAFrameYOuterSupport_z = 4*$inch;
1911 
1912 # if there were an inner support to fill the hole
1913 $APAFrameYInnerSupport_x = $ArapucaOut_x;
1914 
1915 $EdgeFrameSteelThickness = 0.12*$inch;
1916 $InnerFrameSteelThickness = 0.062*$inch;
1917 
1918 
1919 $G10BoardYSide_x = $APAFrame_x;
1920 $G10BoardYSide_y = $APAFrame_y;
1921 $G10BoardYSide_z = $G10thickness;
1922 
1923 $G10BoardZSide_x = $APAFrame_x;
1924 $G10BoardZSide_y = $G10thickness;
1925 $G10BoardZSide_z = $APAFrame_z;
1926 
1927 if($_[4]==1) # top APAs
1928 {
1929  $posG10ZSideZ_y = $APAFrameCenter_y - $APAFrame_y/2 - (0+.5)*($G10BoardZSide_y);
1930  $posG10ZSideV_y = $APAFrameCenter_y - $APAFrame_y/2 - (1+.5)*($G10BoardZSide_y);
1931  $posG10ZSideU_y = $APAFrameCenter_y - $APAFrame_y/2 - (2+.5)*($G10BoardZSide_y);
1932  $posG10ZSideGrid_y = $APAFrameCenter_y - $APAFrame_y/2 - (3+.5)*($G10BoardZSide_y);
1933 }
1934 elsif($_[4]==0) # bottom APAs
1935 {
1936  $posG10ZSideZ_y = $APAFrameCenter_y + $APAFrame_y/2 + (0+.5)*($G10BoardZSide_y);
1937  $posG10ZSideV_y = $APAFrameCenter_y + $APAFrame_y/2 + (1+.5)*($G10BoardZSide_y);
1938  $posG10ZSideU_y = $APAFrameCenter_y + $APAFrame_y/2 + (2+.5)*($G10BoardZSide_y);
1939  $posG10ZSideGrid_y = $APAFrameCenter_y + $APAFrame_y/2 + (3+.5)*($G10BoardZSide_y);
1940 }
1941 else{ print "APA not labeled as top or bottom"; }
1942 
1943  # First put in the frame
1944 # print CRYO <<EOF;
1945 #<!--
1946 # <physvol>
1947 # <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1948 # <position name="posAPAFrameYOuterSupportNeg\-$APA_i" unit="cm"
1949 # x="$APAFrameCenter_x - ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1950 # y="$APAFrameCenter_y"
1951 # z="$APAFrameCenter_z"/>
1952 # <rotationref ref="rIdentity"/>
1953 # </physvol>
1954 # <physvol>
1955 # <volumeref ref="volAPAFrameYOuterSupport\-$APA_i"/>
1956 # <position name="posAPAFrameYOuterSupportPos\-$APA_i" unit="cm"
1957 # x="$APAFrameCenter_x + ($APAFrameYOuterSupport_x + $APAFrameYInnerSupport_x/2 - $EdgeFrameSteelThickness/2)"
1958 # y="$APAFrameCenter_y"
1959 # z="$APAFrameCenter_z"/>
1960 # <rotationref ref="rIdentity"/>
1961 # </physvol>
1962 #-->
1963 #EOF
1964  print CRYO <<EOF;
1965  <physvol>
1966  <volumeref ref="volAPAFrameYSide"/>
1967  <position name="posAPAFrameYSideNeg\-$APA_i" unit="cm"
1968  x="@{[$APAFrameCenter_x]}"
1969  y="@{[$APAFrameCenter_y]}"
1970  z="@{[$APAFrameCenter_z - $APAFrame_z/2 + $APAFrameYSide_z/2]}"/>
1971  <rotationref ref="rIdentity"/>
1972  </physvol>
1973  <physvol>
1974  <volumeref ref="volAPAFrameYSide"/>
1975  <position name="posAPAFrameYSidePos\-$APA_i" unit="cm"
1976  x="@{[$APAFrameCenter_x]}"
1977  y="@{[$APAFrameCenter_y]}"
1978  z="@{[$APAFrameCenter_z + $APAFrame_z/2 - $APAFrameYSide_z/2]}"/>
1979  <rotationref ref="rIdentity"/>
1980  </physvol>
1981  <physvol>
1982  <volumeref ref="volAPAFrameZSide"/>
1983  <position name="posAPAFrameZSidePos\-$APA_i" unit="cm"
1984  x="@{[$APAFrameCenter_x]}"
1985  y="@{[$APAFrameCenter_y + $APAFrame_y/2 - $APAFrameZSide_y/2]}"
1986  z="@{[$APAFrameCenter_z]}"/>
1987  <rotationref ref="rIdentity"/>
1988  </physvol>
1989  <physvol>
1990  <volumeref ref="volAPAFrameZSide"/>
1991  <position name="posAPAFrameZSideNeg\-$APA_i" unit="cm"
1992  x="@{[$APAFrameCenter_x]}"
1993  y="@{[$APAFrameCenter_y - $APAFrame_y/2 + $APAFrameZSide_y/2]}"
1994  z="@{[$APAFrameCenter_z]}"/>
1995  <rotationref ref="rIdentity"/>
1996  </physvol>
1997 
1998 
1999  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2000  - Add the *parts* of the G10 boards that exist directly in volCryostat.
2001  - There are two boards on each the up and downstream end,
2002  one each to wrap the U and V views around the APA frame
2003  - There are 4 on the bottom which anchor the U V and Z wires and the grid plane
2004  - The rest of the parts of the G10 boards must be placed directly in volTPC -->
2005 
2006  <physvol>
2007  <volumeref ref="volG10BoardYSideCenterSeg"/>
2008  <position name="posG10BoardYSideCenterSeg\-Vup\-$APA_i" unit="cm"
2009  x="@{[$APAFrameCenter_x]}"
2010  y="@{[$APAFrameCenter_y]}"
2011  z="@{[$APAFrameCenter_z - $APAFrame_z/2 - (0+.5)*($G10BoardYSide_z)]}"/>
2012  <rotationref ref="rIdentity"/>
2013  </physvol>
2014  <physvol>
2015  <volumeref ref="volG10BoardYSideCenterSeg"/>
2016  <position name="posG10BoardYSideCenterSeg\-Uup\-$APA_i" unit="cm"
2017  x="@{[$APAFrameCenter_x]}"
2018  y="@{[$APAFrameCenter_y]}"
2019  z="@{[$APAFrameCenter_z - $APAFrame_z/2 - (1+.5)*($G10BoardYSide_z)]}"/>
2020  <rotationref ref="rIdentity"/>
2021  </physvol>
2022 
2023  <physvol>
2024  <volumeref ref="volG10BoardYSideCenterSeg"/>
2025  <position name="posG10BoardYSideCenterSeg\-Vdown\-$APA_i" unit="cm"
2026  x="@{[$APAFrameCenter_x]}"
2027  y="@{[$APAFrameCenter_y]}"
2028  z="@{[$APAFrameCenter_z + $APAFrame_z/2 + (0+.5)*($G10BoardYSide_z)]}"/>
2029  <rotationref ref="rIdentity"/>
2030  </physvol>
2031  <physvol>
2032  <volumeref ref="volG10BoardYSideCenterSeg"/>
2033  <position name="posG10BoardYSideCenterSeg\-Udown\-$APA_i" unit="cm"
2034  x="@{[$APAFrameCenter_x]}"
2035  y="@{[$APAFrameCenter_y]}"
2036  z="@{[$APAFrameCenter_z + $APAFrame_z/2 + (1+.5)*($G10BoardYSide_z)]}"/>
2037  <rotationref ref="rIdentity"/>
2038  </physvol>
2039 
2040  <physvol>
2041  <volumeref ref="volG10BoardZSideCenterSeg"/>
2042  <position name="posG10BoardZSideCenterSeg\-Z\-$APA_i" unit="cm"
2043  x="@{[$APAFrameCenter_x]}"
2044  y="@{[$posG10ZSideZ_y]}"
2045  z="@{[$APAFrameCenter_z]}"/>
2046  <rotationref ref="rIdentity"/>
2047  </physvol>
2048  <physvol>
2049  <volumeref ref="volG10BoardZSideCenterSeg"/>
2050  <position name="posG10BoardZSideCenterSeg\-V\-$APA_i" unit="cm"
2051  x="@{[$APAFrameCenter_x]}"
2052  y="@{[$posG10ZSideV_y]}"
2053  z="@{[$APAFrameCenter_z]}"/>
2054  <rotationref ref="rIdentity"/>
2055  </physvol>
2056  <physvol>
2057  <volumeref ref="volG10BoardZSideCenterSeg"/>
2058  <position name="posG10BoardZSideCenterSeg\-U\-$APA_i" unit="cm"
2059  x="@{[$APAFrameCenter_x]}"
2060  y="@{[$posG10ZSideU_y]}"
2061  z="@{[$APAFrameCenter_z]}"/>
2062  <rotationref ref="rIdentity"/>
2063  </physvol>
2064  <physvol>
2065  <volumeref ref="volG10BoardZSideCenterSeg"/>
2066  <position name="posG10BoardZSideCenterSeg\-Grid\-$APA_i" unit="cm"
2067  x="@{[$APAFrameCenter_x]}"
2068  y="@{[$posG10ZSideGrid_y]}"
2069  z="@{[$APAFrameCenter_z]}"/>
2070  <rotationref ref="rIdentity"/>
2071  </physvol>
2072 
2073 EOF
2074 
2075 
2076 }
2077 
2078 
2079 
2080 
2081 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2082 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
2083 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2084 
2085 sub gen_Enclosure()
2086 {
2087 
2088 # Create the detector enclosure fragment file name,
2089 # add file to list of output GDML fragments,
2090 # and open it
2091  $ENCL = "dune10kt_v4_DetEnclosure" . $suffix . ".gdml";
2092  push (@gdmlFiles, $ENCL);
2093  $ENCL = ">" . $ENCL;
2094  open(ENCL) or die("Could not open file $ENCL for writing");
2095 
2096 
2097 # The standard XML prefix and starting the gdml
2098  print ENCL <<EOF;
2099 <?xml version='1.0'?>
2100 <gdml>
2101 EOF
2102 
2103 
2104 # All the detector enclosure solids.
2105 print ENCL <<EOF;
2106 <solids>
2107 
2108  <box name="FoamPadBlock" lunit="cm"
2109  x="@{[$Cryostat_x + 2*$FoamPadding]}"
2110  y="@{[$Cryostat_y + 2*$FoamPadding]}"
2111  z="@{[$Cryostat_z + 2*$FoamPadding]}" />
2112 
2113  <box name="FoamPadInner" lunit="cm"
2114  x="@{[$Cryostat_x + 0.01]}"
2115  y="@{[$Cryostat_y + 0.01]}"
2116  z="@{[$Cryostat_z + 0.01]}" />
2117 
2118  <subtraction name="FoamPadding">
2119  <first ref="FoamPadBlock"/>
2120  <second ref="FoamPadInner"/>
2121  <positionref ref="posCenter"/>
2122  </subtraction>
2123 
2124  <box name="SteelSupportBlock" lunit="cm"
2125  x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
2126  y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
2127  z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
2128 
2129  <box name="SteelSupportInner" lunit="cm"
2130  x="@{[$Cryostat_x + 2*$FoamPadding + 0.01]}"
2131  y="@{[$Cryostat_y + 2*$FoamPadding + 0.01]}"
2132  z="@{[$Cryostat_z + 2*$FoamPadding + 0.01]}" />
2133 
2134  <subtraction name="SteelSupport">
2135  <first ref="SteelSupportBlock"/>
2136  <second ref="SteelSupportInner"/>
2137  <positionref ref="posCenter"/>
2138  </subtraction>
2139 
2140  <box name="DetEnclosure" lunit="cm"
2141  x="@{[$DetEncWidth]}"
2142  y="@{[$DetEncHeight]}"
2143  z="@{[$DetEncLength]}"/>
2144 
2145 </solids>
2146 EOF
2147 
2148 
2149 
2150 # Detector enclosure structure
2151  print ENCL <<EOF;
2152 <structure>
2153  <volume name="volFoamPadding">
2154  <materialref ref="FD_foam"/>
2155  <solidref ref="FoamPadding"/>
2156  </volume>
2157 
2158  <volume name="volSteelSupport">
2159  <materialref ref="AirSteelMixture"/>
2160  <solidref ref="SteelSupport"/>
2161  </volume>
2162 
2163  <volume name="volDetEnclosure">
2164  <materialref ref="Air"/>
2165  <solidref ref="DetEnclosure"/>
2166 
2167  <physvol>
2168  <volumeref ref="volFoamPadding"/>
2169  <positionref ref="posCryoInDetEnc"/>
2170  </physvol>
2171  <physvol>
2172  <volumeref ref="volSteelSupport"/>
2173  <positionref ref="posCryoInDetEnc"/>
2174  </physvol>
2175  <physvol>
2176  <volumeref ref="volCryostat"/>
2177  <positionref ref="posCryoInDetEnc"/>
2178  </physvol>
2179 EOF
2180 
2181 
2182 
2183  print ENCL <<EOF;
2184  </volume>
2185 EOF
2186 
2187 print ENCL <<EOF;
2188 </structure>
2189 </gdml>
2190 EOF
2191 
2192 close(ENCL);
2193 }
2194 
2195 
2196 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2197 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
2198 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2199 
2200 sub gen_World()
2201 {
2202 
2203 # Create the WORLD fragment file name,
2204 # add file to list of output GDML fragments,
2205 # and open it
2206  $WORLD = "dune10kt_v4_World" . $suffix . ".gdml";
2207  push (@gdmlFiles, $WORLD);
2208  $WORLD = ">" . $WORLD;
2209  open(WORLD) or die("Could not open file $WORLD for writing");
2210 
2211 
2212 # The standard XML prefix and starting the gdml
2213  print WORLD <<EOF;
2214 <?xml version='1.0'?>
2215 <gdml>
2216 EOF
2217 
2218 
2219 # All the World solids.
2220 print WORLD <<EOF;
2221 <solids>
2222  <box name="World" lunit="cm"
2223  x="@{[$DetEncWidth+2*$RockThickness]}"
2224  y="@{[$DetEncHeight+2*$RockThickness]}"
2225  z="@{[$DetEncLength+2*$RockThickness]}"/>
2226 </solids>
2227 EOF
2228 
2229 # World structure
2230 print WORLD <<EOF;
2231 <structure>
2232  <volume name="volWorld" >
2233  <materialref ref="DUSEL_Rock"/>
2234  <solidref ref="World"/>
2235 
2236  <physvol>
2237  <volumeref ref="volDetEnclosure"/>
2238  <position name="posDetEnclosure" unit="cm" x="@{[$OriginXSet]}" y="@{[$OriginYSet]}" z="@{[$OriginZSet]}"/>
2239  </physvol>
2240 
2241  </volume>
2242 </structure>
2243 </gdml>
2244 EOF
2245 
2246 # make_gdml.pl will take care of <setup/>
2247 
2248 close(WORLD);
2249 }
2250 
2251 
2252 
2253 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2254 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
2255 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2256 
2257 sub write_fragments()
2258 {
2259  # This subroutine creates an XML file that summarizes the the subfiles output
2260  # by the other sub routines - it is the input file for make_gdml.pl which will
2261  # give the final desired GDML file. Specify its name with the output option.
2262  # (you can change the name when running make_gdml)
2263 
2264  # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
2265 
2266  if ( ! defined $output )
2267  {
2268  $output = "-"; # write to STDOUT
2269  }
2270 
2271  # Set up the output file.
2272  $OUTPUT = ">" . $output;
2273  open(OUTPUT) or die("Could not open file $OUTPUT");
2274 
2275  print OUTPUT <<EOF;
2276 <?xml version='1.0'?>
2277 
2278 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
2279  that will be zipped together to create a detector description.
2280  -->
2281 
2282 <config>
2283 
2284  <constantfiles>
2285 
2286  <!-- These files contain GDML <constant></constant>
2287  blocks. They are read in separately, so they can be
2288  interpreted into the remaining GDML. See make_gdml.pl for
2289  more information.
2290  -->
2291 
2292 EOF
2293 
2294  foreach $filename (@defFiles)
2295  {
2296  print OUTPUT <<EOF;
2297  <filename> $filename </filename>
2298 EOF
2299  }
2300 
2301  print OUTPUT <<EOF;
2302 
2303  </constantfiles>
2304 
2305  <gdmlfiles>
2306 
2307  <!-- The GDML file fragments to be zipped together. -->
2308 
2309 EOF
2310 
2311  foreach $filename (@gdmlFiles)
2312  {
2313  print OUTPUT <<EOF;
2314  <filename> $filename </filename>
2315 EOF
2316  }
2317 
2318  print OUTPUT <<EOF;
2319 
2320  </gdmlfiles>
2321 
2322 </config>
2323 EOF
2324 
2325  close(OUTPUT);
2326 }
2327 
2328 
2329 
2330 # run the sub routines that generate the fragments
2331 
2332 gen_Define(); # generates definitions at beginning of GDML
2333 gen_Materials(); # generates materials to be used
2334 
2335 
2336  gen_TPC( $TPCInner_x, $TPC_y, $TPC_z, 'Inner');
2337  gen_TPC( $TPCOuter_x, $TPC_y, $TPC_z, 'Outer');
2338 
2339 close $wout;
2340 
2341 gen_Cryostat(); # places (2*nAPAWide x nAPAHigh x nAPALong) volTPC,
2342  # half rotated 180 about Y
2343 gen_Enclosure(); # places two cryostats and concrete volumes
2344 
2345 gen_World(); # places the enclosure among DUSEL Rock
2346 
2347 
2348 write_fragments(); # writes the XML input for make_gdml.pl
2349  # which zips together the final GDML
2350 exit;