5 # First attempt to make a GDML fragment generator for the DUNE vertical drift
6 # 10kt detector geometry with 3 views: +/- Xdeg for induction and 90 deg collection
7 # The lower chamber is not added yet.
8 # !!!NOTE!!!: the readout is on a positive Y plane (drift along horizontal X)
9 # due to current reco limitations)
10 # No photon detectors declared
11 # Simplified treatment of inter-module dead spaces
13 # Created: Thu Oct 1 16:45:27 CEST 2020
14 # Vyacheslav Galymov <vgalymov@ipnl.in2p3.fr>
17 # VG: Added defs to enable use in the refactored sim framework
18 # VG: 23.02.21 Adjust plane dimensions to fit a given number of ch per side
19 # VG: 23.02.21 Group CRUs in CRPs
20 # VG: 02.03.21 The length for the ROP is force to be the lenght
21 # given by nch_collection x pitch_collection
22 # Laura Paulucci (lpaulucc@fnal.gov): Sept 2021 PDS added.
23 # Use option -pds=1 for backup design (membrane only coverage).
24 # Default (pds=0) is the reference design (~4-pi).
25 # This is linked with a larger geometry to account for photon propagation, generate it with -k=4.
26 # Field Cage is turned on with reference and backup designs to match PDS option.
27 # For not including the pds, please use option -pds=-1
29 #################################################################################
31 # Each subroutine generates a fragment GDML file, and the last subroutine
32 # creates an XML file that make_gdml.pl will use to appropriately arrange
33 # the fragment GDML files to create the final desired DUNE GDML file,
34 # to be named by make_gdml output command
36 ##################################################################################
44 Math::BigFloat->precision(-16);
47 GetOptions( "help|h" => \$help,
48 "suffix|s:s" => \$suffix,
49 "output|o:s" => \$output,
50 "wires|w:s" => \$wires,
51 "workspace|k:s" => \$wkspc,
52 "pdsconfig|pds:s" => \$pdsconfig);
54 my $FieldCage_switch="on";
55 my $Cathode_switch="off";
59 # If the user requested help, print the usage notes and exit.
64 if ( ! defined $suffix )
66 # The user didn't supply a suffix, so append nothing to the file
72 # Otherwise, stick a "-" before the suffix, so that a suffix of
73 # "test" applied to filename.gdml becomes "filename-test.gdml".
74 $suffix = "-" . $suffix;
83 elsif ( $workspace != 0 )
85 print "\t\tCreating smaller workspace geometry.\n";
88 if ( ! defined $pdsconfig )
91 print "\t\tCreating reference design: 4-pi PDS converage.\n";
93 elsif ( $pdsconfig == 1 )
95 print "\t\tCreating backup design: membrane-only PDS coverage.\n";
98 # set wires on to be the default, unless given an input by the user
99 $wires_on = 1; # 1=on, 0=off
109 ##################################################################
110 ############## Parameters for One Readout Panel ##################
112 # parameters for 1.5 x 1.7 sub-unit Charge Readout Module / Unit
113 #$widthPCBActive = 169.0; # cm
114 #$lengthPCBActive = 150.0; # cm
116 # views and channel counts
117 %nChans = ('Ind1', 298, 'Ind1Bot', 100, 'Ind2', 298, 'Col', 304);
118 $nViews = keys %nChans;
119 #print "$nViews %nChans\n";
121 # first induction view
122 $wirePitchU = 0.7335; # cm
123 $wireAngleU = 150.0; # deg
125 # second induction view
126 $wirePitchV = 0.7335; # cm
127 $wireAngleV = 30.0; # deg
130 # last collection view
131 $wirePitchZ = 0.489; # cm
133 # force length to be equal to collection nch x pitch
134 $lengthPCBActive = $wirePitchZ * $nChans{'Col'};
135 $widthPCBActive = 167.7006;
138 $borderCRM = 0.0; # border space aroud each CRM
140 $widthCRM_active = $widthPCBActive;
141 $lengthCRM_active = $lengthPCBActive;
143 $widthCRM = $widthPCBActive + 2 * $borderCRM;
144 $lengthCRM = $lengthPCBActive + 2 * $borderCRM;
146 $borderCRP = 0.5; # cm
148 # number of CRMs in y and z
152 # create a smaller geometry
153 if( $workspace == 1 )
159 # create a smaller geometry
160 if( $workspace == 2 )
166 # create a smaller geometry
167 if( $workspace == 3 )
173 # create pds geometry
174 if( $workspace == 4 )
181 # calculate tpc area based on number of CRMs and their dimensions
182 # each CRP should have a 2x2 CRMs
183 $widthTPCActive = $nCRM_x * $widthCRM + $nCRM_x * $borderCRP; # around 1200 for full module
184 $lengthTPCActive = $nCRM_z * $lengthCRM + $nCRM_z * $borderCRP; # around 6000 for full module
186 # active volume dimensions
187 $driftTPCActive = 650.0;
189 # model anode strips as wires of some diameter
191 $ReadoutPlane = $nViews * $padWidth; # 3 readout planes (no space b/w)!
193 ##################################################################
194 ############## Parameters for TPC and inner volume ###############
196 # inner volume dimensions of the cryostat
201 # width of gas argon layer on top
202 $HeightGaseousAr = 100;
204 if( $workspace != 0 )
206 #active tpc + 1.0 m buffer on each side
207 $Argon_x = $driftTPCActive + $HeightGaseousAr + $ReadoutPlane + 100;
208 $Argon_y = $widthTPCActive + 200;
209 $Argon_z = $lengthTPCActive + 200;
213 # size of liquid argon buffer
214 $xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane;
215 $yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive);
216 $zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive);
219 $SteelThickness = 0.12; # membrane
221 $Cryostat_x = $Argon_x + 2*$SteelThickness;
222 $Cryostat_y = $Argon_y + 2*$SteelThickness;
223 $Cryostat_z = $Argon_z + 2*$SteelThickness;
225 ##################################################################
226 ############## DetEnc and World relevant parameters #############
228 $SteelSupport_x = 100;
229 $SteelSupport_y = 100;
230 $SteelSupport_z = 100;
232 $FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel
233 $FracMassOfAir = 1 - $FracMassOfSteel;
236 $SpaceSteelSupportToWall = 100;
237 $SpaceSteelSupportToCeiling = 100;
239 $DetEncX = $Cryostat_x
240 + 2*($SteelSupport_x + $FoamPadding) + $SpaceSteelSupportToCeiling;
242 $DetEncY = $Cryostat_y
243 + 2*($SteelSupport_y + $FoamPadding) + 2*$SpaceSteelSupportToWall;
245 $DetEncZ = $Cryostat_z
246 + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall;
248 $posCryoInDetEnc_x = - $DetEncX/2 + $SteelSupport_x + $FoamPadding + $Cryostat_x/2;
251 $RockThickness = 4000;
253 # We want the world origin to be vertically centered on active TPC
254 # This is to be added to the x and y position of every volume in volWorld
256 $OriginXSet = $DetEncX/2.0
261 - $driftTPCActive/2.0;
263 $OriginYSet = $DetEncY/2.0
264 - $SpaceSteelSupportToWall
269 - $widthTPCActive/2.0;
271 # We want the world origin to be at the very front of the fiducial volume.
272 # move it to the front of the enclosure, then back it up through the concrete/foam,
273 # then through the Cryostat shell, then through the upstream dead LAr (including the
274 # dead LAr on the edge of the TPC)
275 # This is to be added to the z position of every volume in volWorld
277 $OriginZSet = $DetEncZ/2.0
278 - $SpaceSteelSupportToWall
285 ##################################################################
286 ############## Field Cage Parameters ###############
287 $FieldShaperLongTubeLength = $lengthTPCActive;
288 $FieldShaperShortTubeLength = $widthTPCActive;
289 #$FieldShaperInnerRadius = 1.485;
290 #$FieldShaperOuterRadius = 1.685;
291 #$FieldShaperTorRad = 1.69;
292 $FieldShaperInnerRadius = 0.5; #cm
293 $FieldShaperOuterRadius = 2.285; #cm
294 $FieldShaperOuterRadiusSlim = 0.75; #cm
295 $FieldShaperTorRad = 2.3; #cm
297 $FieldShaperLength = $FieldShaperLongTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
298 $FieldShaperWidth = $FieldShaperShortTubeLength + 2*$FieldShaperOuterRadius+ 2*$FieldShaperTorRad;
300 $FieldShaperSeparation = 6.0; #cm
301 $NFieldShapers = ($driftTPCActive/$FieldShaperSeparation) - 1;
303 $FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2;
304 $FieldCageSizeY = $FieldShaperWidth+2;
305 $FieldCageSizeZ = $FieldShaperLength+2;
308 ####################################################################
309 ######################## ARAPUCA Dimensions ########################
312 $ArapucaOut_x = 65.0;
314 $ArapucaOut_z = 65.0;
318 $ArapucaAcceptanceWindow_x = 60.0;
319 $ArapucaAcceptanceWindow_y = 1.0;
320 $ArapucaAcceptanceWindow_z = 60.0;
321 $BlockPD_x = 0.5*$widthCRM_active - 6.35; #Sub-division of Frame (4 n x, 4 in z)
322 $BlockPD_z = 0.5*$lengthCRM_active - 6.25;
323 $GapPD = 0.5; #Size of supporting bars in Frame
324 $FrameToArapucaSpace = 1.0; #At this moment, should cover the thickness of Frame + small gap to prevent overlap. VALUE NEEDS TO BE CHECKED!!!
325 $FrameToArapucaSpaceLat = $yLArBuffer - 60.0; #Arapucas 60 cm behind FC. At this moment, should cover the thickness of Frame + small gap to prevent overlap. VALUE NEEDS TO BE CHECKED!!!
326 $VerticalPDdist = 75.0; #distance of arapucas (center to center) in the y direction
327 $HorizontalPDdist = 150.0; #distance of arapucas (center to center) in the x direction
329 #Positions of the 4 arapucas with respect to the Frame center --> arapucas over the cathode
330 $list_posx_bot[0]=-2*$BlockPD_x - 1.5*$GapPD + 0.5*$ArapucaOut_x;
331 $list_posz_bot[0]= 0.5*$BlockPD_z + $GapPD;
332 $list_posx_bot[1]=- $GapPD - 0.5*$ArapucaOut_x;
333 $list_posz_bot[1]=-1.5*$BlockPD_z - 1.5*$GapPD;
334 $list_posx_bot[2]=-$list_posx_bot[1];
335 $list_posz_bot[2]=-$list_posz_bot[1];
336 $list_posx_bot[3]=-$list_posx_bot[0];
337 $list_posz_bot[3]=-$list_posz_bot[0];
340 #+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++
343 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
344 #+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++
345 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
349 print "Usage: $0 [-h|--help] [-o|--output <fragments-file>] [-s|--suffix <string>]\n";
350 print " if -o is omitted, output goes to STDOUT; <fragments-file> is input to make_gdml.pl\n";
351 print " -s <string> appends the string to the file names; useful for multiple detector versions\n";
352 print " -h prints this message, then quits\n";
359 # Create the <define> fragment file name,
360 # add file to list of fragments,
362 $DEF = $basename."_Ext" . $suffix . ".gdml";
363 push (@gdmlFiles, $DEF);
365 open(DEF) or die("Could not open file $DEF for writing");
368 <?xml version='1.0'?>
371 <color name="magenta" R="0.0" G="1.0" B="0.0" A="1.0" />
372 <color name="green" R="0.0" G="1.0" B="0.0" A="1.0" />
373 <color name="red" R="1.0" G="0.0" B="0.0" A="1.0" />
374 <color name="blue" R="0.0" G="0.0" B="1.0" A="1.0" />
375 <color name="yellow" R="1.0" G="1.0" B="0.0" A="1.0" />
382 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
383 #++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++
384 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
389 # Create the <define> fragment file name,
390 # add file to list of fragments,
392 $DEF = $basename."_Def" . $suffix . ".gdml";
393 push (@gdmlFiles, $DEF);
395 open(DEF) or die("Could not open file $DEF for writing");
399 <?xml version='1.0'?>
409 <position name="posCryoInDetEnc" unit="cm" x="$posCryoInDetEnc_x" y="0" z="0"/>
410 <position name="posCenter" unit="cm" x="0" y="0" z="0"/>
411 <rotation name="rUWireAboutX" unit="deg" x="$wireAngleU" y="0" z="0"/>
412 <rotation name="rVWireAboutX" unit="deg" x="$wireAngleV" y="0" z="0"/>
413 <rotation name="rPlus90AboutX" unit="deg" x="90" y="0" z="0"/>
414 <rotation name="rPlus90AboutY" unit="deg" x="0" y="90" z="0"/>
415 <rotation name="rPlus90AboutXPlus90AboutY" unit="deg" x="90" y="90" z="0"/>
416 <rotation name="rMinus90AboutX" unit="deg" x="270" y="0" z="0"/>
417 <rotation name="rMinus90AboutY" unit="deg" x="0" y="270" z="0"/>
418 <rotation name="rMinus90AboutYMinus90AboutX" unit="deg" x="270" y="270" z="0"/>
419 <rotation name="rPlus180AboutX" unit="deg" x="180" y="0" z="0"/>
420 <rotation name="rPlus180AboutY" unit="deg" x="0" y="180" z="0"/>
421 <rotation name="rPlus180AboutXPlus180AboutY" unit="deg" x="180" y="180" z="0"/>
422 <rotation name="rIdentity" unit="deg" x="0" y="0" z="0"/>
429 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
430 #+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++
431 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
436 # Create the <materials> fragment file name,
437 # add file to list of output GDML fragments,
439 $MAT = $basename."_Materials" . $suffix . ".gdml";
440 push (@gdmlFiles, $MAT);
443 open(MAT) or die("Could not open file $MAT for writing");
445 # Add any materials special to this geometry by defining a mulitline string
446 # and passing it to the gdmlMaterials::gen_Materials() function.
448 <!-- preliminary values -->
449 <material name="AirSteelMixture" formula="AirSteelMixture">
450 <D value=" 0.001205*(1-$FracMassOfSteel) + 7.9300*$FracMassOfSteel " unit="g/cm3"/>
451 <fraction n="$FracMassOfSteel" ref="STEEL_STAINLESS_Fe7Cr2Ni"/>
452 <fraction n="$FracMassOfAir" ref="Air"/>
454 <material name="vm2000" formula="vm2000">
455 <D value="1.2" unit="g/cm3"/>
456 <composite n="2" ref="carbon"/>
457 <composite n="4" ref="hydrogen"/>
461 # add the general materials used anywere
462 print MAT gdmlMaterials::gen_Materials( $asmix );
468 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
469 #++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++
470 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
471 # line clip on the rectangle boundary
482 if( abs( nx ) < tol ){
483 push( @endpts, ($x0, 0) );
484 push( @endpts, ($x0, $rcw) );
487 if( abs( ny ) < tol ){
488 push( @endpts, (0, $y0) );
489 push( @endpts, ($rcl, $y0) );
493 # left border at x = 0
494 my $y = $y0 - $x0 * $ny/$nx;
495 if( $y >= 0 && $y <= $rcw ){
496 push( @endpts, (0, $y) );
499 # right border at x = l
500 $y = $y0 + ($rcl-$x0) * $ny/$nx;
501 if( $y >= 0 && $y <= $rcw ){
502 push( @endpts, ($rcl, $y) );
503 if( scalar(@endpts) == 4 ){
508 # bottom border at y = 0
509 my $x = $x0 - $y0 * $nx/$ny;
510 if( $x >= 0 && $x <= $rcl ){
511 push( @endpts, ($x, 0) );
512 if( scalar(@endpts) == 4 ){
517 # top border at y = w
518 $x = $x0 + ($rcw-$y0)* $nx/$ny;
519 if( $x >= 0 && $x <= $rcl ){
520 push( @endpts, ($x, $rcw) );
528 my $length = $_[0]; #
531 my $nchb = $_[3]; # nch per bottom side
533 my $theta = $_[5]; # deg
536 $theta = $theta * pi()/180.0;
537 my @dirw = (cos($theta), sin($theta));
538 my @dirp = (cos($theta - pi()/2), sin($theta - pi()/2));
542 if( $alpha > pi()/2 ){
543 $alpha = pi() - $alpha;
545 my $dX = $pitch / sin( $alpha );
546 my $dY = $pitch / sin( pi()/2 - $alpha );
548 $length = $dX * $nchb;
551 $width = $dY * ($nch - $nchb);
562 #print "origin : @orig\n";
563 #print "pitch dir : @dirp\n";
564 #print "wire dir : @dirw\n";
565 #print "$length x $width cm2\n";
569 my $offset = $pitch/2;
570 foreach my $ch (0..$nch-1){
571 #print "Processing $ch\n";
573 # calculate reference point for this strip
575 $wcn[0] = $orig[0] + $offset * $dirp[0];
576 $wcn[1] = $orig[1] + $offset * $dirp[1];
578 # line clip on the rectangle boundary
579 @endpts = lineClip( $wcn[0], $wcn[1], $dirw[0], $dirw[1], $length, $width );
581 if( scalar(@endpts) != 4 ){
582 print "Could not find end points for wire $ch : @endpts\n";
583 $offset = $offset + $pitch;
587 # re-center on the mid-point
588 $endpts[0] -= $length/2;
589 $endpts[2] -= $length/2;
590 $endpts[1] -= $width/2;
591 $endpts[3] -= $width/2;
593 # calculate the strip center in the rectangle of CRU
594 $wcn[0] = ($endpts[0] + $endpts[2])/2;
595 $wcn[1] = ($endpts[1] + $endpts[3])/2;
597 # calculate the length
598 my $dx = $endpts[0] - $endpts[2];
599 my $dy = $endpts[1] - $endpts[3];
600 my $wlen = sqrt($dx**2 + $dy**2);
602 # put all info together
603 my @wire = ($ch, $wcn[0], $wcn[1], $wlen);
604 push( @wire, @endpts );
605 push( @winfo, \@wire);
606 $offset = $offset + $pitch;
616 my $TPCActive_x = $driftTPCActive;
617 my $TPCActive_y = $widthCRM_active;
618 my $TPCActive_z = $lengthCRM_active;
621 my $TPC_x = $TPCActive_x + $ReadoutPlane;
622 my $TPC_y = $widthCRM;
623 my $TPC_z = $lengthCRM;
625 print " TPC dimensions : $TPC_x x $TPC_y x $TPC_z\n";
627 $TPC = $basename."_TPC" . $suffix . ".gdml";
628 push (@gdmlFiles, $TPC);
630 open(TPC) or die("Could not open file $TPC for writing");
632 # The standard XML prefix and starting the gdml
634 <?xml version='1.0'?>
638 # compute wires for 1st induction
641 if( $wires_on == 1 ){
642 @winfoU = gen_Wires( $TPCActive_z, 0, # force length
643 $nChans{'Ind1'}, $nChans{'Ind1Bot'},
644 $wirePitchU, $wireAngleU, $padWidth );
645 @winfoV = gen_Wires( $TPCActive_z, 0, # force length
646 $nChans{'Ind2'}, $nChans{'Ind1Bot'},
647 $wirePitchV, $wireAngleV, $padWidth );
651 # All the TPC solids save the wires.
662 <box name="CRMUPlane"
667 <box name="CRMVPlane"
672 <box name="CRMZPlane"
677 <box name="CRMActive"
684 #++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++
687 foreach my $wire (@winfoU) {
688 my $wid = $wire->[0];
689 my $wln = $wire->[3];
691 <tube name="CRMWireU$wid"
695 aunit="deg" lunit="cm"/>
699 foreach my $wire (@winfoV) {
700 my $wid = $wire->[0];
701 my $wln = $wire->[3];
703 <tube name="CRMWireV$wid"
707 aunit="deg" lunit="cm"/>
713 <tube name="CRMWireZ"
717 aunit="deg" lunit="cm"/>
725 # Begin structure and create wire logical volumes
728 <volume name="volTPCActive">
729 <materialref ref="LAr"/>
730 <solidref ref="CRMActive"/>
731 <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
732 <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5208*cm"/>
733 <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="500*V/cm"/>
734 <colorref ref="blue"/>
740 foreach my $wire (@winfoU)
742 my $wid = $wire->[0];
744 <volume name="volTPCWireU$wid">
745 <materialref ref="Copper_Beryllium_alloy25"/>
746 <solidref ref="CRMWireU$wid"/>
751 foreach my $wire (@winfoV)
753 my $wid = $wire->[0];
755 <volume name="volTPCWireV$wid">
756 <materialref ref="Copper_Beryllium_alloy25"/>
757 <solidref ref="CRMWireV$wid"/>
763 <volume name="volTPCWireZ">
764 <materialref ref="Copper_Beryllium_alloy25"/>
765 <solidref ref="CRMWireZ"/>
769 # 1st induction plane
771 <volume name="volTPCPlaneU">
772 <materialref ref="LAr"/>
773 <solidref ref="CRMUPlane"/>
775 if ($wires_on==1) # add wires to U plane
777 # the coordinates were computed with a corner at (0,0)
778 # so we need to move to plane coordinates
779 my $offsetZ = 0; #-0.5 * $TPCActive_z;
780 my $offsetY = 0; #-0.5 * $TPCActive_y;
782 foreach my $wire (@winfoU) {
783 my $wid = $wire->[0];
784 my $zpos = $wire->[1] + $offsetZ;
785 my $ypos = $wire->[2] + $offsetY;
788 <volumeref ref="volTPCWireU$wid"/>
789 <position name="posWireU$wid" unit="cm" x="0" y="$ypos" z="$zpos"/>
790 <rotationref ref="rUWireAboutX"/>
799 # 2nd induction plane
801 <volume name="volTPCPlaneV">
802 <materialref ref="LAr"/>
803 <solidref ref="CRMVPlane"/>
806 if ($wires_on==1) # add wires to V plane (plane with wires reading y position)
808 # the coordinates were computed with a corner at (0,0)
809 # so we need to move to plane coordinates
810 my $offsetZ = 0; #-0.5 * $TPCActive_z;
811 my $offsetY = 0; #-0.5 * $TPCActive_y;
813 foreach my $wire (@winfoV) {
814 my $wid = $wire->[0];
815 my $zpos = $wire->[1] + $offsetZ;
816 my $ypos = $wire->[2] + $offsetY;
819 <volumeref ref="volTPCWireV$wid"/>
820 <position name="posWireV$wid" unit="cm" x="0" y="$ypos" z="$zpos"/>
821 <rotationref ref="rVWireAboutX"/>
832 <volume name="volTPCPlaneZ">
833 <materialref ref="LAr"/>
834 <solidref ref="CRMZPlane"/>
836 if ($wires_on==1) # add wires to Z plane (plane with wires reading z position)
838 for($i=0;$i<$nChans{'Col'};++$i)
840 #my $zpos = -0.5 * $TPCActive_z + ($i+0.5)*$wirePitchZ + 0.5*$padWidth;
841 my $zpos = ($i + 0.5 - $nChans{'Col'}/2)*$wirePitchZ;
842 if( (0.5 * $TPCActive_z - abs($zpos)) < 0 ){
843 die "Cannot place wire $i in view Z, as plane is too small\n";
847 <volumeref ref="volTPCWireZ"/>
848 <position name="posWireZ$i" unit="cm" x="0" y="0" z="$zpos"/>
849 <rotationref ref="rPlus90AboutX"/>
859 $posUplane[0] = 0.5*$TPC_x - 2.5*$padWidth;
863 $posVplane[0] = 0.5*$TPC_x - 1.5*$padWidth;
867 $posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth;
871 $posTPCActive[0] = -$ReadoutPlane/2;
872 $posTPCActive[1] = 0;
873 $posTPCActive[2] = 0;
876 #wrap up the TPC file
878 <volume name="volTPC">
879 <materialref ref="LAr"/>
880 <solidref ref="CRM"/>
882 <volumeref ref="volTPCPlaneU"/>
883 <position name="posPlaneU" unit="cm"
884 x="$posUplane[0]" y="$posUplane[1]" z="$posUplane[2]"/>
885 <rotationref ref="rIdentity"/>
888 <volumeref ref="volTPCPlaneV"/>
889 <position name="posPlaneY" unit="cm"
890 x="$posVplane[0]" y="$posVplane[1]" z="$posVplane[2]"/>
891 <rotationref ref="rIdentity"/>
894 <volumeref ref="volTPCPlaneZ"/>
895 <position name="posPlaneZ" unit="cm"
896 x="$posZplane[0]" y="$posZplane[1]" z="$posZplane[2]"/>
897 <rotationref ref="rIdentity"/>
900 <volumeref ref="volTPCActive"/>
901 <position name="posActive" unit="cm"
902 x="$posTPCActive[0]" y="$posTPCAtive[1]" z="$posTPCActive[2]"/>
903 <rotationref ref="rIdentity"/>
916 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
917 #++++++++++++++++++++++++++++++++++++++ gen_FieldCage ++++++++++++++++++++++++++++++++++++
918 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
922 $FieldCage = $basename."_FieldCage" . $suffix . ".gdml";
923 push (@gdmlFiles, $FieldCage);
924 $FieldCage = ">" . $FieldCage;
925 open(FieldCage) or die("Could not open file $FieldCage for writing");
927 # The standard XML prefix and starting the gdml
928 print FieldCage <<EOF;
929 <?xml version='1.0'?>
932 # The printing solids used in the Field Cage
933 #print "lengthTPCActive : $lengthTPCActive \n";
934 #print "widthTPCActive : $widthTPCActive \n";
937 print FieldCage <<EOF;
939 <torus name="FieldShaperCorner" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" rtor="$FieldShaperTorRad" deltaphi="90" startphi="0" aunit="deg" lunit="cm"/>
940 <tube name="FieldShaperLongtube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
941 <tube name="FieldShaperLongtubeSlim" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadiusSlim" z="$FieldShaperLongTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
942 <tube name="FieldShaperShorttube" rmin="$FieldShaperInnerRadius" rmax="$FieldShaperOuterRadius" z="$FieldShaperShortTubeLength" deltaphi="360" startphi="0" aunit="deg" lunit="cm"/>
944 <union name="FSunion1">
945 <first ref="FieldShaperLongtube"/>
946 <second ref="FieldShaperCorner"/>
947 <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
948 <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
951 <union name="FSunion2">
952 <first ref="FSunion1"/>
953 <second ref="FieldShaperShorttube"/>
954 <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
955 <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
958 <union name="FSunion3">
959 <first ref="FSunion2"/>
960 <second ref="FieldShaperCorner"/>
961 <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
962 <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
965 <union name="FSunion4">
966 <first ref="FSunion3"/>
967 <second ref="FieldShaperLongtube"/>
968 <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
971 <union name="FSunion5">
972 <first ref="FSunion4"/>
973 <second ref="FieldShaperCorner"/>
974 <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
975 <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
978 <union name="FSunion6">
979 <first ref="FSunion5"/>
980 <second ref="FieldShaperShorttube"/>
981 <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
982 <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
985 <union name="FieldShaperSolid">
986 <first ref="FSunion6"/>
987 <second ref="FieldShaperCorner"/>
988 <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
989 <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
992 <union name="FSunionSlim1">
993 <first ref="FieldShaperLongtubeSlim"/>
994 <second ref="FieldShaperCorner"/>
995 <position name="esquinapos1" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
996 <rotation name="rot1" unit="deg" x="90" y="0" z="0" />
999 <union name="FSunionSlim2">
1000 <first ref="FSunionSlim1"/>
1001 <second ref="FieldShaperShorttube"/>
1002 <position name="esquinapos2" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[+0.5*$FieldShaperLongTubeLength+$FieldShaperTorRad]}"/>
1003 <rotation name="rot2" unit="deg" x="0" y="90" z="0" />
1006 <union name="FSunionSlim3">
1007 <first ref="FSunionSlim2"/>
1008 <second ref="FieldShaperCorner"/>
1009 <position name="esquinapos3" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[0.5*$FieldShaperLongTubeLength]}"/>
1010 <rotation name="rot3" unit="deg" x="90" y="270" z="0" />
1013 <union name="FSunionSlim4">
1014 <first ref="FSunionSlim3"/>
1015 <second ref="FieldShaperLongtubeSlim"/>
1016 <position name="esquinapos4" unit="cm" x="@{[-$FieldShaperShortTubeLength-2*$FieldShaperTorRad]}" y="0" z="0"/>
1019 <union name="FSunionSlim5">
1020 <first ref="FSunionSlim4"/>
1021 <second ref="FieldShaperCorner"/>
1022 <position name="esquinapos5" unit="cm" x="@{[-$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
1023 <rotation name="rot5" unit="deg" x="90" y="180" z="0" />
1026 <union name="FSunionSlim6">
1027 <first ref="FSunionSlim5"/>
1028 <second ref="FieldShaperShorttube"/>
1029 <position name="esquinapos6" unit="cm" x="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength-$FieldShaperTorRad]}"/>
1030 <rotation name="rot6" unit="deg" x="0" y="90" z="0" />
1033 <union name="FieldShaperSolidSlim">
1034 <first ref="FSunionSlim6"/>
1035 <second ref="FieldShaperCorner"/>
1036 <position name="esquinapos7" unit="cm" x="@{[-$FieldShaperTorRad]}" y="0" z="@{[-0.5*$FieldShaperLongTubeLength]}"/>
1037 <rotation name="rot7" unit="deg" x="90" y="90" z="0" />
1044 print FieldCage <<EOF;
1047 <volume name="volFieldShaper">
1048 <materialref ref="Al2O3"/>
1049 <solidref ref="FieldShaperSolid"/>
1051 <volume name="volFieldShaperSlim">
1052 <materialref ref="Al2O3"/>
1053 <solidref ref="FieldShaperSolidSlim"/>
1060 print FieldCage <<EOF;
1069 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1070 #++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++
1071 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1076 # Create the cryostat fragment file name,
1077 # add file to list of output GDML fragments,
1079 $CRYO = $basename."_Cryostat" . $suffix . ".gdml";
1080 push (@gdmlFiles, $CRYO);
1081 $CRYO = ">" . $CRYO;
1082 open(CRYO) or die("Could not open file $CRYO for writing");
1085 # The standard XML prefix and starting the gdml
1087 <?xml version='1.0'?>
1091 # All the cryostat solids.
1092 # External active are two side volumes for generating light outside the field cage (no top or bottom buffers included)
1095 <box name="Cryostat" lunit="cm"
1100 <box name="ArgonInterior" lunit="cm"
1105 <box name="GaseousArgon" lunit="cm"
1106 x="$HeightGaseousAr"
1110 <box name="ExternalAuxOut" lunit="cm"
1111 x="$Argon_x - $xLArBuffer"
1112 y="$Argon_y - 2*$ArapucaOut_y - 2*$FrameToArapucaSpaceLat"
1115 <box name="ExternalAuxIn" lunit="cm"
1120 <subtraction name="ExternalActive">
1121 <first ref="ExternalAuxOut"/>
1122 <second ref="ExternalAuxIn"/>
1125 <subtraction name="SteelShell">
1126 <first ref="Cryostat"/>
1127 <second ref="ArgonInterior"/>
1134 #Double sided detectors should only be included when both top and bottom volumes become available
1135 #Optical sensitive volumes cannot be rotated because Larsoft cannot pick up the rotation when obtinaing the lengths needed for the semi-analytic model --> two acceptance windows for single sided lateral and cathode
1138 <box name="ArapucaOut" lunit="cm"
1139 x="@{[$ArapucaOut_x]}"
1140 y="@{[$ArapucaOut_y]}"
1141 z="@{[$ArapucaOut_z]}"/>
1143 <box name="ArapucaIn" lunit="cm"
1144 x="@{[$ArapucaIn_x]}"
1145 y="@{[$ArapucaOut_y]}"
1146 z="@{[$ArapucaIn_z]}"/>
1148 <subtraction name="ArapucaWalls">
1149 <first ref="ArapucaOut"/>
1150 <second ref="ArapucaIn"/>
1151 <position name="posArapucaSub" x="0" y="@{[$ArapucaOut_y/2.0]}" z="0." unit="cm"/>
1154 <box name="ArapucaAcceptanceWindow" lunit="cm"
1155 x="@{[$ArapucaAcceptanceWindow_x]}"
1156 y="@{[$ArapucaAcceptanceWindow_y]}"
1157 z="@{[$ArapucaAcceptanceWindow_z]}"/>
1159 <box name="ArapucaDoubleIn" lunit="cm"
1160 x="@{[$ArapucaIn_x]}"
1161 y="@{[$ArapucaOut_y+1.0]}"
1162 z="@{[$ArapucaIn_z]}"/>
1164 <subtraction name="ArapucaDoubleWalls">
1165 <first ref="ArapucaOut"/>
1166 <second ref="ArapucaDoubleIn"/>
1167 <position name="posArapucaDoubleSub" x="0" y="0" z="0" unit="cm"/>
1170 <box name="ArapucaDoubleAcceptanceWindow" lunit="cm"
1171 x="@{[$ArapucaOut_y-0.02]}"
1172 y="@{[$ArapucaAcceptanceWindow_x]}"
1173 z="@{[$ArapucaAcceptanceWindow_z]}"/>
1175 <box name="ArapucaCathodeAcceptanceWindow" lunit="cm"
1176 x="@{[$ArapucaAcceptanceWindow_y]}"
1177 y="@{[$ArapucaAcceptanceWindow_x]}"
1178 z="@{[$ArapucaAcceptanceWindow_z]}"/>
1183 # Cryostat structure
1186 <volume name="volSteelShell">
1187 <materialref ref="STEEL_STAINLESS_Fe7Cr2Ni" />
1188 <solidref ref="SteelShell" />
1190 <volume name="volGaseousArgon">
1191 <materialref ref="ArGas"/>
1192 <solidref ref="GaseousArgon"/>
1194 <volume name="volExternalActive">
1195 <materialref ref="LAr"/>
1196 <solidref ref="ExternalActive"/>
1197 <auxiliary auxtype="SensDet" auxvalue="SimEnergyDeposit"/>
1198 <auxiliary auxtype="StepLimit" auxunit="cm" auxvalue="0.5208*cm"/>
1199 <auxiliary auxtype="Efield" auxunit="V/cm" auxvalue="0*V/cm"/>
1200 <colorref ref="green"/>
1203 #including single sided arapucas over the cathode while there is only the top volume
1204 #if double sided, use
1205 # <volume name="volArapucaDouble_$i\-$j\-$p">
1206 # <materialref ref="G10" />
1207 # <solidref ref="ArapucaDoubleWalls" />
1209 # <volume name="volOpDetSensitive_ArapucaDouble_$i\-$j\-$p">
1210 # <materialref ref="LAr"/>
1211 # <solidref ref="ArapucaDoubleAcceptanceWindow"/>
1213 if ($pdsconfig == 0){ #4-pi PDS converage
1214 for($i=0 ; $i<$nCRM_x/2 ; $i++){ #arapucas over the cathode
1215 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1216 for($p=0 ; $p<4 ; $p++){
1218 <volume name="volArapucaDouble_$i\-$j\-$p">
1219 <materialref ref="G10" />
1220 <solidref ref="ArapucaWalls" />
1222 <volume name="volOpDetSensitive_ArapucaDouble_$i\-$j\-$p">
1223 <materialref ref="LAr"/>
1224 <solidref ref="ArapucaCathodeAcceptanceWindow"/>
1232 if ($nCRM_x==8){ #arapucas on the laterals
1233 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1234 for($p=0 ; $p<8 ; $p++){
1236 <volume name="volArapucaLat_$j\-$p">
1237 <materialref ref="G10" />
1238 <solidref ref="ArapucaWalls" />
1240 <volume name="volOpDetSensitive_ArapucaLat_$j\-$p">
1241 <materialref ref="LAr"/>
1242 <solidref ref="ArapucaAcceptanceWindow"/>
1249 if ($pdsconfig == 1){ #Membrane PDS converage
1250 if ($nCRM_x==8) { #arapucas on the laterals
1251 for($j=0 ; $j<$nCRM_z/2 ; $j++){
1252 for($p=8 ; $p<18 ; $p++){
1254 <volume name="volArapucaLat_$j\-$p">
1255 <materialref ref="G10" />
1256 <solidref ref="ArapucaWalls" />
1258 <volume name="volOpDetSensitive_ArapucaLat_$j\-$p">
1259 <materialref ref="LAr"/>
1260 <solidref ref="ArapucaAcceptanceWindow"/>
1270 <volume name="volCryostat">
1271 <materialref ref="LAr" />
1272 <solidref ref="Cryostat" />
1274 <volumeref ref="volGaseousArgon"/>
1275 <position name="posGaseousArgon" unit="cm" x="@{[$Argon_x/2-$HeightGaseousAr/2]}" y="0" z="0"/>
1278 <volumeref ref="volSteelShell"/>
1279 <position name="posSteelShell" unit="cm" x="0" y="0" z="0"/>
1282 <volumeref ref="volExternalActive"/>
1283 <position name="posExternalActive" unit="cm" x="-$xLArBuffer/2" y="0" z="0"/>
1287 if ($tpc_on==1) # place TPC inside croysotat offsetting each pair of CRMs by borderCRP
1289 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1291 my $posZ = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCRM;
1292 for(my $ii=0;$ii<$nCRM_z;$ii++)
1295 $posZ += $borderCRP;
1297 $posZ += $borderCRP;
1300 my $posY = -0.5*$Argon_y + $yLArBuffer + 0.5*$widthCRM;
1301 for(my $jj=0;$jj<$nCRM_x;$jj++)
1304 $posY += $borderCRP;
1306 $posY += $borderCRP;
1311 <volumeref ref="volTPC"/>
1312 <position name="posTPC\-$idx" unit="cm"
1313 x="$posX" y="$posY" z="$posZ"/>
1320 $posZ += $lengthCRM;
1324 #The +50 in the x positions must depend on some other parameter
1325 if ( $FieldCage_switch eq "on" ) {
1326 for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) {
1327 $dist=$i*$FieldShaperSeparation;
1328 $posX = $Argon_x/2 - $HeightGaseousAr - 0.5*($driftTPCActive + $ReadoutPlane);
1333 <volumeref ref="volFieldShaperSlim"/>
1334 <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1335 <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1341 <volumeref ref="volFieldShaper"/>
1342 <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1343 <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1350 <volumeref ref="volFieldShaperSlim"/>
1351 <position name="posFieldShaper$i" unit="cm" x="@{[-$OriginXSet+50+($i-$NFieldShapers*0.5)*$FieldShaperSeparation]}" y="@{[-0.5*$FieldShaperShortTubeLength-$FieldShaperTorRad]}" z="0" />
1352 <rotation name="rotFS$i" unit="deg" x="0" y="0" z="90" />
1360 $CathodePosX =-$OriginXSet+50+(-1-$NFieldShapers*0.5)*$FieldShaperSeparation;
1363 if ( $Cathode_switch eq "on" )
1367 <volumeref ref="volGroundGrid"/>
1368 <position name="posGroundGrid01" unit="cm" x="$CathodePosX" y="@{[-$CathodePosY]}" z="@{[$CathodePosZ]}"/>
1369 <rotation name="rotGG01" unit="deg" x="0" y="0" z="90" />
1375 $FrameLenght_x= 2.0*$widthCRM_active;
1376 $FrameLenght_z= 2.0*$lengthCRM_active;
1378 if ($pdsconfig == 0) { #4-pi PDS converage
1380 #for placing the Arapucas over the cathode
1381 $FrameCenter_x=-1.5*$FrameLenght_x+(4-$nCRM_x/2)/2*$FrameLenght_x;
1382 $FrameCenter_y=$CathodePosX;
1383 $FrameCenter_z=-9.5*$FrameLenght_z+(20-$nCRM_z/2)/2*$FrameLenght_z;
1384 for($i=0;$i<$nCRM_x/2;$i++){
1385 for($j=0;$j<$nCRM_z/2;$j++){
1386 place_OpDetsCathode($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $i, $j);
1387 $FrameCenter_z+=$FrameLenght_z;
1389 $FrameCenter_x+=$FrameLenght_x;
1390 $FrameCenter_z=-9.5*$FrameLenght_z+(20-$nCRM_z/2)/2*$FrameLenght_z;
1394 if ($pdsconfig == 0) { #4-pi PDS converage
1395 #for placing the Arapucas on laterals
1397 $FrameCenter_y=$posZplane[0]; #anode position
1398 $FrameCenter_z=-19*$FrameLenght_z/2+(40-$nCRM_z)/2*$FrameLenght_z/2;
1399 for($j=0;$j<$nCRM_z/2;$j++){#nCRM will give the collumn number (1 collumn per frame)
1400 place_OpDetsLateral($FrameCenter_y, $FrameCenter_z, $j);
1401 $FrameCenter_z+=$FrameLenght_z;
1405 } else { #membrane only PDS converage
1407 if($pdsconfig == 1){
1409 $FrameCenter_y=$posZplane[0]; #anode position
1410 $FrameCenter_z=-19*$FrameLenght_z/2+(40-$nCRM_z)/2*$FrameLenght_z/2;
1411 for($j=0;$j<$nCRM_z/2;$j++){#nCRM will give the collumn number (1 collumn per frame)
1412 place_OpDetsMembOnly($FrameCenter_y, $FrameCenter_z, $j);
1413 $FrameCenter_z+=$FrameLenght_z;
1429 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1430 #++++++++++++++++++++++++++++++++++++ place_OpDets +++++++++++++++++++++++++++++++++++++++
1431 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1433 sub place_OpDetsCathode()
1436 $FrameCenter_x = $_[0];
1437 $FrameCenter_y = $_[1];
1438 $FrameCenter_z = $_[2];
1442 #Placing Arapucas over the Cathode
1443 #If there are both top and bottom volumes --> use double-sided:
1445 # <volumeref ref="volOpDetSensitive_ArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1446 # <position name="posOpArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1452 for ($ara = 0; $ara<4; $ara++)
1454 # All Arapuca centers will have the same Y coordinate
1455 # X and Z coordinates are defined with respect to the center of the current Frame
1457 $Ara_Y = $FrameCenter_x+$list_posx_bot[$ara]; #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1458 $Ara_X = $FrameCenter_y + $FrameToArapucaSpace;
1459 $Ara_Z = $FrameCenter_z+$list_posz_bot[$ara];
1463 <volumeref ref="volArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1464 <position name="posArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1468 <rotation name="rPlus90AboutXPlus90AboutZ" unit="deg" x="90" y="0" z="90"/>
1471 <volumeref ref="volOpDetSensitive_ArapucaDouble_$Frame_x\-$Frame_z\-$ara"/>
1472 <position name="posOpArapucaDouble$ara-Frame\-$Frame_x\-$Frame_z" unit="cm"
1473 x="@{[$Ara_X+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01]}"
1484 sub place_OpDetsLateral()
1487 $FrameCenter_y = $_[0];
1488 $FrameCenter_z = $_[1];
1491 #Placing Arapucas on the laterals if nCRM_x=8 -- Single Sided
1492 for ($ara = 0; $ara<8; $ara++)
1494 # Arapucas on laterals
1495 # All Arapuca centers on a given collumn will have the same Z coordinate
1496 # X coordinates are on the left and right laterals
1497 # Y coordinates are defined with respect to the cathode position
1498 # There are two collumns per frame on each side.
1500 if ($ara<4) {$Ara_Y = -0.5*$Argon_y + $FrameToArapucaSpaceLat;
1501 $Ara_YSens = ($Ara_Y+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01);
1502 $rot= "rIdentity"; }
1503 else {$Ara_Y = 0.5*$Argon_y - $FrameToArapucaSpaceLat;
1504 $Ara_YSens = ($Ara_Y-0.5*$ArapucaOut_y+0.5*$ArapucaAcceptanceWindow_y+0.01);
1505 $rot = "rPlus180AboutX";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1506 if ($ara==0||$ara==4) {$Ara_X = $FrameCenter_y-40.0;} #first tile's center 40 cm bellow anode
1507 else {$Ara_X-=$VerticalPDdist;} #other tiles separated by VerticalPDdist
1508 $Ara_Z = $FrameCenter_z;
1510 # print "lateral arapucas: $Ara_X, $Ara_Y, $Ara_Z \n";
1514 <volumeref ref="volArapucaLat_$Lat_z\-$ara"/>
1515 <position name="posArapuca$ara-Lat\-$Lat_z" unit="cm"
1519 <rotationref ref="$rot"/>
1522 <volumeref ref="volOpDetSensitive_ArapucaLat_$Lat_z\-$ara"/>
1523 <position name="posOpArapuca$ara-Lat\-$Lat_z" unit="cm"
1535 sub place_OpDetsMembOnly()
1538 $FrameCenter_y = $_[0];
1539 $FrameCenter_z = $_[1];
1542 #Placing Arapucas on the laterals if nCRM_x=8 -- Single Sided
1543 for ($ara = 0; $ara<18; $ara++)
1545 # Arapucas on laterals
1546 # All Arapuca centers on a given collumn will have the same Z coordinate
1547 # X coordinates are on the left and right laterals
1548 # Y coordinates are defined with respect to the cathode position
1549 # There are two collumns per frame on each side.
1551 if($ara<9) {$Ara_Y = -0.5*$Argon_y + $FrameToArapucaSpaceLat;
1552 $Ara_YSens = ($Ara_Y+0.5*$ArapucaOut_y-0.5*$ArapucaAcceptanceWindow_y-0.01);
1553 $rot= "rIdentity"; }
1554 else {$Ara_Y = 0.5*$Argon_y - $FrameToArapucaSpaceLat;
1555 $Ara_YSens = ($Ara_Y-0.5*$ArapucaOut_y+0.5*$ArapucaAcceptanceWindow_y+0.01);
1556 $rot = "rPlus180AboutX";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X
1557 if($ara==0||$ara==9) {$Ara_X = $FrameCenter_y-$ArapucaOut_x/2;} #first tile's center right below anode
1558 else {$Ara_X-=$ArapucaOut_x - $FrameToArapucaSpace;} #other tiles separated by minimal distance + buffer
1559 $Ara_Z = $FrameCenter_z;
1561 # print "lateral arapucas: $Ara_X, $Ara_Y, $Ara_Z \n";
1565 <volumeref ref="volArapucaLat_$Lat_z\-$ara"/>
1566 <position name="posArapuca$ara-Lat\-$Lat_z" unit="cm"
1570 <rotationref ref="$rot"/>
1573 <volumeref ref="volOpDetSensitive_ArapucaLat_$Lat_z\-$ara"/>
1574 <position name="posOpArapuca$ara-Lat\-$Lat_z" unit="cm"
1588 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1589 #+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++
1590 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1595 # Create the detector enclosure fragment file name,
1596 # add file to list of output GDML fragments,
1598 $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml";
1599 push (@gdmlFiles, $ENCL);
1600 $ENCL = ">" . $ENCL;
1601 open(ENCL) or die("Could not open file $ENCL for writing");
1604 # The standard XML prefix and starting the gdml
1606 <?xml version='1.0'?>
1611 # All the detector enclosure solids.
1615 <box name="FoamPadBlock" lunit="cm"
1616 x="@{[$Cryostat_x + 2*$FoamPadding]}"
1617 y="@{[$Cryostat_y + 2*$FoamPadding]}"
1618 z="@{[$Cryostat_z + 2*$FoamPadding]}" />
1620 <subtraction name="FoamPadding">
1621 <first ref="FoamPadBlock"/>
1622 <second ref="Cryostat"/>
1623 <positionref ref="posCenter"/>
1626 <box name="SteelSupportBlock" lunit="cm"
1627 x="@{[$Cryostat_x + 2*$FoamPadding + 2*$SteelSupport_x]}"
1628 y="@{[$Cryostat_y + 2*$FoamPadding + 2*$SteelSupport_y]}"
1629 z="@{[$Cryostat_z + 2*$FoamPadding + 2*$SteelSupport_z]}" />
1631 <subtraction name="SteelSupport">
1632 <first ref="SteelSupportBlock"/>
1633 <second ref="FoamPadBlock"/>
1634 <positionref ref="posCenter"/>
1637 <box name="DetEnclosure" lunit="cm"
1646 # Detector enclosure structure
1649 <volume name="volFoamPadding">
1650 <materialref ref="fibrous_glass"/>
1651 <solidref ref="FoamPadding"/>
1654 <volume name="volSteelSupport">
1655 <materialref ref="AirSteelMixture"/>
1656 <solidref ref="SteelSupport"/>
1659 <volume name="volDetEnclosure">
1660 <materialref ref="Air"/>
1661 <solidref ref="DetEnclosure"/>
1664 <volumeref ref="volFoamPadding"/>
1665 <positionref ref="posCryoInDetEnc"/>
1668 <volumeref ref="volSteelSupport"/>
1669 <positionref ref="posCryoInDetEnc"/>
1672 <volumeref ref="volCryostat"/>
1673 <positionref ref="posCryoInDetEnc"/>
1692 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1693 #+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++
1694 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1699 # Create the WORLD fragment file name,
1700 # add file to list of output GDML fragments,
1702 $WORLD = $basename."_World" . $suffix . ".gdml";
1703 push (@gdmlFiles, $WORLD);
1704 $WORLD = ">" . $WORLD;
1705 open(WORLD) or die("Could not open file $WORLD for writing");
1708 # The standard XML prefix and starting the gdml
1710 <?xml version='1.0'?>
1715 # All the World solids.
1718 <box name="World" lunit="cm"
1719 x="@{[$DetEncX+2*$RockThickness]}"
1720 y="@{[$DetEncY+2*$RockThickness]}"
1721 z="@{[$DetEncZ+2*$RockThickness]}"/>
1728 <volume name="volWorld" >
1729 <materialref ref="DUSEL_Rock"/>
1730 <solidref ref="World"/>
1733 <volumeref ref="volDetEnclosure"/>
1734 <position name="posDetEnclosure" unit="cm" x="$OriginXSet" y="$OriginYSet" z="$OriginZSet"/>
1742 # make_gdml.pl will take care of <setup/>
1749 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1750 #++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++
1751 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1753 sub write_fragments()
1755 # This subroutine creates an XML file that summarizes the the subfiles output
1756 # by the other sub routines - it is the input file for make_gdml.pl which will
1757 # give the final desired GDML file. Specify its name with the output option.
1758 # (you can change the name when running make_gdml)
1760 # This code is taken straigh from the similar MicroBooNE generate script, Thank you.
1762 if ( ! defined $output )
1764 $output = "-"; # write to STDOUT
1767 # Set up the output file.
1768 $OUTPUT = ">" . $output;
1769 open(OUTPUT) or die("Could not open file $OUTPUT");
1772 <?xml version='1.0'?>
1774 <!-- Input to Geometry/gdml/make_gdml.pl; define the GDML fragments
1775 that will be zipped together to create a detector description.
1782 <!-- These files contain GDML <constant></constant>
1783 blocks. They are read in separately, so they can be
1784 interpreted into the remaining GDML. See make_gdml.pl for
1790 foreach $filename (@defFiles)
1793 <filename> $filename </filename>
1803 <!-- The GDML file fragments to be zipped together. -->
1807 foreach $filename (@gdmlFiles)
1810 <filename> $filename </filename>
1825 print "Some of the principal parameters for this TPC geometry (unit cm unless noted otherwise)\n";
1826 print " CRM active area : $widthCRM_active x $lengthCRM_active\n";
1827 print " CRM total area : $widthCRM x $lengthCRM\n";
1828 print " Wire pitch in U, V, Z : $wirePitchU, $wirePitchV, $wirePitchZ\n";
1829 print " TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n";
1830 print " Argon volume : ($Argon_x, $Argon_y, $Argon_z) \n";
1831 print " Argon buffer : ($xLArBuffer, $yLArBuffer, $zLArBuffer) \n";
1832 print " Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n";
1833 print " TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n";
1834 print " Field Cage : $FieldCage_switch \n";
1835 print " Cathode : $Cathode_switch \n";
1836 print " Workspace : $workspace \n";
1837 print " Wires : $wires_on \n";
1839 # run the sub routines that generate the fragments
1840 if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); }
1841 #if ( $Cathode_switch eq "on" ) { gen_Cathode(); } #Cathode for now has the same geometry as the Ground Grid
1843 gen_Extend(); # generates the GDML color extension for the refactored geometry
1844 gen_Define(); # generates definitions at beginning of GDML
1845 gen_Materials(); # generates materials to be used
1846 gen_TPC(); # generate TPC for a given unit CRM
1849 gen_World(); # places the enclosure among DUSEL Rock
1850 write_fragments(); # writes the XML input for make_gdml.pl
1851 # which zips together the final GDML
1852 print "--- done\n\n\n";