From 0993fcac3f5edb27e15152d1c43ae13779b0bf4c Mon Sep 17 00:00:00 2001 From: Andreas Salzburger <Andreas.Salzburger@cern.ch> Date: Mon, 10 Feb 2020 13:17:35 +0100 Subject: [PATCH] updated TGeo and Obj writer --- .../ACTFW/TGeoDetector/BuildTGeoDetector.hpp | 41 +++- .../TGeoDetector/TGeoDetectorOptions.hpp | 217 ++++++++++++++---- .../include/ACTFW/Plugins/Obj/ObjHelper.hpp | 12 + Plugins/Obj/src/ObjHelper.cpp | 78 +++++++ Plugins/Obj/src/ObjSurfaceWriter.cpp | 44 ++-- Plugins/Obj/src/ObjTrackingGeometryWriter.cpp | 5 +- external/acts-core | 2 +- 7 files changed, 329 insertions(+), 70 deletions(-) diff --git a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/BuildTGeoDetector.hpp b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/BuildTGeoDetector.hpp index b24d7ea43..fb72dd5b8 100644 --- a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/BuildTGeoDetector.hpp +++ b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/BuildTGeoDetector.hpp @@ -25,8 +25,11 @@ #include "Acts/Material/Material.hpp" #include "Acts/Material/MaterialProperties.hpp" #include "Acts/Plugins/TGeo/TGeoDetectorElement.hpp" +#include "Acts/Utilities/Units.hpp" #include "TGeoManager.h" +using namespace Acts::UnitLiterals; + namespace FW { namespace TGeo { @@ -93,11 +96,39 @@ namespace TGeo { std::string rootFileName = vm["geo-tgeo-filename"].template as<std::string>(); + + // Create a beam pipe if configured to do so + auto beamPipeParameters + = vm["geo-tgeo-bp-parameters"].template as<read_range>(); + if (beamPipeParameters.size() > 2){ + + /// configure the beam pipe layer builder + Acts::PassiveLayerBuilder::Config bplConfig; + bplConfig.layerIdentification = "BeamPipe"; + bplConfig.centralLayerRadii = std::vector<double>(1, beamPipeParameters[0]); + bplConfig.centralLayerHalflengthZ = std::vector<double>(1, beamPipeParameters[1]); + bplConfig.centralLayerThickness = std::vector<double>(1, beamPipeParameters[2]); + auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>( + bplConfig, Acts::getDefaultLogger("BeamPipeLayerBuilder", layerLogLevel)); + // create the volume for the beam pipe + Acts::CylinderVolumeBuilder::Config bpvConfig; + bpvConfig.trackingVolumeHelper = cylinderVolumeHelper; + bpvConfig.volumeName = "BeamPipe"; + bpvConfig.layerBuilder = beamPipeBuilder; + bpvConfig.layerEnvelopeR = {1. * Acts::units::_mm, 1. * Acts::units::_mm}; + bpvConfig.buildToRadiusZero = true; + auto beamPipeVolumeBuilder + = std::make_shared<const Acts::CylinderVolumeBuilder>( + bpvConfig, + Acts::getDefaultLogger("BeamPipeVolumeBuilder", volumeLogLevel)); + // add to the list of builders + volumeBuilders.push_back(beamPipeVolumeBuilder); + + } + // import the file from TGeoManager::Import(rootFileName.c_str()); - bool firstOne = true; - auto layerBuilderConfigs = FW::Options::readTGeoLayerBuilderConfigs<variable_maps_t>( vm, layerCreator); @@ -116,7 +147,9 @@ namespace TGeo { Acts::CylinderVolumeBuilder::Config volumeConfig; volumeConfig.trackingVolumeHelper = cylinderVolumeHelper; volumeConfig.volumeName = lbc.configurationName; - volumeConfig.buildToRadiusZero = firstOne; + volumeConfig.checkRingLayout = lbc.checkRingLayout; + volumeConfig.ringTolerance = lbc.ringTolerance; + volumeConfig.buildToRadiusZero = (volumeBuilders.size() == 0); volumeConfig.layerEnvelopeR = {1. * Acts::units::_mm, 5. * Acts::units::_mm}; volumeConfig.layerBuilder = layerBuilder; @@ -127,8 +160,6 @@ namespace TGeo { volumeLogLevel)); // add to the list of builders volumeBuilders.push_back(volumeBuilder); - // remember that you've built to the beam pipe already - firstOne = false; } //------------------------------------------------------------------------------------- diff --git a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetectorOptions.hpp b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetectorOptions.hpp index 7d7d1c49d..e85969ccf 100644 --- a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetectorOptions.hpp +++ b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetectorOptions.hpp @@ -42,6 +42,9 @@ namespace Options { "geo-tgeo-unitScalor", po::value<double>()->default_value(10.), "Unit scalor from ROOT to Acts.")( + "geo-tgeo-bp-parameters", + po::value<read_range>()->multitoken()->default_value({}), + "Potential beam pipe parameters {r, z, t} in [mm].")( "geo-tgeo-nlayers", po::value<read_series>()->multitoken()->default_value({}), "Number of layers on the negative side.")( @@ -51,6 +54,12 @@ namespace Options { "geo-tgeo-players", po::value<read_series>()->multitoken()->default_value({}), "Number of layers on the positive side.")( + "geo-tgeo-ringlayout", + po::value<read_series>()->multitoken()->default_value({}), + "Indicator if ring layout is present.")( + "geo-tgeo-ringtolerance", + po::value<read_range>()->multitoken()->default_value({}), + "Tolerance for ring layout detection in [mm].")( "geo-tgeo-nlayernames", po::value<read_strings>()->multitoken()->default_value({}), "Name identifier for negative layer objects, odered along the series.")( @@ -74,10 +83,54 @@ namespace Options { po::value<read_strings>()->multitoken()->default_value({}), "Axes definition for negative sensitive objects, odered " "along the series.")( - "geo-tgeo-clayersplits", + "geo-tgeo-nlayer-rmin", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy min r for negative layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-nlayer-rmax", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy max r for negative layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-clayer-rmin", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy min r for central layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-clayer-rmax", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy max r for central layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-player-rmin", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy min r for central layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-player-rmax", + po::value<read_range>()->multitoken()->default_value({}), + "Cylindrical boundariy max r for positive layers " + "to restrict the module parsing (optional).")( + "geo-tgeo-nlayer-rsplit", po::value<read_range>()->multitoken()->default_value({}), - "Radial tolerances (if different from 0.) that triggers splitting " - " of collected surfaces into different layers.")( + "R-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different negative layers.")( + "geo-tgeo-nlayer-zsplit", + po::value<read_range>()->multitoken()->default_value({}), + "Z-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different negative layers.")( + "geo-tgeo-clayer-rsplit", + po::value<read_range>()->multitoken()->default_value({}), + "R-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different central layers.")( + "geo-tgeo-clayer-zsplit", + po::value<read_range>()->multitoken()->default_value({}), + "Z-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different central layers.")( + "geo-tgeo-player-rsplit", + po::value<read_range>()->multitoken()->default_value({}), + "R-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different positive layers.")( + "geo-tgeo-player-zsplit", + po::value<read_range>()->multitoken()->default_value({}), + "Z-tolerances (if > 0.) that triggers splitting " + " of collected surfaces into different positive layers.")( "geo-tgeo-cmoduleaxes", po::value<read_strings>()->multitoken()->default_value({}), "Axes definition for central sensitive objects, odered along the " @@ -103,83 +156,151 @@ namespace Options { { std::vector<Acts::TGeoLayerBuilder::Config> detLayerConfigs; - // general stuff + // General: subdetector naming read_strings subdetectors = vm["geo-subdetectors"].template as<read_strings>(); double unitScalor = vm["geo-tgeo-unitScalor"].template as<double>(); - // these define a series, such as 1, 3, 4 + + // The number of layers, can be set 1 with splitting detection read_series nlayers = vm["geo-tgeo-nlayers"].template as<read_series>(); read_series clayers = vm["geo-tgeo-clayers"].template as<read_series>(); read_series players = vm["geo-tgeo-players"].template as<read_series>(); - // - // these are going continously through the series, such as i in [ 1 + 3 + 4 - // ] + std::array<read_series, 3> layers = {nlayers, clayers, players}; + + std::array<size_t, 3> series_size + = {nlayers.size(), clayers.size(), players.size()}; + + read_series ringlayout + = vm["geo-tgeo-ringlayout"].template as<read_series>(); + + read_range ringtolerance + = vm["geo-tgeo-ringtolerance"].template as<read_range>(); + + // The layer names to parse for in the TGeo read_strings nlayernames = vm["geo-tgeo-nlayernames"].template as<read_strings>(); read_strings clayernames = vm["geo-tgeo-clayernames"].template as<read_strings>(); read_strings playernames = vm["geo-tgeo-playernames"].template as<read_strings>(); + + std::array<read_strings, 3> layernames + = {nlayernames, clayernames, playernames}; + read_strings nsensitivenames = vm["geo-tgeo-nmodulenames"].template as<read_strings>(); read_strings csensitivenames = vm["geo-tgeo-cmodulenames"].template as<read_strings>(); read_strings psensitivenames = vm["geo-tgeo-pmodulenames"].template as<read_strings>(); + + // The sensitive names to parse for in the TGeo + std::array<read_strings, 3> sensitivenames + = {nsensitivenames, csensitivenames, psensitivenames}; + read_strings nsensitiveaxes = vm["geo-tgeo-nmoduleaxes"].template as<read_strings>(); read_strings csensitiveaxes = vm["geo-tgeo-cmoduleaxes"].template as<read_strings>(); read_strings psensitiveaxes = vm["geo-tgeo-pmoduleaxes"].template as<read_strings>(); - // the layer splits - read_range clayersplits - = vm["geo-tgeo-clayersplits"].template as<read_range>(); - // total coutners - int tin = 0; - int tic = 0; - int tip = 0; - // prepare the TGeoLayerBuilder::Configs - for (size_t idet = 0; idet < clayers.size(); ++idet) { + std::array<read_strings, 3> sensitiveaxes + = {nsensitiveaxes, csensitiveaxes, psensitiveaxes}; - Acts::TGeoLayerBuilder::Config layerBuilderConfig; - // get the current numbers - int cn = nlayers[idet]; - int cc = clayers[idet]; - int cp = players[idet]; - // fill the configs - for negative - for (int in = 0; in < cn; ++in, ++tin) { - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.layerName = nlayernames[tin]; - lConfig.sensorName = nsensitivenames[tin]; - lConfig.localAxes = nsensitiveaxes[tin]; - layerBuilderConfig.negativeLayerConfigs.push_back(lConfig); - } - // fill the configs - for barrel - for (int ic = 0; ic < cc; ++ic, ++tic) { - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.layerName = clayernames[tic]; - lConfig.sensorName = csensitivenames[tic]; - lConfig.localAxes = csensitiveaxes[tic]; - layerBuilderConfig.centralLayerSplit = clayersplits[tic]; - layerBuilderConfig.centralLayerConfigs.push_back(lConfig); + // The parse radii in r + read_range nrmin = vm["geo-tgeo-nlayer-rmin"].template as<read_range>(); + read_range nrmax = vm["geo-tgeo-nlayer-rmax"].template as<read_range>(); + read_range crmin = vm["geo-tgeo-clayer-rmin"].template as<read_range>(); + read_range crmax = vm["geo-tgeo-clayer-rmax"].template as<read_range>(); + read_range prmin = vm["geo-tgeo-player-rmin"].template as<read_range>(); + read_range prmax = vm["geo-tgeo-player-rmax"].template as<read_range>(); + + std::array<read_range, 3> rmin = {nrmin, crmin, prmin}; + std::array<read_range, 3> rmax = {nrmax, crmax, prmax}; + + // The split tolerances in r and z + read_range nlayersplitr + = vm["geo-tgeo-nlayer-rsplit"].template as<read_range>(); + read_range nlayersplitz + = vm["geo-tgeo-nlayer-zsplit"].template as<read_range>(); + read_range clayersplitr + = vm["geo-tgeo-clayer-rsplit"].template as<read_range>(); + read_range clayersplitz + = vm["geo-tgeo-clayer-zsplit"].template as<read_range>(); + read_range playersplitr + = vm["geo-tgeo-player-rsplit"].template as<read_range>(); + read_range playersplitz + = vm["geo-tgeo-player-zsplit"].template as<read_range>(); + + std::array<read_range, 3> splittolr + = {nlayersplitr, clayersplitr, playersplitr}; + + std::array<read_range, 3> splittolz + = {nlayersplitz, clayersplitz, playersplitz}; + + // The maximum series and total counter for access of nonsplit layers + size_t max_series + = *std::max_element(series_size.begin(), series_size.end()); + std::array<size_t, 3> ti = {0, 0, 0}; + + + // If a beam pipe is present, shift the sub detector names by one + // Create a beam pipe if configured to do so + int idetaddon = 0; + auto beamPipeParameters + = vm["geo-tgeo-bp-parameters"].template as<read_range>(); + if (beamPipeParameters.size() > 2){ + ++idetaddon; } - // fill the configs - for positive - for (int ip = 0; ip < cp; ++ip, ++tip) { - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.layerName = playernames[tip]; - lConfig.sensorName = psensitivenames[tip]; - lConfig.localAxes = psensitiveaxes[tip]; - layerBuilderConfig.positiveLayerConfigs.push_back(lConfig); + + // Prepare the TGeoLayerBuilder::Configs + for (size_t idet = 0; idet < max_series; ++idet) { + // Each detector needs a layer builder + Acts::TGeoLayerBuilder::Config layerBuilderConfig; + // Loop over the | n | c | p | configuration + for (unsigned int ncp = 0; ncp < 3; ++ncp) { + // number of layers of this configuration + unsigned int nl = layers[ncp].size() > idet ? layers[ncp][idet] : 0; + for (int in = 0; in < nl; ++in, ++ti[ncp]) { + // Create the layer config object and fill it + Acts::TGeoLayerBuilder::LayerConfig lConfig; + lConfig.layerName = layernames[ncp][ti[ncp]]; + lConfig.sensorName = sensitivenames[ncp][ti[ncp]]; + lConfig.localAxes = sensitiveaxes[ncp][ti[ncp]]; + // Fill the parsing restrictions in r + auto crmin = rmin[ncp]; + auto crmax = rmax[ncp]; + if (crmin.size() > ti[ncp] and crmax.size() > ti[ncp]) { + lConfig.parseRangeR = {crmin[ti[ncp]], crmax[ti[ncp]]}; + } + // Fill the layer splitting parameters in r + if (splittolr[ncp].size() > ti[ncp]) { + layerBuilderConfig.layerSplitToleranceR[ncp] + = splittolr[ncp][ti[ncp]]; + } + // Fill the layer splitting parameters in z + if (splittolz[ncp].size() > ti[ncp]) { + layerBuilderConfig.layerSplitToleranceZ[ncp] + = splittolz[ncp][ti[ncp]]; + } + layerBuilderConfig.layerConfigurations[ncp].push_back(lConfig); + // Set the ring layout if configured to do so + if (ringlayout.size() > idet and ringtolerance.size() > idet) { + layerBuilderConfig.checkRingLayout = (ringlayout[idet] != 0); + layerBuilderConfig.ringTolerance = ringtolerance[idet]; + } + } } - // set the scale and the layer creator - layerBuilderConfig.configurationName = subdetectors[idet]; + + + // Set the scale and the layer creator + layerBuilderConfig.configurationName = subdetectors[idet+idetaddon]; layerBuilderConfig.unit = unitScalor; layerBuilderConfig.layerCreator = layerCreator; - // now add it to the configs + // Now add it to the configs detLayerConfigs.push_back(layerBuilderConfig); } return detLayerConfigs; diff --git a/Plugins/Obj/include/ACTFW/Plugins/Obj/ObjHelper.hpp b/Plugins/Obj/include/ACTFW/Plugins/Obj/ObjHelper.hpp index 472fefa8f..33dcab9c9 100644 --- a/Plugins/Obj/include/ACTFW/Plugins/Obj/ObjHelper.hpp +++ b/Plugins/Obj/include/ACTFW/Plugins/Obj/ObjHelper.hpp @@ -58,6 +58,18 @@ namespace Obj { double thickness = 0., const std::vector<unsigned int>& vsides = {}); + /// This will write a disc surface with annulus bounds + /// + /// @param stream is the stream where to write to + void + writeAnnulusDisc(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + unsigned int nSegments, + const Acts::Transform3D& transform, + const std::vector<Acts::Vector2D>& vertices, + double thickness = 0.); + /// This will write a cylindrical object /// /// @param stream is the stream where to write to diff --git a/Plugins/Obj/src/ObjHelper.cpp b/Plugins/Obj/src/ObjHelper.cpp index 3c614c8ad..650c734fd 100644 --- a/Plugins/Obj/src/ObjHelper.cpp +++ b/Plugins/Obj/src/ObjHelper.cpp @@ -7,7 +7,9 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "ACTFW/Plugins/Obj/ObjHelper.hpp" +#include <iostream> #include <vector> +#include "Acts/Utilities/Helpers.hpp" void FW::Obj::writeVTN(std::ofstream& stream, @@ -105,6 +107,82 @@ FW::Obj::writePlanarFace(std::ofstream& stream, constructVerticalFaces(stream, fvertex, vsides); } +void +FW::Obj::writeAnnulusDisc(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + unsigned int nSegments, + const Acts::Transform3D& transform, + const std::vector<Acts::Vector2D>& vertices, + double thickness) +{ + + unsigned int cvc = vtnCounter.vcounter; + + std::vector<Acts::Vector3D> gVertices; + // Write the vertices + for (auto& v : vertices) { + gVertices.push_back(transform * Acts::Vector3D(v.x(), v.y(), 0.)); + } + + // Complete if there are segments defined for a bow + if (nSegments > 1) { + + /// Fill the vertices in betwen + auto fillBow + = [&](const Acts::Vector3D& first, + const Acts::Vector3D& second) -> std::vector<Acts::Vector3D> { + // The completed list of vertices + std::vector<Acts::Vector3D> completed3D; + + double oseg = 1. / nSegments; + double phif = Acts::VectorHelpers::phi(first); + double phis = Acts::VectorHelpers::phi(second); + double phiD = (phis - phif); + + if (std::abs(phiD) > M_PI and phif * phis < 0.) { + phiD += phiD < 0. ? 2 * M_PI : -2 * M_PI; + } + + double rf = Acts::VectorHelpers::perp(first); + double rs = Acts::VectorHelpers::perp(second); + double zf = first.z(); + double zs = second.z(); + + phiD *= oseg; + double rD = (rs - rf) * oseg; + double zD = (zs - zf) * oseg; + + for (unsigned int is = 0; is < nSegments + 1; ++is) { + double r = rf + is * rD; + double phi = phif + is * phiD; + double z = zf + is * zD; + completed3D.push_back(Acts::Vector3D(r * cos(phi), r * sin(phi), z)); + } + // Reassing the global points + return completed3D; + }; + // Fill the bows + auto completedBow1 = fillBow(gVertices[0], gVertices[1]); + auto completedBow2 = fillBow(gVertices[2], gVertices[3]); + // Clear the vertices + gVertices = completedBow1; + gVertices.insert( + gVertices.end(), completedBow2.begin(), completedBow2.end()); + } + + // Write the vertices + for (const auto& gv : gVertices) { + writeVTN(stream, vtnCounter, scalor, gv, "v"); + } + // Write the faces + stream << "f"; + for (unsigned int iv = 0; iv < gVertices.size(); ++iv) { + stream << " " << cvc + iv + 1; + } + stream << std::endl; +} + void FW::Obj::writeTube(std::ofstream& stream, VtnCounter& vtnCounter, diff --git a/Plugins/Obj/src/ObjSurfaceWriter.cpp b/Plugins/Obj/src/ObjSurfaceWriter.cpp index d9506661c..472013dc7 100644 --- a/Plugins/Obj/src/ObjSurfaceWriter.cpp +++ b/Plugins/Obj/src/ObjSurfaceWriter.cpp @@ -14,6 +14,7 @@ #include <Acts/Geometry/GeometryID.hpp> #include <Acts/Geometry/Layer.hpp> +#include <Acts/Surfaces/AnnulusBounds.hpp> #include <Acts/Surfaces/CylinderBounds.hpp> #include <Acts/Surfaces/PlanarBounds.hpp> #include <Acts/Surfaces/RadialBounds.hpp> @@ -31,7 +32,6 @@ FW::Obj::ObjSurfaceWriter::ObjSurfaceWriter( } else if (!m_cfg.outputStream) { throw std::invalid_argument("Missing output stream"); } - // Write down the file prefix (*(m_cfg.outputStream)) << m_cfg.filePrefix << '\n'; } @@ -51,20 +51,19 @@ FW::Obj::ObjSurfaceWriter::write(const AlgorithmContext& context, ACTS_DEBUG(">>Obj: Writer for Surface object called."); auto scalor = m_cfg.outputScalor; - // let's get the bounds & the transform - const Acts::SurfaceBounds& surfaceBounds = surface.bounds(); - auto sTransform = surface.transform(context.geoContext); - // dynamic_cast to PlanarBounds - const Acts::PlanarBounds* planarBounds - = dynamic_cast<const Acts::PlanarBounds*>(&surfaceBounds); - // only continue if the cast worked + // Bounds and transform defines the full 3D object + const auto& surfaceBounds = surface.bounds(); + auto sTransform = surface.transform(context.geoContext); + + // Dynamic_cast to PlanarBounds + auto planarBounds = dynamic_cast<const Acts::PlanarBounds*>(&surfaceBounds); if (planarBounds && m_cfg.outputSensitive) { ACTS_VERBOSE(">>Obj: Writing out a PlaneSurface"); - // set the precision - just to be sure + // Set the precision (*(m_cfg.outputStream)) << '\n'; (*(m_cfg.outputStream)) << std::setprecision(m_cfg.outputPrecision); - // get the vertices + // Get the vertices auto planarVertices = planarBounds->vertices(); // loop over the vertices std::vector<Acts::Vector3D> vertices; @@ -92,9 +91,26 @@ FW::Obj::ObjSurfaceWriter::write(const AlgorithmContext& context, (*(m_cfg.outputStream)) << '\n'; } - // check if you have layer and check what your have - // dynamic cast to CylinderBounds work the same - const Acts::CylinderBounds* cylinderBounds + // Dynamic cast to AnnulusBounds + auto annulusBounds = dynamic_cast<const Acts::AnnulusBounds*>(&surfaceBounds); + if (annulusBounds != nullptr and m_cfg.outputSensitive) { + ACTS_VERBOSE(">>Obj: Writing out a Annulus bounded disc"); + // Set the precision + (*(m_cfg.outputStream)) << '\n'; + (*(m_cfg.outputStream)) << std::setprecision(m_cfg.outputPrecision); + // Get the vertices + auto annulusVertices = annulusBounds->vertices(); + Obj::writeAnnulusDisc(*(m_cfg.outputStream), + m_vtnCounter, + scalor, + 3, + sTransform, + annulusVertices); + (*(m_cfg.outputStream)) << '\n'; + } + + // Dynamic cast to CylinderBounds work the same + auto cylinderBounds = dynamic_cast<const Acts::CylinderBounds*>(&surfaceBounds); if (cylinderBounds && m_cfg.outputLayerSurface) { ACTS_VERBOSE(">>Obj: Writing out a CylinderSurface with r = " @@ -115,7 +131,7 @@ FW::Obj::ObjSurfaceWriter::write(const AlgorithmContext& context, (*(m_cfg.outputStream)) << '\n'; } - ////dynamic cast to RadialBounds or disc bounds work the same + /// Dynamic cast to RadialBounds or disc bounds work the same const Acts::RadialBounds* radialBounds = dynamic_cast<const Acts::RadialBounds*>(&surfaceBounds); if (radialBounds && m_cfg.outputLayerSurface) { diff --git a/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp b/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp index 3ce37ea20..0daae73fc 100644 --- a/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp +++ b/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp @@ -74,8 +74,9 @@ FW::Obj::ObjTrackingGeometryWriter::write(const AlgorithmContext& context, if (!surfaceWriter) return; // layer prefix surfaceWriter->write(m_cfg.layerPrefix); - // try to write the material surface as well - if (layer->surfaceRepresentation().surfaceMaterial()) { + // Try to write the material surface as well + if (layer->surfaceRepresentation().surfaceMaterial() + or layer->surfaceArray() == nullptr) { surfaceWriter->write(context, layer->surfaceRepresentation()); } // the the approaching surfaces and check if they have material diff --git a/external/acts-core b/external/acts-core index 8a6f7485e..325dff6d4 160000 --- a/external/acts-core +++ b/external/acts-core @@ -1 +1 @@ -Subproject commit 8a6f7485eb2b4674ec1073fb5dd58ff5d8547301 +Subproject commit 325dff6d42223fcc092256b56ebe9f855570a715 -- GitLab