Belle II Software  release-05-01-25
GeoPXDCreator.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Andreas Moll, Zbynek Drasal, Christian Oswald, *
7  * Martin Ritter, Benjamin Schwenker *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <pxd/geometry/GeoPXDCreator.h>
13 #include <vxd/geometry/GeoCache.h>
14 #include <pxd/geometry/SensorInfo.h>
15 #include <pxd/simulation/SensitiveDetector.h>
16 
17 #include <simulation/background/BkgSensitiveDetector.h>
18 
19 #include <geometry/Materials.h>
20 #include <geometry/CreatorFactory.h>
21 #include <geometry/utilities.h>
22 #include <framework/gearbox/GearDir.h>
23 #include <framework/gearbox/Unit.h>
24 #include <framework/logging/Logger.h>
25 
26 #include <cmath>
27 #include <boost/format.hpp>
28 
29 #include <G4LogicalVolume.hh>
30 #include <G4PVPlacement.hh>
31 
32 //Shapes
33 #include <G4Box.hh>
34 #include <G4Tubs.hh>
35 #include <G4Polycone.hh>
36 #include <G4SubtractionSolid.hh>
37 #include <G4Region.hh>
38 
39 using namespace std;
40 using namespace boost;
41 
42 namespace Belle2 {
47  using namespace geometry;
49  namespace PXD {
50 
52  geometry::CreatorFactory<GeoPXDCreator> GeoPXDFactory("PXDCreator");
53 
54  GeoPXDCreator::~GeoPXDCreator()
55  {
56  for (SensorInfo* sensorInfo : m_SensorInfo) delete sensorInfo;
57  m_SensorInfo.clear();
58  }
59 
60  VXD::SensorInfoBase* GeoPXDCreator::createSensorInfo(const VXDGeoSensorPar& sensor)
61  {
62 
63  const PXDSensorInfoPar& infoPar = dynamic_cast<const PXDSensorInfoPar&>(*sensor.getSensorInfo());
64 
65  SensorInfo* info = new SensorInfo(
66  VxdID(0, 0, 0),
67  infoPar.getWidth(),
68  infoPar.getLength(),
69  infoPar.getThickness(),
70  infoPar.getUCells(),
71  infoPar.getVCells1(),
72  infoPar.getSplitLength(),
73  infoPar.getVCells2()
74  );
75  info->setDEPFETParams(
76  infoPar.getBulkDoping() / (Unit::um * Unit::um * Unit::um),
77  infoPar.getBackVoltage(),
78  infoPar.getTopVoltage(),
79  infoPar.getSourceBorderSmallPitch(),
80  infoPar.getClearBorderSmallPitch(),
81  infoPar.getDrainBorderSmallPitch(),
82  infoPar.getSourceBorderLargePitch(),
83  infoPar.getClearBorderLargePitch(),
84  infoPar.getDrainBorderLargePitch(),
85  infoPar.getGateDepth(),
86  infoPar.getDoublePixel(),
87  infoPar.getChargeThreshold(),
88  infoPar.getNoiseFraction()
89  );
90  info->setIntegrationWindow(
91  infoPar.getIntegrationStart(),
92  infoPar.getIntegrationEnd()
93  );
94 
95  m_SensorInfo.push_back(info);
96  return info;
97  }
98 
99  PXDSensorInfoPar* GeoPXDCreator::readSensorInfo(const GearDir& sensor)
100  {
102  VxdID(0, 0, 0),
103  sensor.getLength("width"),
104  sensor.getLength("length"),
105  sensor.getLength("height"),
106  sensor.getInt("pixelsU"),
107  sensor.getInt("pixelsV[1]"),
108  sensor.getLength("splitLength", 0),
109  sensor.getInt("pixelsV[2]", 0)
110  );
111 
112  info->setDEPFETParams(
113  sensor.getDouble("BulkDoping"),
114  sensor.getWithUnit("BackVoltage"),
115  sensor.getWithUnit("TopVoltage"),
116  sensor.getLength("SourceBorderSmallPixel"),
117  sensor.getLength("ClearBorderSmallPixel"),
118  sensor.getLength("DrainBorderSmallPixel"),
119  sensor.getLength("SourceBorderLargePixel"),
120  sensor.getLength("ClearBorderLargePixel"),
121  sensor.getLength("DrainBorderLargePixel"),
122  sensor.getLength("GateDepth"),
123  sensor.getBool("DoublePixel"),
124  sensor.getDouble("ChargeThreshold"),
125  sensor.getDouble("NoiseFraction")
126  );
127  info->setIntegrationWindow(
128  sensor.getTime("IntegrationStart"),
129  sensor.getTime("IntegrationEnd")
130  );
131  return info;
132  }
133 
134 
135  PXDGeometryPar GeoPXDCreator::createConfiguration(const GearDir& content)
136  {
137  // Create an empty payload
138  PXDGeometryPar pxdGeometryPar;
139 
140  //Read prefix ('SVD' or 'PXD')
141  pxdGeometryPar.setPrefix(m_prefix);
142 
143  //Read some global parameters
144  VXDGlobalPar globals((float)content.getDouble("ElectronTolerance", 100),
145  (float)content.getDouble("MinimumElectrons", 10),
146  content.getLength("ActiveStepSize", 0.005),
147  content.getBool("ActiveChips", false),
148  content.getBool("SeeNeutrons", false),
149  content.getBool("OnlyPrimaryTrueHits", false),
150  content.getBool("OnlyActiveMaterial", false),
151  (float)content.getLength("DistanceTolerance", 0.005),
152  content.getString("DefaultMaterial", "Air")
153  );
154  pxdGeometryPar.setGlobalParams(globals);
155 
156  //Read envelope parameters
157  GearDir envelopeParams(content, "Envelope/");
158  VXDEnvelopePar envelope(envelopeParams.getString("Name", ""),
159  envelopeParams.getString("Material", "Air"),
160  envelopeParams.getString("Color", ""),
161  envelopeParams.getAngle("minPhi", 0),
162  envelopeParams.getAngle("maxPhi", 2 * M_PI),
163  (envelopeParams.getNodes("InnerPoints/point").size() > 0)
164  );
165 
166  for (const GearDir point : envelopeParams.getNodes("InnerPoints/point")) {
167  pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
168  envelope.getInnerPoints().push_back(ZXPoint);
169  }
170  for (const GearDir point : envelopeParams.getNodes("OuterPoints/point")) {
171  pair<double, double> ZXPoint(point.getLength("z"), point.getLength("x"));
172  envelope.getOuterPoints().push_back(ZXPoint);
173  }
174  pxdGeometryPar.setEnvelope(envelope);
175 
176  // Read alignment for detector m_prefix ('PXD' or 'SVD')
177  string pathAlign = (boost::format("Align[@component='%1%']/") % m_prefix).str();
178  GearDir paramsAlign(GearDir(content, "Alignment/"), pathAlign);
179  if (!paramsAlign) {
180  B2WARNING("Could not find alignment parameters for component " << m_prefix);
181  return pxdGeometryPar;
182  }
183  pxdGeometryPar.getAlignmentMap()[m_prefix] = VXDAlignmentPar(paramsAlign.getLength("du"),
184  paramsAlign.getLength("dv"),
185  paramsAlign.getLength("dw"),
186  paramsAlign.getAngle("alpha"),
187  paramsAlign.getAngle("beta"),
188  paramsAlign.getAngle("gamma")
189  );
190 
191  //Read the definition of all sensor types
192  GearDir components(content, "Components/");
193  for (const GearDir& paramsSensor : components.getNodes("Sensor")) {
194  string sensorTypeID = paramsSensor.getString("@type");
195 
196  VXDGeoSensorPar sensor(paramsSensor.getString("Material"),
197  paramsSensor.getString("Color", ""),
198  paramsSensor.getLength("width"),
199  paramsSensor.getLength("width2", 0),
200  paramsSensor.getLength("length"),
201  paramsSensor.getLength("height"),
202  paramsSensor.getAngle("angle", 0),
203  paramsSensor.getBool("@slanted", false)
204  );
205  sensor.setActive(VXDGeoComponentPar(
206  paramsSensor.getString("Material"),
207  paramsSensor.getString("Active/Color", "#f00"),
208  paramsSensor.getLength("Active/width"),
209  paramsSensor.getLength("Active/width2", 0),
210  paramsSensor.getLength("Active/length"),
211  paramsSensor.getLength("Active/height")
213  "Active",
214  paramsSensor.getLength("Active/u"),
215  paramsSensor.getLength("Active/v"),
216  paramsSensor.getString("Active/w", "center"),
217  paramsSensor.getLength("Active/woffset", 0)
218  ));
219 
220  PXDSensorInfoPar* pxdInfo = readSensorInfo(GearDir(paramsSensor, "Active"));
221  sensor.setSensorInfo(pxdInfo);
222  sensor.setComponents(getSubComponents(paramsSensor));
223  pxdGeometryPar.getSensorMap()[sensorTypeID] = sensor;
224  pxdGeometryPar.getSensorInfos().push_back(pxdInfo);
225  }
226 
227  //Build all ladders including Sensors
228  GearDir support(content, "Support/");
229  readHalfShellSupport(support, pxdGeometryPar);
230 
231  for (const GearDir& shell : content.getNodes("HalfShell")) {
232 
233  string shellName = m_prefix + "." + shell.getString("@name");
234  string pathShell = (boost::format("Align[@component='%1%']/") % shellName).str();
235  GearDir paramsShell(GearDir(content, "Alignment/"), pathShell);
236  if (!paramsShell) {
237  B2WARNING("Could not find alignment parameters for component " << shellName);
238  return pxdGeometryPar;
239  }
240  pxdGeometryPar.getAlignmentMap()[shellName] = VXDAlignmentPar(paramsShell.getLength("du"),
241  paramsShell.getLength("dv"),
242  paramsShell.getLength("dw"),
243  paramsShell.getAngle("alpha"),
244  paramsShell.getAngle("beta"),
245  paramsShell.getAngle("gamma")
246  );
247 
248  VXDHalfShellPar halfShell(shell.getString("@name") , shell.getAngle("shellAngle", 0));
249 
250  for (const GearDir& layer : shell.getNodes("Layer")) {
251  int layerID = layer.getInt("@id");
252 
253  readLadder(layerID, components, pxdGeometryPar);
254 
255  //Loop over defined ladders
256  for (const GearDir& ladder : layer.getNodes("Ladder")) {
257  int ladderID = ladder.getInt("@id");
258  double phi = ladder.getAngle("phi", 0);
259  readLadderComponents(layerID, ladderID, content, pxdGeometryPar);
260  halfShell.addLadder(layerID, ladderID, phi);
261  }
262  }
263  pxdGeometryPar.getHalfShells().push_back(halfShell);
264  }
265 
266  //Create diamond radiation sensors if defined and in background mode
267  GearDir radiationDir(content, "RadiationSensors");
268  if (pxdGeometryPar.getGlobalParams().getActiveChips() && radiationDir) {
269  VXDGeoRadiationSensorsPar radiationSensors(
270  m_prefix,
271  radiationDir.getBool("insideEnvelope"),
272  radiationDir.getLength("width"),
273  radiationDir.getLength("length"),
274  radiationDir.getLength("height"),
275  radiationDir.getString("material")
276  );
277 
278  //Add radiation sensor positions
279  for (GearDir& position : radiationDir.getNodes("position")) {
280  VXDGeoRadiationSensorsPositionPar diamonds(position.getLength("z"),
281  position.getLength("radius"),
282  position.getAngle("theta")
283  );
284 
285  //Loop over all phi positions
286  for (GearDir& sensor : position.getNodes("phi")) {
287  //Add sensor with angle and id
288  diamonds.addSensor(sensor.getInt("@id"), sensor.getAngle());
289  }
290  radiationSensors.addPosition(diamonds);
291  }
292  pxdGeometryPar.setRadiationSensors(radiationSensors);
293  }
294 
295  return pxdGeometryPar;
296  }
297 
298  void GeoPXDCreator::readHalfShellSupport(const GearDir& support, PXDGeometryPar& pxdGeometryPar)
299  {
300  for (const GearDir& endflange : support.getNodes("Endflange")) {
301  VXDPolyConePar endflangePar(
302  endflange.getString("@name"),
303  endflange.getString("Material", "Air"),
304  endflange.getAngle("minPhi", 0),
305  endflange.getAngle("maxPhi", 2 * M_PI),
306  (endflange.getNodes("Cutout").size() > 0),
307  endflange.getLength("Cutout/width", 0.),
308  endflange.getLength("Cutout/height", 0.),
309  endflange.getLength("Cutout/depth", 0.)
310  );
311 
312  for (const GearDir& plane : endflange.getNodes("Plane")) {
313  VXDPolyConePlanePar planePar(
314  plane.getLength("posZ"),
315  plane.getLength("innerRadius"),
316  plane.getLength("outerRadius")
317  );
318  endflangePar.getPlanes().push_back(planePar);
319  }
320  pxdGeometryPar.getEndflanges().push_back(endflangePar);
321  }
322 
323  // Cout outs for endflanges
324  pxdGeometryPar.setNCutOuts(support.getInt("Cutout/count"));
325  pxdGeometryPar.setCutOutWidth(support.getLength("Cutout/width"));
326  pxdGeometryPar.setCutOutHeight(support.getLength("Cutout/height"));
327  pxdGeometryPar.setCutOutShift(support.getLength("Cutout/shift"));
328  pxdGeometryPar.setCutOutRPhi(support.getLength("Cutout/rphi"));
329  pxdGeometryPar.setCutOutStartPhi(support.getAngle("Cutout/startPhi"));
330  pxdGeometryPar.setCutOutDeltaPhi(support.getAngle("Cutout/deltaPhi"));
331 
332  //Create Carbon cooling tubes
333  pxdGeometryPar.setNTubes(support.getInt("CarbonTubes/count"));
334  pxdGeometryPar.setTubesMinZ(support.getLength("CarbonTubes/minZ"));
335  pxdGeometryPar.setTubesMaxZ(support.getLength("CarbonTubes/maxZ"));
336  pxdGeometryPar.setTubesMinR(support.getLength("CarbonTubes/innerRadius"));
337  pxdGeometryPar.setTubesMaxR(support.getLength("CarbonTubes/outerRadius"));
338  pxdGeometryPar.setTubesRPhi(support.getLength("CarbonTubes/rphi"));
339  pxdGeometryPar.setTubesStartPhi(support.getAngle("CarbonTubes/startPhi"));
340  pxdGeometryPar.setTubesDeltaPhi(support.getAngle("CarbonTubes/deltaPhi"));
341  pxdGeometryPar.setTubesMaterial(support.getString("CarbonTubes/Material", "Carbon"));
342 
343  return;
344  }
345 
346  void GeoPXDCreator::createGeometry(const PXDGeometryPar& parameters, G4LogicalVolume& topVolume, geometry::GeometryTypes)
347  {
348 
349  m_activeStepSize = parameters.getGlobalParams().getActiveStepSize() / Unit::mm;
350  m_activeChips = parameters.getGlobalParams().getActiveChips();
351  m_seeNeutrons = parameters.getGlobalParams().getSeeNeutrons();
352  m_onlyPrimaryTrueHits = parameters.getGlobalParams().getOnlyPrimaryTrueHits();
353  m_distanceTolerance = parameters.getGlobalParams().getDistanceTolerance();
354  m_electronTolerance = parameters.getGlobalParams().getElectronTolerance();
355  m_minimumElectrons = parameters.getGlobalParams().getMinimumElectrons();
356  m_onlyActiveMaterial = parameters.getGlobalParams().getOnlyActiveMaterial();
357  m_defaultMaterial = parameters.getGlobalParams().getDefaultMaterial();
358 
359  G4Material* material = Materials::get(m_defaultMaterial);
360  if (!material) B2FATAL("Default Material of VXD, '" << m_defaultMaterial << "', could not be found");
361 
362 
363  //Build envelope
364  G4LogicalVolume* envelope(0);
365  G4VPhysicalVolume* physEnvelope{nullptr};
366  if (!parameters.getEnvelope().getExists()) {
367  B2INFO("Could not find definition for " + m_prefix + " Envelope, placing directly in top volume");
368  envelope = &topVolume;
369  } else {
370  double minZ(0), maxZ(0);
371  G4Polycone* envelopeCone = geometry::createRotationSolid("Envelope",
372  parameters.getEnvelope().getInnerPoints(),
373  parameters.getEnvelope().getOuterPoints(),
374  parameters.getEnvelope().getMinPhi(),
375  parameters.getEnvelope().getMaxPhi(),
376  minZ, maxZ
377  );
378  envelope = new G4LogicalVolume(envelopeCone, material, m_prefix + ".Envelope");
379  setVisibility(*envelope, false);
380  physEnvelope = new G4PVPlacement(getAlignment(parameters.getAlignment(m_prefix)), envelope, m_prefix + ".Envelope",
381  &topVolume, false, 1);
382 
383  // Set up region for production cuts
384  G4Region* aRegion = new G4Region("PXDEnvelope");
385  envelope->SetRegion(aRegion);
386  aRegion->AddRootLogicalVolume(envelope);
387  }
388 
389  //Read the definition of all sensor types
390  for (const pair<const string, VXDGeoSensorPar>& typeAndSensor : parameters.getSensorMap()) {
391  const string& sensorTypeID = typeAndSensor.first;
392  const VXDGeoSensorPar& paramsSensor = typeAndSensor.second;
393  VXDGeoSensor sensor(
394  paramsSensor.getMaterial(),
395  paramsSensor.getColor(),
396  paramsSensor.getWidth() / Unit::mm,
397  paramsSensor.getWidth2() / Unit::mm,
398  paramsSensor.getLength() / Unit::mm,
399  paramsSensor.getHeight() / Unit::mm,
400  paramsSensor.getSlanted()
401  );
402  sensor.setActive(VXDGeoComponent(
403  paramsSensor.getMaterial(),
404  paramsSensor.getActiveArea().getColor(),
405  paramsSensor.getActiveArea().getWidth() / Unit::mm,
406  paramsSensor.getActiveArea().getWidth2() / Unit::mm,
407  paramsSensor.getActiveArea().getLength() / Unit::mm,
408  paramsSensor.getActiveArea().getHeight() / Unit::mm
409  ), VXDGeoPlacement(
410  "Active",
411  paramsSensor.getActivePlacement().getU() / Unit::mm,
412  paramsSensor.getActivePlacement().getV() / Unit::mm,
413  paramsSensor.getActivePlacement().getW(),
414  paramsSensor.getActivePlacement().getWOffset() / Unit::mm
415  ));
416  sensor.setSensorInfo(createSensorInfo(paramsSensor));
417 
418  vector<VXDGeoPlacement> subcomponents;
419  const auto& components = paramsSensor.getComponents();
420  subcomponents.reserve(components.size());
421  std::transform(components.begin(), components.end(), std::back_inserter(subcomponents),
422  [](auto const & component) {
423  return VXDGeoPlacement(component.getName(),
424  component.getU() / Unit::mm,
425  component.getV() / Unit::mm,
426  component.getW(),
427  component.getWOffset() / Unit::mm
428  );
429  });
430  sensor.setComponents(subcomponents);
431  m_sensorMap[sensorTypeID] = sensor;
432  }
433 
434  //Read the component cache from DB
435  for (const string& name : parameters.getComponentInsertOder()) {
436  if (m_componentCache.find(name) != m_componentCache.end()) {
437  // already created due to being a sub component of a previous
438  // component. Seems fishy since the information of this component
439  // is in the db at least twice so we could run into
440  // inconsistencies.
441  B2WARNING("Component " << name << " already created from previous subcomponents, should not be here");
442  continue;
443  }
444  const VXDGeoComponentPar& paramsComponent = parameters.getComponent(name);
445  VXDGeoComponent c(
446  paramsComponent.getMaterial(),
447  paramsComponent.getColor(),
448  paramsComponent.getWidth() / Unit::mm,
449  paramsComponent.getWidth2() / Unit::mm,
450  paramsComponent.getLength() / Unit::mm,
451  paramsComponent.getHeight() / Unit::mm
452  );
453  double angle = paramsComponent.getAngle();
454 
455 
456  if (c.getWidth() <= 0 || c.getLength() <= 0 || c.getHeight() <= 0) {
457  B2DEBUG(100, "One dimension empty, using auto resize for component");
458  } else {
459  G4VSolid* solid = createTrapezoidal(m_prefix + "." + name, c.getWidth(), c.getWidth2(), c.getLength(), c.getHeight(), angle);
460  c.setVolume(new G4LogicalVolume(solid, Materials::get(c.getMaterial()), m_prefix + "." + name));
461  }
462 
463  vector<VXDGeoPlacement> subComponents;
464  const auto& paramsSubComponents = paramsComponent.getSubComponents();
465  subComponents.reserve(paramsSubComponents.size());
466  std::transform(paramsSubComponents.begin(), paramsSubComponents.end(), std::back_inserter(subComponents),
467  [](auto const & paramsSubComponent) {
468  return VXDGeoPlacement(paramsSubComponent.getName(),
469  paramsSubComponent.getU() / Unit::mm,
470  paramsSubComponent.getV() / Unit::mm,
471  paramsSubComponent.getW(),
472  paramsSubComponent.getWOffset() / Unit::mm
473  );
474  });
475  createSubComponents(m_prefix + "." + name, c, subComponents);
476  if (m_activeChips && parameters.getSensitiveChipID(name) >= 0) {
477  int chipID = parameters.getSensitiveChipID(name);
478  B2DEBUG(50, "Creating BkgSensitiveDetector for component " << name << " with chipID " << chipID);
479  BkgSensitiveDetector* sensitive = new BkgSensitiveDetector(m_prefix.c_str(), chipID);
480  c.getVolume()->SetSensitiveDetector(sensitive);
481  m_sensitive.push_back(sensitive);
482  }
483 
484  m_componentCache[name] = c;
485  }
486 
487  //Build all ladders including Sensors
488  VXD::GeoVXDAssembly shellSupport = createHalfShellSupport(parameters);
489 
490  //const std::vector<VXDHalfShellPar>& HalfShells = parameters.getHalfShells();
491  for (const VXDHalfShellPar& shell : parameters.getHalfShells()) {
492  string shellName = shell.getName();
493  m_currentHalfShell = m_prefix + "." + shellName;
494  G4Transform3D shellAlignment = getAlignment(parameters.getAlignment(m_currentHalfShell));
495 
496  // Remember shell coordinate system (into which ladders are inserted)
497  VXD::GeoCache::getInstance().addHalfShellPlacement(m_halfShellVxdIDs[m_currentHalfShell], shellAlignment);
498 
499  //Place shell support
500  double shellAngle = shell.getShellAngle(); // Only used to move support, not active volumes!
501  if (!m_onlyActiveMaterial) shellSupport.place(envelope, shellAlignment * G4RotateZ3D(shellAngle));
502 
503  //const std::map< int, std::vector<std::pair<int, double>> >& Layers = shell.getLayers();
504  for (const std::pair<const int, std::vector<std::pair<int, double>> >& layer : shell.getLayers()) {
505  int layerID = layer.first;
506  const std::vector<std::pair<int, double>>& Ladders = layer.second;
507 
508 
509  setCurrentLayer(layerID, parameters);
510 
511  //Place Layer support
512  VXD::GeoVXDAssembly layerSupport = createLayerSupport();
513  if (!m_onlyActiveMaterial) layerSupport.place(envelope, shellAlignment * G4RotateZ3D(shellAngle));
514  VXD::GeoVXDAssembly ladderSupport = createLadderSupport();
515 
516  //Loop over defined ladders
517  for (const std::pair<int, double>& ladder : Ladders) {
518  int ladderID = ladder.first;
519  double phi = ladder.second;
520 
521  G4Transform3D ladderPlacement = placeLadder(ladderID, phi, envelope, shellAlignment, parameters);
522  if (!m_onlyActiveMaterial) ladderSupport.place(envelope, ladderPlacement);
523  }
524 
525  }
526  }
527 
528  //Now build cache with all transformations
529  if (physEnvelope) {
530  VXD::GeoCache::getInstance().findVolumes(physEnvelope);
531  } else {
532  //create a temporary placement of the top volume.
533  G4PVPlacement topPlacement(nullptr, G4ThreeVector(0, 0, 0), &topVolume,
534  "temp_Top", nullptr, false, 1, false);
535  //and search for all VXD sensitive sensors within
536  VXD::GeoCache::getInstance().findVolumes(&topPlacement);
537  }
538 
539  //Create diamond radiation sensors if defined and in background mode
540  if (m_activeChips) {
541  if (parameters.getRadiationSensors().getSubDetector() == "") {
542  B2DEBUG(10, "Apparently no radiation sensors defined, skipping");
543  } else {
544  createDiamonds(parameters.getRadiationSensors(), topVolume, *envelope);
545  }
546  }
547  }
548 
549  VXD::SensitiveDetectorBase* GeoPXDCreator::createSensitiveDetector(VxdID sensorID, const VXDGeoSensor& sensor,
550  const VXDGeoSensorPlacement& placement)
551  {
552  SensorInfo* sensorInfo = new SensorInfo(dynamic_cast<const SensorInfo&>(*sensor.getSensorInfo()));
553  sensorInfo->setID(sensorID);
554  if (placement.getFlipV()) sensorInfo->flipVSegmentation();
555  SensitiveDetector* sensitive = new SensitiveDetector(sensorInfo);
556  return sensitive;
557  }
558 
559  VXD::GeoVXDAssembly GeoPXDCreator::createLayerSupport() { return VXD::GeoVXDAssembly(); }
560 
561  VXD::GeoVXDAssembly GeoPXDCreator::createLadderSupport() { return VXD::GeoVXDAssembly(); }
562 
563  VXD::GeoVXDAssembly GeoPXDCreator::createHalfShellSupport(const PXDGeometryPar& parameters)
564  {
565  VXD::GeoVXDAssembly supportAssembly;
566 
567  if (!parameters.getBuildSupport()) return supportAssembly;
568 
569 
570  // Create the Endlanges
571  const std::vector<VXDPolyConePar> Endflanges = parameters.getEndflanges();
572  for (const VXDPolyConePar& endflange : Endflanges) {
573 
574  double minZ(0), maxZ(0);
575  string name = endflange.getName();
576 
577  // Create a polycone
578  double minPhi = endflange.getMinPhi();
579  double dPhi = endflange.getMaxPhi() - minPhi;
580  int nPlanes = endflange.getPlanes().size();
581  if (nPlanes < 2) {
582  B2ERROR("Polycone needs at least two planes");
583  return supportAssembly;
584  }
585  std::vector<double> z(nPlanes, 0);
586  std::vector<double> rMin(nPlanes, 0);
587  std::vector<double> rMax(nPlanes, 0);
588  int index(0);
589  minZ = numeric_limits<double>::infinity();
590  maxZ = -numeric_limits<double>::infinity();
591 
592  const std::vector<VXDPolyConePlanePar> Planes = endflange.getPlanes();
593  for (const VXDPolyConePlanePar& plane : Planes) {
594  z[index] = plane.getPosZ() / Unit::mm;
595  minZ = min(minZ, z[index]);
596  maxZ = max(maxZ, z[index]);
597  rMin[index] = plane.getInnerRadius() / Unit::mm;
598  rMax[index] = plane.getOuterRadius() / Unit::mm;
599  ++index;
600  }
601 
602  G4VSolid* supportCone = new G4Polycone(name, minPhi, dPhi, nPlanes, z.data(), rMin.data(), rMax.data());
603 
604 
605  //Cutout boxes to make place for modules
606 
607  //We have the z dimensions of the polycon. Let's
608  //add 1mm on each side to make sure we don't run into problems when the
609  //surfaces match
610  minZ -= 1. / Unit::mm;
611  maxZ += 1. / Unit::mm;
612 
613 
614  //Now get the number of cutouts and their size/position/angle
615  int nCutouts = parameters.getNCutOuts();
616  double sizeX = parameters.getCutOutWidth() / Unit::mm / 2.;
617  double sizeY = parameters.getCutOutHeight() / Unit::mm / 2.;
618  double sizeZ = (maxZ - minZ) / 2.;
619  G4ThreeVector origin(
620  parameters.getCutOutShift() / Unit::mm,
621  parameters.getCutOutRPhi() / Unit::mm,
622  minZ + sizeZ
623  );
624 
625  double phi0 = parameters.getCutOutStartPhi();
626  double dphi = parameters.getCutOutDeltaPhi();
627  for (int i = 0; i < nCutouts; ++i) {
628  G4Box* box = new G4Box("Cutout", sizeX, sizeY, sizeZ);
629  G4Transform3D placement = G4RotateZ3D(phi0 + i * dphi) * G4Translate3D(origin);
630  supportCone = new G4SubtractionSolid("PXD Support endflange", supportCone, box, placement);
631  }
632 
633 
634  string materialName = endflange.getMaterial();
635  G4Material* material = geometry::Materials::get(materialName);
636  if (!material) B2FATAL("Material '" << materialName << "', required by PXD component " << name << ", could not be found");
637 
638  G4LogicalVolume* volume = new G4LogicalVolume(supportCone, material, name);
639  geometry::setColor(*volume, "#ccc4");
640  supportAssembly.add(volume);
641 
642  }
643 
644 
645  //Create Carbon cooling tubes
646  {
647  int nTubes = parameters.getNTubes();
648  double minZ = parameters.getTubesMinZ() / Unit::mm;
649  double maxZ = parameters.getTubesMaxZ() / Unit::mm;
650  double minR = parameters.getTubesMinR() / Unit::mm;
651  double maxR = parameters.getTubesMaxR() / Unit::mm;
652  double sizeZ = (maxZ - minZ) / 2.;
653  double shiftX = parameters.getTubesRPhi() / Unit::mm;
654  double shiftY = 0;
655  double shiftZ = minZ + sizeZ;
656  double phi0 = parameters.getTubesStartPhi();
657  double dphi = parameters.getTubesDeltaPhi();
658  string material = parameters.getTubesMaterial();
659 
660  G4Tubs* tube = new G4Tubs("CarbonTube", minR, maxR, sizeZ, 0, 2 * M_PI);
661  G4LogicalVolume* tubeVol = new G4LogicalVolume(tube, geometry::Materials::get(material), "CarbonTube");
662  geometry::setColor(*tubeVol, "#000");
663  for (int i = 0; i < nTubes; ++i) {
664  G4Transform3D placement = G4RotateZ3D(phi0 + i * dphi) * G4Translate3D(shiftX, shiftY, shiftZ);
665  supportAssembly.add(tubeVol, placement);
666  }
667  }
668 
669  return supportAssembly;
670  }
671 
672 
673  }
675 }
Belle2::VXDGeometryPar::setRadiationSensors
void setRadiationSensors(const VXDGeoRadiationSensorsPar &diamonds)
set radiation sensor parameters
Definition: VXDGeometryPar.h:66
Belle2::VXDGeoSensorPlacement
Struct holding the information where a sensor should be placed inside the ladder.
Definition: GeoVXDComponents.h:154
Belle2::PXDSensorInfoPar::getClearBorderSmallPitch
double getClearBorderSmallPitch() const
Return the distance along u between the clear side of a small pixel and the start of the internal gat...
Definition: PXDSensorInfoPar.h:90
Belle2::PXDSensorInfoPar::getChargeThreshold
double getChargeThreshold() const
Get the charge threshold in ADU for the sensor.
Definition: PXDSensorInfoPar.h:100
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::VXDAlignmentPar
The Class for VXD Alignment payload.
Definition: VXDAlignmentPar.h:33
Belle2::PXD::GeoPXDFactory
geometry::CreatorFactory< GeoPXDCreator > GeoPXDFactory("PXDCreator")
Register the creator.
Belle2::PXDSensorInfoPar::getBackVoltage
double getBackVoltage() const
Return the voltage at the backside of the sensor.
Definition: PXDSensorInfoPar.h:80
Belle2::PXDSensorInfoPar::getGateDepth
double getGateDepth() const
Return the gate depth for the sensor.
Definition: PXDSensorInfoPar.h:96
Belle2::VXDRotationSolidPar::getOuterPoints
const std::list< std::pair< double, double > > & getOuterPoints() const
get outer XZ points
Definition: VXDRotationSolidPar.h:64
Belle2::VXDRotationSolidPar::getInnerPoints
const std::list< std::pair< double, double > > & getInnerPoints() const
get inner XZ points
Definition: VXDRotationSolidPar.h:62
Belle2::gearbox::Interface::getAngle
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
Definition: Interface.h:301
Belle2::PXDGeometryPar::setTubesMinR
void setTubesMinR(double minR)
set tubes minR
Definition: PXDGeometryPar.h:85
Belle2::VXDGeoPlacement
Class holding all parameters to place a VXD geometry subcomponent.
Definition: GeoVXDComponents.h:28
Belle2::VXDGeoRadiationSensorsPar::addPosition
void addPosition(const VXDGeoRadiationSensorsPositionPar &position)
add radiation sensor position
Definition: VXDGeoRadiationSensorsPar.h:113
Belle2::VXDGeoSensorPar::getSlanted
bool getSlanted() const
return wether or not the sensor is slanted (usually only the first sensor in layers 4-6)
Definition: VXDGeoSensorPar.h:68
Belle2::gearbox::Interface::getInt
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
Definition: Interface.cc:70
Belle2::PXDGeometryPar::setTubesMaxZ
void setTubesMaxZ(double maxZ)
set tubes maxZ
Definition: PXDGeometryPar.h:81
Belle2::VXDSensorInfoBasePar::getWidth
double getWidth() const
Return the (backward) width of the sensor.
Definition: VXDSensorInfoBasePar.h:87
Belle2::VXDSensorInfoBasePar::getSplitLength
double getSplitLength() const
Return the splitLength of the sensor.
Definition: VXDSensorInfoBasePar.h:91
Belle2::PXDGeometryPar::setTubesMaxR
void setTubesMaxR(double maxR)
set tubes maxR
Definition: PXDGeometryPar.h:89
Belle2::VXDGeoSensorPar
The Class for VXD Sensor payload.
Definition: VXDGeoSensorPar.h:39
Belle2::VXDSensorInfoBasePar::getVCells1
int getVCells1() const
Return number of pixel/strips in v direction for first segment.
Definition: VXDSensorInfoBasePar.h:99
Belle2::VXDGeometryPar::getSensorMap
const std::map< std::string, VXDGeoSensorPar > & getSensorMap() const
get sensor map
Definition: VXDGeometryPar.h:84
Belle2::VXDGeoComponentPar::getSubComponents
const std::vector< VXDGeoPlacementPar > & getSubComponents() const
get sub components
Definition: VXDGeoComponentPar.h:79
Belle2::VXDGeoPlacementPar
The Class for VXD placement payload.
Definition: VXDGeoPlacementPar.h:36
Belle2::VXD::SensitiveDetectorBase
Base class for Sensitive Detector implementation of PXD and SVD.
Definition: SensitiveDetectorBase.h:47
Belle2::VXDGeoPlacementPar::getW
const std::string & getW() const
get local w position where to place the component
Definition: VXDGeoPlacementPar.h:57
Belle2::VXDSensorInfoBasePar::getLength
double getLength() const
Return the length of the sensor.
Definition: VXDSensorInfoBasePar.h:89
Belle2::VXDGeometryPar::getGlobalParams
const VXDGlobalPar & getGlobalParams() const
get global parameters
Definition: VXDGeometryPar.h:56
Belle2::VXD::SensorInfoBase
Base class to provide Sensor Information for PXD and SVD.
Definition: SensorInfoBase.h:40
Belle2::BkgSensitiveDetector
The Class for BeamBackground Sensitive Detector.
Definition: BkgSensitiveDetector.h:34
Belle2::PXDGeometryPar::getSensorInfos
std::vector< PXDSensorInfoPar * > & getSensorInfos()
get sensorInfos
Definition: PXDGeometryPar.h:109
Belle2::VXDPolyConePar::getPlanes
std::vector< VXDPolyConePlanePar > & getPlanes(void)
Get planes.
Definition: VXDPolyConePar.h:91
Belle2::VXDGeometryPar::setEnvelope
void setEnvelope(const VXDEnvelopePar &envelope)
set envelope parameters
Definition: VXDGeometryPar.h:62
Belle2::VXDGeometryPar::getHalfShells
const std::vector< VXDHalfShellPar > & getHalfShells() const
get half-shell
Definition: VXDGeometryPar.h:72
Belle2::PXDGeometryPar::setCutOutShift
void setCutOutShift(double shift)
set shift of cutouts
Definition: PXDGeometryPar.h:56
Belle2::VXDGeoSensorPar::getActiveArea
const VXDGeoComponentPar & getActiveArea() const
get the component description for the active area
Definition: VXDGeoSensorPar.h:56
Belle2::VXDGlobalPar::getActiveChips
bool getActiveChips() const
Get whether chips are sensitive
Definition: VXDGlobalPar.h:58
Belle2::PXDGeometryPar::setCutOutHeight
void setCutOutHeight(double height)
set height of cutouts
Definition: PXDGeometryPar.h:52
Belle2::VXDGeoComponentPar::getLength
double getLength() const
get the length of the component
Definition: VXDGeoComponentPar.h:65
Belle2::PXDSensorInfoPar::getIntegrationEnd
double getIntegrationEnd() const
Return the end of the integration window, the timeframe the PXD is sensitive.
Definition: PXDSensorInfoPar.h:106
Belle2::VXD::GeoVXDAssembly
Class to group some Geant4 volumes and place them all at once with a given transformation matrix.
Definition: GeoVXDAssembly.h:31
Belle2::PXDGeometryPar::setCutOutStartPhi
void setCutOutStartPhi(double start)
set start phi of cutouts
Definition: PXDGeometryPar.h:64
Belle2::VXDPolyConePlanePar
The Class for VXD Polycone Plane.
Definition: VXDPolyConePar.h:35
Belle2::VXDGeoRadiationSensorsPar
The Class for VXD Radiation Sensor parameters.
Definition: VXDGeoRadiationSensorsPar.h:77
Belle2::PXDGeometryPar::setTubesRPhi
void setTubesRPhi(double rphi)
set tubes tubes RPhi
Definition: PXDGeometryPar.h:93
Belle2::PXDSensorInfoPar::getSourceBorderLargePitch
double getSourceBorderLargePitch() const
Return the distance along v between the source side of a large pixel and the start of the internal ga...
Definition: PXDSensorInfoPar.h:84
Belle2::PXDGeometryPar::setTubesDeltaPhi
void setTubesDeltaPhi(double delta)
set tubes tubes DeltaPhi
Definition: PXDGeometryPar.h:101
Belle2::VXDGeoComponentPar::getColor
const std::string & getColor() const
get the name of the color for the component
Definition: VXDGeoComponentPar.h:53
Belle2::PXDGeometryPar::getEndflanges
const std::vector< VXDPolyConePar > & getEndflanges() const
get Endflanges
Definition: PXDGeometryPar.h:107
Belle2::VXDHalfShellPar::addLadder
void addLadder(int layerID, int ladderID, double phi)
add ladder
Definition: VXDHalfShellPar.h:47
Belle2::PXD::SensorInfo
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:34
Belle2::PXD::SensorInfo::setID
void setID(VxdID id)
Change the SensorID, useful to copy the SensorInfo from one sensor and use it for another.
Definition: SensorInfo.h:48
Belle2::PXDGeometryPar
The Class for VXD geometry.
Definition: PXDGeometryPar.h:35
Belle2::PXDGeometryPar::setNCutOuts
void setNCutOuts(int nCutouts)
set number of cutouts
Definition: PXDGeometryPar.h:44
Belle2::VXDGeoComponentPar::getMaterial
const std::string & getMaterial() const
get the name of the Material for the component
Definition: VXDGeoComponentPar.h:49
Belle2::VXDGeoPlacementPar::getU
double getU() const
get local u coordinate where to place the component
Definition: VXDGeoPlacementPar.h:49
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::VXDGeoComponentPar::getWidth
double getWidth() const
get the width of the component
Definition: VXDGeoComponentPar.h:57
Belle2::geometry::setVisibility
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition: utilities.cc:115
Belle2::VXDGeoSensorPar::getActivePlacement
const VXDGeoPlacementPar & getActivePlacement() const
get the placement description for the active area
Definition: VXDGeoSensorPar.h:58
Belle2::PXDSensorInfoPar::getNoiseFraction
double getNoiseFraction() const
Get the noise fraction for the sensor.
Definition: PXDSensorInfoPar.h:102
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::VXDGeometryPar::setGlobalParams
void setGlobalParams(const VXDGlobalPar &globals)
set global parameters
Definition: VXDGeometryPar.h:58
Belle2::PXDSensorInfoPar::getTopVoltage
double getTopVoltage() const
Return the voltage at the top of the sensor.
Definition: PXDSensorInfoPar.h:82
Belle2::VXDSensorInfoBasePar::getVCells2
int getVCells2() const
Return number of pixel/strips in v direction for second segment.
Definition: VXDSensorInfoBasePar.h:101
Belle2::VXDGeoComponentPar::getWidth2
double getWidth2() const
get the forward width of the component, 0 for rectangular
Definition: VXDGeoComponentPar.h:61
Belle2::VXDGeometryPar::setPrefix
void setPrefix(const std::string &prefix)
set prefix
Definition: VXDGeometryPar.h:54
Belle2::VXD::GeoVXDAssembly::add
void add(G4LogicalVolume *volume, const G4Transform3D &transform=G4Transform3D())
Add a volume to the assembly.
Definition: GeoVXDAssembly.h:46
Belle2::PXDSensorInfoPar::getDrainBorderLargePitch
double getDrainBorderLargePitch() const
Return the distance along v between the drain side of a large pixel and the start of the internal gat...
Definition: PXDSensorInfoPar.h:92
Belle2::VXDGeoSensorPar::getComponents
const std::vector< VXDGeoPlacementPar > & getComponents() const
get the list of sub components
Definition: VXDGeoSensorPar.h:62
Belle2::PXDSensorInfoPar::getClearBorderLargePitch
double getClearBorderLargePitch() const
Return the distance along u between the clear side of a large pixel and the start of the internal gat...
Definition: PXDSensorInfoPar.h:88
Belle2::VXDGlobalPar
The Class for VXD global paramter payload.
Definition: VXDGlobalPar.h:34
Belle2::PXD::SensorInfo::flipVSegmentation
void flipVSegmentation()
Flip the Pitch segmentation along v.
Definition: SensorInfo.h:54
Belle2::VXDGeoComponentPar::getHeight
double getHeight() const
get the height of the component
Definition: VXDGeoComponentPar.h:69
Belle2::PXDGeometryPar::setNTubes
void setNTubes(int nTubes)
set number of tubes
Definition: PXDGeometryPar.h:73
Belle2::VXDPolyConePar
The Class for VXD PolyCone, possibly with coutouts.
Definition: VXDPolyConePar.h:65
Belle2::VXDSensorInfoBasePar::getUCells
int getUCells() const
Return number of pixel/strips in u direction.
Definition: VXDSensorInfoBasePar.h:95
Belle2::VXDGeoRadiationSensorsPositionPar::addSensor
void addSensor(int id, double phi)
add sensor with individual id
Definition: VXDGeoRadiationSensorsPar.h:58
Belle2::gearbox::Interface::getLength
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:261
Belle2::VXDGeoPlacementPar::getV
double getV() const
get local v coordinate where to place the component
Definition: VXDGeoPlacementPar.h:53
Belle2::GearDir::getString
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition: GearDir.h:79
Belle2::VXDGeoSensorPlacement::getFlipV
bool getFlipV() const
check whether or not the sensor should be flipped around the V coordinate
Definition: GeoVXDComponents.h:169
Belle2::VXDGeoSensor
Struct holding all parameters for a completeVXD Sensor.
Definition: GeoVXDComponents.h:112
Belle2::PXDSensorInfoPar
The Class for VXD geometry.
Definition: PXDSensorInfoPar.h:32
Belle2::VXDGeoComponentPar
The Class for VXD geometry component.
Definition: VXDGeoComponentPar.h:36
Belle2::PXDGeometryPar::setCutOutDeltaPhi
void setCutOutDeltaPhi(double delta)
set deltaphi of cutouts
Definition: PXDGeometryPar.h:68
Belle2::PXDSensorInfoPar::getIntegrationStart
double getIntegrationStart() const
Return the start of the integration window, the timeframe the PXD is sensitive.
Definition: PXDSensorInfoPar.h:104
Belle2::VXD::SensitiveDetector
Sensitive Detector implementation of PXD and SVD.
Definition: SensitiveDetector.h:67
Belle2::PXDSensorInfoPar::getDrainBorderSmallPitch
double getDrainBorderSmallPitch() const
Return the distance along v between the drain side of a small pixel and the start of the internal gat...
Definition: PXDSensorInfoPar.h:94
Belle2::PXDSensorInfoPar::getDoublePixel
bool getDoublePixel() const
Return true if the Sensor is a double pixel structure: every other pixel is mirrored along v.
Definition: PXDSensorInfoPar.h:98
Belle2::VXDGeoComponentPar::getAngle
double getAngle() const
get the angle of the component
Definition: VXDGeoComponentPar.h:75
Belle2::VXD::GeoVXDAssembly::place
void place(G4LogicalVolume *mother, const G4Transform3D &transform)
Place all the volumes already added to the assembly in the given mother.
Definition: GeoVXDAssembly.cc:32
Belle2::gearbox::Interface::getBool
bool getBool(const std::string &path="") const noexcept(false)
Get the parameter path as a bool.
Definition: Interface.cc:90
Belle2::VXDHalfShellPar
The Class for VXD half shell payload.
Definition: VXDHalfShellPar.h:37
Belle2::PXDGeometryPar::setCutOutWidth
void setCutOutWidth(double width)
set width of cutouts
Definition: PXDGeometryPar.h:48
Belle2::PXDGeometryPar::setTubesMaterial
void setTubesMaterial(const std::string &material)
set tubes tubes material
Definition: PXDGeometryPar.h:105
Belle2::gearbox::Interface::getNodes
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:31
Belle2::VXDGeoComponent
Class holding all parameters for an VXD geometry component.
Definition: GeoVXDComponents.h:65
Belle2::PXDGeometryPar::setCutOutRPhi
void setCutOutRPhi(double rphi)
set rphi of cutouts
Definition: PXDGeometryPar.h:60
Belle2::geometry::GeometryTypes
GeometryTypes
Flag indiciating the type of geometry to be used.
Definition: GeometryManager.h:39
Belle2::VXDGeoPlacementPar::getWOffset
double getWOffset() const
get offset to local w position where to place the component
Definition: VXDGeoPlacementPar.h:61
Belle2::VXDEnvelopePar
The Class for VXD Envelope parameters.
Definition: VXDEnvelopePar.h:31
Belle2::VXDGeoRadiationSensorsPositionPar
The Class for VXD Radiation Sensor Position parameters.
Definition: VXDGeoRadiationSensorsPar.h:36
Belle2::PXDSensorInfoPar::getBulkDoping
double getBulkDoping() const
Return the bulk doping of the Silicon sensor.
Definition: PXDSensorInfoPar.h:78
Belle2::PXDGeometryPar::setTubesStartPhi
void setTubesStartPhi(double start)
set tubes tubes StartPhi
Definition: PXDGeometryPar.h:97
Belle2::VXDSensorInfoBasePar::getThickness
double getThickness() const
Return the thickness of the sensor.
Definition: VXDSensorInfoBasePar.h:93
Belle2::VXDGeometryPar::getAlignmentMap
std::map< std::string, VXDAlignmentPar > & getAlignmentMap()
get alignmant map
Definition: VXDGeometryPar.h:68
Belle2::PXDGeometryPar::setTubesMinZ
void setTubesMinZ(double minZ)
set tubes minZ
Definition: PXDGeometryPar.h:77
Belle2::PXDSensorInfoPar::getSourceBorderSmallPitch
double getSourceBorderSmallPitch() const
Return the distance along v between the source side of a small pixel and the start of the internal ga...
Definition: PXDSensorInfoPar.h:86