diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 98ea1231e488ed108f4c8e315bf5f8f91c25593e..81bda5cd15af9625b23bb2d9e2381ad9d1dffee6 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -375,6 +375,7 @@ namespace dd4hep { enum ReplicationAxis { REPLICATED = 1UL << 4, PARAMETERIZED = 1UL << 5, + Undefined = 1UL << 7, X_axis = 1UL << 8, Y_axis = 1UL << 9, Z_axis = 1UL << 10, diff --git a/DDCore/include/Parsers/detail/Dimension.h b/DDCore/include/Parsers/detail/Dimension.h index 98b4ad2d709bc95b71dd647e0cfc4fafbddf0f2d..6ccb6819d3c06b8c2b1de8c841f2b06635400fe8 100644 --- a/DDCore/include/Parsers/detail/Dimension.h +++ b/DDCore/include/Parsers/detail/Dimension.h @@ -102,13 +102,13 @@ namespace dd4hep { double gamma() const; /// Access rotation constants: angle double gamma(double default_value) const; - /// Access rotation constants: angle + /// Access rotation constants: delta double delta() const; - /// Access rotation constants: angle + /// Access rotation constants: delta double delta(double default_value) const; - /// Access rotation constants: angle + /// Access rotation constants: epsilon double epsilon() const; - /// Access rotation constants: angle + /// Access rotation constants: epsilon double epsilon(double default_value) const; /// Access rotation constants: theta double theta() const; @@ -191,9 +191,13 @@ namespace dd4hep { double c() const; /// Access parameters: c double c(double default_value) const; - ///Access parameters: distance + /// Access rotation constants: dist + double dist() const; + /// Access rotation constants: dist + double dist(double default_value) const; + /// Access parameters: distance double distance() const; - ///Access parameters: distance + /// Access parameters: distance double distance(double default_value) const; /// Access parameters: fraction double fraction() const; @@ -525,6 +529,8 @@ namespace dd4hep { /// Access attribute values: offset double offset(double default_value) const; + /// Access attribute values: count + int count() const; /// Access attribute values: item int item() const; /// Access attribute values: items @@ -575,6 +581,8 @@ namespace dd4hep { double phi_tilt() const; /// Access attribute values: nphi int nphi() const; + /// Access attribute values: replicate + int replicate() const; /// Access attribute values: rc double rc() const; diff --git a/DDCore/include/Parsers/detail/Dimension.imp b/DDCore/include/Parsers/detail/Dimension.imp index f22e6cc03025a375febeae6553b6447ffc4e4620..e9c27e70326b0050b3860579370f3f23f3cf2ff8 100644 --- a/DDCore/include/Parsers/detail/Dimension.imp +++ b/DDCore/include/Parsers/detail/Dimension.imp @@ -83,6 +83,7 @@ XML_ATTR_ACCESSOR(double, inner_z) XML_ATTR_ACCESSOR_DOUBLE(a) XML_ATTR_ACCESSOR_DOUBLE(b) XML_ATTR_ACCESSOR_DOUBLE(c) +XML_ATTR_ACCESSOR_DOUBLE(dist) XML_ATTR_ACCESSOR_DOUBLE(distance) XML_ATTR_ACCESSOR_DOUBLE(g) XML_ATTR_ACCESSOR_DOUBLE(A) @@ -151,7 +152,9 @@ XML_ATTR_ACCESSOR(double, gap) XML_ATTR_ACCESSOR(double, z_length) XML_ATTR_ACCESSOR(double, zhalf) XML_ATTR_ACCESSOR(double, phi_tilt) +XML_ATTR_ACCESSOR(int, count) XML_ATTR_ACCESSOR(int, nphi) +XML_ATTR_ACCESSOR(int, replicate) XML_ATTR_ACCESSOR(double, rc) XML_ATTR_ACCESSOR(int, nz) XML_ATTR_ACCESSOR(int, key) diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index 0e088210ff1cf9482b4a79812a6554b7194e8508..89d4ec706704eb648d2a89f1af67c6b056ef75a9 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -52,6 +52,7 @@ UNICODE (attribute); UNICODE (attributes); UNICODE (aunit); UNICODE (author); +UNICODE (axis); UNICODE (b); UNICODE (B); @@ -64,7 +65,6 @@ UNICODE (box); UNICODE (build); UNICODE (c); -UNICODE (distance); UNICODE (C); UNICODE (calorimeter); UNICODE (cartesian_grid_xy); @@ -95,6 +95,7 @@ UNICODE (connected); UNICODE (cons); UNICODE (constant); UNICODE (correction); +UNICODE (count); UNICODE (create); UNICODE (crossing_angle); UNICODE (cut); @@ -121,6 +122,8 @@ UNICODE (dipole_coeff); UNICODE (disk); UNICODE (disks); UNICODE (display); +UNICODE (dist); +UNICODE (distance); UNICODE (division); UNICODE (dr); UNICODE (drawing_style); @@ -402,6 +405,7 @@ UNICODE (region); UNICODE (regions); UNICODE (regionref); UNICODE (repeat); +UNICODE (replicate); UNICODE (rhi); UNICODE (ring); UNICODE (rlo); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 00a38f6f4f148ac2504802d575492716819b3c85..582428c600d460ab03d9812eba783550bafdd990 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -1001,6 +1001,8 @@ PlacedVolume Volume::paramVolume3D(const Transform3D& start, data->params->addref(); data->params->flags = PARAMETERIZED; data->params->start = start; + data->params->trafo1D.first = trafo_1; + data->params->trafo1D.second = count_1; data->params->trafo2D.first = trafo_2; data->params->trafo2D.second = count_2; data->params->trafo3D.first = trafo_3; diff --git a/DDG4/examples/initAClick.C b/DDG4/examples/initAClick.C index 77d8c2e8bbed07a4acd73a04532b5516af31d157..f712a13ee38e8220131a358197512c9e686345bd 100644 --- a/DDG4/examples/initAClick.C +++ b/DDG4/examples/initAClick.C @@ -84,21 +84,22 @@ int initAClick(const char* command=0) { #ifndef __APPLE__ libs += " -lCore -lMathCore -pthread -lm -ldl -rdynamic"; #endif - libs += " " +dd4hep+"/lib/libDD4hepGaudiPluginMgr." + ext; - libs += " " +dd4hep+"/lib/libDDCore."+ ext; - libs += " " +dd4hep+"/lib/libDDG4."+ ext; + //libs += " " +dd4hep+"/lib/libDD4hepGaudiPluginMgr." + ext; + //libs += " " +dd4hep+"/lib/libDDCore."+ ext; + //libs += " " +dd4hep+"/lib/libDDG4."+ ext; + libs += " -L" +dd4hep+"/lib "; // -lDD4hepGaudiPluginMgr -lDDCore -lDDG4"; #ifdef __APPLE__ - gSystem->Load("libDD4hepGaudiPluginMgr"); + int ret = gSystem->Load("libDD4hepGaudiPluginMgr"); +#else + //int ret = gSystem->Load("libDDG4Plugins"); + int ret = gSystem->Load("libDD4hepGaudiPluginMgr"); #endif gSystem->AddIncludePath(inc.c_str()); gSystem->AddLinkedLibs(libs.c_str()); std::cout << "+++ Includes: " << gSystem->GetIncludePath() << std::endl; std::cout << "+++ Linked libs:" << gSystem->GetLinkedLibs() << std::endl; - int ret = 0; // gSystem->Load("libDDG4Plugins"); - if ( 0 == ret ) { - if ( command ) { - processCommand(command, true); - } + if ( command ) { + processCommand(command, true); } return ret; } diff --git a/DDG4/include/DDG4/Geant4Helpers.h b/DDG4/include/DDG4/Geant4Helpers.h index 827e07e1d20aec86811391fa10a190b83a1bfa62..791017bb0a9590733928cc01da71413e7e465388 100644 --- a/DDG4/include/DDG4/Geant4Helpers.h +++ b/DDG4/include/DDG4/Geant4Helpers.h @@ -69,8 +69,15 @@ namespace dd4hep { /// These conversions automatically apply the conversion from CM to MM! - G4Transform3D g4Transform(const double translation[]); - G4Transform3D g4Transform(const double translation[], const double rotation[]); + void g4Transform(const double* translation, const double* rotation, G4Transform3D& transform); + void g4Transform(const Position& pos, const Rotation3D& rot, G4Transform3D& transform); + void g4Transform(const double* translation, G4Transform3D& transform); + void g4Transform(const Transform3D& matrix, G4Transform3D& transform); + void g4Transform(const TGeoMatrix* matrix, G4Transform3D& transform); + void g4Transform(const TGeoMatrix& matrix, G4Transform3D& transform); + + G4Transform3D g4Transform(const double* translation); + G4Transform3D g4Transform(const double* translation, const double* rotation); G4Transform3D g4Transform(const Transform3D& matrix); G4Transform3D g4Transform(const Position& pos, const Rotation3D& rot); diff --git a/DDG4/include/DDG4/Geant4PlacementParameterisation.h b/DDG4/include/DDG4/Geant4PlacementParameterisation.h index d9c45b42689b99bc303b8d2da9f4e9d0761e5e7b..641e20e8eb3ca8257f5d18e42846517ecc23aa02 100644 --- a/DDG4/include/DDG4/Geant4PlacementParameterisation.h +++ b/DDG4/include/DDG4/Geant4PlacementParameterisation.h @@ -62,18 +62,22 @@ namespace dd4hep { using Translations = std::vector<G4ThreeVector>; using Dimensions = std::vector<Dimension>; - /// Setup parameters + /// Setup parameters: Reference to the DD4hep placement handle + PlacedVolume m_placement; + /// Setup parameters: Reference to the DD4hep placement parameters + const Parameters& m_params; + /// Setup parameters: Initial parameterisation position Dimension m_start { }; + /// Setup parameters: Dimensional parameter setup Dimensions m_dimensions { }; - EAxis m_axis { kUndefined }; + /// Axis definition + EAxis m_axis { kUndefined }; + /// Total number of parameterized cells + size_t m_num_cells { 0UL }; /// Optimization flag for simple parameteristions bool m_have_rotation { false }; - /// Reference to the DD4hep placement handle - PlacedVolume m_placement; - const Parameters& m_params; - /// Cached rotations and translations for complex parameterisations mutable Rotations m_rotations; mutable Translations m_translations; diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index 794693e6f8dc5e4b5045b5c5115aacbc419a7337..c86bd3e7fb29975d3730b9e2010851c33227bba5 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -31,8 +31,7 @@ #include "Geant4ShapeConverter.h" // ROOT includes -#include <TMath.h> -#include <TROOT.h> +#include <TClass.h> #include <TGeoBoolNode.h> // Geant4 include files @@ -53,7 +52,6 @@ #include <G4Region.hh> #include <G4Element.hh> -#include <G4Element.hh> #include <G4Isotope.hh> #include <G4Material.hh> #include <G4UserLimits.hh> @@ -594,7 +592,8 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c } if ( matrix->IsRotation() ) { - G4Transform3D transform(g4Transform(matrix)); + G4Transform3D transform; + g4Transform(matrix, transform); if (oper == TGeoBoolNode::kGeoSubtraction) solid = new G4SubtractionSolid(name, left, right, transform); else if (oper == TGeoBoolNode::kGeoUnion) @@ -728,8 +727,9 @@ void* Geant4Converter::handleAssembly(const string& name, const TGeoNode* node) TGeoNode* dau = mot_vol->GetNode(i); TGeoVolume* dau_vol = dau->GetVolume(); TGeoMatrix* tr = dau->GetMatrix(); - G4Transform3D transform(g4Transform(tr)); + G4Transform3D transform; + g4Transform(tr, transform); if ( is_left_handed(tr) ) { G4Scale3D scale; G4Rotate3D rot; @@ -808,9 +808,10 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) bool node_is_reflected = is_left_handed(tr); bool node_is_assembly = vol->IsA() == TGeoVolumeAssembly::Class(); bool mother_is_assembly = mot_vol ? mot_vol->IsA() == TGeoVolumeAssembly::Class() : false; - G4Transform3D transform(g4Transform(tr)); + G4Transform3D transform; Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(mot_vol); + g4Transform(tr, transform); if ( mother_is_assembly ) { // // Mother is an assembly: @@ -871,6 +872,15 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) else except("Geant4Converter", "++ Replication around unknown axis is not implemented. flags: %16X", flags); + auto* g4pv = new G4PVReplica(name, // its name + g4vol, // its logical volume + g4mot, // its mother (logical) volume + axis, // its replication axis + count, // Number of replicas + width, // Distanve between 2 replicas + offset); // Placement offset in axis direction + pvPlaced = { g4pv, nullptr }; +#if 0 pvPlaced = G4ReflectionFactory::Instance()->Replicate(name, // its name g4vol, // its logical volume @@ -881,6 +891,7 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) offset); // Placement offset in axis direction /// Update replica list to avoid additional conversions... auto* g4pv = pvPlaced.second ? pvPlaced.second : pvPlaced.first; +#endif for( auto& handle : pv_data->params->placements ) info.g4Placements[handle.ptr()] = g4pv; } @@ -899,12 +910,12 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) } else { pvPlaced = - G4ReflectionFactory::Instance()->Place(transform, // no rotation - name, // its name - g4vol, // its logical volume - g4mot, // its mother (logical) volume - false, // no boolean operations - copy, // its copy number + G4ReflectionFactory::Instance()->Place(transform, // no rotation + name, // its name + g4vol, // its logical volume + g4mot, // its mother (logical) volume + false, // no boolean operations + copy, // its copy number checkOverlaps); } printout(debugReflections||debugPlacements ? ALWAYS : lvl, "Geant4Converter", diff --git a/DDG4/src/Geant4Helpers.cpp b/DDG4/src/Geant4Helpers.cpp index 7b905b86747e44266bab7a4de53fb91a9d5b53b4..5e5f3fcd05972cf3f4407732b26d786e8fff5a5b 100644 --- a/DDG4/src/Geant4Helpers.cpp +++ b/DDG4/src/Geant4Helpers.cpp @@ -26,10 +26,13 @@ namespace { /// Overload to access protected constructor struct MyTransform3D : public G4Transform3D { - MyTransform3D(double XX, double XY, double XZ, double DX, double YX, double YY, double YZ, double DY, double ZX, double ZY, - double ZZ, double DZ) +#if 0 + MyTransform3D(double XX, double XY, double XZ, double DX, + double YX, double YY, double YZ, double DY, + double ZX, double ZY, double ZZ, double DZ) : G4Transform3D(XX, XY, XZ, DX, YX, YY, YZ, DY, ZX, ZY, ZZ, DZ) { } +#endif MyTransform3D(const double* t, const double* r) : G4Transform3D(r[0],r[1],r[2],t[0]*CM_2_MM,r[3],r[4],r[5],t[1]*CM_2_MM,r[6],r[7],r[8],t[2]*CM_2_MM) { } @@ -42,12 +45,9 @@ namespace { class MyG4RotationMatrix : public G4RotationMatrix { public: MyG4RotationMatrix() : G4RotationMatrix() {} - MyG4RotationMatrix(const double* r) - : G4RotationMatrix(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8]) { + MyG4RotationMatrix(const double* r) : G4RotationMatrix(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8]) { } }; - const double identity[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; - } G4RotationMatrix dd4hep::sim::g4Rotation(const TGeoMatrix* matrix) { @@ -76,15 +76,22 @@ G4RotationMatrix dd4hep::sim::g4Rotation(const RotationZYX& rot) { return g4Rotation(Rotation3D(rot)); } - G4Transform3D dd4hep::sim::g4Transform(const double translation[]) { return MyTransform3D(translation); } -G4Transform3D dd4hep::sim::g4Transform(const double translation[], const double rotation[]) { +G4Transform3D dd4hep::sim::g4Transform(const double* translation, const double* rotation) { return MyTransform3D(translation, rotation); } +void dd4hep::sim::g4Transform(const double translation[], G4Transform3D& transform) { + transform = MyTransform3D(translation); +} + +void dd4hep::sim::g4Transform(const double* translation, const double* rotation, G4Transform3D& transform) { + transform = MyTransform3D(translation, rotation); +} + G4Transform3D dd4hep::sim::g4Transform(const TGeoMatrix& matrix) { return g4Transform(&matrix); } @@ -95,6 +102,16 @@ G4Transform3D dd4hep::sim::g4Transform(const TGeoMatrix* matrix) { : g4Transform(matrix->GetTranslation()); } +void dd4hep::sim::g4Transform(const TGeoMatrix* matrix, G4Transform3D& transform) { + matrix->IsRotation() + ? g4Transform(matrix->GetTranslation(), matrix->GetRotationMatrix(), transform) + : g4Transform(matrix->GetTranslation(), transform); +} + +void dd4hep::sim::g4Transform(const TGeoMatrix& matrix, G4Transform3D& transform) { + g4Transform(&matrix, transform); +} + G4Transform3D dd4hep::sim::g4Transform(const TGeoTranslation& translation, const TGeoRotation& rotation) { return g4Transform(&translation, &rotation); } @@ -111,6 +128,12 @@ G4Transform3D dd4hep::sim::g4Transform(const Position& pos, const Rotation3D& ro return g4Transform(t, r); } +void dd4hep::sim::g4Transform(const Position& pos, const Rotation3D& rot, G4Transform3D& transform) { + double r[9], t[3] = {pos.X(), pos.Y(), pos.Z()}; + rot.GetComponents(r, r+9); + g4Transform(t, r, transform); +} + G4Transform3D dd4hep::sim::g4Transform(const Position& pos, const RotationZYX& rot) { return g4Transform(pos, Rotation3D(rot)); } @@ -122,6 +145,13 @@ G4Transform3D dd4hep::sim::g4Transform(const Transform3D& matrix) { return g4Transform(pos, rot); } +void dd4hep::sim::g4Transform(const Transform3D& matrix, G4Transform3D& transform) { + Position pos; + Rotation3D rot; + matrix.GetDecomposition(rot, pos); + g4Transform(pos, rot, transform); +} + /// Generate parameterised placements in 2 dimension according to transformation delta G4Transform3D dd4hep::sim::generate_placements(const G4Transform3D& start, diff --git a/DDG4/src/Geant4PlacementParameterisation.cpp b/DDG4/src/Geant4PlacementParameterisation.cpp index 3261c0485caf6a375105cfcff5e61dc5792069f9..429174d533af36eedc286369b01cd4850d7cbc73 100644 --- a/DDG4/src/Geant4PlacementParameterisation.cpp +++ b/DDG4/src/Geant4PlacementParameterisation.cpp @@ -20,39 +20,45 @@ // Geant4 include files #include <G4Transform3D.hh> - /// Initializing constructor +/// Initializing constructor dd4hep::sim::Geant4PlacementParameterisation::Geant4PlacementParameterisation(PlacedVolume pv) : G4VPVParameterisation(), m_placement(pv), m_params(*pv.data()->params) { + G4Transform3D tr; auto& dim = m_dimensions; - G4Transform3D start = g4Transform(m_params.start); - G4Transform3D tr(g4Transform(m_params.trafo1D.first)); - m_start = {tr, 0UL}; - m_have_rotation = false; + g4Transform(m_params.start, m_start.delta); + m_start.translation = m_start.delta.getTranslation(); + + g4Transform(m_params.trafo1D.first, tr); dim.emplace_back(Dimension(tr, m_params.trafo1D.second)); - m_have_rotation |= dim.back().delta.getRotation().isIdentity(); + + m_have_rotation = false; + m_have_rotation |= !dim.back().delta.getRotation().isIdentity(); + m_num_cells = m_params.trafo1D.second; if ( m_params.trafo2D.second > 0 ) { - tr = g4Transform(m_params.trafo2D.first); + g4Transform(m_params.trafo2D.first, tr); dim.emplace_back(Dimension(tr, m_params.trafo2D.second)); - m_have_rotation |= dim.back().delta.getRotation().isIdentity(); + m_have_rotation |= !dim.back().delta.getRotation().isIdentity(); + m_num_cells *= m_params.trafo2D.second; } if ( m_params.trafo3D.second > 0 ) { - tr = g4Transform(m_params.trafo3D.first); + g4Transform(m_params.trafo3D.first, tr); dim.emplace_back(Dimension(tr, m_params.trafo3D.second)); - m_have_rotation |= dim.back().delta.getRotation().isIdentity(); + m_have_rotation |= !dim.back().delta.getRotation().isIdentity(); + m_num_cells *= m_params.trafo3D.second; } if ( m_have_rotation ) { auto callback = std::bind(&Geant4PlacementParameterisation::operator(), - *this, std::placeholders::_1); + this, std::placeholders::_1); if ( dim.size() == 1 ) - generate_placements(start, + generate_placements(m_start.delta, dim[0].delta, dim[0].count, callback); else if ( dim.size() == 2 ) - generate_placements(start, + generate_placements(m_start.delta, dim[0].delta, dim[0].count, dim[1].delta, dim[1].count, callback); else if ( dim.size() == 3 ) - generate_placements(start, + generate_placements(m_start.delta, dim[0].delta, dim[0].count, dim[1].delta, dim[1].count, dim[2].delta, dim[2].count, callback); @@ -61,37 +67,35 @@ dd4hep::sim::Geant4PlacementParameterisation::Geant4PlacementParameterisation(Pl /// Access number of replicas std::size_t dd4hep::sim::Geant4PlacementParameterisation::count() const { - std::size_t ncell = 1; - for(const auto& d : m_dimensions) ncell *= d.count; - return ncell; + return m_num_cells; } /// Callback to store resulting rotation void dd4hep::sim::Geant4PlacementParameterisation::operator()(const G4Transform3D& transform) { - m_translations.emplace_back(transform.getTranslation()); + this->m_translations.emplace_back(transform.getTranslation()); if ( this->m_have_rotation ) { G4RotationMatrix rot = transform.inverse().getRotation(); - m_rotations.emplace_back(rot); + this->m_rotations.emplace_back(rot); } } /// G4VPVParameterisation overload: Callback to place sub-volumes void dd4hep::sim::Geant4PlacementParameterisation::ComputeTransformation(const G4int copy, G4VPhysicalVolume *pv) const { const auto& dim = m_dimensions; - std::size_t nd = dim.size(); + std::size_t nd = dim.size(); if ( !m_have_rotation ) { G4ThreeVector tra = m_start.translation; if ( nd >= 1 ) { - std::size_t dim1 = nd == 1 ? copy : (nd == 2 ? copy%dim[1].count : (nd == 3 ? copy%(dim[1].count*dim[2].count) : 0)); - tra = dim[0].translation * dim1; + std::size_t d1 = (nd == 1) ? copy : (nd >= 2 ? copy%dim[1].count : 0); + tra = tra + (dim[0].translation * d1); } if ( nd >= 2 ) { - std::size_t dim2 = nd == 3 ? copy%dim[2].count / dim[0].count : (nd==2 ? copy / dim[0].count : 0); - tra = tra + dim[1].translation * dim2; + std::size_t d2 = (nd == 2) ? copy / dim[0].count : (nd >= 3 ? copy%dim[2].count / dim[0].count : 0); + tra = tra + (dim[1].translation * d2); } if ( nd >= 3 ) { - std::size_t dim3 = nd == 3 ? copy / (dim[0].count*dim[1].count) : 0; - tra = tra + dim[2].translation * dim3; + std::size_t d3 = (nd == 3) ? copy / (dim[0].count*dim[1].count) : 0; + tra = tra + (dim[2].translation * d3); } pv->SetTranslation(tra); return; diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt index b16248d1b16e5fac19c368d46486ebb659aba466..584584ceb2eccce32bca822250be6b9d79e55a71 100644 --- a/examples/ClientTests/CMakeLists.txt +++ b/examples/ClientTests/CMakeLists.txt @@ -276,6 +276,7 @@ dd4hep_add_test_reg( ClientTests_Check_reflection_matrices # foreach (test Assemblies BoxTrafos CaloEndcapReflection IronCylinder LheD_tracker MagnetFields MiniTel SectorBarrelCalorimeter SiliconBlock NestedSimple NestedDetectors + ParamVolume1D ParamVolume2D ParamVolume3D MultiCollections MultiSegmentations ) # Test materials in volumes. Test here the proper access to the materials from the volumes, @@ -310,6 +311,7 @@ endforeach() # MaterialTester no geometry # SectorBarrelCalorimeter is bad foreach (test Assemblies BoxTrafos CaloEndcapReflection LheD_tracker MagnetFields MiniTel SiliconBlock + ParamVolume1D ParamVolume2D ParamVolume3D NestedSimple NestedDetectors MultiCollections ) # # Test material scans in [origine to 10 meters in y] @@ -435,12 +437,23 @@ if (DD4HEP_USE_GEANT4) else() # Geant4 full simulation checks of multi-collection/segmentation detectors dd4hep_print("|++> Geant4 fast simulation tests enabled for Geant4 ${Geant4_VERSION}") - foreach(script SiliconBlockGFlash SiliconBlockFastSim ) + foreach(script SiliconBlockGFlash SiliconBlockFastSim) dd4hep_add_test_reg( ClientTests_sim_${script}_LONGTEST COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" EXEC_ARGS ${Python_EXECUTABLE} ${ClientTestsEx_INSTALL}/scripts/${script}.py -batch -events 2 + -geometry ${ClientTestsEx_INSTALL}/compact/${script}.xml -batch -events 2 REGEX_PASS "Event 1 Begin event action. Access event related information" REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" ) endforeach(script) + # + foreach(script ParamVolume1D ParamVolume2D ParamVolume3D) + dd4hep_add_test_reg( ClientTests_sim_${script}_LONGTEST + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" + EXEC_ARGS ${Python_EXECUTABLE} ${ClientTestsEx_INSTALL}/scripts/ParamVolume.py + -geometry ${script}.xml -batch -events 2 + REGEX_PASS "Event 1 Begin event action. Access event related information" + REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" ) + endforeach(script) + # endif() endif(DD4HEP_USE_GEANT4) diff --git a/examples/ClientTests/compact/ParamVolume1D.xml b/examples/ClientTests/compact/ParamVolume1D.xml index 7d8937cbe7b2aed69f8240e91a34093e0599e8f8..5e2b900f1faf6ba8790cf64c5b4e5909f04c8822 100644 --- a/examples/ClientTests/compact/ParamVolume1D.xml +++ b/examples/ClientTests/compact/ParamVolume1D.xml @@ -41,7 +41,7 @@ </limits> <detectors> - <detector id="1" name="Param1D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits"> + <detector id="1" name="Param1D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits1" limits="param_limits"> <box x="20*cm" y="15*cm" z="150*cm" material="Air"/> <param x="15*cm" y="10*cm" z="2*cm" material="Iron" vis="VisibleRed" limits="param_limits"> <transformation> @@ -58,7 +58,8 @@ <position x="0" y="0" z="175*cm"/> <rotation x="0" y="0" z="0"/> </detector> - <detector id="2" name="Param1D_2" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits"> + + <detector id="2" name="Param1D_2" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits2" limits="param_limits"> <box x="20*cm" y="100*cm" z="15*cm" material="Air"/> <param x="15*cm" y="2*cm" z="10*cm" material="Iron" vis="VisibleBlue" limits="param_limits"> <transformation> @@ -75,7 +76,8 @@ <position x="0" y="130*cm" z="0*cm"/> <rotation x="0" y="0" z="0"/> </detector> - <detector id="3" name="Param1D_3" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits"> + + <detector id="3" name="Param1D_3" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits3" limits="param_limits"> <box x="100*cm" y="20*cm" z="15*cm" material="Air"/> <param x="2*cm" y="15*cm" z="10*cm" material="Iron" vis="VisibleYellow" limits="param_limits"> <transformation> @@ -93,7 +95,7 @@ <rotation x="0" y="0" z="0"/> </detector> - <detector id="4" name="Param1D_4" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits"> + <detector id="4" name="Param1D_4" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits4" limits="param_limits"> <box x="100*cm" y="20*cm" z="15*cm" material="Air"/> <param x="2*cm" y="15*cm" z="10*cm" material="Iron" vis="VisibleViolet" limits="param_limits"> <transformation> @@ -134,19 +136,19 @@ <readouts> <readout name="Hits1"> <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/> - <id>system:6,x:12:-6,y:24:-6</id> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> </readout> <readout name="Hits2"> <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/> - <id>system:6,x:12:-6,y:24:-6</id> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> </readout> <readout name="Hits3"> <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/> - <id>system:6,x:12:-6,y:24:-6</id> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> </readout> <readout name="Hits4"> <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/> - <id>system:6,side:2,x:12:-6,y:24:-6</id> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> </readout> </readouts> diff --git a/examples/ClientTests/compact/ParamVolume2D.xml b/examples/ClientTests/compact/ParamVolume2D.xml index 037aab00e7c16a5ca6777b87da2c3772930348f2..988e9ee591439431e18588400a9f99266c991d60 100644 --- a/examples/ClientTests/compact/ParamVolume2D.xml +++ b/examples/ClientTests/compact/ParamVolume2D.xml @@ -67,7 +67,7 @@ <readouts> <readout name="Hits1"> <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/> - <id>system:6,x:12:-6,y:24:-6</id> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> </readout> </readouts> diff --git a/examples/ClientTests/compact/ParamVolume3D.xml b/examples/ClientTests/compact/ParamVolume3D.xml index a9229f80cae51e69ff712d9c569ab5356a0d5e0f..5768c06af52d8206df29ca156dc8ebd1c6ce3bf3 100644 --- a/examples/ClientTests/compact/ParamVolume3D.xml +++ b/examples/ClientTests/compact/ParamVolume3D.xml @@ -58,18 +58,18 @@ <transformation> <!-- Parameterisation in dimension 1 with 20 placements --> <dim_x repeat="20"> - <position x="0*cm" y="0*cm" z="10*cm"/> - <rotation x="0" y="0" z="0"/> + <position x="10*cm" y="0*cm" z="0*cm"/> + <rotation x="0" y="0" z="0"/> </dim_x> <!-- Parameterisation in dimension 2 with 20 placements --> <dim_y repeat="20"> <position x="0*cm" y="10*cm" z="0*cm"/> - <rotation x="0" y="0" z="0"/> + <rotation x="0" y="0" z="0"/> </dim_y> <!-- Parameterisation in dimension 3 with 20 placements --> <dim_z repeat="20"> - <position x="10*cm" y="0*cm" z="0*cm"/> - <rotation x="0" y="0" z="0"/> + <position x="0*cm" y="0*cm" z="10*cm"/> + <rotation x="0" y="0" z="0"/> </dim_z> </transformation> </param> diff --git a/examples/ClientTests/compact/ReplicateVolume.xml b/examples/ClientTests/compact/ReplicateVolume.xml new file mode 100644 index 0000000000000000000000000000000000000000..a42f2cce8340806906a8912ee559b49ce2b4a932 --- /dev/null +++ b/examples/ClientTests/compact/ReplicateVolume.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd> + <!-- #========================================================================== + # AIDA Detector description implementation + #========================================================================== + # Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) + # All rights reserved. + # + # For the licensing terms see $DD4hepINSTALL/LICENSE. + # For the list of contributors see $DD4hepINSTALL/doc/CREDITS. + # + #========================================================================== + --> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + + <define> + <constant name="world_size" value="30*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + </define> + + <display> + <vis name="Invisible" showDaughters="false" visible="false"/> + <vis name="InvisibleWithChildren" showDaughters="true" visible="false"/> + <vis name="VisibleRed" r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="VisibleBlue" r="0.0" g="0.0" b="1.0" showDaughters="false" visible="true"/> + <vis name="VisibleYellow" r="1.0" g="1.0" b="0.0" showDaughters="false" visible="true"/> + <vis name="VisibleViolet" r="1.0" g="0.0" b="1.0" showDaughters="false" visible="true"/> + <vis name="VisibleGreen" alpha="0.1" r="0.0" g="1.0" b="0.0" drawingStyle="solid" lineStyle="solid" showDaughters="true" visible="true"/> + </display> + + <limits> + <limitset name="param_limits"> + <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> + </limitset> + </limits> + + <detectors> + <detector id="1" name="Param3D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits3D" limits="param_limits"> + <!-- Mother volume dimensions --> + <box x="120*cm" y="120*cm" z="120*cm" material="Air"/> + <!-- Mother volume placement in the world --> + <position x="0*cm" y="0*cm" z="-120*cm"/> + <rotation x="0" y="0" z="0"/> + + <!-- Parameterisation arguments --> + <param x="15*cm" y="10*cm" z="2*cm" material="Iron" vis="VisibleRed" limits="param_limits"> + <start> + <!-- Parameterisation start position in the mother volume frame --> + <position x="0*cm" y="0*cm" z="0*cm"/> + <rotation x="0" y="0" z="0"/> + </start> + <replicate count="1" distance="10*cm" start="0*cm" axis="z"/> + </param> + </detector> + </detectors> + + <readouts> + <readout name="Hits3D"> + <segmentation type="CartesianGridXY" grid_size_x="1*mm" grid_size_y="1*mm"/> + <id>system:6,volume:16,x:32:-6,y:48:-6</id> + </readout> + </readouts> + + <fields> + <field name="GlobalSolenoid" type="solenoid" + inner_field="5.0*tesla" + outer_field="-1.5*tesla" + zmax="2*m" + outer_radius="3*m"> + </field> + </fields> + +</lccdd> diff --git a/examples/ClientTests/src/ParamVolume_geo.cpp b/examples/ClientTests/src/ParamVolume_geo.cpp index 123936f38c895b5077c40e15f48bf9bd6d7467e4..79492220a506c0b4b8e9d0929178889b74a82803 100644 --- a/examples/ClientTests/src/ParamVolume_geo.cpp +++ b/examples/ClientTests/src/ParamVolume_geo.cpp @@ -44,36 +44,57 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s xml_comp_t x_param = x_det.child(_U(param)); Box box (x_param.x(), x_param.y(), x_param.z()); Volume box_vol (x_det.nameStr()+"_param", box, description.material(x_param.materialStr())); - xml_dim_t x_trafo = x_param.transformation(); - xml_dim_t x_dim_x = x_trafo.child(_U(dim_x)); - Transform3D start, trafo1; PlacedVolume pv; - if ( x_param.hasChild(_U(start)) ) { - start = get_trafo(x_param.child(_U(start))); + if ( x_param.hasChild(_U(replicate)) ) { + xml_dim_t x_repl = x_param.child(_U(replicate)); + std::string ax = x_repl.attr<std::string>(_U(axis)); + Volume::ReplicationAxis axis = Volume::Undefined; + ax[0] = ::toupper(ax[0]); + if ( ax[0] == 'X' ) axis = Volume::X_axis; + if ( ax[0] == 'Y' ) axis = Volume::Y_axis; + if ( ax[0] == 'Z' ) axis = Volume::Z_axis; + if ( ax[0] == 'R' ) axis = Volume::Rho_axis; + if ( ax[0] == 'P' ) axis = Volume::Phi_axis; + pv = envelope_vol.replicate(box_vol, axis, + x_repl.count(), + x_repl.distance(), + x_repl.start()); } + else if ( x_param.hasChild(_U(transformation)) ) { + xml_dim_t x_dim_x, x_dim_y, x_dim_z, x_trafo = x_param.transformation(); + Transform3D start, trafo1, trafo2, trafo3; - trafo1 = get_trafo(x_trafo.child(_U(dim_x))); + if ( x_param.hasChild(_U(start)) ) { + start = get_trafo(x_param.child(_U(start))); + } + if ( x_trafo.hasChild(_U(dim_x)) ) { + x_dim_x = x_trafo.child(_U(dim_x)); + trafo1 = get_trafo(x_dim_x); + } + if ( x_trafo.hasChild(_U(dim_y)) ) { + x_dim_y = x_trafo.child(_U(dim_y)); + trafo2 = get_trafo(x_dim_y); + } + if ( x_trafo.hasChild(_U(dim_z)) ) { + x_dim_z = x_trafo.child(_U(dim_z)); + trafo3 = get_trafo(x_dim_z); + } - if ( x_trafo.hasChild(_U(dim_y)) && x_trafo.hasChild(_U(dim_z)) ) { - xml_dim_t x_dim_y = x_trafo.child(_U(dim_y)); - xml_dim_t x_dim_z = x_trafo.child(_U(dim_z)); - Transform3D trafo2 = get_trafo(x_dim_y); - Transform3D trafo3 = get_trafo(x_dim_z); - pv = envelope_vol.paramVolume3D(start, box_vol, - x_dim_x.repeat(), trafo1, - x_dim_y.repeat(), trafo2, - x_dim_z.repeat(), trafo3); - } - else if ( x_trafo.hasChild(_U(dim_y)) ) { - xml_dim_t x_dim_y = x_trafo.child(_U(dim_y)); - Transform3D trafo2 = get_trafo(x_dim_y); - pv = envelope_vol.paramVolume2D(start, box_vol, - x_dim_x.repeat(), trafo1, - x_dim_y.repeat(), trafo2); - } - else { - pv = envelope_vol.paramVolume1D(start, box_vol, x_dim_x.repeat(), trafo1); + if ( x_trafo.hasChild(_U(dim_y)) && x_trafo.hasChild(_U(dim_z)) ) { + pv = envelope_vol.paramVolume3D(start, box_vol, + x_dim_x.repeat(), trafo1, + x_dim_y.repeat(), trafo2, + x_dim_z.repeat(), trafo3); + } + else if ( x_trafo.hasChild(_U(dim_y)) ) { + pv = envelope_vol.paramVolume2D(start, box_vol, + x_dim_x.repeat(), trafo1, + x_dim_y.repeat(), trafo2); + } + else { + pv = envelope_vol.paramVolume1D(start, box_vol, x_dim_x.repeat(), trafo1); + } } if ( sens.isValid() ) { sens.setType("calorimeter");