diff --git a/dunecore/Geometry/gdml/gdmlMaterials.pm b/dunecore/Geometry/gdml/gdmlMaterials.pm old mode 100644 new mode 100755 index ef575bf4..df1f1439 --- a/dunecore/Geometry/gdml/gdmlMaterials.pm +++ b/dunecore/Geometry/gdml/gdmlMaterials.pm @@ -362,7 +362,12 @@ sub gen_Materials - + + + + + + EOF my $nStrings = scalar $ARGV + 1; diff --git a/dunecore/Geometry/gdml/generate_protodunevd_v5_refactored.pl b/dunecore/Geometry/gdml/generate_protodunevd_v5_refactored.pl new file mode 100644 index 00000000..f29aac0e --- /dev/null +++ b/dunecore/Geometry/gdml/generate_protodunevd_v5_refactored.pl @@ -0,0 +1,5100 @@ +#!/usr/bin/perl +# +# First attempt to make a GDML generator for the ProtoDUNE vertical drift +# detector geometry with 3 views: +/- Xdeg for induction and 90 deg collection. +# !!!NOTE!!!: the readout is on Y plane (drift along horizontal X) +# due to current reco limitations). +# Simplified treatment of inter-module dead spaces +# +# Created: Mon July 18 2022 +# Laura Paulucci , based on Vyacheslav Galymov's script for dunevd10kt +# +# Details: Collection pitch = 5.1 mm / Induction pitch = 7.65 mm +# TO DO: solve overlaps (3) on account of beam pipe +# TO DO: include perforated PCB in the gdml (LEMs in dual phase gdml are not perforated) +# TO DO: add electronic box for PDs modules. +# TO DO: exchange x and y in SteelSupport structure (currently, overlaps avoided by changing position +# of volSteelSuport_LS/RS/Bottom/Top) +# +# V2: Inclusion of CRT panels (as in ProtoDUNE-HD) +# Update of the PDS and of FC +# Reorganize the "wire" generator algorithm to allow +# easily generating full length strips on the CRU plane +# These are then split through mid-CRU section to make +# wire objets for geo planes and geo vol TPCs, as done +# by V. Galymov for the ColdBox2 +# +# V3.1: JS Real, July 21 2023 +# -Add the existing CRTs on NP02, used for the previous Double Phase data taking +# -Add switches for CRT of ProtoDUNE-HD, CRT of NP02 DP +# -NP02 CRT's position are optimized for VD module 0 (centered on active volume, +# and lower position for bottom CRTs to better match bottom drift volume) +# +# V4: Updates on Mon October 16th 2023 +################################################################################## +# +# Hamza Amar Es-sghir +# José Alfonso Soto Otón +# +############################# New foam material ################################## +# As assayed by School of Mines (Juergen Reichenbacher) +# and remarked by Viktor Pěč (Institute of Physics — FZU). +################################ FC profiles ##################################### +# Number of field shapers 104 --> 114 +# Number of thin field shapers 50 --> 72 +# Number of thick field shapers 54 --> 42 +# FC material: Al₂O₃ --> Al +# Realistic field cage profiles +################################## Cathode ####################################### +# Cathode frame material: Stainless steel --> G10 +# Cathode-Field cage distance 0 --> 15.1 cm +# Cathode mesh, built-in cathode frame +################################# X-ARAPUCAs ##################################### +# Frame size (width & length): 65.0 --> 65.3 cm +# Distance of arapucas (center to center) in the drift direction: 85.3 --> 75.8 cm +# Vertical position of top/bottom X-As center from cathode center ± 283 cm --> + 302.18 & - 283.03 cm +# Membrane and cathode X-ARAPUCA mesh +############################## Dual Phase PMTs ################################### +# Added by: +# Pablo Barham Alzás +################################################################################## + +# Each subroutine generates a fragment GDML file, and the last subroutine +# creates an XML file that make_gdml.pl will use to appropriately arrange +# the fragment GDML files to create the final desired DUNE GDML file, +# to be named by make_gdml output command + +################################################################################## +# +# V5: Updates on January 2025 (LP + changes by Yoann Kermaïdic, J. Soto and H. Amar) +# Fixed cathode X-arapucas' positions to match beam pipe placement +# Fixed cathode X-arapuca's positions to include displacement due to the electronic box +# Inclusion of anode plate on top of the 3 wire planes for backgrounds. +# This is included together with the cathode switch on. Currently the material of this plate is +# set to vm2000 so that no additional geometry (ReflAnode) is needed to obtain optical fast simulation. +# Placement of cathode resistive meshes individually for lighter visualization +# J. Soto: Fixed PMTs' positions to match installation placement +# H. Amar: Fixed membrane X-arapuca's positions to match installation placement +# +# NOTE THAT BECAUSE OF AN UNRESOLVED OVERLAP BETWEEN volCryostat AND volTPC +# PROTODUNE-VD GEOMETRY GENERATOR WAS MOVED TO GGD +################################################################################## + +#use warnings; +use gdmlMaterials; +use Math::Trig; +use Getopt::Long; +use Math::BigFloat; +Math::BigFloat->precision(-16); + +### +GetOptions( "help|h" => \$help, + "suffix|s:s" => \$suffix, + "output|o:s" => \$output, + "wires|w:s" => \$wires); + + +my $FieldCage_switch="on"; +my $Cathode_switch="on"; +$ArapucaMesh_switch="on"; + +my $HD_CRT_switch="off"; +my $DP_CRT_switch="off"; # existing CRTs in NP02 (VD module 0), CRT used for the double phase DP +# DP_CRT switch is OFF due to overlaps with the beam pipe. Once solved it should be turned ON. + +if ( defined $help ) +{ + # If the user requested help, print the usage notes and exit. + usage(); + exit; +} + +if ( ! defined $suffix ) +{ + # The user didn't supply a suffix, so append nothing to the file + # names. + $suffix = ""; +} +else +{ + # Otherwise, stick a "-" before the suffix, so that a suffix of + # "test" applied to filename.gdml becomes "filename-test.gdml". + $suffix = "-" . $suffix; +} + + + +# set wires on to be the default, unless given an input by the user +$wires_on = 0; # 1=on, 0=off +if (defined $wires) +{ + $wires_on = $wires; +} + +$tpc_on = 1; +$basename="protodune-vd"; + + +################################################################## +############## Parameters for One Readout Panel ################## + +$inch = 2.54; + +# views and channel counts per CRU (=1/2 of CRP) +%nChans = ('Ind1', 476, 'Ind2', 476, 'Col', 2*292); +$nViews = keys %nChans; + +# first induction view +$wirePitchU = 0.765; # cm +$wireAngleU = 150.0; # deg + +# second induction view +$wirePitchV = 0.765; # cm +$wireAngleV = 30.0; # deg + +# last collection view +$wirePitchZ = 0.51; # cm + +# offset of 1st u/v strip centre I measured +# (not as precisely probably) directly from gerber +@offsetUVwire = (1.50, 0.87); # cm + +# Active CRU area +$lengthPCBActive = 149.0; #cm +$widthPCBActive = 335.8; #cm +$gapCRU = 0.1; #cm +$borderCRP = 0.6; #cm + +# total area covered by CRP +$widthCRP = $widthPCBActive + 2 * $borderCRP; +$lengthCRP = 2 * $lengthPCBActive + 2 * $borderCRP + $gapCRU; + +# number of CRMs in y and z +$nCRM_x = 2 * 2; +$nCRM_z = 1 * 2; + +# active volume dimensions +# only one crp so active area dimensions are given by CRP area +$widthTPCActive = $nCRM_x/2 * $widthCRP; +$lengthTPCActive = $nCRM_z/2 * $lengthCRP; + +# active volume dimensions +$driftTPCActive = 338.5; # cm, in cold + +# model anode strips as wires of some diameter +$padWidth = 0.02; +$ReadoutPlane = $nViews * $padWidth; # 3 readout planes (no space b/w)! + +# anode plate definition +$anodePlateWidth = $padWidth/2.; + +################################################################## +############## Parameters for TPC and inner volume ############### + +# inner volume dimensions of the cryostat +$Argon_x = 789.6; #790.0 --> 789.6; +$Argon_y = 854.4; #854.8 --> 854.4; +$Argon_z = 854.4; #854.8 --> 854.4; + +# width of gas argon layer on top +$HeightGaseousAr = 49.7; #51.5 --> 49.7; + +# size of liquid argon buffer +$xLArBuffer = $Argon_x - $driftTPCActive - $HeightGaseousAr - $ReadoutPlane; +$Upper_xLArBuffer = 23.6 - $ReadoutPlane; +$Lower_xLArBuffer = 34.7 - $ReadoutPlane; # Upper: 23.6 cm Lower: 34.7 cm +$yLArBuffer = 0.5 * ($Argon_y - $widthTPCActive); +$zLArBuffer = 0.5 * ($Argon_z - $lengthTPCActive); + +# cryostat +$SteelThickness = 0.2; # membrane + +$Cryostat_x = $Argon_x + 2*$SteelThickness; # 854.64 +$Cryostat_y = $Argon_y + 2*$SteelThickness; # 789.84 +$Cryostat_z = $Argon_z + 2*$SteelThickness; # 854.64 + + +# Adding PMTs (from DP) +################################################################## +############## Parameters for PMTs ############### + +$HeightPMT = 37.0; + +# "Horizontal PMT heights" + $HorizontalLowerPMT=0.0; + $HorizontalUpperPMT=10.0; + +#pmts not equally spaced: + + # List of TPB-coated PMTs + @pmt_TPB = (11,12,13,14,23,24); + # List of left-rotated PMTs + @pmt_left_rotated = (11,12,13,14); + # List of right-rotated PMTs + @pmt_right_rotated = (21,22,23,24); + + $y1 = 405.3; + $y2 = 170.0; + $y3 = 0; + $y4 = -170.0; + $y5 = -405.3; + + $z1 = 306.0; + $z2 = 204.0; + $z3 = -204.0; + $z4 = -306.0; + $z5 = 68.1; + $z6 = 0; + + $pos1 = " z=\"$z5\" y=\"$y5\" "; + $pos2 = " z=\"$z6\" y=\"$y5\" "; + $pos3 = " z=\"$z6\" y=\"$y1\" "; + $pos4 = " z=\"$z5\" y=\"$y1\" "; + + $pos5 = " z=\"$z2\" y=\"$y2\" "; + $pos6 = " z=\"$z2\" y=\"$y3\" "; + $pos7 = " z=\"$z2\" y=\"$y4\" "; + $pos8 = " z=\"$z1\" y=\"$y2\" "; + $pos9 = " z=\"$z1\" y=\"$y3\" "; + $pos10 = " z=\"$z1\" y=\"$y4\" "; + + $pos15 = " z=\"$z3\" y=\"$y2\" "; + $pos16 = " z=\"$z3\" y=\"$y3\" "; + $pos17 = " z=\"$z3\" y=\"$y4\" "; + $pos18 = " z=\"$z4\" y=\"$y2\" "; + $pos19 = " z=\"$z4\" y=\"$y3\" "; + $pos20 = " z=\"$z4\" y=\"$y4\" "; + + #Beam plug is in z<0 and y>0 + $HorizontalPMTpos_bot = -301.7; + $HorizontalPMTpos_top = -225.9; + $pos11 = " x=\"$HorizontalPMTpos_top\" z=\"256.9\" y=\"221.0\" "; # Horizontal PMTs nonTCO side PEN + $pos12 = " x=\"$HorizontalPMTpos_bot\" z=\"256.9\" y=\"221.0\" "; # Horizontal PMTs nonTCO side PEN + + $pos13 = " x=\"$HorizontalPMTpos_top\" z=\"256.9\" y=\"-221.0\" "; # Horizontal PMTs TCO side TPB + $pos14 = " x=\"$HorizontalPMTpos_bot\" z=\"256.9\" y=\"-221.0\" "; # Horizontal PMTs TCO side TPB + + $pos21 = " x=\"$HorizontalPMTpos_top\" z=\"-256.9\" y=\"221.0+35.0\" "; # Horizontal PMTs near the beam plug TPB + offset + $pos22 = " x=\"$HorizontalPMTpos_bot\" z=\"-256.9\" y=\"221.0+35.0\" "; # Horizontal PMTs near the beam plug TPB + offset + + $pos23 = " x=\"$HorizontalPMTpos_top\" z=\"-256.9\" y=\"-221.0\" "; # Horizontal PMTs TCO side TPB + $pos24 = " x=\"$HorizontalPMTpos_bot\" z=\"-256.9\" y=\"-221.0\" "; # Horizontal PMTs TCO side TPB + + @pmt_pos = ( + $pos1, $pos2, $pos3, $pos4, $pos5, $pos6, $pos7, $pos8, + $pos9, $pos10, $pos11, $pos12, $pos13, $pos14, $pos15, $pos16, + $pos17, $pos18, $pos19, $pos20, $pos21, $pos22, $pos23, $pos24); + +################################################################## + + + +################################################################## +############## Cathode Parameters ############### +$heightCathode = 6.0; #cm +$CathodeBorder = 4.0; #cm +$widthCathode = $widthCRP; +$lengthCathode = $lengthCRP; +$widthCathodeVoid = 77.25; # 76.35 --> 77.25 cm +$lengthCathodeVoid = 67.25; # 67.0 --> 67.25 cm + +################################################################## +############## Cathode Mesh Parameters ############### +$CathodeMeshInnerStructureLength_vertical = $lengthCathodeVoid; +$CathodeMeshInnerStructureLength_horizontal = $widthCathodeVoid; +$CathodeMeshInnerStructureWidth = 0.25; +$CathodeMeshInnerStructureThickness = 0.05; #No info about it in blueprints +$CathodeMeshInnerStructureSeparation = 2.5; +$CathodeMeshInnerStructureNumberOfStrips_vertical = 30; +$CathodeMeshInnerStructureNumberOfStrips_horizontal = 26; + +################################################################## +############## Cathode Frame Parameters ############### +$CathodeMeshOffset_Y = 87.625; #cm The Y coordinate of the first cathode mesh in place. +# We have chosen the square depicted below. Filling by columns, i.e., downwards. +################ Bottom view ################## +################ Axes ################## +################ ^ ################## +################ Y| ################## +################ |___ > ################## +################ Z ################## + +########## ########## ########## ########## +#++++++++# # # # # # # +#++++++++# # # # # # # +#++++++++# # # # # # # +########## ########## ########## ########## +# # # # # # # # +# # # # # # # # +# # # # # # # # +########## ########## ########## ########## +# # # # # # # # +# # # # # # # # +# # # # # # # # +########## ########## ########## ########## +# # # # # # # # +# # # # # # # # +# # # # # # # # +########## ########## ########## ########## + +################################################################## +############## DetEnc and World relevant parameters ############# + +$SteelSupport_x = 1; +$SteelSupport_y = 1; +$SteelSupport_z = 1; +$SteelPlate = 1.0; +$FoamPadding = 80; + +$FracMassOfSteel = 0.5; #The steel support is not a solid block, but a mixture of air and steel +$FracMassOfAir = 1 - $FracMassOfSteel; + + +$SpaceSteelSupportToWall = 1500; # 900; +$SpaceSteelSupportToCeiling = 1500; # 900; + +#TO DO: Whole outside structure has to be x--> Y and Y-->X +$DetEncX = $Cryostat_x + 2*($SteelSupport_x + $FoamPadding) + 2*$SpaceSteelSupportToWall; +$DetEncY = $Cryostat_y + 2*($SteelSupport_y + $FoamPadding) + $SpaceSteelSupportToCeiling; +$DetEncZ = $Cryostat_z + 2*($SteelSupport_z + $FoamPadding) + 2*$SpaceSteelSupportToWall; + +$posCryoInDetEnc_x = 0; +$posCryoInDetEnc_y = 0; +$posCryoInDetEnc_z = 0; + +$posTopSteelStruct = $Argon_y/2+$FoamPadding+$SteelSupport_y; #+ 61.8/2; ## JS Real, add boxCryoTop dz/2. +$posBotSteelStruct = -$Argon_y/2-$FoamPadding-$SteelSupport_y; # - 61.8/2; +$posZBackSteelStruct = $Argon_z/2+$FoamPadding+$SteelSupport_z;# + 61.8/2; ## JS Real, add boxCryoWallSm dz/2.; +$posZFrontSteelStruct = -$Argon_z/2-$FoamPadding-$SteelSupport_z;# - 61.8/2; +$posLeftSteelStruct = $Argon_x/2+$FoamPadding+$SteelSupport_x; # + 61.8/2; ## JS Real, add boxCryoWallLg dz/2.; +$posRightSteelStruct = -$Argon_x/2-$FoamPadding-$SteelSupport_x;# + 61.8/2; ## JS Real, add boxCryoWallLg dz/2.; + +$posTopSteelStruct -= 29.7 if $DP_CRT_switch eq "on"; # overlap volume otherwise +$posBotSteelStruct += 29.7 if $DP_CRT_switch eq "on"; + +# 2*AirThickness is added to the world volume in x, y and z +$AirThickness = 3000; + + # We want the world origin to be at the very front of the fiducial volume. + # move it to the front of the enclosure, then back it up through the concrete/foam, + # then through the Cryostat shell, then through the upstream dead LAr (including the + # dead LAr on the edge of the TPC) + # This is to be added to the z position of every volume in volWorld + +$OriginZSet = $DetEncZ/2.0 + - $SpaceSteelSupportToWall + - $SteelSupport_z + - $FoamPadding + - $SteelThickness + - $zLArBuffer; + + # We want the world origin to be vertically centered on the cathode + # This is to be added to the y position of every volume in volWorld + +$OriginYSet = $DetEncY/2.0 + - $SpaceSteelSupportToCeiling/2.0 + - $SteelSupport_y + - $FoamPadding + - $SteelThickness + - $yLArBuffer + - $widthTPCActive/2; + +$OriginXSet = $DetEncX/2.0 + - $SpaceSteelSupportToWall + - $SteelSupport_x + - $FoamPadding + - $SteelThickness + - $xLArBuffer +# - $driftTPCActive/2.0; + + $heightCathode/2 + + $Upper_xLArBuffer; + +################################################################### +######################## Beam Window 2 Parameters ################### + +# $thetaYZ = 11.342; +# $theta2XZ = 8.189; +# +# $BeamTheta2 = atan (sqrt(tan(deg2rad($theta2XZ))**2 +tan(deg2rad($thetaYZ))**2)); +# $BeamPhi2 = atan (tan(deg2rad($thetaYZ))/tan(deg2rad($theta2XZ))); +# +# $thetaYZprime = rad2deg(atan(sin($BeamTheta2)*sin($BeamPhi2+deg2rad(180))/sqrt(cos($BeamTheta2)**2 + sin($BeamTheta2)**2*cos($BeamPhi2)**2))); +# +# print "thetaYZprime =".$thetaYZprime."\n"; +# +# $DeltaXZ2 = tan($BeamTheta2)*cos($BeamPhi2); +# $DeltaYZ2 = tan($BeamTheta2)*sin($BeamPhi2); +# +# print "DeltaXZ2 = ".$DeltaXZ2."\n"; +# print "DeltaYZ2 = ".$DeltaYZ2."\n"; +# +# $BeamTheta2Deg = rad2deg($BeamTheta2); +# $BeamPhi2Deg = rad2deg($BeamPhi2); + +######################### Beam Window 3 Parameters ################### + +# $thetaYZ = 11.671; +# $theta3XZ = 10.578; + +$thetaYZ = 45.0; +$theta3XZ = 7.7; + +####### Version 1 ##################################################### +#### $thetaYZ = 11.342; +#### $theta3XZ = 11.844; + +$BeamTheta3 = atan (sqrt(tan(deg2rad($theta3XZ))**2 +tan(deg2rad($thetaYZ))**2)); +$BeamPhi3 = atan (tan(deg2rad($thetaYZ))/tan(deg2rad($theta3XZ))); + +print "BeamTheta3 = ".rad2deg($BeamTheta3)."\n"; +print "BeamPhi3 = ".rad2deg($BeamPhi3)."\n"; + +$thetaYZ3prime = rad2deg(atan(sin($BeamTheta3)*sin($BeamPhi3+deg2rad(180))/sqrt(cos($BeamTheta3)**2 + sin($BeamTheta3)**2*cos($BeamPhi3)**2))); + +print "thetaYZ3prime =".rad2deg($thetaYZ3prime)."\n"; + +$DeltaXZ3 = tan($BeamTheta3)*cos($BeamPhi3); +$DeltaYZ3 = tan($BeamTheta3)*sin($BeamPhi3); +print "DeltaXZ3 =".$DeltaXZ3."\n"; +print "DeltaYZ3 =".$DeltaYZ3."\n"; + +$BeamPipeRad = 12.5; +$BeamVaPipeRad = $BeamPipeRad - 0.2; +$BeamPipeLe = 900.0; +$BeamVaPipeLe = $BeamPipeLe; +$BeamWFoLe = 52.0; +$BeamWGlLe = 10.0; +$BeamWStPlateFF_x = 634.2 - $Cryostat_x / 2.0; +$BeamWStPlateFF_y = $Cryostat_y / 2.0 + $SteelSupport_y + $FoamPadding; +$BeamWStPlateFF_z = - ($Cryostat_z/2 + $FoamPadding + $SteelPlate); + +$BeamWStPlateLe = $SteelPlate/cos($BeamTheta3)+0.001; +$BeamWStPlate_x = $BeamWStPlateFF_x - ($SteelPlate/2.0)*$DeltaXZ3; +$BeamWStPlate_y = $BeamWStPlateFF_y - ($SteelPlate/2.0)*$DeltaYZ3; +$BeamWStPlate_z = $BeamWStPlateFF_z + $SteelPlate/2.0; + +$BeamWFoRemLe = $FoamPadding/cos($BeamTheta3)+0.001; +$BeamWFoRemPosDZ = $SteelPlate + $FoamPadding/2.0; +$BeamWFoRem_x = $BeamWStPlateFF_x - $BeamWFoRemPosDZ*$DeltaXZ3; +$BeamWFoRem_y = $BeamWStPlateFF_y - $BeamWFoRemPosDZ*$DeltaYZ3; +$BeamWFoRem_z = $BeamWStPlateFF_z + $BeamWFoRemPosDZ; + +$BeamWStSuLe = ($SteelSupport_z - $SteelPlate)/cos($BeamTheta3)+0.001; +$BeamWStSuPosDZ = - ($SteelSupport_z - $SteelPlate)/2.0; # going upstream from the steel plate +$BeamWStSu_x = $BeamWStPlateFF_x - $BeamWStSuPosDZ*$DeltaXZ3; +$BeamWStSu_y = $BeamWStPlateFF_y - $BeamWStSuPosDZ*$DeltaYZ3; +$BeamWStSu_z = $BeamWStPlateFF_z + $BeamWStSuPosDZ; + +$BeamWFoPosDZ = $SteelPlate + $FoamPadding - $BeamWFoLe*cos($BeamTheta3)/2.0; +$BeamWFo_x = $BeamWStPlateFF_x - $BeamWFoPosDZ*$DeltaXZ3; +$BeamWFo_y = $BeamWStPlateFF_y - $BeamWFoPosDZ*$DeltaYZ3 + $posCryoInDetEnc_y; +$BeamWFo_z = $BeamWStPlateFF_z + $BeamWFoPosDZ; +print "BeamWFoPosDZ = ".$BeamWFoPosDZ."\n"; + +$BeamWGlPosDZ = $SteelPlate + $FoamPadding - ($BeamWFoLe + $BeamWGlLe/2.0)*cos($BeamTheta3); +$BeamWGl_x = $BeamWStPlateFF_x - $BeamWGlPosDZ*$DeltaXZ3; +$BeamWGl_y = $BeamWStPlateFF_y - $BeamWGlPosDZ*$DeltaYZ3 + $posCryoInDetEnc_y; +$BeamWGl_z = $BeamWStPlateFF_z + $BeamWGlPosDZ; + +$BeamWVaPosDZ = $SteelPlate + $FoamPadding - ($BeamWFoLe + $BeamWGlLe + $BeamPipeLe/2.0)*cos($BeamTheta3); +$BeamWVa_x = $BeamWStPlateFF_x - $BeamWVaPosDZ*$DeltaXZ3; +$BeamWVa_y = $BeamWStPlateFF_y - $BeamWVaPosDZ*$DeltaYZ3 + $posCryoInDetEnc_y; +$BeamWVa_z = $BeamWStPlateFF_z + $BeamWVaPosDZ; +print "BeamWVaPosDZ = ".$BeamWVaPosDZ."\n"; + +$BeamPlugRad = 10.48; +$BeamPlugNiRad = 9.72; +$BeamPlugUSAr = 1/cos($BeamTheta3); # 1 cm US LAr layer between beam plug and primary membrane +$BeamPlugLe = (188)/cos($BeamTheta3) - $BeamPlugUSAr; #with current geometry and 49.22 Dz the flange's front face just touches the active volume. +$BeamPlugNiLe = $BeamPlugLe-0.59/cos($BeamTheta3); + +$BeamPlugPosDZ = $SteelPlate + $FoamPadding + $SteelThickness + $BeamPlugUSAr + $BeamPlugLe*cos($BeamTheta3)/2; +$BeamPlug_x = $BeamWStPlateFF_x - $BeamPlugPosDZ*$DeltaXZ3; +$BeamPlug_y = $BeamWStPlateFF_y - $BeamPlugPosDZ*$DeltaYZ3; +$BeamPlug_z = $BeamWStPlateFF_z + $BeamPlugPosDZ; + +$BePlFlangePosDZ = $SteelPlate + $FoamPadding + $SteelThickness + $BeamPlugUSAr + $BeamPlugLe*cos($BeamTheta3); #This is Dz to the end of the beam plug pipe needed for x,y position. +$BePlFlange_x = $BeamWStPlateFF_x - $BePlFlangePosDZ*$DeltaXZ3; +$BePlFlange_y = $BeamWStPlateFF_y - $BePlFlangePosDZ*$DeltaYZ3; +$BePlFlange_z = $BeamWStPlateFF_z + $BePlFlangePosDZ + 1.8; # Adding the half the thickness of the flange. + +$BeamPlugNiPos_z = 0.59/2/cos($BeamTheta3); + +print "BeamPlugLe = $BeamPlugLe"."\n"; +print "BeamTheta3 = $BeamTheta3"."\n"; +print "BeamWStPlate x=$BeamWStPlate_x".", y=$BeamWStPlate_y".", z=$BeamWStPlate_z"."\n"; +print "BeamWStSu x=$BeamWStSu_x".", y=$BeamWStSu_y".", z=$BeamWStSu_z"."\n"; +print "BeamWFoRem x=$BeamWFoRem_x".", y=$BeamWFoRem_y".", z=$BeamWFoRem_z"."\n"; +print "BeamWFo x=$BeamWFo_x".", y=$BeamWFo_y".", z=$BeamWFo_z"."\n"; +print "BeamWGl x=$BeamWGl_x".", y=$BeamWGl_y".", z=$BeamWGl_z"."\n"; +print "BeamWVa x=$BeamWVa_x".", y=$BeamWVa_y".", z=$BeamWVa_z"."\n"; +#print "CPAToWestCrWall=$CPAToWestCrWall"."\n"; +print "BeamPlug x=$BeamPlug_x".", y=$BeamPlug_y".", z=$BeamPlug_z"."\n"; +print "BeamPlugFlange x=$BePlFlange_x".", y=$BePlFlange_y".", z=$BePlFlange_z"."\n"; + +$BeamTheta3Deg = rad2deg($BeamTheta3); +$BeamPhi3Deg = rad2deg($BeamPhi3); + +$BeamPlugMembPosDZ = $SteelPlate + $FoamPadding + $SteelThickness; +$BeamPlugMemb_x = $BeamWStPlateFF_x - $BeamPlugMembPosDZ*$DeltaXZ3; +$BeamPlugMemb_y = $BeamWStPlateFF_y - $BeamPlugMembPosDZ*$DeltaYZ3; +$BeamPlugMemb_z = $BeamWStPlateFF_z + $BeamPlugMembPosDZ; + +print "BeamPlugMemb_x=".$BeamPlugMemb_x.", BeamPlugMemb_y=".$BeamPlugMemb_y.", BeamPlugMemb_z=".$BeamPlugMemb_z."\n"; + +$BWFFCoord3X = $BeamWStPlateFF_x - $BeamWStSuPosDZ*$DeltaXZ3*2 + + $OriginXSet; +$BWFFCoord3Y = $BeamWStPlateFF_y - $BeamWStSuPosDZ*$DeltaYZ3*2 + + $OriginYSet + $posCryoInDetEnc_y; +$BWFFCoord3Z = - ($Cryostat_z/2 + $SteelSupport_z + $FoamPadding) + + $OriginZSet; +print "BeamWStPlateFF_x=".$BeamWStPlateFF_x.", BeamWStPlateFF_y=".$BeamWStPlateFF_y.", BeamWStPlateFF_z = ".$BeamWStPlateFF_z."\n"; +print "BeamWStSuPosDZ= $BeamWStSuPosDZ; "." DeltaYZ3=".$DeltaYZ3."\n"; +print "BWFFCoord3X =".$BWFFCoord3X."\n"; +print "BWFFCoord3Y =".$BWFFCoord3Y."\n"; +print "BWFFCoord3Z =".$BWFFCoord3Z."\n"; + +$BW3StPlCoordX = $BeamWStPlateFF_x + $OriginXSet; +$BW3StPlCoordY = $BeamWStPlateFF_y + $OriginYSet + $posCryoInDetEnc_y; +$BW3StPlCoordZ = $BeamWStPlateFF_z + $OriginZSet; + +print "BW3StPlCoordX =".$BW3StPlCoordX."\n"; +print "BW3StPlCoordY =".$BW3StPlCoordY."\n"; +print "BW3StPlCoordZ =".$BW3StPlCoordZ."\n"; + +################################################################## +####################### PD2 Beam Plug ############################ + +# $thetaIIYZ = 11.671; +# $thetaII3XZ = 10.578; + +$thetaIIYZ = $thetaYZ; +$thetaII3XZ = $theta3XZ; + +$BeamThetaII3 = atan (sqrt(tan(deg2rad($thetaII3XZ))**2 +tan(deg2rad($thetaIIYZ))**2)); +$BeamPhiII3 = atan (tan(deg2rad($thetaIIYZ))/tan(deg2rad($thetaII3XZ))); + +print "BeamThetaII3 = ".rad2deg($BeamThetaII3)."\n"; +print "BeamPhiII3 = ".rad2deg($BeamPhiII3)."\n"; + + +$thetaIIYZ3prime = rad2deg(atan(sin($BeamThetaII3)*sin($BeamPhiII3+deg2rad(180))/sqrt(cos($BeamThetaII3)**2 + sin($BeamThetaII3)**2*cos($BeamPhiII3)**2))); + +print "thetaIIYZ3prime =".$thetaIIYZ3prime."\n"; + +$DeltaIIXZ3 = tan($BeamThetaII3)*cos($BeamPhiII3); +$DeltaIIYZ3 = tan($BeamThetaII3)*sin($BeamPhiII3); +print "DeltaIIXZ3 = ".$DeltaIIXZ3."\n"; +print "DeltaIIYZ3 = ".$DeltaIIYZ3."\n"; + +$BeamPlIIMem_x = $BeamPlugMemb_x; +$BeamPlIIMem_y = $BeamPlugMemb_y; +$BeamPlIIMem_z = $BeamPlugMemb_z; + +$BeamPlIIRad = 11*$inch/2; +$BeamPlIINiRad = 10*$inch/2; +$BeamPlIIUSAr = 1/cos($BeamThetaII3); # 1 cm US LAr layer between beam plug and primary membrane +$BeamPlIILe = ($zLArBuffer - 5.3)/cos($BeamThetaII3); #with current geometry and 49.22 Dz the flange's front face just touches the active volume. +print "BeamPlIILe = ".$BeamPlIILe."\n"; +$BeamPlIINiLe = $BeamPlIILe; +$BeamPlIICapDZ = 0.5*cos($BeamThetaII3); + +$BeamPlIIPosDZ = $BeamPlIICapDZ + $BeamPlIILe*cos($BeamThetaII3)/2.0; +$BeamPlII_x = $BeamPlIIMem_x - $BeamPlIIPosDZ*$DeltaIIXZ3; +$BeamPlII_y = $BeamPlIIMem_y - $BeamPlIIPosDZ*$DeltaIIYZ3; +$BeamPlII_z = $BeamPlIIMem_z + $BeamPlIIPosDZ; + +$BeamPlIIUSCap_x = $BeamPlIIMem_x - $BeamPlIICapDZ/2.0*$DeltaIIXZ3; +$BeamPlIIUSCap_y = $BeamPlIIMem_y - $BeamPlIICapDZ/2.0*$DeltaIIYZ3; +$BeamPlIIUSCap_z = $BeamPlIIMem_z + $BeamPlIICapDZ/2.0; + +$BeamPlIIDSPosDZ = $BeamPlIICapDZ + $BeamPlIILe*cos($BeamThetaII3) + $BeamPlIICapDZ/2; +$BeamPlIIDSCap_x = $BeamPlIIMem_x - $BeamPlIIDSPosDZ*$DeltaIIXZ3; +$BeamPlIIDSCap_y = $BeamPlIIMem_y - $BeamPlIIDSPosDZ*$DeltaIIYZ3; +$BeamPlIIDSCap_z = $BeamPlIIMem_z + $BeamPlIIDSPosDZ; + +#################################################### +############## Field Cage Parameters ############### +#################################################### +$FieldShaperInnerRadius = 1.758; #0.5; #cm +$FieldShaperOuterRadius = 1.858; #2.285; #cm +$FieldShaperSlimInnerRadius = 0.65; +$FieldShaperSlimOuterRadius = 0.80; +$FieldShaperTorRad = 10; #2.3; #cm + +$FieldShaperLength = 329.4 - 2*$FieldShaperTorRad; +$FieldShaperWidth = 704.5 - 2*$FieldShaperTorRad; +$FieldShaperCutLength = $FieldShaperLength + 0.02; +$FieldShaperCutWidth = $FieldShaperWidth + 0.02; + +$FieldShaperSeparation = 6.0; #cm +$NFieldShapers = 114; + +$FieldCageSizeX = $FieldShaperSeparation*$NFieldShapers+2; +$FieldCageSizeY = $FieldShaperWidth+2; +$FieldCageSizeZ = $FieldShaperLength+2; + +################################################################### +######################## CRT Dimensions ########################## + +$CRTPaddleWidth = 5.0; +$CRTPaddleHeight = 1.0; +$CRTPaddleLength = 322.5; + +$CRTModWidth = 162.5; +$CRTModHeight = 2.0; +$CRTModLength = 322.5; + +$TopCRTDPPaddleWidth = 20; #mm +$TopCRTDPPaddleHeight = 132; #mm +$TopCRTDPPaddleLength = 1440; #mm +$BottomCRTDPPaddleWidth = 20; #mm +$BottomCRTDPPaddleHeight = 116; #mm +$BottomCRTDPPaddleLength = 1440; #mm +$CRTDPPaddleSpacing = 132+10; # spacing between two consecutive paddles (edge to edge) (mm) + +$TopCRTDPModWidth = 21; #mm +$TopCRTDPModHeight = 1126; #mm +$TopCRTDPModLength = 1440; #mm +$BottomCRTDPModWidth = 21; #mm +$BottomCRTDPModHeight = 1110; #mm +$BottomCRTDPModLength = 1440; #mm + +# SuperModule Centers as per Survey Document +$CRT_DSTopLeft_x = 171.2; +$CRT_DSTopLeft_y = -473.88; +$CRT_DSTopLeftFr_z = 1042.13; +$CRT_DSTopLeftBa_z = 1050.13; + +$CRT_DSBotLeft_x = 176.51; +$CRT_DSBotLeft_y = -840.6; +$CRT_DSBotLeftFr_z = 1041.74; +$CRT_DSBotLeftBa_z = 1050.13; + +$CRT_DSTopRight_x = -176.23; +$CRT_DSTopRight_y = -474.85; +$CRT_DSTopRightFr_z = 1042.64; +$CRT_DSTopRightBa_z = 1050.85; + +$CRT_DSBotRight_x = -169.6; +$CRT_DSBotRight_y = -840.55; +$CRT_DSBotRightFr_z = 1042.88; +$CRT_DSBotRightBa_z = 1051.93; + +$CRT_USTopLeft_x = 393.6; +$CRT_USTopLeft_y = -401.33; +$CRT_USTopLeftFr_z = -295.05; +$CRT_USTopLeftBa_z = -286.85; + +$CRT_USBotLeft_x = 394.14; +$CRT_USBotLeft_y = -734.48; +$CRT_USBotLeftFr_z = -320.24; +$CRT_USBotLeftBa_z = -310.88; + +$CRT_USTopRight_x = -38.85; +$CRT_USTopRight_y = -400.85; +$CRT_USTopRightFr_z = -998.95; +$CRT_USTopRightBa_z = -990.97; + +$CRT_USBotRight_x = -31.47; +$CRT_USBotRight_y = -735.13; +$CRT_USBotRightFr_z = -1022.25; +$CRT_USBotRightBa_z = -1015.01; + +# Coordinates of Survey origin w.r.t. Steel Plate box center as per penetrations steel plate drawing (flange 1.2) +$CRTSurveyOrigin_x = -36.0; +$CRTSurveyOrigin_y = 534.43; +$CRTSurveyOrigin_z = -344.1; + +# Distance between CRT module centers and CRT SuperModule Centers +$ModuleSMDist = 85.6; +$ModuleOff_z = 1; # approx. correction for the center of a Module. Survey measures Z to the outside surface. Negative for the most US CRTs (surveyed from behind). +$ModuleLongCorr = 5.6; # allign the the modules at the frame's edge + +# Beam Spot on the inside of the cryostat + +$BeamSpotDSS_x = -20.58; +$BeamSpotDSS_y = -425.41; +$BeamSpotDSS_z = -82.96; + +$BeamSpot_x = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $BeamSpotDSS_x + $OriginXSet; +$BeamSpot_y = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $BeamSpotDSS_y + $OriginYSet; +$BeamSpot_z = $posCryoInDetEnc_z + $CRTSurveyOrigin_z + $BeamSpotDSS_z + $OriginZSet; + +print "posCryoInDetEnc_x =".$posCryoInDetEnc_x.", posCryoInDetEnc_y=".$posCryoInDetEnc_y.", posCryoInDetEnc_z =".$posCryoInDetEnc_z."\n"; +print "BeamSpot_x =".$BeamSpot_x.", BeamSpot_y =".$BeamSpot_y.", BeamSpot_z =".$BeamSpot_z."\n"; + +####################### End of Survey data ########## + + +my @posCRTDS_x = (); +my @posCRTDS_y = (); +my @posCRTDS_z = (); +my @posCRTDS_rot = (); + +$posCRTDS_x[0] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopLeft_x - $ModuleSMDist; +$posCRTDS_y[0] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopLeft_y - $ModuleLongCorr; +$posCRTDS_z[0] = $CRTSurveyOrigin_z + $CRT_DSTopLeftBa_z + $ModuleOff_z; +$posCRTDS_rot[0] = "rPlus90AboutX"; + +$posCRTDS_x[1] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopLeft_x + $ModuleSMDist; +$posCRTDS_y[1] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopLeft_y - $ModuleLongCorr; +$posCRTDS_z[1] = $CRTSurveyOrigin_z + $CRT_DSTopLeftBa_z + $ModuleOff_z; +$posCRTDS_rot[1] = "rPlus90AboutX"; + +$posCRTDS_x[2] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopLeft_x - $ModuleLongCorr; +$posCRTDS_y[2] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopLeft_y - $ModuleSMDist; +$posCRTDS_z[2] = $CRTSurveyOrigin_z + $CRT_DSTopLeftFr_z + $ModuleOff_z; +$posCRTDS_rot[2] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[3] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopLeft_x - $ModuleLongCorr; +$posCRTDS_y[3] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopLeft_y + $ModuleSMDist; +$posCRTDS_z[3] = $CRTSurveyOrigin_z + $CRT_DSTopLeftFr_z + $ModuleOff_z; +$posCRTDS_rot[3] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[4] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotLeft_x - $ModuleSMDist; +$posCRTDS_y[4] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotLeft_y + $ModuleLongCorr; +$posCRTDS_z[4] = $CRTSurveyOrigin_z + $CRT_DSBotLeftFr_z + $ModuleOff_z; +$posCRTDS_rot[4] = "rPlus90AboutX"; + +$posCRTDS_x[5] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotLeft_x + $ModuleSMDist; +$posCRTDS_y[5] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotLeft_y + $ModuleLongCorr; +$posCRTDS_z[5] = $CRTSurveyOrigin_z + $CRT_DSBotLeftFr_z + $ModuleOff_z; +$posCRTDS_rot[5] = "rPlus90AboutX"; + +$posCRTDS_x[6] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotLeft_x - $ModuleLongCorr; +$posCRTDS_y[6] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotLeft_y - $ModuleSMDist; +$posCRTDS_z[6] = $CRTSurveyOrigin_z + $CRT_DSBotLeftBa_z + $ModuleOff_z; +$posCRTDS_rot[6] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[7] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotLeft_x - $ModuleLongCorr; +$posCRTDS_y[7] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotLeft_y + $ModuleSMDist; +$posCRTDS_z[7] = $CRTSurveyOrigin_z + $CRT_DSBotLeftBa_z + $ModuleOff_z; +$posCRTDS_rot[7] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[8] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopRight_x - $ModuleSMDist; +$posCRTDS_y[8] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopRight_y - $ModuleLongCorr; +$posCRTDS_z[8] = $CRTSurveyOrigin_z + $CRT_DSTopRightFr_z + $ModuleOff_z; +$posCRTDS_rot[8] = "rPlus90AboutX"; + +$posCRTDS_x[9] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopRight_x + $ModuleSMDist; +$posCRTDS_y[9] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopRight_y - $ModuleLongCorr; +$posCRTDS_z[9] = $CRTSurveyOrigin_z + $CRT_DSTopRightFr_z + $ModuleOff_z; +$posCRTDS_rot[9] = "rPlus90AboutX"; + +$posCRTDS_x[10] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopRight_x + $ModuleLongCorr; +$posCRTDS_y[10] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopRight_y - $ModuleSMDist; +$posCRTDS_z[10] = $CRTSurveyOrigin_z + $CRT_DSTopRightBa_z + $ModuleOff_z; +$posCRTDS_rot[10] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[11] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSTopRight_x + $ModuleLongCorr; +$posCRTDS_y[11] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSTopRight_y + $ModuleSMDist; +$posCRTDS_z[11] = $CRTSurveyOrigin_z + $CRT_DSTopRightBa_z + $ModuleOff_z; +$posCRTDS_rot[11] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[12] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotRight_x - $ModuleSMDist; +$posCRTDS_y[12] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotRight_y + $ModuleLongCorr; +$posCRTDS_z[12] = $CRTSurveyOrigin_z + $CRT_DSBotRightBa_z + $ModuleOff_z; +$posCRTDS_rot[12] = "rPlus90AboutX"; + +$posCRTDS_x[13] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotRight_x + $ModuleSMDist; +$posCRTDS_y[13] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotRight_y + $ModuleLongCorr; +$posCRTDS_z[13] = $CRTSurveyOrigin_z + $CRT_DSBotRightBa_z + $ModuleOff_z; +$posCRTDS_rot[13] = "rPlus90AboutX"; + +$posCRTDS_x[14] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotRight_x + $ModuleLongCorr; +$posCRTDS_y[14] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotRight_y - $ModuleSMDist; +$posCRTDS_z[14] = $CRTSurveyOrigin_z + $CRT_DSBotRightFr_z + $ModuleOff_z; +$posCRTDS_rot[14] = "rMinus90AboutYMinus90AboutX"; + +$posCRTDS_x[15] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_DSBotRight_x + $ModuleLongCorr; +$posCRTDS_y[15] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_DSBotRight_y + $ModuleSMDist; +$posCRTDS_z[15] = $CRTSurveyOrigin_z + $CRT_DSBotRightFr_z + $ModuleOff_z; +$posCRTDS_rot[15] = "rMinus90AboutYMinus90AboutX"; + + +my @posCRTUS_x = (); +my @posCRTUS_y = (); +my @posCRTUS_z = (); +my @posCRTUS_rot = (); + + +$posCRTUS_x[0] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopLeft_x - $ModuleSMDist; +$posCRTUS_y[0] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopLeft_y - $ModuleLongCorr; +$posCRTUS_z[0] = $CRTSurveyOrigin_z + $CRT_USTopLeftBa_z + $ModuleOff_z; +$posCRTUS_rot[0] = "rPlus90AboutX"; + +$posCRTUS_x[1] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopLeft_x + $ModuleSMDist; +$posCRTUS_y[1] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopLeft_y - $ModuleLongCorr; +$posCRTUS_z[1] = $CRTSurveyOrigin_z + $CRT_USTopLeftBa_z + $ModuleOff_z; +$posCRTUS_rot[1] = "rPlus90AboutX"; + +$posCRTUS_x[2] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopLeft_x - $ModuleLongCorr; +$posCRTUS_y[2] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopLeft_y - $ModuleSMDist; +$posCRTUS_z[2] = $CRTSurveyOrigin_z + $CRT_USTopLeftFr_z + $ModuleOff_z; +$posCRTUS_rot[2] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[3] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopLeft_x - $ModuleLongCorr; +$posCRTUS_y[3] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopLeft_y + $ModuleSMDist; +$posCRTUS_z[3] = $CRTSurveyOrigin_z + $CRT_USTopLeftFr_z + $ModuleOff_z; +$posCRTUS_rot[3] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[4] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotLeft_x - $ModuleSMDist; +$posCRTUS_y[4] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotLeft_y + $ModuleLongCorr; +$posCRTUS_z[4] = $CRTSurveyOrigin_z + $CRT_USBotLeftFr_z + $ModuleOff_z; +$posCRTUS_rot[4] = "rPlus90AboutX"; + +$posCRTUS_x[5] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotLeft_x + $ModuleSMDist; +$posCRTUS_y[5] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotLeft_y + $ModuleLongCorr; +$posCRTUS_z[5] = $CRTSurveyOrigin_z + $CRT_USBotLeftFr_z + $ModuleOff_z; +$posCRTUS_rot[5] = "rPlus90AboutX"; + +$posCRTUS_x[6] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotLeft_x - $ModuleLongCorr; +$posCRTUS_y[6] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotLeft_y - $ModuleSMDist; +$posCRTUS_z[6] = $CRTSurveyOrigin_z + $CRT_USBotLeftBa_z + $ModuleOff_z; +$posCRTUS_rot[6] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[7] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotLeft_x - $ModuleLongCorr; +$posCRTUS_y[7] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotLeft_y + $ModuleSMDist; +$posCRTUS_z[7] = $CRTSurveyOrigin_z + $CRT_USBotLeftBa_z + $ModuleOff_z; +$posCRTUS_rot[7] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[8] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopRight_x - $ModuleSMDist; +$posCRTUS_y[8] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopRight_y - $ModuleLongCorr; +$posCRTUS_z[8] = $CRTSurveyOrigin_z + $CRT_USTopRightFr_z - $ModuleOff_z; +$posCRTUS_rot[8] = "rPlus90AboutX"; + +$posCRTUS_x[9] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopRight_x + $ModuleSMDist; +$posCRTUS_y[9] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopRight_y - $ModuleLongCorr; +$posCRTUS_z[9] = $CRTSurveyOrigin_z + $CRT_USTopRightFr_z - $ModuleOff_z; +$posCRTUS_rot[9] = "rPlus90AboutX"; + +$posCRTUS_x[10] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopRight_x + $ModuleLongCorr; +$posCRTUS_y[10] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopRight_y - $ModuleSMDist; +$posCRTUS_z[10] = $CRTSurveyOrigin_z + $CRT_USTopRightBa_z - $ModuleOff_z; +$posCRTUS_rot[10] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[11] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USTopRight_x + $ModuleLongCorr; +$posCRTUS_y[11] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USTopRight_y + $ModuleSMDist; +$posCRTUS_z[11] = $CRTSurveyOrigin_z + $CRT_USTopRightBa_z - $ModuleOff_z; +$posCRTUS_rot[11] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[12] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotRight_x - $ModuleSMDist; +$posCRTUS_y[12] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotRight_y + $ModuleLongCorr; +$posCRTUS_z[12] = $CRTSurveyOrigin_z + $CRT_USBotRightBa_z - $ModuleOff_z; +$posCRTUS_rot[12] = "rPlus90AboutX"; + +$posCRTUS_x[13] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotRight_x + $ModuleSMDist; +$posCRTUS_y[13] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotRight_y + $ModuleLongCorr; +$posCRTUS_z[13] = $CRTSurveyOrigin_z + $CRT_USBotRightBa_z - $ModuleOff_z; +$posCRTUS_rot[13] = "rPlus90AboutX"; + +$posCRTUS_x[14] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotRight_x + $ModuleLongCorr; +$posCRTUS_y[14] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotRight_y - $ModuleSMDist; +$posCRTUS_z[14] = $CRTSurveyOrigin_z + $CRT_USBotRightFr_z - $ModuleOff_z; +$posCRTUS_rot[14] = "rMinus90AboutYMinus90AboutX"; + +$posCRTUS_x[15] = $posCryoInDetEnc_x + $CRTSurveyOrigin_x + $CRT_USBotRight_x + $ModuleLongCorr; +$posCRTUS_y[15] = $posCryoInDetEnc_y + $CRTSurveyOrigin_y + $CRT_USBotRight_y + $ModuleSMDist; +$posCRTUS_z[15] = $CRTSurveyOrigin_z + $CRT_USBotRightFr_z - $ModuleOff_z; +$posCRTUS_rot[15] = "rMinus90AboutYMinus90AboutX"; + + +#################################################################### +######################## ARAPUCA Dimensions ######################## +## in cm + +$ArapucaOut_x = 65.3; +$ArapucaOut_y = 2.5; +$ArapucaOut_z = 65.3; +$ArapucaIn_x = 60.0; +$ArapucaIn_y = 2.0; +$ArapucaIn_z = 60.0; +$ArapucaAcceptanceWindow_x = 60.0; +$ArapucaAcceptanceWindow_y = 1.0; +$ArapucaAcceptanceWindow_z = 60.0; +$GapPD = 0.5; #Arapuca distance from Cathode Frame +$CathodeFrameToFC = 15.1; +$FCToArapucaSpaceLat = 65 + $ArapucaOut_y; #X-ARAPUCA frame distance from FC. 65 cm to X-ARAPUCA window. +$FirstFrameVertDist = 37.57; # 30.0 --> 37.57 cm # Vertical distance from top/bottom anode (=204.55+85.3 cm above/below cathode) +$Upper_FirstFrameVertDist = 302.6; +$Lower_FirstFrameVertDist = 280.7; # Vertical distance from cathode center in cold +$VerticalPDdist = 75.6; # 75.8 (warm) -> 75.6 (cold) distance between arapucas (center to center) in the y direction in cold +$heightElectronicBox = 7.5; #height of arapuca electronic box is 7.7 cm but some of it may be inside the cathode frame (all facing the non-tco side) + +#Positions of the 4 arapucas with respect to the Frame center --> arapucas over the cathode +$list_posx_bot[0]=-1*$widthCathodeVoid - 2.0*$CathodeBorder - $GapPD - 0.5*$ArapucaOut_x; +$list_posz_bot[0]= -0.5*$lengthCathodeVoid - $CathodeBorder; +$list_posx_bot[1]= $widthCathodeVoid + $CathodeBorder - $GapPD - 0.5*$ArapucaOut_x; +$list_posz_bot[1]=-1.5*$lengthCathodeVoid - 2.0*$CathodeBorder; +$list_posx_bot[2]=-$CathodeBorder - $GapPD - 0.5*$ArapucaOut_x; +$list_posz_bot[2]=-$list_posz_bot[1]; +$list_posx_bot[3]= 2*$widthCathodeVoid + 2.0*$CathodeBorder - $GapPD - 0.5*$ArapucaOut_x; +$list_posz_bot[3]=-$list_posz_bot[0]; + +#+++++++++++++++++++++++++ End defining variables ++++++++++++++++++++++++++ + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++ usage +++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub usage() +{ + print "Usage: $0 [-h|--help] [-o|--output ] [-s|--suffix ]\n"; + print " if -o is omitted, output goes to STDOUT; is input to make_gdml.pl\n"; + print " -s appends the string to the file names; useful for multiple detector versions\n"; + print " -h prints this message, then quits\n"; +} + + +sub gen_Extend() +{ + +# Create the fragment file name, +# add file to list of fragments, +# and open it + $DEF = $basename."_Ext" . $suffix . ".gdml"; + push (@gdmlFiles, $DEF); + $DEF = ">" . $DEF; + open(DEF) or die("Could not open file $DEF for writing"); +#Check out +print DEF < + + + + + + + + + + +EOF + close (DEF); +} + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++++ gen_Define +++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_Define() +{ + +# Create the fragment file name, +# add file to list of fragments, +# and open it + $DEF = $basename."_Def" . $suffix . ".gdml"; + push (@gdmlFiles, $DEF); + $DEF = ">" . $DEF; + open(DEF) or die("Could not open file $DEF for writing"); + + +print DEF < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + close (DEF); +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++ gen_Materials +++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_Materials() +{ + +# Create the fragment file name, +# add file to list of output GDML fragments, +# and open it + $MAT = $basename."_Materials" . $suffix . ".gdml"; + push (@gdmlFiles, $MAT); + $MAT = ">" . $MAT; + + open(MAT) or die("Could not open file $MAT for writing"); + + # Add any materials special to this geometry by defining a mulitline string + # and passing it to the gdmlMaterials::gen_Materials() function. +my $asmix = < + + + + + +EOF + + # add the general materials used anywere + print MAT gdmlMaterials::gen_Materials( $asmix ); + + close(MAT); +} + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++++++ gen_TPC ++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# line clip on the rectangle boundary +sub lineClip { + my $x0 = $_[0]; + my $y0 = $_[1]; + my $nx = $_[2]; + my $ny = $_[3]; + my $rcl = $_[4]; + my $rcw = $_[5]; + + my $tol = 1.0E-4; + my @endpts = (); + if( abs( nx ) < tol ){ + push( @endpts, ($x0, 0) ); + push( @endpts, ($x0, $rcw) ); + return @endpts; + } + if( abs( ny ) < tol ){ + push( @endpts, (0, $y0) ); + push( @endpts, ($rcl, $y0) ); + return @endpts; + } + + # left border at x = 0 + my $y = $y0 - $x0 * $ny/$nx; + if( $y >= 0 && $y <= $rcw ){ + push( @endpts, (0, $y) ); + } + + # right border at x = l + $y = $y0 + ($rcl-$x0) * $ny/$nx; + if( $y >= 0 && $y <= $rcw ){ + push( @endpts, ($rcl, $y) ); + if( scalar(@endpts) == 4 ){ + return @endpts; + } + } + + # bottom border at y = 0 + my $x = $x0 - $y0 * $nx/$ny; + if( $x >= 0 && $x <= $rcl ){ + push( @endpts, ($x, 0) ); + if( scalar(@endpts) == 4 ){ + return @endpts; + } + } + + # top border at y = w + $x = $x0 + ($rcw-$y0)* $nx/$ny; + if( $x >= 0 && $x <= $rcl ){ + push( @endpts, ($x, $rcw) ); + } + + return @endpts; +} + +sub gen_Wires +{ + my $length = $_[0]; # + my $width = $_[1]; # + my $nch = $_[2]; # + my $pitch = $_[3]; # + my $theta = $_[4]; # deg + my $dia = $_[5]; # + my $w1offx = $_[6]; # offset for wire 1 1st coord + my $w1offy = $_[7]; # offset for wire 1 2nd coord + + $theta = $theta * pi()/180.0; + my @dirw = (cos($theta), sin($theta)); + my @dirp = (cos($theta - pi()/2), sin($theta - pi()/2)); + + # calculate + my $alpha = $theta; + if( $alpha > pi()/2 ){ + $alpha = pi() - $alpha; + } + my $dX = $pitch / sin( $alpha ); + my $dY = $pitch / sin( pi()/2 - $alpha ); + + my @orig = ($w1offx, $w1offy); + if( $dirp[0] < 0 ){ + $orig[0] = $length - $w1offx; + } + if( $dirp[1] < 0 ){ + $orig[1] = $width - $w1offy; + } + + #print "origin : @orig\n"; + #print "pitch dir : @dirp\n"; + #print "wire dir : @dirw\n"; + #print "$length x $width cm2\n"; + + # gen wires + my @winfo = (); + my $offset = 0; # starting point is now given by w1offx and w1offy + foreach my $ch (0..$nch-1){ + #print "Processing $ch\n"; + + # calculate reference point for this strip + my @wcn = (0, 0); + $wcn[0] = $orig[0] + $offset * $dirp[0]; + $wcn[1] = $orig[1] + $offset * $dirp[1]; + + # line clip on the rectangle boundary + @endpts = lineClip( $wcn[0], $wcn[1], $dirw[0], $dirw[1], $length, $width ); + + if( scalar(@endpts) != 4 ){ + print "Could not find end points for wire $ch : @endpts\n"; + $offset = $offset + $pitch; + next; + } + + # re-center on the mid-point + $endpts[0] -= $length/2; + $endpts[2] -= $length/2; + $endpts[1] -= $width/2; + $endpts[3] -= $width/2; + + # calculate the strip center in the rectangle of CRU + $wcn[0] = ($endpts[0] + $endpts[2])/2; + $wcn[1] = ($endpts[1] + $endpts[3])/2; + + # calculate the length + my $dx = $endpts[0] - $endpts[2]; + my $dy = $endpts[1] - $endpts[3]; + my $wlen = sqrt($dx**2 + $dy**2); + + # put all info together + my @wire = ($ch, $wcn[0], $wcn[1], $wlen); + push( @wire, @endpts ); + push( @winfo, \@wire); + $offset = $offset + $pitch; + #last; + } + return @winfo; +} + +sub split_wires +{ + # split wires at y = 0 line (widht / 2) + # assumes that the CRU wire plane has been + # centered already on 0,0 + + # reference to array of wires + my $wires = $_[0]; + my $width = $_[1]; # split + my $theta = $_[2]; # deg + + ### + my $yref = 0; + my $nx = cos($theta * pi()/180.0); + my $ny = sin($theta * pi()/180.0); + my $ich1 = 0; + my $ich2 = 0; + my @winfo1 = (); # lower half of CRU + my @winfo2 = (); # upper half of CRU + + foreach my $wire (@$wires){ + my $x0 = $wire->[1]; + my $y0 = $wire->[2]; + my @endpts = ($wire->[4], $wire->[5], + $wire->[6], $wire->[7]); + + # min of two y-values + my $y1 = ($endpts[1], $endpts[3])[$endpts[1] > $endpts[3]]; + # max of two y-values + my $y2 = ($endpts[1], $endpts[3])[$endpts[1] < $endpts[3]]; + if( $y2 < $yref ) + { + my @wire1 = ($ich1, $x0, $y0, $wire->[3]); + push( @wire1, @endpts ); + push( @winfo1, \@wire1); + $ich1++; + next; + } + elsif( $y1 > $yref ) + { + my @wire2 = ($ich2, $x0, $y0, $wire->[3]); + push( @wire2, @endpts ); + push( @winfo2, \@wire2); + $ich2++; + next; + } + + # calculate an intercept point with yref + $y = $yref; + $x = $x0 + ($y - $y0) * $nx/$ny; + + # make new endpoints + my @endpts1 = @endpts; + my @endpts2 = @endpts; + if( $endpts[1] < $y ) + { + $endpts1[2] = $x; + $endpts1[3] = $y; + $endpts2[0] = $x; + $endpts2[1] = $y; + } + else + { + $endpts1[0] = $x; + $endpts1[1] = $y; + $endpts2[2] = $x; + $endpts2[3] = $y; + } + + my @wcn1 = (0, 0); + $wcn1[0] = ($endpts1[0] + $endpts1[2])/2; + $wcn1[1] = ($endpts1[1] + $endpts1[3])/2; + my $dx = $endpts1[0] - $endpts1[2]; + my $dy = $endpts1[1] - $endpts1[3]; + my $wlen1 = sqrt($dx**2 + $dy**2); + my @wire1 = ($ich1, $wcn1[0], $wcn1[1], $wlen1); + push( @wire1, @endpts1 ); + push( @winfo1, \@wire1 ); + $ich1++; + + my @wcn2 = (0, 0); + $wcn2[0] = ($endpts2[0] + $endpts2[2])/2; + $wcn2[1] = ($endpts2[1] + $endpts2[3])/2; + $dx = $endpts2[0] - $endpts2[2]; + $dy = $endpts2[1] - $endpts2[3]; + my $wlen2 = sqrt($dx**2 + $dy**2); + my @wire2 = ($ich2, $wcn2[0], $wcn2[1], $wlen2); + push( @wire2, @endpts2 ); + push( @winfo2, \@wire2 ); + $ich2++; + } + + #return ( \@winfo1, \@winfo2 ); + foreach my $w (@winfo1){ + $w->[5] -= (-0.25 * $width); + $w->[7] -= (-0.25 * $width); + $w->[2] = 0.5 * ($w->[5]+$w->[7]); + } + + foreach my $w (@winfo2){ + $w->[5] -= (0.25 * $width); + $w->[7] -= (0.25 * $width); + $w->[2] = 0.5 * ($w->[5]+$w->[7]); + } + + return ( \@winfo1, \@winfo2 ); +} + +sub flip_wires +{ + # flip generated wires for one CRU by 180 deg + # for the 2nd CRU + + # input array + my $wires = $_[0]; + # output array + my @winfo = (); + foreach my $wire (@$wires){ + my $xn1 = -$wire->[4]; + my $yn1 = -$wire->[5]; + my $xn2 = -$wire->[6]; + my $yn2 = -$wire->[7]; + my $xc = 0.5*($xn1 + $xn2); + my $yc = 0.5*($yn1 + $yn2); + my @new_wire = ($wire->[0], $xc, $yc, $wire->[3], + $xn1, $yn1, $xn2, $yn2 ); + push( @winfo, \@new_wire); + } + return @winfo; +} + +# +sub gen_crm +{ + my $quad = $_[0]; # CRP quadrant: 0, 1, 2, 3 + my $winfoU = $_[1]; + my $winfoV = $_[2]; + + my $do_init = $quad; + + + # CRM active volume + my $TPCActive_x = $driftTPCActive; + my $TPCActive_y = $widthCRP / 2; + my $TPCActive_z = $lengthCRP / 2; + + # CRM total volume + my $TPC_x = $TPCActive_x + $ReadoutPlane; + my $TPC_y = $TPCActive_y; + my $TPC_z = $TPCActive_z; + + # readout plane dimensions + my $UPlaneLength = $lengthPCBActive; + my $VPlaneLength = $lengthPCBActive; + my $ZPlaneLength = $lengthPCBActive; + + my $UPlaneWidth = $widthPCBActive / 2; + my $VPlaneWidth = $widthPCBActive / 2; + my $ZPlaneWidth = $widthPCBActive / 2; + + if( $do_init == 0 ){ + #print " $UPlaneWidth x $UPlaneLenght\n"; + print " TPC vol dimensions : $TPC_x x $TPC_y x $TPC_z\n"; + } + + $TPC = $basename."_TPC$quad" . $suffix . ".gdml"; + push (@gdmlFiles, $TPC); + $TPC = ">" . $TPC; + open(TPC) or die("Could not open file $TPC for writing"); + + # The standard XML prefix and starting the gdml +print TPC < + +EOF + + # All the TPC solids save the wires. +print TPC < +EOF + +if( $do_init == 0 ){ # do it only once +print TPC < + + + + +EOF +} + +#++++++++++++++++++++++++++++ Wire Solids ++++++++++++++++++++++++++++++ +if($wires_on == 1 ){ + + foreach my $wire (@$winfoU){ + my $wid = $wire->[0]; + my $wln = $wire->[3]; +print TPC < +EOF + } + + foreach my $wire (@$winfoV){ + my $wid = $wire->[0]; + my $wln = $wire->[3]; +print TPC < +EOF + } + + + # Z wires are all the same length +print TPC < +EOF +} # if wires_on +print TPC < +EOF + +# Begin structure and create wire logical volume +# but do it only once for the volumes that are the same +# for all CRP quadrants +print TPC < +EOF +if( $do_init == 0 ){ # do it only once +print TPC < + + + + + + + +EOF +} + + +if($wires_on==1) +{ + foreach my $wire (@$winfoU){ + my $wid = $wire->[0]; +print TPC < + + + +EOF + } + + foreach my $wire (@$winfoV){ + my $wid = $wire->[0]; +print TPC < + + + +EOF + } + +print TPC < + + + +EOF +} + + + # + # 1st induction plane +print TPC < + + +EOF +if ($wires_on==1) # add wires to U plane +{ + # if the coordinates were computed with a corner at (0,0) + # we need to move to plane coordinates + my $offsetZ = 0; + my $offsetY = 0; + # + foreach my $wire (@$winfoU) { + my $wid = $wire->[0]; + my $zpos = $wire->[1] + $offsetZ; + my $ypos = $wire->[2] + $offsetY; +print TPC < + + + + +EOF + } +} +print TPC < +EOF + +# +# 2nd induction plane +print TPC < + + +EOF + +if ($wires_on==1) # add wires to V plane + { + # if the coordinates were computed with a corner at (0,0) + # we need to move to plane coordinates + my $offsetZ = 0; + my $offsetY = 0; + + foreach my $wire (@$winfoV) { + my $wid = $wire->[0]; + my $zpos = $wire->[1] + $offsetZ; + my $ypos = $wire->[2] + $offsetY; +print TPC < + + + + +EOF + } +} +print TPC < +EOF + +# collection plane +print TPC < + + +EOF +if ($wires_on==1) # add wires to Z plane (plane with wires reading z position) + { + my $nch = $nChans{'Col'}/2; + my $zdelta = $lengthPCBActive - $wirePitchZ * $nch; + if( $zdelta < 0 ){ + print " Bad dimensions : Z delta $zdelta should be positive or 0\n"; + $zdelta = 0; + } + + my $zoffset = $zdelta; + if( $quad > 1 ){ $zoffset = 0; } + for($i=0;$i<$nch;++$i) + { + my $zpos = $zoffset + ( $i + 0.5) * $wirePitchZ - 0.5 * $lengthPCBActive; + if( (0.5 * $lengthPCBActive - abs($zpos)) < 0 ){ + die "Cannot place wire $i in view Z, as plane is too small\n"; + } + my $wid = $i + $quad * $nch; +print TPC < + + + + +EOF + } +} +print TPC < +EOF + +my @posUplane = (0, 0, 0); +$posUplane[0] = 0.5*$TPC_x - 2.5*$padWidth; +$posUplane[1] = 0; +$posUplane[2] = 0; + +my @posVplane = (0, 0, 0); +$posVplane[0] = 0.5*$TPC_x - 1.5*$padWidth; +$posVplane[1] = 0; +$posVplane[2] = 0; + +my @posZplane = (0, 0, 0); +$posZplane[0] = 0.5*$TPC_x - 0.5*$padWidth; +$posZplane[1] = 0; +$posZplane[2] = 0; + +my @posTPCActive = (0, 0, 0); +$posTPCActive[0] = -$ReadoutPlane/2; +$posTPCActive[1] = 0; +$posTPCActive[2] = 0; + + +#wrap up the TPC file +print TPC < + + + + + + + + + + + + + + + + + + + + + + + +EOF + +print TPC < + +EOF + + close(TPC); +} + + +sub gen_TopCRP +{ + # Total volume covered by CRP envelope + my $CRP_x = $driftTPCActive + $ReadoutPlane; + my $CRP_y = $widthCRP; + my $CRP_z = $lengthCRP; + print " CRP vol dimensions : $CRP_x x $CRP_y x $CRP_z\n"; + + # compute wires for 1st and 2nd induction + my @winfoU = (); + my @winfoV = (); + if( $wires_on == 1 ){ + # normally should do this only once once, but perl is impossible + + # first CRU + my @winfoU1 = gen_Wires( $lengthPCBActive, $widthPCBActive, + $nChans{'Ind1'}, + $wirePitchU, $wireAngleU, $padWidth, + $offsetUVwire[0], $offsetUVwire[1]); + my @winfoV1 = gen_Wires( $lengthPCBActive, $widthPCBActive, + $nChans{'Ind2'}, + $wirePitchV, $wireAngleV, $padWidth, + $offsetUVwire[0], $offsetUVwire[1]); + # second CRU + my @winfoU2 = flip_wires( \@winfoU1 ); + my @winfoV2 = flip_wires( \@winfoV1 ); + #foreach my $wire (@winfoU2){ + #printf ("U%d %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n", + #$wire->[0], $wire->[1], $wire->[2], + #$wire->[3], $wire->[4], $wire->[5], + #$wire->[6], $wire->[7]); + #} + + my ($winfoU1a, $winfoU1b) = split_wires( \@winfoU1, $widthPCBActive, $wireAngleU ); + my ($winfoV1a, $winfoV1b) = split_wires( \@winfoV1, $widthPCBActive, $wireAngleV ); + + my ($winfoU2a, $winfoU2b) = split_wires( \@winfoU2, $widthPCBActive, $wireAngleU ); + my ($winfoV2a, $winfoV2b) = split_wires( \@winfoV2, $widthPCBActive, $wireAngleV ); + + # put them the same order as volTPCs for a given CRP + @winfoU = ($winfoU1a, $winfoU1b, $winfoU2a, $winfoU2b); + @winfoV = ($winfoV1a, $winfoV1b, $winfoV2a, $winfoV2b); + + # assign unique ID to each CRM wire + my $wcountU=0; + foreach my $crm_wires (@winfoU){ + foreach my $wire (@$crm_wires){ + $wire->[0] = $wcountU; + $wcountU++; + #printf ("U%d %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n", + #$wire->[0], $wire->[1], $wire->[2], + #$wire->[3], $wire->[4], $wire->[5], + #$wire->[6], $wire->[7]); + + } + } + + my $wcountV=0; + foreach my $crm_wires (@winfoV){ + foreach my $wire (@$crm_wires){ + $wire->[0] = $wcountV; + $wcountV++; + } + } + } + + # generate GDML fragments for 4 CRP quadrants + for my $quad (0..3) + { + if( $wires_on == 1 ){ + gen_crm( $quad, $winfoU[$quad], $winfoV[$quad] ); + } else { + @dummpy = (); + gen_crm( $quad, \@dummy, \@dummy ); + } + } +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++ gen_FieldCage +++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_FieldCage { + + $FieldCage = $basename."_FieldCage" . $suffix . ".gdml"; + push (@gdmlFiles, $FieldCage); + $FieldCage = ">" . $FieldCage; + open(FieldCage) or die("Could not open file $FieldCage for writing"); + +# The standard XML prefix and starting the gdml +print FieldCage < + +EOF + +print FieldCage < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +################################################# Field Cage ################################################# + +print FieldCage < + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +print FieldCage < +EOF +close(FieldCage); +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++ Cathode mesh ++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_CathodeMesh { + + $CathodeMesh = $basename."_CathodeMesh" . $suffix . ".gdml"; + push (@gdmlFiles, $CathodeMesh); + $CathodeMesh = ">" . $CathodeMesh; + open(CathodeMesh) or die("Could not open file $CathodeMesh for writing"); + +# The standard XML prefix and starting the gdml +print CathodeMesh < + +EOF + +#Cathode Mesh SOLIDS +print CathodeMesh < + + + +EOF +# First cathode mesh vertical strip +print CathodeMesh < + + + + +EOF +for($ii=2; $ii<$CathodeMeshInnerStructureNumberOfStrips_vertical; $ii++) +{ + print CathodeMesh < + + + + +EOF +} +print CathodeMesh < + + + + +EOF +for($jj=1; $jj<$CathodeMeshInnerStructureNumberOfStrips_horizontal; $jj++) +{ + print CathodeMesh < + + + + +EOF +} +print CathodeMesh < +EOF + +print CathodeMesh < + + + + + + + + + + + + + + + + + + + + + + +EOF +close(CathodeMesh); +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++ X-ARAPUCA mesh ++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_ArapucaMesh { + + $ArapucaMesh = $basename."_ArapucaMesh" . $suffix . ".gdml"; + push (@gdmlFiles, $ArapucaMesh); + $ArapucaMesh = ">" . $ArapucaMesh; + open(ArapucaMesh) or die("Could not open file $ArapucaMesh for writing"); + +# The standard XML prefix and starting the gdml +print ArapucaMesh < + +EOF + +############## Membrane X-ARAPUCA Mesh Parameters ############### +$ArapucaMeshTubeLength_vertical = 65.3; +$ArapucaMeshTubeLength_horizontal = 72.4; +$ArapucaMeshInnerRadious = 0; +$ArapucaMeshOuterRadious = 0.6; +$ArapucaMeshTorRad = 5; + +$ArapucaMeshInnerStructureLength_vertical = 73.5; +$ArapucaMeshInnerStructureLength_horizontal = 80.9; +$ArapucaMeshRodInnerRadious = 0; +$ArapucaMeshRodOuterRadious = 0.1; +$ArapucaMeshInnerStructureSeparation = 7.388 + $ArapucaMeshRodOuterRadious; +$ArapucaMeshInnerStructureNumberOfBars_vertical = 11; +$ArapucaMeshInnerStructureNumberOfBars_horizontal = 9; + +$Distance_Mesh_Arapuca_window = 1.8 + $ArapucaMeshOuterRadious; + +############## Cathode X-ARAPUCA Mesh Parameters ############### +$CathodeArapucaMeshRodRadious = 0.063/2; #cm +$CathodeArapucaMeshRodSeparation = 1.27; #center to center of cathode X-ARAPUCA mesh profiles in cm +$CathodeArapucaMeshNumberOfBars_vertical = $lengthCathodeVoid/1.27; #60.827 +$CathodeArapucaMeshNumberOfBars_horizontal = $widthCathodeVoid/1.27; #52.95 +$CathodeArapucaMesh_verticalOffset = 0.525; +$CathodeArapucaMesh_horizontalOffset = 0.605; +$CathodeArapucaMeshOffset_Y = 0.5; #cm + +print ArapucaMesh < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +$xMeshorigin = 0.5*$ArapucaMeshTubeLength_horizontal + $ArapucaMeshTorRad; + +$zMeshorigin = 0; + +print ArapucaMesh < + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +for($ii=0; $ii<$ArapucaMeshInnerStructureNumberOfBars_vertical; $ii++) +{ + print ArapucaMesh < + + + +EOF +} + +for($ii=0; $ii<$ArapucaMeshInnerStructureNumberOfBars_horizontal; $ii++) +{ + print ArapucaMesh < + + + + +EOF +} +#Cathode X-ARAPUCA mesh + print ArapucaMesh < + + + +EOF + +for($ii=0; $ii<$CathodeArapucaMeshNumberOfBars_vertical; $ii++) +{ + print ArapucaMesh < + + + +EOF +} + +for($ii=0; $ii<$CathodeArapucaMeshNumberOfBars_horizontal; $ii++) +{ + print ArapucaMesh < + + + + +EOF +} + print ArapucaMesh < + + +EOF +close(ArapucaMesh); +} + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++++++ gen_pmt ++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_pmt { + + $PMT = $basename."_PMT" . $suffix . ".gdml"; + push (@gdmlFiles, $PMT); + $PMT = ">" . $PMT; + open(PMT) or die("Could not open file $PMT for writing"); + + print PMT < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF +} + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++++ gen_Cryostat +++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_Cryostat() +{ + +# Create the cryostat fragment file name, +# add file to list of output GDML fragments, +# and open it + $CRYO = $basename."_Cryostat" . $suffix . ".gdml"; + push (@gdmlFiles, $CRYO); + $CRYO = ">" . $CRYO; + open(CRYO) or die("Could not open file $CRYO for writing"); + + +# The standard XML prefix and starting the gdml + print CRYO < + +EOF + +# All the cryostat solids. +print CRYO < + + +EOF + +print CRYO < + + + + + + + + + + + + + + + + + + + + + + +EOF + +#PDS +#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 lateral and cathode) +print CRYO < + + + + + + + + + + + + + + + + +EOF + +# Cryostat structure +print CRYO < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +#PDS converage +for($i=0 ; $i<$nCRM_x/2 ; $i++){ #arapucas over the cathode +for($j=0 ; $j<$nCRM_z/2 ; $j++){ +for($p=0 ; $p<4 ; $p++){ + print CRYO < + + + + + + + +EOF +} +} +} + +#arapucas on the laterals +for($j=0 ; $j<$nCRM_x/2 ; $j++){ +for($p=0 ; $p<8 ; $p++){ + print CRYO < + + + + + + + +EOF +} +} + + print CRYO < + + + + + + + + + + + + + + + +EOF + +print CRYO < + + + + + + + + + + + + + + + + +EOF +print "Beam Plug position x=".$BePlFlange_x." y=".$BePlFlange_y." z=".$BePlFlange_z."\n"; + +# nested for loops to place the non-rotated AND rotated volTPC + # x loop rotation: There are two drift volumes. Top volume has readout on top and bottom volume on bottom. + # Default is TPC with readout on top so we need to rotate the bottom TPC 180deg about Y. +if ($tpc_on==1) # place Top and Bottom TPCs inside croystat offsetting each pair of CRMs by borderCRP +{ + $posX = $Argon_x/2 - $HeightGaseousAr - $Upper_xLArBuffer - 0.5*($driftTPCActive + $ReadoutPlane); + $posXBot = $posX - $driftTPCActive - $heightCathode - $ReadoutPlane; + $idx = 0; + + my $CRP_y = $widthCRP; + my $CRP_z = $lengthCRP; + my $myposTCPY = 0; + my $myposTPCZ = 0; + + my $posZ = -0.5*$Argon_z + $zLArBuffer + 0.5*$CRP_z; + + for(my $ii=0;$ii<$nCRM_z;$ii++) + { + if( $ii % 2 == 0 && $ii>0){$posZ += $CRP_z;} + my $posY = -0.5*$Argon_y + $yLArBuffer + 0.5*$CRP_y; + + for(my $jj=0;$jj<$nCRM_x;$jj++) + { + if( $jj % 2 == 0 && $jj>0){$posY += $CRP_y;} + + if($ii%2==0){ + if($jj%2==0){ + $quad=0; + $pcbOffsetY = $borderCRP/2; # offset of the active area from CRP envelope + $pcbOffsetZ = ($borderCRP/2 - $gapCRU/4); + $myposTPCY = $posY-$CRP_y/4 + $pcbOffsetY; + $myposTPCZ = $posZ-$CRP_z/4 + $pcbOffsetZ; + }else{ + $quad=1; + $pcbOffsetY = -$borderCRP/2; + $pcbOffsetZ = ($borderCRP/2 - $gapCRU/4); + $myposTPCY = $posY+$CRP_y/4 + $pcbOffsetY; + $myposTPCZ = $posZ-$CRP_z/4 + $pcbOffsetZ; + } + }else{ + if($jj%2==0){ + $quad=2; + $pcbOffsetY = $borderCRP/2; + $pcbOffsetZ = -($borderCRP/2 - $gapCRU/4); + $myposTPCY = $posY-$CRP_y/4 + $pcbOffsetY; + $myposTPCZ = $posZ+$CRP_z/4 + $pcbOffsetZ; + }else{ + $quad=3; + $pcbOffsetY = -$borderCRP/2; + $pcbOffsetZ = -($borderCRP/2 - $gapCRU/4); + $myposTPCY = $posY+$CRP_y/4 + $pcbOffsetY; + $myposTPCZ = $posZ+$CRP_z/4 + $pcbOffsetZ; + } + } + + print CRYO < + + + + + + + + +EOF + $idx++; + } + } +} + +#Field cage profiles structure + if ( $FieldCage_switch eq "on" ) { + for ( $i=0; $i<$NFieldShapers; $i=$i+1 ) { # $NFieldShapers = 144: 36 slim + 42 thick + 36 slim + $dist = $i*$FieldShaperSeparation; + $FirstFieldShaper_to_MembraneRoof = 76; #cm + $posX = $Cryostat_x/2 - $FirstFieldShaper_to_MembraneRoof - $dist; + if ($i<36||$i>77){ + print CRYO < + + + + +EOF + }else{ + print CRYO < + + + + +EOF + } + } + } + +#Cathode +$CathodePosX = $Argon_x/2 - $HeightGaseousAr - $Upper_xLArBuffer - ($driftTPCActive + $ReadoutPlane) - 0.5*$heightCathode; +$CathodePosY = -0.5*$Argon_y + $yLArBuffer + 0.5*$widthCathode; +$CathodePosZ = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCathode; +$posAnodePlateTop = $CathodePosX + 0.5*$heightCathode + $driftTPCActive + $nViews*$padWidth + $anodePlateWidth/2;#right above TPC vol +$posAnodePlateBot = $posAnodePlateTop -2.*($driftTPCActive + $nViews*$padWidth) - $anodePlateWidth - $heightCathode; + +$idx = 0; + if ( $Cathode_switch eq "on" ) + { + for(my $ii=0;$ii<$nCRM_z/2;$ii++) + { + for(my $jj=0;$jj<$nCRM_x/2;$jj++) + { + print CRYO < + + + +EOF + print CRYO < + + + + + + + + + + +EOF + $idx++; + $CathodePosY += $widthCathode; + } + $CathodePosZ += $lengthCathode; + $CathodePosY = -0.5*$Argon_y + $yLArBuffer + 0.5*$widthCathode; + } + } + +# Adding Dual Phase PMTs + # Get the PMT array length + $pmt_array_length = scalar @pmt_pos; + $pmt_pos_x = -367.6; # Hardcoded value to ensure a distance of 38cm from the photocathode to the membrane floor! + $jj=0; + for ( $i=0; $i<$pmt_array_length; $i=$i+1 ) { + + $k = $i + 1; + + # Define the rotation string + if ( grep { $_ == $k } @pmt_left_rotated ) { + $rot = "rPlus180AboutX"; + } elsif ( grep { $_ == $k } @pmt_right_rotated ) { + $rot = "rIdentity"; + } else { + $rot = "rMinus90AboutY"; + } + + # Define the PMT type string + if ( grep { $_ == $k } @pmt_TPB ) { + $pmt_type = "volPMT_coated"; + } else { + $pmt_type = "volPMT_foil"; + } + + if ( grep { $_ == $k } @pmt_left_rotated or grep { $_ == $k } @pmt_right_rotated ) { + +#Rotated PMTs also have a Ground Grid mesh in front of it. + print CRYO < + + + + +EOF + $jj=$jj+1; + } + + else{ + print CRYO < + + + + +EOF + } + } + +# End adding Dual Phase PMTs + +#for placing the Arapucas and their meshes over the cathode + $FrameCenter_y=-0.5*$Argon_y + $yLArBuffer + 0.5*$widthCathode; + $FrameCenter_x=$CathodePosX; + $FrameCenter_z=-0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCathode; +for($i=0;$i<$nCRM_x/2;$i++){ + for($j=0;$j<$nCRM_z/2;$j++){ + place_OpDetsCathode($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $i, $j); + + if($ArapucaMesh_switch eq "on"){ + place_MeshCathode($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $i, $j); + place_ResistiveMeshCathode($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $i, $j); + } + $FrameCenter_z+=$lengthCathode; + } + $FrameCenter_y+=$widthCathode; + $FrameCenter_z=-0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCathode; +} + +#for placing the Arapucas on laterals + $FrameCenter_x = $CathodePosX; + $FrameCenter_y = -$widthCathode - $CathodeFrameToFC - $FCToArapucaSpaceLat + $ArapucaOut_y/2; + $FrameCenter_z = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCathode; + +for($j=0;$j<1;$j++){#nCRM will give the column number (1 column per frame) + place_OpDetsLateral($FrameCenter_x, $FrameCenter_y, $FrameCenter_z, $j); + $FrameCenter_z+=2*$lengthCathode; +} + + +$MeshCenter_x = $CathodePosX; +$MeshCenter_y = -$widthCathode - $CathodeFrameToFC - $FCToArapucaSpaceLat + $ArapucaOut_y; +$MeshCenter_z = -0.5*$Argon_z + $zLArBuffer + 0.5*$lengthCathode; +#for placing the X-ARAPUCA meshes on laterals +if($ArapucaMesh_switch eq "on") +{ + for($j=0;$j<1;$j++){#nCRM will give the column number (1 column per frame) + place_MeshLateral($MeshCenter_x, $MeshCenter_y, $MeshCenter_z, $j); + } +} + +print CRYO < + + +EOF + +close(CRYO); +} + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++ place_OpDets +++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub place_OpDetsCathode() +{ + + $FrameCenter_x = $_[0]; + $FrameCenter_y = $_[1]; + $FrameCenter_z = $_[2]; + $Frame_x = $_[3]; + $Frame_z = $_[4]; + +for ($ara = 0; $ara<4; $ara++) +{ + # All Arapuca centers will have the same X coordinate + # Y and Z coordinates are defined with respect to the center of the current Frame + + $Ara_Z = $FrameCenter_z+$list_posz_bot[$ara]; + #if($Ara_z==1&&$ara==2){$Ara_Z = $FrameCenter_z+$list_posz_bot[0];} #If Z is longer + $Ara_X = $FrameCenter_x; + if($Frame_x==0&&$ara==0){$Ara_Y = $FrameCenter_y+$list_posx_bot[2]; + }else{$Ara_Y = $FrameCenter_y+$list_posx_bot[$ara];} #GEOMETRY IS ROTATED: X--> Y AND Y--> X + $Ara_Y = $Ara_Y - $heightElectronicBox; + + print CRYO < + + + + + + + + +EOF + +}#end Ara for-loop + +} + +sub place_OpDetsLateral() +{ + + $FrameCenter_x = $_[0]; + $FrameCenter_y = $_[1]; + $FrameCenter_z = $_[2]; + $Lat_z = $_[3]; + +#Placing Arapucas on the laterals +for ($ara = 0; $ara<8; $ara++) +{ + # Arapucas on laterals + # All Arapuca centers on a given column will have the same Z coordinate + # X coordinates are on the left and right laterals + # Y coordinates are defined with respect to the cathode position + +$Ara_Y = $FrameCenter_y; +$Ara_Z = $FrameCenter_z; + if ($ara<4) {$Ara_YSens = ($Ara_Y + 0.5*$ArapucaOut_y - 0.5*$ArapucaAcceptanceWindow_y - 0.01); + $rot= "rIdentity"; } + else { $Ara_Y = $Ara_Y + 2*$widthCathode + 2*($CathodeFrameToFC + $FCToArapucaSpaceLat - $ArapucaOut_y/2); + $Ara_YSens = ($Ara_Y -0.5*$ArapucaOut_y + 0.5*$ArapucaAcceptanceWindow_y + 0.01); + $rot = "rPlus180AboutX";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X + if ($ara==0||$ara==4) { + $Ara_X = $FrameCenter_x + $Upper_FirstFrameVertDist; + } #first tile center distance from top anode + if ($ara==1||$ara==5) {$Ara_X-=$VerticalPDdist;} #other tiles separated by VerticalPDdist + if ($ara==2||$ara==6) { + $Ara_X = $FrameCenter_x - $Lower_FirstFrameVertDist; + } #first tile center distance from bottom anode + if ($ara==3||$ara==7) {$Ara_X+=$VerticalPDdist;} #other tiles separated by VerticalPDdist + + print CRYO < + + + + + + + + +EOF + +}#end Ara for-loop + +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++ place X-ARAPUCA Mesh +++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +if($ArapucaMesh_switch eq "on") +{ + #Cathode conductive mesh + sub place_MeshCathode() + { + + $FrameCenter_x = $_[0]; + $FrameCenter_y = $_[1]; + $FrameCenter_z = $_[2]; + $Frame_x = $_[3]; + $Frame_z = $_[4]; + + for ($mesh = 0; $mesh<4; $mesh++) + { + # All Mesh centers will have the same X coordinate + $Mesh_Z = $FrameCenter_z+$list_posz_bot[$mesh]; + $Mesh_X = $FrameCenter_x; + if($Frame_x==0 && $mesh==0){$Mesh_Y = $FrameCenter_y + $list_posx_bot[2];} + else{$Mesh_Y = $FrameCenter_y + $list_posx_bot[$mesh];} #GEOMETRY IS ROTATED: X--> Y AND Y--> X + # To correctly center cathode X-ARAPUCA meshes + $Mesh_Y = $Mesh_Y - 5.475; + + print CRYO < + + + + + + + + + +EOF + + }#end Cathode Conductive Mesh for-loop + + }#end Cathode Conductive Mesh subroutine + + #Cathode resistive mesh + sub place_ResistiveMeshCathode() + { + + $FrameCenter_x = $_[0]; + $FrameCenter_y = $_[1]; + $FrameCenter_z = $_[2]; + $Frame_x = $_[3]; + $Frame_z = $_[4]; + + # All Top/Bottom Mesh centers will have the same X coordinate + $TopMesh_X = $FrameCenter_x + ($heightCathode - $CathodeMeshInnerStructureThickness)/2; + $BotMesh_X = $TopMesh_X - ($heightCathode - $CathodeMeshInnerStructureThickness)/2; + + for ($mesh_y = 0; $mesh_y<4; $mesh_y++) + { + for ($mesh_z = 0; $mesh_z<4; $mesh_z++) + { + if($Frame_x==0){ + if(($mesh_y==0&&$mesh_z==2)||($mesh_y==1&&$mesh_z==0)||($mesh_y==2&&$mesh_z==1)||($mesh_y==2&&$mesh_z==3)) {$mesh_z++;} + }else{ + if(($mesh_y==0&&$mesh_z==2)||($mesh_y==1&&$mesh_z==0)||($mesh_y==2&&$mesh_z==3)||($mesh_y==3&&$mesh_z==1)) {$mesh_z++;} + } + $Mesh_Z = $FrameCenter_z+($mesh_z-1.5)*$lengthCathodeVoid+($mesh_z-2.0)*$CathodeBorder; + if($mesh_z>1) {$Mesh_Z+=$CathodeBorder;} + $Mesh_Y = $FrameCenter_y + $CathodeMeshOffset_Y - $mesh_y*$widthCathodeVoid - $mesh_y*$CathodeBorder; + if($mesh_y>1) {$Mesh_Y+=-$CathodeBorder;} + if($mesh_z<4){ + print CRYO < + + + + + + + +EOF + } + } #end mesh_z + $Mesh_Y+= $widthCathodeVoid + $CathodeBorder; + }#end mesh_y + + }#end Cathode Resistive Mesh subroutine + + + # Membrane mesh + sub place_MeshLateral() + { + + $MeshCenter_x = $_[0]; + $MeshCenter_y = $_[1]; + $MeshCenter_z = $_[2]; + $Lat_z = $_[3]; + + #Placing X-ARAPUCA meshes on the laterals + for ($mesh = 0; $mesh<8; $mesh++) + { + # X-ARAPUCA mesh on laterals + # All mesh centers on a given column will have the same Z coordinate + # X coordinates are on the left and right laterals + # Y coordinates are defined with respect to the cathode position + + $Mesh_Y = $MeshCenter_y; + $Mesh_Z = $MeshCenter_z; + if ($mesh<4) {$Mesh_Y = ($Mesh_Y + $Distance_Mesh_Arapuca_window); + $rot= "rot90AboutY"; } + else {$Mesh_Y = $Mesh_Y + 2*$widthCathode + 2*($CathodeFrameToFC + $FCToArapucaSpaceLat - $ArapucaOut_y) - $Distance_Mesh_Arapuca_window; + $rot = "rot05";} #GEOMETRY IS ROTATED: X--> Y AND Y--> X + if ($mesh==0||$mesh==4) {$Mesh_X = $MeshCenter_x + $Upper_FirstFrameVertDist;} #first mesh center distance from top anode + if ($mesh==1||$mesh==5) {$Mesh_X-=$VerticalPDdist;} + if ($mesh==2||$mesh==6) {$Mesh_X = $MeshCenter_x - $Lower_FirstFrameVertDist;} #first mesh center distance from bottom anode + if ($mesh==3||$mesh==7) {$Mesh_X+=$VerticalPDdist;} + + print CRYO < + + + + +EOF + }#end Mesh lateral for-loop + + } +} + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++ gen_Enclosure +++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_Enclosure() +{ + +# Create the detector enclosure fragment file name, +# add file to list of output GDML fragments, +# and open it + $ENCL = $basename."_DetEnclosure" . $suffix . ".gdml"; + push (@gdmlFiles, $ENCL); + $ENCL = ">" . $ENCL; + open(ENCL) or die("Could not open file $ENCL for writing"); + + +# The standard XML prefix and starting the gdml + print ENCL < + +EOF + + +# All the detector enclosure solids. +print ENCL < +EOF + + if($HD_CRT_switch eq "on"){ +# All the detector enclosure solids. +print ENCL < + + +EOF + } + + if($DP_CRT_switch eq "on"){ + print ENCL < + + + +EOF + } + + print ENCL < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + + +# Detector enclosure structure + print ENCL < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + +if($HD_CRT_switch eq "on"){ + +for($imod=0 ; $imod<16 ; $imod++){ + $modnum = $imod + 1; +for($i=0 ; $i<64 ; $i++){ + $padnum = $i+1; + $paddleid = "U$modnum"."_$padnum"; + print ENCL < + + + +EOF +} + print ENCL < + + +EOF +for($i=0 ; $i<32 ; $i++){ + $paddle_x1 = - $CRTModWidth/2 + $CRTPaddleWidth*($i + 0.5); + $paddle_x2 = - $CRTModWidth/2 + $CRTPaddleWidth*($i + 1); + $paddle_y1 = $CRTPaddleHeight/2; + $paddle_y2 = - $CRTPaddleHeight/2; + $paddle_z = 0; + $padnum1 = $i + 1; + $padnum2 = $i + 33; + $paddleid1 = "U$modnum"."_$padnum1"; + $paddleid2 = "U$modnum"."_$padnum2"; + print ENCL < + + + + + + + + + +EOF +} + print ENCL < +EOF +} + +for($imod=0 ; $imod<16 ; $imod++){ + $modnum = $imod + 1; +for($i=0 ; $i<64 ; $i++){ + $padnum = $i+1; + $paddleid = "D$modnum"."_$padnum"; + print ENCL < + + + +EOF +} + print ENCL < + + +EOF +for($i=0 ; $i<32 ; $i++){ + $paddle_x1 = - $CRTModWidth/2 + $CRTPaddleWidth*($i + 0.5); + $paddle_x2 = - $CRTModWidth/2 + $CRTPaddleWidth*($i + 1); + $paddle_y1 = $CRTPaddleHeight/2; + $paddle_y2 = - $CRTPaddleHeight/2; + $paddle_z = 0; + $padnum1 = $i + 1; + $padnum2 = $i + 33; + $paddleid1 = "D$modnum"."_$padnum1"; + $paddleid2 = "D$modnum"."_$padnum2"; + print ENCL < + + + + + + + + + +EOF +} + print ENCL < +EOF +} + +} # end of $HD_CRT_switch eq "on" + + + +############# existing NP02 CRT, used for Double Phase data taking + if($DP_CRT_switch eq "on"){ + + # VD CRT + print ENCL < + + + + + + + + + + + +EOF + +# top CRT-DP module +print ENCL < + + +EOF + my @poscrttop = ($TopCRTDPModHeight/2. - $TopCRTDPPaddleHeight/2., 0., 0.); + for($i=0 ; $i<8 ; $i++){ + $padnum = $i; + $paddleindex = $padnum; + print ENCL < + + + + +EOF + $poscrttop[0] -= $CRTDPPaddleSpacing; + } +print ENCL < +EOF + +# bottom CRT-DP module + my @poscrtbottom = ($BottomCRTDPModHeight/2. - $BottomCRTDPPaddleHeight/2., 0., 0.); +print ENCL < + + +EOF + # loop over paddles + for($i=0 ; $i<8 ; $i++){ + $padnum = $i; + $paddleindex = 8+$padnum; + print ENCL < + + + + +EOF + $poscrtbottom[0] -= $CRTDPPaddleSpacing; + } # end loop over CRT-DP bottom modules + print ENCL < +EOF + } # end of $DP_CRT_switch eq "on" + + #flag : for DP-CRT above, change --> + + + print ENCL < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + + print ENCL < + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + + + + if($HD_CRT_switch eq "on"){ + for($i=0 ; $i<16 ; $i++){ + $modnum = $i + 1; + $modid = "U$modnum"; + +print ENCL < + + + + +EOF + } + + for($i=0 ; $i<16 ; $i++){ + $modnum = $i + 1; + $modid = "D$modnum"; + +print ENCL < + + + + +EOF + } + }# end of if($HD_CRT_switch eq "on") + + + ############# existing NP02 CRT, used for Double Phase data taking + if($DP_CRT_switch eq "on"){ + ##my @posCRT_DP_top = ( -5882, 4345, 0); #mm #flag + my @posCRT_DP_top = ( 3848, 5882, 0); #mm #flag + print ENCL < + + + + +EOF + my @posCRT_DP_bot = (-4406, -5882, -0); #mm #flag + print ENCL < + + + + +EOF + } # end of $DP_CRT_switch eq "on" + + +print ENCL < +EOF + +print ENCL < + +EOF + +close(ENCL); +} + + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++ gen_World +++++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub gen_World() +{ + +# Create the WORLD fragment file name, +# add file to list of output GDML fragments, +# and open it + $WORLD = $basename."_World" . $suffix . ".gdml"; + push (@gdmlFiles, $WORLD); + $WORLD = ">" . $WORLD; + open(WORLD) or die("Could not open file $WORLD for writing"); + + +# The standard XML prefix and starting the gdml + print WORLD < + +EOF + + +# All the World solids. +print WORLD < + + +EOF + +# World structure +print WORLD < + + + + + + + + + + +EOF + +# make_gdml.pl will take care of + +close(WORLD); +} + + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#++++++++++++++++++++++++++++++++++++ write_fragments ++++++++++++++++++++++++++++++++++++ +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sub write_fragments() +{ + # This subroutine creates an XML file that summarizes the the subfiles output + # by the other sub routines - it is the input file for make_gdml.pl which will + # give the final desired GDML file. Specify its name with the output option. + # (you can change the name when running make_gdml) + + # This code is taken straigh from the similar MicroBooNE generate script, Thank you. + + if ( ! defined $output ) + { + $output = "-"; # write to STDOUT + } + + # Set up the output file. + $OUTPUT = ">" . $output; + open(OUTPUT) or die("Could not open file $OUTPUT"); + + print OUTPUT < + + + + + +EOF + + foreach $filename (@defFiles) + { + print OUTPUT < $filename +EOF + } + + print OUTPUT < + + +EOF + + foreach $filename (@gdmlFiles) + { + print OUTPUT < $filename +EOF + } + + print OUTPUT < + +EOF + + close(OUTPUT); +} + + +print "Some of the principal parameters for this TPC geometry (unit cm unless noted otherwise)\n"; +print "CRP total area : $widthCRP x $lengthCRP\n"; +print "Wire pitch in U, V, Z : $wirePitchU, $wirePitchV, $wirePitchZ\n"; +print "TPC active volume : $driftTPCActive x $widthTPCActive x $lengthTPCActive\n"; +print "Argon volume : ($Argon_x, $Argon_y, $Argon_z) \n"; +print "Argon buffer : (Upper: $Upper_xLArBuffer & Lower: $Lower_xLArBuffer, $yLArBuffer, $zLArBuffer) \n"; +print "Detector enclosure : $DetEncX x $DetEncY x $DetEncZ\n"; +print "TPC Origin : ($OriginXSet, $OriginYSet, $OriginZSet) \n"; +print "Field Cage : $FieldCage_switch \n"; +print "Cathode : $Cathode_switch \n"; +print "Wires : $wires \n"; +print "X-ARAPUCA mesh : $ArapucaMesh_switch \n"; +print "PMTs : $PMT_switch \n"; + +# run the sub routines that generate the fragments + +gen_Extend(); +gen_Define(); # generates definitions at beginning of GDML +gen_Materials(); # generates materials to be used + + +if ( $FieldCage_switch eq "on" ) { gen_FieldCage(); } +if ( $ArapucaMesh_switch eq "on" ) { gen_ArapucaMesh(); } # generates X-ARAPUCA mesh for membrane PDs +gen_CathodeMesh(); # generates cathode mesh +gen_pmt(); # generates PMTs from DP +gen_TopCRP(); +#gen_TPC(); # generate TPC for a given unit CRM +gen_Cryostat(); # +gen_Enclosure(); # +gen_World(); # places the enclosure among DUSEL Rock + + +write_fragments(); # writes the XML input for make_gdml.pl + # which zips together the final GDML +exit;