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