EDepSimModuleBuilder.cc
Go to the documentation of this file.
2 #include "EDepSimException.hh"
3 
4 #include "EDepSimLog.hh"
5 
6 #include <globals.hh>
7 #include <G4Box.hh>
8 #include <G4Material.hh>
9 #include <G4LogicalVolume.hh>
10 #include <G4VPhysicalVolume.hh>
11 #include <G4PVPlacement.hh>
12 #include <G4VisAttributes.hh>
13 
14 #include <G4SystemOfUnits.hh>
15 #include <G4PhysicalConstants.hh>
16 
17 #include <cmath>
18 
20  if (fPartsList != 0) {
21  fPartsList->clear();
22  delete fPartsList;
23  }
24  if (fTransList != 0) {
25  fTransList->clear();
26  delete fTransList;
27  }
28 }
29 
31  fWidth = 250*CLHEP::cm;
32  fHeight = 250*CLHEP::cm;
33  fLength = 0*CLHEP::cm;
35  fFixLength = false;
36  xPosition = 0*CLHEP::cm;
37  yPosition = 0*CLHEP::cm;
38 
39  // Set default translation parameters as 0.
40  fPair.first = 0.0*CLHEP::mm;
41  fPair.second = 0.0*CLHEP::mm;
42 
44 
45  fPartsList = new PartsList();
46  fTransList = new TransList();
47 
48  xmax = xmin = ymax = ymin = 0.0*CLHEP::mm;
49 }
50 
51 G4LogicalVolume *EDepSim::ModuleBuilder::GetPiece(void) {
52 
53  // Build the logical volumes.
54 
55  for (PartsList::iterator e = fPartsList->begin();
56  e != fPartsList->end(); ++e) {
57  (*e)->SetWidth(GetWidth());
58  (*e)->SetHeight(GetHeight());
59  }
60 
61  // Calculate the length
62  fLength = 0.0;
63  for (PartsList::iterator e = fPartsList->begin();
64  e != fPartsList->end();++e) {
65  double componentLength = (*e)->GetLength();
66  if (componentLength < 0.0) {
67  EDepSimWarn("%%%%%%% Negative Component Length ");
68  EDepSimWarn("%% " << (*e)->GetName());
69  continue;
70  }
71  fLength += componentLength;
72  }
73 
74  if (fLength<0.10*CLHEP::mm) return NULL;
75 
76  if (GetLength()>GetTargetLength()) {
78  EDepSimError(" Is " << GetLength()/CLHEP::cm << " cm long with "
79  << GetTargetLength()/CLHEP::cm << " cm available");
80  EDepSimThrow("EDepSim::ModuleBuilder::GetPiece(): Volume too long");
81  }
82 
83  /// Position all of the sub volumes.
84  double zPosition = -fLength/2.;
85 
87 
88  // Construct the envelope.
89  G4VSolid *solid = new G4Box(GetName(),
90  GetWidth()/2,
91  GetHeight()/2,
92  GetLength()/2);
93 
94  /// Create the volume for the envelope.
95  G4LogicalVolume *logVolume
96  = new G4LogicalVolume(solid,
97  FindMaterial("Air"),
98  GetName());
99 
100  int i = 0;
101  for (PartsList::iterator e = fPartsList->begin();
102  e != fPartsList->end(); ++e) {
103  zPosition += (*e)->GetLength()/2;
104 
105  // Add translation parameters from fTransList in the placement, called
106  // by the index i.
107 
108  G4double xpos = fTransList->at(i).first;
109  G4double ypos = fTransList->at(i).second;
110 
111  if(xpos>xmax)xmax=xpos;
112  if(xpos<xmin)xmin=xpos;
113  if(ypos>ymax)ymax=ypos;
114  if(ypos<ymin)ymin=ypos;
115 
116  new G4PVPlacement(0,
117  G4ThreeVector(xPosition+xpos,
118  yPosition+ypos,
119  zPosition),
120  (*e)->GetPiece(),
121  (*e)->GetName(),
122  logVolume,
123  false,
124  i);
125  zPosition += (*e)->GetLength()/2;
126  i++;
127  }
128 
129  return logVolume;
130 }
131 
133  fPartsList->clear();
134 }
135 
137  EDepSim::ComponentBuilder* fBuilder
138  = &Get<EDepSim::ComponentBuilder>(name);
139  fPartsList->push_back(fBuilder);
140 
141  // Run parallel with fPartsList.
142  fTransList->push_back(fPair);
143 }
144 
146  if (r<1) {
147  EDepSimError("*** Repetition count must be greater than "
148  "or equal to one.");
149  }
150 
151  if (c<1) {
152  EDepSimError("*** Component count must be greater than "
153  "or equal to one.");
154  }
155 
156  if (fPartsList->size()<(unsigned) c) {
157  EDepSimError("Not enough parts to build module");
158  EDepSimError(" Parts supplied: " << fPartsList->size()
159  << " Parts required: " << c);
160  EDepSimError("Module construction failed.");
161  return;
162  }
163 
164  PartsList additions(fPartsList->end() - c, fPartsList->end());
165 
166  // Start the count from 1 since there is already one component on the list.
167  for (int i=1; i<r; ++i) {
169  fPartsList->insert(e,additions.begin(),additions.end());
170  }
171  for (int i = 0; i < r*c; i++)
172  {
173  fTransList->push_back(fPair);
174  }
175 }
176 
177 // Method to translate each component in a module, so that misalignment is
178 // simulated. module is the module number, cPerM is the component interval
179 // (number of components in a module). c is the number of components to
180 // translate, starting from the top of the list. This was design to simulate
181 // FGD scintillator module misalignments. There is no translation parameter
182 // in z.
183 void EDepSim::ModuleBuilder::SetModuleCompTrans(int module, int cPerM, int c,
184  double transX, double transY) {
185  for (int i = 0; i < c; i++) {
186  fTransList->at(module*cPerM+i).first = transX;
187  fTransList->at(module*cPerM+i).second = transY;
188  }
189 }
static constexpr double cm
Definition: Units.h:68
static QCString name
Definition: declinfo.cpp:673
intermediate_table::iterator iterator
G4String GetName(void)
Return the base name of the object that this builds.
std::pair< double, double > fPair
Default pair of translation constants.
std::vector< EDepSim::ComponentBuilder * > PartsList
A vector of ComponentBuilders that will be added to the module.
TH3F * xpos
Definition: doAna.cpp:29
void SetMessenger(G4UImessenger *m)
Set the messenger for this constructor.
double fLength
The length of the module.
G4Material * FindMaterial(G4String m)
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
double yPosition
The y position at which components are positioned inside the module.
TH3F * ypos
Definition: doAna.cpp:30
double GetTargetLength(void)
Get the target length of the module bounding box.
void ClearComponentList(void)
Clear the list of components to be added to the FG tracker.
void SetModuleCompTrans(int m, int cPerM, int c, double transX, double transY)
bool fFixLength
Logical flag to accept the target length as the module length.
const double e
virtual G4LogicalVolume * GetPiece(void)
double GetLength(void)
Get the length of the module.
void SetRepetitions(int r, int c)
double GetWidth(void)
Get the width of the module.
double xPosition
The x position at which components are positioned inside the module.
double fHeight
The height of the module.
#define EDepSimError(outStream)
Definition: EDepSimLog.hh:503
G4double xmax
Collect the minimum and maximum of translations in x and y.
#define EDepSimWarn(outStream)
Definition: EDepSimLog.hh:576
double fWidth
The width of the module.
static constexpr double mm
Definition: Units.h:65
std::vector< std::pair< double, double > > TransList
double GetHeight(void)
Get the height of the module.