CaptCryostatBuilder.cc
Go to the documentation of this file.
1 #include "CaptCryostatBuilder.hh"
2 #include "CaptImmersedBuilder.hh"
3 #include "CaptExposedBuilder.hh"
6 
7 #include "EDepSimBuilder.hh"
8 
9 #include "EDepSimLog.hh"
10 
11 #include <globals.hh>
12 #include <G4Material.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4VPhysicalVolume.hh>
15 #include <G4PVPlacement.hh>
16 #include <G4VisAttributes.hh>
17 #include <G4Tubs.hh>
18 #include <G4Polycone.hh>
19 
20 #include <G4SystemOfUnits.hh>
21 #include <G4PhysicalConstants.hh>
22 
24  : public EDepSim::BuilderMessenger {
25 private:
27  G4UIcmdWithADoubleAndUnit* fArgonDepthCMD;
28  G4UIcmdWithADoubleAndUnit* fTPCDepthCMD;
29  G4UIcmdWithAString* fVesselTypeCMD;
30 
31 public:
33  : EDepSim::BuilderMessenger(c,"Control the driftRegion geometry."),
34  fBuilder(c) {
35 
36  fArgonDepthCMD
37  = new G4UIcmdWithADoubleAndUnit(CommandName("argonDepth"),this);
38  fArgonDepthCMD->SetGuidance(
39  "Set the distance between the flange and the liquid argon.");
40  fArgonDepthCMD->SetParameterName("depth",false);
41  fArgonDepthCMD->SetUnitCategory("Length");
42 
43  fTPCDepthCMD
44  = new G4UIcmdWithADoubleAndUnit(CommandName("tpcDepth"),this);
45  fTPCDepthCMD->SetGuidance(
46  "Set the distance between the flange and TPC origin.");
47  fTPCDepthCMD->SetParameterName("depth",false);
48  fTPCDepthCMD->SetUnitCategory("Length");
49 
50  fVesselTypeCMD
51  = new G4UIcmdWithAString(CommandName("vessel"),this);
52  fVesselTypeCMD->SetGuidance(
53  "Set the type of vessel to be built.");
54  fVesselTypeCMD->SetCandidates("CAPTAIN mCAPTAIN");
55  };
56 
58  delete fArgonDepthCMD;
59  delete fTPCDepthCMD;
60  delete fVesselTypeCMD;
61  };
62 
63  void SetNewValue(G4UIcommand *cmd, G4String val) {
64  if (cmd==fArgonDepthCMD) {
65  fBuilder->SetArgonDepth(
66  fArgonDepthCMD->GetNewDoubleValue(val));
67  }
68  else if (cmd==fTPCDepthCMD) {
69  fBuilder->SetTPCDepth(
70  fTPCDepthCMD->GetNewDoubleValue(val));
71  }
72  else if (cmd==fVesselTypeCMD) {
73  fBuilder->SetVesselType(val);
74  }
75  else {
77  }
78  };
79 };
80 
82  SetMessenger(new CaptCryostatMessenger(this));
83 
84  SetVesselType("CAPTAIN");
85 
86  SetSensitiveDetector("cryo","segment");
87 
88  AddBuilder(new CaptImmersedBuilder("Immersed",this));
89  AddBuilder(new CaptExposedBuilder("Exposed",this));
90  AddBuilder(new MiniCaptImmersedBuilder("mImmersed",this));
91  AddBuilder(new MiniCaptExposedBuilder("mExposed",this));
92 }
93 
95 
97  return G4ThreeVector(0,0,0);
98 }
99 
101  return G4ThreeVector(0,0,-GetTPCDepth());
102 }
103 
105  SetArgonDepth(24*25.4*CLHEP::mm); // The design spec for CAPTAIN (24 inch).
106  SetTPCDepth(GetArgonDepth()+25*CLHEP::mm); // I made this one up...
107 
108  fInnerVessel.clear();
109 #include "captainInnerVessel.hxx"
110 
111  fOuterVessel.clear();
112 #include "captainOuterVessel.hxx"
113 
114  for (Shape::reverse_iterator p = fOuterVessel.rbegin();
115  p != fOuterVessel.rend(); ++p) {
116  fVesselEnvelope.push_back(*p);
117  }
118  for (Shape::reverse_iterator p = fInnerVessel.rbegin();
119  p != fInnerVessel.rend(); ++p) {
120  if (p->fZ >= fVesselEnvelope.back().fZ) continue;
121  fVesselEnvelope.push_back(*p);
122  }
123  std::reverse(fVesselEnvelope.begin(), fVesselEnvelope.end());
124 
125 }
126 
128  SetArgonDepth(9*25.4*CLHEP::mm); // The design spec for CAPTAIN (24 inch).
129  SetTPCDepth(GetArgonDepth()+25*CLHEP::mm); // I made this one up...
130 
131  fInnerVessel.clear();
133 
134  fOuterVessel.clear();
136 
137  for (Shape::reverse_iterator p = fOuterVessel.rbegin();
138  p != fOuterVessel.rend(); ++p) {
139  fVesselEnvelope.push_back(*p);
140  }
141  for (Shape::reverse_iterator p = fInnerVessel.rbegin();
142  p != fInnerVessel.rend(); ++p) {
143  if (p->fZ >= fVesselEnvelope.back().fZ) continue;
144  fVesselEnvelope.push_back(*p);
145  }
146  std::reverse(fVesselEnvelope.begin(), fVesselEnvelope.end());
147 
148 }
149 
150 G4LogicalVolume *CaptCryostatBuilder::GetPiece(void) {
151 
152  if (fVesselType == "CAPTAIN") {
153  DefineCAPTAINVessel();
154  }
155  else if (fVesselType == "mCAPTAIN") {
156  DefineMiniCAPTAINVessel();
157  }
158  else {
159  std::cout << "Undefine vessel type: " << fVesselType << std::endl;
160  std::exit(0);
161  }
162 
163  std::vector<double> conePlanes;
164  std::vector<double> coneMax;
165  std::vector<double> coneMin;
166 
167  ////////////////////////////////////////////////////////
168  // Define the envelope to contain the vessel.
169  ////////////////////////////////////////////////////////
170  for (Shape::reverse_iterator p = fVesselEnvelope.rbegin();
171  p != fVesselEnvelope.rend();
172  ++p) {
173  conePlanes.push_back(- p->fZ);
174  coneMax.push_back(p->fOuter+10*CLHEP::cm);
175  coneMin.push_back(0.0);
176  }
177 
178  G4LogicalVolume* logVolume
179  = new G4LogicalVolume(
180  new G4Polycone(GetName(),
181  0*CLHEP::degree, 360*CLHEP::degree, conePlanes.size(),
182  conePlanes.data(),
183  coneMin.data(), coneMax.data()),
184  FindMaterial("Air"),
185  GetName());
186  logVolume->SetVisAttributes(G4VisAttributes::Invisible);
187 
188  ////////////////////////////////////////////////////////
189  // Define the outer vessel.
190  ////////////////////////////////////////////////////////
191  conePlanes.clear();
192  coneMax.clear();
193  coneMin.clear();
194  for (Shape::reverse_iterator p = fOuterVessel.rbegin();
195  p != fOuterVessel.rend();
196  ++p) {
197  conePlanes.push_back(- p->fZ);
198  coneMin.push_back(p->fInner);
199  coneMax.push_back(p->fOuter);
200  }
201 
202  G4LogicalVolume* logOuterVessel
203  = new G4LogicalVolume(
204  new G4Polycone(GetName()+"/OuterVessel",
205  0*CLHEP::degree, 360*CLHEP::degree, conePlanes.size(),
206  conePlanes.data(),
207  coneMin.data(), coneMax.data()),
208  FindMaterial("SS_304"),
209  GetName()+"/OuterVessel");
210  logOuterVessel->SetVisAttributes(GetColor(logOuterVessel));
211 
212  new G4PVPlacement(NULL, // rotation.
213  G4ThreeVector(0,0,0),
214  logOuterVessel, // logical volume
215  logOuterVessel->GetName(), // name
216  logVolume, // mother volume
217  false, // (not used)
218  0, // Copy number (zero)
219  Check()); // Check overlaps.
220 
221 
222  ////////////////////////////////////////////////////////
223  // Define the inner vessel.
224  ////////////////////////////////////////////////////////
225  conePlanes.clear();
226  coneMax.clear();
227  coneMin.clear();
228  for (Shape::reverse_iterator p = fInnerVessel.rbegin();
229  p != fInnerVessel.rend();
230  ++p) {
231  conePlanes.push_back(- p->fZ);
232  coneMin.push_back(p->fInner);
233  coneMax.push_back(p->fOuter);
234  }
235 
236  G4LogicalVolume* logInnerVessel
237  = new G4LogicalVolume(
238  new G4Polycone(GetName()+"/InnerVessel",
239  0*CLHEP::degree, 360*CLHEP::degree, conePlanes.size(),
240  conePlanes.data(),
241  coneMin.data(), coneMax.data()),
242  FindMaterial("SS_304"),
243  GetName()+"/InnerVessel");
244  logInnerVessel->SetVisAttributes(GetColor(logInnerVessel));
245 
246  new G4PVPlacement(NULL, // rotation.
247  G4ThreeVector(0,0,0),
248  logInnerVessel, // logical volume
249  logInnerVessel->GetName(), // name
250  logVolume, // mother volume
251  false, // (not used)
252  0, // Copy number (zero)
253  Check()); // Check overlaps.
254 
255  ////////////////////////////////////////////////////////
256  // Define the liquid volume.
257  ////////////////////////////////////////////////////////
258  conePlanes.clear();
259  coneMax.clear();
260  coneMin.clear();
261  for (Shape::reverse_iterator p = fInnerVessel.rbegin();
262  p != fInnerVessel.rend();
263  ++p) {
264  if (p->fZ < GetArgonDepth()) continue;
265  conePlanes.push_back(- p->fZ);
266  coneMin.push_back(0.0);
267  coneMax.push_back(p->fInner);
268  }
269  if (conePlanes.back() < -GetArgonDepth()) {
270  conePlanes.push_back(- GetArgonDepth());
271  coneMin.push_back(0.0);
272  coneMax.push_back(coneMax.back());
273  }
274 
275  fLiquidVolume
276  = new G4LogicalVolume(
277  new G4Polycone(GetName()+"/Liquid",
278  0*CLHEP::degree, 360*CLHEP::degree, conePlanes.size(),
279  conePlanes.data(),
280  coneMin.data(), coneMax.data()),
281  FindMaterial("Argon_Liquid"),
282  GetName()+"/Liquid");
283  fLiquidVolume->SetVisAttributes(GetColor(fLiquidVolume));
284 
285  new G4PVPlacement(NULL, // rotation.
286  G4ThreeVector(0,0,0),
287  fLiquidVolume, // logical volume
288  fLiquidVolume->GetName()+"/Liquid", // name
289  logVolume, // mother volume
290  false, // (not used)
291  0, // Copy number (zero)
292  Check()); // Check overlaps.
293 
294  if (fVesselType == "CAPTAIN") {
295  CaptImmersedBuilder& immersed = Get<CaptImmersedBuilder>("Immersed");
296  G4LogicalVolume* logImmersed = immersed.GetPiece();
297  G4ThreeVector p = GetTPCOffset() - immersed.GetOffset();
298  new G4PVPlacement(NULL, // rotation.
299  p, // position
300  logImmersed, // logical volume
301  logImmersed->GetName(), // name
302  fLiquidVolume, // mother volume
303  false, // (not used)
304  0, // Copy number (zero)
305  Check()); // Check overlaps.
306  }
307  else if (fVesselType == "mCAPTAIN") {
308  MiniCaptImmersedBuilder& immersed
309  = Get<MiniCaptImmersedBuilder>("mImmersed");
310  G4LogicalVolume* logImmersed = immersed.GetPiece();
311  G4ThreeVector p = GetTPCOffset() - immersed.GetOffset();
312  new G4PVPlacement(NULL, // rotation.
313  p, // position
314  logImmersed, // logical volume
315  logImmersed->GetName(), // name
316  fLiquidVolume, // mother volume
317  false, // (not used)
318  0, // Copy number (zero)
319  Check()); // Check overlaps.
320  }
321  else {
322  std::cout << "Undefined immersed volume" << std::endl;
323  std::exit(0);
324  }
325 
326 
327  ////////////////////////////////////////////////////////
328  // Define the ullage volume.
329  ////////////////////////////////////////////////////////
330  conePlanes.clear();
331  coneMax.clear();
332  coneMin.clear();
333  for (Shape::reverse_iterator p = fInnerVessel.rbegin();
334  p != fInnerVessel.rend();
335  ++p) {
336  if (p->fZ >= GetArgonDepth()-1*CLHEP::mm) continue;
337  if (conePlanes.empty() ) {
338  conePlanes.push_back(-GetArgonDepth()+1*CLHEP::um);
339  coneMin.push_back(0.0);
340  coneMax.push_back(p->fInner);
341  }
342  conePlanes.push_back(- p->fZ);
343  coneMin.push_back(0.0);
344  coneMax.push_back(p->fInner);
345  }
346 
347  fUllageVolume
348  = new G4LogicalVolume(
349  new G4Polycone(GetName()+"/Ullage",
350  0*CLHEP::degree, 360*CLHEP::degree, conePlanes.size(),
351  conePlanes.data(),
352  coneMin.data(), coneMax.data()),
353  FindMaterial("Argon_Gas"),
354  GetName()+"/Ullage");
355  fUllageVolume->SetVisAttributes(GetColor(fUllageVolume));
356 
357  new G4PVPlacement(NULL, // rotation.
358  G4ThreeVector(0,0,0),
359  fUllageVolume, // logical volume
360  fUllageVolume->GetName(), // name
361  logVolume, // mother volume
362  false, // (not used)
363  0, // Copy number (zero)
364  Check()); // Check overlaps.
365 
366  if (fVesselType == "CAPTAIN") {
367  CaptExposedBuilder& exposed = Get<CaptExposedBuilder>("Exposed");
368  G4LogicalVolume* logExposed = exposed.GetPiece();
369  G4ThreeVector p(0.0,0.0,-GetArgonDepth());
370  p -= exposed.GetOffset();
371  new G4PVPlacement(NULL, // rotation.
372  p, // position
373  logExposed, // logical volume
374  logExposed->GetName(), // name
375  fUllageVolume, // mother volume
376  false, // (not used)
377  0, // Copy number (zero)
378  Check()); // Check overlaps.
379  }
380  else if (fVesselType == "mCAPTAIN") {
381  MiniCaptExposedBuilder& exposed
382  = Get<MiniCaptExposedBuilder>("mExposed");
383  G4LogicalVolume* logExposed = exposed.GetPiece();
384  if (logExposed) {
385  G4ThreeVector p(0.0,0.0,-GetArgonDepth());
386  p -= exposed.GetOffset();
387  new G4PVPlacement(NULL, // rotation.
388  p, // position
389  logExposed, // logical volume
390  logExposed->GetName(), // name
391  fUllageVolume, // mother volume
392  false, // (not used)
393  0, // Copy number (zero)
394  Check()); // Check overlaps.
395  }
396  }
397  else {
398  std::cout << "Undefined exposed volume" << std::endl;
399  std::exit(0);
400  }
401 
402  return logVolume;
403 }
static constexpr double cm
Definition: Units.h:68
void SetNewValue(G4UIcommand *cmd, G4String val)
void DefineMiniCAPTAINVessel()
Fill the vessel definition with values for miniCAPTAIN.
G4UIcmdWithADoubleAndUnit * fArgonDepthCMD
CaptCryostatBuilder * fBuilder
G4ThreeVector GetOffset()
G4UIcmdWithAString * fVesselTypeCMD
void SetArgonDepth(double v)
Construct a module from components.
Definition: TG4HitSegment.h:10
BuilderMessenger(EDepSim::Builder *c, const char *guide=NULL)
p
Definition: test.py:223
void SetTPCDepth(double v)
void DefineCAPTAINVessel()
Fill the vessel definition with values for CAPTAIN.
void SetNewValue(G4UIcommand *cmd, G4String val)
G4ThreeVector GetTPCOffset()
virtual G4LogicalVolume * GetPiece(void)
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
Definition: qstring.cpp:11649
virtual G4LogicalVolume * GetPiece(void)
static constexpr double mm
Definition: Units.h:65
G4ThreeVector GetOffset()
G4ThreeVector GetOffset()
virtual G4LogicalVolume * GetPiece(void)
static constexpr double degree
Definition: Units.h:161
list cmd
Definition: getreco.py:22
CaptCryostatMessenger(CaptCryostatBuilder *c)
G4String CommandName(G4String cmd)
Build a command name with the directory prefix.
G4UIcmdWithADoubleAndUnit * fTPCDepthCMD
void SetVesselType(std::string v)
virtual G4LogicalVolume * GetPiece(void)
QTextStream & endl(QTextStream &s)
virtual G4LogicalVolume * GetPiece(void)