Belle II Software development
GeoSVDCreator Class Reference

The creator for the SVD geometry of the Belle II detector. More...

#include <GeoSVDCreator.h>

Inheritance diagram for GeoSVDCreator:
GeoVXDCreator CreatorBase

Public Member Functions

 GeoSVDCreator ()
 Constructor of the GeoSVDCreator class.
 
virtual ~GeoSVDCreator ()
 The destructor of the GeoSVDCreator class.
 
virtual void create (const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 The old create member: create the configuration object(s) on the fly and call the geometry creation routine.
 
virtual void createPayloads (const GearDir &content, const IntervalOfValidity &iov) override
 Create the configuration objects and save them in the Database.
 
virtual void createFromDB (const std::string &name, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 Create the geometry from the Database.
 
virtual VXD::GeoVXDAssembly createLayerSupport (int, const SVDGeometryPar &parameters)
 Create support structure for a SVD Layer.
 
virtual VXD::GeoVXDAssembly createLadderSupport (int, const SVDGeometryPar &parameters)
 Create support structure for a SVD Ladder.
 
virtual VXD::GeoVXDAssembly createHalfShellSupport (const SVDGeometryPar &parameters)
 Create support structure for SVD Half Shell, that means everything that does not depend on layer or sensor alignment.
 
virtual VXD::SensorInfoBasecreateSensorInfo (const VXDGeoSensorPar &sensor) override
 Read the sensor definitions from the database.
 
SVDSensorInfoParreadSensorInfo (const GearDir &sensor)
 Read the sensor definitions from gearbox.
 
virtual VXD::SensitiveDetectorBasecreateSensitiveDetector (VxdID sensorID, const VXDGeoSensor &sensor, const VXDGeoSensorPlacement &placement) override
 Return a SensitiveDetector implementation for a given sensor.
 
void readHalfShellSupport (const GearDir &support, SVDGeometryPar &svdGeometryPar)
 Create support structure for SVD Half Shell, that means everything that does not depend on layer or sensor alignment.
 
void readLayerSupport (int layer, const GearDir &support, SVDGeometryPar &svdGeometryPar)
 Create support structure for a SVD Layer.
 
void readLadderSupport (int layer, const GearDir &support, SVDGeometryPar &svdGeometryPar)
 Create support structure for a SVD Ladder.
 
virtual void setCurrentLayer (int layer, const VXDGeometryPar &parameters)
 Read parameters for given layer and store in m_ladder.
 
G4Transform3D placeLadder (int ladderID, double phi, G4LogicalVolume *volume, const G4Transform3D &placement, const VXDGeometryPar &parameters)
 Place ladder corresponding to the given ladder id into volume setLayer has to be called first to set the correct layer id.
 
G4Transform3D getPosition (const VXDGeoComponent &mother, const VXDGeoComponent &daughter, const VXDGeoPlacement &placement, bool originCenter)
 Return the position where a daughter component is to be placed.
 
G4Transform3D getAlignment (const VXDAlignmentPar &params)
 Get Alignment from paylead object.
 
GeoVXDAssembly createSubComponents (const std::string &name, VXDGeoComponent &component, std::vector< VXDGeoPlacement > placements, bool originCenter=true, bool allowOutside=false)
 Place a list of subcomponents into an component.
 
G4VSolid * createTrapezoidal (const std::string &name, double width, double width2, double length, double &height, double angle=0)
 Create a trapezoidal solid.
 
void createDiamonds (const VXDGeoRadiationSensorsPar &params, G4LogicalVolume &topVolume, G4LogicalVolume &envelopeVolume)
 Create diamond radiation sensors.
 
std::vector< VXDGeoPlacementPargetSubComponents (const GearDir &path)
 Return vector of VXDGeoPlacements with all the components defined inside a given path.
 
virtual void readLadder (int layer, GearDir components, VXDGeometryPar &geoparameters)
 Read parameters for a ladder in layer with given ID from gearbox and layer store them in payload.
 
virtual void readLadderComponents (int layerID, int ladderID, GearDir content, VXDGeometryPar &vxdGeometryPar)
 Read parameters for ladder components and their alignment corresponding to the given ladder id.
 
void readComponent (const std::string &name, GearDir components, VXDGeometryPar &vxdGeometryPar)
 Read parameters for component name from Gearbox into geometry payload.
 
void readSubComponents (const std::vector< VXDGeoPlacementPar > &placements, const GearDir &componentsDir, VXDGeometryPar &vxdGeometryPar)
 Read parameters for all components in placement container from Gearbox into payload.
 
 BELLE2_DEFINE_EXCEPTION (DBNotImplemented, "Cannot create geometry from Database.")
 Exception that will be thrown in createFromDB if member is not yet implemented by creator.
 

Protected Attributes

std::string m_prefix
 Prefix to prepend to all volume names.
 
GearDir m_alignment
 GearDir pointing to the alignment parameters.
 
GearDir m_components
 GearDir pointing to the toplevel of the components.
 
std::map< std::string, VXDGeoComponentm_componentCache
 Cache of all previously created components.
 
std::map< std::string, VXDGeoSensorm_sensorMap
 Map containing Information about all defined sensor types.
 
VXDGeoLadder m_ladder
 Parameters of the currently active ladder.
 
std::vector< Simulation::SensitiveDetectorBase * > m_sensitive
 List to all created sensitive detector instances.
 
GeoVXDRadiationSensors m_radiationsensors
 Diamond radiation sensor "sub creator".
 
std::string m_defaultMaterial
 Name of the Material to be used for Air.
 
float m_distanceTolerance {(float)(5 * Unit::um)}
 tolerance for Geant4 steps to be merged to a single step
 
float m_electronTolerance {100}
 tolerance for the energy deposition in electrons to be merged in a single step
 
float m_minimumElectrons {10}
 minimum number of electrons to be deposited by a particle to be saved
 
double m_activeStepSize {5 * Unit::um}
 Stepsize to be used inside active volumes.
 
bool m_activeChips {false}
 Make also chips sensitive.
 
bool m_seeNeutrons {false}
 Make sensitive detectors also see neutrons.
 
bool m_onlyPrimaryTrueHits {false}
 If true only create TrueHits from primary particles and ignore secondaries.
 
bool m_onlyActiveMaterial {false}
 If this is true, only active Materials will be placed for tracking studies.
 
std::vector< G4UserLimits * > m_UserLimits
 Vector of G4UserLimit pointers.
 
std::string m_currentHalfShell {""}
 Current half-shell being processed (need to know ladder parent for hierarchy)
 
std::map< std::string, Belle2::VxdIDm_halfShellVxdIDs
 Used for translation of half-shell name into a VxdID to consitently handle it in hierarchy.
 

Private Member Functions

SVDGeometryPar createConfiguration (const GearDir &param)
 Create a parameter object from the Gearbox XML parameters.
 
void createGeometry (const SVDGeometryPar &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
 Create the geometry from a parameter object.
 

Private Attributes

std::vector< SensorInfo * > m_SensorInfo
 Vector of pointers to SensorInfo objects.
 

Detailed Description

The creator for the SVD geometry of the Belle II detector.


Definition at line 28 of file GeoSVDCreator.h.

Constructor & Destructor Documentation

◆ GeoSVDCreator()

GeoSVDCreator ( )
inline

Constructor of the GeoSVDCreator class.

Definition at line 37 of file GeoSVDCreator.h.

37: VXD::GeoVXDCreator("SVD") {};

◆ ~GeoSVDCreator()

~GeoSVDCreator ( )
virtual

The destructor of the GeoSVDCreator class.

Definition at line 53 of file GeoSVDCreator.cc.

54 {
55 for (SensorInfo* sensorInfo : m_SensorInfo) delete sensorInfo;
56 m_SensorInfo.clear();
57 }
std::vector< SensorInfo * > m_SensorInfo
Vector of pointers to SensorInfo objects.

Member Function Documentation

◆ create()

virtual void create ( const GearDir content,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
inlineoverridevirtual

The old create member: create the configuration object(s) on the fly and call the geometry creation routine.

Implements CreatorBase.

Definition at line 44 of file GeoSVDCreator.h.

45 {
46 SVDGeometryPar config = createConfiguration(content);
47 createGeometry(config, topVolume, type);
48 }
SVDGeometryPar createConfiguration(const GearDir &param)
Create a parameter object from the Gearbox XML parameters.
void createGeometry(const SVDGeometryPar &parameters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create the geometry from a parameter object.

◆ createConfiguration()

SVDGeometryPar createConfiguration ( const GearDir param)
private

Create a parameter object from the Gearbox XML parameters.

Definition at line 145 of file GeoSVDCreator.cc.

146 {
147 SVDGeometryPar svdGeometryPar;
148
149 //Read prefix ('SVD' or 'PXD')
150 svdGeometryPar.setPrefix(m_prefix);
151
152 //Read some global parameters
153 VXDGlobalPar globals((float)content.getDouble("ElectronTolerance", 100),
154 (float)content.getDouble("MinimumElectrons", 10),
155 content.getLength("ActiveStepSize", 0.005),
156 content.getBool("ActiveChips", false),
157 content.getBool("SeeNeutrons", false),
158 content.getBool("OnlyPrimaryTrueHits", false),
159 content.getBool("OnlyActiveMaterial", false),
160 (float)content.getLength("DistanceTolerance", 0.005),
161 content.getString("DefaultMaterial", "Air")
162 );
163 svdGeometryPar.setGlobalParams(globals);
164
165 //Read envelope parameters
166 GearDir envelopeParams(content, "Envelope/");
167 VXDEnvelopePar envelope(envelopeParams.getString("Name", ""),
168 envelopeParams.getString("Material", "Air"),
169 envelopeParams.getString("Color", ""),
170 envelopeParams.getAngle("minPhi", 0),
171 envelopeParams.getAngle("maxPhi", 2 * M_PI),
172 (envelopeParams.getNodes("InnerPoints/point").size() > 0)
173 );
174
175 for (const GearDir& point : envelopeParams.getNodes("InnerPoints/point")) {
176 pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
177 envelope.getInnerPoints().push_back(ZXPoint);
178 }
179 for (const GearDir& point : envelopeParams.getNodes("OuterPoints/point")) {
180 pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
181 envelope.getOuterPoints().push_back(ZXPoint);
182 }
183 svdGeometryPar.setEnvelope(envelope);
184
185 // Read alignment for detector m_prefix ('PXD' or 'SVD')
186 string pathAlign = (boost::format("Align[@component='%1%']/") % m_prefix).str();
187 GearDir paramsAlign(GearDir(content, "Alignment/"), pathAlign);
188 if (!paramsAlign) {
189 B2WARNING("Could not find alignment parameters for component " << m_prefix);
190 return svdGeometryPar;
191 }
192 svdGeometryPar.getAlignmentMap()[m_prefix] = VXDAlignmentPar(paramsAlign.getLength("du"),
193 paramsAlign.getLength("dv"),
194 paramsAlign.getLength("dw"),
195 paramsAlign.getAngle("alpha"),
196 paramsAlign.getAngle("beta"),
197 paramsAlign.getAngle("gamma")
198 );
199
200 //Read the definition of all sensor types
201 GearDir components(content, "Components/");
202 for (const GearDir& paramsSensor : components.getNodes("Sensor")) {
203 string sensorTypeID = paramsSensor.getString("@type");
204
205 VXDGeoSensorPar sensor(paramsSensor.getString("Material"),
206 paramsSensor.getString("Color", ""),
207 paramsSensor.getLength("width"),
208 paramsSensor.getLength("width2", 0),
209 paramsSensor.getLength("length"),
210 paramsSensor.getLength("height"),
211 paramsSensor.getAngle("angle", 0),
212 paramsSensor.getBool("@slanted", false)
213 );
214 sensor.setActive(VXDGeoComponentPar(
215 paramsSensor.getString("Material"),
216 paramsSensor.getString("Active/Color", "#f00"),
217 paramsSensor.getLength("Active/width"),
218 paramsSensor.getLength("Active/width2", 0),
219 paramsSensor.getLength("Active/length"),
220 paramsSensor.getLength("Active/height")
221 ), VXDGeoPlacementPar(
222 "Active",
223 paramsSensor.getLength("Active/u"),
224 paramsSensor.getLength("Active/v"),
225 paramsSensor.getString("Active/w", "center"),
226 paramsSensor.getLength("Active/woffset", 0)
227 ));
228
229 SVDSensorInfoPar* svdInfo = readSensorInfo(GearDir(paramsSensor, "Active"));
230 sensor.setSensorInfo(svdInfo);
231 sensor.setComponents(getSubComponents(paramsSensor));
232 svdGeometryPar.getSensorMap()[sensorTypeID] = sensor;
233 svdGeometryPar.getSensorInfos().push_back(svdInfo);
234 }
235
236 //Build all ladders including Sensors
237 GearDir support(content, "Support/");
238 readHalfShellSupport(support, svdGeometryPar);
239
240 for (const GearDir& shell : content.getNodes("HalfShell")) {
241
242 string shellName = m_prefix + "." + shell.getString("@name");
243 string pathShell = (boost::format("Align[@component='%1%']/") % shellName).str();
244 GearDir paramsShell(GearDir(content, "Alignment/"), pathShell);
245 if (!paramsShell) {
246 B2WARNING("Could not find alignment parameters for component " << shellName);
247 return svdGeometryPar;
248 }
249 svdGeometryPar.getAlignmentMap()[shellName] = VXDAlignmentPar(paramsShell.getLength("du"),
250 paramsShell.getLength("dv"),
251 paramsShell.getLength("dw"),
252 paramsShell.getAngle("alpha"),
253 paramsShell.getAngle("beta"),
254 paramsShell.getAngle("gamma")
255 );
256
257 VXDHalfShellPar halfShell(shell.getString("@name"), shell.getAngle("shellAngle", 0));
258
259 for (const GearDir& layer : shell.getNodes("Layer")) {
260 int layerID = layer.getInt("@id");
261
262 readLadder(layerID, components, svdGeometryPar);
263 readLayerSupport(layerID, support, svdGeometryPar);
264 readLadderSupport(layerID, support, svdGeometryPar);
265
266 //Loop over defined ladders
267 for (const GearDir& ladder : layer.getNodes("Ladder")) {
268 int ladderID = ladder.getInt("@id");
269 double phi = ladder.getAngle("phi", 0);
270 readLadderComponents(layerID, ladderID, content, svdGeometryPar);
271 halfShell.addLadder(layerID, ladderID, phi);
272 }
273 }
274 svdGeometryPar.getHalfShells().push_back(halfShell);
275 }
276
277 //Create diamond radiation sensors if defined and in background mode
278 GearDir radiationDir(content, "RadiationSensors");
279 if (svdGeometryPar.getGlobalParams().getActiveChips() && radiationDir) {
280 VXDGeoRadiationSensorsPar radiationSensors(
281 m_prefix,
282 radiationDir.getBool("insideEnvelope"),
283 radiationDir.getLength("width"),
284 radiationDir.getLength("length"),
285 radiationDir.getLength("height"),
286 radiationDir.getString("material")
287 );
288
289 //Add radiation sensor positions
290 for (GearDir& position : radiationDir.getNodes("position")) {
291 VXDGeoRadiationSensorsPositionPar diamonds(position.getLength("z"),
292 position.getLength("radius"),
293 position.getAngle("theta")
294 );
295
296 //Loop over all phi positions
297 for (GearDir& sensor : position.getNodes("phi")) {
298 //Add sensor with angle and id
299 diamonds.addSensor(sensor.getInt("@id"), sensor.getAngle());
300 }
301 radiationSensors.addPosition(diamonds);
302 }
303 svdGeometryPar.setRadiationSensors(radiationSensors);
304 }
305 return svdGeometryPar;
306 }
void readLayerSupport(int layer, const GearDir &support, SVDGeometryPar &svdGeometryPar)
Create support structure for a SVD Layer.
void readLadderSupport(int layer, const GearDir &support, SVDGeometryPar &svdGeometryPar)
Create support structure for a SVD Ladder.
void readHalfShellSupport(const GearDir &support, SVDGeometryPar &svdGeometryPar)
Create support structure for SVD Half Shell, that means everything that does not depend on layer or s...
SVDSensorInfoPar * readSensorInfo(const GearDir &sensor)
Read the sensor definitions from gearbox.
virtual void readLadderComponents(int layerID, int ladderID, GearDir content, VXDGeometryPar &vxdGeometryPar)
Read parameters for ladder components and their alignment corresponding to the given ladder id.
std::string m_prefix
Prefix to prepend to all volume names.
virtual void readLadder(int layer, GearDir components, VXDGeometryPar &geoparameters)
Read parameters for a ladder in layer with given ID from gearbox and layer store them in payload.
std::vector< VXDGeoPlacementPar > getSubComponents(const GearDir &path)
Return vector of VXDGeoPlacements with all the components defined inside a given path.

◆ createDiamonds()

void createDiamonds ( const VXDGeoRadiationSensorsPar params,
G4LogicalVolume &  topVolume,
G4LogicalVolume &  envelopeVolume 
)
inherited

Create diamond radiation sensors.

Definition at line 209 of file GeoVXDCreator.cc.

211 {
212 //Set the correct top volume to either global top or detector envelope
213 G4LogicalVolume* top = &topVolume;
214 if (params.getInsideEnvelope()) {
215 top = &envelopeVolume;
216 }
217
218 //shape and material are the same for all sensors so create them now
219 const double width = params.getWidth();
220 const double length = params.getLength();
221 const double height = params.getHeight();
222 G4Box* shape = 0;
223 G4Material* material = geometry::Materials::get(params.getMaterial());
224
225 //Now loop over all positions
226 const std::vector<VXDGeoRadiationSensorsPositionPar>& Positions = params.getPositions();
227 for (const VXDGeoRadiationSensorsPositionPar& position : Positions) {
228 //get the radial and z position
229 const double r = position.getRadius();
230 const double z = position.getZ();
231 const double theta = position.getTheta();
232 //and loop over all phi positions
233 const std::map<int, double>& Sensors = position.getSensors();
234 for (const std::pair<const int, double>& sensor : Sensors) {
235 //for (GearDir& sensor : position.getNodes("phi")) {
236 //we need angle and Id
237 const double phi = sensor.second;
238 const int id = sensor.first;
239 //then we create a nice name
240 const std::string name = params.getSubDetector() + ".DiamondSensor." + std::to_string(id);
241 //and create the sensor volume
242 if (not shape) shape = new G4Box("radiationSensorDiamond", width / 2 * CLHEP::cm, length / 2 * CLHEP::cm, height / 2 * CLHEP::cm);
243 G4LogicalVolume* volume = new G4LogicalVolume(shape, material, name);
244 //add a sensitive detector implementation
245 BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(params.getSubDetector().c_str(), id);
246 volume->SetSensitiveDetector(sensitive);
247 //and place it at the correct position
248 G4Transform3D transform = G4RotateZ3D(phi - M_PI / 2) * G4Translate3D(0, r * CLHEP::cm,
249 z * CLHEP::cm) * G4RotateX3D(-M_PI / 2 - theta);
250 new G4PVPlacement(transform, volume, name, top, false, 1);
251 }
252 }
253 }
static G4Material * get(const std::string &name)
Find given material.
Definition: Materials.h:63
std::map< VxdID, Sensor > Sensors
Map of all hits in all Sensors.

◆ createFromDB()

virtual void createFromDB ( const std::string &  name,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
inlineoverridevirtual

Create the geometry from the Database.

Reimplemented from CreatorBase.

Definition at line 60 of file GeoSVDCreator.h.

61 {
62 DBObjPtr<SVDGeometryPar> dbObj;
63 if (!dbObj) {
64 // Check that we found the object and if not report the problem
65 B2FATAL("No configuration for " << name << " found.");
66 }
67 createGeometry(*dbObj, topVolume, type);
68 }

◆ createGeometry()

void createGeometry ( const SVDGeometryPar parameters,
G4LogicalVolume &  topVolume,
geometry::GeometryTypes  type 
)
private

Create the geometry from a parameter object.

Definition at line 308 of file GeoSVDCreator.cc.

309 {
310
311 m_activeStepSize = parameters.getGlobalParams().getActiveStepSize() / Unit::mm;
312 m_activeChips = parameters.getGlobalParams().getActiveChips();
313 m_seeNeutrons = parameters.getGlobalParams().getSeeNeutrons();
314 m_onlyPrimaryTrueHits = parameters.getGlobalParams().getOnlyPrimaryTrueHits();
315 m_distanceTolerance = parameters.getGlobalParams().getDistanceTolerance();
316 m_electronTolerance = parameters.getGlobalParams().getElectronTolerance();
317 m_minimumElectrons = parameters.getGlobalParams().getMinimumElectrons();
318 m_onlyActiveMaterial = parameters.getGlobalParams().getOnlyActiveMaterial();
319 m_defaultMaterial = parameters.getGlobalParams().getDefaultMaterial();
320
321 G4Material* material = Materials::get(m_defaultMaterial);
322 if (!material) B2FATAL("Default Material of VXD, '" << m_defaultMaterial << "', could not be found");
323
324
325 //Build envelope
326 G4LogicalVolume* envelope(0);
327 G4VPhysicalVolume* physEnvelope{nullptr};
328 if (!parameters.getEnvelope().getExists()) {
329 B2INFO("Could not find definition for " + m_prefix + " Envelope, placing directly in top volume");
330 envelope = &topVolume;
331 } else {
332 double minZ(0), maxZ(0);
333 G4Polycone* envelopeCone = geometry::createRotationSolid("Envelope",
334 parameters.getEnvelope().getInnerPoints(),
335 parameters.getEnvelope().getOuterPoints(),
336 parameters.getEnvelope().getMinPhi(),
337 parameters.getEnvelope().getMaxPhi(),
338 minZ, maxZ
339 );
340 envelope = new G4LogicalVolume(envelopeCone, material, m_prefix + ".Envelope");
341 setVisibility(*envelope, false);
342 physEnvelope = new G4PVPlacement(getAlignment(parameters.getAlignment(m_prefix)), envelope, m_prefix + ".Envelope",
343 &topVolume, false, 1);
344
345 // Set up region for production cuts
346 G4Region* aRegion = new G4Region("SVDEnvelope");
347 envelope->SetRegion(aRegion);
348 aRegion->AddRootLogicalVolume(envelope);
349 }
350
351 //Read the definition of all sensor types
352 for (const pair<const string, VXDGeoSensorPar>& typeAndSensor : parameters.getSensorMap()) {
353 const string& sensorTypeID = typeAndSensor.first;
354 const VXDGeoSensorPar& paramsSensor = typeAndSensor.second;
355 VXDGeoSensor sensor(
356 paramsSensor.getMaterial(),
357 paramsSensor.getColor(),
358 paramsSensor.getWidth() / Unit::mm,
359 paramsSensor.getWidth2() / Unit::mm,
360 paramsSensor.getLength() / Unit::mm,
361 paramsSensor.getHeight() / Unit::mm,
362 paramsSensor.getSlanted()
363 );
364 sensor.setActive(VXDGeoComponent(
365 paramsSensor.getMaterial(),
366 paramsSensor.getActiveArea().getColor(),
367 paramsSensor.getActiveArea().getWidth() / Unit::mm,
368 paramsSensor.getActiveArea().getWidth2() / Unit::mm,
369 paramsSensor.getActiveArea().getLength() / Unit::mm,
370 paramsSensor.getActiveArea().getHeight() / Unit::mm
371 ), VXDGeoPlacement(
372 "Active",
373 paramsSensor.getActivePlacement().getU() / Unit::mm,
374 paramsSensor.getActivePlacement().getV() / Unit::mm,
375 paramsSensor.getActivePlacement().getW(),
376 paramsSensor.getActivePlacement().getWOffset() / Unit::mm
377 ));
378 sensor.setSensorInfo(createSensorInfo(paramsSensor));
379
380 vector<VXDGeoPlacement> subcomponents;
381 for (const VXDGeoPlacementPar& component : paramsSensor.getComponents()) {
382 subcomponents.push_back(VXDGeoPlacement(
383 component.getName(),
384 component.getU() / Unit::mm,
385 component.getV() / Unit::mm,
386 component.getW(),
387 component.getWOffset() / Unit::mm
388 ));
389 }
390 sensor.setComponents(subcomponents);
391 m_sensorMap[sensorTypeID] = sensor;
392 }
393
394 //Read the component cache from DB
395 for (const string& name : parameters.getComponentInsertOder()) {
396 if (m_componentCache.find(name) != m_componentCache.end()) {
397 // already created due to being a sub component of a previous
398 // component. Seems fishy since the information of this component
399 // is in the db at least twice so we could run into
400 // inconsistencies.
401 B2WARNING("Component " << name << " already created from previous subcomponents, should not be here");
402 continue;
403 }
404 const VXDGeoComponentPar& paramsComponent = parameters.getComponent(name);
405 VXDGeoComponent c(
406 paramsComponent.getMaterial(),
407 paramsComponent.getColor(),
408 paramsComponent.getWidth() / Unit::mm,
409 paramsComponent.getWidth2() / Unit::mm,
410 paramsComponent.getLength() / Unit::mm,
411 paramsComponent.getHeight() / Unit::mm
412 );
413 double angle = paramsComponent.getAngle();
414
415
416 if (c.getWidth() <= 0 || c.getLength() <= 0 || c.getHeight() <= 0) {
417 B2DEBUG(100, "One dimension empty, using auto resize for component");
418 } else {
419 G4VSolid* solid = createTrapezoidal(m_prefix + "." + name, c.getWidth(), c.getWidth2(), c.getLength(), c.getHeight(), angle);
420 c.setVolume(new G4LogicalVolume(solid, Materials::get(c.getMaterial()), m_prefix + "." + name));
421 }
422
423 vector<VXDGeoPlacement> subComponents;
424 for (const VXDGeoPlacementPar& paramsSubComponent : paramsComponent.getSubComponents()) {
425 subComponents.push_back(VXDGeoPlacement(
426 paramsSubComponent.getName(),
427 paramsSubComponent.getU() / Unit::mm,
428 paramsSubComponent.getV() / Unit::mm,
429 paramsSubComponent.getW(),
430 paramsSubComponent.getWOffset() / Unit::mm
431 ));
432
433 }
434
435 createSubComponents(m_prefix + "." + name, c, subComponents);
436 if (m_activeChips && parameters.getSensitiveChipID(name) >= 0) {
437 int chipID = parameters.getSensitiveChipID(name);
438 B2DEBUG(50, "Creating BkgSensitiveDetector for component " << name << " with chipID " << chipID);
439 BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(m_prefix.c_str(), chipID);
440 c.getVolume()->SetSensitiveDetector(sensitive);
441 m_sensitive.push_back(sensitive);
442 }
443
444 m_componentCache[name] = c;
445 }
446
447 //Build all ladders including Sensors
448 VXD::GeoVXDAssembly shellSupport = createHalfShellSupport(parameters);
449
450 //const std::vector<VXDHalfShellPar>& HalfShells = parameters.getHalfShells();
451 for (const VXDHalfShellPar& shell : parameters.getHalfShells()) {
452 string shellName = shell.getName();
453 m_currentHalfShell = m_prefix + "." + shellName;
454 G4Transform3D shellAlignment = getAlignment(parameters.getAlignment(m_currentHalfShell));
455
456 // Remember shell coordinate system (into which ladders are inserted)
458
459 //Place shell support
460 double shellAngle = shell.getShellAngle();
461 if (!m_onlyActiveMaterial) shellSupport.place(envelope, shellAlignment * G4RotateZ3D(shellAngle));
462
463 //const std::map< int, std::vector<std::pair<int, double>> >& Layers = shell.getLayers();
464 for (const std::pair<const int, std::vector<std::pair<int, double>> >& layer : shell.getLayers()) {
465 int layerID = layer.first;
466 const std::vector<std::pair<int, double>>& Ladders = layer.second;
467
468
469 setCurrentLayer(layerID, parameters);
470
471 //Place Layer support
472 VXD::GeoVXDAssembly layerSupport = createLayerSupport(layerID, parameters);
473 if (!m_onlyActiveMaterial) layerSupport.place(envelope, shellAlignment * G4RotateZ3D(shellAngle));
474 VXD::GeoVXDAssembly ladderSupport = createLadderSupport(layerID, parameters);
475
476 //Loop over defined ladders
477 for (const std::pair<int, double>& ladder : Ladders) {
478 int ladderID = ladder.first;
479 double phi = ladder.second;
480
481 G4Transform3D ladderPlacement = placeLadder(ladderID, phi, envelope, shellAlignment, parameters);
482 if (!m_onlyActiveMaterial) ladderSupport.place(envelope, ladderPlacement);
483 }
484
485 }
486 }
487
488 //Now build cache with all transformations
489 if (physEnvelope) {
491 } else {
492 //create a temporary placement of the top volume.
493 G4PVPlacement topPlacement(nullptr, G4ThreeVector(0, 0, 0), &topVolume,
494 "temp_Top", nullptr, false, 1, false);
495 //and search for all VXD sensitive sensors within
497 }
498
499 //Create diamond radiation sensors if defined and in background mode
500 if (m_activeChips) {
501 if (parameters.getRadiationSensors().getSubDetector() == "") {
502 B2DEBUG(10, "Apparently no radiation sensors defined, skipping");
503 } else {
504 createDiamonds(parameters.getRadiationSensors(), topVolume, *envelope);
505 }
506 }
507 }
virtual VXD::GeoVXDAssembly createLayerSupport(int, const SVDGeometryPar &parameters)
Create support structure for a SVD Layer.
virtual VXD::GeoVXDAssembly createLadderSupport(int, const SVDGeometryPar &parameters)
Create support structure for a SVD Ladder.
virtual VXD::GeoVXDAssembly createHalfShellSupport(const SVDGeometryPar &parameters)
Create support structure for SVD Half Shell, that means everything that does not depend on layer or s...
virtual VXD::SensorInfoBase * createSensorInfo(const VXDGeoSensorPar &sensor) override
Read the sensor definitions from the database.
static const double mm
[millimeters]
Definition: Unit.h:70
void findVolumes(G4VPhysicalVolume *envelope)
Search a given Geometry for Sensors.
Definition: GeoCache.cc:78
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
void addHalfShellPlacement(VxdID halfShell, const G4Transform3D &placement)
Remember how half-shell is placed into world volume.
Definition: GeoCache.cc:232
std::map< std::string, VXDGeoSensor > m_sensorMap
Map containing Information about all defined sensor types.
float m_minimumElectrons
minimum number of electrons to be deposited by a particle to be saved
G4VSolid * createTrapezoidal(const std::string &name, double width, double width2, double length, double &height, double angle=0)
Create a trapezoidal solid.
void createDiamonds(const VXDGeoRadiationSensorsPar &params, G4LogicalVolume &topVolume, G4LogicalVolume &envelopeVolume)
Create diamond radiation sensors.
std::vector< Simulation::SensitiveDetectorBase * > m_sensitive
List to all created sensitive detector instances.
bool m_onlyActiveMaterial
If this is true, only active Materials will be placed for tracking studies.
double m_activeStepSize
Stepsize to be used inside active volumes.
float m_distanceTolerance
tolerance for Geant4 steps to be merged to a single step
std::map< std::string, Belle2::VxdID > m_halfShellVxdIDs
Used for translation of half-shell name into a VxdID to consitently handle it in hierarchy.
bool m_onlyPrimaryTrueHits
If true only create TrueHits from primary particles and ignore secondaries.
float m_electronTolerance
tolerance for the energy deposition in electrons to be merged in a single step
G4Transform3D getAlignment(const VXDAlignmentPar &params)
Get Alignment from paylead object.
GeoVXDAssembly createSubComponents(const std::string &name, VXDGeoComponent &component, std::vector< VXDGeoPlacement > placements, bool originCenter=true, bool allowOutside=false)
Place a list of subcomponents into an component.
std::map< std::string, VXDGeoComponent > m_componentCache
Cache of all previously created components.
G4Transform3D placeLadder(int ladderID, double phi, G4LogicalVolume *volume, const G4Transform3D &placement, const VXDGeometryPar &parameters)
Place ladder corresponding to the given ladder id into volume setLayer has to be called first to set ...
virtual void setCurrentLayer(int layer, const VXDGeometryPar &parameters)
Read parameters for given layer and store in m_ladder.
bool m_seeNeutrons
Make sensitive detectors also see neutrons.
std::string m_defaultMaterial
Name of the Material to be used for Air.
bool m_activeChips
Make also chips sensitive.
std::string m_currentHalfShell
Current half-shell being processed (need to know ladder parent for hierarchy)
G4Polycone * createRotationSolid(const std::string &name, const GearDir &params, double &minZ, double &maxZ)
Create a solid by roating two polylines around the Z-Axis.
Definition: utilities.cc:203
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition: utilities.cc:108

◆ createHalfShellSupport()

VXD::GeoVXDAssembly createHalfShellSupport ( const SVDGeometryPar parameters)
virtual

Create support structure for SVD Half Shell, that means everything that does not depend on layer or sensor alignment.

Parameters
parameters

Definition at line 635 of file GeoSVDCreator.cc.

636 {
637 VXD::GeoVXDAssembly supportAssembly;
638
639 //Half shell support is easy as we just add all the defined RotationSolids
640 double minZ(0), maxZ(0);
641
642 const std::vector<VXDRotationSolidPar>& RotationSolids = parameters.getRotationSolids();
643
644 for (const VXDRotationSolidPar& component : RotationSolids) {
645
646 string name = component.getName();
647 string material = component.getMaterial();
648
649 G4Polycone* solid = geometry::createRotationSolid(name,
650 component.getInnerPoints(),
651 component.getOuterPoints(),
652 component.getMinPhi(),
653 component.getMaxPhi(),
654 minZ, maxZ
655 );
656
657 G4LogicalVolume* volume = new G4LogicalVolume(
658 solid, geometry::Materials::get(material), m_prefix + ". " + name);
659 geometry::setColor(*volume, component.getColor());
660 supportAssembly.add(volume);
661 }
662 return supportAssembly;
663 }
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition: utilities.cc:100

◆ createLadderSupport()

VXD::GeoVXDAssembly createLadderSupport ( int  layer,
const SVDGeometryPar parameters 
)
virtual

Create support structure for a SVD Ladder.

Parameters
layerLayer ID to create the support
parameters

Definition at line 797 of file GeoSVDCreator.cc.

798 {
799 VXD::GeoVXDAssembly supportAssembly;
800
801 if (!parameters.getSupportRibsExist(layer)) return supportAssembly;
802 const SVDSupportRibsPar& support = parameters.getSupportRibs(layer);
803
804 // Get the common values for all layers
805 double spacing = support.getSpacing() / Unit::mm / 2.0;
806 double height = support.getHeight() / Unit::mm / 2.0;
807 double innerWidth = support.getInnerWidth() / Unit::mm / 2.0;
808 double outerWidth = support.getOuterWidth() / Unit::mm / 2.0;
809 double tabLength = support.getTabLength() / Unit::mm / 2.0;
810 G4VSolid* inner(0);
811 G4VSolid* outer(0);
812 G4Transform3D placement;
813
814
815 // Now lets create the ribs by adding all boxes to form one union solid
816 const std::vector<SVDSupportBoxPar>& Boxes = support.getBoxes();
817 for (const SVDSupportBoxPar& box : Boxes) {
818 double theta = box.getTheta();
819 double zpos = box.getZ() / Unit::mm;
820 double rpos = box.getR() / Unit::mm;
821 double length = box.getLength() / Unit::mm / 2.0;
822 G4Box* innerBox = new G4Box("innerBox", height, innerWidth, length);
823 G4Box* outerBox = new G4Box("outerBox", height, outerWidth, length);
824 if (!inner) {
825 inner = innerBox;
826 outer = outerBox;
827 placement = G4Translate3D(rpos, 0, zpos) * G4RotateY3D(theta);
828 } else {
829 G4Transform3D relative = placement.inverse() * G4Translate3D(rpos, 0, zpos) * G4RotateY3D(theta);
830 inner = new G4UnionSolid("innerBox", inner, innerBox, relative);
831 outer = new G4UnionSolid("outerBox", outer, outerBox, relative);
832 }
833 }
834
835 // Now lets add the tabs
836 const std::vector<SVDSupportTabPar>& Tabs = support.getTabs();
837 for (const SVDSupportTabPar& tab : Tabs) {
838 double theta = tab.getTheta();
839 double zpos = tab.getZ() / Unit::mm;
840 double rpos = tab.getR() / Unit::mm;
841 G4Box* innerBox = new G4Box("innerBox", height, innerWidth, tabLength);
842 if (!inner) {
843 inner = innerBox;
844 placement = G4Translate3D(rpos, 0, zpos) * G4RotateY3D(theta);
845 } else {
846 G4Transform3D relative = placement.inverse() * G4Translate3D(rpos, 0, zpos) * G4RotateY3D(theta);
847 inner = new G4UnionSolid("innerBox", inner, innerBox, relative);
848 }
849 }
850
851 // Now lets create forward and backward endmounts for the ribs
852 const std::vector<SVDEndmountPar>& Endmounts = support.getEndmounts();
853 for (const SVDEndmountPar& endmount : Endmounts) {
854 double endMountHeight = endmount.getHeight() / Unit::mm / 2.0;
855 double endMountWidth = endmount.getWidth() / Unit::mm / 2.0;
856 double endMountLength = endmount.getLength() / Unit::mm / 2.0;
857 double zpos = endmount.getZ() / Unit::mm;
858 double rpos = endmount.getR() / Unit::mm;
859 G4VSolid* endmountBox = new G4Box("endmountBox", endMountHeight, endMountWidth, endMountLength);
860 if (outer) { // holes for the ribs
861 endmountBox = new G4SubtractionSolid("endmountBox", endmountBox, outer, G4TranslateY3D(-spacing)*placement * G4Translate3D(-rpos, 0,
862 -zpos));
863 endmountBox = new G4SubtractionSolid("endmountBox", endmountBox, outer, G4TranslateY3D(spacing)*placement * G4Translate3D(-rpos, 0,
864 -zpos));
865 }
866 G4LogicalVolume* endmountVolume = new G4LogicalVolume(
867 endmountBox, geometry::Materials::get(support.getEndmountMaterial()),
868 (boost::format("%1%.Layer%2%.%3%Endmount") % m_prefix % layer % endmount.getName()).str());
869 supportAssembly.add(endmountVolume, G4Translate3D(rpos, 0, zpos));
870 }
871
872 // If there has been at least one Box, create the volumes and add them to the assembly
873 if (inner) {
874 outer = new G4SubtractionSolid("outerBox", outer, inner);
875 G4LogicalVolume* outerVolume = new G4LogicalVolume(
876 outer, geometry::Materials::get(support.getOuterMaterial()),
877 (boost::format("%1%.Layer%2%.SupportRib") % m_prefix % layer).str());
878 G4LogicalVolume* innerVolume = new G4LogicalVolume(
879 inner, geometry::Materials::get(support.getInnerMaterial()),
880 (boost::format("%1%.Layer%2%.SupportRib.Airex") % m_prefix % layer).str());
881 geometry::setColor(*outerVolume, support.getOuterColor());
882 geometry::setColor(*innerVolume, support.getInnerColor());
883 supportAssembly.add(innerVolume, G4TranslateY3D(-spacing)*placement);
884 supportAssembly.add(innerVolume, G4TranslateY3D(spacing)*placement);
885 supportAssembly.add(outerVolume, G4TranslateY3D(-spacing)*placement);
886 supportAssembly.add(outerVolume, G4TranslateY3D(spacing)*placement);
887 }
888
889 // Done, return the finished assembly
890 return supportAssembly;
891 }

◆ createLayerSupport()

VXD::GeoVXDAssembly createLayerSupport ( int  layer,
const SVDGeometryPar parameters 
)
virtual

Create support structure for a SVD Layer.

Parameters
layerLayer ID to create the support
parameters

Definition at line 667 of file GeoSVDCreator.cc.

668 {
669 VXD::GeoVXDAssembly supportAssembly;
670
671 //Check if there are any endrings defined for this layer. If not we don't create any
672 if (parameters.getEndringsExist(layer)) {
673 const SVDEndringsPar& support = parameters.getEndrings(layer);
674
675 string material = support.getMaterial();
676 double length = support.getLength() / Unit::mm / 2.0;
677 double gapWidth = support.getGapWidth() / Unit::mm;
678 double baseThickness = support.getBaseThickness() / Unit::mm / 2.0;
679
680 //Create the endrings
681 const std::vector<SVDEndringsTypePar>& Endrings = support.getTypes();
682 for (const SVDEndringsTypePar& endring : Endrings) {
683 double z = endring.getZ() / Unit::mm;
684 double baseRadius = endring.getBaseRadius() / Unit::mm;
685 double innerRadius = endring.getInnerRadius() / Unit::mm;
686 double outerRadius = endring.getOuterRadius() / Unit::mm;
687 double horiBarWidth = endring.getHorizontalBarWidth() / Unit::mm / 2.0;
688 double vertBarWidth = endring.getVerticalBarWidth() / Unit::mm / 2.0;
689
690 double angle = asin(gapWidth / innerRadius);
691 G4VSolid* endringSolid = new G4Tubs("OuterEndring", innerRadius, outerRadius, length, -M_PI / 2 + angle, M_PI - 2 * angle);
692 angle = asin(gapWidth / baseRadius);
693 G4VSolid* endringBase = new G4Tubs("InnerEndring", baseRadius, baseRadius + baseThickness, length, -M_PI / 2 + angle,
694 M_PI - 2 * angle);
695 endringSolid = new G4UnionSolid("Endring", endringSolid, endringBase);
696
697 //Now we need the bars which connect the two rings
698 double height = (innerRadius - baseRadius) / 2.0;
699 double x = vertBarWidth + gapWidth;
700 G4Box* verticalBar = new G4Box("VerticalBar", vertBarWidth, height, length);
701 G4Box* horizontalBar = new G4Box("HorizontalBar", height, horiBarWidth, length);
702 endringSolid = new G4UnionSolid("Endring", endringSolid, verticalBar, G4Translate3D(x, baseRadius + height, 0));
703 endringSolid = new G4UnionSolid("Endring", endringSolid, verticalBar, G4Translate3D(x, -(baseRadius + height), 0));
704 endringSolid = new G4UnionSolid("Endring", endringSolid, horizontalBar, G4Translate3D((baseRadius + height), 0, 0));
705
706 //Finally create the volume and add it to the assembly at the correct z position
707 G4LogicalVolume* endringVolume = new G4LogicalVolume(
708 endringSolid, geometry::Materials::get(material),
709 (boost::format("%1%.Layer%2%.%3%") % m_prefix % layer % endring.getName()).str());
710 supportAssembly.add(endringVolume, G4TranslateZ3D(z));
711 }
712 }
713
714 //Check if there are any coling pipes defined for this layer. If not we don't create any
715 if (parameters.getCoolingPipesExist(layer)) {
716 const SVDCoolingPipesPar& pipes = parameters.getCoolingPipes(layer);
717
718 string material = pipes.getMaterial();
719 double outerRadius = pipes.getOuterDiameter() / Unit::mm / 2.0;
720 double innerRadius = outerRadius - pipes.getWallThickness() / Unit::mm;
721 int nPipes = pipes.getNPipes();
722 double startPhi = pipes.getStartPhi();
723 double deltaPhi = pipes.getDeltaPhi();
724 double radius = pipes.getRadius() / Unit::mm;
725 double zstart = pipes.getZStart() / Unit::mm;
726 double zend = pipes.getZEnd() / Unit::mm;
727 double zlength = (zend - zstart) / 2.0;
728
729
730 // There are two parts: the straight pipes and the bendings. So we only need two different volumes
731 // which we place multiple times
732 G4Tubs* pipeSolid = new G4Tubs("CoolingPipe", innerRadius, outerRadius, zlength, 0, 2 * M_PI);
733 G4LogicalVolume* pipeVolume = new G4LogicalVolume(
734 pipeSolid, geometry::Materials::get(material),
735 (boost::format("%1%.Layer%2%.CoolingPipe") % m_prefix % layer).str());
736 geometry::setColor(*pipeVolume, "#ccc");
737
738 G4Torus* bendSolid = new G4Torus("CoolingBend", innerRadius, outerRadius, sin(deltaPhi / 2.0)*radius, -M_PI / 2, M_PI);
739 G4LogicalVolume* bendVolume = new G4LogicalVolume(
740 bendSolid, geometry::Materials::get(material),
741 (boost::format("%1%.Layer%2%.CoolingBend") % m_prefix % layer).str());
742
743 // Last pipe may be closer, thus we need additional bending
744 if (pipes.getDeltaL() > 0) {
745 double deltaL = pipes.getDeltaL() / Unit::mm;
746 G4Torus* bendSolidLast = new G4Torus("CoolingBendLast", innerRadius, outerRadius, sin(deltaPhi / 2.0) * radius - deltaL / 2.0,
747 -M_PI / 2, M_PI);
748 G4LogicalVolume* bendVolumeLast = new G4LogicalVolume(bendSolidLast, geometry::Materials::get(material),
749 (boost::format("%1%.Layer%2%.CoolingBendLast") % m_prefix % layer).str());
750 --nPipes;
751
752 // Place the last straight pipe
753 G4Transform3D placement_pipe = G4RotateZ3D(startPhi + (nPipes - 0.5) * deltaPhi) * G4Translate3D(cos(deltaPhi / 2.0) * radius,
754 sin(deltaPhi / 2.0) * radius - deltaL, zstart + zlength);
755 supportAssembly.add(pipeVolume, placement_pipe);
756
757 // Place forward or backward bend
758 double zpos = nPipes % 2 > 0 ? zend : zstart;
759 // Calculate transformation
760 G4Transform3D placement = G4RotateZ3D(startPhi + (nPipes - 0.5) * deltaPhi) * G4Translate3D(cos(deltaPhi / 2.0) * radius,
761 -deltaL / 2.0, zpos) * G4RotateY3D(M_PI / 2);
762 // If we are at the forward side we rotate the bend by 180 degree
763 if (nPipes % 2 > 0) {
764 placement = placement * G4RotateZ3D(M_PI);
765 }
766 // And place the bend
767 supportAssembly.add(bendVolumeLast, placement);
768 }
769
770 for (int i = 0; i < nPipes; ++i) {
771 // Place the straight pipes
772 G4Transform3D placement_pipe = G4RotateZ3D(startPhi + i * deltaPhi) * G4Translate3D(radius, 0, zstart + zlength);
773 supportAssembly.add(pipeVolume, placement_pipe);
774
775 // This was the easy part, now lets add the connection between the pipes. We only need n-1 bendings
776 if (i > 0) {
777 // Place forward or backward bend
778 double zpos = i % 2 > 0 ? zend : zstart;
779 // Calculate transformation
780 G4Transform3D placement = G4RotateZ3D(startPhi + (i - 0.5) * deltaPhi) * G4Translate3D(cos(deltaPhi / 2.0) * radius, 0,
781 zpos) * G4RotateY3D(M_PI / 2);
782 // If we are at the forward side we rotate the bend by 180 degree
783 if (i % 2 > 0) {
784 placement = placement * G4RotateZ3D(M_PI);
785 }
786 // And place the bend
787 supportAssembly.add(bendVolume, placement);
788 }
789 }
790 }
791
792 return supportAssembly;
793 }

◆ createPayloads()

virtual void createPayloads ( const GearDir content,
const IntervalOfValidity iov 
)
inlineoverridevirtual

Create the configuration objects and save them in the Database.

If more than one object is needed adjust accordingly

Reimplemented from CreatorBase.

Definition at line 52 of file GeoSVDCreator.h.

53 {
54 DBImportObjPtr<SVDGeometryPar> importObj;
55 importObj.construct(createConfiguration(content));
56 importObj.import(iov);
57 }

◆ createSensitiveDetector()

VXD::SensitiveDetectorBase * createSensitiveDetector ( VxdID  sensorID,
const VXDGeoSensor sensor,
const VXDGeoSensorPlacement placement 
)
overridevirtual

Return a SensitiveDetector implementation for a given sensor.

Parameters
sensorIDSensorID for the sensor
sensorInformation about the sensor to create the Sensitive Detector for
placementInformation on how to place the sensor

Implements GeoVXDCreator.

Definition at line 136 of file GeoSVDCreator.cc.

138 {
139 SensorInfo* sensorInfo = new SensorInfo(dynamic_cast<const SensorInfo&>(*sensor.getSensorInfo()));
140 sensorInfo->setID(sensorID);
141 SensitiveDetector* sensitive = new SensitiveDetector(sensorInfo);
142 return sensitive;
143 }
VXD::SensitiveDetector< SVDSimHit, SVDTrueHit > SensitiveDetector
The SVD Sensitive Detector class.

◆ createSensorInfo()

VXD::SensorInfoBase * createSensorInfo ( const VXDGeoSensorPar sensor)
overridevirtual

Read the sensor definitions from the database.

Parameters
sensorReference to the database containing the parameters

Implements GeoVXDCreator.

Definition at line 59 of file GeoSVDCreator.cc.

60 {
61 const SVDSensorInfoPar& infoPar = dynamic_cast<const SVDSensorInfoPar&>(*sensor.getSensorInfo());
62
63 SensorInfo* info = new SensorInfo(
64 VxdID(0, 0, 0),
65 infoPar.getWidth(),
66 infoPar.getLength(),
67 infoPar.getThickness(),
68 infoPar.getUCells(),
69 infoPar.getVCells(),
70 infoPar.getWidth2()
71 );
72 info->setSensorParams(
73 infoPar.getStripEdgeU(),
74 infoPar.getStripEdgeV(),
75 infoPar.getDepletionVoltage(),
76 infoPar.getBiasVoltage(),
77 infoPar.getBackplaneCapacitanceU(),
78 infoPar.getInterstripCapacitanceU(),
79 infoPar.getCouplingCapacitanceU(),
80 infoPar.getBackplaneCapacitanceV(),
81 infoPar.getInterstripCapacitanceV(),
82 infoPar.getCouplingCapacitanceV(),
83 infoPar.getAduEquivalentU(),
84 infoPar.getAduEquivalentV(),
85 infoPar.getElectronicNoiseU(),
86 infoPar.getElectronicNoiseV(),
87 infoPar.getAduEquivalentSbwU(),
88 infoPar.getAduEquivalentSbwV(),
89 infoPar.getElectronicNoiseSbwU(),
90 infoPar.getElectronicNoiseSbwV()
91 );
92 m_SensorInfo.push_back(info);
93 return info;
94 }

◆ createSubComponents()

GeoVXDAssembly createSubComponents ( const std::string &  name,
VXDGeoComponent component,
std::vector< VXDGeoPlacement placements,
bool  originCenter = true,
bool  allowOutside = false 
)
inherited

Place a list of subcomponents into an component.

If the volume of the given component is NULL, a new container will be created to fit all subcomponents. It will have air as medium. If at least one subcomponent with this placement is found the whole component is wrapped in a container volume with Air medium which extends above and below to fit the subcomponents

Parameters
nameName for the potential new volume or as prefix for the container to extend the component
componentComponent to fit the subcomponents into
placementsPlacement information for all subcomponents
originCenterbool
allowOutsidebool
Returns
offset in w which was applied to the component when extending it

Definition at line 74 of file GeoVXDCreator.cc.

76 {
77 GeoVXDAssembly assembly;
78 B2DEBUG(100, "Creating component " << name);
79 vector<VXDGeoComponent> subComponents;
80 subComponents.reserve(placements.size());
81 //Go over all subcomponents and check if they will fit inside.
82 //If component.volume is zero we will create one so sum up needed space
83 bool widthResize = component.getWidth() <= 0;
84 bool lengthResize = component.getLength() <= 0;
85 bool heightResize = component.getHeight() <= 0;
86
87 for (VXDGeoPlacement& p : placements) {
88 //Test component already exists
89 if (m_componentCache.find(p.getName()) == m_componentCache.end()) {
90 B2FATAL("A component is requested that was not created before!");
91 }
92 VXDGeoComponent sub = m_componentCache[p.getName()];
93
94 B2DEBUG(100, "SubComponent " << p.getName());
95 B2DEBUG(100, boost::format("Placement: u:%1% cm, v:%2% cm, w:%3% + %4% cm") % p.getU() % p.getV() % p.getW() % p.getWOffset());
96 B2DEBUG(100, boost::format("Dimensions: %1%x%2%x%3% cm") % sub.getWidth() % sub.getLength() % sub.getHeight());
97
98 if (p.getW() == VXDGeoPlacement::c_above || p.getW() == VXDGeoPlacement::c_below) {
99 //Below placement only valid if we are allowed to create a container around component
100 if (!allowOutside) B2FATAL("Cannot place component " << p.getName() << " outside of component " << name);
101 } else if (sub.getHeight() + p.getWOffset() > component.getHeight()) {
102 //Component will not fit heightwise. If we resize the volume anyway than we don't have problems
103 if (!heightResize) {
104 B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
105 << "height " << sub.getHeight() << " > " << component.getHeight());
106 }
107 component.getHeight() = sub.getHeight() + p.getWOffset();
108 }
109
110 //Check if compoent will fit inside width,length. If we can resize do it if needed, otherwise bail
111 double minWidth = max(abs(p.getU() + sub.getWidth() / 2.0), abs(p.getU() - sub.getWidth() / 2.0));
112 double minLength = max(abs(p.getV() + sub.getLength() / 2.0), abs(p.getV() - sub.getLength() / 2.0));
113 if (minWidth > component.getWidth() + component.getWidth() * numeric_limits<double>::epsilon()) {
114 if (!widthResize) {
115 B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
116 << "minWidth " << minWidth << " > " << component.getWidth());
117 }
118 component.setWidth(minWidth * 2.0);
119 }
120 if (minLength > component.getLength() + component.getLength() * numeric_limits<double>::epsilon()) {
121 if (!lengthResize) {
122 B2FATAL("Subcomponent " << p.getName() << " does not fit into volume: "
123 << "minLength " << minLength << " > " << component.getLength());
124 }
125 component.setLength(minLength * 2.0);
126 }
127 subComponents.push_back(sub);
128 }
129
130 //zero dimensions are fine mathematically but we don't want them in the simulation
131 if (component.getWidth() <= 0 || component.getLength() <= 0 || component.getHeight() <= 0) {
132 B2FATAL("At least one dimension of component " << name << " is zero which does not make sense");
133 }
134
135 //No volume yet, create a new one automatically assuming air material
136 if (!component.getVolume()) {
137 G4VSolid* componentShape = createTrapezoidal(name, component.getWidth(), component.getWidth2(), component.getLength(),
138 component.getHeight());
139 component.setVolume(new G4LogicalVolume(componentShape, Materials::get(component.getMaterial()), name));
140 }
141
142 B2DEBUG(100, boost::format("Component %1% dimensions: %2%x%3%x%4% cm") % name % component.getWidth() % component.getLength() %
143 component.getHeight());
144
145 //Ok, all volumes set up, now add them together
146 for (size_t i = 0; i < placements.size(); ++i) {
147 VXDGeoPlacement& p = placements[i];
148 VXDGeoComponent& s = subComponents[i];
149
150 G4Transform3D transform = getPosition(component, s, p, originCenter);
151 if (p.getW() == VXDGeoPlacement::c_below || p.getW() == VXDGeoPlacement::c_above) {
152 //Add to selected mother (either component or container around component
153 assembly.add(s.getVolume(), transform);
154 } else {
155 new G4PVPlacement(transform, s.getVolume(), name + "." + p.getName(), component.getVolume(), false, i);
156 }
157 }
158
159 //Set some visibility options for volume. Done here because all components including sensor go through here
160 if (component.getColor().empty()) {
161 B2DEBUG(200, "Component " << name << " is an Air volume, setting invisible");
162 setVisibility(*component.getVolume(), false);
163 } else {
164 B2DEBUG(200, "Component " << name << " color: " << component.getColor());
165 setColor(*component.getVolume(), component.getColor());
166 }
167 B2DEBUG(100, "--> Created component " << name);
168 //Return the difference in W between the origin of the original component and the including container
169 return assembly;
170 }
@ c_above
Place the component above the mother.
@ c_below
Place the component below the mother.
G4Transform3D getPosition(const VXDGeoComponent &mother, const VXDGeoComponent &daughter, const VXDGeoPlacement &placement, bool originCenter)
Return the position where a daughter component is to be placed.

◆ createTrapezoidal()

G4VSolid * createTrapezoidal ( const std::string &  name,
double  width,
double  width2,
double  length,
double &  height,
double  angle = 0 
)
inherited

Create a trapezoidal solid.

Parameters
namename of the Geant4 solid
widthfull forward width of the shape in mm
width2full backward width of the shape in mm
lengthlength of the shape in mm
[in,out]heightof the shape in mm. If angle is not 0 this value might be changed if the actual height will be smaller due to the slanted edges
angleangle of the sides along w with respect to to the uv plane. 0 means normal box shaped, !=0 means the upper endcap of the solid will be smaller since all edges will be slanted by angle
Returns
A G4VShape which could be a G4Box, a G4Trd or a G4Trap depending on the parameters

Definition at line 255 of file GeoVXDCreator.cc.

257 {
258 double offset(0);
259 if (angle > 0) {
260 const double tana = tan(angle);
261 height = min(tana * length, min(tana * width, height));
262 offset = height / tana;
263 }
264 const double hwidth = width / 2.0;
265 const double hwidth2 = width2 / 2.0;
266 const double hlength = length / 2.0;
267 const double hheight = height / 2.0;
268
269 if (width2 <= 0 || width == width2) {
270 if (angle <= 0) {
271 return new G4Box(name, hwidth, hlength, hheight);
272 } else {
273 return new G4Trd(name, hwidth, hwidth - offset, hlength, hlength - offset, hheight);
274 }
275 }
276 //FIXME: offset not working, g4 complains about nonplanarity of face -X. But we do not need that shape at the moment
277 //so lets ignore it for now
278 return new G4Trap(name, hheight, 0, 0, hlength, hwidth, hwidth2, 0, hlength - offset, hwidth - offset, hwidth2 - offset, 0);
279 }

◆ getAlignment()

G4Transform3D getAlignment ( const VXDAlignmentPar params)
inherited

Get Alignment from paylead object.

Parameters
paramsPayload object
Returns
Transformation matrix for component

Definition at line 172 of file GeoVXDCreator.cc.

173 {
174 G4RotationMatrix rotation(params.getAlpha(), params.getBeta(), params.getGamma());
175 G4ThreeVector translation(params.getDU() / Unit::mm, params.getDV() / Unit::mm, params.getDW() / Unit::mm);
176 return G4Transform3D(rotation, translation);
177 }

◆ getPosition()

G4Transform3D getPosition ( const VXDGeoComponent mother,
const VXDGeoComponent daughter,
const VXDGeoPlacement placement,
bool  originCenter 
)
inherited

Return the position where a daughter component is to be placed.

Parameters
motherMother component
daughterDaughter component
placementVXDGeoPlacement
originCenterbool
Returns
Transformation matrix to place the daughter relative to the origin to the mother

Definition at line 179 of file GeoVXDCreator.cc.

181 {
182 double u(placement.getU()), v(placement.getV()), w(0);
183 switch (placement.getW()) {
184 case VXDGeoPlacement::c_below: //Place below component
185 w = - mother.getHeight() / 2.0 - daughter.getHeight() / 2.0;
186 break;
187 case VXDGeoPlacement::c_bottom: //Place inside, at bottom of component
188 w = - mother.getHeight() / 2.0 + daughter.getHeight() / 2.0;
189 break;
190 case VXDGeoPlacement::c_center: //Place inside, centered
191 w = 0;
192 break;
193 case VXDGeoPlacement::c_top: //Place inside, at top of mother
194 w = mother.getHeight() / 2.0 - daughter.getHeight() / 2.0;
195 break;
196 case VXDGeoPlacement::c_above: //Place above mother
197 w = mother.getHeight() / 2.0 + daughter.getHeight() / 2.0;
198 break;
199 }
200 if (!originCenter) { //Sensor has coordinate origin in the corner, all submothers at their center
201 u -= mother.getWidth() / 2.0;
202 v -= mother.getLength() / 2.0;
203 }
204 return G4Translate3D(u, v, w + placement.getWOffset());
205 }
@ c_bottom
Place the component at the bottom of the mother.
@ c_center
Place the component at the center of the mother.
@ c_top
Place the component at the top of the mother.

◆ getSubComponents()

std::vector< VXDGeoPlacementPar > getSubComponents ( const GearDir path)
inherited

Return vector of VXDGeoPlacements with all the components defined inside a given path.

Definition at line 606 of file GeoVXDCreator.cc.

607 {
608 vector<VXDGeoPlacementPar> result;
609 for (const GearDir& component : path.getNodes("Component")) {
610 string type;
611 if (!component.exists("@type")) {
612 type = component.getString("@name");
613 } else {
614 type = component.getString("@type");
615 }
616 int nPos = max(component.getNumberNodes("u"), component.getNumberNodes("v"));
617 nPos = max(nPos, component.getNumberNodes("w"));
618 nPos = max(nPos, component.getNumberNodes("woffset"));
619 for (int iPos = 1; iPos <= nPos; ++iPos) {
620 string index = (boost::format("[%1%]") % iPos).str();
621 result.push_back(VXDGeoPlacementPar(
622 type,
623 component.getLength("u" + index, 0),
624 component.getLength("v" + index, 0),
625 component.getString("w" + index, "bottom"),
626 component.getLength("woffset" + index, 0)
627 ));
628 }
629 }
630 return result;
631 }

◆ placeLadder()

G4Transform3D placeLadder ( int  ladderID,
double  phi,
G4LogicalVolume *  volume,
const G4Transform3D &  placement,
const VXDGeometryPar parameters 
)
inherited

Place ladder corresponding to the given ladder id into volume setLayer has to be called first to set the correct layer id.

Definition at line 281 of file GeoVXDCreator.cc.

284 {
285 VxdID ladder(m_ladder.getLayerID(), ladderID, 0);
286
287 G4Translate3D ladderPos(m_ladder.getRadius(), m_ladder.getShift(), 0);
288 G4Transform3D ladderPlacement = placement * G4RotateZ3D(phi) * ladderPos * getAlignment(parameters.getAlignment(ladder));
289 // The actuall coordinate system of ladder (w still points to Z, there is only phi rotation + move to correct radius + shift)
291
292
293 vector<G4Point3D> lastSensorEdge;
294 for (const VXDGeoSensorPlacement& p : m_ladder.getSensors()) {
295 VxdID sensorID(ladder);
296 sensorID.setSensorNumber(p.getSensorID());
297
298
299 std::map<string, VXDGeoSensor>::iterator it = m_sensorMap.find(p.getSensorTypeID());
300 if (it == m_sensorMap.end()) {
301 B2FATAL("Invalid SensorTypeID " << p.getSensorTypeID() << ", please check the definition of " << sensorID);
302 }
303 VXDGeoSensor& s = it->second;
304 string name = m_prefix + "." + (string)sensorID;
305
306 //Calculate the reflection transformation needed. Since we want the
307 //active area to be non reflected we apply this transformation on the
308 //sensor and on the active area
309 G4Transform3D reflection;
310 if (p.getFlipU()) reflection = reflection * G4ReflectX3D();
311 if (p.getFlipV()) reflection = reflection * G4ReflectY3D();
312 if (p.getFlipW()) reflection = reflection * G4ReflectZ3D();
313
314 G4VSolid* sensorShape = createTrapezoidal(name, s.getWidth(), s.getWidth2(), s.getLength(),
315 s.getHeight());
316 G4Material* sensorMaterial = Materials::get(s.getMaterial());
318 s.setVolume(new G4LogicalVolume(sensorShape, Materials::get(m_defaultMaterial), name));
319 } else {
320 s.setVolume(new G4LogicalVolume(sensorShape, sensorMaterial, name));
321 }
322
323 // Create sensitive Area: this Part is created separately since we want full control over the coordinate system:
324 // local x (called u) should point in RPhi direction
325 // local y (called v) should point in global z
326 // local z (called w) should away from the origin
327 G4VSolid* activeShape = createTrapezoidal(name + ".Active", s.getActiveArea().getWidth(), s.getActiveArea().getWidth2(),
328 s.getActiveArea().getLength(), s.getActiveArea().getHeight());
329
330 //Create appropriate sensitive detector instance
331 SensitiveDetectorBase* sensitive = createSensitiveDetector(sensorID, s, p);
332
333 sensitive->setOptions(m_seeNeutrons, m_onlyPrimaryTrueHits,
335 m_sensitive.push_back(sensitive);
336 G4LogicalVolume* active = new G4LogicalVolume(activeShape, sensorMaterial, name + ".Active",
337 0, sensitive);
338 m_UserLimits.push_back(new G4UserLimits(m_activeStepSize));
339 active->SetUserLimits(m_UserLimits.back());
340
341 setColor(*active, s.getActiveArea().getColor());
342
343 //The coordinates of the active region are given as the distance between the corners, not to the center
344 //Place the active area
345 G4Transform3D activePosition = G4Translate3D(s.getActiveArea().getWidth() / 2.0, s.getActiveArea().getLength() / 2.0, 0) *
346 getPosition(s, s.getActiveArea(), s.getActivePlacement(), false);
347
348 G4ReflectionFactory::Instance()->Place(activePosition * reflection, name + ".Active", active, s.getVolume(),
349 false, (int)sensorID, false);
350
351 //Now create all the other components and place the Sensor
352 GeoVXDAssembly assembly;
353 if (!m_onlyActiveMaterial) assembly = createSubComponents(name, s, s.getComponents(), false, true);
354
355 G4RotationMatrix rotation(0, -M_PI / 2.0, -M_PI / 2.0);
356 G4Transform3D sensorAlign = getAlignment(parameters.getAlignment(sensorID));
357 G4Transform3D sensorPlacement = G4Rotate3D(rotation) * sensorAlign * reflection;
358
359 if (s.getSlanted()) {
360 sensorPlacement = G4TranslateX3D(m_ladder.getSlantedRadius() - m_ladder.getRadius()) * G4RotateY3D(
361 -m_ladder.getSlantedAngle()) * sensorPlacement;
362 }
363 sensorPlacement = G4Translate3D(0.0, 0.0, p.getZ()) * sensorPlacement;
364 // Remember the placement of sensor into ladder
365 VXD::GeoCache::getInstance().addSensorPlacement(ladder, sensorID, sensorPlacement * activePosition * reflection);
366 sensorPlacement = ladderPlacement * sensorPlacement;
367
368 assembly.add(s.getVolume());
369 assembly.place(volume, sensorPlacement);
370
371 //See if we want to glue the modules together
372 if (!m_ladder.getGlueMaterial().empty() && !m_onlyActiveMaterial) {
373 double u = s.getWidth() / 2.0 + m_ladder.getGlueSize();
374 double v = s.getLength() / 2.0;
375 double w = s.getHeight() / 2.0 + m_ladder.getGlueSize();
376 std::vector<G4Point3D> curSensorEdge(4);
377 //Lets get the forward corners of the sensor by applying the unreflected placement matrix
378 curSensorEdge[0] = sensorPlacement * reflection * G4Point3D(u, v, + w);
379 curSensorEdge[1] = sensorPlacement * reflection * G4Point3D(u, v, - w);
380 curSensorEdge[2] = sensorPlacement * reflection * G4Point3D(-u, v, - w);
381 curSensorEdge[3] = sensorPlacement * reflection * G4Point3D(-u, v, + w);
382 //If we already have backward edges this is not the first module so we can apply the glue
383 if (lastSensorEdge.size()) {
384 //Check that the modules don't overlap in z
385 bool glueOK = true;
386 for (int i = 0; i < 4; ++i) glueOK &= curSensorEdge[i].z() <= lastSensorEdge[i].z();
387 if (!glueOK) {
388 B2WARNING("Cannot place Glue at sensor " + (string)sensorID +
389 " since it overlaps with the last module in z");
390 } else {
391 //Create Glue which spans from last sensor to this sensor
392 G4TessellatedSolid* solidTarget = new G4TessellatedSolid(m_prefix + ".Glue." + (string)sensorID);
393
394 //Face at end of last Sensor
395 solidTarget->AddFacet(new G4QuadrangularFacet(
396 curSensorEdge[3], curSensorEdge[2], curSensorEdge[1], curSensorEdge[0], ABSOLUTE));
397 //Face at begin of current Sensor
398 solidTarget->AddFacet(new G4QuadrangularFacet(
399 lastSensorEdge[0], lastSensorEdge[1], lastSensorEdge[2], lastSensorEdge[3], ABSOLUTE));
400
401 //Top faces
402 solidTarget->AddFacet(new G4TriangularFacet(
403 curSensorEdge[3], curSensorEdge[0], lastSensorEdge[0], ABSOLUTE));
404 solidTarget->AddFacet(new G4TriangularFacet(
405 lastSensorEdge[0], lastSensorEdge[3], curSensorEdge[3], ABSOLUTE));
406 //Bottom faces
407 solidTarget->AddFacet(new G4TriangularFacet(
408 curSensorEdge[1], curSensorEdge[2], lastSensorEdge[2], ABSOLUTE));
409 solidTarget->AddFacet(new G4TriangularFacet(
410 lastSensorEdge[2], lastSensorEdge[1], curSensorEdge[1], ABSOLUTE));
411 //Right faces
412 solidTarget->AddFacet(new G4TriangularFacet(
413 curSensorEdge[0], curSensorEdge[1], lastSensorEdge[1], ABSOLUTE));
414 solidTarget->AddFacet(new G4TriangularFacet(
415 lastSensorEdge[1], lastSensorEdge[0], curSensorEdge[0], ABSOLUTE));
416 //Left faces
417 solidTarget->AddFacet(new G4TriangularFacet(
418 curSensorEdge[2], curSensorEdge[3], lastSensorEdge[3], ABSOLUTE));
419 solidTarget->AddFacet(new G4TriangularFacet(
420 lastSensorEdge[3], lastSensorEdge[2], curSensorEdge[2], ABSOLUTE));
421
422 solidTarget->SetSolidClosed(true);
423
424 G4LogicalVolume* glue = new G4LogicalVolume(solidTarget, Materials::get(m_ladder.getGlueMaterial()),
425 m_prefix + ".Glue." + (string)sensorID);
426 setColor(*glue, "#097");
427 new G4PVPlacement(G4Transform3D(), glue, m_prefix + ".Glue." + (string)sensorID, volume, false, 1);
428 }
429 }
430 //Remember the backward edge of this sensor to be glued to.
431 lastSensorEdge.resize(4);
432 lastSensorEdge[0] = sensorPlacement * reflection * G4Point3D(u, -v, + w);
433 lastSensorEdge[1] = sensorPlacement * reflection * G4Point3D(u, -v, - w);
434 lastSensorEdge[2] = sensorPlacement * reflection * G4Point3D(-u, -v, - w);
435 lastSensorEdge[3] = sensorPlacement * reflection * G4Point3D(-u, -v, + w);
436 }
437 }
438
439 return ladderPlacement;
440 }
const std::vector< VXDGeoSensorPlacement > & getSensors() const
get list of sensors
int getLayerID() const
get the layer id
const std::string & getGlueMaterial() const
get the glue material
double getSlantedAngle() const
get the slant angle for slanted sensors
double getRadius() const
get the radius of all sensors except slanted ones
double getShift() const
get the shift along the u coordinate for all sensors in the ladder
double getSlantedRadius() const
get the radius for slanted sensors
double getGlueSize() const
get the additional glue size, e.g.
void addSensorPlacement(VxdID ladder, VxdID sensor, const G4Transform3D &placement)
Remember how sensor is placed into ladder.
Definition: GeoCache.cc:220
void addLadderPlacement(VxdID halfShell, VxdID ladder, const G4Transform3D &placement)
Remember how ladder is placed into half-shell.
Definition: GeoCache.cc:225
VXDGeoLadder m_ladder
Parameters of the currently active ladder.
std::vector< G4UserLimits * > m_UserLimits
Vector of G4UserLimit pointers.
virtual SensitiveDetectorBase * createSensitiveDetector(VxdID sensorID, const VXDGeoSensor &sensor, const VXDGeoSensorPlacement &placement)=0
Return a SensitiveDetector implementation for a given sensor.

◆ readComponent()

void readComponent ( const std::string &  name,
GearDir  components,
VXDGeometryPar vxdGeometryPar 
)
inherited

Read parameters for component name from Gearbox into geometry payload.

The name is assumed to be unique and Volumes are cached.

Parameters
nameName of the component
componentsPath to components
vxdGeometryParVXD geometry parameters

Definition at line 533 of file GeoVXDCreator.cc.

534 {
535
536
537 //Check if component already exists
538 if (vxdGeometryPar.getComponentMap().find(name) != vxdGeometryPar.getComponentMap().end()) {
539 return; // nothing to do
540 }
541
542 //Component does not exist, so lets create a new one
543 string path = (boost::format("descendant::Component[@name='%1%']/") % name).str();
544 GearDir params(componentsDir, path);
545 if (!params) {
546 B2FATAL("Could not find definition for component " << name);
547 return;
548 }
549
550 VXDGeoComponentPar c(
551 params.getString("Material", vxdGeometryPar.getGlobalParams().getDefaultMaterial()),
552 params.getString("Color", ""),
553 params.getLength("width", 0),
554 params.getLength("width2", 0),
555 params.getLength("length", 0),
556 params.getLength("height", 0),
557 params.getAngle("angle", 0)
558 );
559
560 if (c.getWidth() <= 0 || c.getLength() <= 0 || c.getHeight() <= 0) {
561 B2DEBUG(100, "One dimension empty, using auto resize for component");
562 }
563
564 c.setSubComponents(getSubComponents(params));
565 readSubComponents(c.getSubComponents(), componentsDir, vxdGeometryPar);
566
567 if (vxdGeometryPar.getGlobalParams().getActiveChips() && params.exists("activeChipID")) {
568 int chipID = params.getInt("activeChipID");
569 vxdGeometryPar.getSensitiveChipIdMap()[name] = chipID;
570 }
571 vxdGeometryPar.getComponentMap()[name] = c;
572 vxdGeometryPar.getComponentInsertOder().push_back(name);
573 }
void readSubComponents(const std::vector< VXDGeoPlacementPar > &placements, const GearDir &componentsDir, VXDGeometryPar &vxdGeometryPar)
Read parameters for all components in placement container from Gearbox into payload.

◆ readHalfShellSupport()

void readHalfShellSupport ( const GearDir support,
SVDGeometryPar svdGeometryPar 
)

Create support structure for SVD Half Shell, that means everything that does not depend on layer or sensor alignment.

Parameters
supportReference to the database containing the parameters
svdGeometryPar

Definition at line 509 of file GeoSVDCreator.cc.

510 {
511 if (!support) return;
512
513 for (const GearDir& params : support.getNodes("HalfShell/RotationSolid")) {
514
515 VXDRotationSolidPar rotationSolidPar(params.getString("Name", ""),
516 params.getString("Material", "Air"),
517 params.getString("Color", ""),
518 params.getAngle("minPhi", 0),
519 params.getAngle("maxPhi", 2 * M_PI),
520 (params.getNodes("InnerPoints/point").size() > 0)
521 );
522
523 for (const GearDir& point : params.getNodes("InnerPoints/point")) {
524 pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
525 rotationSolidPar.getInnerPoints().push_back(ZXPoint);
526 }
527 for (const GearDir& point : params.getNodes("OuterPoints/point")) {
528 pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
529 rotationSolidPar.getOuterPoints().push_back(ZXPoint);
530 }
531 svdGeometryPar.getRotationSolids().push_back(rotationSolidPar);
532 }
533 return;
534 }

◆ readLadder()

void readLadder ( int  layer,
GearDir  components,
VXDGeometryPar geoparameters 
)
virtualinherited

Read parameters for a ladder in layer with given ID from gearbox and layer store them in payload.

Definition at line 575 of file GeoVXDCreator.cc.

576 {
577 string path = (boost::format("Ladder[@layer=%1%]/") % layer).str();
578 GearDir paramsLadder(components, path);
579 if (!paramsLadder) {
580 B2FATAL("Could not find Ladder definition for layer " << layer);
581 }
582
583 geoparameters.getLadderMap()[layer] = VXDGeoLadderPar(
584 layer,
585 paramsLadder.getLength("shift"),
586 paramsLadder.getLength("radius"),
587 paramsLadder.getAngle("slantedAngle", 0),
588 paramsLadder.getLength("slantedRadius", 0),
589 paramsLadder.getLength("Glue/oversize", 0),
590 paramsLadder.getString("Glue/Material", "")
591 );
592
593 for (const GearDir& sensorInfo : paramsLadder.getNodes("Sensor")) {
594
595 geoparameters.getLadderMap()[layer].addSensor(VXDGeoSensorPlacementPar(
596 sensorInfo.getInt("@id"),
597 sensorInfo.getString("@type"),
598 sensorInfo.getLength("."),
599 sensorInfo.getBool("@flipU", false),
600 sensorInfo.getBool("@flipV", false),
601 sensorInfo.getBool("@flipW", false)
602 ));
603 }
604 }

◆ readLadderComponents()

void readLadderComponents ( int  layerID,
int  ladderID,
GearDir  content,
VXDGeometryPar vxdGeometryPar 
)
virtualinherited

Read parameters for ladder components and their alignment corresponding to the given ladder id.

Definition at line 471 of file GeoVXDCreator.cc.

472 {
473 VxdID ladder(layerID, ladderID, 0);
474
475 // Read alignment for ladder
476 string path = (boost::format("Align[@component='%1%']/") % ladder).str();
477 GearDir params(GearDir(content, "Alignment/"), path);
478 if (!params) {
479 B2WARNING("Could not find alignment parameters for ladder " << ladder);
480 return;
481 }
482 vxdGeometryPar.getAlignmentMap()[ladder] = VXDAlignmentPar(params.getLength("du"),
483 params.getLength("dv"),
484 params.getLength("dw"),
485 params.getAngle("alpha"),
486 params.getAngle("beta"),
487 params.getAngle("gamma")
488 );
489
490
491
492 for (const VXDGeoSensorPlacementPar& p : vxdGeometryPar.getLadderMap()[layerID].getSensors()) {
493 VxdID sensorID(ladder);
494 sensorID.setSensorNumber(p.getSensorID());
495
496 std::map<string, VXDGeoSensorPar>::iterator it = vxdGeometryPar.getSensorMap().find(p.getSensorTypeID());
497 if (it == vxdGeometryPar.getSensorMap().end()) {
498 B2FATAL("Invalid SensorTypeID " << p.getSensorTypeID() << ", please check the definition of " << sensorID);
499 }
500
501 //Now create all the other components and place the Sensor
502 if (!vxdGeometryPar.getGlobalParams().getOnlyActiveMaterial()) {
503 VXDGeoSensorPar& s = it->second;
504 readSubComponents(s.getComponents(), GearDir(content, "Components/"), vxdGeometryPar);
505 }
506 // Read alignment for sensor
507 string pathSensor = (boost::format("Align[@component='%1%']/") % sensorID).str();
508 GearDir paramsSensor(GearDir(content, "Alignment/"), pathSensor);
509 if (!paramsSensor) {
510 B2WARNING("Could not find alignment parameters for sensorID " << sensorID);
511 return;
512 }
513 vxdGeometryPar.getAlignmentMap()[sensorID] = VXDAlignmentPar(paramsSensor.getLength("du"),
514 paramsSensor.getLength("dv"),
515 paramsSensor.getLength("dw"),
516 paramsSensor.getAngle("alpha"),
517 paramsSensor.getAngle("beta"),
518 paramsSensor.getAngle("gamma")
519 );
520 }
521 return;
522 }

◆ readLadderSupport()

void readLadderSupport ( int  layer,
const GearDir support,
SVDGeometryPar svdGeometryPar 
)

Create support structure for a SVD Ladder.

Parameters
layerLayer ID to create the support for
supportReference to the database containing the parameters
svdGeometryPar

Definition at line 581 of file GeoSVDCreator.cc.

582 {
583 if (!support) return;
584
585 // Check if there are any support ribs defined for this layer. If not return empty assembly
586 GearDir params(support, (boost::format("SupportRibs/Layer[@id='%1%']") % layer).str());
587 if (params) {
588 svdGeometryPar.getSupportRibs()[layer] = SVDSupportRibsPar(support.getLength("SupportRibs/spacing"),
589 support.getLength("SupportRibs/height"),
590 support.getLength("SupportRibs/inner/width"),
591 support.getLength("SupportRibs/outer/width"),
592 support.getLength("SupportRibs/inner/tabLength"),
593 support.getString("SupportRibs/outer/Material"),
594 support.getString("SupportRibs/inner/Material"),
595 support.getString("SupportRibs/outer/Color"),
596 support.getString("SupportRibs/inner/Color"),
597 support.getString("SupportRibs/endmount/Material")
598 );
599
600 // Get values for the layer if available
601 if (params.exists("spacing")) svdGeometryPar.getSupportRibs()[layer].setSpacing(params.getLength("spacing"));
602 if (params.exists("height")) svdGeometryPar.getSupportRibs()[layer].setHeight(params.getLength("height"));
603
604 for (const GearDir& box : params.getNodes("box")) {
605 SVDSupportBoxPar boxPar(box.getAngle("theta"),
606 box.getLength("z"),
607 box.getLength("r"),
608 box.getLength("length")
609 );
610 svdGeometryPar.getSupportRibs()[layer].getBoxes().push_back(boxPar);
611 }
612
613 for (const GearDir& tab : params.getNodes("tab")) {
614 SVDSupportTabPar tabPar(tab.getAngle("theta"),
615 tab.getLength("z"),
616 tab.getLength("r")
617 );
618 svdGeometryPar.getSupportRibs()[layer].getTabs().push_back(tabPar);
619 }
620
621 for (const GearDir& endmount : params.getNodes("Endmount")) {
622 SVDEndmountPar mountPar(endmount.getString("@name"),
623 endmount.getLength("height"),
624 endmount.getLength("width"),
625 endmount.getLength("length"),
626 endmount.getLength("z"),
627 endmount.getLength("r")
628 );
629 svdGeometryPar.getSupportRibs()[layer].getEndmounts().push_back(mountPar);
630 }
631 }
632 return;
633 }

◆ readLayerSupport()

void readLayerSupport ( int  layer,
const GearDir support,
SVDGeometryPar svdGeometryPar 
)

Create support structure for a SVD Layer.

Parameters
layerLayer ID to create the support for
supportReference to the database containing the parameters
svdGeometryPar

Definition at line 536 of file GeoSVDCreator.cc.

537 {
538 if (!support) return;
539
540 //Check if there are any endrings defined for this layer. If not we don't create any
541 GearDir endrings(support, (boost::format("Endrings/Layer[@id='%1%']") % layer).str());
542 if (endrings) {
543 svdGeometryPar.getEndrings()[layer] = SVDEndringsPar(support.getString("Endrings/Material"),
544 support.getLength("Endrings/length"),
545 support.getLength("Endrings/gapWidth"),
546 support.getLength("Endrings/baseThickness")
547 );
548
549 //Create the endrings
550 for (const GearDir& endring : endrings.getNodes("Endring")) {
551 SVDEndringsTypePar endringPar(endring.getString("@name"),
552 endring.getLength("z"),
553 endring.getLength("baseRadius"),
554 endring.getLength("innerRadius"),
555 endring.getLength("outerRadius"),
556 endring.getLength("horizontalBar"),
557 endring.getLength("verticalBar")
558 );
559 svdGeometryPar.getEndrings()[layer].getTypes().push_back(endringPar);
560 }
561 }
562
563 // Now let's add the cooling pipes to the Support
564 GearDir pipes(support, (boost::format("CoolingPipes/Layer[@id='%1%']") % layer).str());
565 if (pipes) {
566 svdGeometryPar.getCoolingPipes()[layer] = SVDCoolingPipesPar(support.getString("CoolingPipes/Material"),
567 support.getLength("CoolingPipes/outerDiameter"),
568 support.getLength("CoolingPipes/wallThickness"),
569 pipes.getInt("nPipes"),
570 pipes.getAngle("startPhi"),
571 pipes.getAngle("deltaPhi"),
572 pipes.getLength("radius"),
573 pipes.getLength("zstart"),
574 pipes.getLength("zend")
575 );
576 if (pipes.exists("deltaL")) svdGeometryPar.getCoolingPipes()[layer].setDeltaL(pipes.getLength("deltaL"));
577 }
578 return;
579 }

◆ readSensorInfo()

SVDSensorInfoPar * readSensorInfo ( const GearDir sensor)

Read the sensor definitions from gearbox.

Parameters
sensorReference to the database containing the parameters

Definition at line 96 of file GeoSVDCreator.cc.

97 {
98
99 const double unit_pFcm = 1;
100 // This was 1000 * Unit::fC / Unit::V / Unit::cm; // pF/cm.
101 // We only use ratios of capacities, and this gives nicer numbers.
102 SVDSensorInfoPar* info = new SVDSensorInfoPar(
103 VxdID(0, 0, 0),
104 sensor.getLength("width"),
105 sensor.getLength("length"),
106 sensor.getLength("height"),
107 sensor.getInt("stripsU"),
108 sensor.getInt("stripsV"),
109 sensor.getLength("width2", 0)
110 );
111
112 info->setSensorParams(
113 sensor.getWithUnit("stripEdgeU"),
114 sensor.getWithUnit("stripEdgeV"),
115 sensor.getWithUnit("DepletionVoltage"),
116 sensor.getWithUnit("BiasVoltage"),
117 sensor.getDouble("BackplaneCapacitanceU") * unit_pFcm,
118 sensor.getDouble("InterstripCapacitanceU") * unit_pFcm,
119 sensor.getDouble("CouplingCapacitanceU") * unit_pFcm,
120 sensor.getDouble("BackplaneCapacitanceV") * unit_pFcm,
121 sensor.getDouble("InterstripCapacitanceV") * unit_pFcm,
122 sensor.getDouble("CouplingCapacitanceV") * unit_pFcm,
123 sensor.getWithUnit("ADUEquivalentU"),
124 sensor.getWithUnit("ADUEquivalentV"),
125 sensor.getWithUnit("ElectronicNoiseU"),
126 sensor.getWithUnit("ElectronicNoiseV"),
127 sensor.getWithUnit("ADUEquivalentSbwU", 0),
128 sensor.getWithUnit("ADUEquivalentSbwV", 0),
129 sensor.getWithUnit("ElectronicNoiseSbwU", 0),
130 sensor.getWithUnit("ElectronicNoiseSbwV", 0)
131 );
132
133 return info;
134 }

◆ readSubComponents()

void readSubComponents ( const std::vector< VXDGeoPlacementPar > &  placements,
const GearDir componentsDir,
VXDGeometryPar vxdGeometryPar 
)
inherited

Read parameters for all components in placement container from Gearbox into payload.

Parameters
placementscontainer holding names of all components to be cached
componentsDirPath to Gearbox where parameters are to be found
vxdGeometryPar

Definition at line 524 of file GeoVXDCreator.cc.

526 {
527 for (const VXDGeoPlacementPar& p : placements) {
528 readComponent(p.getName(), componentsDir, vxdGeometryPar);
529 }
530 return;
531 }
void readComponent(const std::string &name, GearDir components, VXDGeometryPar &vxdGeometryPar)
Read parameters for component name from Gearbox into geometry payload.

◆ setCurrentLayer()

void setCurrentLayer ( int  layer,
const VXDGeometryPar parameters 
)
virtualinherited

Read parameters for given layer and store in m_ladder.

Definition at line 442 of file GeoVXDCreator.cc.

443 {
444 const VXDGeoLadderPar& paramsLadder = parameters.getLadder(layer);
445
446 m_ladder = VXDGeoLadder(
447 layer,
448 paramsLadder.getShift() / Unit::mm,
449 paramsLadder.getRadius() / Unit::mm,
450 paramsLadder.getSlantedAngle(),
451 paramsLadder.getSlantedRadius() / Unit::mm,
452 paramsLadder.getGlueSize() / Unit::mm,
453 paramsLadder.getGlueMaterial()
454 );
455
456
457 for (const VXDGeoSensorPlacementPar& sensorInfo : paramsLadder.getSensors()) {
458 m_ladder.addSensor(VXDGeoSensorPlacement(
459 sensorInfo.getSensorID(),
460 sensorInfo.getSensorTypeID(),
461 sensorInfo.getZ() / Unit::mm,
462 sensorInfo.getFlipU(),
463 sensorInfo.getFlipV(),
464 sensorInfo.getFlipW()
465 ));
466 }
467 }
void addSensor(const VXDGeoSensorPlacement &sensor)
add a sensor to the list of sensors in the ladder

Member Data Documentation

◆ m_activeChips

bool m_activeChips {false}
protectedinherited

Make also chips sensitive.

Definition at line 209 of file GeoVXDCreator.h.

◆ m_activeStepSize

double m_activeStepSize {5 * Unit::um}
protectedinherited

Stepsize to be used inside active volumes.

Definition at line 207 of file GeoVXDCreator.h.

◆ m_alignment

GearDir m_alignment
protectedinherited

GearDir pointing to the alignment parameters.

Definition at line 183 of file GeoVXDCreator.h.

◆ m_componentCache

std::map<std::string, VXDGeoComponent> m_componentCache
protectedinherited

Cache of all previously created components.

Definition at line 188 of file GeoVXDCreator.h.

◆ m_components

GearDir m_components
protectedinherited

GearDir pointing to the toplevel of the components.

Definition at line 185 of file GeoVXDCreator.h.

◆ m_currentHalfShell

std::string m_currentHalfShell {""}
protectedinherited

Current half-shell being processed (need to know ladder parent for hierarchy)

Definition at line 220 of file GeoVXDCreator.h.

◆ m_defaultMaterial

std::string m_defaultMaterial
protectedinherited

Name of the Material to be used for Air.

Definition at line 199 of file GeoVXDCreator.h.

◆ m_distanceTolerance

float m_distanceTolerance {(float)(5 * Unit::um)}
protectedinherited

tolerance for Geant4 steps to be merged to a single step

Definition at line 201 of file GeoVXDCreator.h.

◆ m_electronTolerance

float m_electronTolerance {100}
protectedinherited

tolerance for the energy deposition in electrons to be merged in a single step

Definition at line 203 of file GeoVXDCreator.h.

◆ m_halfShellVxdIDs

std::map<std::string, Belle2::VxdID> m_halfShellVxdIDs
protectedinherited
Initial value:
{
{{"PXD.Ying"}, {Belle2::VxdID(1, 0, 0, 1)}},
{{"PXD.Yang"}, {Belle2::VxdID(1, 0, 0, 2)}},
{{"SVD.Pat"}, {Belle2::VxdID(3, 0, 0, 1)}},
{{"SVD.Mat"}, {Belle2::VxdID(3, 0, 0, 2)}}
}
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33

Used for translation of half-shell name into a VxdID to consitently handle it in hierarchy.

Definition at line 222 of file GeoVXDCreator.h.

◆ m_ladder

VXDGeoLadder m_ladder
protectedinherited

Parameters of the currently active ladder.

Definition at line 192 of file GeoVXDCreator.h.

◆ m_minimumElectrons

float m_minimumElectrons {10}
protectedinherited

minimum number of electrons to be deposited by a particle to be saved

Definition at line 205 of file GeoVXDCreator.h.

◆ m_onlyActiveMaterial

bool m_onlyActiveMaterial {false}
protectedinherited

If this is true, only active Materials will be placed for tracking studies.

Dead Material will be ignored

Definition at line 216 of file GeoVXDCreator.h.

◆ m_onlyPrimaryTrueHits

bool m_onlyPrimaryTrueHits {false}
protectedinherited

If true only create TrueHits from primary particles and ignore secondaries.

Definition at line 213 of file GeoVXDCreator.h.

◆ m_prefix

std::string m_prefix
protectedinherited

Prefix to prepend to all volume names.

Definition at line 181 of file GeoVXDCreator.h.

◆ m_radiationsensors

GeoVXDRadiationSensors m_radiationsensors
protectedinherited

Diamond radiation sensor "sub creator".

Definition at line 196 of file GeoVXDCreator.h.

◆ m_seeNeutrons

bool m_seeNeutrons {false}
protectedinherited

Make sensitive detectors also see neutrons.

Definition at line 211 of file GeoVXDCreator.h.

◆ m_sensitive

std::vector<Simulation::SensitiveDetectorBase*> m_sensitive
protectedinherited

List to all created sensitive detector instances.

Definition at line 194 of file GeoVXDCreator.h.

◆ m_SensorInfo

std::vector<SensorInfo*> m_SensorInfo
private

Vector of pointers to SensorInfo objects.

Definition at line 139 of file GeoSVDCreator.h.

◆ m_sensorMap

std::map<std::string, VXDGeoSensor> m_sensorMap
protectedinherited

Map containing Information about all defined sensor types.

Definition at line 190 of file GeoVXDCreator.h.

◆ m_UserLimits

std::vector<G4UserLimits*> m_UserLimits
protectedinherited

Vector of G4UserLimit pointers.

Definition at line 218 of file GeoVXDCreator.h.


The documentation for this class was generated from the following files: