LBNEVolumePlacementsAdd.cc
Go to the documentation of this file.
2 
3 #include "G4UIdirectory.hh"
4 #include "G4UIcmdWithAString.hh"
5 #include "G4UIcmdWithABool.hh"
6 #include "G4UIcmdWithAnInteger.hh"
7 #include "G4UIcmdWithADoubleAndUnit.hh"
8 #include "G4UIcmdWithoutParameter.hh"
9 #include "G4UnitsTable.hh"
10 
11 #include "G4Material.hh"
12 #include "G4Box.hh"
13 #include "G4Tubs.hh"
14 
15 #include "G4Polycone.hh"
16 #include "G4GenericPolycone.hh"
17 #include "G4Trap.hh"
18 #include "G4Cons.hh"
19 #include "G4Torus.hh"
20 #include "G4LogicalVolume.hh"
21 #include "G4ThreeVector.hh"
22 #include "G4PVPlacement.hh"
23 #include "G4SubtractionSolid.hh"
24 #include "G4UnionSolid.hh"
25 #include "G4VisAttributes.hh"
26 #include "globals.hh"
27 #include "G4Transform3D.hh"
28 #include "G4RotationMatrix.hh"
29 #include "G4PVReplica.hh"
30 #include "G4AssemblyVolume.hh"
31 #include "LBNEMagneticField.hh"
32 #include "G4PhysicalVolumeStore.hh"
33 #include "G4LogicalVolumeStore.hh"
34 #include "G4PVPlacement.hh"
35 #include "G4RegionStore.hh"
36 #include "G4SolidStore.hh"
37 #include "G4GeometryManager.hh"
38 #include "G4FieldManager.hh"
39 #include "G4SubtractionSolid.hh"
40 
41 #include "G4RunManager.hh"
42 #include "G4ExceptionSeverity.hh"
43 
44 #include "G4VisExtent.hh"
46 #include "LBNESurveyor.hh"
47 #include "LBNERunManager.hh"
48 #include <cmath>
49 //---------------------------------------------------------------------------//
50 // Additional code for placing the volume and supporting multiple options
51 // We start here with the 1.2 MW plan, as of February 2014.
52 // Paul L. G. Lebrun
53 //---------------------------------------------------------------------------//
55  /*
56  * discard this implementation, we now move to the NuMI style target, Rev 2, with a bigger
57  * Helium cont. vessel.
58  */
59  if (fUseCDR2015Optimized) return; // We don't do this if we document the small cooling pipe 1.2 MW target..
60  //
61  if (fUseNumberOfHornsPoly != 0) {
63  return;
64  } else {
65  return; // July 31 2017: assume here that we deal with the old reference design..
66  }
67  fTargetHeContTubeInnerRadius = 35.2*CLHEP::mm/2.; // LBNE Docdb 8639-v1
68  fTargetCTubeOuterRadius = 3.0*CLHEP::mm;
69  fTargetCTubeInnerRadius = 5.2*CLHEP::mm/2.;
70  fTargetFinHeight = 20.0*CLHEP::mm; // This include the cooling tubes. Total height
71  fTargetFinWidth = 10*CLHEP::mm; // // ajustable via G4 UI data card.
73  fTargetFinWidth /= 2; // we divide by 2:We will place two of them, side by side, center offset of fTargetFinWidth/2.
75  fTargetFinWidthRequired + 0.010*CLHEP::mm);
76  fTargetFinExtraWidth = -1.0*CLHEP::mm; // No additional piece on the side, by defaul
77  fBaffleInnerRadius = 17.0*CLHEP::mm/2.;
78  //
79  // The longitudinal segmentation of the target will be unchanged.
80  // April 11 2014 : set the default the target length outside Horn1 to 450 mm.
81  // I put it to 500 mm originally because of the presumed need for more tolerance
82  // near the neck, but 450 mm. is good enough after revision of the Horn1 geometry..
83  //
84 // fTargetLengthIntoHorn = fTargetSLengthGraphite - 500.*CLHEP::mm + 25.3; // Integration drawing 8875.000-ME-363028
86  // Will be revised with the Conceptual Drawing. .. // Integration drawing 8875.000-ME-363028
87  fHorn1RadialSafetyMargin = 0.25*CLHEP::mm;
88  fRotVertical.set(CLHEP::HepRotationX(-90.0*CLHEP::deg));
89  fTargetFinWWingRadius = 12.0*CLHEP::mm;
90  fUseRoundedTargetFins = (fUse1p2MW) ? true : false; // If need be, we "back implement" for the 700 kW option.
91  fTargetNumFinsWithWings = 0; // We had no wings for the idealistic version of the "optimized" sequence.
92 
93 }
95 //
96 // taken from release v3r2p6, December 2016. A re-adaptation.. Note the change in fTargetHeContTubeInnerRadius
97 //
98  fTargetSLengthGraphite= 953.8*CLHEP::mm;
99  std::cerr << " Adapting for the NuMI target, short version length of graphite "
101  fTargetHeContTubeInnerRadius = 35.2*CLHEP::mm/2.; // LBNE Docdb 8639-v1
102  fTargetCTubeOuterRadius = 3.0*CLHEP::mm;
103  fTargetCTubeInnerRadius = 5.2*CLHEP::mm/2.;
104  fTargetFinHeight = 2.0*(13.3675 - 3.0 + 0.005)*CLHEP::mm; // This excludes the cooling tubes.
105  fTargetFinWidth = 10*CLHEP::mm; // // ajustable via G4 UI data card.
106  fTargetFinWidth /= 2; // we divide by 2:We will place two of them, side by side, center offset of fTargetFinWidth/2.
108  fTargetFinContainerWidth = 2.0*fTargetCTubeOuterRadius + 0.010*CLHEP::mm;
109  fTargetFinExtraWidth = -1.0*CLHEP::mm; // No additional piece on the side, by defaul
110  fBaffleInnerRadius = 17.0*CLHEP::mm/2.;
111  //
112  // The longitudinal segmentation of the target will be unchanged.
113  // April 11 2014 : set the default the target length outside Horn1 to 450 mm.
114  // I put it to 500 mm originally because of the presumed need for more tolerance
115  // near the neck, but 450 mm. is good enough after revision of the Horn1 geometry..
116  //
117 // fTargetLengthIntoHorn = fTargetSLengthGraphite - 500.*mm + 25.3; // Integration drawing 8875.000-ME-363028
118  fTargetLengthIntoHorn = fTargetSLengthGraphite - 450.*CLHEP::mm + 25.3*CLHEP::mm; // Integration drawing 8875.000-ME-363028
119  // The above is subject to change///
120  fHorn1RadialSafetyMargin = 0.25*CLHEP::mm;
121  fRotVertical.set(CLHEP::HepRotationX(-90.0*CLHEP::deg));
122  fUseRoundedTargetFins = (fUse1p2MW) ? true : false; // If need be, we "back implement" for the 700 kW option.
123 }
124 
126 //
127 // taken from release v3r2p6, December 2016. A re-adaptation.. Note the change in fTargetHeContTubeInnerRadius
128 //
129  std::cerr << " Adapting for the RAL target, length of graphite "
132 
133  //Dimensions for the outer helium containment tube, which is tapered
134 
135  fTargetOutHeContTubeInnerRadius = 37.5*CLHEP::mm; // LBNE Docdb 8639-v1
136  fTargetOutHeContTubeOuterRadius = 38*CLHEP::mm; // LBNE Docdb 8639-v1
137  fTargetOutHeContTubeInnerRadiusTapered = 27.22*CLHEP::mm;
138  fTargetOutHeContTubeOuterRadiusTapered = 27.72*CLHEP::mm;
139 
140 
141  fTargetOutHeContTubeTaperedLength = 1094.49*CLHEP::mm;
142  fTargetOutHeContTubeStraightLength = 1170.51*CLHEP::mm;
143  fTargetCTubeLength = 2225*CLHEP::mm;
144 
145 
148  fTargetDistFlangeToTargetStart = 55*CLHEP::mm;
149  fSimpleTargetRadius = 8*CLHEP::mm; // not used if box.
150 
151  //Smaller helium containment tube housing the target
152  fTargetCTubeInnerRadius = 15*CLHEP::mm;
153  fTargetCTubeOuterRadius = 15.5*CLHEP::mm;
154 
155  //Section connecting the bafflet to the target
156  fTargetHeContTubeSmallConeLength = 28.82*CLHEP::mm;
157  fTargetHeContTubeSmallConeInnerRad = 22.5*CLHEP::mm;
158  fTargetHeContTubeSmallConeOuterRad = 23.5*CLHEP::mm;
159  fTargetHeContTubeSmallCylLength = 22.5*CLHEP::mm;
160 
161  //Large conical section extending upstream from the inner helium containment tube
162  fTargetHeContTubeLargeConeInnerRad = 52.5*CLHEP::mm;
163  fTargetHeContTubeLargeConeOuterRad = 53*CLHEP::mm;
164  fTargetHeContTubeLargeConeLength = 109.32*CLHEP::mm;
165 
166  fTargetHeContTubeBaffletLength = 120*CLHEP::mm;
167  fTargetBaffletOutRadius = 14*CLHEP::mm;
168  fTargetBaffletLengthNoFlange = 105*CLHEP::mm;
169  fTargetBaffletFlangeLength = 15*CLHEP::mm;
170  fTargetHeContTubeColdHeCurvature = 38*CLHEP::mm;
171 
172  //DSSupport Structure
173  fTargetDSSupportConnRing = 12*CLHEP::mm;
174  fTargetDSSupportAlRingThickness = 1*CLHEP::mm;
175  fTargetDSSupportAlRingInnerRad = 24.988*CLHEP::mm;
176 
177  //DSSupport double cone structure where "Small cone" indicates the right cone and "large cone" indicates the left cone in this dual cone structure
178  fTargetDSSupportSmallConeLength = 6.9*CLHEP::mm;
179  fTargetDSSupportSmallConeSmallInnerRad = 25.4*CLHEP::mm;
183 
185  fTargetDSSupportLargeConeSmallOuterRad = 30.3384274344*CLHEP::mm;
187  fTargetDSSupportLargeConeLargeOuterRad = 40.3476088767*CLHEP::mm;
188  fTargetDSSupportLargeConeLength = 27.5*CLHEP::mm;
189 
190  fTargetDSSupportOuterRingInnerRad = 677*CLHEP::mm;
191  fTargetDSSupportOuterRingOuterRad = 697*CLHEP::mm;
192  fTargetDSSupportOuterRingLength = 20*CLHEP::mm;
193 
194  fTargetFinHeight = NAN; //2.0*(15 - 8 + 0.005)*CLHEP::mm; // This excludes the cooling tubes.
195  fTargetFinWidth = NAN;//10*CLHEP::mm; // // ajustable via G4 UI data card.
196  // fTargetFinWidth /= 2; // we divide by 2:We will place two of them, side by side, center offset of fTargetFinWidth/2.
198  // fTargetFinContainerWidth = 2.0*fTargetCTubeOuterRadius + 0.010*CLHEP::mm;
199  // fTargetFinExtraWidth = -1.0*CLHEP::mm; // No additional piece on the side, by defaul
200  fBaffleInnerRadius = 17.0*CLHEP::mm;
201  //
202  // The longitudinal segmentation of the target will be unchanged.
203  // April 11 2014 : set the default the target length outside Horn1 to 450 mm.
204  // I put it to 500 mm originally because of the presumed need for more tolerance
205  // near the neck, but 450 mm. is good enough after revision of the Horn1 geometry..
206  //
207 // fTargetLengthIntoHorn = 55. ; // Integration drawing 8875.000-ME-363028
208  fTargetLengthIntoHorn = 55.*CLHEP::mm; //+ 25.3*CLHEP::mm; // Integration drawing 8875.000-ME-363028
209  // The above is subject to change
210  fHorn1RadialSafetyMargin = 0.25*CLHEP::mm;
211  fRotVertical.set(CLHEP::HepRotationX(-90.0*CLHEP::deg));
212 // fUseRoundedTargetFins = (fUse1p2MW) ? true : false; // If need be, we "back implement" for the 700 kW option.
213 }
214 
215 
217 
218  std::cerr << " Adapting for the NuMI target, long version, as Optimized horns are requested. " << std::endl;
219 
220  fTargetCTubeOuterRadius = 4.0*CLHEP::mm;
222  fTargetHeContTubeThickness = 1.0*CLHEP::mm;
224 // fTargetFinWidth = 13.4*CLHEP::mm; // // ajustable via G4 UI data card, but let us stick with this model
225  fTargetFinWidth = 10.0*CLHEP::mm; // For now... This does not
227  fTargetFinWidth /= 2.; // We divide by two, because we create left/right module, to avoid doing multiple
228  // volume subtractions.
229  fTargetFinContainerWidth = 16.125*CLHEP::mm; // This is to include the 4mm Outer Radius tubes.
230  // This might not be use anylonger, the volume hierarchy is still in the work.
231 // fTargetFinHeight = 24.0*CLHEP::mm; // increased size, per Cory e-mail, Nov 5 2016.
232  fTargetFinHeight = 26.0*CLHEP::mm; // increased size, again, per Cory & Jim H., Nov 11 2016.
233  fTargetFinHeight /= 2.; // Also divide by two, same reason as for along the X axis.
234  fTargetSLengthGraphite = 2.01*CLHEP::meter; // include specing. nominally, 2 m long of graphite.
235  fTargetSLength = 2243.0*CLHEP::mm; // include the empty (beside Helium) section, ~ 20 cm long
236  fTargetNumFins = 100; // 100 fins 20 mm length
237  fTargetFinWWingRadius = 13.0*CLHEP::mm;
238  fUseRoundedTargetFins = true; // for checking the geometry of the fins, avoiding complication for now..
239  std::cerr << " .... done target for HornA Rev2, fTargetLengthIntoHorn "
240  << fTargetLengthIntoHorn << " fTargetLengthOutsideHorn " << fTargetLengthOutsideHorn << std::endl;
241 }
242 //
243 // Clone of v3r0p12 PlaceFinalUpstrTarget.
244 // Cloning is always a bad idea with respect to maintenance, but it is somewhat unlikely
245 // that we will have to maintain the previous iteration.
246 //
247 // August 2014: Avoid now to split the target, as the mother volume for Horn1 is a G4Polycone.
248 // Thus, the "Upstr" substring in the name of this method is superfluous, but kept for backwards readability.
249 //
251 
252  // Define in LBNEDetectorConstruction..
253  //Start by defining the top level of the target container volume, which includes the canister (TargetUpstrM0)
254  // and the target section which is outside Horn1 (TargetUpstrM1)
255 
256  //
257  // We leave all the volume that are upstream of the first graphite target segment identical..
258  // We have no mechanicl drawing for this part yet.
259  //
260  Create("TargetUpstrMTop");
261  G4PVPlacement *vMTop = PlaceFinal(std::string("TargetUpstrMTop"), mother); // Obsolete.. But keep for reference
263  G4Exception("LBNEVolumePlacements::PlaceFinalUpstrTarget1p2MW", "No target! ", JustWarning, "Target has been removed");
264  return;
265  }
266 
268  Create("TargetNoSplitM1");
269  G4PVPlacement *vMt1 = PlaceFinal(std::string("TargetNoSplitM1"), fTargetHorn1HallPhysPtr);
270 
271  Create("TargetNoSplitHeContainer");
272  G4PVPlacement *vMt2 = PlaceFinal(std::string("TargetNoSplitHeContainer"), vMt1);
273 
276  } else {
278  }
279  return;
280  }
281 
282 // std::cerr << " TargetUpstrMTop created and placed ... " << std::endl;
283  LBNEVolumePlacementData *plM0 = Create("TargetUpstrM0");
284 // std::cerr << " TargetUpstrM0 created ... " << std::endl;
285 // std::cerr << " TargetUpstrM1 created ... " << std::endl;
286  G4PVPlacement *vM0 = PlaceFinal(std::string("TargetUpstrM0"), vMTop);
287  std::cerr << " TargetUpstrM0 placed ... " << std::endl;
288 
289  // Place the target module, e.g. the spherical array target (SAT) setup
290  std::cout<<"fUseTargetModule = "<<(int)fUseTargetModule<<std::endl;
291  std::cout<<"fUseTarget2Module = "<<(int)fUseTarget2Module<<std::endl;
292  if (fUseTargetModule) {
295  return;
296  }
297 
298  G4String targetTopStr; LBNEVolumePlacementData *plM1; G4PVPlacement *vM1=0;
299  targetTopStr = std::string("TargetNoSplitM1");
300  plM1 = Create(targetTopStr);
301  vM1 = PlaceFinal(targetTopStr, fTargetHorn1HallPhysPtr);
302  std::cerr << " .. " << targetTopStr
303  << " is now placed in PlaceFinalUpstrTarget1p2MW...in fTargetHorn1HallPhysPtr " << std::endl;
304  std::string tUpUp("TargetUpstrUpstr");
305  Create(tUpUp + std::string("Plate"));
306  Create(tUpUp + std::string("Can"));
307  Create(tUpUp + std::string("CanEndPlate"));
308  Create(tUpUp + std::string("DwstrFlange"));
309  Create(tUpUp + std::string("CoolingTube"));
310  Create(tUpUp + std::string("CoolingTubeWater"));
311  Create(tUpUp + std::string("SupportBlockTopLeft"));
312  Create(tUpUp + std::string("SupportBlockBottomLeft"));
313  Create(tUpUp + std::string("SupportBlockRight"));
314  Create(tUpUp + std::string("SupportSleeve"));
315  // None of these are surveyable, position is fixed.
316  PlaceFinal(tUpUp + std::string("Plate"), vM0);
317  PlaceFinal(tUpUp + std::string("Can"), vM0);
318  PlaceFinal(tUpUp + std::string("CanEndPlate"), vM0);
319  PlaceFinal(tUpUp + std::string("DwstrFlange"), vM0);
320  // Cooling tubes: two copies. This breaks the Placement data model. Never mind, assume here that misalignment
321  // of these cooling tube has negligible effect on the physics.
322 
323  G4String nameTmp5(tUpUp + std::string("CoolingTube"));
325  LBNEVolumePlacementData &infoTmp = itTmp->second;
326  G4ThreeVector posTmp;
327  posTmp[0] = 0.;
328  posTmp[1] = 0.5*fTargetFinHeight;
329  posTmp[2] = -1.0*plM0->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
331  fTargetDownstrCanFlangeThick + fTargetFlangeThick - infoTmp.fParams[2]/2 - 1.0*CLHEP::mm;
332  G4String vpNameTmp5(nameTmp5);
333 // std::cerr << " Position for " << vpNameTmp5+G4String("_PTop") << " X = "
334 // << posTmp[0] << " Y " << posTmp[1] << " Z " << posTmp[2] << std::endl;
335  G4PVPlacement *vCoolingTubeTop = new G4PVPlacement((G4RotationMatrix *) 0,
336  posTmp, infoTmp.fCurrent, vpNameTmp5+G4String("_PTop"),
337  vM0->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC );
338  posTmp[1] = -0.5*fTargetFinHeight;
339  G4PVPlacement *vCoolingTubeBottom = new G4PVPlacement((G4RotationMatrix *) 0,
340  posTmp, infoTmp.fCurrent, vpNameTmp5+std::string("_PBottom"),
341  vM0->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
342 
343  PlaceFinal(tUpUp + std::string("CoolingTubeWater"), vCoolingTubeTop);
344  PlaceFinal(tUpUp + std::string("CoolingTubeWater"), vCoolingTubeBottom); // Those are the old tubes...
345  // Incorrect, as they are now double... To be fixed, it is deemed necessary.. (all these are upstream of the first segment. )
346  PlaceFinal(tUpUp + std::string("SupportBlockTopLeft"), vM0);
347  PlaceFinal(tUpUp + std::string("SupportBlockBottomLeft"), vM0);
348  PlaceFinal(tUpUp + std::string("SupportBlockRight"), vM0);
349  PlaceFinal(tUpUp + std::string("SupportSleeve"), vM0);
350  // We need three support/alignment rods. Identical volume, but at different locations.
351  std::string nameTmp10(tUpUp + std::string("SupportRod"));
352  Create(nameTmp10);
353  itTmp = fSubVolumes.find(nameTmp10);
354  infoTmp = itTmp->second;
355  // Top Left alignment/support rod.
356  posTmp[0] = -20.5*CLHEP::mm; // Again, accurate to +- 1 mm or so.
357  posTmp[1] = 24.0*CLHEP::mm;
358  posTmp[2] = -1.0*plM0->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
360  fTargetDownstrCanFlangeThick - infoTmp.fParams[2]/2 - 1.0*CLHEP::mm;
361  G4String vpNameTmp10(nameTmp10);
362  new G4PVPlacement((G4RotationMatrix *) 0,
363  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PTopLeft"),
364  vM0->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
365  posTmp[0] = -15.5*CLHEP::mm; // Again, accurate to +- 1 mm or so.
366  posTmp[1] = -36.0*CLHEP::mm;
367  new G4PVPlacement((G4RotationMatrix *) 0,
368  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PBottomLeft"),
369  vM0->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
370  posTmp[0] = 33.0*CLHEP::mm; // Again, accurate to +- 1 mm or so.
371  posTmp[1] = 5.0*CLHEP::mm;
372  new G4PVPlacement((G4RotationMatrix *) 0,
373  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PRight"),
374  vM0->GetLogicalVolume(), false, 2, fCheckVolumeOverLapWC);
375 
376 // Horizontal fin for beam alignment. Most important thing in the canister, in terms of material budget
377 // August 1/2 2016 : Allow for the capability to remove the horizontal target, as it confuses the comparison of
378 // the neutrino flux, simple optimized horns vs (evolving) conceptual horns, circa May/June 2016.
379 //
381  std::string nameTmp11("TargetFinHorizontal");
382  Create(nameTmp11);
383  PlaceFinal(nameTmp11, vM0);
384  }
385  // Done with the target canister..Now assemble the upstream part of the target it self. (Upstream of the horn1)
386  std::string tUpDown("TargetUpstrDownstr"); // Obsolete if Conceptual Horn A.
387  tUpDown = std::string("TargetNoSplit");
388  Create(tUpDown + std::string("HeContainer"));
389  G4PVPlacement *vHeTube = PlaceFinal(tUpDown + std::string("HeContainer"), vM1); // Surveyable
390  LBNEVolumePlacementData *plHelium = Create(tUpDown + std::string("Helium"));
391  G4PVPlacement *vHelium = PlaceFinal(tUpDown + std::string("Helium"), vHeTube); // Fixed
392  if (fUseMultiSphereTarget) {
393  PlaceFinalMultiSphereTarget(plHelium, vHelium);
394  return;
395  }
396  //
397  // Define a container volume to avoid overloading the volume tree.
398  //
399  LBNEVolumePlacementData *plTargetSegmentBox = Create(G4String("TargetConceptHeliumBoxSegment"));
400  LBNEVolumePlacementData *plTargetSegmentTubWWings = Create(G4String("TargetConceptHeliumTubWWings"));
401  std::cerr << " Defined the container for target fin + section of cooling tube, name "
402  << plTargetSegmentBox->fCurrent->GetName() << std::endl;
403  std::cerr << " Defined the container for winged target fin + section of cooling tube, name "
404  << plTargetSegmentTubWWings->fCurrent->GetName() << std::endl;
405  G4String nameTgtUpDownSegLeft("");
406  G4String nameTgtUpDownSegRight("");
407  LBNEVolumePlacementData *plTargetCoolingTube = 0;
408  LBNEVolumePlacementData *plTargetCoolingTubeWater = 0;
409 // LBNEVolumePlacementData *plTargetGenSegmentLeft = 0;
410  plTargetCoolingTube = Create(G4String("TargetNormalCoolingTube"));
411  plTargetCoolingTubeWater = Create(G4String("TargetNormalCoolingTubeWater"));
412  LBNEVolumePlacementData *plTargetCoolingTubeWW = Create(G4String("TargetWWingsCoolingTube"));
413  LBNEVolumePlacementData *plTargetCoolingTubeWWWater = Create(G4String("TargetWWingsCoolingTubeWater"));
414 // nameTgtUpDownSegLeft = G4String("TargetNoSplitSegmentLeft");
415 // plTargetGenSegmentLeft = Create(nameTgtUpDownSegLeft);
416 // nameTgtUpDownSegRight = G4String("TargetNoSplitSegmentRight");
417 // LBNEVolumePlacementData *plTargetUpstrDownstrSegmentRight = Create(nameTgtUpDownSegRight);
418  std::vector< std::string > namesSegment(4,"");
419  namesSegment[0] = std::string("TargetFinVertTargetCutV2UpLeft");
420  namesSegment[1] = std::string("TargetFinVertTargetCutV2UpRight");
421  namesSegment[2] = std::string("TargetFinVertTargetCutV2DwnLeft");
422  namesSegment[3] = std::string("TargetFinVertTargetCutV2DwnRight");
423  std::cerr << "LBNEVolumePlacements::PlaceFinalUpstrTarget1p2MW, central width " << fTargetFinWidth << std::endl;
424  LBNEVolumePlacementData *plTargetTargetCutV2UpLeft = Create(namesSegment[0]);
425  LBNEVolumePlacementData *plTargetTargetCutV2UpRight = Create(namesSegment[1]);
426  LBNEVolumePlacementData *plTargetTargetCutV2DwnLeft = Create(namesSegment[2]);
427  LBNEVolumePlacementData *plTargetTargetCutV2DwnRight = Create(namesSegment[3]);
428  G4PVPlacement *vSegTgt[4];
429 // G4PVPlacement *vSegTgtWWing[4]; // might be needed if we cut cornors on the wings..
430  double zCoordTmp = -1.0*plM1->fParams[2]/2.0;
431  zCoordTmp += 0.050*CLHEP::mm;
432  int copyNumberT = 0;
433  int numSegHere = fTargetNumFins;
434  std::cerr << " LBNEVolumePlacements::PlaceFinalUpstrTarget1p2MW, numSegHere "
435  << numSegHere << " Number of segment with wings " << fTargetNumFinsWithWings << std::endl;
436  //
437  // Define the target fins with wings here
438  //
439  LBNEVolumePlacementData *plTargetTargetWWingUpLeft = 0;
440  LBNEVolumePlacementData *plTargetTargetWWingUpRight = 0;
441  LBNEVolumePlacementData *plTargetTargetWWingDwnLeft = 0;
442  LBNEVolumePlacementData *plTargetTargetWWingDwnRight = 0;
443  if (fTargetNumFinsWithWings != 0) { // fins with so-called wings.
444  G4ThreeVector zeroTmp(0., 0., 0.);
445  plTargetTargetWWingUpLeft = Create(G4String("TargetWWingCylinderUpLeft"));
446  std::cerr << " plTargetTargetWWingUpLeft.... defined ... name "
447  << plTargetTargetWWingUpLeft->fCurrent->GetName() << std::endl;
448  new G4PVPlacement((G4RotationMatrix *) 0,
449  zeroTmp, plTargetTargetWWingUpLeft->fCurrent,
450  std::string("TargetWWingCylinderUpLeft_P"),
451  plTargetSegmentTubWWings->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
452  std::cerr << " plTargetTargetWWingUpLeft.... Placed ... name "
453  << plTargetTargetWWingUpLeft->fCurrent->GetName() << std::endl;
454  plTargetTargetWWingUpRight = Create(G4String("TargetWWingCylinderUpRight"));
455  new G4PVPlacement((G4RotationMatrix *) 0,
456  zeroTmp, plTargetTargetWWingUpRight->fCurrent,
457  std::string("TargetWWingCylinderUpRight_P"),
458  plTargetSegmentTubWWings->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
459 
460  plTargetTargetWWingDwnLeft = Create(G4String("TargetWWingCylinderDwnLeft"));
461  new G4PVPlacement((G4RotationMatrix *) 0,
462  zeroTmp, plTargetTargetWWingDwnLeft->fCurrent,
463  std::string("TargetWWingCylinderDwnLeft_P"),
464  plTargetSegmentTubWWings->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
465  plTargetTargetWWingDwnRight = Create(G4String("TargetWWingCylinderDwnRight"));
466  new G4PVPlacement((G4RotationMatrix *) 0,
467  zeroTmp, plTargetTargetWWingDwnRight->fCurrent,
468  std::string("TargetWWingCylinderDwnRight_P"),
469  plTargetSegmentTubWWings->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
470 
471 
472  }
473  // normal fins. Thinner, to let the pions go out of the target.
474  {
475  posTmp[0] = -0.5*plTargetTargetCutV2UpLeft->fParams[0] - 0.003*CLHEP::mm;
476  posTmp[1] = 0.5*plTargetTargetCutV2UpLeft->fParams[1] + 0.003*CLHEP::mm;
477  posTmp[2] = 0.;
478  std::cerr << " Placing target segments, no wings ... in volume = " << plTargetSegmentBox->fCurrent->GetName() << std::endl;
479  vSegTgt[0] = new G4PVPlacement((G4RotationMatrix *) 0,
480  posTmp, plTargetTargetCutV2UpLeft->fCurrent,
481  plTargetTargetCutV2UpLeft->fCurrent->GetName()+std::string("_P"),
482  plTargetSegmentBox->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
483  posTmp[0] *= -1.0;
484  vSegTgt[1] = new G4PVPlacement((G4RotationMatrix *) 0,
485  posTmp, plTargetTargetCutV2UpRight->fCurrent,
486  plTargetTargetCutV2UpRight->fCurrent->GetName()+std::string("_P"),
487  plTargetSegmentBox->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
488  posTmp[0] = -0.5*plTargetTargetCutV2UpLeft->fParams[0] - 0.003*CLHEP::mm;
489  posTmp[1] = -0.5*plTargetTargetCutV2UpLeft->fParams[1] - 0.003*CLHEP::mm;
490  vSegTgt[2] = new G4PVPlacement((G4RotationMatrix *) 0,
491  posTmp, plTargetTargetCutV2DwnLeft->fCurrent,
492  plTargetTargetCutV2DwnLeft->fCurrent->GetName() +std::string("_P"),
493  plTargetSegmentBox->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
494  posTmp[0] *= -1.0;
495  vSegTgt[3] = new G4PVPlacement((G4RotationMatrix *) 0,
496  posTmp, plTargetTargetCutV2DwnRight->fCurrent,
497  plTargetTargetCutV2DwnRight->fCurrent->GetName()+std::string("_P"),
498  plTargetSegmentBox->fCurrent, false, copyNumberT, fCheckVolumeOverLapWC);
499  }
500  G4LogicalVolume *motherForCoolingTube = 0; // default fins..
501  G4LogicalVolume *theCoolingTubeV = 0;
502 // Cooling tubes. For bith kind of fins (w/o wings)
503 
504  for (int kType=0; kType != 2; kType++) {
505  if ((fTargetNumFinsWithWings == 0) && (kType == 1)) break;
506  motherForCoolingTube = plTargetSegmentTubWWings->fCurrent;
507  switch (kType) {
508  case 0: // Normal fins..
509  motherForCoolingTube = plTargetSegmentBox->fCurrent;
510  theCoolingTubeV = plTargetCoolingTube->fCurrent;
511  break;
512  case 1:
513  motherForCoolingTube = plTargetSegmentTubWWings->fCurrent;
514  theCoolingTubeV = plTargetCoolingTubeWW->fCurrent;
515  break;
516  }
517  posTmp[0] = -fTargetCTubeOuterRadius - 0.575*CLHEP::mm;
518  // for brazing.
519  posTmp[1] = fTargetFinHeight + 0.050*CLHEP::mm;
520  posTmp[2] = 0.;
521  std::cerr << " Placing Cooling tube... At XYZ = " << posTmp[0]<< "/" << posTmp[1] << "/" << posTmp[2] << " name "
522  << theCoolingTubeV->GetName() << std::endl;
523  std::cerr << " In volume " << motherForCoolingTube->GetName()
524  << " placing " << theCoolingTubeV->GetName() << std::endl;
525  new G4PVPlacement((G4RotationMatrix *) 0,
526  posTmp, theCoolingTubeV,
527  theCoolingTubeV->GetName()+ std::string("UpLeft")+ std::string("_P"),
528  motherForCoolingTube, false, copyNumberT, fCheckVolumeOverLapWC);
529  posTmp[0] *= -1.0;
530  new G4PVPlacement((G4RotationMatrix *) 0,
531  posTmp, theCoolingTubeV,
532  theCoolingTubeV->GetName()+ std::string("UpRight") + std::string("_P"),
533  motherForCoolingTube, false, copyNumberT, fCheckVolumeOverLapWC);
534  posTmp[0] *= -1.;
535  posTmp[1] *=-1.;
536  new G4PVPlacement((G4RotationMatrix *) 0,
537  posTmp, theCoolingTubeV,
538  theCoolingTubeV->GetName()+ std::string("DwnLeft") + std::string("_P"),
539  motherForCoolingTube, false, copyNumberT, fCheckVolumeOverLapWC);
540  posTmp[0] *= -1.0;
541  new G4PVPlacement((G4RotationMatrix *) 0,
542  posTmp, theCoolingTubeV,
543  theCoolingTubeV->GetName()+ std::string("DwnRight") + std::string("_P"),
544  motherForCoolingTube, false, copyNumberT, fCheckVolumeOverLapWC);
545  } // on cooling tube type.
546 //
547 // Cooling tubes water. On placement should do it...for normal wings, not quite ready for prime time.
548 //
549  G4ThreeVector posTmpWater(0., 0., 0.);
550  new G4PVPlacement((G4RotationMatrix *) 0,
551  posTmpWater, plTargetCoolingTubeWater->fCurrent,
552  std::string("TargetFinCoolingTubeWater_P"),
553  plTargetCoolingTube->fCurrent , false, 0, fCheckVolumeOverLapWC);
554  if (fTargetNumFinsWithWings != 0) {
555  new G4PVPlacement((G4RotationMatrix *) 0,
556  posTmpWater, plTargetCoolingTubeWWWater->fCurrent,
557  std::string("TargetFinWWingsCoolingTubeWater_P"),
558  plTargetCoolingTubeWW->fCurrent , false, 0, fCheckVolumeOverLapWC);
559  }
560 //
561 // New Rounded fins. The curvature of the previous version was wrong, I suspect.
562 // Also, the cut is not strictly cylindical, probably. Just take a little piece off make it a box, to be made of helium,
563 // in the side of the
564 //
565  if (fUseRoundedTargetFins) {
566  const double widthCornerOff = fTargetFinWidth * std::sqrt(1.0 - M_PI/4); // See drawing from Cory, Nov 5.
567  double heightCornerOff = plTargetTargetCutV2UpLeft->fParams[1]- fTargetCTubeOuterRadius - 0.250*CLHEP::mm;
568  // Overly complicated... Not roubst against change on the target fin width.
569 // double ddRC = 0.;
570 // if (fTargetFinWidth < 2.0*fTargetCTubeOuterRadius) {
571 // const double ddRC1 = std::abs(0.575*CLHEP::mm + fTargetCTubeOuterRadius - fTargetFinWidth);
572 // const double ddRC2 = std::abs(0.575*CLHEP::mm + fTargetCTubeOuterRadius - fTargetFinWidth - widthCornerOff);
573 // ddRC = std::min(ddRC1, ddRC2);
574 // const double thetaddRC = std::asin(ddRC/fTargetCTubeOuterRadius);
575 //
576 // heightCornerOff -= fTargetCTubeOuterRadius*std::cos(thetaddRC);
577 // }
578  const double lengthCornerOff = widthCornerOff; // made up number... Need to check with Jim H.
579  std::cerr << " Dimensions for cut corners Width " << widthCornerOff
580  << " height " << heightCornerOff << std::endl;
581  std::string aNameCornerOff = std::string("TargetRoundOffCorner");
582  G4Box* aBoxCornerOff = new G4Box(aNameCornerOff,
583  0.5*widthCornerOff, 0.5*heightCornerOff, 0.5*lengthCornerOff);
584  G4LogicalVolume *aBoxCornerOffLV =
585  new G4LogicalVolume(aBoxCornerOff,
586  G4Material::GetMaterial(std::string("HeliumTarget")), aNameCornerOff);
587  // Adjust the size of these little cuts.
588  double xOffTmpUpR = 0.5*plTargetTargetCutV2UpLeft->fParams[0] - 0.5*widthCornerOff - 0.005*CLHEP::mm;
589  double yOffTmpUpR = -0.5*plTargetTargetCutV2UpLeft->fParams[1] + 0.5*heightCornerOff + 0.005*CLHEP::mm;
590  std::cerr << " .... Position of these in CutV2 volumes X = " << xOffTmpUpR << " Y = " << yOffTmpUpR << std::endl;
591  for (size_t kCorners=0; kCorners !=4; kCorners++) {
592  double xOffTmp = xOffTmpUpR; double yOffTmp = yOffTmpUpR;
593  switch (kCorners) {
594  case 0:
595  xOffTmp *=-1.;
596  break;
597  case 1:
598  break;
599  case 2:
600  xOffTmp *=-1.;
601  yOffTmp *=-1.;
602  break;
603  case 3:
604  yOffTmp *=-1.;
605  break;
606  }
607 
608  const double zOffTmp = plTargetTargetCutV2UpLeft->fParams[2]/2. - 0.5*lengthCornerOff - 0.002*CLHEP::mm;
609  G4ThreeVector posTmpOffC(xOffTmp, yOffTmp, -1.0*zOffTmp);
610  std::cerr << " ...locate cut corners Width X = " << xOffTmp << " Y " << yOffTmp << " Z " << zOffTmp << std::endl;
611  new G4PVPlacement((G4RotationMatrix *) 0,
612  posTmpOffC, aBoxCornerOffLV,
613  aNameCornerOff + std::string("_PUpst"),
614  vSegTgt[kCorners]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
615  posTmpOffC[2] *= -1.0;
616  new G4PVPlacement((G4RotationMatrix *) 0,
617  posTmpOffC, aBoxCornerOffLV,
618  aNameCornerOff + std::string("_PDwnst"),
619  vSegTgt[kCorners]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
620  }
621  } // Rounding off corners.
622  //
623  // Now install these segment in the Helium
624  //
625  double zLastSegment = 0.;
626  std::cerr << "Using the container for target fin + section of cooling tube, name "
627  << plTargetSegmentBox->fCurrent->GetName() << std::endl;
628  for (unsigned int iSeg=0; iSeg != static_cast<unsigned int>(numSegHere); iSeg++, copyNumberT++) { //
629 
630  std::ostringstream cNumStrStr; cNumStrStr << "_Seg" << iSeg << "_P";
631  posTmp[0] = 0.;
632  posTmp[1] = 0.;
633  posTmp[2] = zCoordTmp
634  + plTargetSegmentBox->fParams[2]/2. + iSeg*(fTargetFinLength + fTargetFinSpacingLength);
635  zLastSegment = posTmp[2];
636  if (iSeg < fTargetNumFinsWithWings) {
637 // std::cerr << " Placing target with wings segments... At Z = " << posTmp[2] << std::endl;
638  new G4PVPlacement((G4RotationMatrix *) 0,
639  posTmp, plTargetSegmentTubWWings->fCurrent,
640  std::string("TargetWWingCylinder")+cNumStrStr.str(),
641  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
642  std::cerr << " The cooling tube volume name is " << theCoolingTubeV->GetName() << std::endl;
643  } else {
644  //
645  // Place with no misalignment...If segments are misaligned with respecto each other,s
646  // Need to use the LBNEVolumePlacement class.
647  //
648 // std::cerr << " Placing target segments, no wings ... At Z = " << posTmp[2] << std::endl;
649  new G4PVPlacement((G4RotationMatrix *) 0,
650  posTmp, plTargetSegmentBox->fCurrent,
651  plTargetSegmentBox->fCurrent->GetName()+cNumStrStr.str(),
652  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
653  }
654  } // on segments.
655 
656  {
657  // Now the end
658  LBNEVolumePlacementData *plCoolingTubeReturnLeft = Create("TargetCoolingTubeReturnLoopLeft");
659  LBNEVolumePlacementData *plCoolingTubeReturnRight = Create("TargetCoolingTubeReturnLoopRight");
660  LBNEVolumePlacementData *plCoolingTubeReturnLeftWater = Create("TargetCoolingTubeReturnLoopLeftWater");
661  LBNEVolumePlacementData *plCoolingTubeReturnRightWater = Create("TargetCoolingTubeReturnLoopRightWater");
662  G4ThreeVector zeroTmp(0., 0., 0.);
663  new G4PVPlacement((G4RotationMatrix *) 0,
664  zeroTmp, plCoolingTubeReturnLeftWater->fCurrent,
665  G4String("TargetCoolingTubeReturnLoopLeftWater_P"),
666  plCoolingTubeReturnLeft->fCurrent , false, 0, fCheckVolumeOverLapWC);
667 
668  new G4PVPlacement((G4RotationMatrix *) 0,
669  zeroTmp, plCoolingTubeReturnRightWater->fCurrent,
670  G4String("TargetCoolingTubeReturnLoopRightWater_P"),
671  plCoolingTubeReturnRight->fCurrent , false, 0, fCheckVolumeOverLapWC);
672 
673  posTmp[0] = -0.350*CLHEP::mm - fTargetCTubeOuterRadius; // extra 100 microns for (unimplemented) connection.
674  posTmp[1] = 0.;
675  posTmp[2] = plHelium->fParams[2]/2 -
677  posTmp[2] = zLastSegment + plCoolingTubeReturnLeft->fParams[2] + 0.1*fTargetFinLength; // 10% of fin length to avoid clash.
678  // fine details.. a bit arbitrary..
679  // Hopefully some roo to spare..Hummm not really.
680  std::cerr << " Placing TargetCoolingTubeReturnLoopLeft, front, length of helium " << plHelium->fParams[2]/2
681  << " at Z = " << posTmp[2] << std::endl;
682  new G4PVPlacement(&plCoolingTubeReturnLeft->fRotation,
683  posTmp, plCoolingTubeReturnLeft->fCurrent,
684  G4String("TargetCoolingTubeReturnLoopLeft_P"),
685  vHelium->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
686  posTmp[0] *= -1.0;
687  new G4PVPlacement(&plCoolingTubeReturnRight->fRotation,
688  posTmp, plCoolingTubeReturnRight->fCurrent,
689  G4String("TargetCoolingTubeReturnLoopRight_P"),
690  vHelium->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
691 
692 //
693 // Open ended.. Supported from the downstream end of Horn1.
694 //
696 
697  Create("Horn1TargetDownstrHeContainerCap");
698  PlaceFinal("Horn1TargetDownstrHeContainerCap", vHelium);
699 
700  }
701 
702  } // End of the target.
703  //
704  // Now need to place the holding rings.
705  //
706  //
708  //
709  // See drawing F10063951. We approximate to a simple ring, but use the same volume of alum, roughly
710  // at the same radius. we redo the arythmetic explictly here.
711  //
712  const double radHRingAll = 23.85*CLHEP::mm; // Not the real number on drawing, but it does not fit otherwise
713  const double radHoleLighter = 2.5*CLHEP::mm;
714  const double radCoolingTube = 3.9688*CLHEP::mm;
715  const double widthCentralPlate = 32.*CLHEP::mm;
716  const double heightCentralPlate = 26*CLHEP::mm;
717  const double StotRing = M_PI*radHRingAll*radHRingAll;
718  const double SRealRing = StotRing
719  - M_PI*(10.0*radHoleLighter*radHoleLighter + 2*radCoolingTube*radCoolingTube)
720  - widthCentralPlate*heightCentralPlate
721  + 4.0*CLHEP::mm*CLHEP::mm*(2.0*2.0)*(1.0-M_PI/4.);
722  // the last term is the rounded edges of the extruded plate.
723  const double radHRingInside = 21.75*CLHEP::mm; // to include the segment container volume.
724  const double SEffRing = StotRing - M_PI*(radHRingInside*radHRingInside);
725  const double lengthHRing = 6.0*CLHEP::mm * (SRealRing/SEffRing);
726  std::cerr << " Installation of holding ring. Check: SRealRing " << SRealRing
727  << " Seff " << SEffRing << " eff Length " << lengthHRing << std::endl;
728 
729  std::string aHRingName("TargetHoldingRing");
730  G4Tubs* aHRingTub = new G4Tubs(aHRingName, radHRingInside, radHRingAll,
731  0.5*lengthHRing, 0., 360.0*CLHEP::degree);
732  G4LogicalVolume *aHRingVolLG =
733  new G4LogicalVolume(aHRingTub, G4Material::GetMaterial(std::string("Aluminum")), aHRingName);
734  const unsigned int numHRing = 7;
735  const double zHRSpacing = (zLastSegment - zCoordTmp - 15*CLHEP::mm)/(numHRing-1); // 15 mm made up.
736  for (size_t kHR=0; kHR!= 7; kHR++) {
737  const double zzHR = zCoordTmp + kHR*zHRSpacing + 7.5*CLHEP::mm;
738  G4ThreeVector posHR(0., 0., zzHR);
739  new G4PVPlacement((G4RotationMatrix *) 0, posHR, aHRingVolLG,
740  aHRingName + std::string("_P"),
741  vHelium->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
742  }
743  // End for the segment of the target, 1.2 MW.
744  }
745 }
746 
747 // Obsolete code... As we no longer split Horn1 in two parts..
748 
750 
751  std::cerr << " LBNEVolumePlacements::PlaceFinalDownstrTarget1p2MW, Obsolete, do not use .. " << std::endl;
752  exit(2);
753  Create("Horn1TargetDownstrHeContainer");
754  G4PVPlacement *vMTop = PlaceFinal(std::string("Horn1TargetDownstrHeContainer"), mother);
755  LBNEVolumePlacementData *plDowstrHe = Create("Horn1TargetDownstrHelium");
756  G4PVPlacement *vMHe = PlaceFinal(std::string("Horn1TargetDownstrHelium"), vMTop);
757  // Skip the alignment ring for now..
758  // Deal with alignment ring located in the dowstream part of the target. We assume here that
759  // they have been already defined while dealing with the Upstream target portion
760  // First alignment ring, locate flush with the end plate (within 1 mm ) , left and right
761 // std::map<G4String, LBNEVolumePlacementData>::iterator itTmpRLeft = fSubVolumes.find(G4String("TargetAlignmentRingLeft"));
762 // LBNEVolumePlacementData &infoTmpRLeft = itTmpRLeft->second;
763 // std::map<G4String, LBNEVolumePlacementData>::iterator itTmpRRight = fSubVolumes.find(G4String("TargetAlignmentRingRight"));
764 // LBNEVolumePlacementData &infoTmpRRight = itTmpRRight->second;
765  std::map<G4String, LBNEVolumePlacementData>::iterator itMother = fSubVolumes.find(G4String("Horn1TargetDownstrHelium"));
766 // LBNEVolumePlacementData *plMother = &itMother ->second;
767 // if (fUseSimpleTargetCylinder) {
768 // PlaceFinalDownstrTargetSimpleCylinder(plMother, vMHe);
769 // return;
770 // }
771  LBNEVolumePlacementData *plTargetFinExtra = 0;
772  if (fTargetFinExtraWidth > 0.) {
773  std::map<G4String, LBNEVolumePlacementData>::iterator itM5 = fSubVolumes.find(G4String("TargetFinVertExtra"));
774  plTargetFinExtra = &itM5->second;
775  }
776 
777  G4ThreeVector posTmp(3, 0.);
778  LBNEVolumePlacementData *infoTargSegFirstLeft = 0;
779  G4String nameTgtUpDownSegFirst("Horn1TargetDownstrSegmentFirst");
780  if (fTargetFinLengthSplitDwnstr > 0.3*CLHEP::mm) {
781  LBNEVolumePlacementData *plTargetFinExtr2 = (fTargetFinExtraWidth > 0.) ?
782  Create(G4String("Horn1TargetFinVertExtraFirst")) : 0;
783  infoTargSegFirstLeft = Create("Horn1TargetSegmentFirstLeft");
784  LBNEVolumePlacementData *infoTargSegFirstRight = Create("Horn1TargetSegmentFirstRight");
785  G4PVPlacement *vTargSegFirst[2];
786  posTmp[0] = -0.5*fTargetFinContainerWidth - 0.023*CLHEP::mm; posTmp[1] = 0.;
787 
788  posTmp[2] = infoTargSegFirstLeft->fPosition[2];
789  vTargSegFirst[0] = new G4PVPlacement((G4RotationMatrix *) 0,
790  posTmp, infoTargSegFirstLeft->fCurrent,
791  G4String("TargetUpstrDowstrSegmentFirstLeft"),
792  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
793  posTmp[0] *= -1.0;
794  vTargSegFirst[1] = new G4PVPlacement((G4RotationMatrix *) 0,
795  posTmp, infoTargSegFirstRight->fCurrent,
796  G4String("TargetUpstrDowstrSegmentFirstRight"),
797  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
798  if (plTargetFinExtr2 != 0) {
799  posTmp[0] = -1.0*fTargetFinContainerWidth - 0.5*fTargetFinExtraWidth - 0.040*CLHEP::mm;
800  posTmp[1] = 0.; posTmp[2] = infoTargSegFirstLeft->fPosition[2];
801  new G4PVPlacement((G4RotationMatrix *) 0,
802  posTmp, plTargetFinExtr2->fCurrent,
803  nameTgtUpDownSegFirst + std::string("ExtraLeft"),
804  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
805  posTmp[0] *= -1.0;
806  new G4PVPlacement((G4RotationMatrix *) 0,
807  posTmp, plTargetFinExtr2->fCurrent,
808  nameTgtUpDownSegFirst + std::string("ExtraRight"),
809  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
810  }
811 
812 // LBNEVolumePlacementData *infoFinVert = Create("Horn1TargetFinVertFirst");
813  LBNEVolumePlacementData *plCoolingTubeFirst = Create("Horn1TargetCoolingTubeFirst");
814  LBNEVolumePlacementData *plCoolingTubeWaterFirst = Create("Horn1TargetCoolingTubeFirstWater");
815  LBNEVolumePlacementData *plTargetFinHeSide = (2.0*fTargetCTubeOuterRadius > fTargetFinWidth) ?
816  Create(G4String("Horn1TargetFinVertFirstHeliumSide")) : 0;
817  for (size_t kLeftRight=0; kLeftRight !=2; kLeftRight++) {
818 
819  posTmp[0] = 0.; posTmp[1] = fTargetFinHeight/2. + fTargetCTubeOuterRadius - 0.005*CLHEP::mm; posTmp[2] = 0.;
820  G4PVPlacement *vTubeUp = new G4PVPlacement((G4RotationMatrix *) 0,
821  posTmp, plCoolingTubeFirst->fCurrent,
822  G4String("Horn1TargetSegmentCoolingTubeFirst_PTop"),
823  vTargSegFirst[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
824  posTmp[1] *= -1.0;
825  G4PVPlacement *vTubeDown = new G4PVPlacement((G4RotationMatrix *) 0,
826  posTmp, plCoolingTubeFirst->fCurrent,
827  G4String("Horn1TargetSegmentCoolingTubeFirst_PBottom"),
828  vTargSegFirst[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
829  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
830  new G4PVPlacement((G4RotationMatrix *) 0,
831  posTmp, plCoolingTubeWaterFirst->fCurrent,
832  nameTgtUpDownSegFirst+G4String("CoolingTubeWater_PTop"),
833  vTubeUp->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
834  new G4PVPlacement((G4RotationMatrix *) 0,
835  posTmp, plCoolingTubeWaterFirst->fCurrent,
836  nameTgtUpDownSegFirst+G4String("CoolingTubeWater_PBottom"),
837  vTubeDown->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
838 
839 // posTmp[0] = (kLeftRight == 0) ? ( fTargetFinContainerWidth - fTargetFinWidth) :
840 // -1.0*( fTargetFinContainerWidth - fTargetFinWidth);
841 // posTmp[1]=0.; posTmp[2]=0.;
842 // new G4PVPlacement((G4RotationMatrix *) 0,
843 // posTmp, infoFinVert->fCurrent,
844 // G4String("Horn1TargetFinVertFirst_PLeft"),
845 // vTargSegFirst[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
846 //
847 //
848 // Put back some helium into the target segment, if target is thinner that the cooling tube diameter.
849 //
850  if (plTargetFinHeSide != 0) {
851  const double heThick = plTargetFinHeSide->fParams[0];
852  const double heThickShift = -0.5*fTargetFinContainerWidth + 0.5*heThick + 0.0175*CLHEP::mm;
853  posTmp[0] = (kLeftRight == 0) ? heThickShift : -1.0*heThickShift;
854  posTmp[1] = 0.;
855 // std::cerr << " Positioning helium side at X " << heThickShift << " width " << heThick << std::endl;
856  new G4PVPlacement((G4RotationMatrix *) 0,
857  posTmp, plTargetFinHeSide->fCurrent,
858  nameTgtUpDownSegFirst+G4String("TargetFinVertHeSide_P"),
859  vTargSegFirst[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
860  }
861  } // left/right part of the target.
862  }
863 
864  // Now place the previously defined standard target segment. Note: they already contain their cooling and
865  // real target.
866 // LBNEVolumePlacementData *plHorn1TargetSegment = Create("Horn1TargetSegment");
868  fSubVolumes.find(G4String("TargetUpstrDownstrSegmentLeft"));
870  fSubVolumes.find(G4String("TargetUpstrDownstrSegmentRight"));
871  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentLeft= &itTargSegLeft->second;
872  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentRight= &itTargSegRight->second;
873 
874  double zCoordTmp = (infoTargSegFirstLeft == 0) ?
875  (-1.0*plDowstrHe->fParams[2]/2. + plTargetUpstrDownstrSegmentLeft->fParams[2]/2. + 0.005*CLHEP::mm) :
876  ( infoTargSegFirstLeft->fPosition[2] + infoTargSegFirstLeft->fParams[2]/2. +
877  plTargetUpstrDownstrSegmentLeft->fParams[2]/2. + 0.002*CLHEP::mm);
878  int copyNumberT = 100;
879 // G4PVPlacement *vSeg[2];
880  std::string nameTgtUpDownSegLeft("Horn1TargetDownstrSegLeft");
881  std::string nameTgtUpDownSegRight("Horn1TargetDownstrSegRight");
882  if (fTargetFinExtraWidth > 0.) {
884  fSubVolumes.find(G4String("TargetFinVertExtra"));
885  plTargetFinExtra = &itExtraThin->second;
886  }
887  for (int iSeg=0; iSeg != fTargetNumFinsInHorn; iSeg++) { // Place with no misalignment
888  posTmp[0] = -0.5*fTargetFinContainerWidth - 0.023*CLHEP::mm;
889  posTmp[1] = 0.;
890  posTmp[2] = zCoordTmp;
891  std::ostringstream cNumStrStr; cNumStrStr << "_PDwnstr" << iSeg;
892  new G4PVPlacement((G4RotationMatrix *) 0,
893  posTmp, plTargetUpstrDownstrSegmentLeft->fCurrent,
894  nameTgtUpDownSegLeft+cNumStrStr.str(),
895  vMHe->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
896  copyNumberT ++;
897  posTmp[0] *= -1.0;
898  new G4PVPlacement((G4RotationMatrix *) 0,
899  posTmp, plTargetUpstrDownstrSegmentRight->fCurrent,
900  nameTgtUpDownSegRight+cNumStrStr.str(),
901  vMHe->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
902 
903  if (plTargetFinExtra != 0) {
904  posTmp[0] = -1.0*fTargetFinContainerWidth - 0.5*fTargetFinExtraWidth - 0.040*CLHEP::mm;
905  // to avoid false overlap errors.
906  new G4PVPlacement((G4RotationMatrix *) 0,
907  posTmp, plTargetFinExtra->fCurrent,
908  nameTgtUpDownSegLeft + std::string("Extra")+cNumStrStr.str(),
909  vMHe->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
910  posTmp[0] *= -1.0;
911  new G4PVPlacement((G4RotationMatrix *) 0,
912  posTmp, plTargetFinExtra->fCurrent,
913  nameTgtUpDownSegRight + std::string("Extra")+cNumStrStr.str(),
914  vMHe->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
915 
916  }
917  zCoordTmp += (fTargetFinLength + fTargetFinSpacingLength);
918  }
919 
920  // Now the end
921  LBNEVolumePlacementData *plCoolingTubeReturn = Create("Horn1TargetCoolingTubeDwnRetTit");
922  posTmp[0] = 0.; posTmp[1] = 0.;
923  posTmp[2] = plDowstrHe->fParams[2]/2 -
925  // Hopefully some roo to spare..
926  new G4PVPlacement(&plCoolingTubeReturn->fRotation,
927  posTmp, plCoolingTubeReturn->fCurrent,
928  G4String("Horn1TargetCoolingTubeDwnRetTit_PFront"),
929  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
930  posTmp[2] = plDowstrHe->fParams[2]/2 - 0.5*fTargetCTubeReturnDownstrThickTitanium/2. - 1.3*CLHEP::mm;
931  new G4PVPlacement(&plCoolingTubeReturn->fRotation,
932  posTmp, plCoolingTubeReturn->fCurrent,
933  G4String("Horn1TargetCoolingTubeDwnRetTit_PBack"),
934  vMHe->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
935 
936  Create("Horn1TargetCoolingTubeDwnRetWater");
937  PlaceFinal("Horn1TargetCoolingTubeDwnRetWater", vMHe);
938 
939  Create("Horn1TargetDownstrHeContainerCap");
940  PlaceFinal("Horn1TargetDownstrHeContainerCap", vMHe);
941 }
942 
943 void LBNEVolumePlacements::PlaceFinalRALTarget(G4PVPlacement *mother) {
944 
945  std::vector<double> fParams(3,0.);
946 
947 
948 
949  fParams[1] = fRALTargetRadius;
950  fParams[2] = fRALSimpleTargetLength;
951 
953  fParams[2] = 1500*CLHEP::mm;}
954 
955  std::string volumeName("RAL-Target");
956 
957  G4Tubs* aTube = new G4Tubs(volumeName, fParams[0], fParams[1], fParams[2]/2., 0., 360.*CLHEP::deg);
958 
959  G4LogicalVolume* fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial("Target"), volumeName);
960 
961  G4ThreeVector posTmp; posTmp[1] = 0.; posTmp[1] = 0.;
962 
963  posTmp[2] = fParams[2]/2. - fTargetOutHeContTubeStraightLength/2.;
964  //std::cout<<"Placing RAL-Target "<<posTmp[2]*CLHEP::mm<<std::endl;
965  new G4PVPlacement((G4RotationMatrix *) 0,
966  posTmp, fCurrent,
967  G4String("TargetSimpleCylinder_P"),
968  mother->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
969 
970  }
971 
973 
974  //
975  // Straight G4 coding. No alignment needed. Simple is Simple
976  //
977  std::vector<double> fParams(3,0.);
978  fParams[1] = fSimpleTargetRadius;
979  fParams[2] = fSimpleTargetLength;
980  std::string volumeName("TargetUsptreamSimpleCylinder");
981  G4Tubs* aTube = new G4Tubs(volumeName, fParams[0], fParams[1], fParams[2]/2., 0., 360.*CLHEP::deg);
982  G4LogicalVolume* fCurrent = new G4LogicalVolume(aTube, G4Material::GetMaterial("Target"), volumeName);
983  G4ThreeVector posTmp; posTmp[1] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
984  new G4PVPlacement((G4RotationMatrix *) 0,
985  posTmp, fCurrent,
986  G4String("TargetUsptreamSimpleCylinder_P"),
987  mother->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
988 }
989 
991 // std::cerr << " Entering LBNEVolumePlacements::PlaceFinalUpstrTargetSimpleCylinder ...radius "
992 // << fSimpleTargetRadius << std::endl;
993  //
994  // Straight G4 coding. No alignment needed. Simple is Simple
995  //
996 
997  std::vector<double> fParams(3,0.);
998  fParams[0] = fSimpleTargetWidth;
999  fParams[1] = fSimpleTargetHeight;
1000  fParams[2] = fSimpleTargetLength;
1001  std::string volumeName("TargetUsptreamSimpleBox");
1002  G4Box* aBox = new G4Box(volumeName, fParams[0]/2, fParams[1]/2, fParams[2]/2.);
1003  G4LogicalVolume* fCurrent = new G4LogicalVolume(aBox, G4Material::GetMaterial("Target"), volumeName);
1004  G4ThreeVector posTmp; posTmp[1] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
1005  new G4PVPlacement((G4RotationMatrix *) 0,
1006  posTmp, fCurrent,
1007  G4String("TargetUsptreamSimpleCylinder_P"),
1008  mother->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
1009 }
1010 
1011 // Quynh, August 2014.
1013 
1014  fTargetSLengthGraphite = 969.285*CLHEP::mm ;//953.8*CLHEP::mm; // Quynh calculation . real target.(7). 57 spheres x (17mm diameter + 0.005 tolerance)
1015 
1016  fTargetSLengthDownstrEnd = 0; // Quynh. remove this. real target. (8). not sure. based on T2K target, add 9mm for Helium return when calculate target position.
1017 //
1018 // The following quantity can be changed via messenger command.
1019 //
1020 // fTargetLengthIntoHorn = fTargetSLengthGraphite- 400*CLHEP::mm; //Quynh -> this can be overwritten by a data card
1021 // fTargetLengthIntoHorn = fTargetSLengthGraphite - 350.*CLHEP::mm + 25.3; // Integration drawing 8875.000-ME-363028
1022 // Does not belong here!. P.L.
1023  //last number emprically set
1024  // to have the first fin target at coord 0.3mm, to follow the convention.
1025  double targetNumSphereNominal = fTargetSLengthGraphite/(fMultiSphereTargetRadius*2+0.005*CLHEP::mm);
1026  std::cout << "---Sphere Diameter: " << fMultiSphereTargetRadius*2;
1027  std::cout << "---Nominal number of Sphere: "<< targetNumSphereNominal <<std::endl;
1028 
1029  fTargetNumSphere = (int) (targetNumSphereNominal + 0.5); //rounding-fTargetNumSphere has been defined as int in .hh
1030  std::cout << "fTargetNumSphere is rounded to: "<< fTargetNumSphere <<std::endl;
1031 
1032  double deltaNumSphere = targetNumSphereNominal - (double) fTargetNumSphere;
1033 
1034  std::cout << "LBNEVolumePlacements::AdaptForMultiSphereTarget, total number of sphere: " << fTargetNumSphere <<
1035 "---Delta Num of Sphere: " << deltaNumSphere << std::endl;
1036  std::cout << "fTargetSLength: " << fTargetSLength << "---fTargetLengthOutsideHorn before adjustment: "
1038 
1039  const double oldLength = fTargetSLengthGraphite;
1040  std::cout << "Input fTargetsLengthGraphite: "<< oldLength <<std::endl;
1041  fTargetSLengthGraphite = fTargetNumSphere*(fMultiSphereTargetRadius*2 + 0.005*CLHEP::mm); //tolerance 5 micron
1042  std::cout <<"---fTargetSLengthGraphite adjusted to " <<fTargetSLengthGraphite<<"="<< fTargetNumSphere <<"x ("
1043  << fMultiSphereTargetRadius<<"x 2 + 0.005mm)"<<std::endl;
1044 
1045 
1046  if (std::abs(oldLength - fTargetSLengthGraphite) > 0.001*CLHEP::mm)
1047  std::cout << "LBNEVolumePlacements::AdaptForMultiSphereTarget: Warning: re-adjust the target length from " <<
1048  oldLength << " to " << fTargetSLengthGraphite << " to get an integer number of spheres " << std::endl;
1049  //
1050  // Change the diameter of the Helium Tube
1051  //
1052  fTargetHeContTubeInnerRadius = 35.2*CLHEP::mm/2.; // T2K drawing, August 2014. To be reviewed, Alberto in contact with Rutherford.
1053 }
1054 
1056 //Quynh. real target . (8)
1057  LBNEVolumePlacementData* plInfo = this->Create(G4String("TargetMultiSphere"));
1058  G4ThreeVector posTmp;
1059 // const double zCoordTmp = -1.0*fParams[2]/2.+(fParams[2]-fTargetLengthOutsideHorn)+(fMultiSphereTargetRadius+0.005*CLHEP::mm);//Quynh.. the container is longer than target and need to be fixed. not sure how
1060  const double zCoordTmp = -plHelium->fParams[2]/2. + fMultiSphereTargetRadius + 0.005*CLHEP::mm ; // Simplify... P.L.
1061  posTmp[0] = 0.; posTmp[1] = 0.;
1062  for (int iSphere=0; iSphere !=fTargetNumSphere; iSphere++) {
1063  posTmp[2] = zCoordTmp + iSphere*(fMultiSphereTargetRadius*2+0.005*CLHEP::mm);
1064  std::ostringstream cNumStrStr; cNumStrStr << iSphere;
1065  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, plInfo->fCurrent,
1066  (G4String("TargetUsptreamMultiSphere_P") + cNumStrStr.str()),
1067  mother->GetLogicalVolume(), false, iSphere, fCheckVolumeOverLapWC); //copy Number = iSphere
1068 // std::cout<<"sphere: "<< iSphere<< std::endl;
1069  }
1070 
1071 }
1072 void LBNEVolumePlacements::PlaceFinalNoSplitHorn1(G4PVPlacement* mother, G4PVPlacement* motherTop) {
1073 
1074  std::cerr << " Entering LBNEVolumePlacements::PlaceFinalNoSplitHorn1, mother name " <<
1075  mother->GetLogicalVolume()->GetName() << std::endl;
1076 //
1077  if (fHorn1RadiusBigEnough) {
1078  std::cerr << " Obsolete data card /LBNE/det/TargetAndHorn1RadiusBigEnough used, quit here for good ! " << std::endl;
1079  G4Exception("LBNEVolumePlacements::PlaceFinalNoSplitHorn1", "InvalidSetup", FatalErrorInArgument, "Wrong data card");
1080  }
1081  const bool doCheckOverlapNoG4ConsBug = false; // in v4.9.6., this check is worthless.
1082 // const bool doCheckOverlapNoG4ConsBug = true;
1083  // in v4.9.6., bug corrected by Tatiana, Sept. 3 2014, if G4Cons source file added to this directory..
1084 
1085  //
1086  // New Plug Code. Based on what John LoSecco did. Adapted for the new geometry, August 31 2014.
1087  //
1089  G4ThreeVector posTmp; posTmp[0] =0.; posTmp[1] =0.;
1090  G4Tubs* plugTube = new G4Tubs("Plug", fPlugInnerRadius, fPlugOuterRadius, fPlugLength*.5, 0., 360.*CLHEP::deg);
1091  G4LogicalVolume *plugl = new G4LogicalVolume(plugTube, G4Material::GetMaterial(fPlugMaterial.c_str()), "PlugInHorn1");
1092  const LBNEVolumePlacementData *plMotherTop = Find(G4String("pluggingHorn1"), "TargetHallAndHorn1", G4String("Create"));
1093  const double posHorn1 = plMotherTop->fPosition[2]; // With respect to Z = 0 (MCZERO, drawing 36309x)
1094  posTmp[2] = -1.0*posHorn1 + fPlugZPosition;
1095  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, plugl, "PlugInHorn1_P",
1096  motherTop->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1097  }
1099  std::cerr << "LBNEVolumePlacements::PlaceFinalNoSplitHorn1, calling for Simple Horn PolyNumber 1 " << std::endl;
1100  PlaceFinalSimpleHornPolyNumber(0, mother);
1101  return;
1102  }
1103 //
1104 // Start with upstream Inner to Out transition.
1105 //
1106 {
1107  G4String nameHorn1IO("UpstrHorn1TransInnerOuter");
1108  G4String nameHorn1IOCont(nameHorn1IO + G4String("Cont"));
1109  Create(nameHorn1IOCont);
1110  G4PVPlacement *vHorn1IOCont = PlaceFinal(nameHorn1IOCont, mother);
1111  for (size_t iPartIO = 0; iPartIO != fTargetHorn1InnerRadsUpstr.size(); iPartIO++) {
1112  std::ostringstream nameStrStr; nameStrStr << nameHorn1IO << "Part" << iPartIO;
1113  G4String nameStr(nameStrStr.str());
1114  Create(nameStr);
1115  PlaceFinal(nameStr, vHorn1IOCont);
1116  }
1117  }
1118  const double in = 2.54*CLHEP::cm;
1119 // const double innerConductThicknessNeck = 4.0*CLHEP::mm; // only relevant if fHorn1RadiusBigEnough is true.
1120 // const double fHorn1RMinAllBG = fTargetHeContTubeInnerRadius + fTargetHeContTubeThickness + 1.25*CLHEP::mm; // Only 250 micron tolerance.
1121 //
1122 // std::cerr << " Start testing PlaceFinalHorn1, mother Logical volume name " << mother->GetLogicalVolume()->GetName() << std::endl;
1123  if ((std::abs(fHorn1LongRescale - 1.0) < 1.0e-5) && (std::abs(fHorn1RadialRescale - 1.0) < 1.0e-5))
1124  fHorn1Equations[0].test1(); // this supposed to work. But not if we rescale the Horn1,
1125  // since we compare with hardtyped data extracted from a blue print
1126 // std::cerr << " Test 1 passed " << std::endl;
1127 // fHorn1Equations[3].test1(); // This supposed to fail...
1128  LBNEVolumePlacementData *plTrUpst = this->Create("Horn1IOTransCont");
1129  G4PVPlacement *vTrUpst = this->PlaceFinal("Horn1IOTransCont", mother); //August 21, check longitudinal offsets here...
1130  //
1131  // These sub-volumes will be never misaligned with respect to each other, or the container volume
1132  // above. So skip the VolumePlacement utilities. Code bloat here instead in the Create method.. Oh well..
1133  //
1134  for (size_t k=0; k!=fHorn1UpstrLengths.size(); k++) {
1135  std::ostringstream nameStrStr; nameStrStr << "Horn1IOTransInnerPart" << k;
1136  G4String nameStr(nameStrStr.str());
1137  fHorn1IC.push_back(nameStr);
1138 
1139  G4Cons *aCons = new G4Cons(nameStr, fHorn1UpstrInnerRadsUpstr[k],fHorn1UpstrInnerRadsOuterUpstr[k],
1141  fHorn1UpstrLengths[k]/2., 0., 360.0*CLHEP::deg);
1142  G4LogicalVolume *pCurrent = new G4LogicalVolume(aCons, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1143  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.;
1144  posTmp[2] = -1.0*(plTrUpst->fParams[2])/2. + fHorn1UpstrZPositions[k];
1145  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1146  vTrUpst->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1147 // const G4PVPlacement *plHorn1IO = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1148 // vTrUpst->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1149 // Debugging misshaped volume, Oct 28 2013.
1150 // if (k == 3) {
1151 // this->CheckOverlaps(plHorn1IO, 10000, 1.0e-5, true);
1152 // std::cerr << " Placing IOTrans Sub elem " << k << " at z = " << fHorn1UpstrZPositions[k] << " (abs), rel " <<
1153 // posTmp[2] << " length " << fHorn1UpstrLengths[k] << std::endl;
1154 // std::cerr << " RIUps " << fHorn1UpstrInnerRadsUpstr[k] << " ROUps " << fHorn1UpstrInnerRadsOuterUpstr[k];
1155 // std::cerr << " RIDwn " << fHorn1UpstrInnerRadsDownstr[k] << " RODwn " << fHorn1UpstrInnerRadsOuterDownstr[k] << std::endl;
1156 // }
1157  }
1158 
1159  for (size_t k=0; k!= fHorn1UpstrOuterIOTransInnerRads.size(); k++) {
1160  std::ostringstream nameStrStr; nameStrStr << "Horn1IOTransOuterPart" << k;
1161  G4String nameStr(nameStrStr.str());
1162  G4Tubs *aTubs = new G4Tubs(nameStr, fHorn1UpstrOuterIOTransInnerRads[k],
1164  fHorn1UpstrOuterIOTransLengths[k]/2., 0., 360.0*CLHEP::deg);
1165  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.;
1166  posTmp[2] = -1.0*(plTrUpst->fParams[2])/2. + fHorn1UpstrOuterIOTransPositions[k];
1167  G4LogicalVolume *pCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1AllCondMat), nameStr);
1168  new G4PVPlacement( (G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1169  vTrUpst->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1170  }
1171  //
1172  // We place more volumes in the mother volume
1173  //
1174  G4PVPlacement *vUpst = mother;
1175  const LBNEVolumePlacementData *plHUpst = Find(G4String("InnerConductors"), "Horn1PolyM1", G4String("Create"));
1176 
1177 // Start by checking possible radial overlap at the downstream end of the target.
1178 // The size and position of Horn1TopLevelUpstr and Horn1TargetDownstrHeContainer
1179 
1180  fZHorn1ACRNT1Shift = 3.316*in*fHorn1LongRescale; // Drawing 8875.112-MD-363097
1181  // Correct here for the new dimension of the "No split" mother volume.
1182 
1184 
1185  const double z21p088 = fHorn1LongRescale*21.088*in; //Equation change.
1186  const double zOffsetDrawingUpstrEdge = 5.752*in*fHorn1LongRescale; // On the inner conductor, excluding I/O trans. Drawing 363097
1187 
1188  double lengthInnerConductUpstr = z21p088 - (3.316*in*fHorn1LongRescale) - 0.010*CLHEP::mm; // Up to Z = 21.088, Drawing coordinate system.
1189 
1190  int numSubSect = GetNumberOfInnerHornSubSections(0, 0., lengthInnerConductUpstr, 10);
1191  // Fill with it one or more inner conductor conical section
1192  // We require a precision of 5 microns in the radius.
1193  double deltaZ = lengthInnerConductUpstr/numSubSect;
1194  for (int iSub=0; iSub != numSubSect; iSub++) {
1195  //
1196  const double zzBegin = fZHorn1ACRNT1Shift + (iSub*deltaZ); // from the
1197  const double zzEnd = zzBegin + deltaZ;
1198  std::ostringstream nameStrStr; nameStrStr << "Horn1UpstrSubSect" << iSub;
1199  G4String nameStr(nameStrStr.str());
1200  fHorn1IC.push_back(nameStr);
1201 // Smooth transition between equation 1 and 2
1202  const double rMin1Eqn1 = fHorn1Equations[0].GetVal(zzBegin); // Equation 1 or 0
1203  const double rMin2Eqn1 = fHorn1Equations[0].GetVal(zzEnd);
1204  const double rMin1Eqn2 = fHorn1Equations[1].GetVal(zzBegin); // Equation 1 or 0
1205  const double rMin2Eqn2 = fHorn1Equations[1].GetVal(zzEnd);
1206  const double ratio10vs1 = std::min(1.0, (zzBegin/(21.0888*in*fHorn1LongRescale)));
1207  double rMin1 = rMin1Eqn2*ratio10vs1 + (1.0-ratio10vs1)*rMin1Eqn1;
1208  const double ratio20vs1 = std::min(1.0, (zzEnd/(21.0888*in*fHorn1LongRescale)));
1209  double rMin2 = rMin2Eqn2*ratio20vs1 + (1.0-ratio20vs1)*rMin2Eqn1;
1210  double rMax1 = fHorn1Equations[5].GetVal(zzBegin) + fWaterLayerThickInHorns + 0.0025*CLHEP::mm;
1211  // Equation 6 (Drawing 8875.112-MD 363104)
1212  double rMax2 = fHorn1Equations[5].GetVal(zzEnd) + fWaterLayerThickInHorns + 0.0025*CLHEP::mm;
1213  std::cerr << " Inner radius for section " << nameStr << " At zzBegin " << zzBegin << " to " << zzEnd
1214  << " rMin1 " << rMin1 << " rMin2 " << rMin2
1215  << " rMax1 " << rMax1 << " rMax2 " << rMax2 << std::endl;
1216  G4Cons *aCons = new G4Cons(nameStr, rMin1, rMax1,rMin2, rMax2,
1217  (deltaZ - 0.005*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1218  G4LogicalVolume *pCurrent = new G4LogicalVolume(aCons, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1219  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.;
1220  // plHUpst constain part of the Inner Outer Transition. Shift downtream by it's length
1221  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zOffsetDrawingUpstrEdge + deltaZ/2. + iSub*deltaZ + 0.055*CLHEP::mm;
1222  std::cerr << " Placing section " << nameStr << " at z = " << posTmp[2] << std::endl;
1223  std::cerr << " Beginning of the volume with respect to upstre edge "
1224  << posTmp[2] + plHUpst->fParams[2]/2 - deltaZ/2. << " downstrEdge " <<
1225  posTmp[2] + plHUpst->fParams[2]/2 + deltaZ/2. << std::endl;
1226 // Shift in Z until no clash?????
1227 // posTmp[2] += 30*CLHEP::mm;
1228 // Unresolved clash here!!!
1229 //
1230  G4PVPlacement *vSub = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1231  vUpst->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1232 
1233  if (fWaterLayerThickInHorns > 0.002*CLHEP::mm) {
1234  nameStrStr.str(""); nameStrStr.clear(); nameStrStr << "Horn1UpstrSubSect" << iSub << "Water";
1235  nameStr = nameStrStr.str();
1236  fHorn1IC.push_back(nameStr);
1237  G4Cons *aConsW = new G4Cons(nameStr, rMax1 - fWaterLayerThickInHorns, rMax1-0.001*CLHEP::mm,
1238  rMax2 - fWaterLayerThickInHorns, rMax2-0.001*CLHEP::mm,
1239  (deltaZ - 0.0075*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1240  G4LogicalVolume *pCurrentW = new G4LogicalVolume(aConsW, G4Material::GetMaterial(std::string("Water")), nameStr);
1241  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] =0.;
1242  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentW, nameStr + std::string("_P"),
1243  vSub->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1244  }
1245  }
1246  // on the number of subsections for the inner conductor, for the upstream part of Horn1
1247  // Now add the welding joint between the most upstream part of the inner conductor and the Inner Outer transition section
1248  // Drawing Drawing 8875.112-MD 363104
1249  {
1250  G4String nameStr("Horn1UpstrSubSect0WeldUpstr");
1251  const double length = 12.0*CLHEP::mm; // Make it a bit shorter, it is rounded...
1252  double rTmp1 = fHorn1Equations[5].GetVal(3.2645*in)
1253  + 0.02*CLHEP::mm + fWaterLayerThickInHorns;
1254 
1255  // place it a little more detached..Also, the weld is on top of the layer of water.. Oh well..
1256  const double rTmp2 = rTmp1 + 1.8*CLHEP::mm; //
1257  G4Tubs *aTubs = new G4Tubs(nameStr, rTmp1, rTmp2,
1258  length/2. , 0., 360.0*CLHEP::deg);
1259  G4LogicalVolume *pCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1260  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.;
1261  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zOffsetDrawingUpstrEdge + length/2. + 1.0*CLHEP::mm; // extra space..
1262 
1263  std::cerr << " Placing section " << nameStr << " at z = " << posTmp[2] << " radii "
1264  << rTmp1 << " , " << rTmp2 << " length " << length << std::endl;
1265  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1266  vUpst->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1267 
1268  }
1269  // Now place the first support ring, and the spider hang
1270  const double lengthHangerRing = fHorn1LongRescale*0.750*in;
1271  std::cerr << " First Spider Hanger is in Horn1Upstr section " << std::endl;
1272 
1273  G4String nameStrFirstHanger("Horn1UpstrSpiderHanger");
1274  const double zPosCenterMotherVolume = -1.0*(plHUpst->fParams[2])/2. + 2.436*in + 0.5*CLHEP::mm +
1275  19.347*in*fHorn1LongRescale + lengthHangerRing/2. ; // Drawing 363093 and 363097
1276  const double zPosUpstrDrawingCoord = 19.347*in*fHorn1LongRescale;
1277 
1278  this->Horn1InstallSpiderHanger(nameStrFirstHanger, zPosUpstrDrawingCoord,
1279  zPosCenterMotherVolume, vUpst );
1280  // Outer tube
1281  const double zShiftDrawingDownstr = 2.436*in*fHorn1LongRescale;
1282  // from now, a better orgin is the upstram point on mother Horn1PolyM1
1283 
1284  G4String nameStr("Horn1OutrTube");
1285  const double lengthOutT = (127.550 - 1.510)*in*fHorn1LongRescale - 1.0*CLHEP::mm;
1286  // displace 100 microns to avoid clash with spider hanger.
1287  G4Tubs *aTubs = new G4Tubs(nameStr, fHorn1OuterTubeInnerRad + 0.1*CLHEP::mm,
1288  fHorn1OuterTubeOuterRad + 0.1*CLHEP::mm, lengthOutT/2. , 0., 360.0*CLHEP::deg);
1289  G4LogicalVolume *pCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1AllCondMat), nameStr);
1290  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.;
1291  const double zOffOut = 3.316*in*fHorn1LongRescale;
1292  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zShiftDrawingDownstr + zOffOut + lengthOutT/2. + 0.25*CLHEP::mm;
1293  std::cerr << " Installing Outer tube sptream at " << posTmp[2] << " lengthOutT " << lengthOutT << std::endl;
1294  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStr + std::string("_P"),
1295  vUpst->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1296 
1297  // Outer Tube Upstream flange. See drawing 363094
1298  G4String nameStrOutFlUpstr("Horn1UpstrOutrTubeFlange");
1299  const double lengthOutFlUpstr = 1.0*in*fHorn1LongRescale; //Not cleanly shown on drawing 363094
1300  const double rTmpOutFlUpstrInner = fHorn1OuterTubeOuterRad + 0.1*CLHEP::mm;
1301  const double rTmpOutFlUpstrOuter = rTmpOutFlUpstrInner + 2.5*in*fHorn1RadialRescale; // Still a guess.. Probably a bit oversized.
1302  aTubs = new G4Tubs(nameStrOutFlUpstr, rTmpOutFlUpstrInner, rTmpOutFlUpstrOuter, lengthOutFlUpstr/2.0, 0., 360.0*CLHEP::deg);
1303  pCurrent = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1AllCondMat), nameStrOutFlUpstr);
1304  posTmp[0] = 0.; posTmp[1] = 0.;
1305  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zShiftDrawingDownstr + zOffOut + lengthOutFlUpstr + 0.055*CLHEP::mm;
1306  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrent, nameStrOutFlUpstr + std::string("_P"),
1307  vUpst->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1308  //
1309 
1310  double lengthToTheNeck = (30.3150 - 21.088)*in*fHorn1LongRescale; // Drawing 363105
1311 
1312  // Downstream of the neck, we install everything in Horn1PolyM1.. Simpler..
1313 
1314  // Let us call this the mid-section.. Historical notation.. It will install in the upstream section..
1315  //
1316  // Install the length of inner conductor, from downstream end of the target to Zdrawing 21.0888 inches
1317  //
1318 // std::cerr << " ... Length to the neck " << lengthToTheNeck << std::endl;
1319  {
1320  numSubSect = 4;
1321  deltaZ = lengthToTheNeck/numSubSect;
1322  const double zOffStart = 21.088*in*fHorn1LongRescale + 0.025*CLHEP::mm;
1323 // std::cerr << " ...... delta z to 21.0888 " << deltaZ << std::endl;
1324  for (int iSub = 0; iSub != numSubSect; iSub++) {
1325  const double zzBegin = z21p088 + iSub*deltaZ;
1326  const double zzEnd = zzBegin + deltaZ;
1327  std::ostringstream nameStrStr; nameStrStr << "Horn1ToNeckPartM0SubSect" << iSub;
1328  nameStr = nameStrStr.str();
1329  const double rMin1Eqn1 = fHorn1Equations[0].GetVal(zzBegin); // Equation 1 or 0
1330  const double rMin2Eqn1 = fHorn1Equations[0].GetVal(zzEnd);
1331  const double rMin1Eqn2 = fHorn1Equations[1].GetVal(zzBegin); // Equation 1 or 0
1332  const double rMin2Eqn2 = fHorn1Equations[1].GetVal(zzEnd);
1333  const double rMin1 = ((numSubSect - iSub -1)*rMin1Eqn1 + ((iSub+1)*rMin1Eqn2))/numSubSect;
1334  const double rMin2 = ((numSubSect - iSub -1)*rMin2Eqn1 + ((iSub+1)*rMin2Eqn2))/numSubSect;
1335  const double rMax1 = fHorn1Equations[5].GetVal(zzBegin) + fWaterLayerThickInHorns + 0.0025;
1336  // Equation 6 (Drawing 8875.112-MD 363104)
1337  const double rMax2 = fHorn1Equations[5].GetVal(zzEnd) + fWaterLayerThickInHorns + 0.0025;
1338  const double lengthTmp = deltaZ - 0.050*CLHEP::mm;
1339  G4Cons *aCons = new G4Cons(nameStr, rMin1, rMax1,rMin2, rMax2, lengthTmp/2., 0., 360.0*CLHEP::deg);
1340  G4LogicalVolume *pCurrentSu = new G4LogicalVolume(aCons, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1341  posTmp[0] = 0.; posTmp[1] = 0.;
1342  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zShiftDrawingDownstr + zOffStart + deltaZ/2. + iSub*deltaZ;
1343  std::cerr << " Installing mid section Horn1, length " << lengthTmp << " at Z = " << posTmp[2]
1344  << " Rads " << rMin1 << " , " << rMin2 << " max " << rMax1 << " " << rMax2 << std::endl;
1345  G4PVPlacement *vSub = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentSu, nameStr + std::string("_P"),
1346  vUpst->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1347 
1348  if (fWaterLayerThickInHorns > 0.002*CLHEP::mm) {
1349  nameStrStr.str(""); nameStrStr.clear(); nameStrStr << "Horn1ToNeckPartM0SubSect" << iSub << "Water";
1350  nameStr=nameStrStr.str();
1351  G4Cons *aConsW = new G4Cons(nameStr, rMax1 - fWaterLayerThickInHorns, rMax1-0.001*CLHEP::mm,
1352  rMax2 - fWaterLayerThickInHorns, rMax2-0.001*CLHEP::mm,
1353  (lengthTmp - 0.0075*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1354  G4LogicalVolume *pCurrentW = new G4LogicalVolume(aConsW, G4Material::GetMaterial(std::string("Water")), nameStr);
1355  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] =0.;
1356  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentW, nameStr + std::string("_P"),
1357  vSub->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1358  }
1359  } // of the number of subsections in the upstream part of the neck region (zDrawing = 21.0888 inches)
1360  }
1361  // The first weld for this section.
1362  {
1363  nameStr = std::string("Horn1UpstrSubSect1Weld0");
1364  posTmp[0] = 0.; posTmp[1] = 0.;
1365  double length = 24.0*CLHEP::mm; //Cover two real sections...
1366  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + z21p088 + length/2 + zShiftDrawingDownstr; // with respecto the upstr edge of Horn1TopLevelDownstr
1367  double rTmp1 = fHorn1Equations[5].GetVal(z21p088 - length - 1.0*CLHEP::mm)
1368  + 0.015*CLHEP::mm + fWaterLayerThickInHorns;
1369  // place it a little more detached..The radius is estimated on the upstream side, biggest radius.
1370  double rTmp2 = rTmp1 + 1.8*CLHEP::mm; //
1371  G4Tubs *aTubsW = new G4Tubs(nameStr, rTmp1, rTmp2, length/2. , 0., 360.0*CLHEP::deg);
1372  std::cerr << " Installing the weld " << nameStr << " at Z " << posTmp[2] << std::endl;
1373  G4LogicalVolume *pCurrentW = new G4LogicalVolume(aTubsW, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1374  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentW, nameStr + std::string("_P"),
1375  vUpst->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1376  }
1377  //
1378  // Now the dowstream section. We no longer create the mother volume for it. We will install it directly in
1379  // Horn1PolyM1.
1380  //
1381  //
1382  //
1383  // Now, the neck. Just a tube
1384  //
1385  {
1386  nameStr = G4String("Horn1Neck");
1387  fHorn1IC.push_back(nameStr);
1388  const double zNeckDrawing = fHorn1LongRescale*(30.3150)*in; //start of the neck..
1389  double rTmp1 = fHorn1RadialRescale*(0.709*in/2.); // Drawing 8875.112-MD 363105
1390  double rTmp2 = fHorn1RadialRescale*(1.063*in/2.) + fWaterLayerThickInHorns + 0.025*CLHEP::mm;
1391  // Drawing 8875.112-MD 363105
1392  fHorn1NeckInnerRadius = rTmp1; // For use in computing the magnetic field
1393 // fHorn1NeckOuterRadius = rTmp2; // For use in computing the magnetic field
1394 // Bug fix, September 2014 : there are no skin depth effect in water!...
1395  fHorn1NeckOuterRadius = rTmp2 - fWaterLayerThickInHorns - 0.025*CLHEP::mm; // For use in computing the magnetic field
1396  const double length = fHorn1LongRescale*1.5680*in - 0.050*CLHEP::mm; // last term to absord
1397  // small shifts in the upstream part..
1398  G4Tubs *aTubsNe1 = new G4Tubs(nameStr, rTmp1, rTmp2,
1399  length/2. , 0., 360.0*CLHEP::deg);
1400  G4LogicalVolume *pCurrentNe1 = new G4LogicalVolume(aTubsNe1, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1401  posTmp[0] = 0.; posTmp[1] = 0.;
1402  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zNeckDrawing + zShiftDrawingDownstr + length/2. + 0.025*CLHEP::mm;
1403 
1404  G4PVPlacement* vSub = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentNe1, nameStr + std::string("_P"),
1405  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1406  if (fWaterLayerThickInHorns > 0.002*CLHEP::mm) {
1407  G4String nameStrW(nameStr); nameStrW += G4String("Water");
1408  G4Tubs *aTubsW = new G4Tubs(nameStrW, rTmp2-fWaterLayerThickInHorns-0.012*CLHEP::mm, rTmp2-0.012*CLHEP::mm,
1409  length/2. , 0., 360.0*CLHEP::deg);
1410  G4LogicalVolume *pCurrentW = new G4LogicalVolume(aTubsW,
1411  G4Material::GetMaterial(std::string("Water")), nameStrW);
1412  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] =0.;
1413  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentW, nameStrW + std::string("_P"),
1414  vSub->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1415  }
1416  }
1417  // The downstream part of the real section that has the neck.
1418  {
1419  const double zStartDrawing = fHorn1LongRescale*31.8827*in;
1420  const double zEndDrawing = fHorn1LongRescale*(41.0776)*in;
1421  fHorn1ZDEndNeckRegion = zEndDrawing;
1422  numSubSect = GetNumberOfInnerHornSubSections(3, zStartDrawing,
1423  zEndDrawing, 10); // These Z position are from the start of the inner conductor.
1424  deltaZ = (zEndDrawing - zStartDrawing)/numSubSect;
1425  for (int iSub = 0; iSub != numSubSect; iSub++) {
1426  const double zzBegin = zStartDrawing + iSub*deltaZ;
1427  const double zzEnd = zzBegin + deltaZ;
1428  std::ostringstream nameStrStr; nameStrStr << "Horn1DownstrPart1SubSect" << iSub;
1429  nameStr = nameStrStr.str();
1430  fHorn1IC.push_back(nameStr);
1431  double rMin1 = fHorn1Equations[3].GetVal(zzBegin);
1432  double rMin2 = fHorn1Equations[3].GetVal(zzEnd);
1433  double rMax1 = fHorn1Equations[7].GetVal(zzBegin) + fWaterLayerThickInHorns + 0.0025;
1434  // Equation 6 (Drawing 8875.112-MD 363104)
1435  double rMax2 = fHorn1Equations[7].GetVal(zzEnd) + fWaterLayerThickInHorns + 0.0025;
1436  G4Cons *aConsSuU = new G4Cons(nameStr, rMin1, rMax1,rMin2, rMax2,
1437  (deltaZ - 0.005*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1438  G4LogicalVolume *pCurrentSuU = new G4LogicalVolume(aConsSuU, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1439  posTmp[0] = 0.; posTmp[1] = 0.;
1440  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zzBegin + zShiftDrawingDownstr + deltaZ/2.;
1441  G4PVPlacement *vSub = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentSuU, nameStr + std::string("_P"),
1442  mother->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1443 
1444  if (fWaterLayerThickInHorns > 0.002*CLHEP::mm) {
1445  nameStrStr.str(""); nameStrStr.clear(); nameStrStr << "Horn1DownstrPart1SubSect" << iSub << "Water";
1446  nameStr = nameStrStr.str();
1447  G4Cons *aConsWa = new G4Cons(nameStr, rMax1 - fWaterLayerThickInHorns, rMax1-0.001*CLHEP::mm,
1448  rMax2 - fWaterLayerThickInHorns, rMax2-0.001*CLHEP::mm,
1449  (deltaZ - 0.0075*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1450  G4LogicalVolume *pCurrentWa = new G4LogicalVolume(aConsWa, G4Material::GetMaterial(std::string("Water")), nameStr);
1451  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] =0.;
1452  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentWa, nameStr + std::string("_P"),
1453  vSub->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1454  }
1455  } // of the number of subsection to the neck
1456  // The weld at the end
1457  {
1458  nameStr = std::string("Horn1DownstrPart1Weld1");
1459  fHorn1IC.push_back(nameStr);
1460  const double zWW = fHorn1LongRescale*(41.0776)*in;;
1461  const double length = 24.0*CLHEP::mm; //Cover two real sections...
1462  const double rTmp1 = fHorn1Equations[7].GetVal(zWW + length) + 0.150*CLHEP::mm + fWaterLayerThickInHorns;
1463  // place it a little more detached..Also, the weld is on top of the layer of water.. Oh well..
1464  const double rTmp2 = rTmp1 + 1.8*CLHEP::mm; //
1465  G4Tubs *aTubsWW = new G4Tubs(nameStr, rTmp1, rTmp2,
1466  length/2. , 0., 360.0*CLHEP::deg);
1467  G4LogicalVolume *pCurrentWW = new G4LogicalVolume(aTubsWW, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1468  posTmp[0] = 0.; posTmp[1] = 0.;
1469  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zWW + zShiftDrawingDownstr + length/2.;
1470  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentWW, nameStr + std::string("_P"),
1471  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1472  }
1473  } // The downstream part horn1, starting downstream of the real section that has the neck
1474  // More Inner conductors, covering the drawings 8875.112-MD 363105 through 363109 included.
1475  // Radial equation 5 and 8 (indices 4 and 7 in our arrays)
1476  // From ZDrawing 41.0576 to 117.126
1477  {
1478  const double zStartDrawing = fHorn1LongRescale*41.108*in;
1479  const double zEndDrawing = fHorn1LongRescale*117.126*in;
1480  fHorn1ZEndIC = zEndDrawing; // For use in the Magnetic field class.
1481  numSubSect = GetNumberOfInnerHornSubSections(4, zStartDrawing,
1482  zEndDrawing, 10); // These Z position are from the start of the inner conductor.
1483  deltaZ = (zEndDrawing - zStartDrawing)/numSubSect;
1484 // std::cerr << " Number of subsection for the downstream half of Horn1 " << numSubSect
1485 // << " deltaz " << deltaZ << std::endl;
1486  for (int iSub = 0; iSub != numSubSect; iSub++) {
1487  const double zzBegin = zStartDrawing + iSub*deltaZ;
1488  const double zzEnd = zzBegin + deltaZ;
1489  std::ostringstream nameStrStr; nameStrStr << "Horn1DownstrPart1SubSect" << iSub;
1490  nameStr = nameStrStr.str();
1491  fHorn1IC.push_back(nameStr);
1492  const double rMin1 = fHorn1Equations[4].GetVal(zzBegin); // Equation 1
1493  const double rMin2 = fHorn1Equations[4].GetVal(zzEnd);
1494  const double rMax1 = fHorn1Equations[7].GetVal(zzBegin) + fWaterLayerThickInHorns + 0.0025;
1495  // Equation 6 (Drawing 8875.112-MD 363104)
1496  const double rMax2 = fHorn1Equations[7].GetVal(zzEnd) + fWaterLayerThickInHorns + 0.0025;
1497  G4Cons *aConsSu = new G4Cons(nameStr, rMin1, rMax1,rMin2, rMax2,
1498  (deltaZ - 0.005*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1499  G4LogicalVolume *pCurrentSu = new G4LogicalVolume(aConsSu, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1500  posTmp[0] = 0.; posTmp[1] = 0.;
1501  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zzBegin + zShiftDrawingDownstr + deltaZ/2.;
1502  G4PVPlacement *vSub = new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentSu, nameStr + std::string("_P"),
1503  mother->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1504 
1505  if (fWaterLayerThickInHorns > 0.002*CLHEP::mm) {
1506  nameStrStr.str(""); nameStrStr.clear(); nameStrStr << "Horn1DownstrPart1SubSect" << iSub << "Water";
1507  nameStr = nameStrStr.str();
1508  G4Cons *aConsWa = new G4Cons(nameStr, rMax1 - fWaterLayerThickInHorns, rMax1-0.001*CLHEP::mm,
1509  rMax2 - fWaterLayerThickInHorns, rMax2-0.001*CLHEP::mm,
1510  (deltaZ - 0.0075*CLHEP::mm)/2., 0., 360.0*CLHEP::deg);
1511  G4LogicalVolume *pCurrentWa = new G4LogicalVolume(aConsWa, G4Material::GetMaterial(std::string("Water")), nameStr);
1512  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] =0.;
1513  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentWa, nameStr + std::string("_P"),
1514  vSub->GetLogicalVolume(), false, 1, (fCheckVolumeOverLapWC && doCheckOverlapNoG4ConsBug));
1515  }
1516  } // of the number of subsection to the neck
1517  {
1518  // Now the Hangers. (two of them.. )
1519  {
1520  G4String nameStr2ndHanger("Horn1DownstrSecondSpiderHanger");
1521  double zLocDrawing = zStartDrawing + fHorn1LongRescale*1.416*in;
1522  double zLocPosM = -1.0*(plHUpst->fParams[2])/2. + zLocDrawing + zShiftDrawingDownstr + 0.375*in*fHorn1LongRescale; // with respect to the center of
1523  // of the mother volume.
1524  this->Horn1InstallSpiderHanger( nameStr2ndHanger, zLocDrawing, zLocPosM, mother);
1525 
1526  G4String nameStrSecondHanger("Horn1DownstrThirdSpiderHanger");
1527  zLocDrawing = fHorn1LongRescale*(80.9951 + 1.791)*in;
1528 // zLocPosM = -1.0*(plHUpst->fParams[2])/2. + -1.0*(plHUpst->fParams[2])/2. + zLocDrawing + zShiftDrawingDownstr + 0.375*in*fHorn1LongRescale;
1529 // Typo, unveiled looking at the HEPRep representation, by Laura F., Aug 4-5 2015.
1530  zLocPosM = -1.0*(plHUpst->fParams[2])/2. + zLocDrawing + zShiftDrawingDownstr + 0.375*in*fHorn1LongRescale;
1531  this->Horn1InstallSpiderHanger( nameStrSecondHanger, zLocDrawing, zLocPosM, mother);
1532  }
1533  // now a few welds..
1534  std::vector<double> zLocWelds(4,0.); // Drawing coordinate system
1535  zLocWelds[0] = fHorn1LongRescale*61.0464*in;
1536  zLocWelds[1] = fHorn1LongRescale*81.0151*in;
1537  zLocWelds[2] = fHorn1LongRescale*100.9839*in;
1538  zLocWelds[3] = fHorn1LongRescale*116.5*in; // Cheat a bit, place it upstream to make sure it does not overlap with the end
1539  // April 2 .. Zeongtae notice this cheat, it manifest itself as a visible gap of a bout 1/2 inch in Z
1540  // Let us fix this by re-adjusting the position of this weld, which, after checking the end and
1541  // beginning of the sub section number 5 and flange below, we now have:
1542  zLocWelds[3] = fHorn1LongRescale*117.1126*in - 12.0*CLHEP::mm;
1543  // final adjustment to avoid collision with the flange.. Wehereby substract 1/2 of the length., +
1544  for (size_t iW=0; iW !=zLocWelds.size(); iW++) {
1545  std::ostringstream nameStrStr; nameStrStr << "Horn1DownstrPart1Weld" << iW+2;
1546  nameStr = nameStrStr.str();
1547  fHorn1IC.push_back(nameStr);
1548  const double length = 24.0*CLHEP::mm; //Cover two real sections...
1549  const double zW = zLocWelds[iW];
1550  double rTmp1 = fHorn1Equations[7].GetVal(zW + length) + 0.015*CLHEP::mm + fWaterLayerThickInHorns;
1551  // To make it a bit nice on fancy plots.
1552  if (iW == 3) rTmp1 += 0.150*CLHEP::mm; // To be safe at the downstream end.
1553  const double rTmp2 = rTmp1 + 1.8*CLHEP::mm; //
1554  G4Tubs *aTubsWn = new G4Tubs(nameStr, rTmp1, rTmp2,
1555  length/2. , 0., 360.0*CLHEP::deg);
1556  std::cerr << " Horn1, Weld " << iW << " volume name " << nameStr << " rTmp1 "
1557  << rTmp1 << " rTmp2 " << rTmp2 << std::endl;
1558  G4LogicalVolume *pCurrentWn = new G4LogicalVolume(aTubsWn, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1559  posTmp[0] = 0.; posTmp[1] = 0.;
1560  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zW + zShiftDrawingDownstr + length/2.;
1561  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentWn, nameStr + std::string("_P"),
1562  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1563  }
1564  }
1565  {
1566  //Flange for the Inner Downstream, drawing 8875-112 363096 .. Two tubes
1567  // Upstream part
1568  nameStr = std::string("Horn1InnerDownstrFlangePart0");
1569  fHorn1IC.push_back(nameStr);
1570  const double rTmp1 = fHorn1RadialRescale*(7.750*in/2.0);
1571  const double rTmp2 = fHorn1RadialRescale*(8.50*in/2.0);; //
1572  const double length = fHorn1LongRescale*(12.244 - 1.10)*in - 12.5*CLHEP::mm;
1573  // Subtract the 1/2 the length weld to avoid collision with the Horn1DownstrPart1Weld
1574  G4Tubs *aTubsFl0 = new G4Tubs(nameStr, rTmp1, rTmp2, length/2. , 0., 360.0*CLHEP::deg);
1575  G4LogicalVolume *pCurrentFl0 = new G4LogicalVolume(aTubsFl0, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1576  posTmp[0] = 0.; posTmp[1] = 0.;
1577  const double zDrawing = fHorn1LongRescale*(117.1126*in) + 12.5*CLHEP::mm; // small shift to handle collisions
1578  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zDrawing + zShiftDrawingDownstr + length/2.;
1579  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentFl0, nameStr + std::string("_P"),
1580  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1581  }
1582  {
1583  //Flange per-se drawing 8875-112 363096 ..
1584  nameStr = std::string("Horn1InnerDownstrFlangePart1");
1585  fHorn1IC.push_back(nameStr);
1586  const double rTmp1 = fHorn1RadialRescale*7.750*in/2.0 + 1.0*CLHEP::mm;
1587  const double rTmp2 = fHorn1RadialRescale*11.271*in/2.0 + 1.0*CLHEP::mm; //
1588  const double length = fHorn1LongRescale*(1.25)*in; // Add a bit for the connectors.
1589  G4Tubs *aTubsFl1 = new G4Tubs(nameStr, rTmp1, rTmp2, length/2. , 0., 360.0*CLHEP::deg);
1590  G4LogicalVolume *pCurrentFl1 = new G4LogicalVolume(aTubsFl1, G4Material::GetMaterial(fHorn1InnerCondMat), nameStr);
1591  posTmp[0] = 0.; posTmp[1] = 0.;
1592  const double zDrawing = fHorn1LongRescale*117.1126*in + fHorn1LongRescale*((12.244 - 1.10)*in + 0.5*CLHEP::mm);
1593  posTmp[2] = -1.0*(plHUpst->fParams[2])/2. + zDrawing + zShiftDrawingDownstr + length/2.;
1594  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentFl1, nameStr + std::string("_P"),
1595  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1596  }
1597 
1598 
1599  } // The downstream part of the real section that has the neck.
1600 
1601  // The outer flange (downstream connector and bulk heads) Just a relatively thick tube.
1602  {
1603  nameStr = G4String("Horn1OuterTubeDowsntreamFlanges");
1604  const double rTmp1 = fHorn1OuterTubeOuterRad + 2.0*CLHEP::mm;
1605  const double rTmp2 = 23.5*in/2.; //
1606  const double length = 3.0*in;
1607  const double zDrawing = (117.1126 + 6.0)*in*fHorn1LongRescale; // 6" is still aproximate
1608  G4Tubs *aTubsFl = new G4Tubs(nameStr, rTmp1, rTmp2, length/2. , 0., 360.0*CLHEP::deg);
1609  G4LogicalVolume *pCurrentFl = new G4LogicalVolume(aTubsFl, G4Material::GetMaterial(fHorn1AllCondMat), nameStr);
1610  posTmp[0] = 0.; posTmp[1] = 0.;
1611  posTmp[2] =-1.0*(plHUpst->fParams[2])/2. + zDrawing + zShiftDrawingDownstr + length/2.; ;
1612  new G4PVPlacement((G4RotationMatrix *) 0, posTmp, pCurrentFl, nameStr + std::string("_P"),
1613  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1614  }
1615 
1616 
1617 }
1618 //
1619 // Simple Horn1, based on a Polycone, for 1rst stage optimization of Horn1 September 2014.
1620 // Revised Oct. 2015, for more clarity and fix a small volume overlap at the edge of the outer conductor.
1621 // Also fix a sign mistake in addition of epsil..
1622 //
1624  //
1625  // Convert the array of 3-vector to the fMotherHorn1AllLengths, AllRads
1626  //
1627 
1628  fMotherHorn1AllLengths.clear();
1629  fMotherHorn1AllRads.clear();
1630  if (fHorn1PolyListRinThickZVects.size() != static_cast<size_t>(fUseHorn1PolyNumInnerPts)) {
1631  G4Exception("LBNEVolumePlacements::UpdateParamsForHorn1MotherPoly",
1632  " ", FatalErrorInArgument, "Inconsistency in sizing Hor1 Polycone ");
1633  }
1634  const double epsil = 0.050*CLHEP::mm;
1635  const double thickInnerAtZStart = fHorn1PolyListRinThickZVects[0][1];
1636  //
1637  // This "fMotherHornsAll" Lengths/Radiis is used to defined
1638  // The first point in these arrays is located on the external surface of the outer conductor, most upstream point
1639  // We set the point to be epsil away from the physical conductor. We add the thickness of the innerconductor
1640  // to avoid volume overlap when we will define the IC, and the water layer. This is clearly unphysical, but avoids
1641  // the complexity of having to define more volumes.
1642  // Note the water layer thickness is assumed to be uniform across the length of the device. Clearly wrong...
1643  // This is a more serious approximation...
1644  //
1645  const double rOut = fHorn1PolyOuterRadius + 2.5*CLHEP::cm + epsil + thickInnerAtZStart + fWaterLayerThickInHorns;
1646  fHorn1OuterTubeOuterRad = rOut;
1647  fMotherHorn1AllRads.push_back(rOut);
1648  fMotherHorn1AllLengths.push_back(0.);
1649  for(size_t k=0; k != fHorn1PolyListRinThickZVects.size(); k++) {
1650  const double r = fHorn1PolyListRinThickZVects[k][0] - epsil ;
1651  // Should be needed for k != 0, but easier this way. The location of the IC will be off by epsil,
1652  // no physics inplications..
1653  const double z = fHorn1PolyListRinThickZVects[k][2] + epsil;
1654  fMotherHorn1AllLengths.push_back(z);
1655  fMotherHorn1AllRads.push_back(r);
1656  }
1657  if (std::abs(fHorn1PolyListRinThickZVects[0][2]) > 1.0e-10) {
1658  G4Exception("LBNEVolumePlacements::UpdateParamsForHorn1MotherPoly",
1659  " ", FatalErrorInArgument, " The first point must be at Z =0., for consistency... ");
1660  }
1661  //
1662  // Now the outer...extended a bit (kind of arbitrary at this point in time.. )
1663  //
1664  const double zLast = fHorn1PolyListRinThickZVects[fHorn1PolyListRinThickZVects.size()-1][2] + 2.0*epsil;
1665  fMotherHorn1AllLengths.push_back(zLast);
1666  fMotherHorn1AllRads.push_back(rOut);
1667  fHorn1Length = zLast + 1.0*CLHEP::mm;
1668  std::cerr << " LBNEVolumePlacements::UpdateParamsForHorn1MotherPoly, total length of Horn1 " <<
1669  zLast << " Outer Radius " << rOut << std::endl;
1670 }
1671 //
1672 // Generalization for multiple simple horns, ranging from 0 to 4.
1673 //
1675  //
1676  // Convert the array of 3-vector to the fMotherHorn1AllLengths, AllRads
1677  //
1678  const bool debugIsOn = false;
1679  if (debugIsOn) std::cerr << " LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum, index " << iH << std::endl;
1680  if (fMotherHornsAllLengths.size() != static_cast<size_t>(fUseNumberOfHornsPoly)) {
1681  G4Exception("LBNEVolumePlacements::UpdateParamsForHornsMotherPoly",
1682  " ", FatalErrorInArgument, "Inconsistency in the number of simple Polycone Horns ");
1683  }
1684  if ((iH >= fMotherHornsAllLengths.size()) || (iH >= fMotherHornsAllRads.size())) {
1685  G4Exception("LBNEVolumePlacements::UpdateParamsForHornsMotherPoly",
1686  " ", FatalErrorInArgument, "Inconsistency in indexing simple Polycone Horns number");
1687  }
1688  fMotherHornsAllLengths[iH].clear();
1689  fMotherHornsAllRads[iH].clear();
1690  fMotherHornsAllThick[iH].clear();
1691 
1692  if (fHornsPolyListRinThickZVects[iH].size() != static_cast<size_t>(fUseHornsPolyNumInnerPts[iH])) {
1693  std::ostringstream message; message << " Inconsistency in sizing Horn Polycone " << iH;
1694  std::string messStr(message.str());
1695  G4Exception("LBNEVolumePlacements::UpdateParamsForHornsMotherPoly",
1696  " ", FatalErrorInArgument, messStr.c_str());
1697  }
1698  //
1699  // This "fMotherHornsAll" Lengths/Radiis is used to defined
1700  // The first point in these arrays is located on the external surface of the outer conductor, most upstream point
1701  // We set the point to be epsil away from the physical conductor. We add the thickness of the innerconductor
1702  // to avoid volume overlap when we will define the IC, and the water layer. This is clearly unphysical, but avoids
1703  // the complexity of having to define more volumes.
1704  // Note the water layer thickness is assumed to be uniform across the length of the device. Clearly wrong...
1705  // This is a more serious approximation...
1706  //
1707  const double epsil = 0.050*CLHEP::mm;
1708  const double thickInnerAtZStart = fHornsPolyListRinThickZVects[iH][0][1];
1709  const double rOut = fHorn1PolyOuterRadius + 2.5*CLHEP::cm + epsil + thickInnerAtZStart + fWaterLayerThickInHorns;
1710  fHorn1OuterTubeOuterRad = rOut;
1711  fMotherHornsAllRads[iH].push_back(rOut);
1712  fMotherHornsAllLengths[iH].push_back(0.);
1713  fMotherHornsAllThick[iH].push_back(0.25*25.4*CLHEP::mm);
1714  if (debugIsOn) std::cerr<< " LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum... for IH "
1715  << iH <<std::endl; /* for debugging */
1716  for(size_t k=0; k != fHornsPolyListRinThickZVects[iH].size(); k++) {
1717  const double r = fHornsPolyListRinThickZVects[iH][k][0] - epsil;
1718  const double z = fHornsPolyListRinThickZVects[iH][k][2] + epsil;
1719  const double thick = fHornsPolyListRinThickZVects[iH][k][1];
1720  if (debugIsOn) std::cerr<< " ..... at k "<< k << " z " << fHornsPolyListRinThickZVects[iH][k][2]
1721  << " r "<< fHornsPolyListRinThickZVects[iH][k][0]
1722  << " thick " << thick << std::endl; /* for debugging */
1723  // Not the last point
1724  if (fPolyconeHornsAreParabolic[iH]) {
1725  if(k+1!=fHornsPolyListRinThickZVects[iH].size()){
1726  // If the radius changes it could, should be a parabola
1727  if (debugIsOn) std::cerr<< " ..... Delta R at k "<< k << " to " << k+1 << " = " <<
1729  if(std::abs(fHornsPolyListRinThickZVects[iH][k][0] - fHornsPolyListRinThickZVects[iH][k+1][0]) > 1.5*mm){
1730  double a=(fHornsPolyListRinThickZVects[iH][k][2]-fHornsPolyListRinThickZVects[iH][k+1][2])/
1733  // z=a*r^2+c --> a=(z1-z2)/(r1^2-r2^2)
1734 // Check for a flange ... a flange is a very rapid change in r over small change in z
1735 // if(std::abs(a)<1.e-4)continue;
1736  if (debugIsOn) std::cerr<< " ....radial jump... at k "<< k << " a " << a << std::endl; /* for debugging */
1737  if(std::abs(a)<1.e-4){
1738  fMotherHornsAllLengths[iH].push_back(z);
1739  fMotherHornsAllRads[iH].push_back(r);
1740  fMotherHornsAllThick[iH].push_back(fHornsPolyListRinThickZVects[iH][k][1]);
1741  } else {
1742  double c= fHornsPolyListRinThickZVects[iH][k][2]
1744  // 1 mm radial spacing? Number of points
1745  int np=((int)std::abs(fHornsPolyListRinThickZVects[iH][k][0]-fHornsPolyListRinThickZVects[iH][k+1][0]))+1;
1746  double rstep=(fHornsPolyListRinThickZVects[iH][k][0]-fHornsPolyListRinThickZVects[iH][k+1][0])/(double)np;
1747  if (debugIsOn) std::cerr<< " ..... ..... Parabolic section intiated at k... "<< k << " a " << a << " c " << c <<
1748  " np " << np << " z "<< z << std::endl; /* for debugging */
1749  for(int numr=0; numr<np; numr++){
1750  double radTmp1=fHornsPolyListRinThickZVects[iH][k][0]-numr*rstep;
1751  double zl=a*(radTmp1*radTmp1)+c-epsil;
1752  double rl = (radTmp1 > epsil) ? (radTmp1 - epsil) : radTmp1;
1753  fMotherHornsAllLengths[iH].push_back(zl);
1754  fMotherHornsAllRads[iH].push_back(rl);
1755  fMotherHornsAllThick[iH].push_back(fHornsPolyListRinThickZVects[iH][k][1]);
1756  // std::cout<<"HornsPoly "<<zl<<" "<<rl<<std::endl; /* for debugging */
1757  }
1758  }
1759  } else { // If no change in radius just a pipe. Change z keep r fixed
1760  fMotherHornsAllLengths[iH].push_back(z);
1761  fMotherHornsAllRads[iH].push_back(r);
1762  fMotherHornsAllThick[iH].push_back(fHornsPolyListRinThickZVects[iH][k][1]);
1763  if (fPolyconeHornsAreParabolic[iH]) std::cerr << " ..... Keep linear profile at k " << k << std::endl;
1764  }
1765  } else { // the last point
1766  fMotherHornsAllLengths[iH].push_back(z);
1767  fMotherHornsAllRads[iH].push_back(r);
1768  fMotherHornsAllThick[iH].push_back(fHornsPolyListRinThickZVects[iH][k][1]);
1769  }
1770  } else { // linear horns..
1771  fMotherHornsAllLengths[iH].push_back(z);
1772  fMotherHornsAllRads[iH].push_back(r);
1773  fMotherHornsAllThick[iH].push_back(thick);
1774  }
1775  } // on number of segments.
1776 
1777  const G4ThreeVector dataRZT = fHornsPolyListRinThickZVects[iH][0];
1778  if (dataRZT[2] > 1.0e-10) {
1779  std::ostringstream message;
1780  message << " The first point must be at Z =0., for consistency.. Horn " << (iH +1)
1781  << " Z-begin " <<dataRZT[2];
1782  std::string messStr(message.str());
1783  G4Exception("LBNEVolumePlacements::UpdateParamsForHornMotherPoly",
1784  " ", FatalErrorInArgument, messStr.c_str());
1785  }
1786  const double zLast = fHornsPolyListRinThickZVects[iH][fHornsPolyListRinThickZVects[iH].size()-1][2] + 2.0*epsil;
1787  fMotherHornsAllLengths[iH].push_back(zLast);
1788  fMotherHornsAllRads[iH].push_back(rOut);
1789  fHornsLength[iH] = zLast + 2.0*epsil;
1790  fMotherHornsAllThick[iH].push_back(0.25*25.4*CLHEP::mm);
1791  if (debugIsOn) std::cerr << " LBNEVolumePlacements::UpdateParamsForHornMotherPoly, total length of Horn " << (iH + 1) <<
1792  " = " << zLast << " Length of thickneses " << fMotherHornsAllThick[iH].size() << std::endl;
1793  //
1794  // Check the consistency
1795  //
1796  for (size_t iHH = 0; iHH != static_cast<size_t>(fUseNumberOfHornsPoly); iHH++) {
1797 // std::cerr << " LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum, checks, at Horn " << (iHH+1)
1798 // << " ZStart " << fHornsPolyZStartPos[iHH] << std::endl;
1799  if (fHornsPolyZStartPos[iHH] < -5000.*CLHEP::m) continue; // Not declared yet.
1800  if ((iHH != 0) && (fHornsPolyZStartPos[iHH-1] > fHornsPolyZStartPos[iHH-1])) {
1801  std::ostringstream mStrStr; mStrStr
1802  << " The Polycones Horns must be declared in sequential order along the beam axis, \n "
1803  << " Upstream to downstream. Problem for Horn "
1804  << (iHH) << " to " << (iHH+1);
1805  std::string mStr(mStrStr.str());
1806  G4Exception("LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum",
1807  " ", FatalErrorInArgument, mStr.c_str());
1808 
1809  }
1810  double zPosPtLast = fMotherHornsAllLengths[iHH][fMotherHornsAllLengths[iHH].size()-1];
1811  double zCurr = fHornsPolyZStartPos[iHH] + zPosPtLast + 1.0*CLHEP::mm;
1812  bool badLength= false;
1813  std::ostringstream mblStrStr;
1814  if (iHH == static_cast<size_t>(fUseNumberOfHornsPoly-1)) {
1815  badLength = (zCurr > fDecayPipeLongPosition);
1816  if (badLength)
1817  mblStrStr << " Likely longitudinal overlap for Horn "
1818  << (iHH+1) << " Z End of this horn " << zCurr/CLHEP::m << " meters" << std::endl
1819  << " ZStart of this horn " << fHornsPolyZStartPos[iHH] << " length"
1820  << zPosPtLast << " Start of decay Pipe " << fDecayPipeLongPosition << std::endl;
1821  } else {
1822  badLength = ((zCurr + 1.0*CLHEP::mm) > fHornsPolyZStartPos[(iHH+1)]);
1823  if (badLength)
1824  mblStrStr << " Likely longitudinal overlap for Horn "
1825  << (iHH+1) << " Z End of this horn " << zCurr/CLHEP::m << " meters" << std::endl
1826  << " ZStart of this horn " << fHornsPolyZStartPos[iHH] << " length "
1827  << zPosPtLast << " Start ofNext horn " << fHornsPolyZStartPos[iHH+1] << std::endl;
1828  }
1829  if (badLength) {
1830  std::string mblStr(mblStrStr.str());
1831  G4Exception("LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum",
1832  " ", FatalErrorInArgument, mblStr.c_str());
1833  }
1834  const bool badOutRadius = (fHornsPolyOuterRadius[iH] > (fChaseWidthForLBNF - 152.4*CLHEP::mm));
1835  if (badOutRadius) {
1836 
1837  std::ostringstream mStrStr;
1838  mStrStr << " Horn " << (iHH+1)
1839  << " will not fit easily into the Chase, outer radius too big, " << fHornsPolyOuterRadius[iH] << " meters";
1840  std::string mStr(mStrStr.str());
1841  G4Exception("LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum",
1842  " ", FatalErrorInArgument, mStr.c_str());
1843 
1844  }
1845  }
1846  if (iH == 0) { // copy the parameters to the old (Sept. 2014 ) arrays for Horn1
1850  fHorn1Length = fMotherHornsAllLengths[iH][fMotherHornsAllLengths[iH].size()-1] + 1.0*CLHEP::mm;
1851  if (debugIsOn) std::cerr << " LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum, setting Horn1 length to " <<
1853  }
1854  // make sure they are all defined...
1855  if (iH == fMotherHornsAllLengths.size()-1) this->DumpAllHornsPolyconeParameters();
1856 }
1857 
1859  const double epsil = 0.050*CLHEP::mm;
1860  for (size_t iH=0; iH != fMotherHornsAllLengths.size(); iH++) {
1861  std::ostringstream aNStrStr; aNStrStr << "./AllHornsPolyconeParametersHorn_" << (iH+1) << ".txt";
1862  std::string aNStr(aNStrStr .str());
1863  std::ofstream fOut(aNStr.c_str());
1864  fOut << " ip Z Rin ROut " << std::endl;
1865  for (size_t k=0; k != fMotherHornsAllLengths[iH].size(); k++) {
1866  fOut << " " << k << " " << fMotherHornsAllLengths[iH][k] - epsil
1867  << " " << fMotherHornsAllRads[iH][k] + epsil << " "
1868  << fMotherHornsAllRads[iH][k] + epsil + fMotherHornsAllThick[iH][k] << std::endl; // Not counting the water layer.
1869  }
1870  fOut.close();
1871  }
1872 }
1873 void LBNEVolumePlacements::PlaceFinalSimpleHornPolyNumber(size_t iH, G4PVPlacement *mother) {
1874 
1875 // Place the inner conductor. A G4Polycone, fitting inside the mother G4Polycone, or the tube.
1876 // Note that we create a few temporary arrrays, first for the outer raddi of the inner conducter itself
1877 // second, for the water layer (inside the inner conductor, to make the volume tree logical hierachy more vertical)
1878 // The number of points on the inner C polygon (and the water layer ) is 2*(fMotherHornsAllRads.size() -2),
1879 // since we skip the outer conductor, but we install the nearly vertical flange.
1880 // Correction: we do not put a water layer on the vertical flange..
1881 //
1882  const bool debugIsOn = false;
1883  if (debugIsOn) std::cerr << " LBNEVolumePlacements::PlaceFinalSimpleHornPolyNumber " << iH << " num segments "
1884  << fMotherHornsAllRads[iH].size() << std::endl;
1885  std::vector<double> innerRads(fMotherHornsAllRads[iH].size()-2);
1886  std::vector<double> innerZs(fMotherHornsAllLengths[iH].size()-2);
1887  // Skip the outer conductor.
1888  if (debugIsOn) std::cerr << " ................. innerRads size " << innerRads.size() << std::endl;
1889  for (size_t k=1; k!= fMotherHornsAllRads[iH].size()-1; k++) {
1890  innerRads[k-1] = fMotherHornsAllRads[iH][k];
1891  innerZs[k-1] = fMotherHornsAllLengths[iH][k];
1892  }
1893  std::vector<double> allRads(innerRads); // not yet full size... Only 1/2 of it.
1894  std::vector<double> allZs(innerZs);
1895  std::vector<double> outerRads(innerRads.size(), 0.); // covering volume (rin + thick + water + epsil)
1896  const double epsil = 0.050*CLHEP::mm;
1897  double zMax = -1.0e23;
1898  double zMin = 1.0e23;
1899  for (size_t k=0; k != allZs.size(); k++) {
1900  allRads[k] += epsil;
1901  allZs[k] -= epsil;
1902  innerRads[k] += epsil;
1903  innerZs[k] -= epsil;
1904  zMax = std::max(zMax, innerZs[k]);
1905  zMin = std::min(zMin, innerZs[k]);
1906  outerRads[k] = innerRads[k] + fMotherHornsAllThick[iH][k];
1907  }
1908  // Futher at the edges.
1909  innerZs[0] += epsil;
1910  innerZs[innerZs.size()-1] -= epsil;
1911  allZs[0] += epsil;
1912  allZs[allZs.size()-1] -= epsil;
1913  //
1914  // Now we implement the return loop, downstream to upstream. We made two arrays, such that, if the "all" vector move in memory,
1915  // we are safe...
1916  //
1917  size_t nPtsHalf = innerZs.size();
1918  const double thickUsptream = fMotherHornsAllThick[iH][1]; // Index 1 : the first thicknes is the outer conductor...
1919  const double thickDownstream = (fMotherHornsAllThick[iH].size() < 2) ?
1920  thickUsptream : fMotherHornsAllThick[iH][fMotherHornsAllThick[iH].size()-2];
1921  if (debugIsOn) std::cerr << " Vertical Flange thicknesses, upstream "
1922  << thickUsptream << " downstream " << thickDownstream << std::endl;
1923  for (size_t k=0; k != nPtsHalf; k++) {
1924  size_t kk = nPtsHalf -1 - k;
1925  double zzLocal = innerZs[kk];
1926  if (k == 0) zzLocal -= thickDownstream;
1927  if (kk == 0) zzLocal += thickUsptream; // to avoid R-Z crossing for the vertical flange
1928  // only valid if the flange is vertical.. Hopefully, this is the case for all the Horns Laura F. is considering.
1929  if (k == 1) zzLocal -= thickDownstream;
1930  if (kk == 1) zzLocal += thickUsptream; // to avoid R-Z crossing for the vertical flange
1931  double radius = outerRads[kk];
1932  if (k == 0) radius = outerRads[kk] - thickDownstream; // Again, valid only if flange is nearly vertical.
1933  if (kk == 0) radius = outerRads[kk] - thickUsptream; // Again, valid only if flange is nearly vertical.
1934  allRads.push_back(radius);
1935  allZs.push_back(zzLocal);
1936  zMax = std::max(zMax, zzLocal);
1937  zMin = std::min(zMin, zzLocal);
1938  }
1939  //
1940  // We shift the Z position by half the length, such the relative definition is the same as for the other volumes.
1941  std::vector<double> zz(allZs);
1942  const double zMiddle = (zMax + zMin)/2.;
1943  if (debugIsOn) std::cerr << " .................. Zmin " << zMin << " max " << " zMax "
1944  << zMax << " zMiddle " << zMiddle << std::endl
1945  << " .................. InnerRads size " << innerRads.size() << std::endl;
1946  for (std::vector<double>::iterator il = zz.begin(); il != zz.end(); il++) *il -= zMiddle;
1947  if (debugIsOn) {
1948  std::ostringstream aNStrStr; aNStrStr << "./AllHornsPolyconeParametersHornInner_" << (iH+1) << ".txt";
1949  std::string aNStr(aNStrStr .str());
1950  std::ofstream fOut(aNStr.c_str());
1951  fOut << " ip Z R " << std::endl;
1952  for (size_t k=0; k != allZs.size(); k++) {
1953  fOut << " " << k << " " << zz[k] << " " << allRads[k] << " " << std::endl;
1954  }
1955  fOut.close();
1956  }
1957 
1958  std::ostringstream vNameInnerStr; vNameInnerStr << "Horn" << (iH+1) << "PolyInnerC";
1959  G4String vNameInner(vNameInnerStr.str());
1960  fHorn1IC.push_back(vNameInner);
1961  G4GenericPolycone* aPCon = new G4GenericPolycone(vNameInner, 0., 360.0*CLHEP::deg, static_cast<int>(zz.size()),
1962  &allRads[0], &zz[0]);
1963  G4ThreeVector posTmp; posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
1964  G4LogicalVolume *pCurrent = new G4LogicalVolume(aPCon,
1965  G4Material::GetMaterial(std::string(fHorn1InnerCondMat)), vNameInner);
1966  new G4PVPlacement((G4RotationMatrix *) 0,
1967  posTmp, pCurrent, vNameInner + std::string("_P"),
1968  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
1969 
1970  if (debugIsOn) std::cerr << " LBNEVolumePlacements::PlaceFinalSimpleHornPolyNumber ... Inner conductor placed " << std::endl;
1971  if (std::abs(fWaterLayerThickInHorns) > 0.00002*CLHEP::mm) {
1972  // We assume that there are no water on vertical flange...
1973  if (innerRads.size() < 2) {
1974  std::ostringstream mStrStr;
1975  mStrStr << " Horn " << (iH+1)
1976  << " has to few segments ( " << innerRads.size() <<" ) to support a water layer.. Review the geometry. ";
1977  std::string mStr(mStrStr.str());
1978  G4Exception("LBNEVolumePlacements::PlaceFinalSimpleHornPolyNumber",
1979  " ", JustWarning, mStr.c_str());
1980  } else {
1981  //
1982  // We skip the vertical flange..
1983  //
1984  std::vector<double> innerWaterRads((outerRads.size()-2), 0.); // Aluminum only. (rin + thick + water + epsil)
1985  std::vector<double> innerWaterZs(innerWaterRads.size(), 0.);
1986  for (size_t k=1; k != innerRads.size()-1; k++) {
1987  innerWaterRads[k-1] = outerRads[k] + 2.0*epsil; // to take possible edge effect away, for sharped angle sections (unphysical, anyways..)
1988  innerWaterZs[k-1] = zz[k]; // we take the shifted array, to ease debugging, and avoid volume overlap.
1989  if (k == 1) innerWaterZs[k-1] += 2.0*thickUsptream; // Chop the most upstream section, it clashes with vertical flange.
1990  else if (k == (innerRads.size()-2)) innerWaterZs[k-1] -= 2.0*thickDownstream; // same, assume symmetrical thickness.
1991  // assume it will fit, otherwise...
1992  }
1993  //
1994  // Now we implement again the same the return loop, downstream to upstream.
1995  size_t nPtsWHalf = innerWaterZs.size();
1996  std::vector<double> allWaterRads(innerWaterRads);
1997  std::vector<double> allWaterZs(innerWaterZs);
1998 // double zWMin = 1.0e23; double zWMax = -1.0e23;
1999  for (size_t k=0; k != nPtsWHalf; k++) {
2000  size_t kk = nPtsWHalf -1 - k;
2001  allWaterRads.push_back(allWaterRads[kk] + fWaterLayerThickInHorns);
2002  allWaterZs.push_back(innerWaterZs[kk]);
2003 // zWMin = std::min(innerWaterZs[kk], zWMin);
2004 // zWMax = std::max(innerWaterZs[kk], zWMax);
2005  }
2006  //
2007  // We do not shift, we are already in the correct frame with respect to the mother volume.
2008  // important if the thicknesses of the flange are asymmetric.
2009  //
2010  std::vector<double> zzWater(allWaterZs);
2011 // const double zWMiddle = (zWMax + zWMin)/2.;
2012 // if (debugIsOn) std::cerr << " .................. ZWmin " << zWMin << " max " << " zWMax "
2013 // << zWMax << " zWMiddle " << zWMiddle << std::endl;
2014 // for (std::vector<double>::iterator il = zzWater.begin(); il != zzWater.end(); il++) *il -= zWMiddle;
2015  if (debugIsOn) {
2016  std::cerr << ".......... ... Water layer placed, nPtsWHalf " << nPtsWHalf << std::endl;
2017  std::ostringstream aNStrStr; aNStrStr << "./AllHornsPolyconeParametersHornInnerWater_" << (iH+1) << ".txt";
2018  std::string aNStr(aNStrStr .str());
2019  std::ofstream fOut(aNStr.c_str());
2020  fOut << " ip Z R " << std::endl;
2021  for (size_t k=0; k != zzWater.size(); k++) {
2022  fOut << " " << k << " " << zzWater[k] << " " << allWaterRads[k] << " " << std::endl;
2023  }
2024  fOut.close();
2025  }
2026  std::ostringstream vNameInnerWStr; vNameInnerWStr << "Horn" << (iH+1) << "PolyInnerCWaterL";
2027  G4String vNameInnerW(vNameInnerWStr.str());
2028  G4GenericPolycone* aPConW5 = new G4GenericPolycone(vNameInnerW, 0.*CLHEP::deg, 360.0*CLHEP::deg, static_cast<int>(allWaterRads.size()),
2029  &allWaterRads[0], &zzWater[0]);
2030  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
2031  G4LogicalVolume *pCurrentW5 = new G4LogicalVolume(aPConW5,
2032  G4Material::GetMaterial(std::string("Water")), vNameInnerW);
2033  new G4PVPlacement((G4RotationMatrix *) 0,
2034  posTmp, pCurrentW5, vNameInnerW + std::string("_P"),
2035  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
2036  }
2037  }
2038  //
2039  // Now the outer Tube
2040  //
2041  const double rOuterInner = fHornsPolyOuterRadius[iH] - 0.250*25.4*CLHEP::mm - 0.1*CLHEP::mm;
2042  const double rOuterOuter = fHornsPolyOuterRadius[iH] - 0.1*CLHEP::mm;
2043  const double lengthOT = fHornsPolyListRinThickZVects[iH][fUseHornsPolyNumInnerPts[iH]-1][2] - 5.0*CLHEP::mm; // to fit inside the edges of IC
2044  std::ostringstream nameOTStr; nameOTStr << "Horn" << (iH+1) << "OuterC";
2045  G4String nameOT(nameOTStr.str());
2046  G4Tubs *aTubs = new G4Tubs(nameOT, rOuterInner, rOuterOuter, lengthOT/2., 0., 360.0*CLHEP::deg);
2047  G4LogicalVolume *pCurrentOT = new G4LogicalVolume(aTubs, G4Material::GetMaterial(fHorn1InnerCondMat), nameOT);
2048  new G4PVPlacement((G4RotationMatrix *) 0,
2049  posTmp, pCurrentOT, nameOT + std::string("_P"),
2050  mother->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
2051 
2052 }
2053 //
2054 // Re-issuing the NuMI target, circa Feb 2014,
2055 //
2057 
2058  const G4double in = 2.54*CLHEP::cm;
2059 
2060  fTargetSLength = fTargetSLengthDownstrEnd + fTargetSLengthGraphite; // Russian drawing 7589-00-00-00
2061  fTargetLengthOutsideHorn = fTargetSLength - fTargetLengthIntoHorn + fTargetFinLength; // why + one fin Transition fin...
2062  fTargetFinSpacingLength = 0.3*CLHEP::mm; // Nominal value..
2063  double targetNumFinsNominal = fTargetSLengthGraphite/(fTargetFinLength + fTargetFinSpacingLength);
2064  fTargetNumFins = (int) (targetNumFinsNominal + 0.5);
2065  double deltaNumFins = targetNumFinsNominal - (double) fTargetNumFins;
2066  if (deltaNumFins > 0.5) fTargetNumFins++;
2067  if (deltaNumFins < -0.5) fTargetNumFins--;
2068  std::cerr << " LBNEVolumePlacements::SegmentTargetSmallTgt, total number of segments " << fTargetNumFins <<
2069  " Delta Num fins " << deltaNumFins << std::endl;
2070  std::cerr << " fTargetSLength " << fTargetSLength
2071  << " fTargetLengthOutsideHorn " << fTargetLengthOutsideHorn << std::endl;
2072  const double oldLength = fTargetSLengthGraphite;
2073  fTargetSLengthGraphite = fTargetNumFins*fTargetFinLength + (fTargetNumFins-1)*fTargetFinSpacingLength;
2074  fTargetFinSpacingLength = (fTargetSLengthGraphite - fTargetNumFins*fTargetFinLength)/(fTargetNumFins - 1); //
2075  if (std::abs(oldLength - fTargetSLengthGraphite) > 0.001*fTargetSLengthGraphite)
2076  std::cout << " LBNEVolumePlacements::SegmentTargetSmallTgt: Warning: re-adjust the target length from " <<
2077  oldLength << " to " << fTargetSLengthGraphite << " to get an integer number of 2 cm long segments " << std::endl;
2078  // Compute the number of fins upstream and dowsntream of the break between target and horn1.
2079 
2080  double tempNFins = (fTargetLengthOutsideHorn - fTargetFinSpacingLength) /(fTargetFinLength + fTargetFinSpacingLength);
2081  fTargetNumFinsUpstr = (int) tempNFins; // Obsolete.. kept to confuse the chinese...
2082  // more deduced variables..
2083 // fTargetHeContTubeLengthInHorn = fTargetLengthIntoHorn + fTargetSLengthDownstrEnd;
2088  + fTargetDownstrCanFlangeThick + fTargetFlangeThick + 0.2*CLHEP::mm + 44.18*in +
2089  fTargetUpstrDwnstrMargin + fTargetDistFlangeToTargetStart + fTargetLengthOutsideHorn + 2.0*CLHEP::mm;
2090  // NUMI Drawing 8875.000-ME-363028 with 2 mm margin of error.
2093  fTargetAlignRingSpacing *= fTargetSLengthGraphite/953.8*CLHEP::mm; // must fit 5 rings within the prescribed space.
2094 // std::cerr << " Target after segmentation " << fTargetSLengthGraphite << std::endl;
2097  // Approximate...
2100  fTargetUpstrDwnstrMargin + fTargetDistFlangeToTargetStart + fTargetLengthOutsideHorn + 2.0*CLHEP::mm;
2101  // NUMI Drawing 8875.000-ME-363028 with 2 mm margin of error.
2102  std::cerr << " Lengths, fTargetUpstrDwnstrMargin " << fTargetUpstrDwnstrMargin
2103  << " fTargetDistFlangeToTargetStart " << fTargetDistFlangeToTargetStart
2104  << " fTargetSLength " << fTargetSLength << std::endl;
2105  std::cerr << " End of LBNEVolumePlacements::SegmentTargetSmallTgt " << std::endl;
2106 }
2107 
2108 void LBNEVolumePlacements::PlaceRALTGTv1(G4PVPlacement *mother){
2109  fUseRALTGTv1 = true;
2110  fUse1p2MWSmallTgt = false;
2111  fUseSimpleTargetCylinder = true;
2112 
2113 
2114  const G4LogicalVolume *lVolMother = mother->GetLogicalVolume();
2115  std::cerr << " Installing the RAL target version 1 "
2116  << lVolMother->GetName() << std::endl;
2117 
2118 
2119 //Target Hall and Horn 1
2120  const G4LogicalVolume *lVolMotherForTargetNoSPlitM1 = fTargetHorn1HallPhysPtr->GetLogicalVolume();
2121  std::cerr << " Installing TargetNoSplitM1 in "
2122  << lVolMotherForTargetNoSPlitM1->GetName() << std::endl;
2123 
2124 
2125 //Target Upstream M Top ( just as a mother volume, it is not actually placed )
2126  std::string targetTopStr("TargetUpstrMTop");
2127  Create(targetTopStr);
2128 
2129 
2130 //Construction of the outer helium containment tube with the tapered region and the spherical endcap
2131 
2132  G4String targetNSStr = std::string("TargetNoSplitM1");
2133  Create(targetNSStr);
2134  G4PVPlacement *vMt2 = PlaceFinal(targetNSStr, fTargetHorn1HallPhysPtr);
2135  std::cerr << " .. " << targetNSStr
2136  << " is now placed in PlaceFinalUpstrTarget1p2MW...in fTargetHorn1HallPhysPtr " << std::endl;
2137 
2138 
2139 //Helium filling of the outer helium containment tube with the tapered region and the spherical endcap
2140 
2141  G4String targetNSHelium("TargetNoSplitM1Helium");
2142  Create(targetNSHelium);
2143  G4PVPlacement *TNSvmt1 = PlaceFinal(targetNSHelium, vMt2);
2144 
2145 
2146 //Construction of the inner helium containment simple cylinder that will house the target
2147 
2148  G4String targetNSHeCont("TargetNoSplitHeContainer");
2149  Create(targetNSHeCont);
2150  //PlaceFinal(targetNSHeCont, fTargetHorn1HallPhysPtr);
2151  PlaceFinal(targetNSHeCont, TNSvmt1);
2152 
2153 
2154 //Construction of the simple cylindrical graphite target
2155 
2156  PlaceFinalRALTarget(TNSvmt1);
2157 
2158 //Construction of the cylindrical helium containment tube that will house the bafflet
2159 
2160  G4String targetNSBaffletMoth("TargetNoSplitCoolingTubeFirstMoth");
2161  Create(targetNSBaffletMoth);
2162  G4PVPlacement* HeCont2 = PlaceFinal(targetNSBaffletMoth, fTargetHorn1HallPhysPtr);
2163 
2164 
2165 //Helium filling of the cylindrical helium containment tube that will house the bafflet
2166 
2167  G4String targetNSBaffletMothHe("TargetNoSplitCoolingTubeFirstHelium");
2168  Create(targetNSBaffletMothHe);
2169  G4PVPlacement *MothHelium = PlaceFinal(targetNSBaffletMothHe, HeCont2);
2170 
2171 
2172 //Construction of the bafflet and the downstream bafflet flanging section
2173 
2174 
2175  G4String targetNSBafflet("TargetNoSplitSimpleBafflet");
2176  Create(targetNSBafflet);
2177 if (!fRemoveRALBafflet){
2178 
2179  PlaceFinal(targetNSBafflet, MothHelium);
2180 }
2181 
2182  G4String targetNSBaffletFlangeOut("TargetNoSplitSimpleBaffletFlange");
2183  Create(targetNSBaffletFlangeOut);
2184 if (!fRemoveRALBafflet){
2185  PlaceFinal(targetNSBaffletFlangeOut, MothHelium);
2186 }
2187 
2188 //Construction of the curved cold helium tube that is connected to the bafflet containment tube
2189 
2190  G4String targetNSBaffletCold("TargetNoSplitBaffletCold");
2191  Create(targetNSBaffletCold);
2192  G4PVPlacement* HeCont1 = PlaceFinal(targetNSBaffletCold, fTargetHorn1HallPhysPtr);
2193 
2194 
2195 //Helium filling of the curved cold helium tube that is connected to the bafflet containment tube
2196 
2197  G4String targetNSBaffletColdHe("TargetNoSplitBaffletColdHe");
2198  Create(targetNSBaffletColdHe);
2199  PlaceFinal(targetNSBaffletColdHe, HeCont1);
2200 
2201 
2202 
2203 
2204 //Constructing the large conical section upstream of the helium cooling tube that houses the target (incomplete)
2205 
2206  G4String targetBaffletFlange("TargetNoSplitLargeCone");
2207  Create(targetBaffletFlange);
2208  G4PVPlacement* HeCont3 = PlaceFinal(targetBaffletFlange, fTargetHorn1HallPhysPtr);
2209 
2210 
2211 //Helium filling of the large conical section upstream of the helium cooling tube that houses the target (incomplete)
2212 
2213  G4String targetBaffletFlangeHe("TargetNoSplitLargeConeHe");
2214  Create(targetBaffletFlangeHe);
2215  G4PVPlacement* vmt3 = PlaceFinal(targetBaffletFlangeHe, HeCont3);
2216 
2217 //Construction of the ring that separates the target from the incoming helium flow
2218 
2219  G4String targetRingTube("TargetNoSplitRingTube");
2220  Create(targetRingTube);
2221  PlaceFinal(targetRingTube, vmt3);
2222 
2223 
2224 //Construction of the conical + cylindrical section between the target and bafflet
2225 
2226  G4String targetNSCTube("TargetNoSplitCoolingTubeLast");
2227  Create(targetNSCTube);
2228  PlaceFinal(targetNSCTube, vmt3);
2229 
2230 
2231 //Downstream spiked support (x pieces)
2232 
2234 
2235  G4String DSSupportConnection("TargetNoSplitDSSupportConnectionRing");
2236  Create(DSSupportConnection);
2237  PlaceFinal(DSSupportConnection, fTargetHorn1HallPhysPtr);
2238 
2239  G4String DSSupportAlRing("TargetNoSplitDSSupportAlRing");
2240  Create(DSSupportAlRing);
2241  PlaceFinal(DSSupportAlRing, fTargetHorn1HallPhysPtr);
2242 
2243  G4String DSSupportLargeCone1("TargetNoSplitDSSupportLargeCones");
2244  Create(DSSupportLargeCone1);
2245  G4PVPlacement *vmt4 = PlaceFinal(DSSupportLargeCone1, fTargetHorn1HallPhysPtr);
2246 
2247  G4String DSSupportHeliumLargeCone("TargetNoSplitDSSupportHeLargeCone");
2248  Create(DSSupportHeliumLargeCone);
2249  PlaceFinal(DSSupportHeliumLargeCone, vmt4);
2250 
2251  G4String DSSupportInnerRing("TargetNoSplitDSSupportInnerRing");
2252  Create(DSSupportInnerRing);
2253  PlaceFinal(DSSupportInnerRing, fTargetHorn1HallPhysPtr);
2254 
2255  }
2256 
2257 
2258 
2259 
2260 }
2262  //
2263  // Start with an ugly patch: restore the value of this bool, as it might have been overwritten
2264  // when the Horn1 is set to Optimized Polycone. The logical flow has been corrected in the DetectorConstruciton.
2265 
2266  fUse1p2MWSmallTgt = true;
2267 
2268 
2269  // Code to be picked up from Release v3r2p6, December 2016/ January 2017.
2270  const G4LogicalVolume *lVolMother = mother->GetLogicalVolume();
2271  std::cerr << " Installing the short (~ 1 m. long ) target, circa Feb. 2014 in mother "
2272  << lVolMother->GetName() << std::endl;
2273  const G4LogicalVolume *lVolMotherForTargetNoSPlitM1 = fTargetHorn1HallPhysPtr->GetLogicalVolume();
2274  std::cerr << " Installing TargetNoSplitM1 in "
2275  << lVolMotherForTargetNoSPlitM1->GetName() << std::endl;
2276  std::string targetTopStr("TargetUpstrMTop");
2277  // We us an overly deep volume hierarchy here... To be consistency with previous version
2278  // of this code. To be cleaned up at a later stage.
2279  Create(targetTopStr);
2280  G4PVPlacement *vMTop = PlaceFinal(targetTopStr, mother);
2281  std::string targetTopStrM0("TargetUpstrM0");
2282  LBNEVolumePlacementData *plM0 = Create(targetTopStrM0);
2283  G4PVPlacement *vM0 = PlaceFinal(targetTopStrM0, vMTop);
2284  std::cerr << " .. " << targetTopStr
2285  << " is now placed in.... " << lVolMother->GetName() << std::endl;
2286  G4String targetNSStr = std::string("TargetNoSplitM1");
2287  LBNEVolumePlacementData *plM1 = Create(targetNSStr);
2288  G4PVPlacement *vM1 = PlaceFinal(targetNSStr, fTargetHorn1HallPhysPtr);
2289  std::cerr << " .. " << targetNSStr
2290  << " is now placed in PlaceFinalUpstrTarget1p2MW...in fTargetHorn1HallPhysPtr " << std::endl;
2291 
2292 
2293 
2294 
2295 
2296  // ALL RELATED TO BAFFLE AND UPSTREAM TARGET ASSEMBLY!!!!!!!!!!!
2297 
2298 
2299 
2300  std::string tUpUp("TargetUpstrUpstr");
2301  Create(tUpUp + std::string("Plate"));
2302  Create(tUpUp + std::string("Can"));
2303  Create(tUpUp + std::string("CanEndPlate"));
2304  Create(tUpUp + std::string("DwstrFlange"));
2305  Create(tUpUp + std::string("CoolingTube"));
2306  Create(tUpUp + std::string("CoolingTubeWater"));
2307  Create(tUpUp + std::string("SupportBlockTopLeft"));
2308  Create(tUpUp + std::string("SupportBlockBottomLeft"));
2309  Create(tUpUp + std::string("SupportBlockRight"));
2310  Create(tUpUp + std::string("SupportSleeve"));
2311  // None of these are surveyable, position is fixed.
2312  PlaceFinal(tUpUp + std::string("Plate"), vM0);
2313  PlaceFinal(tUpUp + std::string("Can"), vM0);
2314  PlaceFinal(tUpUp + std::string("CanEndPlate"), vM0);
2315  PlaceFinal(tUpUp + std::string("DwstrFlange"), vM0);
2316  // Cooling tubes: two copies. This breaks the Placement data model. Never mind, assume here that misalignment
2317  // of these cooling tube has negligible effect on the physics.
2318 
2319 
2320 
2321  // ALL RELATED TO BAFFLE AND UPSTREAM TARGET ASSEMBLY!!!!!!!!!!!
2322 
2323 
2324 
2325 
2326  // Cooling tubes: two copies. This breaks the Placement data model. Never mind, assume here that misalignment
2327  // of these cooling tube has negligible effect on the physics.
2328 
2329  G4String nameTmp5(tUpUp + std::string("CoolingTube"));
2331  LBNEVolumePlacementData &infoTmp = itTmp->second;
2332  G4ThreeVector posTmp;
2333  posTmp[0] = 0.;
2334  posTmp[1] = 0.5*fTargetFinHeight;
2335  posTmp[2] = -1.0*plM0->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
2337  fTargetDownstrCanFlangeThick + fTargetFlangeThick - infoTmp.fParams[2]/2 - 1.0*CLHEP::mm;
2338 
2339 
2340  // Cooling tubes: two copies. This breaks the Placement data model. Never mind, assume here that misalignment
2341  // of these cooling tube has negligible effect on the physics.
2342 
2343 
2344  G4String vpNameTmp5(nameTmp5);
2345 // std::cerr << " Position for " << vpNameTmp5+G4String("_PTop") << " X = "
2346 // << posTmp[0] << " Y " << posTmp[1] << " Z " << posTmp[2] << std::endl;
2347  G4PVPlacement *vCoolingTubeTop = new G4PVPlacement((G4RotationMatrix *) 0,
2348  posTmp, infoTmp.fCurrent, vpNameTmp5+G4String("_PTop"),
2349  vM0->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC );
2350  posTmp[1] = -0.5*fTargetFinHeight;
2351  G4PVPlacement *vCoolingTubeBottom = new G4PVPlacement((G4RotationMatrix *) 0,
2352  posTmp, infoTmp.fCurrent, vpNameTmp5+std::string("_PBottom"),
2353  vM0->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
2354 
2355 
2356 
2357  // Cooling tubes: two copies. This breaks the Placement data model. Never mind, assume here that misalignment
2358  // of these cooling tube has negligible effect on the physics.
2359 
2360 
2361  PlaceFinal(tUpUp + std::string("CoolingTubeWater"), vCoolingTubeTop);
2362  PlaceFinal(tUpUp + std::string("CoolingTubeWater"), vCoolingTubeBottom);
2363  PlaceFinal(tUpUp + std::string("SupportBlockTopLeft"), vM0);
2364  PlaceFinal(tUpUp + std::string("SupportBlockBottomLeft"), vM0);
2365  PlaceFinal(tUpUp + std::string("SupportBlockRight"), vM0);
2366  PlaceFinal(tUpUp + std::string("SupportSleeve"), vM0);
2367  // We need three support/alignment rods. Identical volume, but at different locations.
2368  std::string nameTmp10(tUpUp + std::string("SupportRod"));
2369  Create(nameTmp10);
2370  itTmp = fSubVolumes.find(nameTmp10);
2371  infoTmp = itTmp->second;
2372  // Top Left alignment/support rod.
2373  posTmp[0] = -20.5*CLHEP::mm; // Again, accurate to +- 1 mm or so.
2374  posTmp[1] = 24.0*CLHEP::mm;
2375  posTmp[2] = -1.0*plM0->fParams[2]/2.0 + fTargetUpstrUpstrMargin +
2377  fTargetDownstrCanFlangeThick - infoTmp.fParams[2]/2 - 1.0*CLHEP::mm;
2378  G4String vpNameTmp10(nameTmp10);
2379  new G4PVPlacement((G4RotationMatrix *) 0,
2380  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PTopLeft"),
2381  vM0->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2382  posTmp[0] = -15.5*CLHEP::mm; // Again, accurate to +- 1 mm or so.
2383  posTmp[1] = -36.0*CLHEP::mm;
2384  new G4PVPlacement((G4RotationMatrix *) 0,
2385  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PBottomLeft"),
2386  vM0->GetLogicalVolume(), false, 1, fCheckVolumeOverLapWC);
2387  posTmp[0] = 33.0*CLHEP::mm; // Again, accurate to +- 1 mm or so.
2388  posTmp[1] = 5.0*CLHEP::mm;
2389  new G4PVPlacement((G4RotationMatrix *) 0,
2390  posTmp, infoTmp.fCurrent, vpNameTmp10+std::string("_PRight"),
2391  vM0->GetLogicalVolume(), false, 2, fCheckVolumeOverLapWC);
2392 
2393 // Horizontal fin for beam alignment. Most important thing in the canister, in terms of material budget
2394 //
2395 // We have decided not to implement the horizontal fins.. But it was present in the
2396 // v3r2p6.
2397 //
2398 // std::string nameTmp11("TargetFinHorizontal");
2399 // Create(nameTmp11);
2400 // PlaceFinal(nameTmp11, vM0);
2401 
2402  // Done with the target canister..Now assemble the upstream part of the target it self. (Upstream of the horn1)
2403  // Or, since we use this in the context of noSplitHorn1, for the entire target, we have:
2404  std::string tUpDown("TargetNoSplit");
2405  Create(tUpDown + std::string("HeContainer"));
2406  G4PVPlacement *vHeTube = PlaceFinal(tUpDown + std::string("HeContainer"), vM1); // Surveyable
2407 // LBNEVolumePlacementData *plHelium = Create(tUpDown + std::string("Helium"));
2408  Create(tUpDown + std::string("Helium"));
2409  G4PVPlacement *vHelium = PlaceFinal(tUpDown + std::string("Helium"), vHeTube); // Fixed
2410 
2411  // First alignment ring, locate flush with the end plate (within 1 mm ) , left and right
2412  // Take them off, as in v3r2p6..
2413 // LBNEVolumePlacementData *infoTmpRLeft = Create(G4String("TargetAlignmentRingLeft"));
2414 // LBNEVolumePlacementData *infoTmpRRight = Create(G4String("TargetAlignmentRingRight"));
2415 // std::cerr << " Placing target alignment rings..... up to " << plM0->fParams[2]/2.0 << std::endl;
2416 // posTmp[0] = 0.; // The alignment rings are always centered..
2417 // posTmp[1] = 0.;
2418 // posTmp[2] = -1.0*plHelium->fParams[2]/2.0 + infoTmpRLeft->fParams[2]/2. + 1.0*CLHEP::mm; // 1 mm spacing Left and right have the same thickness.
2419 // int copyNumber = 0;
2420 // while (true) {
2421 // std::ostringstream cNumStrStr; cNumStrStr << "_P" << copyNumber;
2422 // new G4PVPlacement((G4RotationMatrix *) 0,
2423 // posTmp, infoTmpRLeft->fCurrent, G4String("TargetAlignmentRingLeft")+cNumStrStr.str(),
2424 // vHelium->GetLogicalVolume(), false, copyNumber, fCheckVolumeOverLapWC);
2425 // new G4PVPlacement((G4RotationMatrix *) 0,
2426 // posTmp, infoTmpRRight->fCurrent, G4String("TargetAlignmentRingRight")+ cNumStrStr.str(),
2427 // vHelium->GetLogicalVolume(), false, copyNumber, fCheckVolumeOverLapWC);
2428 // posTmp[2] += fTargetAlignRingSpacing;
2429 // copyNumber++;
2430 // std::cerr << " Placed target alignment ring at " << posTmp[2] << std::endl;
2431 // if ( posTmp[2] > (plM0->fParams[2]/2.0 - 1.0*CLHEP::mm)) break;
2432 // }
2433  //
2434  LBNEVolumePlacementData *plTargetCoolingTube = Create(G4String("TargetUpstrDownstrCoolingTube"));
2435  LBNEVolumePlacementData *plTargetCoolingTubeWater = Create(G4String("TargetUpstrDownstrCoolingTubeWater"));
2436 // LBNEVolumePlacementData *plTargetFin = Create(G4String("TargetFinVert"));
2437  G4String nameTgtUpDownSegLeft("TargetUpstrDownstrSegmentLeft");
2438  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentLeft = Create(nameTgtUpDownSegLeft);
2439  G4String nameTgtUpDownSegRight("TargetUpstrDownstrSegmentRight");
2440  std::vector< std::string > namesSegment(2,"");
2441  namesSegment[0] = nameTgtUpDownSegLeft;
2442  namesSegment[1] = nameTgtUpDownSegRight;
2443  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentRight = Create(nameTgtUpDownSegRight);
2444  std::cerr << "LBNEVolumePlacements::PlaceFinalSmallTarget1p2MW, fTargetFinExtraWidth "
2445  << fTargetFinExtraWidth << " central width " << fTargetFinWidth << std::endl;
2446  LBNEVolumePlacementData *plTargetFinExtra = (fTargetFinExtraWidth > 0.) ?
2447  Create(G4String("TargetFinVertExtra")) : 0;
2448  LBNEVolumePlacementData *plTargetFinHeSide = (fTargetFinExtraWidth < 0.) ?
2449  Create(G4String("TargetFinVertHeliumSide")) : 0;
2450  LBNEVolumePlacementData *plTargetRoundCornerUpstrLeft = (fUseRoundedTargetFins) ?
2451  Create(G4String("TargetFinVertHeliumRoundedUpstrLeft")) : 0;
2452  LBNEVolumePlacementData *plTargetRoundCornerUpstrRight = (fUseRoundedTargetFins) ?
2453  Create(G4String("TargetFinVertHeliumRoundedUpstrRight")) : 0;
2454  LBNEVolumePlacementData *plTargetRoundCornerDownstrLeft = (fUseRoundedTargetFins) ?
2455  Create(G4String("TargetFinVertHeliumRoundedDownstrLeft")) : 0;
2456  LBNEVolumePlacementData *plTargetRoundCornerDownstrRight = (fUseRoundedTargetFins) ?
2457  Create(G4String("TargetFinVertHeliumRoundedDownstrRight")) : 0;
2458  G4PVPlacement *vSeg[2];
2459  const double zCoordTmp = -1.0*plM1->fParams[2]/2.0 + 0.0075*CLHEP::mm;
2460  int copyNumberT = 0;
2461  for (int iSeg=0; iSeg != fTargetNumFins; iSeg++) { // Place with no misalignment, The last segment is placed below
2462  posTmp[0] = -0.5*fTargetFinContainerWidth - 0.023*CLHEP::mm; posTmp[1] = 0.;
2463  posTmp[2] = zCoordTmp
2464  + plTargetUpstrDownstrSegmentLeft->fParams[2]/2. + iSeg*(fTargetFinLength + fTargetFinSpacingLength);
2465 // std::cerr << " Placing target segments... At Z = " << posTmp[2] << std::endl;
2466  std::ostringstream cNumStrStrL; cNumStrStrL << "_PLeft" << iSeg;
2467  vSeg[0] = new G4PVPlacement((G4RotationMatrix *) 0,
2468  posTmp, plTargetUpstrDownstrSegmentLeft->fCurrent,
2469  nameTgtUpDownSegLeft+cNumStrStrL.str(),
2470  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2471  copyNumberT ++;
2472  posTmp[0] *= -1.0;
2473  std::ostringstream cNumStrStrR; cNumStrStrR << "_PRight" << iSeg;
2474  vSeg[1] = new G4PVPlacement((G4RotationMatrix *) 0,
2475  posTmp, plTargetUpstrDownstrSegmentRight->fCurrent,
2476  nameTgtUpDownSegRight+cNumStrStrR.str(),
2477  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2478 
2479  if (plTargetFinExtra != 0) {
2480  posTmp[0] = -1.0*fTargetFinContainerWidth - 0.5*fTargetFinExtraWidth -0.040*CLHEP::mm;
2481  new G4PVPlacement((G4RotationMatrix *) 0,
2482  posTmp, plTargetFinExtra->fCurrent,
2483  namesSegment[0] + std::string("Extra")+cNumStrStrL.str(),
2484  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2485  posTmp[0] *= -1.0;
2486  new G4PVPlacement((G4RotationMatrix *) 0,
2487  posTmp, plTargetFinExtra->fCurrent,
2488  namesSegment[1] + std::string("Extra")+cNumStrStrR.str(),
2489  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2490 
2491  }
2492 // std::cerr << " Placing target at Zs " << posTmp[2] << std::endl;
2493  }
2494 
2495  for (size_t kLeftRight=0; kLeftRight !=2; kLeftRight++) {
2496  posTmp[0] = 0.; posTmp[1] = fTargetFinHeight/2. + fTargetCTubeOuterRadius - 0.005*CLHEP::mm; posTmp[2] = 0.;
2497  std::cerr << " Height of the cooling tube Up... .. " << posTmp[1] <<std::endl;
2498  std::cerr << " Placing cooling tube in " << vSeg[kLeftRight]->GetLogicalVolume()->GetName() <<
2499  " Fin height " << fTargetFinHeight << " Outer tube radius " << fTargetCTubeOuterRadius
2500  << " pos H. " << posTmp[1] << std::endl;
2501 
2502  G4PVPlacement *vTubeUp = new G4PVPlacement((G4RotationMatrix *) 0,
2503  posTmp, plTargetCoolingTube->fCurrent,
2504  namesSegment[kLeftRight]+G4String("CoolingTubeUp_PTop"),
2505  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2506 
2507  posTmp[1] *= -1.0;
2508  std::cerr << " Height of the cooling tube Down... .. "<< posTmp[1] << std::endl;
2509  G4PVPlacement *vTubeDwn = new G4PVPlacement((G4RotationMatrix *) 0,
2510  posTmp, plTargetCoolingTube->fCurrent,
2511  namesSegment[kLeftRight]+ G4String("CoolingTubeUp_PBottom"),
2512  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2513  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
2514  new G4PVPlacement((G4RotationMatrix *) 0,
2515  posTmp, plTargetCoolingTubeWater->fCurrent,
2516  namesSegment[kLeftRight]+ G4String("CoolingTubeWater_PUp"),
2517  vTubeUp->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2518 
2519  new G4PVPlacement((G4RotationMatrix *) 0,
2520  posTmp, plTargetCoolingTubeWater->fCurrent,
2521  namesSegment[kLeftRight]+ G4String("CoolingTubeWater_PDwn"),
2522  vTubeDwn->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2523 
2524 //
2525 // This is no longer really needed, as we the container is graphite.. but keep it, for
2526 // debugging the geometry..
2527 // posTmp[0] = (kLeftRight == 0) ? -1.0*( fTargetFinContainerWidth - fTargetFinWidth)/2. -0.010:
2528 // ( fTargetFinContainerWidth - fTargetFinWidth)/2. + 0.010;
2529 // std::cerr << " TargetFin Horizontal shift " << posTmp[0]
2530 // << " Container width " << fTargetFinContainerWidth << " TargetFin Width " << fTargetFinWidth << std::endl;
2531 // posTmp[1] = 0.;
2532 // new G4PVPlacement((G4RotationMatrix *) 0,
2533 // posTmp, plTargetFin->fCurrent,
2534 // namesSegment[kLeftRight]+G4String("TargetFinVert_P"),
2535 // vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2536 //
2537 // Put back some helium into the container..
2538 //
2539  if (plTargetFinHeSide != 0) {
2540  const double heThick = plTargetFinHeSide->fParams[0];
2541  const double heThickShift = -0.5*fTargetFinContainerWidth + 0.5*heThick + 0.0175*CLHEP::mm;
2542  std::cerr << " Helium back fill.. width " << heThick
2543  << " Container width " << fTargetFinContainerWidth << " shift " << heThickShift << std::endl;
2544  posTmp[0] = (kLeftRight == 0) ? heThickShift : -1.0*heThickShift;
2545  posTmp[1] = 0.;
2546  new G4PVPlacement((G4RotationMatrix *) 0,
2547  posTmp, plTargetFinHeSide->fCurrent,
2548  namesSegment[kLeftRight]+G4String("TargetFinVertHeSide_P"),
2549  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2550  }
2551  if (fUseRoundedTargetFins) {
2552  posTmp[0] = 0.;
2553  posTmp[1] = 0.;
2554  if (kLeftRight == 0) {
2555  posTmp[2] = plTargetUpstrDownstrSegmentLeft->fParams[2]/2. - plTargetRoundCornerDownstrLeft->fParams[1]/2. - 0.001*CLHEP::mm;
2556  std::cerr << " Z shift for round cornres .. DownstrLeft " << posTmp[2] << " half length Target " <<
2557  plTargetUpstrDownstrSegmentLeft->fParams[2]/2. << " cuboid width " <<
2558  plTargetRoundCornerDownstrLeft->fParams[0]/2. << std::endl;
2559  new G4PVPlacement(&fRotVertical, posTmp,
2560  plTargetRoundCornerDownstrLeft->fCurrent,
2561  namesSegment[kLeftRight]+G4String("TargetFinVertRoundCornerDL_P"),
2562  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2563  posTmp[2] *= -1.0;
2564  new G4PVPlacement(&fRotVertical, posTmp,
2565  plTargetRoundCornerUpstrLeft->fCurrent,
2566  namesSegment[kLeftRight]+G4String("TargetFinVertRoundCornerUL_P"),
2567  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2568  } else {
2569  posTmp[2] = plTargetUpstrDownstrSegmentRight->fParams[2]/2. - plTargetRoundCornerDownstrRight->fParams[1]/2. - 0.001*CLHEP::mm;
2570  new G4PVPlacement(&fRotVertical, posTmp,
2571  plTargetRoundCornerDownstrRight->fCurrent,
2572  namesSegment[kLeftRight]+G4String("TargetFinVertRoundCornerDR_P"),
2573  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2574  posTmp[2] *= -1.0;
2575  new G4PVPlacement(&fRotVertical, posTmp,
2576  plTargetRoundCornerUpstrRight->fCurrent,
2577  namesSegment[kLeftRight]+G4String("TargetFinVertRoundCornerUR_P"),
2578  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2579  }
2580 
2581  }
2582 //
2583  }
2584  //
2585  // Repeat the last few mantra for the last segment ... But we skip the round corner..
2586  // And we skip this for the CDR Optimized case... February 2017..
2587  // We also skip this if the length of the target has been res-scaled.
2588  //
2589  if ((!fUseCDR2015Optimized) &&
2590  (fTargetFinLengthSplitUpstr > 0.3*CLHEP::mm) &&
2591  (std::abs(fTargetSLengthGraphite - 953.8) < 5.0*CLHEP::mm)) {
2592  std::cerr << " Installing the last target segment upstream of Horn1 .. " << std::endl;
2593  LBNEVolumePlacementData *plTargetCoolingTubeLast = Create(G4String("TargetUpstrDownstrCoolingTubeLast"));
2594  LBNEVolumePlacementData *plTargetCoolingTubeWaterLast = Create(G4String("TargetUpstrDownstrCoolingTubeLastWater"));
2595 // LBNEVolumePlacementData *plTargetFinLast = Create(G4String("TargetFinVertUpstrLast"));
2596  G4String nameTgtUpDownSegLastLeft("TargetUpstrDownstrSegmentLastLeft");
2597  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentLastLeft = Create(nameTgtUpDownSegLastLeft);
2598  G4String nameTgtUpDownSegLastRight("TargetUpstrDownstrSegmentLastRight");
2599  LBNEVolumePlacementData *plTargetUpstrDownstrSegmentLastRight = Create(nameTgtUpDownSegLastRight);
2600  LBNEVolumePlacementData *plTargetFinExtraLast = (fTargetFinExtraWidth > 0.) ?
2601  Create(G4String("TargetFinVertExtraLast")) : 0;
2602  namesSegment[0] = nameTgtUpDownSegLastLeft;
2603  namesSegment[1] = nameTgtUpDownSegLastRight;
2604  LBNEVolumePlacementData *plTargetFinHeSideLast = (fTargetCTubeOuterRadius > fTargetFinWidth) ?
2605  Create(G4String("TargetFinVertLastHeliumSide")) : 0;
2606  posTmp[0] = -0.5*fTargetFinContainerWidth - 0.023*CLHEP::mm; posTmp[1] = 0.;
2607  posTmp[2] = zCoordTmp + plTargetUpstrDownstrSegmentLastLeft->fParams[2]/2. +
2609  vSeg[0] = new G4PVPlacement((G4RotationMatrix *) 0,
2610  posTmp, plTargetUpstrDownstrSegmentLastLeft->fCurrent,
2611  G4String("TargetUpstrDowstrSegmentLastLeft"),
2612  vHelium->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2613  posTmp[0] *= -1.0;
2614  vSeg[1] = new G4PVPlacement((G4RotationMatrix *) 0,
2615  posTmp, plTargetUpstrDownstrSegmentLastRight->fCurrent,
2616  G4String("TargetUpstrDowstrSegmentLastRight"),
2617  vHelium->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2618  if (plTargetFinExtraLast != 0) {
2619  posTmp[0] = -1.0*fTargetFinContainerWidth - 0.5*fTargetFinExtraWidth - 0.040*CLHEP::mm;
2620  new G4PVPlacement((G4RotationMatrix *) 0,
2621  posTmp, plTargetFinExtraLast->fCurrent,
2622  std::string("TargetUpstrDowstrSegmentLastExtraFinLeft"),
2623  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2624  posTmp[0] *= -1.0;
2625  new G4PVPlacement((G4RotationMatrix *) 0,
2626  posTmp, plTargetFinExtraLast->fCurrent,
2627  std::string("TargetUpstrDowstrSegmentLastExtraFinRight"),
2628  vHelium->GetLogicalVolume(), false, copyNumberT, fCheckVolumeOverLapWC);
2629 
2630  }
2631  for (size_t kLeftRight=0; kLeftRight !=2; kLeftRight++) {
2632  posTmp[0] = 0.; posTmp[1] = fTargetFinHeight/2. + fTargetCTubeOuterRadius - 0.005*CLHEP::mm; posTmp[2] = 0.;
2633  G4PVPlacement *vTubeUp = new G4PVPlacement((G4RotationMatrix *) 0,
2634  posTmp, plTargetCoolingTubeLast->fCurrent,
2635  G4String("TargetUpstrDownstrCoolingTubeUpLast_PTop"),
2636  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2637 
2638  posTmp[1] *= -1.0;
2639  G4PVPlacement *vTubeDwn = new G4PVPlacement((G4RotationMatrix *) 0,
2640  posTmp, plTargetCoolingTubeLast->fCurrent,
2641  G4String("TargetUpstrDownstrCoolingTubeUpLast_PBottom"),
2642  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2643  posTmp[0] = 0.; posTmp[1] = 0.; posTmp[2] = 0.;
2644  new G4PVPlacement((G4RotationMatrix *) 0,
2645  posTmp, plTargetCoolingTubeWaterLast->fCurrent,
2646  namesSegment[kLeftRight]+G4String("CoolingTubeWater_P"),
2647  vTubeUp->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2648  new G4PVPlacement((G4RotationMatrix *) 0,
2649  posTmp, plTargetCoolingTubeWaterLast->fCurrent,
2650  namesSegment[kLeftRight]+G4String("CoolingTubeWater_P"),
2651  vTubeDwn->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2652 
2653 // posTmp[0] = (kLeftRight == 0) ? -1.0*( fTargetFinContainerWidth - fTargetFinWidth)/2. -0.010:
2654 // ( fTargetFinContainerWidth - fTargetFinWidth)/2. + 0.010;
2655 // posTmp[1] = 0.;
2656 // new G4PVPlacement((G4RotationMatrix *) 0,
2657 // posTmp, plTargetFinLast->fCurrent, G4String("TargetFinVertLast_P"),
2658 // vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2659 //
2660 // Put back some helium into the container..
2661 //
2662  if (plTargetFinHeSideLast != 0) {
2663  const double heThick = plTargetFinHeSideLast->fParams[0];
2664  const double heThickShift = -0.5*fTargetFinContainerWidth + 0.5*heThick + 0.0175*CLHEP::mm;
2665  posTmp[0] = (kLeftRight == 0) ? heThickShift : -1.0*heThickShift;
2666  posTmp[1] = 0.;
2667  new G4PVPlacement((G4RotationMatrix *) 0,
2668  posTmp, plTargetFinHeSideLast->fCurrent,
2669  namesSegment[kLeftRight]+G4String("TargetFinVertHeSide_P"),
2670  vSeg[kLeftRight]->GetLogicalVolume(), false, 0, fCheckVolumeOverLapWC);
2671  }
2672  } // Left right/segment of the dual fins (physically one one volume, split for reason of programming convenience. )
2673  }
2674 }
int GetNumberOfInnerHornSubSections(size_t eqn, double z1, double z2, int nMax) const
std::vector< double > fMotherHorn1AllLengths
std::vector< LBNEHornRadialEquation > fHorn1Equations
intermediate_table::iterator iterator
G4double fTargetOutHeContTubeInnerRadiusTapered
std::vector< G4ThreeVector > fHorn1PolyListRinThickZVects
G4double fTargetDSSupportSmallConeSmallOuterRad
void Horn1InstallSpiderHanger(const G4String &name, double zFromStartInnerConduct, double zPos, G4PVPlacement *vMother)
void PlaceFinalDownstrTarget1p2MW(G4PVPlacement *mother)
std::vector< std::vector< G4ThreeVector > > fHornsPolyListRinThickZVects
const LBNEVolumePlacementData * Find(const G4String &name, const char *motherName, const char *method) const
void PlaceFinalRALTarget(G4PVPlacement *mother)
std::string string
Definition: nybbler.cc:12
std::vector< double > fHornsPolyOuterRadius
std::vector< G4double > fHorn1UpstrOuterIOTransPositions
std::vector< std::vector< double > > fMotherHornsAllRads
std::vector< G4double > fHorn1UpstrOuterIOTransLengths
std::vector< double > fHornsPolyZStartPos
G4double fTargetCTubeReturnDownstrThickTitanium
void UpdateParamsForHornMotherPolyNum(size_t iH)
std::vector< int > fUseHornsPolyNumInnerPts
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:45
G4double fTargetOutHeContTubeOuterSphericalEndCap
void PlaceFinalNoSplitHorn1(G4PVPlacement *mother, G4PVPlacement *motherTop)
G4double fTargetDSSupportSmallConeLargeOuterRad
std::vector< G4double > fTargetHorn1InnerRadsUpstr
G4double fTargetDSSupportSmallConeSmallInnerRad
std::map< G4String, LBNEVolumePlacementData > fSubVolumes
std::vector< G4double > fHorn1UpstrOuterIOTransInnerRads
T abs(T value)
void PlaceTargetModule(int number=1)
void PlaceFinalUpstrTargetSimpleCylinder(G4PVPlacement *mother)
void PlaceFinalMultiSphereTarget(LBNEVolumePlacementData *plHelium, G4PVPlacement *mother)
std::vector< double > fParams
unsigned int fTargetNumFinsWithWings
std::vector< bool > fPolyconeHornsAreParabolic
double z
LBNEVolumePlacementData * Create(const G4String &name)
G4double fTargetOutHeContTubeInnerSphericalEndCap
void PlaceFinalUpstrTarget1p2MW(G4PVPlacement *mother)
G4double fTargetDSSupportLargeConeSmallInnerRad
G4double fTargetDSSupportLargeConeLargeOuterRad
static int max(int a, int b)
std::vector< G4double > fHorn1UpstrInnerRadsOuterUpstr
std::vector< double > fMotherHorn1AllThick
void PlaceFinalSmallTarget1p2MW(G4PVPlacement *mother)
void PlaceFinalSimpleHornPolyNumber(size_t iHorn, G4PVPlacement *mother)
std::vector< double > fHornsLength
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
void PlaceRALTGTv1(G4PVPlacement *mother)
void PlaceFinalUpstrTargetSimpleBox(G4PVPlacement *mother)
std::vector< G4double > fHorn1UpstrInnerRadsOuterDownstr
std::vector< std::vector< double > > fMotherHornsAllThick
G4double fTargetDSSupportLargeConeLargeInnerRad
G4double fTargetCTubeReturnDownstrThickWater
std::vector< G4double > fHorn1UpstrOuterIOTransThicks
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
G4RotationMatrix fRotVertical
std::vector< G4double > fHorn1UpstrInnerRadsDownstr
std::vector< G4double > fHorn1UpstrZPositions
std::vector< G4double > fHorn1UpstrInnerRadsUpstr
G4PVPlacement * PlaceFinal(const G4String &name, G4VPhysicalVolume *mother)
std::vector< G4double > fHorn1UpstrLengths
G4VPhysicalVolume * fTargetHorn1HallPhysPtr
std::vector< double > fMotherHorn1AllRads
G4double fTargetDSSupportSmallConeLargeInnerRad
G4double fTargetDSSupportLargeConeSmallOuterRad
static QCString str
QTextStream & endl(QTextStream &s)
std::vector< std::vector< double > > fMotherHornsAllLengths
std::vector< G4String > fHorn1IC
G4double fTargetOutHeContTubeOuterRadiusTapered