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