28 std::unique_ptr<const Logger> logger)
43 std::unique_ptr<const Logger> newLogger) {
44 m_logger = std::move(newLogger);
47 std::shared_ptr<Acts::TrackingVolume>
51 ACTS_DEBUG(
"Configured to build volume : " << m_cfg.volumeName);
53 ACTS_DEBUG(
"- will wrap/enclose : " << existingVolume->volumeName());
70 if (m_cfg.layerBuilder) {
72 negativeLayers = m_cfg.layerBuilder->negativeLayers(gctx);
74 centralLayers = m_cfg.layerBuilder->centralLayers(gctx);
76 positiveLayers = m_cfg.layerBuilder->positiveLayers(gctx);
81 if (m_cfg.ctVolumeBuilder) {
82 centralVolumes = m_cfg.ctVolumeBuilder->centralVolumes();
91 &existingVolume->volumeBounds());
99 existingVolume->center().z() -
102 existingVolume->center().z() +
109 if (externalBounds) {
113 if (ocvBounds !=
nullptr) {
147 wConfig.
nVolumeConfig = analyzeContent(gctx, negativeLayers, {});
148 wConfig.
cVolumeConfig = analyzeContent(gctx, centralLayers, centralVolumes);
149 wConfig.
pVolumeConfig = analyzeContent(gctx, positiveLayers, {});
151 std::string layerConfiguration =
"|";
154 ACTS_VERBOSE(
"Negative layers are present: rmin, rmax | zmin, zmax = "
157 layerConfiguration +=
" Negative Endcap |";
161 ACTS_VERBOSE(
"Central layers are present: rmin, rmax | zmin, zmax = "
164 layerConfiguration +=
" Barrel |";
168 ACTS_VERBOSE(
"Positive layers are present: rmin, rmax | zmin, zmax = "
171 layerConfiguration +=
" Positive Endcap |";
174 ACTS_DEBUG(
"Layer configuration is : " << layerConfiguration);
178 ACTS_VERBOSE(
"Configurations after layer parsing " <<
'\n'
182 ACTS_VERBOSE(
"Configuration after container synchronisation "
188 ACTS_VERBOSE(
"Configuration after wrapping, insertion, attachment "
199 auto tvHelper = m_cfg.trackingVolumeHelper;
203 ? tvHelper->createTrackingVolume(
208 m_cfg.volumeName +
"::Barrel")
218 if (not endcapConfig) {
222 if (m_cfg.checkRingLayout) {
223 ACTS_DEBUG(
"Configured to check for ring layout - parsing layers.");
225 std::vector<double> innerRadii = {};
226 std::vector<double> outerRadii = {};
227 for (
const auto& elay : endcapConfig.layers) {
229 &(elay->surfaceRepresentation().bounds()));
230 if (discBounds !=
nullptr) {
231 double tolerance = m_cfg.ringTolerance;
233 double rMin = discBounds->
rMin();
234 auto innerSearch = std::find_if(
235 innerRadii.begin(), innerRadii.end(), [&](
double reference) {
236 return std::abs(rMin - reference) < tolerance;
238 if (innerSearch == innerRadii.end()) {
239 innerRadii.push_back(rMin);
242 double rMax = discBounds->rMax();
243 auto outerSearch = std::find_if(
244 outerRadii.begin(), outerRadii.end(), [&](
double reference) {
245 return std::abs(rMax - reference) < tolerance;
247 if (outerSearch == outerRadii.end()) {
248 outerRadii.push_back(rMax);
253 if (innerRadii.size() == outerRadii.size() and not innerRadii.empty()) {
254 bool consistent =
true;
256 std::vector<double> interRadii = {};
257 for (
int ir = 1; ir <
int(innerRadii.size()); ++ir) {
259 if (outerRadii[ir - 1] < innerRadii[ir]) {
260 interRadii.push_back(0.5 * (outerRadii[ir - 1] + innerRadii[ir]));
268 ACTS_DEBUG(
"Ring layout detection: " << innerRadii.size()
271 std::vector<std::pair<double, double>> volumeRminRmax = {};
272 for (
unsigned int ii = 0; ii < interRadii.size(); ++ii) {
274 volumeRminRmax.push_back({endcapConfig.rMin, interRadii[ii]});
276 if (ii + 1 < interRadii.size()) {
277 volumeRminRmax.push_back({interRadii[ii], interRadii[ii + 1]});
279 volumeRminRmax.push_back({interRadii[ii], endcapConfig.rMax});
283 std::vector<LayerVector>(innerRadii.size(),
LayerVector());
285 for (
const auto& elay : endcapConfig.layers) {
288 elay->surfaceRepresentation().binningPositionValue(gctx,
binR);
290 auto ringVolume = std::find_if(
291 volumeRminRmax.begin(), volumeRminRmax.end(),
292 [&](
const auto& reference) {
293 return (test > reference.first and test < reference.second);
295 if (ringVolume != volumeRminRmax.end()) {
296 unsigned int ringBin =
297 std::distance(volumeRminRmax.begin(), ringVolume);
298 ringLayers[ringBin].push_back(elay);
304 std::vector<TrackingVolumePtr> endcapContainer;
306 for (
auto& rLayers : ringLayers) {
307 ACTS_DEBUG(
" - ring volume " << ir <<
" with " << rLayers.size()
308 <<
" layers, and rmin/rmax = "
309 << volumeRminRmax[ir].first <<
"/"
310 << volumeRminRmax[ir].second);
311 endcapContainer.push_back(tvHelper->createTrackingVolume(
312 gctx, rLayers, centralConfig.
volumes, m_cfg.volumeMaterial,
313 volumeRminRmax[ir].first, volumeRminRmax[ir].second,
314 endcapConfig.zMin, endcapConfig.zMax,
315 m_cfg.volumeName + endcapName + std::string(
"::Ring") +
320 return tvHelper->createContainerTrackingVolume(gctx, endcapContainer);
326 return tvHelper->createTrackingVolume(
327 gctx, endcapConfig.layers, centralConfig.
volumes, m_cfg.volumeMaterial,
328 endcapConfig.rMin, endcapConfig.rMax, endcapConfig.zMin,
329 endcapConfig.zMax, m_cfg.volumeName + endcapName);
347 std::vector<TrackingVolumePtr> volumesContainer;
349 volumesContainer.push_back(nEndcap);
352 if (not m_cfg.buildToRadiusZero) {
353 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[0],
356 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[1],
358 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[2],
360 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[3],
365 volumesContainer.push_back(barrel);
368 if (not m_cfg.buildToRadiusZero) {
369 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[0],
372 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[1],
374 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[3],
376 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[4],
380 volumesContainer.push_back(pEndcap);
383 if (not m_cfg.buildToRadiusZero) {
384 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[0],
387 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[1],
389 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[4],
391 volume->assignBoundaryMaterial(m_cfg.boundaryMaterial[5],
396 volumesContainer.size() > 1
397 ? tvHelper->createContainerTrackingVolume(gctx, volumesContainer)
401 volume = nEndcap ? nEndcap : (barrel ? barrel : pEndcap);
407 if (existingVolumeCp) {
409 std::vector<TrackingVolumePtr> existingContainer;
412 auto fGap = tvHelper->createGapTrackingVolume(
416 false, m_cfg.volumeName +
"::fGap");
418 existingContainer.push_back(fGap);
420 existingContainer.push_back(existingVolumeCp);
423 auto sGap = tvHelper->createGapTrackingVolume(
427 false, m_cfg.volumeName +
"::sGap");
429 existingContainer.push_back(sGap);
434 existingContainer.size() > 1
435 ? tvHelper->createContainerTrackingVolume(gctx, existingContainer)
440 existingContainer.clear();
442 existingContainer.push_back(existingVolumeCp);
443 existingContainer.push_back(barrel);
445 existingContainer.push_back(barrel);
446 existingContainer.push_back(existingVolumeCp);
450 !existingContainer.empty()
451 ? tvHelper->createContainerTrackingVolume(gctx, existingContainer)
454 std::vector<TrackingVolumePtr> totalContainer;
460 totalContainer.push_back(nEndcap);
462 totalContainer.push_back(existingVolumeCp);
464 totalContainer.push_back(pEndcap);
467 totalContainer.push_back(volume);
468 totalContainer.push_back(existingVolumeCp);
470 totalContainer.push_back(existingVolumeCp);
471 totalContainer.push_back(volume);
473 ACTS_ERROR(
"Misconfiguration in volume building detected.");
477 volume = tvHelper->createContainerTrackingVolume(gctx, totalContainer);
492 if (!lVector.empty() || !mtvVector.empty()) {
496 for (
auto&
layer : lVector) {
500 const Vector3D& center =
layer->surfaceRepresentation().center(gctx);
504 if (cLayer !=
nullptr) {
522 &(
layer->surfaceRepresentation().bounds()));
523 if (dBounds !=
nullptr) {
525 double rMinD = dBounds->
rMin();
526 double rMaxD = dBounds->
rMax();
527 double zMinD = center.z() - 0.5 *
thickness;
528 double zMaxD = center.z() + 0.5 *
thickness;
535 for (
auto&
volume : mtvVector) {
538 if (cvBounds !=
nullptr) {
554 if (m_cfg.buildToRadiusZero) {
555 ACTS_VERBOSE(
"This layer builder is configured to build to the beamline.");