LBNEVolumePlacements.cc
Go to the documentation of this file.
1 //#include <fstream>
2 
4 
5 #include "G4UIdirectory.hh"
6 #include "G4UIcmdWithAString.hh"
7 #include "G4UIcmdWithABool.hh"
8 #include "G4UIcmdWithAnInteger.hh"
9 #include "G4UIcmdWithADoubleAndUnit.hh"
10 #include "G4UIcmdWithoutParameter.hh"
11 #include "G4UnitsTable.hh"
12 
13 #include "G4Material.hh"
14 #include "G4Box.hh"
15 #include "G4Tubs.hh"
16 #include "G4Polycone.hh"
17 #include "G4Trap.hh"
18 #include "G4Cons.hh"
19 #include "G4Polycone.hh"
20 #include "G4GenericPolycone.hh"
21 #include "G4Torus.hh"
22 #include "G4Sphere.hh"
23 #include "G4LogicalVolume.hh"
24 #include "G4ThreeVector.hh"
25 #include "G4PVPlacement.hh"
26 #include "G4SubtractionSolid.hh"
27 #include "G4UnionSolid.hh"
28 #include "G4VisAttributes.hh"
29 #include "globals.hh"
30 #include "G4Transform3D.hh"
31 #include "G4RotationMatrix.hh"
32 #include "G4PVReplica.hh"
33 #include "G4AssemblyVolume.hh"
34 #include "LBNEMagneticField.hh"
35 #include "G4PhysicalVolumeStore.hh"
36 #include "G4LogicalVolumeStore.hh"
37 #include "G4PVPlacement.hh"
38 #include "G4RegionStore.hh"
39 #include "G4SolidStore.hh"
40 #include "G4GeometryManager.hh"
41 #include "G4FieldManager.hh"
42 #include "G4SubtractionSolid.hh"
43 
44 #include "G4RunManager.hh"
45 #include "G4ExceptionSeverity.hh"
46 
47 #include "G4VisExtent.hh"
49 #include "LBNESurveyor.hh"
50 #include "LBNERunManager.hh"
51 
52 //---------------------------------------------------------------------------//
53 // Handles the tricky volume placements
54 //---------------------------------------------------------------------------//
56 
59  return fInstance;
60 }
61 
63 
64  fCheckVolumeOverLapWC = true;
65  fUse1p2MW = true; // We do make it true, August/September 2014.
66  fUse1p2MWSmallTgt = true; // by default, we will use the short target.. Jan 2017
67  fUsePseudoNova = false;
68  fConstructPlug = false;
69  fConstructPlugInHorn1 = false;
70  fRemoveDecayPipeSnout = false; // By default, we have the decay pipe snout, but
71  // if we optimize the Horn 1/2, then we may not have room for it.
72  // We simplify our life by removing temporarely. See G4UI card of the same name.
73  fUseHorn1Polycone = false; // By default, we still use the NuMI Horn1
74  // It's mother is now a Polycone, but the inner conductor
75  // is still based on the set of equation froun in drawing 36309x
76  // However, a simple polycone based Horn1 is available.
77  // See wiki page for details
78  // September 2014.
79  fUseHornsPolycone = false; //
80  // August 2015, Extension to multiple simple horns.
81  // Similar to Horn1Polycone.
82  //
83  fUseNumberOfHornsPoly = 0; // ditto
84  fHorn1RadiusBigEnough = false; // To fully contain (~ 1 m. long) the target. October 2014: a rather stale command...
85  // No longer recommended for use.
86  fUseRALTGTv1 = false;
87 
88  //
89  // Ferbuary 2017: Alberto would like to re-run the CDR Optim 2015 case. We install a new switch, in principle,
90  // not needed, but to make sure we have the re-scale horn2 running..
91  //
92  fUseCDR2015Optimized = false;
93 
94  fArbitraryOffsetHystericalOne = 25.3*CLHEP::mm;
95  const G4double in = 2.54*CLHEP::cm;
96  // declaration of some constant which should not impact the physics at all,
97  // but are needed to build the G4 geometry.
98  fDecayPipeLength=203.7*CLHEP::m; // CDR, Vol 2 LBNE Doc Db 4317-v25
99  fDecayPipeLengthCorrection = -1996*CLHEP::mm; // Thic correction
100  // comes about the fact that the Hadron absorber had to be placed a bit recessed with respect to
101  // end of the decay pipe to avoid volume overlaps. The Hadron absorber is tilte by the beamline angle,
102  // as it has be vertical for mechanical reasons. The value above for that correction has been obtained empirically
103  // by running geantino down the beam line. The shift makes sense, based on the height of the Hadron Absorber
104  // enclosure.
106  const double aRockLength = 2.0*(fDecayPipeLength + 160.*CLHEP::m );
107  // Approximate.. 150 m. is for the target hall, Horn1 + horn2, and the Hadron absorber hall + muon alcove.
108  fLengthOfRockDownstr = 2.0*250.0*CLHEP::m; // to absorb muons..
109  fTotalLength = aRockLength+fLengthOfRockDownstr;
110  fDecayPipeRadius = 4.0*CLHEP::m/2.;
111  fDecayPipeUpstrWindowThick = 1.3*CLHEP::mm; // After discussion with Alberto M., Sept 3 2013. Material is Berylium
112  fDecayPipeWallThick = 12.5*CLHEP::mm; // CDR, March 2012, Vol-2, p 3.130
113  fDecayPipeLongPosition = 22.2*CLHEP::m; // From the target, CDR-Vol2, March 2012, Decay pipe section, p. 3.130
114  // The above will be overwritten in placing the DecayPipeHall, downstream of the decay pipe snout.
115  fDecayPipeGas = G4String("Helium");
116 
117  fHorn1Length = 138.0*in; // Oversized.. Drawing 8875 - ME - 363093
118  fHorn1DownstreamPlateLength = in*(0.00005); // To be defined later...
119  // With respect to the center of the mother volume UpstreamTargetAssembly
120  // Obsolete, August 2014..
121 //
122 // Target The first quantity is the target length as far as the beam is concerned
123 // Can be changed vis G4UIMessenger command
124  fTargetSLengthGraphite = 953.8*CLHEP::mm; // Russian drawing 7589-00-00-00.
125 
126  fTargetSLengthDownstrEnd = 0.964*in; // Doc db 6100. Consistent with Russian drawing.
127 //
128 // The following quantity can be changed via messenger command.
129 //
130  fTargetLengthIntoHorn = fTargetSLengthGraphite - 350.*CLHEP::mm + fArbitraryOffsetHystericalOne; // Integration drawing 8875.000-ME-363028
131  //last number emprically set
132  // to have the first fin target at coord 0.3mm, to follow the convention.
133  // Related to the following quantity...
134 
135  fTargetLengthOutsideHorn = 450.0*CLHEP::mm; // Default with 1.2 mW (to avoid overlap.. )
136  fTargetMaterialName = G4String("Graphite");
137  fTargetDensity = 1.78*CLHEP::g/CLHEP::cm3; // Assume density of POCO ZXF-5Q graphite
138  fTargetSpecificLambda = 85.8*CLHEP::g/CLHEP::cm2; // Specific nuclear interaction length (g/cm2) for graphite
139 
140  fUseRoundedTargetFins = (fUse1p2MW) ? true : false; // If need be, we "back implement" for the 700 kW option.
141  // No fTargetX0, Y0: These would be surveyed point, part of the alignement
142  // realm, i.e. handled in the Surveyor class.
143  fTargetFinHeight = 21.4*CLHEP::mm - 0.005*CLHEP::mm; // It includes half of the cooling tube, which will be inside the fins
144  // Subract 200 microns such that the segments in the He containment tube.
145  // Drawing 7589-01-50-02
146  // The round edges (grinded
147 // fTargetFinWidth = 6.4*CLHEP::mm;
148  fTargetFinWidth = 7.4*CLHEP::mm; // 6.4 -> 7.4 Per discussion with Jim and Alberto, July 25 2013.
149  fTargetFinWidthRequired = fTargetFinWidth; // Used only for 1p2MW option..
150  fTargetFinContainerWidth = fTargetFinWidth; // old behavior, prior to 1p2 MW upgrade.
151  fTargetFinLength = 20*CLHEP::mm; //
152  // We add the fin that span the Usptream target and downstream target part.
153 
154  // fTargetNumberFins = 47; // LBNE Doc 6100.. But we have to compute it from the graphite target length
155  // Since fTargetSLengthGraphite can be changed..Use the same algorithm..
156  fTargetZOffsetStart = 32.2*CLHEP::mm; // From Russian drawing 7589-00-00-00
157  fTargetUpstrUpstrMargin = 1.0*CLHEP::cm; // Perhaps one ought to extend it is Upstream vacuum flange thicker.
158  fTargetUpstrDwnstrMargin = 1.0*CLHEP::mm;
160  fTargetUpstrPlateHoleRadius = (35.0/2.)*CLHEP::mm;//From Russian drawing 7589-00-00-00
161  fTargetUpstrPlateOuterRadius = (214./2.)*CLHEP::mm; //From Russian drawing 7589-00-00-00
162  fTargetUpstrPlateThick = 18.4*CLHEP::mm; // From Russian drawing 7589-00-00-00
163  fTargetCanMaterial = std::string("Aluminum");
164  fTargetCanInnerRadius = (155./2.)*CLHEP::mm; // From Russian drawing 7589-00-00-00
166  fTargetCanLength = 9.80*in; // read out from my scree from LBNE Doc 6100, page 1
169  fTargetDownstrCanFlangeInnerRadius = (155.0/2.)*CLHEP::mm;
170  fTargetDownstrCanFlangeOuterRadius = 120.0*CLHEP::mm; // Approximate
171  fThicknessWall = 0.5*CLHEP::mm;
172 // fTargetDownstrCanFlangeThick = (3.0/8.0)*in; ??? mistake See above
173  fTargetFlangeMaterial = std::string("Steel316");
174  fTargetFlangeInnerRadius = 15.8*CLHEP::mm; // Approximate... +- 0.5 mm
175  fTargetFlangeOuterRadius= (8.24/2.)*in;;
176  fTargetFlangeThick = 25.*CLHEP::mm;
177  fTargetCTubeMaterial = std::string("Titanium");
178  fTargetCTubeOuterRadius = (3. + 0.2)*CLHEP::mm ; // Doc db 6100
179  fRALTargetRing = 10.*CLHEP::mm;
180  fRALTargetRadius = 8.*CLHEP::mm;
181  fTargetCTubeInnerRadius = 3.0*CLHEP::mm;
182  fTargetCTubeUpstrLength = 9.621*in; // Length from the upstream bend to the fron the steel drawnstream flange
183  fTargetCTubeUpstrOffset = 2.32*in; // from the beam line tp to the center of the cooling tube.
184  fTargetCTubeUpstrRadCurve = 0.965*in;
185  fTargetCTubeUpstrNumSegCurve = 12; // 30 degrees angles Should be good enough.
186  fTargetCTubeReturnHOffset = 0.1*in; // guess !!! barely at 3 sigma of the beam...
189  fTargetLengthOutsideExtra = 0.; // differ from zero only for the Pseudo Nova option.
190  // Above quantity obsolete, use a simple model for the downstream end of the Helium target return
191  // cooling pipe.
192  // We will model the bends in the cooling tube with a simple tubular section, of titanium, filled with water.
193  const double lEffCTubeReturnDownstr = 2.0*(0.6*in) + 15*CLHEP::mm; // 1rst term is the bend, horizontal part, top & bottom.
194  const double vCTubeReturnDownstrTitanium = lEffCTubeReturnDownstr*M_PI*
196  const double vCTubeReturnDownstrWater = lEffCTubeReturnDownstr*M_PI*
198  fTargetCTubeReturnDownstrRadInner = 11.0*CLHEP::mm; // Rougly 14.5 - 3 - a bit, to make up the mass
199  // without increasing the thickness by too much
200  fTargetCTubeReturnDownstrRadOuter = 14.25*CLHEP::mm;
203  const double aWedgeRelSize = fTargetCTubeReturnDownstrCutAngleSize/(2.0*M_PI);
205  vCTubeReturnDownstrTitanium/(M_PI*aWedgeRelSize*aSurfWedge);
207  vCTubeReturnDownstrWater/(M_PI*aWedgeRelSize*aSurfWedge);
208 // std::cerr << " Effective thickness for cTube return, " << fTargetCTubeReturnDownstrThickTitanium <<
209 // " Water " << fTargetCTubeReturnDownstrThickWater << std::endl;
210 
211  // A small correction for the tilt angle
212  fTargetDistFlangeToTargetStart = 32.2*CLHEP::mm;
213  fTargetDistToStartOfFlange = 1180.51*CLHEP::mm;
214  fTargetCTubeReturnLengthUpstr = fTargetDistFlangeToTargetStart + 10.25*in; // from the upstream end of target to
215  // Upstr bend return
217  fTargetHeContTubeThickness = 0.4*CLHEP::mm;
218  fTargetHeContTubeInnerRadius = 30.0*CLHEP::mm/2.0 - fTargetHeContTubeThickness; // Doc DB 6100, page 1
220 
221  fTargetAlignRingThick = 11.0*CLHEP::mm; // Accurate to +- 1 mm, from Russian drawing. Err on the excess side.
222  fTargetAlignRingInnerRadius = (18.0/2)*CLHEP::mm + 0.25*CLHEP::mm; // final tweak to avoid overlaps. compensate by increaing thickness.
224 // fTargetAlignRingCutAngle = 0.1735; // Assume atan(3.4 mm/fTargetAlignRingInnerRadius), to remove overlaps
225  fTargetAlignRingCutAngle = 0.45; // Too tight... increase it
226  fTargetAlignRingThick *= 1.0 + 2.0*fTargetAlignRingCutAngle/M_PI; // We compensate the deleted region of the rings
227  // by increasing the thickness. //
228  fTargetAlignRingSpacing = 243.6*CLHEP::mm; // Such we can have 5 alignment rings over the entire distance.
229  fMaxNumAlignRings = 5; // assiming a target length of ~ 1 m. long
230  fTargetBerylDownstrWindowThick = 0.5*CLHEP::mm; // Docdb 6100
232  fTargetBerylUpstrWindowThick = 1.0*CLHEP::mm; // pure guess
233  fTargetBerylUpstrWindowRadius = 0.8425*in/2.; // ???? Again, guessing...
234 //
235 // Simple target code:
236 //
237  fUseSimpleTargetBox = false;
238  fRemoveTargetAlltogether = false;
239  fRALSimpleTargetLength = 2197.33*CLHEP::mm;
240  fSimpleTargetLength = fTargetSLengthGraphite; // default should be what NUMI used, respecting traditions.
241  fSimpleTargetRadius = 7.4*CLHEP::mm; // not used if box.
242  fThicknessBafflet = 1*CLHEP::mm;
243  fSimpleTargetHeight = 20.0*CLHEP::mm; // not used if cylinder
245  fSimpleTargetWidth = 7.4*CLHEP::mm; // not used if cylinder
246 
247 // Quynh, August 2014.
248  fUseMultiSphereTarget = false;//Quynh. Set by G4 UI card /LBNE/det/UseMultiSphereTarget
249  fMultiSphereTargetLength = fTargetSLengthGraphite;// Quynh.real target.(1) - // Preliminary value, see AdaptForMultiSphereTarget
250  fMultiSphereTargetRadius = 8.5*CLHEP::mm ; //controllabe by a UI card
251 
252  // Section of Horn1 which is the logical volume of the target Upstream Assembly.
253  // Drawing NUMI HORN#1, TRANSITION INNER TO OUTER Drawing number 8875. 112-MD-363097
254  // August 2014: "target" is now a misnomer, we place these volume in the Horn1PolyM1
255  fFillHornsWithArgon = true; // momentarily... ! For CD1-Refresh (pre June 2015), this was Air.
256  fTargetHorn1InnerRadsUpstr.resize(5);
258  fTargetHorn1TransThick.resize(5);
259  fTargetHorn1Lengths.resize(5);
260  fTargetHorn1ZPositions.resize(5);
261  fTargetHorn1InnerRadsUpstr[0] = 1.88*in;
262  fTargetHorn1InnerRadsUpstr[1] = 2.28*in;
263  fTargetHorn1InnerRadsUpstr[2] = 2.78*in; // It will a G4tubs, not G4Cons
264  fTargetHorn1InnerRadsUpstr[3] = 4.49*in;
265  fTargetHorn1InnerRadsUpstr[4] = 5.10*in;
266  fTargetHorn1InnerRadsDownstr[0] = 1.573*in;
267  fTargetHorn1InnerRadsDownstr[1] = 1.88*in;
268  fTargetHorn1InnerRadsDownstr[2] = 4.49*in; // It will a G4tubs, not G4Cons This is the outer radius
269  fTargetHorn1InnerRadsDownstr[3] = 5.10*in;
270  fTargetHorn1InnerRadsDownstr[4] = 5.53*in;
271  fTargetHorn1TransThick[0] = (0.25*in)/std::cos(M_PI*45./180.);
272  fTargetHorn1TransThick[4] = (0.25*in)/std::cos(M_PI*45./180.);
273  fTargetHorn1TransThick[1] = (0.25*in)/std::cos(M_PI*60./180.);
274  fTargetHorn1TransThick[3] = (0.25*in)/std::cos(M_PI*60./180.);
276  fTargetHorn1Lengths[0] = 0.457*in;
278  fTargetHorn1Lengths[1] = 0.410*in;
280  fTargetHorn1Lengths[2] = 0.370*in; // Increase thickness
281  // August 2014 Minor adjustments..
282  const double aTotalPseudoTargetHorn1Length =
283  fTargetHorn1Lengths[0] + fTargetHorn1Lengths[1] + fTargetHorn1Lengths[2] + 0.05*CLHEP::mm;
284 // fTargetHorn1ZPositions[0] = -fTargetHorn1Lengths[0]/2. - 2.5*CLHEP::mm ; // With respect to MCZero, or the dowstream end of Upstream Target Assembly
285 // // push them bacward a bit to avoid overlaps
286 // With respecto the center of the container volume. (August 2014.. )
287  fTargetHorn1ZPositions[0] = aTotalPseudoTargetHorn1Length/2. - fTargetHorn1Lengths[0]/2. - 0.005;
289  fTargetHorn1ZPositions[1] = -aTotalPseudoTargetHorn1Length/2. + fTargetHorn1Lengths[2] + fTargetHorn1Lengths[1]/2.;
291  fTargetHorn1ZPositions[2] = -aTotalPseudoTargetHorn1Length/2. + fTargetHorn1Lengths[2]/2 + 0.005*CLHEP::mm; //
292  //
293  // Basic algorithm to determine position of the target main daughter volumes
294  //
295  // Details about the baffle
296  fBaffleInnerRadius = 6.5*CLHEP::mm; // Per discussion with Jim Hylen, July 22 2013
297  fBaffleOuterRadius = 28.3*CLHEP::mm; // from previous version and le010z185i_NumiDPHelium.input
298  fBaffleLength = 1474.8*CLHEP::mm; // Drawing 8875.000-ME-363028
299  fBaffleWindowThickness = 0.5*CLHEP::mm; // e-mail from Bob Zwaska to Minerva et al, August 2014.
300  fBaffleZPosition = -1.0e19; // to be determined one the Target Usptream segment is installed
301  // offset with respecto MCZERO of the center of target mother volume,
302  //
303  // Horn1 initialization.
304  //
307  fHorn1RadialRescale = 1.0; // No units... a ratio between the actual dimensions implemented in Geant4 over the nominal
308  // values found in drawing 8875.112-MD-363xxx
309  fHorn1LongRescale = 1.0;
311  fWaterLayerThickInHorns = 1.*CLHEP::mm; // Sept. 2014:New default value, e-mail from Cory Crowfields to Laura, March 26 2014.
312  fHorn1InnerCondMat = G4String("Aluminum");
313  fHorn1AllCondMat = G4String("Aluminum");
314 
315 
316 
317 // std::cerr << " LBNEVolumePlacements::LBNEVolumePlacements, O.K. done " << std::endl;
318 // Now configure the target. Note: this method can be called from the messenger callback, should the
319 // the users decide to run with non-standard target.
320 //
321  this->setEntireTargetDims(); // See below, first coded up August 18 2014.
322  if (fUseRALTGTv1) {
323  std::cerr << "Using the RAL adapt and segment options" << std::endl;
324  this -> adaptRALTGTv1();
325  //this -> SegmentRALTGTv1();
326  }
327 
328 
329  if (fUse1p2MW) {
331  std::cerr << "Using the adapt and segment options for the small target" << std::endl;
333  this->SegmentTargetSmallTgt();
334  } else {
335  std::cerr << "Using the adapt and segment options for the 1p2MW target" << std::endl;
336  this->adaptTargetFor1p2MW();
337  this->SegmentTarget();
338  }
339  }
340  this->DeclareHorn1Dims(); // See in file LBNEDownstrVolPlacements.cc
341  this->setMotherVolumeForHorn1(); // We do not want top do this for the multiHorn Polygone, but it should not hurt...
342 
343  fExtendChaseLength = 0.;
344 
345  this->DeclareHorn2Dims(); // See in file LBNEDownstrVolPlacements.cc
346  fHorn2InnerCondMat = G4String("Aluminum");
347  fHorn2AllCondMat = G4String("Aluminum");
348  fHorn3InnerCondMat = G4String("Aluminum");
349  fHorn3AllCondMat = G4String("Aluminum");
350 
351  // Details about the plug
352  fPlugInnerRadius = 0.*CLHEP::mm; // Solid cylinder
353  fPlugOuterRadius = 26.*CLHEP::mm; // To fit inside Horn2
354  fPlugLength = 250.0*CLHEP::mm;; // Just a reasonable default
355  fPlugZPosition = 1250.*CLHEP::mm; // An other reasonable default.. Please check target length.
356  fPlugMaterial = std::string("GraphiteBaffle");
357  // Default file name forthe GDML file describing the Hadron generator.
358 //
359 // Ad the decay pipe snout info, this is not very long...
360 //
361 // Old NuMI definition
362 // fDecayPipeLongPosition = 17.3*CLHEP::m; // Tentatively fixzed!!! See "Location Plans and List of Drawing, LBNE CD1 review, CDR-30"
363  // However, for the purpose of Horn placement optimization, this could be overwritten in
364  // ExtendChaseLengthForHorn2 Paul Lebrun, Feb 2015
365  // This will be the case for LBNF
366  //
368 //
369  // The above has been kindly measured off the actual drawing 2251.000-ME-487107, by Glenn Waver,
370  // Sept 2013. It is the distance between the apex of the window
371  // and the point W.P. H.E. ACRNT2, which the entrance of Horn2.
372  // We add to that the extra length of Horn2, should it be rescaled.
373  // However, if so, it is best to leave the decay pipe snout aside, until the
374  // the optimization of the Horn's dimensions and location is settled
375  // The RemoveDecayPipeSnout G4UI card has been introduced, late October 2014.
376  //
377  fDecayPipeWindowRadiusBeryl = 7.874*in/2.0;
378 // fDecayPipeWindowRadiusAlum = 33.0*in/2.0;
379 // Correction, April 9 2015, cross-checking again with the drawing 2251.000-ME-487107
380  fDecayPipeWindowRadiusAlum = 39.370*in/2.0;
382  fDecayPipeWindowThickAlum = 0.064*in; // make it a bit thicker, due to curvature.
383  // August 2015, CD1-R decision:
384  fChaseWidthForLBNF = 78.0*in;
385 // fAbsorberGDMLFilename = G4String("./gdml/lbne_absorber_112912.gdml");
386 //
387 // Received on Sept 27 2013 a new version from Diane Reitzner
388 //
389  fUseMarsTargetHorns = false;
390 
391  char* g4lbne_path = getenv("G4LBNE_DIR");
392  if(g4lbne_path == NULL) {
393  std::cout<<"You have not set $G4LBNE_DIR.... I'm assuming it's your current working directory. Please set $G4LBNE_DIR to the top level directory of your g4lbne installation if that's not the case."<<std::endl;
394  g4lbne_path = static_cast<char *>(malloc(4));
395  strncpy(g4lbne_path, "./\0",3);
396  }
397 
398  fMarsTargetHornsGDMLFilename = G4String(g4lbne_path)+G4String("/gdml/mars_horns.gdml");
399 
400  fAbsorberGDMLFilename = G4String(g4lbne_path)+G4String("/gdml/abs_geomSept13.gdml");
401 
402  std::cout << "Using absorber gdml file here: " << fAbsorberGDMLFilename <<std::endl;
403 
404 // fDoInstallShield = true;
405  fDoInstallShield = false ; // Jan 2017 Now the default for the extend Chase. To be reviewed when
406  // more info available from AD engineers
407 
408 // std::cerr << " Removing the shields until the position of Horn1 is confirmed !!! " << std::endl;
409 // fDoInstallShield = false;
410 
411 // August 2015: restore it, even with Polycone Horns..
412 
413  fRadiusMilindWire = 0.;
414  fCurrentMilindWire = 0.;
415 
416  fWriteGDMLFile = false;
417 
418 //
419 // Octobre 2015, John LoSecco, P.L.
420 //
421  fPolyconeHorn1IsParabolic = false; // default, overwrite with /LBNE/det/SetPolyconeHornParabolic
422 
423  // John Back, March 2016
424  fUseTargetModule = false; // default, overwrite with /LBNE/det/UseTargetModule
425  fTargetRadius = 8.5*CLHEP::mm;
426  fTargetLength = 953.8*CLHEP::mm;
427  // Specify the target module type: SAT, Cylinder
428  fTargetModuleType = LBNEVolumePlacements::SAT; // overwrite with /LBNE/det/TargetModuleType
429  // The fractional length of the full target outside the horn
430  fTargetFracOutHornL = -1.0; // overwrite with /LBNE/det/TargetFracOutHornL
431  // The number of interaction lengths for the target object. If =-1, use fTargetLength instead
432  fTargetNLambda = -1.0; // overwrite with /LBNE/det/TargetNLambda
433 
434  // John Back, Jan 2017 for 2nd target module option
435  fUseTarget2Module = false; // default, overwrite with /LBNE/det/UseTargetModule
436  fTarget2Radius = 8.5*CLHEP::mm;
437  fTarget2Length = 953.8*CLHEP::mm;
438  // Specify the target module type: SAT, Cylinder
439  fTarget2ModuleType = LBNEVolumePlacements::SAT; // overwrite with /LBNE/det/TargetModuleType
440  // The number of interaction lengths for the 2nd target object. If =-1, use fTarget2Length instead
441  fTarget2NLambda = -1.0; // overwrite with /LBNE/det/TargetNLambda
442 
443 //
444 // June 2016 Installation of detailed Horns, conceptual design.
445 //
449  fZShiftConceptHornAStartIC = -101.29*CLHEP::mm; // New value, Oct. 14 2016, after installing the short HornA
450  fZHallHorn1ToHorn1PolyM1 = 200.0*CLHEP::mm; // Approximate.. Re-adjusted when we decide on a final position of
451  // downstream target supports..Done when position Horn1PolyM1 in Create
452  fInstallBaffle = true;
453 // fInstallUpstreamHorizontalTarget = true;
454  //
455  // November 11 2016. This target segment now conflicts with the NuMI target. This is true for Idealistic horns as
456  // well as realistic ones.
457  //
459  // Complicated (helium cooled) downstream target support...
461  //
462  // Lastly, we set again the hysterical, historical variable that sets the position of the horn, only we are using the
463  // NuMI horns, default position.
464  // This variable has been overwritten by Segment target, a call-back to pre-existing G4UI data cards.
465  //
466  if (fUse1p2MWSmallTgt) fTargetLengthOutsideHorn = 45.0*CLHEP::cm;
467  //
468  // To avoid valgrind complains, we initialized some variable that may not be used, by default,
469  // or will be set by the logic of the code.
470  //
471  fHorn1PolyOuterRadius = 0.; // an illicit value.
472  fHorn1NeckInnerRadius = 0.; // will be redefined in PlaceFinalNoSplitHorn1
473  fHorn2NeckInnerRadius = 0.; // will be redefined in PlaceFinalHorn2
474 
475 }
476 //
477 // Compute the number of segments and adjust the overall length, and the spacing such that
478 // We still have a fixed number of 2 cm long pieces of graphite. Do the crazy upstrea/downstream split.
479 // Obsolete, August/Sept 2014.
480 //
481 
483 
484  if (fUse1p2MWSmallTgt) return; // we should not do the segmentation again, random calls from G4UI call-backs
485  std::cerr << " LBNEVolumePlacements::SegmentTarget, NuMI style, long tgt, 1p2 MW " << std::endl;
486  const G4double in = 2.54*CLHEP::cm;
487  // simplify the geometry if we have a simple target. No front can, all target related dimensions, including He Comtainment vessel,
488  // have no materail to speak off ..
489  //
493  fTargetCTubeMaterial = std::string("HeliumTarget");
494  double effectiveRadius = fUseSimpleTargetCylinder ? fSimpleTargetRadius :
496  fTargetCTubeOuterRadius = effectiveRadius + 0.020*CLHEP::mm;
497  fTargetCTubeInnerRadius = effectiveRadius + 0.010*CLHEP::mm;
498  // We do not change the lengths, they won't create conflicts in the Russina-doll type of geometry we have..
499  fTargetHeContTubeThickness = 0.005*CLHEP::mm;
500  fTargetHeContTubeInnerRadius = effectiveRadius + 0.025*CLHEP::mm;
501  return;
502  }
503 
504  fTargetSLength = fTargetSLengthDownstrEnd + fTargetSLengthGraphite; // Russian drawing 7589-00-00-00
505  if (!fUsePseudoNova) {
507  } else {
510  }
511  fTargetFinSpacingLength = 0.3*CLHEP::mm; // Nominal value..
512  double targetNumFinsNominal = fTargetSLengthGraphite/(fTargetFinLength + fTargetFinSpacingLength);
513  fTargetNumFins = (int) (targetNumFinsNominal + 0.5);
514  double deltaNumFins = targetNumFinsNominal - (double) fTargetNumFins;
515  if (deltaNumFins > 0.5) fTargetNumFins++;
516  if (deltaNumFins < -0.5) fTargetNumFins--;
517 // std::cerr << " LBNEVolumePlacements::SegmentTarget, total number of segments " << fTargetNumFins <<
518 // " Delta Num fins " << deltaNumFins << std::endl;
519 // std::cerr << " fTargetSLength " << fTargetSLength << " fTargetLengthOutsideHorn " << fTargetLengthOutsideHorn << std::endl;
520 
521  if (fUsePseudoNova) fTargetNumFins++; // Add one to compensate for the fin that will be split..
523  const double oldLength = fTargetSLengthGraphite;
525  fTargetFinSpacingLength = (fTargetSLengthGraphite - fTargetNumFins*fTargetFinLength)/(fTargetNumFins - 1); //
526  if (std::abs(oldLength - fTargetSLengthGraphite) > 0.001*fTargetSLengthGraphite)
527  std::cout << " LBNEVolumePlacements::segmentTarget: Warning: re-adjust the target length from " <<
528  oldLength << " to " << fTargetSLengthGraphite << " to get an integer number of 2 cm long segments " << std::endl;
529  }
530  if (fUsePseudoNova) {
534  fTargetZ0Upstr = 0.;
535  fTargetZ0Downstr = 0. ;
536  } else {
537  // Compute the number of fins upstream and dowsntream of the break between target and horn1.
538 
540  fTargetNumFinsUpstr = (int) tempNFins;
541  fTargetNumFinsInHorn = fTargetNumFins - fTargetNumFinsUpstr; //Note one fin will be split...
542 // std::cerr << " Num Fins Ups /Downstr " << fTargetNumFinsUpstr << " / " << fTargetNumFinsInHorn << std::endl;
544  fTargetNumFinsUpstr*(fTargetFinLength + fTargetFinSpacingLength);
546  if (( fTargetFinLengthSplitDwnstr < 0.) ||
547  ( fTargetFinLengthSplitDwnstr > (fTargetFinSpacingLength + fTargetFinLength)) ||
548  (fTargetFinLengthSplitUpstr < 0.) ||
549  (fTargetFinLengthSplitUpstr > (fTargetFinSpacingLength + fTargetFinLength))) {
550  // split occurs in a spacing. Set this length to 0., we will not install this target segment
551  std::ostringstream mStrStr;
552  mStrStr << " Odd length for the splitted fin ..." << fTargetFinLengthSplitUpstr << " Downstr " <<
553  fTargetFinLengthSplitDwnstr << " tempNFins = " << tempNFins << std::endl;
554  G4String mStr(mStrStr.str());
555  G4Exception("LBNEVolumePlacements::SegmentTarget", " ", JustWarning, mStr.c_str());
556  if (fTargetFinLengthSplitUpstr > fTargetFinLength) fTargetFinLengthSplitUpstr = fTargetFinLength;
557  if (fTargetFinLengthSplitDwnstr > fTargetFinLength) fTargetFinLengthSplitDwnstr = fTargetFinLength;
558  // if lengths are negative, skip the placement
559 
560  }
561 
562  // more deduced variables..
563 // fTargetHeContTubeLengthInHorn = fTargetLengthIntoHorn + fTargetSLengthDownstrEnd;
565  fTargetZ0Upstr = (-1.0* (fTargetSLength - fTargetLengthIntoHorn))/2. ; // Obsolete...
567  }
568  fTargetAlignRingSpacing *= fTargetSLengthGraphite/953.8*CLHEP::mm; // must fit 5 rings within the prescribed space.
569 // std::cerr << " Target after segmentation " << fTargetSLengthGraphite << std::endl;
572  // Approximate...
575  fTargetUpstrDwnstrMargin + fTargetDistFlangeToTargetStart + fTargetLengthOutsideHorn + 2.0*CLHEP::mm;
576  // NUMI Drawing 8875.000-ME-363028 with 2 mm margin of error.
577 
578 }
579 //
580 // August 2014, with Horn1 Mother is a Polycone.
581 //
583 
584  const G4double in = 2.54*CLHEP::cm;
585  fTargetSLength = fTargetSLengthDownstrEnd + fTargetSLengthGraphite; // Russian drawing 7589-00-00-00
586 // if (!fUsePseudoNova) { // Oboslete, August 2014.
587 // fTargetLengthOutsideHorn = fTargetSLength - fTargetLengthIntoHorn + fTargetFinLength;
588 // } else {
589 // fTargetLengthOutsideExtra = fTargetLengthOutsideHorn - fTargetSLength;
590 // fTargetLengthOutsideHorn = fTargetSLength;
591 // }
592 // Nominal does not defines fTargetLengthOutsideHorn..Must do it here...
593  fTargetLengthOutsideExtra = 95.53*CLHEP::mm; // due to various offsets in the upstream target...
594 
595  fTargetFinSpacingLength = 0.3*CLHEP::mm; // Nominal value..
596  double targetNumFinsNominal = fTargetSLengthGraphite/(fTargetFinLength + fTargetFinSpacingLength);
597  fTargetNumFins = (int) (targetNumFinsNominal + 0.5);
598  double deltaNumFins = targetNumFinsNominal - (double) fTargetNumFins;
599  if (deltaNumFins > 0.5) fTargetNumFins++;
600 // std::cerr << " LBNEVolumePlacements::SetEntireTargetDims, total number of segments " << fTargetNumFins <<
601 // " Delta Num fins " << deltaNumFins << std::endl;
602 // std::cerr << " fTargetSLength " << fTargetSLength << " fTargetLengthOutsideHorn " << fTargetLengthOutsideHorn << std::endl;
603 
604  const double oldLength = fTargetSLengthGraphite;
606  fTargetFinSpacingLength = (fTargetSLengthGraphite - fTargetNumFins*fTargetFinLength)/(fTargetNumFins - 1); //
607  if (std::abs(oldLength - fTargetSLengthGraphite) > 0.001*fTargetSLengthGraphite)
608  std::cout << " LBNEVolumePlacements::setEntireTargetDims: Warning: re-adjust the target length from " <<
609  oldLength << " to " << fTargetSLengthGraphite << " to get an integer number of 2 cm long segments " << std::endl;
610  fTargetZ0Upstr = 0.; // ??? Possibly resurrect for Horn1Mother in one piece,/ Aug/Sept 2014.
611  fTargetZ0Downstr = 0. ;
612  // More deduced variables.
613  fTargetHeContTubeLength = fTargetSLengthDownstrEnd + fTargetSLengthGraphite + 0.025*CLHEP::mm; // To bechecked, August/Sept 2014.
614  fTargetAlignRingSpacing *= fTargetSLengthGraphite/953.8*CLHEP::mm; // must fit 5 rings within the prescribed space.
615 // std::cerr << " Target after segmentation " << fTargetSLengthGraphite << std::endl;
618  // Most likely obsolete variable..
619 
620 }
621 
623  delete fPlacementMessenger;
624 }
626 // std::cerr << " LBNEVolumePlacements::Initialize, about to instantiate PlacementMessengers " << std::endl;
627 // fPlacementMessenger = new LBNEPlacementMessenger();
628 // Why twice ??
629 }
630 // Obsolete... Check who calls this...
631 void LBNEVolumePlacements::Initialize(const G4LogicalVolume* matriarch) {
632 
633  fTopLogicalVolume = matriarch;
634 
635 }
636 
638  LBNEVolumePlacements::Create(const G4String &name) {
639 
640  // Check that it is not already defined.
641 
643  if (itDupl != fSubVolumes.end()) {
644  std::ostringstream mStrStr;
645  mStrStr << " Volume named " << std::string(name) << " Already defined. Fatal ";
646  G4String mStr(mStrStr.str());
647  G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
648  }
649 
650  const G4double in = 2.54*CLHEP::cm;
651  // look for a pre-existing placement. If there, fatal error, exit
653  info.fAlignmentModel = eNominal;
654  info.fIsPlaced = false;
655  info.fRotation = G4RotationMatrix(); // a bit of a waste of space, as, in most cases, not rotations are applied.
656  info.fRotationIsUnitMatrix= true;
657  info.fPosition = G4ThreeVector(0., 0., 0.);
658  info.fParams.resize(3, 0.);
659  info.fMother = 0;
660  info.fTypeName = G4String("Tubs"); // most common type of volume..
661  std::string volumeName(name); // volumeName += std::string("_solid"); Not necessary
662  if (name == G4String("Tunnel")) {
663  info.fParams[0] = std::max((18.5*CLHEP::m), 2.0*(fDecayPipeRadius));
664  // Note: the total volume is 60 m. wide => plenty enough rocks. The last term is for the Hadron Absorber cavern
665  info.fParams[1] = std::max((50*CLHEP::m), 2.0*(fDecayPipeRadius)); // Too tall... Set by the Hadron absorber requirement
666  info.fParams[2] = fTotalLength - fLengthOfRockDownstr -2.0*CLHEP::cm;
667  std::cerr << " Total half length of the tunnel " << info.fParams[2]/2. << std::endl;
668  std::cerr << " Total half Height of the tunnel " << info.fParams[1]/2. << std::endl;
669  std::cerr << " Total half Width of the tunnel " << info.fParams[0]/2. << std::endl;
670  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
671  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), name);
672  info.fTypeName = G4String("Box");
673  }
674  if (name == G4String("TargetHallAndHorn1")) {
675 
676  // Initialise the target module (e.g. SAT) geometry parameters if required.
677  // This can affect the placement of the upstream section
678  if (fUseTargetModule) {
679  std::cout << "We are going to use the Target Module set-up" << std::endl;
680  this->InitTargetModule();
681  if (fUseTarget2Module) {
682  std::cout << "We are also going to use a 2nd mirror image target module" << std::endl;
683  this->InitTarget2Module();
684  }
685  }
686 
687  const LBNEVolumePlacementData *plInfo = Find(name, "Tunnel", "Create");
688  for (size_t k=0; k != 2; ++k)
689  info.fParams[k] = plInfo->fParams[k] - 2.0*CLHEP::cm;
691  + fHorn1Length + 1.0*CLHEP::cm + fTargetAndBaffleLengthApprox ; // 1 cm longitudinally for spare?
692 // Release r0 : this implies a relatiion ship between MCZERO and the word coordinate in G4 that
693 // depends on the tagert Length.
694 // Since the tunnel is centered on Rock and TargetHallAndHorn1 is subdivied in the Upstream Target Assembly and the
695 // the Horn1Hall, two volumes that do not have the same length, then MCZero is not Z = 0. in world coordinate.
696 // info.fPosition[2] = 0.; // Definiing MCZERO, Drawing 8875. 112-MD-363097, annotated by jim Hylen
697 // Jim H. - rightfully so, strongly asked for this to be fixed. We start here, by shifting this volume such that
698 // Horn1 starts at Z = 0.
699 // Formula found for placing Horn1 in TargetHallAndHorn1 (release r0)
700 //
701 // info.fPosition[2] = -1.0*plInfoM->fParams[2]/2. + plInfoC->fParams[2] + info.fParams[2]/2. + 0.020*CLHEP::mm;
702 //
703  const double totalLengthHorn1 = fHorn1DownstreamPlateLength + fHorn1Length + 0.5*CLHEP::cm;
704  const double totalLengthUpstr = fTargetAndBaffleLengthApprox;
705  info.fParams[2] = totalLengthHorn1 + totalLengthUpstr; // Obsolete, August 2014..
706 
710  info.fParams[2] = fHorn1Length + 1.0*CLHEP::cm + fTargetLengthOutsideHorn +
711  fTotalLengthUpstreamAssembly ; //To be adjusted..
712  std::cerr <<
713  " Defining length for mother of Horn1 and Target , fHorn1DownstreamPlateLength "
715  std::cerr << " ............. fHorn1Length " << fHorn1Length
716  << " fTargetLengthOutsideHorn " << fTargetLengthOutsideHorn
717  << " fTotalLengthUpstreamAssembly " << fTotalLengthUpstreamAssembly << std::endl;
718 //
719 // We now need room for the downstream target support structure.
720 //
721  if (fUseLBNFOptimConceptDesignHornA) info.fParams[2] += 400.0*CLHEP::mm; // within a few cm.
723  std::cerr << " ....... Final fTotalLengthTargetAndHorn1Hall " << fTotalLengthTargetAndHorn1Hall << std::endl;
724  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
725  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
726  info.fPosition[2] = (info.fParams[2]/2 - totalLengthUpstr + 0.5*CLHEP::cm); // Defining MCZERO, Drawing 8875. 112-MD-363097, annotated by jim Hylen
727  // Correction for Pseudo Nova: one must shift this volume by the extra length due to the comlete retraction..
729  const double distHorn1UpstrToZ0 = fTotalLengthTargetAndHorn1Hall/2. - (fHorn1Length
730  - 2.0*(2.436*in*fHorn1LongRescale) + 30.0*CLHEP::mm);
731  info.fPosition[2] = -1.0*distHorn1UpstrToZ0 - 1.84*CLHEP::mm; // Last offset due to various margins. Adjusted with Geantino's
733  info.fPosition[2] += -1.0*fZShiftConceptHornAStartIC + 298.3*CLHEP::mm; // Last term emprically set
734  // to align the Z start of the IC at Z = 0., per convention. We are innocent victim of our past
735  // see above for this historical burden. P.L., June 2016.
736  fZHallHorn1ToHorn1PolyM1 = 116.1*CLHEP::mm; // Used in positioning Horn1PolyM1 If this length changes,
737  //, to be revisited..!!!
738  fZHallHorn1ToHorn1PolyM1 += (90.0 + 150.0)*CLHEP::mm; // Correction, August 11-15 2016, based on Tyler J. work in
739  // verification of the geometry, and further discussion with Laura
740  // the want the target insterted a bit more into the horn.
741  // Move Horn1 a bit upstream, -15 cm.
742  // We also have to shift the field map..
743  fHornsPolyZStartPos[0] = -150.88*CLHEP::mm; // Hardcoded. Minor correction to the -150., established
744  // by looking at geantinos... This is the start of
745  // of the IC conductor, with respect to the start of the
746  // Horn1PolyM1, the mother volume of the IC, in global coordinates.
747  // This is not expected to change, it is the definition of our
748  // global coordinates, unless the geometry of HornA changes.
749  }
750  std::cerr << " Placing TargetHallAndHorn1 at " << info.fPosition[2] << " length " << info.fParams[2]
751  << " as upst off " << distHorn1UpstrToZ0 << std::endl << " ...... H1 Length " << fHorn1Length
752  << " with fTargetLengthOutsideHorn = " << fTargetLengthOutsideHorn << std::endl;
753  // Such that we keep the same global coordinate system.
754  info.fTypeName = G4String("Box");
755 
756  } else if (name == G4String("UpstreamTargetAssembly")) {
757  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
758  info.fParams[0] = 64*in - 1.0*CLHEP::cm;
759  info.fParams[1] = 60*in - 1.0*CLHEP::cm; // approximate, we need room for the rotation (Horn is tilted with respect to
760  // true horizontal
761  if (fUseRALTGTv1) {fTotalLengthUpstreamAssembly = 5*CLHEP::mm;}
762  info.fParams[2] = fTotalLengthUpstreamAssembly - 0.001*CLHEP::mm;
763  info.fPosition[2] =-plInfo->fParams[2]/2. + fTotalLengthUpstreamAssembly/2.;
764  // August 2014: Push the target into the horn, by pushing the whole assembly.
765  if (fUseSimpleTargetCylinder || fUseSimpleTargetBox) { // Remove geometrical constraint, such that
766  info.fParams[0] = 2.0*(fTargetHeContTubeInnerRadius + 0.175*CLHEP::mm);
767  info.fParams[1] = info.fParams[0];
768  std::cerr << " Creating UpstreamTargetAssembly with transv. size "
769  << info.fParams[0] << " fTotalLengthUpstreamAssembly "
770  << fTotalLengthUpstreamAssembly << " Position " << info.fPosition[2] << std::endl;
771  }
773  info.fPosition[2] =-plInfo->fParams[2]/2. + info.fParams[2]/2. + 0.5*CLHEP::mm;
774 
775  bool check1 = (!fUseHorn1Polycone) && (!fUseHornsPolycone);
776  // Checks for the target module z alignment
777  bool check2 = fUseTargetModule && fUseHorn1Polycone;
779 
780  if (check1 || check2 || check3) {info.fPosition[2] += fTargetLengthOutsideExtra;}
781 
782  std::cerr << " Correcting.. UpstreamTargetAssembly with transv. size "
783  << info.fParams[0] << " fTotalLengthUpstreamAssembly "
784  << fTotalLengthUpstreamAssembly << " Position " << info.fPosition[2] << std::endl;
785  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
786  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
787  info.fTypeName = G4String("Box");
788 // std::cerr << " LBNEVolumePlacements::Create " << name << " half length " << info.fParams[2]/2. << std::endl;
789 
790  } else if (name == G4String("Baffle")) {
791  // more cases here... a long list.. a too long of a list?
792  // We now go one level down in the hierachy. Start from upstream
793  const LBNEVolumePlacementData *plInfo = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
794  info.fParams[0] = fBaffleInnerRadius;
795  info.fParams[1] = fBaffleOuterRadius;
796  info.fParams[2] = fBaffleLength - 0.75*CLHEP::mm; // to put the windows in...
797  G4Tubs* baffleTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
798  info.fCurrent = new G4LogicalVolume(baffleTube, G4Material::GetMaterial("GraphiteBaffle"), volumeName);
799  info.fPosition[2] = -plInfo->fParams[2]/2. + fBaffleLength/2.0 + 0.505*CLHEP::mm;
800  } else if (name == G4String("BaffleWindowUpstr")) {
801  // more cases here... a long list.. a too long of a list?
802  // We now go one level down in the hierachy. Start from upstream
803  const LBNEVolumePlacementData *plInfo = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
804  info.fParams[0] = 0.;
805  info.fParams[1] = 1.5*fBaffleInnerRadius; // not critical
807  G4Tubs* baffleTubeW = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
808  info.fCurrent = new G4LogicalVolume(baffleTubeW, G4Material::GetMaterial("Beryllium"), volumeName);
809  info.fPosition[2] = -plInfo->fParams[2]/2. + info.fParams[2]/2 + 0.005*CLHEP::mm;
810  } else if (name == G4String("BaffleWindowDownstr")) { // duplicate..except for position.
811  // more cases here... a long list.. a too long of a list?
812  // We now go one level down in the hierachy. Start from upstream
813  const LBNEVolumePlacementData *plInfo = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
814  info.fParams[0] = 0.;
815  info.fParams[1] = 1.5*fBaffleInnerRadius; // not critical
817  G4Tubs* baffleTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
818  info.fCurrent = new G4LogicalVolume(baffleTube, G4Material::GetMaterial("Beryllium"), volumeName);
819  info.fPosition[2] = -plInfo->fParams[2]/2. + fBaffleLength + 0.050*CLHEP::mm + info.fParams[2]/2 + fBaffleWindowThickness;
820  }
821  //
822  // Target stuff.. Lots of it
823  //
824  if (name.find("Target") != std::string::npos) {
825 // if (!fUseRALTGTv1) {
826 
827 // Upstream Stuff
828  // End of Obsolete splitted target. Kept for bacward compatibility and checks.
829  // Volume definition for the target that will fit into the polycone. August, Sept 2014.
830  //
831  // Cloned from the obsolete section above, with volumes renamed..
832 
833  if ((name.find("TargetUpstr") != std::string::npos) || (name.find("TargetConcept") != std::string::npos)) {
834  if (name == G4String("TargetUpstrMTop")) {
835  const LBNEVolumePlacementData *plInfo = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
836  // Complete container the target Canister and the portion of the target outside the horn
837  // Subject to misalignment!!!
838  info.fParams[1] = 10.*in; // mother volume, must hold the Inner/Outer Horn1 transition.
840  info.fParams[1] = plInfo->fParams[0]/2. - 0.025*CLHEP::mm; // radius is 1/2 the width (or height)
841  std::cerr << " Creating TargetUpstrMTop .... with radius " << info.fParams[1] << std::endl;
842  }
844  + fTargetDownstrCanFlangeThick + fTargetFlangeThick + 0.05*CLHEP::mm +
846  std::cerr << " Length of TargetUpstrMTop, ( with Horn1 Mother is Polycone) " << info.fParams[2] << std::endl;
847 
848  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
849  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial("Air"), volumeName);
850  info.fPosition[2] = plInfo->fParams[2]/2. - info.fParams[2]/2. - 0.01*CLHEP::mm; // Nominal:
851  // Half length of UpstreamTargetAssembly - length of this
852 
853  }
854  if (name == G4String("TargetUpstrM0")) { // Complete container for the target Canister and flange
855  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetUpstrMTop"), G4String("Create"));
856  info.fParams[1] = fTargetDownstrCanFlangeOuterRadius + 1.0*CLHEP::cm;
859  // This volume hierarchy could be cleanup some more, evidently.
860  // August 27 2014.. Leave it as such for now..
861  info.fParams[2] = plInfo->fParams[2] - 0.010*CLHEP::mm ; // room for the downstream window of the baffle.
862  std::cerr << " Length of TargetUpstrMTop, ( with Horn1 Mother is Polycone) " << info.fParams[2] << std::endl;
863  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
864  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial("HeliumTarget"), volumeName);
865  info.fPosition[2] = -1.0*plInfo->fParams[2]/2. + info.fParams[2]/2. + 0.002*CLHEP::mm; //
866  }
867  if (name.find("TargetUpstrUpstr") != std::string::npos) {
868  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetUpstrM0"), G4String("Create"));
869  if (name == G4String("TargetUpstrUpstrPlate")) { //
872  info.fParams[2] = fTargetUpstrPlateThick ;
873  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
874  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial("Aluminum"), volumeName);
875  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin + fTargetUpstrPlateThick/2.;
876  }
877  if (name == G4String("TargetUpstrUpstrCan")) { //
878  info.fParams[0] = fTargetCanInnerRadius;
879  info.fParams[1] = fTargetCanOuterRadius;
880  info.fParams[2] = fTargetCanLength ;
881  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
882  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetCanMaterial), volumeName);
883  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
885  }
886  if (name == G4String("TargetUpstrUpstrCanEndPlate")) { //
887  info.fParams[0] = fTargetCanInnerRadius;
888  info.fParams[1] = fTargetCanOuterRadius + 0.5*in; // ?? Guess for the 1/2 inch extra. not critical
890  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
891  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetCanMaterial), volumeName);
892  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
894 // ????? info.fParams[2] = fTargetUpstrUpstrMargin + fTargetUpstrPlateThick + fTargetCanLength // For M0
895 // + fTargetDownstrCanFlangeThick + fTargetFlangeThick;
896  }
897  if (name == G4String("TargetUpstrUpstrDwstrFlange")) { //
900  info.fParams[2] = fTargetFlangeThick ;
901  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
902  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetFlangeMaterial), volumeName);
903  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
906  }
907  if (name == G4String("TargetUpstrUpstrCoolingTube")) { //
908  info.fParams[0] = 0.; // Solid tube of copper, we'll define water below
909  info.fParams[1] = fTargetCTubeOuterRadius;
910  info.fParams[2] = fTargetCTubeUpstrLength ;
911  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
912  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetCTubeMaterial), volumeName);
913  // Leave the position blanks, as there will two copies (top and bottom.)
914  }
915  if (name == G4String("TargetUpstrUpstrCoolingTubeWater")) { //
916  info.fParams[0] = 0.;
917  info.fParams[1] = fTargetCTubeInnerRadius;
918  info.fParams[2] = fTargetCTubeUpstrLength ;
919  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
920  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
921  // Leave the position blanks, as there will two copies (top and bottom.)
922  }
923  if (name == G4String("TargetUpstrUpstrSupportBlockTopLeft")) { //
924  info.fParams[0] = 15.0*CLHEP::mm; // A block of presumed steel to support cooling tubes. +- 2 mm or so.
925  info.fParams[1] = 10.0*CLHEP::mm;
926  info.fParams[2] = 10.0*CLHEP::mm;
927  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2, info.fParams[2]/2.);
928  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Steel316")), volumeName);
929  info.fPosition[0] = -1.0;// Drawing 7589-00-00-00 Approximate. +- 1 mm
930  info.fPosition[1] = 22.5;// Drawing 7589-00-00-00
931  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
932  fTargetUpstrPlateThick + 140.*CLHEP::mm;// Drawing 7589-00-00-00
933  info.fTypeName = G4String("Box");
934  }
935  if (name == G4String("TargetUpstrUpstrSupportBlockBottomLeft")) { //
936  info.fParams[0] = 15.0*CLHEP::mm; // A block of presumed steel to support cooling tubes. +- 2 mm or so.
937  info.fParams[1] = 10.0*CLHEP::mm;
938  info.fParams[2] = 11.0*CLHEP::mm;
939  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2, info.fParams[2]/2.);
940  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Steel316")), volumeName);
941  info.fPosition[0] = -1.0*CLHEP::mm;// Drawing 7589-00-00-00
942  info.fPosition[1] = -20.0;// Drawing 7589-00-00-00
943  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
944  fTargetUpstrPlateThick + 140*CLHEP::mm;// Drawing 7589-00-00-00
945  info.fTypeName = G4String("Box");
946  }
947  if (name == G4String("TargetUpstrUpstrSupportBlockRight")) { //
948  info.fParams[0] = 10.0*CLHEP::mm; // A block of presumed steel to support cooling tubes. +- 2 mm or so.
949  info.fParams[1] = 15.0*CLHEP::mm;
950  info.fParams[2] = 11.0*CLHEP::mm;
951  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2, info.fParams[2]/2.);
952  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Steel316")), volumeName);
953  info.fPosition[0] = 14.0;// Drawing 7589-00-00-00
954  info.fPosition[1] = 7.5;// Drawing 7589-00-00-00
955  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
956  fTargetUpstrPlateThick + 140*CLHEP::mm;// Drawing 7589-00-00-00
957  info.fTypeName = G4String("Box");
958  }
959  if (name == G4String("TargetUpstrUpstrSupportRod")) { //
960  info.fParams[0] = 0.; //
961  info.fParams[1] = 12.*CLHEP::mm; // A bit oversize, the upstream part is thicker..
962  info.fParams[2] = 163.0*CLHEP::mm; // Approx to ~ 3 mm.
963  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.0*CLHEP::degree);
964  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Steel316")), volumeName);
965  // See special implementation due to multiple copies. These rods will not be "surveyable"
966 
967  }
968  if (name == G4String("TargetUpstrUpstrSupportSleeve")) { //
969  info.fParams[0] = fTargetFlangeInnerRadius - 0.2*CLHEP::mm; //
970  info.fParams[1] = info.fParams[0] + 3.0*CLHEP::mm; // Approx to 500 microns
971  info.fParams[2] = 72.0*CLHEP::mm;
972  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.0*CLHEP::degree );
973  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Steel316")), volumeName);
974  info.fPosition[2] =-1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
976  + fTargetDownstrCanFlangeThick - info.fParams[2]/2. -0.1*CLHEP::mm;
977  }
978  if (name == G4String("TargetUpstrUstrHorFin")) { //
979  info.fParams[0] = fTargetFinHeight; // X-Y inverted
980  info.fParams[1] = fTargetFinWidth;
981  info.fParams[2] = fTargetFinLength;
982  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2, info.fParams[2]/2.);
983  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
984  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
985  fTargetUpstrPlateThick + 140*CLHEP::mm;// Drawing 7589-00-00-00
986  info.fTypeName = G4String("Box");
987  }
988  // The following are probably too detailed, and too far away from axis.
989  // Will not be used for now...
990  if (name == G4String("TargetUpstrUpstrCoolingTubeBendSection")) { //
991  info.fParams[0] = 0.; // Solid block of copper, we'll define water below
992  info.fParams[1] = fTargetCTubeOuterRadius;
993  info.fParams[2] = fTargetCTubeUpstrRadCurve/fTargetCTubeUpstrNumSegCurve - 0.1*CLHEP::mm; // 100 microns to avoid overlaps
994  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
995  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetCTubeMaterial), volumeName);
996  // Leave the position blanks, as there will two copies (top and bottom.)
997  }
998  if (name == G4String("TargetUpstrUpstrCoolingTubeBendSectionWater")) { //
999  info.fParams[0] = 0.; // Solid block of copper, we'll define water below
1000  info.fParams[1] = fTargetCTubeInnerRadius;
1002  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1003  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
1004  // Leave the position blanks, as there will two copies (top and bottom.)
1005  }
1006  if (name == G4String("TargetUpstrUpstrCoolingTubeFlangeSection")) { //
1007  info.fParams[0] = 0.;
1008  info.fParams[1] = fTargetCTubeOuterRadius;
1009  info.fParams[2] = fTargetFlangeThick;
1010  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1011  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(fTargetCTubeMaterial), volumeName);
1012  // Leave the position blanks, as there will be two copies (top and bottom.)
1013  }
1014  if (name == G4String("TargetUpstrUpstrCoolingTubeFlangeSectionWater")) { //
1015  info.fParams[0] = 0.;
1016  info.fParams[1] = fTargetCTubeInnerRadius;
1017  info.fParams[2] = fTargetFlangeThick;
1018  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1019  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
1020  // at (0.,0., 0.)
1021  }
1022 
1023 
1024 
1025  } // UpstreamTargetAssembly as mother volume.
1026 
1027 
1028  if ((name.find("TargetUpstrDownstr") != std::string::npos) || (name.find("TargetConceptHelium") != std::string::npos)) {
1029  if (name == G4String("TargetUpstrDownstrHeContainer")) { //
1031  std::cerr
1032  << " Suspicious volume TargetUpstrDownstrHeContainer created in LBNEVolumePlacement .. " << std::endl;
1033  exit(2);
1034  }
1035  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("TargetUpstrM1"), G4String("Create"));
1036  info.fParams[0] = 0.;
1038  info.fParams[2] = plInfoM->fParams[2]- .005*CLHEP::mm;
1039 // if (fUseLBNFOptimConceptDesignHornA) info.fParams[2] = ?????
1040  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1041  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Beryllium")), volumeName);
1042  info.fPosition[2] = 0.; // possibly tweak for the margin...
1043  }
1044  if (name == G4String("TargetUpstrDownstrHelium")) { //
1045  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("TargetUpstrDownstrHeContainer"), G4String("Create"));
1046  info.fParams[0] = 0.;
1048  info.fParams[2] = plInfoM->fParams[2]- .005*CLHEP::mm;
1049  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1050  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1051  info.fPosition[2] = 0.; // possibly tweak for the margin...
1052  }
1053  if (name == G4String("TargetUpstrDownstrCoolingTube")) { //
1054  info.fParams[0] = 0.;
1055  info.fParams[1] = fTargetCTubeOuterRadius;
1057  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1058  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
1059  info.fPosition[2] = fTargetFinHeight + 0.005*CLHEP::mm; // possibly tweak for the margin...
1060  }
1061  if (name == G4String("TargetUpstrDownstrCoolingTubeWater")) { //
1062  info.fParams[0] = 0.;
1063  info.fParams[1] = fTargetCTubeInnerRadius;
1065  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1066  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
1067  }
1068  //
1069  // Used for the normal fins, normal (no wings)
1070  if ((name == G4String("TargetConceptHeliumBoxSegment")) ||
1071  (name == G4String("TargetConceptHeliumTubWWings")) ||
1072  (name == G4String("TargetUpstrDownstrSegment")) ||
1073  (name == G4String("TargetUpstrDownstrSegmentLeft")) ||
1074  (name == G4String("TargetUpstrDownstrSegmentRight")) ) { //
1075 
1076  info.fParams[0] = fTargetFinContainerWidth + 0.025*CLHEP::mm;
1077  info.fParams[1] = fTargetFinHeight + 2.0*fTargetCTubeOuterRadius + 0.025*CLHEP::mm;
1078  // To avoid having to place bits of graphit in the corner, extend the segment upwards/downwards
1079  // to completely encompass the cooling tubes
1080  // Valid only for the old (circa 2014 NuMI short target ) (Jan 5 2017)
1082  if (fUse1p2MW && (name == G4String("TargetConceptHeliumBoxSegment"))) { // New NuMI-stlye target, but LBNF design.
1083  //
1084  // October/November 2016.
1085  // The width is set by either the fin width or the radius of the cooling pipe. We need two of them.
1086  // and the vale between the two pipe (1 mm. ) add 150 microns..
1087  info.fParams[0] = std::max(2.0*fTargetFinWidth + 0.050*CLHEP::mm, 4.0*fTargetCTubeOuterRadius + 1.150*CLHEP::mm);
1088  info.fParams[1] = 2.0*fTargetFinHeight + 2.0*fTargetCTubeOuterRadius + 0.175*CLHEP::mm;
1089  }
1090  if (name == G4String("TargetConceptHeliumTubWWings")) {
1091  info.fParams[0] = 0.;
1092  info.fParams[1] = fTargetHeContTubeInnerRadius - 3.0*CLHEP::mm;
1093  // To reviewed when we have a drawing for the clamps.
1094  }
1096  std::cerr << " Create Volume " << name << " fParams " << info.fParams[0] << " / "
1097  << info.fParams[1] << " / " << info.fParams[2]
1098  << " fin height " << fTargetFinHeight << std::endl;
1099  if (name == G4String("TargetConceptHeliumTubWWings")) {
1100  info.fTypeName = G4String("Box");
1101  G4Tubs* aTubs = new G4Tubs(volumeName, 0., info.fParams[1], info.fParams[2]/2., 0., 360.0*CLHEP::degree);
1102  info.fCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1103  } else {
1104  std::cerr << " Creation of TargetUpstrDownstrSegment, sizes "
1105  << info.fParams[0] << " " << info.fParams[1] << " " << info.fParams[2] << std::endl;
1106 
1107  info.fTypeName = G4String("Box");
1108  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
1109  if (fUse1p2MWSmallTgt)
1110  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
1111  else
1112  info.fCurrent =
1113  new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1114  }
1115  }
1116  if (name == G4String("TargetUpstrDownstrCoolingTubeLast")) { //
1117  info.fParams[0] = 0.;
1118  info.fParams[1] = fTargetCTubeOuterRadius;
1119  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.025*CLHEP::mm;
1120  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1121  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
1122  info.fPosition[2] = fTargetFinHeight + 0.005*CLHEP::mm; // possibly tweak for the margin...
1123  }
1124  if (name == G4String("TargetUpstrDownstrCoolingTubeLastWater")) { //
1125  info.fParams[0] = 0.;
1126  info.fParams[1] = fTargetCTubeInnerRadius;
1127  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.03*CLHEP::mm;
1128  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1129  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
1130  }
1131  if ((name == G4String("TargetUpstrDownstrSegmentLast")) ||
1132  (name == G4String("TargetUpstrDownstrSegmentLastLeft")) ||
1133  (name == G4String("TargetUpstrDownstrSegmentLastRight"))) { //
1134  info.fParams[0] = fTargetFinContainerWidth + 0.025*CLHEP::mm;
1135  info.fParams[1] = fTargetFinHeight + 2.0*fTargetCTubeOuterRadius + 0.025*CLHEP::mm;
1136  if (fUse1p2MW) info.fParams[1] += 2.0*fTargetCTubeOuterRadius;
1137  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.01*CLHEP::mm;
1138 
1139  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
1140  if (!fUse1p2MW)
1141  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1142  else info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
1143  info.fTypeName = G4String("Box");
1144  }
1145  //
1146  } // Downstream of the flange of the target canister.
1147  } // Upstream Stuff
1148  // End of Obsolete splitted target. Kept for bacward compatibility and checks.
1149  // Volume definition for the target that will fit into the polycone. August, Sept 2014.
1150  //
1151  // Cloned from the obsolete section above, with volumes renamed..
1152 
1153 
1154  if (!fUseRALTGTv1){
1155  if (name.find("TargetNoSplit") != std::string::npos) {
1156  std::cerr << " As the data card is off, we will be using the normal optimized design of target and cooling systems" << std::endl;
1157  if (name == G4String("TargetNoSplitM1")) { // Complete container volume placed in the Horn1 and target whole
1158  // to contain the downstream part of the target, i.e., the Helium container tube.
1159  std::cerr << " Creating TargetNoSplitM1 ... " << std::endl;
1160  info.fParams[0] = 0.;
1161  info.fParams[1] = fTargetHeContTubeInnerRadius + fTargetHeContTubeThickness + 0.1*CLHEP::mm; // August 2014, tighter
1162  // December 16 2014: save this radius for Perfect Focusing studies.
1163  LBNERunManager *pRunManager=static_cast<LBNERunManager*> (LBNERunManager::GetRunManager());
1164  const LBNEDetectorConstruction *pDetTmp =
1165  static_cast<const LBNEDetectorConstruction*> (pRunManager->GetUserDetectorConstruction());
1166  pDetTmp->SetRCoordOutOfTarget(fTargetHeContTubeInnerRadius); // mutable here, casting away constness...
1167  // Now position in the mother... Mother name(s) hardcoded here.
1168  // Target configuration dependent.. Quite messy
1170  info.fParams[2] = fTargetSLength + 0.2*CLHEP::mm;
1171  } else {
1172  info.fParams[2] =
1174  }
1175  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1176  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Air")), volumeName);
1177  double lengthMotherNow = 0.;
1178  if (fUse1p2MWSmallTgt) {
1179  //special code for the retro fitted target, if need be...
1180  // for now, cloned from 1.2 MW, long target.
1181  const LBNEVolumePlacementData *plInfo =
1182  Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
1183  const LBNEVolumePlacementData *plInfoUp = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
1184  lengthMotherNow = plInfo->fParams[2];
1185 //
1186 // We attached the real part of the target the upstream segment .
1187 //
1188  info.fPosition[2] = -plInfo->fParams[2]/2. + plInfoUp->fParams[2] + 1.0*CLHEP::cm + info.fParams[2]/2.;
1189 
1191  // easier to start from the downstream end .
1192  } else {
1193 // if (fUseLBNFOptimConceptDesignHornA) info.fParams[2] += 196.2*CLHEP::mm;
1194  // Note: fTargetHeContTubeLengthInHorn = 2243.0*CLHEP::mm;
1195  //Approximate.. Taken indirectly with measurement tool. Drawing F10068454
1196  // This is to extend the helium cooling tube to connect to the target containment vessel
1197  // to the dowsntream support.
1198 
1199  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetUpstrMTop"), G4String("Create"));
1200  info.fPosition[2] = plInfo->fParams[2]/2. - info.fParams[2]/2. - 0.005*CLHEP::mm; // in TargetUpstrMTop To be checked, Aug - Sept 2014.
1201  // August 2014: the mother has to be the TargetHallAndHorn1, such that it can be instered in Horn1
1202  // to get the Z=0. at fTargetLengthOutsideHorn, start if the Horn A IC.
1203  plInfo = Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
1204  lengthMotherNow = plInfo->fParams[2];
1205  const LBNEVolumePlacementData *plInfoUp = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
1206 //
1207 // We attached the real part of the target the upstream segment .
1208 //
1209  info.fPosition[2] = -plInfo->fParams[2]/2. + plInfoUp->fParams[2] + 1.0*CLHEP::cm + info.fParams[2]/2.;
1210 // if ((!fUseHorn1Polycone) && (!fUseHornsPolycone)) info.fPosition[2] += fTargetLengthOutsideExtra;
1211 //
1212 // P.L., L. F., Oct 7 2015:
1213 // The above conditional move should be unconditional ...
1214 // To keep consistency on the definition of the target position with v3r3p8,
1215 // where this move was done for the NuMI-stlye or the Polycone horn,
1216 // we now just have
1217 // Adjusted in HornA is conceptual design, revision 2.
1218 //
1219 
1221  if (fUseLBNFOptimConceptDesignHornA) info.fPosition[2] += 0.01*CLHEP::mm; // To be adjusted, if target length changes.
1222  // or the position of the downstream support.
1223  }
1224  std::cerr << " ...............Done Creating TargetNoSplitM1, length of mother "
1225  << lengthMotherNow << " length of TargetNoSplitM1 " << info.fParams[2] << std::endl
1226  << " ...... Length of Graphite " << fTargetSLengthGraphite
1227  << std::endl << " ............. Z pos relative to mother "
1228  << info.fPosition[2] << std::endl;
1229  } else {
1230  if (name == G4String("TargetNoSplitHeContainer")) { //
1231  const LBNEVolumePlacementData *plInfoM =
1232  Find(name, G4String("TargetNoSplitM1"), G4String("Create"));
1233  info.fParams[0] = 0.;
1235  info.fParams[2] = plInfoM->fParams[2]- .005*CLHEP::mm;
1236  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1237  // November 7 : realized that I never changed the material of the long cooling pipe.. as (sort of agreed upon a year or two
1238  // ago..) that beryllimun would too expensive and hard to manage...
1239  info.fPosition[2] = 0.; // possibly tweak for the margin...
1240  G4Material *myMatTube = G4Material::GetMaterial(std::string("Titanium"));
1241 // temporary revert to Beryllium, to check the effect.. Same thickness. Unrealistic, perhaps...
1242 // G4Material *myMatTube = G4Material::GetMaterial(std::string("Beryllium"));
1243  info.fCurrent = new G4LogicalVolume(aTube,myMatTube , volumeName);
1244  std::cerr << " Defined TargetNoSplitHeContainer, " << myMatTube->GetName() << ", with inner radius "
1245  << fTargetHeContTubeInnerRadius << " Thickness " << fTargetHeContTubeThickness << std::endl;
1246  std::cerr << " Length Mother " << plInfoM->fParams[2]
1247  << " Inner Radius " << plInfoM->fParams[0] << " Outer Radius " << plInfoM->fParams[1] << std::endl;
1248  }
1249  if (name == G4String("TargetNoSplitHelium")) { //
1250  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("TargetNoSplitHeContainer"), G4String("Create"));
1251  info.fParams[0] = 0.;
1253  info.fParams[2] = plInfoM->fParams[2]- .005*CLHEP::mm;
1254  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1255  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1256  std::cerr << " Length of TargetNoSplitHelium " << info.fParams[2]
1257  << " outer radius for helium " << fTargetHeContTubeInnerRadius << std::endl;
1258  info.fPosition[2] = 0.; // possibly tweak for the margin...
1259  }
1260  if ((name == G4String("TargetNoSplitSegment")) ||
1261  (name == G4String("TargetNoSplitSegmentLeft")) ||
1262  (name == G4String("TargetNoSplitSegmentRight")) ) { //
1263 
1264  info.fParams[0] = fTargetFinContainerWidth + 0.025*CLHEP::mm;
1265  info.fParams[1] = fTargetFinHeight + 2.0*fTargetCTubeOuterRadius + 0.025*CLHEP::mm;
1266  // To avoid having to place bits of graphit in the corner, extend the segment upwards/downwards
1267  // to completely encompass the cooling tubes.
1268  if (fUse1p2MW) info.fParams[1] += 2.0*fTargetCTubeOuterRadius;
1269  // the container vessel is bigger.
1270  std::cerr << " Creating " << name << " Height " << info.fParams[1] << std::endl;
1272  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
1273  if (!fUse1p2MW)
1274  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1275  else info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
1276  info.fTypeName = G4String("Box");
1277  }
1278  if (name == G4String("TargetNoSplitCoolingTubeLast")) { //
1279  info.fParams[0] = 0.;
1280  info.fParams[1] = fTargetCTubeOuterRadius;
1281  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.025*CLHEP::mm;
1282  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1283  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
1284  info.fPosition[2] = fTargetFinHeight + 0.005*CLHEP::mm; // possibly tweak for the margin...
1285  }
1286  if (name == G4String("TargetNoSplitCoolingTubeLastWater")) { //
1287  info.fParams[0] = 0.;
1288  info.fParams[1] = fTargetCTubeInnerRadius;
1289  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.03*CLHEP::mm;
1290  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
1291  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
1292  }
1293  if ((name == G4String("TargetNoSplitSegmentLast")) ||
1294  (name == G4String("TargetNoSplitSegmentLastLeft")) ||
1295  (name == G4String("TargetNoSplitSegmentLastRight"))) { //
1296  info.fParams[0] = fTargetFinContainerWidth + 0.025*CLHEP::mm;
1297  info.fParams[1] = fTargetFinHeight + 2.0*fTargetCTubeOuterRadius + 0.025*CLHEP::mm;
1298  if (fUse1p2MW) info.fParams[1] += 2.0*fTargetCTubeOuterRadius;
1299  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.01*CLHEP::mm;
1300 
1301  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
1302  if (!fUse1p2MW)
1303  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
1304  else info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
1305  info.fTypeName = G4String("Box");
1306  }
1307  //
1308  }
1309  } // Downstream of the flange of the target canister.
1310  // Upstream Stuff
1311  }
1312 
1313 //------------------------------------------------------------------------------------------------------------------------------------------------------------
1314  // Design RAL Target <<-----------
1315  //In case we want to use the RAL target, the data card /LBNE/det/fUseRALTGTv1 will implement the following chain instead of the one above
1316 
1317 
1318  else {
1319 
1320 // From this point onwards, we start defining the target helium containment tubes
1321 // We will stick to previous defined TargetNoSplit volume and go from there
1322 
1323 
1324  if (name.find("TargetNoSplit") != std::string::npos) {
1325 
1327  fTargetOutHeContTubeStraightLength = 1001*CLHEP::mm;
1328  fTargetOutHeContTubeTaperedLength = 500*CLHEP::mm;
1329  fTargetCTubeLength = 1500*CLHEP::mm;
1330  }
1331 
1332  std::cerr << " Using RAL configuration for the target and target cooling systems" << std::endl;
1333 
1334  if (name == G4String("TargetNoSplitM1")){
1335 
1336  std::cerr << "TargetNoSplitM1...: Defines the outermost helium containment vessel" << std::endl;
1337 
1338  //Defining the parameters that describe the tapered section of the Outer He Cont tube.
1339 
1340  info.fParams.resize(5);
1341  info.fParams[0] = 0*CLHEP::mm;
1343  info.fParams[2] = 0*CLHEP::mm;
1346 
1347  G4Cons* Outersurface = new G4Cons("Outersurface", info.fParams[0], info.fParams[1], info.fParams[2],
1348  info.fParams[3], info.fParams[4]/2., 0.*CLHEP::mm, 360.0*CLHEP::mm);
1349 
1350  LBNERunManager *pRunManager=static_cast<LBNERunManager*> (LBNERunManager::GetRunManager());
1351  const LBNEDetectorConstruction *pDetTmp =
1352  static_cast<const LBNEDetectorConstruction*> (pRunManager->GetUserDetectorConstruction());
1353  pDetTmp->SetRCoordOutOfTarget(fTargetOutHeContTubeOuterRadius); // mutable here, casting away constness...
1354 
1355 
1356  //Defining the parameters that describe the straight cylindrical section of the Outer He Cont tube.
1357 
1358  G4Tubs* aTube = new G4Tubs("section1", 0*CLHEP::mm, fTargetOutHeContTubeOuterRadius,
1359  fTargetOutHeContTubeStraightLength/2., 0., 360.*CLHEP::degree);
1360 
1361  G4ThreeVector zTrans(0., 0., fTargetOutHeContTubeTaperedLength/2. + fTargetOutHeContTubeStraightLength/2.);
1362  G4Material *myMatTube = G4Material::GetMaterial(std::string("TitaniumG5"));
1363 
1364 
1365  //Merging the straight and tapered section into a new volume
1366 
1367  G4UnionSolid* unionMoved = new G4UnionSolid("totaloutersurface", aTube, Outersurface, 0, zTrans);
1368 
1369  //Defining the volume that describes the half spherical tip of the Outer He Cont tube.
1370 
1371  G4Sphere* Sphere = new G4Sphere("Sphere", 0*CLHEP::mm, fTargetOutHeContTubeOuterSphericalEndCap, 0*CLHEP::degree,
1372  360*CLHEP::degree, 0*CLHEP::degree, 90*CLHEP::degree);
1373 
1374  //Defining the displacement zTrans2 of the half spherical volume w.r.t. the Outer He Cont tube.
1375 
1376  G4ThreeVector zTrans2(0., 0., fTargetOutHeContTubeTaperedLength + fTargetOutHeContTubeStraightLength/2.);
1377 
1378  //Merging the spherical section with the rest of the Outer He Cont tube.
1379 
1380  G4UnionSolid* unionMoved2 = new G4UnionSolid("With spherical end", unionMoved, Sphere, 0, zTrans2);
1381  info.fCurrent = new G4LogicalVolume(unionMoved2 ,myMatTube ,volumeName);
1382 
1383  double lengthMotherNow = 0.;
1384 
1385 
1386  if (fUse1p2MWSmallTgt) {
1387 
1388  const LBNEVolumePlacementData *plInfo =
1389  Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
1390 
1391  const LBNEVolumePlacementData *plInfoUp = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
1392  lengthMotherNow = plInfo->fParams[2];
1393 
1394  info.fPosition[2] = -plInfo->fParams[2]/2. + plInfoUp->fParams[2] + 1.0*CLHEP::cm + info.fParams[2]/2.;
1395 
1397 
1398  } else {
1399 
1400  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetUpstrMTop"), G4String("Create"));
1401 
1402  plInfo = Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
1403  lengthMotherNow = plInfo->fParams[2];
1404 
1405  const LBNEVolumePlacementData *plInfoHorn =
1406  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1407 
1408 
1409  info.fPosition[2] = -plInfoHorn->fParams[2]/2. + plInfoHorn->fPosition[2] + fTargetOutHeContTubeStraightLength/2. + fTargetHeContTubeSmallConeLength +
1411  }
1412 
1413  std::cerr << " ...............Done Creating TargetNoSplitM1, length of mother "
1414  << lengthMotherNow << " length of TargetNoSplitM1 " << info.fParams[4] +
1416  << " ...... Length of Graphite " << fTargetSLengthGraphite
1417  << std::endl << " ............. Z pos relative to mother "
1418  << info.fPosition[2] << std::endl;
1419  }
1420 
1421  else {
1422  if (name == G4String("TargetNoSplitHeContainer")) {
1423  // Looking for mother volumes that define the Z position of the inner helium container
1424 
1425  //Defining the parameters that will describe the inner helium tube
1426  info.fParams.resize(3);
1427  info.fParams[0] = fTargetCTubeInnerRadius;
1428  info.fParams[1] = fTargetCTubeOuterRadius;
1429  info.fParams[2] = fTargetCTubeLength;
1430 
1431 
1432  //Constructing the volume
1433  G4Tubs* InnerHeliumTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
1434  info.fParams[2]/2., 0.*CLHEP::mm, 360.*CLHEP::degree);
1435 
1436  //Determines the position of the TargetNoSplitHeContainer inner radius of the outer helium containment tube
1437 
1439 
1440  G4Material *myMatTube = G4Material::GetMaterial(std::string("TitaniumG5"));
1441 
1442  info.fCurrent = new G4LogicalVolume(InnerHeliumTube ,myMatTube , volumeName);
1443 
1444  std::cerr << " Defined TargetNoSplitHeContainer, " << myMatTube->GetName() << ", with inner radius "
1445  << fTargetCTubeInnerRadius << " Outer radius " << fTargetHeContTubeInnerRadius << std::endl;
1446 
1447  }
1448 
1449  // The TitaniumG5 ring between the helium containment tube and the simple target
1450 
1451 
1452  if (name == G4String("TargetNoSplitCoolingTubeLast")) {
1453  //Defining the section of the helium cooling tube that connects the bafflet to the target
1454 
1455  const LBNEVolumePlacementData *plInfoM2 =
1456  Find(name, G4String("TargetNoSplitLargeConeHe"), G4String("Create"));
1457 
1458  //Defining the parameters of the small cylindrical section between the target and bafflet
1459 
1460  info.fParams.resize(6);
1461 
1462  info.fParams[0] = fSimpleTargetRadius;
1468 
1469 
1470  //Cylinder and Cone that make up the section between the bafflet and target
1471 
1472  G4Tubs* SmallCyl = new G4Tubs("Hetubebafflet", info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1473  0.*CLHEP::degree, 360.*CLHEP::degree);
1474  G4Cons* SmallCone = new G4Cons("Conical section Helium Cont Tube", info.fParams[3], info.fParams[4],
1475  info.fParams[0], info.fParams[1], fTargetHeContTubeSmallConeLength/2.,
1476  0.*CLHEP::degree, 360.0*CLHEP::degree);
1477 
1478 
1479  G4ThreeVector zTrans(0., 0., info.fParams[2]/2. + info.fParams[5]/2.);
1480 
1481  G4UnionSolid* HeSection = new G4UnionSolid("Helium Tube Conical", SmallCone, SmallCyl, 0, zTrans);
1482 
1483  //Define the position of the this section within the mother volume TargetNoSplitLargeCone
1484 
1485  info.fPosition[2] = plInfoM2->fParams[4]/2. - info.fParams[5]/2. - info.fParams[2] - fRALTargetRing;
1486 
1487 
1488  info.fCurrent = new G4LogicalVolume(HeSection, G4Material::GetMaterial(std::string("TitaniumG5")),
1489  volumeName);
1490 
1491  }
1492 
1493  if (name == G4String("TargetNoSplitLargeCone")) {
1494 
1495  //Defining the large conical section upstream of the helium cooling tube that houses the target (incomplete)
1496 
1497  const LBNEVolumePlacementData *plInfoM1 =
1498  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1499 
1500  const LBNEVolumePlacementData *plInfoM =
1501  Find(name, G4String("TargetNoSplitHeContainer"), G4String("Create"));
1502 
1503  info.fParams.resize(5);
1504 
1505  //Defining the parameters of the large conical section upstream of the helium cooling tube
1506 
1507  info.fParams[0] = 0.;
1509  info.fParams[2] = 0.;plInfoM->fParams[0];
1510  info.fParams[3] = plInfoM->fParams[1];
1512 
1513  G4Cons* LargeCone = new G4Cons("LargeCone", info.fParams[0], info.fParams[1],
1514  info.fParams[2], info.fParams[3], info.fParams[4]/2.,
1515  0.*CLHEP::degree, 360.0*CLHEP::degree);
1516 
1517 
1518  G4Tubs* bafflet = new G4Tubs(volumeName, 0., fTargetHeContTubeSmallConeInnerRad +
1519  fThicknessBafflet, fTargetHeContTubeBaffletLength/2., 0., 360.*CLHEP::degree);
1520 
1521 
1522  G4ThreeVector zTrans(0., 0., fTargetHeContTubeLargeConeLength/2. - fTargetHeContTubeBaffletLength/2.
1524 
1525  G4SubtractionSolid* subtraction = new G4SubtractionSolid("LargeCone-Tube", LargeCone, bafflet, 0, zTrans);
1526 
1527 
1528  //Defining the position of the large conical section upstream of the helium cooling tube
1529 
1530  info.fPosition[2] = plInfoM1->fPosition[2] - plInfoM1->fParams[2]/2. + fTargetHeContTubeSmallConeLength +
1532 
1533  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("TitaniumG5")),
1534  volumeName);
1535 
1536  }
1537 
1538  if (name == G4String("TargetNoSplitLargeConeHe")) {
1539 
1540  //Filling the large conical section upstream of the helium cooling tube that houses the target (incomplete) with
1541  //helium
1542 
1543  info.fParams.resize(5);
1544 
1545  info.fParams[0] = 0;
1547  info.fParams[2] = 0;
1548  info.fParams[3] = fTargetCTubeInnerRadius;
1550 
1551  G4Cons* Cone = new G4Cons("LargeCone", info.fParams[0], info.fParams[1], info.fParams[2],
1552  info.fParams[3], info.fParams[4]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1553 
1554 
1555  G4Tubs* bafflet = new G4Tubs(volumeName, info.fParams[0], fTargetHeContTubeSmallConeInnerRad +
1556  fThicknessBafflet, fTargetHeContTubeBaffletLength/2., 0., 360.*CLHEP::degree);
1557 
1558 
1559  G4ThreeVector zTrans(0., 0., fTargetHeContTubeLargeConeLength/2. - fTargetHeContTubeBaffletLength/2.
1561 
1562  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Cone-Tube", Cone, bafflet, 0, zTrans);
1563  info.fPosition[2] = 0.;
1564 
1565  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("Helium")),
1566  volumeName);
1567 
1568  }
1569 
1570 
1571  if (name == G4String("TargetNoSplitM1Helium")){
1572 
1573  //Filling the entire outer helium pipe with helium
1574 
1575  const LBNEVolumePlacementData *plInfoM =
1576  Find(name, G4String("TargetNoSplitM1"), G4String("Create"));
1577 
1578  info.fParams.resize(5);
1579 
1580  info.fParams[0] = 0;
1581  info.fParams[1] = plInfoM->fParams[1] - 1*CLHEP::mm;
1582  info.fParams[2] = 0;
1583  info.fParams[3] = plInfoM->fParams[3] - 1*CLHEP::mm;
1584  info.fParams[4] = plInfoM->fParams[4];
1585 
1586  //Redefining all the separate parts that build up the outer helium containment tube and shrinking it by a small
1587  //amount in order to fill it with helium.
1588 
1589  G4Cons* HeOuter = new G4Cons("HeOuter", info.fParams[0], info.fParams[1], info.fParams[2],
1590  info.fParams[3], info.fParams[4]/2., 0.*CLHEP::mm, 360.0*CLHEP::mm);
1591 
1592  G4Tubs* aTube = new G4Tubs("section1", 0, info.fParams[1], fTargetOutHeContTubeStraightLength/2., 0., 360.*CLHEP::degree);
1593 
1594  G4ThreeVector zTrans(0., 0., info.fParams[4]/2. + fTargetOutHeContTubeStraightLength/2.);
1595 
1596  G4UnionSolid* unionMoved = new G4UnionSolid("totaloutersurface", aTube, HeOuter, 0, zTrans);
1597 
1598  G4Sphere* Sphere = new G4Sphere("Sphere", 0., fTargetOutHeContTubeOuterSphericalEndCap - 1*CLHEP::mm, 0*CLHEP::degree,
1599  360*CLHEP::degree, 0*CLHEP::degree, 90*CLHEP::degree);
1600 
1601 
1602  G4ThreeVector zTrans2(0., 0., fTargetOutHeContTubeTaperedLength + fTargetOutHeContTubeStraightLength/2.);
1603 
1604  G4UnionSolid* unionMoved2 = new G4UnionSolid("With spherical end", unionMoved, Sphere, 0, zTrans2);
1605 
1606 
1607  G4Material *myMatTube = G4Material::GetMaterial(std::string("Helium"));
1608 
1609  info.fCurrent = new G4LogicalVolume(unionMoved2 ,myMatTube ,volumeName);
1610 
1611  info.fPosition[2]= 0.;
1612 
1613  }
1614 
1615 
1616  if (name == G4String("TargetNoSplitCoolingTubeFirstMoth")) { //
1617  const LBNEVolumePlacementData *plInfoM1 =
1618  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1619 
1620  //Defining the mother volume for the bafflet
1621 
1622  info.fParams[0] = 0;//fTargetHeContTubeSmallConeInnerRad;
1625 
1626  G4Tubs* bafflet = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1627  0., 360.*CLHEP::degree);
1628  info.fCurrent = new G4LogicalVolume(bafflet, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1629 
1630  info.fPosition[2] = plInfoM1->fPosition[2] - plInfoM1->fParams[2]/2. - info.fParams[2]/2.;
1631 
1632  }
1633 
1634  if (name == G4String("TargetNoSplitCoolingTubeFirstHelium")) { //
1635 
1636  //Filling the mother volume for the bafflet with helium
1637 
1638  const LBNEVolumePlacementData *plInfoMoth =
1639  Find(name, G4String("TargetNoSplitCoolingTubeFirstMoth"), G4String("Create"));
1640 
1641 
1642  info.fParams[0] = 0.*CLHEP::mm;
1643  info.fParams[1] = plInfoMoth->fParams[1] - fThicknessBafflet;
1644 
1645  info.fParams[2] = plInfoMoth->fParams[2];
1646 
1647  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1648  0., 360.*CLHEP::degree);
1649  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Helium")), volumeName);
1650 
1651  info.fPosition[2] = 0;
1652 
1653  }
1654 
1655  if (name == G4String("TargetNoSplitSimpleBafflet")) { //
1656  //Creating the bafflet and cutting out the outward flanging part by doing a subtraction
1657 
1658  const LBNEVolumePlacementData *plInfoM0 =
1659  Find(name, G4String("TargetNoSplitCoolingTubeFirstMoth"), G4String("Create"));
1660 
1661  info.fParams.resize(5);
1662 
1663  info.fParams[0] = fSimpleTargetRadius;
1664  info.fParams[1] = fTargetBaffletOutRadius;
1668 
1669  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1670  0., 360.*CLHEP::degree);
1671  G4Cons* Cone = new G4Cons("Baffletflange", 0, info.fParams[0], 0, plInfoM0->fParams[1] - fThicknessBafflet, info.fParams[4]/2.,
1672  0.*CLHEP::degree, 360.0*CLHEP::degree);
1673 
1674  G4ThreeVector zTrans(0., 0., info.fParams[3]/2.);
1675 
1676  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Tube-Cone", aTube, Cone, 0, zTrans);
1677 
1678  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("TitaniumG5")),
1679  volumeName);
1680 
1681  info.fPosition[2] = 0.;
1682  }
1683 
1684  //Defining the outward flanging section of the bafflet
1685 
1686 
1687  if (name == G4String("TargetNoSplitSimpleBaffletFlange")) { //
1688 
1689  const LBNEVolumePlacementData *plInfoM0 =
1690  Find(name, G4String("TargetNoSplitCoolingTubeFirstHelium"), G4String("Create"));
1691 
1692  info.fParams.resize(4);
1693 
1694  info.fParams[0] = fSimpleTargetRadius;
1695  info.fParams[1] = fTargetBaffletOutRadius;
1698 
1699 
1700  G4Cons* Cone2 = new G4Cons("Conical section Helium Cont Tube", info.fParams[0] - fThicknessWall,
1701  info.fParams[0], plInfoM0->fParams[1],
1702  plInfoM0->fParams[1], info.fParams[3]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1703 
1704  info.fCurrent = new G4LogicalVolume(Cone2, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1705 
1707  }
1708 
1709  if (name == G4String("TargetNoSplitBaffletCold")) { //
1710 
1711  //Defining cylindrical cooling tube that delivers the cold helium flow
1712 
1713  const LBNEVolumePlacementData *plInfoM =
1714  Find(name, G4String("TargetNoSplitSimpleBafflet"), G4String("Create"));
1715  const LBNEVolumePlacementData *plInfoM1 =
1716  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1717 
1718  info.fParams[0] = 0;
1721 
1722  G4Torus* Torus = new G4Torus("Torus", info.fParams[0], info.fParams[1], info.fParams[2] ,0., M_PI/2.);
1723 
1724  info.fCurrent = new G4LogicalVolume(Torus, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1725 
1726  //Describing the rotation and translation to connect the curved tube to the bafflet helium containment tube.
1727 
1728  info.fPosition[1] = info.fParams[2];
1729  info.fPosition[2] = plInfoM1->fPosition[2] - plInfoM1->fParams[2]/2. - plInfoM->fParams[2];
1730  info.fRotationIsUnitMatrix = false;
1731  info.fRotation.rotateY(3./2.*M_PI);
1732  info.fRotation.rotateZ(M_PI/2.);
1733 
1734 
1735 
1736  }
1737 
1738  if (name == G4String("TargetNoSplitBaffletColdHe")) { //
1739 
1740 
1741  //Filling the cylindrical cooling tube that delivers the cold helium flow with actual helium
1742 
1743  info.fParams[0] = 0.*CLHEP::mm;
1746 
1747  G4Torus* Torus = new G4Torus("Torus", info.fParams[0], info.fParams[1], info.fParams[2] ,0., M_PI/2.);
1748 
1749  info.fCurrent = new G4LogicalVolume(Torus, G4Material::GetMaterial(std::string("Helium")), volumeName);
1750 
1751  info.fPosition[2] = 0;
1752 
1753  }
1754 
1755  if (name == G4String("TargetNoSplitRingTube")) {
1756 
1757  //Describing the small ring that separates the small conical + cylindrical helium section from the target
1758 
1759  info.fParams[0] = 0.;
1760  info.fParams[1] = fSimpleTargetRadius;
1761 
1762  G4Tubs* RingTube = new G4Tubs("Ring", 0., info.fParams[1] + fThicknessBafflet, fRALTargetRing/2., 0., 360.*CLHEP::deg);
1763 
1765 
1766  info.fCurrent = new G4LogicalVolume(RingTube, G4Material::GetMaterial(std::string("TitaniumG5")),
1767  volumeName);
1768 
1769  std::cerr << "Placing the TitaniumG5 ring between the target and the helium tube. " <<std::endl;
1770 
1771  }
1772 
1773 
1774  if (name == G4String("TargetNoSplitDSSupportConnectionRing")) {
1775 
1776  info.fParams[0] = 0;
1779 
1780  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1781  0., 360.*CLHEP::degree);
1782 
1783  G4Sphere* Sphere = new G4Sphere("Sphere", 0,
1785  360*CLHEP::degree, 0*CLHEP::degree, 90*CLHEP::degree);
1786 
1787 
1788  G4ThreeVector zTrans(0., 0., - fTargetDSSupportConnRing/2.);
1789 
1790  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Ring-Sphere", aTube, Sphere, 0, zTrans);
1791 
1792  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1793 
1794  const LBNEVolumePlacementData *plInfoM1 =
1795  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1796 
1799  info.fParams[2]/2.;
1800 
1801  }
1802 
1803  if (name == G4String("TargetNoSplitDSSupportAlRing")) {
1804 
1808 
1809  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1810  0., 360.*CLHEP::degree);
1811 
1812  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Aluminum")), volumeName);
1813 
1814  const LBNEVolumePlacementData *plInfoM1 =
1815  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1816 
1819  fTargetDSSupportConnRing + info.fParams[2]/2.;
1820 
1821  }
1822 
1823 
1824  if (name == G4String("TargetNoSplitDSSupportLargeCones")) {
1825 
1826  info.fParams.resize(10);
1832 
1838 
1839 
1840 
1841  G4Cons* ConeL = new G4Cons("DSSupportLargeCone", info.fParams[5], info.fParams[6], info.fParams[7],
1842  info.fParams[8], info.fParams[9]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1843 
1844 
1845 
1846  G4Cons* ConeS = new G4Cons("DSSupportSmallCone", info.fParams[0], info.fParams[1], info.fParams[2],
1847  info.fParams[3], info.fParams[4]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1848 
1849 
1850  G4ThreeVector zTrans2(0., 0., 27.5*CLHEP::mm/2. + fTargetDSSupportSmallConeLength/2.);
1851  G4UnionSolid* UnionMovedx3 = new G4UnionSolid("DSSupportLConeRings", ConeL, ConeS, 0, zTrans2);
1852 
1853 
1854 
1855 
1856 
1857  const LBNEVolumePlacementData *plInfoM1 =
1858  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1859 
1863 
1864 
1865 
1866  info.fCurrent = new G4LogicalVolume(UnionMovedx3, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1867 
1868  }
1869 
1870  /* if (name == G4String("TargetNoSplitDSSupportRingCone")) {
1871 
1872  //Thicknesses were given vertically, but there were angles that had to be taken into account
1873  info.fParams.resize(5);
1874 
1875  info.fParams[0] = fTargetDSSupportLargeConeLargeOuterRad;// + 0.2*CLHEP::mm;
1876  info.fParams[1] = info.fParams[0] + 2.0219*CLHEP::mm;
1877  info.fParams[2] = 38.7298*CLHEP::mm - 2.0219*CLHEP::mm;//38.775*CLHEP::mm - 2.0219*CLHEP::mm;// + 0.2*CLHEP::mm;
1878  info.fParams[3] = info.fParams[2] + 2.0219*CLHEP::mm;
1879  info.fParams[4] = 10.*CLHEP::mm;
1880 
1881  G4Cons* ConeExt = new G4Cons("DSSupportLargeConeExt", info.fParams[0], info.fParams[1]
1882  , info.fParams[2], info.fParams[3], info.fParams[4]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1883 
1884  const LBNEVolumePlacementData *plInfoM1 =
1885  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1886 
1887  info.fPosition[2] = plInfoM1->fPosition[2] - plInfoM1->fParams[2]/2. + fTargetOutHeContTubeStraightLength + fTargetOutHeContTubeTaperedLength +
1888  fTargetHeContTubeSmallConeLength + fTargetHeContTubeSmallCylLength + fRALTargetRing +
1889  fTargetDSSupportConnRing + fTargetDSSupportAlRingThickness + info.fParams[4]/2. -
1890  fTargetDSSupportLargeConeLength;
1891 
1892  info.fCurrent = new G4LogicalVolume(ConeExt, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
1893 
1894  } */
1895 
1896  if (name == G4String("TargetNoSplitDSSupportHeLargeCone")) {
1897 
1898  //Thicknesses were given vertically, but there were angles that had to be taken into account
1899 
1900 
1901  info.fParams.resize(5);
1902  info.fParams[0] = 37.72*CLHEP::mm + 0.63850*CLHEP::mm;
1903  info.fParams[1] = info.fParams[0] + 1.1705*CLHEP::mm;
1904  info.fParams[2] = 28.5293*CLHEP::mm;
1905  info.fParams[3] = info.fParams[2] + 1.1705*CLHEP::mm;
1906  info.fParams[4] = 28.1*CLHEP::mm;
1907 
1908 
1909  G4Cons* ConeL = new G4Cons("DSSupportLargeConeHe", info.fParams[0], info.fParams[1], info.fParams[2],
1910  info.fParams[3], info.fParams[4]/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1911 
1912 
1913  G4Cons* ConeS = new G4Cons("DSSupportSmallConeHe", fTargetDSSupportSmallConeSmallInnerRad + 0.6092559*CLHEP::mm + 0.105796188*CLHEP::mm,
1914  fTargetDSSupportSmallConeSmallInnerRad + 0.6092559*CLHEP::mm + 0.105796188*CLHEP::mm + 3.960163786*CLHEP::mm, 26.6*CLHEP::mm + 0.6092559*CLHEP::mm,
1915  26.6*CLHEP::mm + 0.6092559*CLHEP::mm + 3.960163*CLHEP::mm, 5.3*CLHEP::mm/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
1916 
1917  G4ThreeVector zTrans(0., 0., 5.3*CLHEP::mm/2. + info.fParams[4]/2.);
1918 
1919  G4UnionSolid* RingplusConeHe = new G4UnionSolid("DSSupportLConeRingHe", ConeL, ConeS, 0, zTrans);
1920 
1921  info.fPosition[2] = 0.6*CLHEP::mm;
1922  info.fCurrent = new G4LogicalVolume(RingplusConeHe, G4Material::GetMaterial(std::string("Helium")), volumeName);
1923 
1924 
1925 
1926  }
1927 
1928  if (name == G4String("TargetNoSplitDSSupportInnerRing")) {
1929 
1930  const LBNEVolumePlacementData *plInfoM1 =
1931  Find(name, G4String("Horn1PolyM1"), G4String("Create"));
1932 
1933  const LBNEVolumePlacementData *plInfoM2 =
1934  Find(name, G4String("TargetNoSplitDSSupportLargeCones"), G4String("Create"));
1935 
1936  info.fParams.resize(4);
1937  info.fParams[0] = 2*CLHEP::mm;
1938  info.fParams[1] = 3*CLHEP::mm;
1939  info.fParams[2] = 677*CLHEP::mm - plInfoM2->fParams[3];
1940  info.fParams[3] = 677*CLHEP::mm - plInfoM2->fParams[6] - 2.0219*CLHEP::mm;
1941 
1942  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
1943  0., 360.*CLHEP::degree);
1944 
1945  G4RotationMatrix* xRot = new G4RotationMatrix;
1946  xRot->rotateX(M_PI/9.*rad);
1947  xRot->rotateY(+ M_PI/75.*rad);
1948 
1949  G4RotationMatrix* xRot2 = new G4RotationMatrix;
1950  xRot2->rotateX(2*M_PI/3.*rad);
1951  xRot2->rotateY(M_PI - 1/200.*M_PI);
1952 
1953  G4RotationMatrix* xRot3 = new G4RotationMatrix;
1954  xRot3->rotateX(14*M_PI/18.*rad);
1955  xRot3->rotateY(M_PI/75.*rad - M_PI/100.*rad);
1956 
1957  G4RotationMatrix* xRot4 = new G4RotationMatrix;
1958  xRot4->rotateX(4*M_PI/3.*rad);
1959  xRot4->rotateY(M_PI - 1/200.*M_PI);
1960 
1961  G4RotationMatrix* xRot5 = new G4RotationMatrix;
1962  xRot5->rotateX(26*M_PI/18.*rad);
1963  xRot5->rotateY(M_PI/75.*rad - M_PI/100.*rad);
1964 
1965  G4ThreeVector zTrans(std::sin(M_PI/75.*rad)*info.fParams[2]/2.,
1966  std::sin(M_PI/9.)*(677*CLHEP::mm/2. + plInfoM2->fParams[6] + 2.0219*CLHEP::mm),
1967  -(1-std::cos(M_PI/9.))*(677*CLHEP::mm/2. + plInfoM2->fParams[6] + 2.0219*CLHEP::mm));
1968 
1969  G4ThreeVector zTrans2(1*CLHEP::mm + std::sin(M_PI/200.*rad)*info.fParams[2]/2.,
1970  std::sin(M_PI/3.)*(info.fParams[2]/2.+ plInfoM2->fParams[3]),
1971  -(info.fParams[3]/2. + plInfoM2->fParams[6]) - std::cos(M_PI/3.)*(info.fParams[2]/2. + plInfoM2->fParams[3]));
1972 
1973  G4ThreeVector zTrans3(std::sin(M_PI/75.*rad + M_PI/100.*rad)*info.fParams[2]/2.,
1974  std::sin(2*M_PI/9.)*(info.fParams[3]/2.+ plInfoM2->fParams[6]),
1975  -(info.fParams[3]/2. + plInfoM2->fParams[6]) - (std::cos(2*M_PI/9.))*(info.fParams[3]/2. + plInfoM2->fParams[6]));
1976 
1977  G4ThreeVector zTrans4(1*CLHEP::mm + std::sin(M_PI/200.*rad)*info.fParams[2]/2.,
1978  -std::sin(M_PI/3.)*(info.fParams[2]/2.+ plInfoM2->fParams[3]),
1979  -(info.fParams[3]/2. + plInfoM2->fParams[6]) - std::cos(M_PI/3.)*(info.fParams[2]/2. + plInfoM2->fParams[3]));
1980 
1981  G4ThreeVector zTrans5(std::sin(M_PI/75.*rad + M_PI/100.*rad)*info.fParams[2]/2.,
1982  - std::sin(4*M_PI/9.)*(info.fParams[3]/2. + plInfoM2->fParams[6]),
1983  -(info.fParams[3]/2. + plInfoM2->fParams[6]) - (std::cos(4*M_PI/9.))*(info.fParams[3]/2. + plInfoM2->fParams[6]));
1984 
1985  G4UnionSolid* Spikes = new G4UnionSolid("DSSupportSpikes", aTube, aTube, xRot2, zTrans2);
1986 
1987  G4UnionSolid* Spikes2 = new G4UnionSolid("DSSupportSpikes", Spikes, aTube, xRot4, zTrans4);
1988 
1989  G4UnionSolid* Spikes3 = new G4UnionSolid("DSSupportSpikes", Spikes2, aTube, xRot, zTrans);
1990 
1991  G4UnionSolid* Spikes4 = new G4UnionSolid("DSSupportSpikes", Spikes3, aTube, xRot3, zTrans3);
1992 
1993  G4UnionSolid* Spikes5 = new G4UnionSolid("DSSupportSpikes", Spikes4, aTube, xRot5, zTrans5);
1994 
1995 
1996  G4Tubs* OUTERRING = new G4Tubs(volumeName, 677*CLHEP::mm, 697*CLHEP::mm, 20*CLHEP::mm/2.,
1997  0., 360.*CLHEP::degree);
1998 
1999  G4RotationMatrix* xRot6 = new G4RotationMatrix;
2000  xRot6->rotateY(- 3./2.*M_PI + 1/200.*M_PI);
2001 
2002  G4ThreeVector zTrans6(10*CLHEP::mm, 0., -(plInfoM2->fParams[6] + info.fParams[2]/2 - 5*CLHEP::mm));
2003 
2004  G4UnionSolid* Spikes6 = new G4UnionSolid("DSSupportSpikes", Spikes5, OUTERRING, xRot6, zTrans6);
2005 
2006 
2007 
2008  G4ThreeVector zTrans7(- fTargetDSSupportAlRingThickness + fTargetDSSupportLargeConeLength, 0., -(plInfoM2->fParams[6] + info.fParams[2]/2 - 5*CLHEP::mm));
2009 
2010 
2011  G4Cons* ConeExt = new G4Cons("DSSupportLargeConeExt", fTargetDSSupportLargeConeLargeOuterRad, fTargetDSSupportLargeConeLargeOuterRad+2.0219*CLHEP::mm
2012  , 38.7298*CLHEP::mm - 2.0219*CLHEP::mm, 38.7298*CLHEP::mm, 10.*CLHEP::mm/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
2013 
2014 
2015  G4Cons* ConeExt2sub = new G4Cons("DSSupportLargeConeExt", 0., fTargetDSSupportLargeConeLargeOuterRad, 0., 38.7298*CLHEP::mm, 10.*CLHEP::mm/2., 0.*CLHEP::degree, 360.0*CLHEP::degree);
2016 
2017 
2018 
2019  G4UnionSolid* Spikes7 = new G4UnionSolid("DSSupportSpikes", Spikes6, ConeExt, xRot6, zTrans7);
2020 
2021  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Ring-Sphere", Spikes7, ConeExt2sub, xRot6, zTrans7);
2022 
2023 
2024 
2025  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("TitaniumG5")), volumeName);
2026 
2027 
2028 
2029 
2033  info.fPosition[0] = plInfoM2->fParams[6] + info.fParams[2]/2 - 5*CLHEP::mm;
2034 
2035  info.fRotationIsUnitMatrix = false;
2036  info.fRotation.rotateY(3./2.*M_PI - 1/200.*M_PI);
2037 
2038  }
2039  }
2040  } // Downstream of the flange of the target canister.
2041  // Upstream Stuff
2042  }
2043  }
2044 
2045  //In case we want to use the RAL target, the data card /LBNE/det/fUseRALTGTv1 will implement the following chain instead of the one above
2046 
2047  //
2048  // October November 2016: rename a few volume to make it clearer.
2049  //
2050  if (name == G4String("TargetNormalCoolingTube")) { //
2051  info.fParams[0] = 0.;
2052  info.fParams[1] = fTargetCTubeOuterRadius;
2054  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2055  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
2056  info.fPosition[1] = fTargetFinHeight - fTargetCTubeOuterRadius + 0.005*CLHEP::mm; // No longer in use..
2057  }
2058 
2059  if (name == G4String("TargetNormalCoolingTubeWater")) { //
2060  info.fParams[0] = 0.;
2061  info.fParams[1] = fTargetCTubeInnerRadius;
2063  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2064  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
2065  }
2066  if (name == G4String("TargetWWingsCoolingTube")) { //
2067  info.fParams[0] = 0.;
2068  info.fParams[1] = fTargetCTubeOuterRadius;
2069  info.fParams[2] = fTargetFinLength - 0.150*CLHEP::mm;
2070  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2071  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
2072  info.fPosition[1] = fTargetFinHeight - fTargetCTubeOuterRadius + 0.005*CLHEP::mm; // possibly tweak for the margin...
2073  }
2074  if (name == G4String("TargetWWingsCoolingTubeWater")) { //
2075  info.fParams[0] = 0.;
2076  info.fParams[1] = fTargetCTubeInnerRadius;
2077  info.fParams[2] = fTargetFinLength - 0.150*CLHEP::mm;
2078  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2079  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
2080  }
2081 
2082 //
2083 // December 2013 : Reverting back to a much simple target.
2084 
2085  if (name == G4String("TargetSimpleUpstrTube")) { //
2086  info.fParams[0] = 0.;
2087  info.fParams[1] = fSimpleTargetRadius;
2088  info.fParams[2] = fTargetSLength; // To be recommissioned, August 28 2014.
2089  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2090  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Target")), volumeName);
2091  // at (0.,0., 0.)
2092  }
2093  if (name == G4String("TargetSimpleUpstrBox")) { //
2094  info.fParams[0] = fSimpleTargetWidth;
2095  info.fParams[1] = fSimpleTargetHeight;
2096  info.fParams[2] = fTargetSLength;
2097  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
2098  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2099  // at (0.,0., 0.)
2100  }
2101 
2102  if (name == G4String("TargetSimpleDownstrTube")) { // Obsolete..
2103  info.fParams[0] = 0.;
2104  info.fParams[1] = fSimpleTargetRadius;
2106  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2107  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Target")), volumeName);
2108  // at (0.,0., 0.)
2109  }
2110  if (name == G4String("TargetSimpleDownstrBox")) { //
2111  info.fParams[0] = fSimpleTargetWidth;
2112  info.fParams[1] = fSimpleTargetHeight;
2114  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2.);
2115  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2116  // at (0.,0., 0.)
2117  }
2118 
2119 //Quynh added for multisphere.
2120  if (name == G4String("TargetMultiSphere")) {
2121  info.fParams[0] = 0.;
2122  info.fParams[1] = fMultiSphereTargetRadius;
2123  info.fParams[2] = 0. ;
2124  G4Sphere* aSphere = new G4Sphere(volumeName,
2125  info.fParams[0],//inner radius = 0
2126  info.fParams[1],//outer radius
2127  0.,360.*CLHEP::degree,0.,180.*CLHEP::degree); //Phi and Theta angles
2128  info.fCurrent = new G4LogicalVolume(aSphere, G4Material::GetMaterial(std::string("Target")), volumeName);
2129 
2130  }
2131  //
2132  // Bits and pieces for the target itself.
2133  //
2134  if (name == G4String("TargetFinVert")) { //
2135  info.fParams[0] = fTargetFinWidth;
2136  info.fParams[1] = fTargetFinHeight - 2.0*fTargetCTubeOuterRadius - 0.05*CLHEP::mm;
2137  info.fParams[2] = fTargetFinLength ;
2138  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2139  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2140  info.fTypeName = G4String("Box");
2141  }
2142  // October-November 2016: obsolote volume.
2143  if (name == G4String("TargetFinVertExtra")) { // Extra pieces to be place left and right of the center
2144  // of the cooling tube. This extends the target transversely
2145  if (fTargetFinExtraWidth < 0.) {
2146  std::ostringstream mStrStr;
2147  mStrStr << " Volume named " << name << " can not be handled, negative dimension ";
2148  G4String mStr(mStrStr.str());
2149  G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
2150  }
2151  info.fParams[0] = fTargetFinExtraWidth;
2152  info.fParams[1] = fTargetFinHeight - 0.05*CLHEP::mm;
2153  info.fParams[2] = fTargetFinLength ;
2154  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2155  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2156  info.fTypeName = G4String("Box");
2157  }
2158  if (name == G4String("TargetFinVertHeliumSide")) { // The fin container is made of graphite, or whatever target material
2159  // if so, we must replace some of back with helium, if the nominal target Fin width is smaller
2160  // then the cooling tube radius, which sets the size of the container.
2161  const double widthHe = 2.0*fTargetCTubeOuterRadius - fTargetFinWidthRequired - 0.005*CLHEP::mm;
2162  if (widthHe < 0.) {
2163  std::ostringstream mStrStr;
2164  mStrStr << " Volume named " << name << " can not be handled, negative dimension ";
2165 // G4String mStr(mStrStr.str());
2166 // G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
2167 // July 2017, can not run the CDR case due to this error.. False error, no need for this complication.
2168 // I presume
2169  return 0;
2170  }
2171  info.fParams[0] = widthHe;
2172  info.fParams[1] = fTargetFinHeight - 0.07*CLHEP::mm;
2173  info.fParams[2] = fTargetFinLength ;
2174  // exclude the round corners.. They will already filled with Helium This is getting out of hand!..
2175 
2176  if (fUseRoundedTargetFins) {
2177  info.fParams[2] -= 2.0*fTargetFinWidthRequired - 0.001*CLHEP::mm;
2178  }
2179  std::cerr << " Creating TargetFinVertHeliumSide, width .." << widthHe
2180  << " heigth " << info.fParams[1] << std::endl;
2181  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2182  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
2183  info.fTypeName = G4String("Box");
2184  }
2185  if (name.find("TargetFinVertHeliumRounded") != std::string::npos) { // We carve out the rounded edges
2186  // We create 4 distinct volumes, because their orientation differ.
2187  // all of them carved out the same box
2188  info.fParams[0] = fTargetFinContainerWidth - 0.005*CLHEP::mm;
2189  info.fParams[1] = fTargetFinWidthRequired;
2190  info.fParams[2] = fTargetFinHeight - 0.010*CLHEP::mm; // Along z. We'll rotate once the volume subtraction is done.
2191  std::string aCuboidName(name); aCuboidName += std::string("_Cuboid");
2192  // Not really a cuboid, only if 12 mm target width
2193  G4Box* aCuboid = new G4Box(aCuboidName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2194  info.fParams.resize(10);
2195  info.fParams[3] = 0.;
2196  info.fParams[4] = fTargetFinWidthRequired;
2197  info.fParams[5] = fTargetFinHeight - 0.0076*CLHEP::mm;
2198  if (name == G4String("TargetFinVertHeliumRoundedDownstrLeft")) {
2199  info.fParams[6] = 90.*CLHEP::degree;
2200  info.fParams[7] = 180.*CLHEP::degree;
2201  info.fParams[8] = info.fParams[0]/2.;
2202  info.fParams[9] = -info.fParams[1]/2.;
2203  } else if (name == G4String("TargetFinVertHeliumRoundedDownstrRight")) {
2204  info.fParams[6] = 0.*CLHEP::degree;
2205  info.fParams[7] = 90.*CLHEP::degree;
2206  info.fParams[8] = -info.fParams[0]/2.;
2207  info.fParams[9] = -info.fParams[1]/2.;
2208  } else if (name == G4String("TargetFinVertHeliumRoundedUpstrRight")) {
2209  info.fParams[6] = 270.*CLHEP::degree;
2210  info.fParams[7] = 360.*CLHEP::degree;
2211  info.fParams[8] = -info.fParams[0]/2.;
2212  info.fParams[9] = info.fParams[1]/2.;
2213  } else if (name == G4String("TargetFinVertHeliumRoundedUpstrLeft")) {
2214  info.fParams[6] = 180.*CLHEP::degree;
2215  info.fParams[7] = 270.*CLHEP::degree;
2216  info.fParams[8] = info.fParams[0]/2.;
2217  info.fParams[9] = info.fParams[1]/2.;
2218  }
2219  std::string aRodName(name); aRodName += std::string("_Rod");
2220  G4Tubs* aRod = new G4Tubs(aRodName, info.fParams[3], info.fParams[4], info.fParams[5]/2., info.fParams[6], info.fParams[7]);
2221  G4ThreeVector xyTrans(info.fParams[8], info.fParams[9], 0.);
2222  G4RotationMatrix Ra;
2223  G4Transform3D transform(Ra, xyTrans);
2224  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Box-Cylinder", aCuboid, aRod, transform);
2225  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
2226  info.fTypeName = G4String("Subtration");
2227  std::cerr << " Target Rounded Corners, defined for name " << name
2228  << " Params ";
2229  for (int k=0; k != 10; k++) std::cerr << " " << info.fParams[k];
2230  std::cerr << std::endl;
2231  }
2232 
2233  // Oct. November 2016
2234  if (name.find("TargetFinVertTargetCutV2") != std::string::npos) { // We carve out the Cut edges
2235  // for the cooling tubes.
2236  // We create 4 distinct volumes, because the cut for pipe. Unlike above, no need to rotate.
2237  // but volume subtraction is needed for the cooling pipe.
2238  // all of them carved out the same box
2239  info.fParams[0] = fTargetFinWidth;
2240  info.fParams[1] = fTargetFinHeight;
2241  info.fParams[2] = fTargetFinLength - 0.010*CLHEP::mm;
2242  std::string aCuboidName(name); aCuboidName += std::string("_Cuboid");
2243  // Not really a cuboid, only if 12 mm target width
2244  G4Box* aCuboid = new G4Box(aCuboidName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2245  info.fParams.resize(8);
2246  info.fParams[3] = 0.;
2247  info.fParams[4] = fTargetCTubeOuterRadius + 0.075*CLHEP::mm;
2248  const double cTubeShift = info.fParams[4] - 0.5*fTargetFinWidth + 0.500*CLHEP::mm;
2249  info.fParams[5] = fTargetFinLength - 0.010*CLHEP::mm;
2250  if (name == G4String("TargetFinVertTargetCutV2UpLeft")) {
2251  info.fParams[6] = -cTubeShift;
2252  info.fParams[7] = +info.fParams[1]/2.;
2253  // Now milling the graphite
2254  } else if (name == G4String("TargetFinVertTargetCutV2UpRight")) {
2255  info.fParams[6] = +cTubeShift ;
2256  info.fParams[7] = +info.fParams[1]/2.;
2257  } else if (name == G4String("TargetFinVertTargetCutV2DwnLeft")) {
2258  info.fParams[6] = -cTubeShift;
2259  info.fParams[7] = -info.fParams[1]/2.;
2260  } else if (name == G4String("TargetFinVertTargetCutV2DwnRight")) {
2261  info.fParams[6] = cTubeShift;
2262  info.fParams[7] = -info.fParams[1]/2.;
2263  }
2264  std::string aRodName(name); aRodName += std::string("_Rod");
2265  G4Tubs* aRod = new G4Tubs(aRodName, info.fParams[3], info.fParams[4], info.fParams[5]/2., 0., 360.*CLHEP::degree);
2266  G4ThreeVector xyTrans(info.fParams[6], info.fParams[7], 0.);
2267  G4RotationMatrix Ra;
2268  G4Transform3D transform(Ra, xyTrans);
2269  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Box-Cylinder", aCuboid, aRod, transform);
2270  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("Target")), volumeName);
2271  info.fTypeName = G4String("Subtration");
2272  std::cerr << " Target Graphite, defined for name " << name
2273  << " Params ";
2274  for (int k=0; k != 8; k++) std::cerr << " " << info.fParams[k];
2275  std::cerr << std::endl;
2276  }
2277 
2278  if (name.find("TargetWWingCylinder") != std::string::npos) { // These are the upstream fins.
2279  // see also parameters. fTargetNumFinsWithWings
2280  // used in LBNEVolumePlacements::PlaceFinalUpstrTarget1p2MW, Conceptual design for HornA.
2281  //
2282  info.fParams[0] = 0.;
2283  info.fParams[1] = fTargetFinWWingRadius;
2284  info.fParams[2] = fTargetFinLength - 0.100*CLHEP::mm; // they won't be rounded, so make them a bit shorter.
2285  // P.L., minor input to the desgin, in absence of real drawing.
2286  info.fParams.resize(9);
2287  info.fParams[3] = 0.;
2288  info.fParams[4] = fTargetCTubeOuterRadius + 0.150*CLHEP::mm;
2289  const double cTubeShift = fTargetCTubeOuterRadius + 0.5*CLHEP::mm + 0.025*CLHEP::mm; // Per phone discussion with
2290  // Cory C., November 4 2016
2291  info.fParams[5] = fTargetFinLength + 0.300*CLHEP::mm; //length can be extended..
2292  if (name == G4String("TargetWWingCylinderUpLeft")) {
2293  info.fParams[6] = -cTubeShift;
2294  info.fParams[7] = +info.fParams[1] - 0.025*CLHEP::mm;
2295  info.fParams[8] = M_PI/2.;
2296  // Now milling the graphite
2297  } else if (name == G4String("TargetWWingCylinderUpRight")) {
2298  info.fParams[6] = +cTubeShift ;
2299  info.fParams[7] = +info.fParams[1] - 0.025*CLHEP::mm;
2300  info.fParams[8] = 0.;
2301  } else if (name == G4String("TargetWWingCylinderDwnLeft")) {
2302  info.fParams[6] = -cTubeShift;
2303  info.fParams[7] = -info.fParams[1] + 0.025*CLHEP::mm;
2304  info.fParams[8] = M_PI;
2305  } else if (name == G4String("TargetWWingCylinderDwnRight")) {
2306  info.fParams[6] = cTubeShift;
2307  info.fParams[7] = -info.fParams[1] + 0.025*CLHEP::mm;
2308  info.fParams[8] = 3.0*M_PI/2.;
2309  }
2310  G4Tubs* aTub = new G4Tubs(volumeName, info.fParams[0]/2, info.fParams[1],
2311  info.fParams[2]/2., info.fParams[8], 90.*CLHEP::degree);
2312  std::string aRodName(name); aRodName += std::string("_Rod");
2313  G4Tubs* aRod = new G4Tubs(aRodName, info.fParams[3], info.fParams[4],
2314  info.fParams[5]/2., 0., 360.*CLHEP::degree);
2315  G4ThreeVector xyTrans(info.fParams[6], info.fParams[7], 0.);
2316  G4RotationMatrix Ra;
2317  G4Transform3D transform(Ra, xyTrans);
2318  G4SubtractionSolid* subtraction = new G4SubtractionSolid("Cylinder-Cylinder", aTub, aRod, transform);
2319  info.fCurrent = new G4LogicalVolume(subtraction, G4Material::GetMaterial(std::string("Target")), volumeName);
2320  info.fTypeName = G4String("Subtration");
2321  std::cerr << " Target Graphite, defined for name " << name
2322  << " Params ";
2323  for (int k=0; k != 9; k++) std::cerr << " " << info.fParams[k];
2324  std::cerr << std::endl;
2325  }
2326 
2327  if (name == G4String("TargetFinVertLastHeliumSide")) { // The fin container might be made of graphite.
2328  // if so, we must replace some of back with helium, if the nominal target Fin width is smaller
2329  // then the cooling tube radius, which sets the size of the container.
2330  const double widthHe = 2.0*fTargetCTubeOuterRadius - fTargetFinWidth - 0.005*CLHEP::mm;
2331  if (widthHe < 0.) {
2332  std::ostringstream mStrStr;
2333  mStrStr << " Volume named " << name << " can not be handled, negative dimension ";
2334  G4String mStr(mStrStr.str());
2335  G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
2336  }
2337  info.fParams[0] = widthHe;
2338  info.fParams[1] = fTargetFinHeight - 0.07*CLHEP::mm;
2339  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.02*CLHEP::mm;
2340  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2341  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("HeliumTarget")), volumeName);
2342  info.fTypeName = G4String("Box");
2343  }
2344 
2345  if (name == G4String("TargetFinHorizontal")) { // only one of those, fixed size
2346  info.fParams[0] = 62.0*CLHEP::mm;
2347  info.fParams[1] = fTargetFinWidth;
2348  info.fParams[2] = fTargetFinLength ;
2349  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2350  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2351  info.fPosition[0] = -info.fParams[0]/2. + 10.0*CLHEP::mm; // Russian drawing 7589-00-00
2352  const LBNEVolumePlacementData *plInfo = Find(name, G4String("TargetUpstrM0"), G4String("Create"));
2353  info.fPosition[0] = -info.fParams[0]/2.0 + 10.*CLHEP::mm;
2354  info.fPosition[1] = 0.;
2355  info.fPosition[2] = -1.0*plInfo->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
2357  - 100.0*CLHEP::mm; // Russian drawing 7589-00-00
2358  info.fTypeName = G4String("Box");
2359  }
2360 
2361  if (name == G4String("TargetFinVertUpstrLast")) { //
2362  info.fParams[0] = fTargetFinWidth;
2363  info.fParams[1] = fTargetFinHeight - 2.0*fTargetCTubeOuterRadius - 0.1*CLHEP::mm;
2364  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.02*CLHEP::mm; // 20 micron safety.
2365  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2366  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2367  info.fTypeName = G4String("Box");
2368  // despite being a single copy, do the placement in a separate method.
2369  }
2370 
2371  if (name == G4String("TargetFinVertExtraLast")) { // Extra pieces to be place left and right of the center
2372  // of the cooling tube. This extends the target transversely
2373  if (fTargetFinExtraWidth < 0.) {
2374  std::ostringstream mStrStr;
2375  mStrStr << " Volume named " << name << " can not be handled, negative dimension ";
2376  G4String mStr(mStrStr.str());
2377  G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
2378  }
2379  info.fParams[0] = fTargetFinExtraWidth;
2380  info.fParams[1] = fTargetFinHeight - 2.0*fTargetCTubeOuterRadius - 0.05*CLHEP::mm;
2381  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.02*CLHEP::mm; // 20 micron safety.;
2382  G4Box* aBox = new G4Box(volumeName, info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2383  info.fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial(std::string("Target")), volumeName);
2384  info.fTypeName = G4String("Box");
2385  }
2386 
2387  // Adding 4 new small volumes to include the bit of graphite locate on each of the 4 corner
2388  // Oct. 29 2013:
2389  // Adding them as well for the last target segment, of the upstream section which has a different length.
2390  // Perhaps an overzealous choice: there will also be 4 more such volumes for the first
2391  // target segments of the downstream part of the target.
2392  if (name.find("TargetFinVertCorner") != std::string::npos) { //
2393  if (fUse1p2MW) {
2394 // this->declareTargetFinVertCorners(info); // simply to avoid too much code in this method. See LBNEVolumePlacementsAdd.cc
2395 // Obsolete..
2396  } else {
2397  info.fParams.resize(7);
2398  info.fParams[0] = fTargetFinContainerWidth/2. - 0.025*CLHEP::mm;
2399  info.fParams[1] = fTargetCTubeOuterRadius - 0.025*CLHEP::mm;
2400  info.fParams[2] = fTargetFinLength ;
2401  info.fParams[3] = 0.;
2402  info.fParams[4] = fTargetCTubeOuterRadius + 0.250*CLHEP::mm;
2403  info.fParams[5] = fTargetFinLength ;
2404  if (name.find("TargetFinVertCornerUpstrLast") != std::string::npos) {
2405  info.fParams[2] = fTargetFinLengthSplitUpstr - 0.02*CLHEP::mm;
2406  info.fParams[5] = fTargetFinLengthSplitUpstr - 0.02*CLHEP::mm;
2407  }
2408  if (name.find("TargetFinVertCornerDownstrFirst") != std::string::npos) {
2409  info.fParams[2] = fTargetFinLengthSplitDwnstr - 0.02*CLHEP::mm;
2410  info.fParams[5] = fTargetFinLengthSplitDwnstr - 0.02*CLHEP::mm;
2411  }
2412  G4Box* aBox = new G4Box(volumeName+G4String("Box"),
2413  info.fParams[0]/2, info.fParams[1]/2, info.fParams[2]/2.);
2414 
2415  G4Tubs* aTubs = new G4Tubs(volumeName+G4String("Tube"),
2416  info.fParams[3], info.fParams[4], info.fParams[5]/2., 0., 360.0*CLHEP::degree);
2417  G4ThreeVector trans(0., 0., 0.);
2418  if (name.find("UpLeft") != std::string::npos) { //
2419  trans[0] = fTargetFinContainerWidth/4.; trans[1] = fTargetCTubeOuterRadius/2.;
2420  } else if (name.find("UpRight") != std::string::npos) {
2421  trans[0] = -fTargetFinContainerWidth/4.; trans[1] = fTargetCTubeOuterRadius/2.;
2422  } else if (name.find("DwnLeft") != std::string::npos) {
2423  trans[0] = fTargetFinContainerWidth/4.; trans[1] = -fTargetCTubeOuterRadius/2.;
2424  } else if (name.find("DwnRight") != std::string::npos) {
2425  trans[0] = -fTargetFinContainerWidth/4.; trans[1] = -fTargetCTubeOuterRadius/2.;
2426  }
2427  G4RotationMatrix unitMatrix;
2428  G4Transform3D transform(unitMatrix, trans);
2429  G4SubtractionSolid *aRoundCorner = new G4SubtractionSolid(volumeName, aBox, aTubs, transform);
2430  info.fCurrent = new G4LogicalVolume(aRoundCorner, G4Material::GetMaterial(std::string("Target")), volumeName);
2431  info.fTypeName = G4String("G4SubtractionSolid");
2432  }
2433  }
2434 
2435  if (name == G4String("TargetAlignmentRingRight")) { //
2436  info.fParams.resize(5);
2439  info.fParams[2] = fTargetAlignRingThick;
2440  info.fParams[3] = M_PI/2. + fTargetAlignRingCutAngle ;
2441  info.fParams[4] = M_PI - 2.0*fTargetAlignRingCutAngle ;
2442  G4Tubs* aTubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2443  info.fParams[3], info.fParams[4] );
2444  info.fCurrent =
2445  new G4LogicalVolume(aTubs, G4Material::GetMaterial(fTargetAlignRingMaterial), volumeName);
2446 
2447 // std::cerr << " Created TargetAlignmentRingRight, Params " ;
2448 // for (size_t k=0; k!=5; k++) std::cerr << " " << info.fParams[k] << " / ";
2449 // std::cerr << " dphi " << aTubs->GetDeltaPhiAngle();
2450 // std::cerr << std::endl;
2451  // Multiple copies..
2452 
2453  }
2454 
2455  if (name == G4String("TargetAlignmentRingLeft")) { //
2456  info.fParams.resize(5);
2459  info.fParams[2] = fTargetAlignRingThick;
2460  info.fParams[3] = -M_PI/2. + fTargetAlignRingCutAngle + 2.0*M_PI;
2461  info.fParams[4] = M_PI - 2.0*fTargetAlignRingCutAngle ;
2462  G4Tubs* aTubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2463  info.fParams[3], info.fParams[4] );
2464  info.fCurrent =
2465  new G4LogicalVolume(aTubs, G4Material::GetMaterial(fTargetAlignRingMaterial), volumeName);
2466  // Multiple copies..
2467 // std::cerr << " Created TargetAlignmentRingLeft, Params " ;
2468 // for (size_t k=0; k!=5; k++) std::cerr << " " << info.fParams[k] << " / ";
2469 // std::cerr << " dphi " << aTubs->GetDeltaPhiAngle();
2470 // std::cerr << std::endl;
2471 
2472  }
2473 
2474  // Things that are physically part of Horn1, but placed in at the dowstream end of the target volume
2475  // These volumes are surrounding the target.
2476  if (name == G4String("UpstrHorn1TransInnerOuterCont")) { // Approximate!...
2477  info.fParams[0] = fTargetHorn1InnerRadsDownstr[0] - 0.2*CLHEP::mm;
2478  info.fParams[1] = fTargetHorn1InnerRadsDownstr[4] + fTargetHorn1TransThick[4] + 1.*CLHEP::mm;
2479  info.fParams[2] = fTargetHorn1Lengths[0] + fTargetHorn1Lengths[1] + fTargetHorn1Lengths[2] + 0.05*CLHEP::mm;; // few mm safety...
2480  G4Tubs* aTubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2481  0., 360.0*CLHEP::degree);
2482  info.fCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(std::string("Air")), volumeName);
2483  // Pick volume Upstream TargetAssembly.
2484  const LBNEVolumePlacementData *plInfo = Find(name, G4String("Horn1PolyM1"), G4String("Create"));
2485  // Correction for Pseudo Nova: Shifted by the extra space we now have between the downstream end of the target.
2486  // The mother volume for this container volume will be Horn1Hall, and it will be placed a bit upstream
2487  // of the Horn1TopLevelUpstr
2488  double lHorn1Real = -10000.0*CLHEP::m;
2490  if (*il > lHorn1Real ) lHorn1Real = *il;
2491  info.fPosition[2] = -lHorn1Real/2. + info.fParams[2]/2;
2492  std::cerr << " Setting position for UpstrHorn1TransInnerOuterCont, length " << info.fParams[2]
2493  << " length mother " << plInfo->fParams[2] << " zRel " << info.fPosition[2] << std::endl;
2494  }
2495 
2496  if (name.find("UpstrHorn1TransInnerOuterPart") != std::string::npos) { // Still even more approximate!...
2497  size_t nameIndex= name.find("UpstrHorn1TransInnerOuterPart") + name.length() - 1;
2498  std::string nameIndexStr(name.substr(nameIndex));
2499  std::istringstream nameIndexStrStr(nameIndexStr);
2500  int iPart = -1;
2501  nameIndexStrStr >> iPart;
2502 // std::cerr << " from LBNEVolumePlacements::Create, for " << name << " Part number " << iPart << std::endl;
2503  if (iPart != 2) {
2504  info.fParams.resize(5);
2505  info.fParams[0] = fTargetHorn1InnerRadsUpstr[iPart];
2506  info.fParams[2] = fTargetHorn1InnerRadsDownstr[iPart];
2507  info.fParams[1] = fTargetHorn1InnerRadsUpstr[iPart] + fTargetHorn1TransThick[iPart];
2508  info.fParams[3] = fTargetHorn1InnerRadsDownstr[iPart] + fTargetHorn1TransThick[iPart];
2509  info.fParams[4] = fTargetHorn1Lengths[iPart];
2510  G4Cons* aCons = new G4Cons(volumeName, info.fParams[0], info.fParams[1], info.fParams[2], info.fParams[3],
2511  info.fParams[4]/2., 0., 360.0*CLHEP::degree);
2512  info.fCurrent = new G4LogicalVolume(aCons, G4Material::GetMaterial(fHorn1AllCondMat), volumeName);
2513  info.fTypeName = G4String("Cons");
2514  } else {
2515  info.fParams[0] = fTargetHorn1InnerRadsUpstr[iPart];
2516  info.fParams[1] = fTargetHorn1InnerRadsUpstr[iPart] + fTargetHorn1TransThick[iPart];
2517  info.fParams[2] = fTargetHorn1Lengths[iPart];
2518  G4Tubs* aTubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2519  0., 360.0*CLHEP::degree);
2520  // Use Aluminum ! P.L. July 2014...
2521  info.fCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1AllCondMat), volumeName);
2522  }
2523  info.fPosition[0] = 0.; info.fPosition[1] = 0.;
2524  info.fPosition[2] = fTargetHorn1ZPositions[iPart];
2525  }
2526 
2527  //
2528  // October/November 2016.
2529  //
2530  if ((name == G4String("TargetCoolingTubeReturnLoopRight")) ||
2531  (name == G4String("TargetCoolingTubeReturnLoopLeft"))) { //
2532  info.fParams.resize(5);
2533  info.fParams[0] = 0.; //rMin
2534  info.fParams[1] = fTargetCTubeOuterRadius; // rMax
2535  info.fParams[2] = fTargetCTubeOuterRadius + fTargetFinHeight + 0.4*CLHEP::mm;
2536  if (name.find("Right") != std::string::npos) {
2537  info.fParams[3] = -M_PI/2.;
2538  info.fParams[4] = M_PI;
2539  } else if (name.find("Left") != std::string::npos) {
2540  info.fParams[3] = M_PI/2.;
2541  info.fParams[4] = M_PI;
2542  }
2543  std::cerr << " Rad max torus.. " << name << " = " << info.fParams[1] << " rSweep Torus " << info.fParams[2] << std::endl;
2544  G4Torus* aTorus = new G4Torus(volumeName, info.fParams[0], info.fParams[1], info.fParams[2],
2545  info.fParams[3], info.fParams[4]);
2546  info.fCurrent = new G4LogicalVolume(aTorus, G4Material::GetMaterial(std::string("Titanium")), volumeName);
2547  info.fTypeName=std::string("Torus");
2548  info.fRotationIsUnitMatrix = false;
2549  if (name.find("Right") != std::string::npos) {
2550  info.fRotation.rotateY(M_PI/3.); // a bit arbitrary.
2551  } else if (name.find("Left") != std::string::npos) {
2552  info.fRotation.rotateY(-M_PI/3.); // a bit arbitrary.
2553  }
2554 
2555  }
2556  if ((name == G4String("TargetCoolingTubeReturnLoopRightWater")) ||
2557  (name == G4String("TargetCoolingTubeReturnLoopLeftWater"))) { //
2558  info.fParams.resize(5);
2559  info.fParams[0] = 0.; //rMin
2560  info.fParams[1] = fTargetCTubeInnerRadius; // rMin Titanium.
2561  info.fParams[2] = fTargetCTubeOuterRadius + fTargetFinHeight + 0.4*CLHEP::mm;
2562  std::cerr << " Rad max torus.. " << name << " = " << info.fParams[1] << " rSweep Torus " << info.fParams[2] << std::endl;
2563  if (name.find("Right") != std::string::npos) {
2564  info.fParams[3] = -M_PI/2. + 3.0e-3;
2565  info.fParams[4] = M_PI - 6.0e-3;
2566  } else if (name.find("Left") != std::string::npos) {
2567  info.fParams[3] = M_PI/2. + 3.0e-3;
2568  info.fParams[4] = M_PI - 6.0e-3;
2569  }
2570  info.fTypeName=std::string("Torus");
2571  G4Torus* aTorus = new G4Torus(volumeName, info.fParams[0], info.fParams[1], info.fParams[2],
2572  info.fParams[3], info.fParams[4]);
2573  info.fCurrent = new G4LogicalVolume(aTorus, G4Material::GetMaterial(std::string("Water")), volumeName);
2574  }
2575 
2576  //
2577  // Beginning of Horn1 declarations
2578  //
2579  if (name.find("Horn1") == 0) {
2580  if (name == G4String("Horn1Hall")) {
2581  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
2582  const LBNEVolumePlacementData *plInfoC = Find(name, G4String("UpstreamTargetAssembly"), G4String("Create"));
2583  info.fParams[0] = 64.0*in - 1.0*CLHEP::cm;
2584  info.fParams[1] = 50.0*in - 1.0*CLHEP::cm;
2586  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
2587  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
2588  info.fPosition[2] = -1.0*plInfoM->fParams[2]/2. + plInfoC->fParams[2] + info.fParams[2]/2. + 0.020*CLHEP::mm;
2589  }
2590  // Note: to optimize the geometry, we place the downstream end of the target into the
2591  // horn1. Target is not a typo, nor misplaced in the information flow.
2592 
2593  if (name == G4String("Horn1TargetCoolingTubeDwnRetTit")) { //
2594  info.fParams.resize(5);
2598  info.fParams[3] = M_PI/2. + fTargetCTubeReturnDownstrCutAngleStart;
2600  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2601  info.fParams[3], info.fParams[4]);
2602  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Titanium")), volumeName);
2603  // Two copies will be placed explictely
2604 // std::cerr << " Params for " << name << std::endl;
2605 // for (size_t k=0; k != info.fParams.size(); k++) {
2606 // std::cerr << " k " << k << " " << info.fParams[k] << std::endl;
2607 // }
2608  }
2609  if (name == G4String("Horn1TargetCoolingTubeDwnRetWater")) { //
2610  //
2611  // August 2014... This has been cloned from the 700 MW. target. we need to review these parameters
2612  // for the 1.2 MW target.
2613  //
2614  const LBNEVolumePlacementData *plInfoM;
2615  plInfoM = Find(name, G4String("TargetNoSplitHelium"), G4String("Create"));
2616  info.fParams.resize(5);
2620  info.fParams[3] = M_PI/2. + fTargetCTubeReturnDownstrCutAngleStart;
2622  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2.,
2623  info.fParams[3], info.fParams[4]);
2624  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Water")), volumeName);
2625  info.fPosition[0] = 0.; info.fPosition[1] = 0.;
2626  info.fPosition[2] = plInfoM->fParams[2]/2 -
2627  fTargetCTubeReturnDownstrThickWater/2. - fTargetCTubeReturnDownstrThickTitanium/2 - 1.5*CLHEP::mm ; // leave room for the cap.
2628  if (fUsePseudoNova) info.fPosition[2] += 0.1*CLHEP::mm; // A bit too tight is the target is not split
2629 // std::cerr << " Params for " << name << std::endl;
2630 // for (size_t k=0; k != info.fParams.size(); k++) {
2631 // std::cerr << " k " << k << " " << info.fParams[k] << std::endl;
2632 // }
2633  }
2634  if (name == G4String("Horn1TargetDownstrHeContainerCap")) { //
2635  const LBNEVolumePlacementData *plInfoM;
2636  plInfoM = Find(name, G4String("TargetNoSplitHelium"), G4String("Create"));
2637  info.fParams[0] = 0.;
2638  info.fParams[1] = fTargetHeContTubeInnerRadius-0.010*CLHEP::mm;
2639  info.fParams[2] = fTargetBerylDownstrWindowThick; // Nominal value
2640  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2641  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Beryllium")), volumeName);
2642  info.fPosition[2] = plInfoM->fParams[2]/2 - info.fParams[2] - 0.5*CLHEP::mm;
2643  }
2644  //
2645  // End of target related stuff.
2646  //
2647  if (name.find("Horn1IOTrans") == 0) {
2648  if (name == G4String("Horn1IOTransCont")) { // Transition Inner to Outer Drawing 8875-112-MD-363097
2649  // This is the part downstream of Z=0., MCZERO (not ACTRN1)
2650  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("Horn1PolyM1"), G4String("Create"));
2651  info.fParams[0] = fHorn1IOTransInnerRad;
2652  info.fParams[1] = fHorn1IOTransOuterRad;
2653  info.fParams[2] = fHorn1IOTransLength;
2654  std::cerr << " Params for " << name << " " << info.fParams[0] << " / " << info.fParams[1]
2655  << " / " << info.fParams[2] << " mother length " << plInfoM->fParams[2] << std::endl;
2656  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2657  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Air")), volumeName);
2658  info.fPosition[2] = -plInfoM->fParams[2]/2. + info.fParams[2]/2. + 0.025*CLHEP::mm;
2659  info.fPosition[2] += (2.436*in - 30*CLHEP::mm)*fHorn1LongRescale; // Worked on, for Horn1PolyM1 August 22 2014.
2660  std::cerr << " Checking long offset for " << name << " length of mother "
2661  << plInfoM->fParams[2] << " offset " << info.fPosition[2] << std::endl;
2662  }
2663 
2664  } // End of the Inner Outer Transition for Horn1
2665 
2666  if (name == G4String("Horn1TopLevelUpstr")) { // A container for the section of inner and outer conductors enveloping
2667  // the target. Obsolete!!! Aug-Sept 2014.
2668  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("Horn1Hall"), G4String("Create"));
2669 // info.fParams[0] = fTargetHeContTubeInnerRadius + fTargetHeContTubeThickness + 1.5*CLHEP::mm;
2670 // Above is not optimum if misalignment Use the equation set
2671 // Improved a bit on March 25 2014. See below..
2672 //
2673  const double zMaxDC = fHorn1TopUpstrLength - 3.0*CLHEP::cm;
2674 // const size_t iEqn = (zMaxDC < (21.0888*in*fHorn1LongRescale)) ? 0 : 1;
2675 // Better model with smooth change in equation number, as in the PlaceFinalHorn1.
2676 //
2677  const double rMinEqn1 = fHorn1Equations[0].GetVal(zMaxDC); // Equation 1 or 0
2678  const double rMinEqn2 = fHorn1Equations[1].GetVal(zMaxDC); // Equation 1 or 0
2679  const double ratio0vs1 = std::min(1.0, (zMaxDC/(21.0888*in*fHorn1LongRescale)));
2680  const double rMin = rMinEqn2*ratio0vs1 + (1.0-ratio0vs1)*rMinEqn1;
2681 // info.fParams[0] = rMin - 0.5*CLHEP::mm;
2682 // Too loose !... Leave only 5 microns We get wrong overlap at 2.9 mm offset.
2683  info.fParams[0] = rMin - 0.005*CLHEP::mm;
2684  if (fUsePseudoNova) info.fParams[0] = 1.0*CLHEP::mm; // The above equation are not applicable if zMaxDC ~ fHorn1TopUpstrLength
2685  const double rMaxOut = fTargetHeContTubeInnerRadius + fTargetHeContTubeThickness +0.050*CLHEP::mm;
2686 
2687  if ((!fUsePseudoNova) && (info.fParams[0] < rMaxOut) && (!fHorn1RadiusBigEnough)) {
2688  std::ostringstream mStrStr;
2689  mStrStr << " Can't create Horn1TopLevelUpstr, radial clash between Horn1 inner conductor, rMin " <<
2690  info.fParams[0] << " Target Helium tube + min. safety = " << rMaxOut << std::endl;
2691  mStrStr << " Length into horn " << fTargetLengthIntoHorn << std::endl;
2692  G4String mStr(mStrStr.str());
2693  G4Exception("LBNEVolumePlacements::Create", " ", FatalErrorInArgument, mStr.c_str());
2694  } else {
2695  std::cerr << " Successfull (preliminary check) of targetinto with max Z = " << zMaxDC
2696  << " (Drawing CS), rMin = " << rMin << std::endl;
2697  }
2698  info.fParams[1] = fHorn1TopUpstrOuterRad + 3.0*in; // room for the flanges.
2699  info.fParams[2] = fHorn1TopUpstrLength - 0.010*CLHEP::mm;
2700 // std::cerr << " Params for " << name << " " << info.fParams[0] << " / " << info.fParams[1]
2701 // << " / " << info.fParams[2] << std::endl;
2702 // std::cerr << " .... into Horn1Hall " << plInfoM->fParams[0] << " / " << plInfoM->fParams[1]
2703 // << " / " << plInfoM->fParams[2] << std::endl;
2704  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2705  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Air")), volumeName);
2706  info.fPosition[2] = -plInfoM->fParams[2]/2. + info.fParams[2]/2. + 0.005*CLHEP::mm;
2707  // Correction for Pseudo Nova: Shift by the extra space we now have between the downstream end of the target.
2708  // and Horn1.
2710  // This is a surveyed volume, tweaked in PlaceFinal
2711  }
2712  if (name == G4String("Horn1TopLevelDownstr")) { // A container for the section of inner and outer conductors
2713  // downstream of the target
2714  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("Horn1Hall"), G4String("Create"));
2715  const LBNEVolumePlacementData *plInfoC = Find(name, G4String("Horn1PolyM1"), G4String("Create"));
2716  info.fParams[0] = 0.;
2717  info.fParams[1] = fHorn1TopDownstrOuterRad + 15.0*in; // big stuff at the downstream end..
2718  info.fParams[2] = fHorn1TopDownstrLength + 0.010*CLHEP::mm;
2719  G4Tubs* aTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.*CLHEP::degree);
2720  info.fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial(std::string("Air")), volumeName);
2721  info.fPosition[2] = -plInfoM->fParams[2]/2. + plInfoC->fParams[2] + info.fParams[2]/2. + 0.005*CLHEP::mm;
2722  // This is a surveyed volume, tweaked in PlaceFinal
2723  // Correction for Pseudo Nova: Shift by the extra space we now have between the downstream end of the target.
2724  // and Horn1.
2725  // Correction for the NoSplit configuration: Offsets to be checked, August 22 2014
2727  double rMin = 1.0e10*CLHEP::mm;
2729  if (*il < rMin) rMin = *il;
2730  info.fParams[0] = rMin - 0.010*CLHEP::mm ;
2731  const double z30p150 = fHorn1LongRescale*30.150*in; //Equation change. We will put the split Upst/Downstr here.
2732  const double zOffsetDrawingUpstrEdge = 5.752*in*fHorn1LongRescale; // Drawing 363097
2733  info.fPosition[2] = - plInfoC->fParams[2]/2. + zOffsetDrawingUpstrEdge + z30p150 + fHorn1TopDownstrLength/2. + 0.005*CLHEP::mm;
2734  // see PlaceFinalNoSplitHorn1..
2735  std::cerr << " Checking long offset for " << name
2736  << " length of mother " << plInfoC->fParams[2] << " length " << info.fParams[2] << " ZPos "
2737  << info.fPosition[2] << std::endl;
2738  }
2739 
2740  if (name == G4String("Horn1PolyM1")) { // A container for the section of inner and outer conductors
2741  // downstream of the target
2742  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("TargetHallAndHorn1"), G4String("Create"));
2743  std::cerr << " Horn1Poly Placement, mother info , long. info, length "
2744  << plInfoM->fParams[2] << " at Z = " << plInfoM->fPosition[2] << std::endl;
2745  info.fParams[0] = 0.; info.fParams[1] = 0.;
2746  info.fParams[2] = -100000.*CLHEP::m;
2748  if (*il > info.fParams[2]) info.fParams[2] = *il;
2749  //
2750  // We shift the Z position by half the length, such the relative definition is the same as for the other volumes.
2751  std::vector<double> zz(fMotherHorn1AllLengths);
2752  for (std::vector<double>::iterator il = zz.begin(); il != zz.end(); il++) *il -= info.fParams[2]/2.;
2753 // std::cerr << " Dump of Horn1 Polycon, mother, parameters.. Ih Z r " << std::endl;
2754 // for (size_t k=0; k!= zz.size(); k++)
2755 // std::cerr << " " << k << " " << zz[k] << " " << fMotherHorn1AllRads[k] << std::endl;
2756  std::cerr << " .... Total length HornPolyM1 " << info.fParams[2];
2757  G4GenericPolycone* aPCon = new G4GenericPolycone(volumeName, 0.*CLHEP::degree, 360.0*CLHEP::degree, static_cast<int>(fMotherHorn1AllLengths.size()),
2758  &fMotherHorn1AllRads[0], &zz[0]);
2759 
2760 
2761  if (fFillHornsWithArgon) {
2762  info.fCurrent = new G4LogicalVolume(aPCon, G4Material::GetMaterial(std::string("Argon")), volumeName);
2763  } else {
2764  info.fCurrent = new G4LogicalVolume(aPCon, G4Material::GetMaterial(std::string("Air")), volumeName);
2765  }
2766  const double lastCorrOnHorn1 = 9.99*CLHEP::mm*fHorn1LongRescale;
2767  info.fPosition[2] = plInfoM->fParams[2]/2. - info.fParams[2]/2. - lastCorrOnHorn1; // Probably needs corrections.
2768  // Indeed... No need for this last correction.. if Custom Horn1. November 7 2014.
2770  info.fPosition[2] = plInfoM->fParams[2]/2. - info.fParams[2]/2. - 0.005*CLHEP::mm;
2771  // June 2016: if we use the Conceptual design, and implement the complete I/O transition section,
2772  // and keep Z = 0. at the same place, then we have to shift downstream the HornA mother Volume.
2773 // info.fPosition[2] += fZShiftConceptHornAStartIC; done with TargetAndHorn1.
2774  // if Horn1 is tilted, leave some room downstream.. Testing here, I should find out what that misalignment is..
2775  //
2777  info.fPosition[2] = plInfoM->fParams[2]/2. - info.fParams[2]/2. - fZHallHorn1ToHorn1PolyM1 - 0.005*CLHEP::mm;
2778 
2779  LBNESurveyor* theSurvey = LBNESurveyor::Instance();
2780  const std::string myHorn1SName("Horn1");
2781  // Use a fixed shift for now. To be refine when (if ever) we do the systemac analysis on misalignment.
2782  if (theSurvey->IsVolumeMisaligned(myHorn1SName)) info.fPosition[2] -= 5.0*CLHEP::mm;
2783  std::cerr << " Horn1Poly Placed, long. info, length "
2784  << info.fParams[2] << " at Z = " << info.fPosition[2] << std::endl;
2785  }
2786 
2787  } // End of Horn1
2788  if (name.find("Horn2") == 0) {
2789  if (name == G4String("Horn2Hall")) { // not align-able.
2790  const LBNEVolumePlacementData *plInfoTunnel = Find(name, G4String("Tunnel"), G4String("Create"));
2791  for (size_t k=0; k != 2; ++k)
2792  info.fParams[k] = plInfoTunnel->fParams[k] - 0.5*CLHEP::cm;
2793  info.fParams[2] = fHorn2Length + 4.0*fHorn2LengthMargin; // Add extra margin, 2 on each side, as there will
2794  // be the container volume
2795  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
2796  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
2797 // The geometric center of tunnel is at z=0 (MCZERO=0), so, we simply have:
2798  info.fPosition[2] = info.fParams[2]/2. + fHorn2LongPosition - fHorn2OffsetIOTr1;
2799  }
2800  if (name == G4String("Horn2TopLevel")) { // align-able. Use survey data in PlaceFinal
2801  info.fParams[0] = 0.;
2802  info.fParams[1] = fHorn2OuterTubeOuterRadMax + 2.0*in;
2803  info.fParams[2] = fHorn2Length + 2.0*fHorn2LengthMargin; // Add extra margin, 2 on each side, as there will
2804  // be the container volume
2805  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2806  info.fParams[2]/2., 0. , 360.0*CLHEP::degree );
2807  if (fFillHornsWithArgon) {
2808  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial(std::string("Argon")), volumeName);
2809  } else {
2810  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial(std::string("Air")), volumeName);
2811  }
2812  info.fPosition[2] = 0.;
2813  }
2814  // Other subvolume defined the usual way in PlaceFinalHorn2
2815  } // End of Horn2
2816  //
2817  // LBNF design, Polycone Horns, generic design.
2818  if (name.find("LBNFChaseDwnstrHorn1") == 0) {
2819  const LBNEVolumePlacementData *plInfoTunnel = Find(name, G4String("Tunnel"), G4String("Create"));
2820  for (size_t k=0; k != 2; ++k)
2821  info.fParams[k] = plInfoTunnel->fParams[k] - 0.5*CLHEP::cm;
2822  const double zBeg = fHornsPolyZStartPos[1] - 1.0*CLHEP::mm;
2823  size_t lastIndex = fMotherHornsAllLengths[fHornsPolyZStartPos.size()-1].size() - 1;
2824  const double zEnd = fHornsPolyZStartPos[fHornsPolyZStartPos.size()-1] +
2825  fMotherHornsAllLengths[fHornsPolyZStartPos.size()-1][lastIndex] + 1.0*CLHEP::mm;
2826 
2827  info.fParams[2] = (zEnd - zBeg); //Simply.. They are ordered in Z.
2828  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
2829  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
2830 // The geometric center of tunnel is at z=0 (MCZERO=0), so, we simply have:
2831  info.fPosition[2] = fHornsPolyZStartPos[1] + info.fParams[2]/2. - 0.5*CLHEP::mm;
2832  }
2833 
2834  if (name.find("LBNFSimpleHorn") == 0) {
2835  size_t ii = name.find("Horn"); ii+=4;
2836  char hornNumChr = name[ii];
2837 // const char *hornNumChrPtr = &hornNumChr; // What was this ? P.L. May 18 2016
2838  size_t iH = hornNumChr - '0' - 1;
2839  const LBNEVolumePlacementData *plInfoM = Find(name, G4String("Tunnel"), G4String("Create"));
2840  for (size_t k=0; k != 2; ++k) info.fParams[k] = plInfoM->fParams[k] - 0.2*CLHEP::mm;
2841  info.fParams[2] = fMotherHornsAllLengths[iH][fMotherHornsAllLengths[iH].size() -1] + 2.*CLHEP::mm; //Simply.. They are ordered in Z.
2842 //
2843 // Make it a tube, such that we can stick a plug if need be. Pick the smalles radii
2844 //
2845  info.fParams[0] = 1.0e8;
2846  for (size_t k=0; k != fMotherHornsAllRads[iH].size(); k++)
2847  info.fParams[0] = std::min(info.fParams[0], fMotherHornsAllRads[iH][k]);
2848  info.fParams[0] -= 0.1*CLHEP::mm;
2849  info.fParams[1] = fHornsPolyOuterRadius[iH] + 5.0*CLHEP::mm;
2850  G4Tubs* hallTube = new G4Tubs(volumeName, info.fParams[0], info.fParams[1], info.fParams[2]/2., 0., 360.0*CLHEP::degree );
2851  info.fCurrent = new G4LogicalVolume(hallTube, G4Material::GetMaterial("Air"), volumeName);
2852  // Assume the tunnel center is at Z = 0., G4 world coordinate..
2853  info.fPosition[2] = fHornsPolyZStartPos[iH] + info.fParams[2]/2.;
2854  std::cerr << " .... Placing Mother volume " << volumeName << " r min " << info.fParams[0]
2855  << " rMax " << info.fParams[1] << " Length "
2856  << info.fParams[2] << " At Z = " << info.fPosition[2] << std::endl;
2857  }
2858 
2859  if (name.find("DecayPipe") == 0) {
2860  if (name == G4String("DecayPipeHall")) { // Surveyable, for ease of convenience, let us do it at this level.
2861  const LBNEVolumePlacementData *plInfoTunnel = Find(name, G4String("Tunnel"), G4String("Create"));
2862  for (size_t k=0; k != 2; ++k)
2863  info.fParams[k] = plInfoTunnel->fParams[k] - 50.*CLHEP::cm; // 50 cm misalignement unlikely.
2864  info.fParams[2] = fDecayPipeLength + 4.0*CLHEP::cm; // Add extra margin, 2 on each side, as there will
2865  // be the container volume
2866  G4Box* hallBox = new G4Box(volumeName, info.fParams[0]/2., info.fParams[1]/2., info.fParams[2]/2. );
2867  info.fCurrent = new G4LogicalVolume(hallBox, G4Material::GetMaterial("Air"), volumeName);
2868  // we decide to place the decay pipe after the snout, and save
2869  if (!fRemoveDecayPipeSnout) {
2870  const LBNEVolumePlacementData *plInfoS = Find(name, G4String("DecayPipeSnout"), G4String("Create"));
2871  fDecayPipeLongPosition = plInfoS->fPosition[2] + plInfoS->fParams[2]/2.;
2872  } else {
2873  std::cerr << " The decay pipe will start " << fDecayPipeLongPosition
2874  << " meters from the start of Horn1, without Decay Pipe snout.. " << std::endl;
2875  }
2876  // longitudinal position of the entrance of the decay pipe hall.
2877  info.fPosition[2] = info.fParams[2]/2. + fDecayPipeLongPosition + 2.0*CLHEP::cm;
2878  std::cerr << " VolumePlacement, decay pipe, position " << info.fPosition[2] << std::endl;
2879  }
2880  if (name == G4String("DecayPipeConcrete")) {
2881  const LBNEVolumePlacementData *plInfo = Find(name, G4String("DecayPipeHall"), G4String("Create"));
2882  info.fParams[0] = fDecayPipeRadius + 2.0*fDecayPipeWallThick + 20.0*CLHEP::cm + 2.0*CLHEP::cm;
2883  info.fParams[1] = std::min(plInfo->fParams[0], plInfo->fParams[1])/2.0 - 1.0*CLHEP::m;
2884  // fill with concrete. Rock is a bit different
2885  // from concrete, but O.K. at such last distance from beam axis. Leave one meter for misalignment..
2886  info.fParams[2] = fDecayPipeLength + 2.0*CLHEP::cm; // Add extra margin, 2 on each side, as there will
2887  // be the container volume
2888  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2889  info.fParams[2]/2., 0., 360.0*CLHEP::degree );
2890  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial("Concrete"), volumeName);
2891  }
2892  if (name == G4String("DecayPipeWall")) {
2893  info.fParams[0] = fDecayPipeRadius; // such that the decay pipe wall & volume
2894  // can be surveyable.
2896  info.fParams[2] = fDecayPipeLength + 1.0*CLHEP::cm; // Add extra margin
2897  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2898  info.fParams[2]/2., 0., 360.*CLHEP::degree);
2899  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial("Steel316"), volumeName);
2900  }
2901  if (name == G4String("DecayPipeOuterWall")) {
2902  info.fParams[0] = fDecayPipeRadius + 20.0*CLHEP::cm + fDecayPipeWallThick; // such that the decay pipe wall & volume
2903  // can be surveyable.
2904  info.fParams[1] = fDecayPipeRadius + 2.0*fDecayPipeWallThick + 20.0*CLHEP::cm ;
2905  info.fParams[2] = fDecayPipeLength + 1.0*CLHEP::cm; // Add extra margin
2906  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2907  info.fParams[2]/2., 0., 360.*CLHEP::degree);
2908  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial("Steel316"), volumeName);
2909  }
2910 
2911  if (name == G4String("DecayPipeVolume")) {
2912  info.fParams[0] = 0.; // such that the decay pipe wall & volume
2913  // can be surveyable.
2914  info.fParams[1] = fDecayPipeRadius - 0.010*CLHEP::mm;
2915  info.fParams[2] = fDecayPipeLength ;
2916  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2917  info.fParams[2]/2., 0., 360.0*CLHEP::degree);
2918  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial("DecayPipeGas"), volumeName);
2919  }
2920  if (name == G4String("DecayPipeSnout")) {
2921  LBNERunManager *pRunManager=static_cast<LBNERunManager*> (LBNERunManager::GetRunManager());
2922  const LBNEDetectorConstruction *pDet =
2923  static_cast<const LBNEDetectorConstruction*> (pRunManager->GetUserDetectorConstruction());
2924  info.fParams[0] = 0.; // Centered
2925  // can be surveyable.
2926  info.fParams[1] = ((50.0*in*std::sqrt(2.))/std::cos(pDet->GetBeamlineAngle()) + 1.0*CLHEP::cm)/2.;
2927  info.fParams[2] = 25.5*in +
2928  25.0*in*std::abs(std::sin(pDet->GetBeamlineAngle())) + 15.0*in + 201.*in;
2929  // 15 in is the space upstream of the window box
2930  // and the upstream part is the window holder, which will have to be rotated.
2931  // the distance between the downstream end of the window unit and the beginning of
2932  // the decay pipe.
2933  // Ref Drawing 2251.000-ME-487107 + drawing from Rich Stefaneck, who obtained it
2934  // from Diane Reiztner
2935  // see also Doc db 5339-v5, page 30
2936  std::cerr << " radius of the snout " << info.fParams[1] << " Length " << info.fParams[2] << std::endl;
2937  G4Tubs* tubs = new G4Tubs(volumeName, info.fParams[0], info.fParams[1],
2938  info.fParams[2]/2., 0., 360.*CLHEP::degree);
2939  info.fCurrent = new G4LogicalVolume(tubs, G4Material::GetMaterial("DecayPipeGas"), volumeName);
2940  info.fPosition[2] = fDecayPipeWindowZLocation + info.fParams[2]/2. - 19.84*in;
2941  // This last number is the distance
2942  // between the upstream side of the container volume and the window itself,
2943  // and the length of the buffer volume, snout to snout container.
2944  std::cerr << " Z Position of the snout window " << info.fPosition[2] << std::endl;
2945  // the last number deduced from drawing 2251.000-ME-487107, right side (Scale 1/4 ) Correct within an inch
2946  // or so
2947  }
2948 
2949  } // End if decay pipe.
2950  fSubVolumes.insert(std::pair<G4String, LBNEVolumePlacementData>(name, info));
2951  return &(fSubVolumes.find(name)->second);
2952 
2953 }
2954 
2955 // Place a volume, single copy.
2956 G4PVPlacement* LBNEVolumePlacements::PlaceFinal(const G4String &name, G4VPhysicalVolume *mother) {
2957 
2958  const bool debugIsOn = false;
2959  G4LogicalVolume *lMother=mother->GetLogicalVolume();
2961  if (it == fSubVolumes.end()) {
2962  std::ostringstream mStrStr;
2963  mStrStr << " Internal error for " << name << " Mother Volume not found " << std::endl;
2964  G4String mStr(mStrStr.str());
2965  G4Exception("LBNEVolumePlacements::PlaceFinal", " ", FatalErrorInArgument, mStr.c_str());
2966  }
2967  std::string surveyedPtName("blank");
2968  if (debugIsOn) std::cerr << " LBNEVolumePlacements::PlaceFinal, name is " << name << std::endl;
2969  // List of suported cases, nomenclature confusion.. Otherwise, name Surveyed point would get too long.
2970  if (name == G4String("UpstreamTargetAssembly")) surveyedPtName = std::string("Canister");
2971  if (name == G4String("TargetUpstrDownstrHeContainer")) surveyedPtName = std::string("HeTube");
2972  if (name == G4String("Horn1TargetDownstrHeContainer")) surveyedPtName = std::string("HeTube");
2973  if (name == G4String("Horn1TopLevelUpstr")) surveyedPtName = std::string("Horn1");
2974  if (name == G4String("Horn1TopLevelDownstr")) surveyedPtName = std::string("Horn1");
2975  // Simplified geometry, Horn1 Mother volume is polycone and contains the entire Horn1
2976  if (name == G4String("TargetNoSplitHeContainer")) surveyedPtName = std::string("HeTube");
2977  if (name == G4String("Horn1PolyM1")) surveyedPtName = std::string("Horn1");
2978  if (name == G4String("LBNFSimpleHorn1Container")) surveyedPtName = std::string("Horn1");
2979  if (name == G4String("LBNFSimpleHorn2Container")) surveyedPtName = std::string("Horn2");
2980  if (name == G4String("LBNFSimpleHorn3Container")) surveyedPtName = std::string("Horn3");
2981  if (name == G4String("Horn2Hall")) surveyedPtName = std::string("Horn2");
2982  if (name == G4String("DecayPipeHall")) surveyedPtName = std::string("DecayPipe");
2983 
2984  LBNEVolumePlacementData &info=it->second;
2985  info.fMother = mother;
2986  LBNESurveyor* theSurvey = LBNESurveyor::Instance();
2987  std::vector<double> posA(3,0.);
2988  for (size_t k=0; k!=3; ++k) posA[k] = info.fPosition[k];
2989  if (debugIsOn) std::cerr << " LBNEVolumePlacements::PlaceFinal, Prior to alignment " << name << " half size "
2990  << info.fParams[2]/2. << " position X " << info.fPosition[0]
2991  << " Y " << info.fPosition[1] << " Z " << info.fPosition[2] << std::endl;
2992  if (theSurvey->size() != 0) {
2993  G4ThreeVector deltaUpstrLeft(0., 0., 0.);
2994  G4ThreeVector deltaUpstrRight(0., 0., 0.);
2995  G4ThreeVector deltaDownstrLeft(0., 0., 0.);
2996  G4ThreeVector deltaDownstrRight(0., 0., 0.);
2997  std::vector<double> deltaUpstr(3, 0.);
2998  std::vector<double> deltaDownstr(3, 0.);
2999  std::vector<double> deltaSlopes(2, 0.);
3000  // This code could be optimize a bit, by removing extra vector copies..
3001  for(std::vector<LBNESurveyedPt>::const_iterator itSurv = theSurvey->begin();
3002  itSurv != theSurvey->end(); itSurv++) {
3003  if (itSurv->GetName().find(surveyedPtName) == std::string::npos) continue;
3004  if (itSurv->GetName().find("Upstr") != std::string::npos) {
3005  if (itSurv->GetName().find("Left") != std::string::npos) deltaUpstrLeft = itSurv->GetPosition();
3006  else if (itSurv->GetName().find("Right") != std::string::npos) deltaUpstrRight = itSurv->GetPosition();
3007  } else if (itSurv->GetName().find("Downstr") != std::string::npos) {
3008  if (itSurv->GetName().find("Left") != std::string::npos) deltaDownstrLeft = itSurv->GetPosition();
3009  else if (itSurv->GetName().find("Right") != std::string::npos) deltaDownstrRight = itSurv->GetPosition();
3010  }
3011  }
3012  for (size_t k=0; k != 3; ++k) {
3013  if ((std::abs(deltaUpstrLeft[k]) > 2.0e-3*CLHEP::mm) && (std::abs(deltaUpstrLeft[k]) > 2.0e-3*CLHEP::mm))
3014  deltaUpstr[k] = 0.5*(deltaUpstrLeft[k] + deltaUpstrRight[k]);
3015  else if (std::abs(deltaUpstrLeft[k]) > 2.0e-3*CLHEP::mm) deltaUpstr[k] = deltaUpstrLeft[k];
3016  else if (std::abs(deltaUpstrRight[k]) > 2.0e-3*CLHEP::mm) deltaUpstr[k] = deltaUpstrRight[k];
3017  if ((std::abs(deltaDownstrLeft[k]) > 2.0e-3*CLHEP::mm) && (std::abs(deltaDownstrLeft[k]) > 2.0e-3*CLHEP::mm))
3018  deltaDownstr[k] = 0.5*(deltaDownstrLeft[k] + deltaDownstrRight[k]);
3019  else if (std::abs(deltaDownstrLeft[k]) > 2.0e-3*CLHEP::mm) deltaDownstr[k] = deltaDownstrLeft[k];
3020  else if (std::abs(deltaDownstrRight[k]) > 2.0e-3*CLHEP::mm) deltaDownstr[k] = deltaDownstrRight[k];
3021  // Special case for the Helium tube that contains the target segments:
3022  // Only the dowstream measurements make sense
3023  if ((name == "TargetUpstrDownstrHeContainer") || (name == "Horn1TargetDownstrHeContainer")) {
3024 // if (std::abs(deltaUpstr[k]) > 2.0e-3*CLHEP::mm) {
3025 // std::cerr << " LBNEVolumePlacements::PlaceFinal The upstream section of the He Container is misaligned." << std::endl;
3026 // std::cerr << " This makes little sense from a mechanical point of view. " << std::endl;
3027 // std::cerr << " Suggested action: misaling the target canister instead. " << std::endl;
3028 // std::cerr << " Meanwhile, setting the deltaUpstream to 0. " << std::endl;
3029 // deltaUpstr[k] = 0.;
3030 // }
3031  }
3032  if (k != 2) {// Case by case for composite volumes..
3033  if (surveyedPtName == std::string("Horn1")) {
3034  const double aTotalLength = fHorn1TopUpstrLength + fHorn1TopDownstrLength;
3035 
3036  deltaSlopes[k] = (deltaDownstr[k] - deltaUpstr[k])/aTotalLength;
3037  if(name == G4String("Horn1TopLevelUpstr")) {
3038  info.fPosition[k] += deltaUpstr[k] + deltaSlopes[k]*(fHorn1TopUpstrLength/2.) ;
3039  } else if(name == G4String("Horn1TopLevelDownstr")) {
3040  info.fPosition[k] += deltaUpstr[k] + deltaSlopes[k]*
3041  (fHorn1TopUpstrLength + fHorn1TopDownstrLength/2.) ;
3042  }
3043  } else { //generic surveyed volume .
3044 // std::cerr << " Valgrind unhappy, LBNEVolumePlacements, line 2251, k " <<
3045 // k << " deltas " << deltaUpstr[k] << " " << deltaDownstr[k] << std::endl;
3046 // Valgrind too picky. Things are properly initialized in std::vector constructor.
3047  info.fPosition[k] += 0.5*(deltaUpstr[k] + deltaDownstr[k]);
3048  deltaSlopes[k] = (deltaDownstr[k] - deltaUpstr[k])/info.fParams[2];
3049  }
3050  }
3051  }
3052 // Valgrind too picky. Things are properly initialized in std::vector constructor.
3053  if ((std::abs(deltaSlopes[0]) > 2.0e-9) || (std::abs(deltaSlopes[1]) > 2.0e-9)) {
3054  info.fRotationIsUnitMatrix = false;
3055  info.fRotation.rotateY(-1.0*deltaSlopes[0]); // change sign??????
3056  info.fRotation.rotateX(deltaSlopes[1]); // rotation in the YZ plane, axis is then X Commutative for small angles..
3057  // Shift the volume longitudinally if a signficant slope exists.
3058  const double maxSlope = std::max(std::abs(deltaSlopes[0]), std::abs(deltaSlopes[1]));
3059  // assume they are tubes..for now, all surveyed points are assigned to tubes..Shift everything downstream
3060  // (an convention arbitrary convention!...)
3061  info.fParams[2] += std::sin(maxSlope)*info.fParams[1];
3062  // Note: position might have to revised as well.. On a case by case basis?
3063  }
3064  } // End of alignment.
3065  if (debugIsOn) std::cerr << " LBNEVolumePlacements::PlaceFinal, " << name << " half size "
3066  << info.fParams[2]/2. << " position X " << info.fPosition[0]
3067  << " Y " << info.fPosition[1] << " Z " << info.fPosition[2] << std::endl;
3069  fSubVolumes.find(lMother->GetName());
3070  if (itMother != fSubVolumes.end()) {
3071 // LBNEVolumePlacementData &infoMother=itMother->second;
3072 // std::cerr << " .... Params for mother ";
3073 // for (size_t k=0; k!= infoMother.fParams.size(); k++) std::cerr << " " << infoMother.fParams[k] << ",";
3074 // std::cerr << " . " << std::endl;
3075 
3076  }
3077  G4PVPlacement *placement=0;
3078  G4String vpName(name); vpName += G4String("_P");
3079  if (name == "Horn1IOTransCont") {
3080  std::cerr << " PlaceFinal, Z-offset for " << name << " is " << info.fPosition << std::endl;
3081  }
3082 // std::cerr << " PlaceFinal , " << info.fCurrent->GetName() << " Last Position "
3083 // << info.fPosition << " Length " << info.fParams[2] << std::endl;
3084  if (info.fRotationIsUnitMatrix)
3085  placement=new G4PVPlacement((G4RotationMatrix *) 0,
3086  info.fPosition, info.fCurrent, vpName, lMother, false, 0, fCheckVolumeOverLapWC);
3087  else {
3088  std::cerr << " Rotated element, slope X= " << info.fRotation.xz() << " Y "
3089  << info.fRotation.yz() << std::endl;
3090  placement=new G4PVPlacement(&info.fRotation, info.fPosition, info.fCurrent,
3091  vpName, lMother, false, 0, fCheckVolumeOverLapWC);
3092  }
3093 // std::cerr << " PlaceFinal, done for volume " << name << std::endl;
3094  info.fIsPlaced = true;
3095  // Optionally, we could test for overlap after installing each new volume here.
3096  return placement;
3097 }
3098 //
3099 
3100 
3101 
3102 void LBNEVolumePlacements::PlaceFinalUpstrTarget(G4PVPlacement *mother) {
3103 //
3104 // We no longer support the 700 kW option, nor the implementation of the split target..
3105 // However, the type of NuMI target we have to use depends on its length...
3106 // The 2m. long target require larger diameter cooling tubes, taller fins => bigger Helium container
3107 // containment vessel.
3108 //
3109 
3110  if (!fUseRALTGTv1){
3112  std::cerr << " LBNEVolumePlacements::PlaceFinalUpstrTarget, small NuMI tgt selected " << std::endl;
3113  this->PlaceFinalSmallTarget1p2MW(mother);
3114  } else {
3115  std::cerr << " LBNEVolumePlacements::PlaceFinalUpstrTarget, NuMI target, 4mm cooling tube, November 2016. " << std::endl;
3116  this->PlaceFinalUpstrTarget1p2MW(mother);
3117  }
3118  }
3119  else {
3120  std::cerr << " LBNEVolumePlacements::PlaceFinalUpstrTarget, Simple target, 8mm radius rod, June 2017. " << std::endl;
3121  this->PlaceRALTGTv1(mother);}
3122 
3123 
3124 
3125 
3126 }
3127 
3129 
3130  std::cout << "======================================================================================" << std::endl;
3131  std::cout << " Dump of all the Placed Volumes " << std::endl;
3133  it++) {
3134 
3135  const LBNEVolumePlacementData &info = it->second;
3136  std::cout << " SubVolume " << it->first << " of type " << info.fTypeName;
3137  if (info.fMother == 0) std::cout << " has no assigned mother volume" << std::endl;
3138  else std::cout << " is in logical volume " << info.fMother->GetLogicalVolume()->GetName() << std::endl;
3139  std::cout << " .... Params Values ";
3140  for (std::vector<double>::const_iterator ip=info.fParams.begin(); ip!=info.fParams.end(); ip++)
3141  std::cout << " " << (*ip) << ", ";
3142  std::cout << std::endl;
3143  std::cout << " .... Position " << info.fPosition;
3144  std::cout << std::endl;
3145  if (!info.fRotationIsUnitMatrix) {
3146  std::cout << " .......... Has a rotation matrix ";
3147  info.fRotation.print(std::cout);
3148  }
3149  std::cout << "-----------------------------------------------------------------------------------" << std::endl;
3150 
3151  }
3152  std::cout << "======================================================================================" << std::endl;
3153 }
3154 
3155 
3157  const char *motherName, const char *descr) const {
3159  if (itM == fSubVolumes.end()) {
3160  std::ostringstream mStrStr;
3161  mStrStr << " Internal error for " << name << " to be placed in "
3162  << motherName << "; mother not found " << " descriptor " << G4String(descr) << std::endl;
3163  G4String mStr(mStrStr.str());
3164  G4String origin("LBNEVolumePlacements::Find");
3165  G4Exception(origin, " ", FatalErrorInArgument, mStr.c_str());
3166  return 0;
3167  }
3168  return &(itM->second);
3169 }
3170 //
3171 // Currently a clone of G4PVPlacement::CheckOverlaps. But we plan to upgrade it
3172 // to handle volume that interesct each other at tiny surfaces.
3173 //
3174 bool LBNEVolumePlacements::CheckOverlaps(const G4PVPlacement *plVol, G4int res, G4double tol, G4bool verbose) const {
3175 
3176  if (res<=0) { return false; }
3177 
3178  G4VSolid* solid = plVol->GetLogicalVolume()->GetSolid();
3179  G4LogicalVolume* motherLog = plVol->GetMotherLogical();
3180  if (!motherLog) { return false; }
3181 
3182  G4VSolid* motherSolid = motherLog->GetSolid();
3183 
3184  if (verbose)
3185  {
3186  G4cout << "Checking overlaps for volume " << plVol->GetName() << " ... ";
3187  }
3188 
3189  // Create the transformation from daughter to mother
3190  //
3191  G4AffineTransform Tm( plVol->GetRotation(), plVol->GetTranslation() );
3192 
3193  for (G4int n=0; n<res; n++)
3194  {
3195  // Generate a random point on the solid's surface
3196  //
3197  G4ThreeVector point = solid->GetPointOnSurface();
3198 
3199  // Transform the generated point to the mother's coordinate system
3200  //
3201  G4ThreeVector mp = Tm.TransformPoint(point);
3202 
3203  // Checking overlaps with the mother volume
3204  //
3205  if (motherSolid->Inside(mp)==kOutside)
3206  {
3207  G4double distin = motherSolid->DistanceToIn(mp);
3208  if (distin > tol)
3209  {
3210  if (verbose) G4cout << G4endl;
3211  if (verbose) G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl
3212  << " Overlap is detected for volume "
3213  << plVol->GetName() << G4endl
3214  << " with its mother volume "
3215  << motherLog->GetName() << G4endl
3216  << " at mother local point " << mp << ", "
3217  << "overlapping by at least: " << G4BestUnit(distin, "Length")
3218  << G4endl;
3219  if (verbose) G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup",
3220  JustWarning, "Overlap with mother volume !");
3221  return true;
3222  }
3223  }
3224 
3225  // Checking overlaps with each 'sister' volume
3226  //
3227  for (G4int i=0; i<motherLog->GetNoDaughters(); i++)
3228  {
3229  G4VPhysicalVolume* daughter = motherLog->GetDaughter(i);
3230 
3231  if (daughter == plVol) { continue; }
3232 
3233  // Create the transformation for daughter volume and transform point
3234  //
3235  G4AffineTransform Td( daughter->GetRotation(),
3236  daughter->GetTranslation() );
3237  G4ThreeVector md = Td.Inverse().TransformPoint(mp);
3238 
3239  G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid();
3240  if (daughterSolid->Inside(md)==kInside)
3241  {
3242  G4double distout = daughterSolid->DistanceToOut(md);
3243  if (distout > tol)
3244  {
3245  if (verbose) G4cout << G4endl;
3246  if (verbose) G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl
3247  << " Overlap is detected for volume "
3248  << plVol->GetName() << G4endl
3249  << " with " << daughter->GetName() << " volume's"
3250  << G4endl
3251  << " local point " << md << ", "
3252  << "overlapping by at least: " << G4BestUnit(distout,"Length")
3253  << G4endl;
3254  if (verbose) G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup",
3255  JustWarning, "Overlap with volume already placed !");
3256  return true;
3257  }
3258  }
3259 
3260  // Now checking that 'sister' volume is not totally included and
3261  // overlapping. Do it only once, for the first point generated
3262  //
3263  if (n==0)
3264  {
3265  // Generate a single point on the surface of the 'sister' volume
3266  // and verify that the point is NOT inside the current volume
3267 
3268  G4ThreeVector dPoint = daughterSolid->GetPointOnSurface();
3269 
3270  // Transform the generated point to the mother's coordinate system
3271  // and finally to current volume's coordinate system
3272  //
3273  G4ThreeVector mp2 = Td.TransformPoint(dPoint);
3274  G4ThreeVector msMp2 = Tm.Inverse().TransformPoint(mp2);
3275 
3276  if (solid->Inside(msMp2)==kInside)
3277  {
3278  if (verbose) G4cout << G4endl;
3279  if (verbose) G4cout << "WARNING - G4PVPlacement::CheckOverlaps()" << G4endl
3280  << " Overlap is detected for volume "
3281  << plVol->GetName() << G4endl
3282  << " apparently fully encapsulating volume "
3283  << daughter->GetName() << G4endl
3284  << " at the same level !" << G4endl;
3285  if (verbose) G4Exception("G4PVPlacement::CheckOverlaps()", "InvalidSetup",
3286  JustWarning, "Overlap with volume already placed !");
3287  return true;
3288  }
3289  }
3290  }
3291  }
3292 
3293  if (verbose)
3294  {
3295  G4cout << "OK! " << G4endl;
3296  }
3297 
3298  return false;
3299 }
3301  double maxR=-1.0;
3302  for (size_t k=0; k!= fMotherHorn1AllRads.size(); k++) maxR = std::max(fMotherHorn1AllRads[k], maxR);
3303  return maxR;
3304 }
3305 
static QCString name
Definition: declinfo.cpp:673
std::vector< double > fMotherHorn1AllLengths
std::vector< LBNEHornRadialEquation > fHorn1Equations
intermediate_table::iterator iterator
void SetRCoordOutOfTarget(double r) const
std::vector< LBNESurveyedPt >::const_iterator end() const
std::vector< G4double > fTargetHorn1ZPositions
G4double fTargetDSSupportSmallConeSmallOuterRad
const LBNEVolumePlacementData * Find(const G4String &name, const char *motherName, const char *method) const
std::string string
Definition: nybbler.cc:12
std::vector< double > fHornsPolyOuterRadius
std::vector< std::vector< double > > fMotherHornsAllRads
static LBNEVolumePlacements * Instance()
G4double fTargetCTubeReturnDownstrCutAngleStart
std::vector< double > fHornsPolyZStartPos
G4double fTargetCTubeReturnDownstrThickTitanium
G4UImessenger * fPlacementMessenger
intermediate_table::const_iterator const_iterator
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:45
G4double fTargetOutHeContTubeOuterSphericalEndCap
G4double fTargetDSSupportSmallConeLargeOuterRad
std::vector< G4double > fTargetHorn1InnerRadsUpstr
G4double fTargetDSSupportSmallConeSmallInnerRad
std::map< G4String, LBNEVolumePlacementData > fSubVolumes
T abs(T value)
std::vector< double > fParams
static LBNESurveyor * Instance()
bool IsVolumeMisaligned(const std::string &vName) const
G4VPhysicalVolume * fMother
std::vector< G4double > fTargetHorn1Lengths
unsigned int fTargetNumFinsWithWings
std::string getenv(std::string const &name)
Definition: getenv.cc:15
LBNEVolumePlacementData * Create(const G4String &name)
void PlaceFinalUpstrTarget1p2MW(G4PVPlacement *mother)
G4double fTargetDSSupportLargeConeSmallInnerRad
size_t size() const
G4double fTargetDSSupportLargeConeLargeOuterRad
static int max(int a, int b)
void PlaceFinalSmallTarget1p2MW(G4PVPlacement *mother)
verbose
Definition: train.py:477
static LBNEVolumePlacements * fInstance
void Initialize(const G4LogicalVolume *matriarch)
void PlaceRALTGTv1(G4PVPlacement *mother)
G4double fTargetDSSupportLargeConeLargeInnerRad
G4double fTargetCTubeReturnDownstrThickWater
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
std::vector< G4double > fTargetHorn1TransThick
G4PVPlacement * PlaceFinal(const G4String &name, G4VPhysicalVolume *mother)
std::vector< double > fMotherHorn1AllRads
G4double fTargetDSSupportSmallConeLargeInnerRad
const G4LogicalVolume * fTopLogicalVolume
bool CheckOverlaps(const G4PVPlacement *phys, G4int nres, G4double eps, G4bool verbose) const
void PlaceFinalUpstrTarget(G4PVPlacement *mother)
std::vector< G4double > fTargetHorn1InnerRadsDownstr
if(!yymsg) yymsg
G4double fTargetDSSupportLargeConeSmallOuterRad
std::vector< LBNESurveyedPt >::const_iterator begin() const
G4double fTargetCTubeReturnDownstrCutAngleSize
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
LBNEVolumePlacements_AlignmentAlgo fAlignmentModel
QTextStream & endl(QTextStream &s)
std::vector< std::vector< double > > fMotherHornsAllLengths
G4double fTargetOutHeContTubeOuterRadiusTapered