From 8add72eac38112f95edf4ce81059a992801c93fe Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Tue, 16 Jan 2024 17:38:41 +0100 Subject: [PATCH] Add FiberTubeCalorimeter test detector. See https://github.com/AIDASoft/DD4hep/issues/1173 --- DDCore/src/plugins/DetectorCheck.cpp | 73 ++++---- .../compact/FiberTubeCalorimeter.xml | 110 +++++++++++ .../src/FiberTubeCalorimeter_geo.cpp | 177 ++++++++++++++++++ 3 files changed, 328 insertions(+), 32 deletions(-) create mode 100644 examples/ClientTests/compact/FiberTubeCalorimeter.xml create mode 100644 examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp diff --git a/DDCore/src/plugins/DetectorCheck.cpp b/DDCore/src/plugins/DetectorCheck.cpp index 21421a8a1..2add90095 100644 --- a/DDCore/src/plugins/DetectorCheck.cpp +++ b/DDCore/src/plugins/DetectorCheck.cpp @@ -97,6 +97,7 @@ namespace { bool check_placements { false }; bool check_volmgr { false }; bool check_sensitive { false }; + bool ignore_detector { false }; SensitiveDetector get_current_sensitive_detector(); @@ -449,7 +450,7 @@ void DetectorCheck::checkManagerSingleVolume(DetElement detector, PlacedVolume p if ( pv.volume().isSensitive() ) { PlacedVolume det_place = m_volMgr.lookupDetElementPlacement(vid); ++m_sens_counters.elements; - if ( pv.ptr() != det_place.ptr() ) { + if ( !ignore_detector && pv.ptr() != det_place.ptr() ) { err << "VolumeMgrTest: Wrong placement " << " got " << det_place.name() << " (" << (void*)det_place.ptr() << ")" << " instead of " << pv.name() << " (" << (void*)pv.ptr() << ") " @@ -551,33 +552,35 @@ void DetectorCheck::checkManagerSingleVolume(DetElement detector, PlacedVolume p printout(ERROR, m_det.name(), "DETELEMENT_PERSISTENCY FAILED: World transformation have DIFFERET pointer!"); ++m_place_counters.errors; } - - if ( pv.ptr() == det_elem.placement().ptr() ) { - // The computed transformation 'trafo' MUST be equal to: - // m_volMgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation() - int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation()); - int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); - if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL ) { - printout(ERROR, m_det.name(), "DETELEMENT_PLACEMENT FAILED: World transformation DIFFER."); - ++m_place_counters.errors; - } - else { - printout(INFO, m_det.name(), "DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s", - volumeID(vid).c_str()); - } - } - else { - // The computed transformation 'trafo' MUST be equal to: - // m_volMgr.worldTransformation(vid) - // The det_elem.nominal().worldTransformation() however is DIFFERENT! - int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); - if ( res2 != detail::matrix::MATRICES_EQUAL ) { - printout(ERROR, m_det.name(), "VOLUME_PLACEMENT FAILED: World transformation DIFFER."); - ++m_place_counters.errors; + + if ( !ignore_detector ) { + if ( pv.ptr() == det_elem.placement().ptr() ) { + // The computed transformation 'trafo' MUST be equal to: + // m_volMgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation() + int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation()); + int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); + if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL ) { + printout(ERROR, m_det.name(), "DETELEMENT_PLACEMENT FAILED: World transformation DIFFER."); + ++m_place_counters.errors; + } + else { + printout(INFO, m_det.name(), "DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s", + volumeID(vid).c_str()); + } } else { - printout(INFO, m_det.name(), "VOLUME_PLACEMENT: PASSED. All matrices equal: %s", - volumeID(vid).c_str()); + // The computed transformation 'trafo' MUST be equal to: + // m_volMgr.worldTransformation(vid) + // The det_elem.nominal().worldTransformation() however is DIFFERENT! + int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); + if ( res2 != detail::matrix::MATRICES_EQUAL ) { + printout(ERROR, m_det.name(), "VOLUME_PLACEMENT FAILED: World transformation DIFFER."); + ++m_place_counters.errors; + } + else { + printout(INFO, m_det.name(), "VOLUME_PLACEMENT: PASSED. All matrices equal: %s", + volumeID(vid).c_str()); + } } } } @@ -643,6 +646,7 @@ void DetectorCheck::help(int argc,char** argv) { " sensitive volume placements. \n\n" " NOTE: Option requires proper PhysVolID setup \n" " of the sensitive volume placements ! \n" + " -ignore_detector Ignore DetElement placement check for -volmgr \n" << std::endl; std::cout << "Arguments: " << std::endl; for(int iarg=0; iarg + + The compact format for the SCEPCAL IDEA from Sarah Eno + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:8,layer:12,tube:12,hole:3,type:3 + + + + + + + + + + + + + + + + + + diff --git a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp new file mode 100644 index 000000000..ed2251b2b --- /dev/null +++ b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp @@ -0,0 +1,177 @@ +//========================================================================== +// 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. +// +// Author : M.Frank +// +//========================================================================== +// +// Specialized generic detector constructor for fiber tube calorimeter. +// See https://github.com/AIDASoft/DD4hep/issues/1173 for details +// +// Detector geometry structure +// +// /world_volume/FiberCalo/rowtube_1/brass_1/hole_1/quartz_1 +// /brass_2/hole_1/scintillator_1 brass_1 == brass_2 == brass....n +// /brass_3/hole_1/quartz_1 +// /brass_4/hole_1/scintillator_1 +// /brass_5/hole_1/quartz_1 +// brass_1/quartz_1 Volume(brass) / hole +// Volume(hole) / quartz +// alt: Volume(hole) / scintillator +// +// /world_volume/FiberCalo/rowtube_1/brass/quartz +// +// Dump using: +// geoPluginRun -input examples/ClientTests/compact/FiberTubeCalorimeter.xml \ +// -volmgr -print 3 -plugin DD4hep_DetectorCheck \ +// -name FiberTubeCalorimeter -geometry -structure -sensitive -volmgr -ignore +// +//========================================================================== +#include "DD4hep/DetFactoryHelper.h" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::detail; + +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { + constexpr double tol = 0.0; + xml_det_t x_det = e; + + // for volume tags in detector + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + Material air = description.air(); + + // pointer to finding dimensins text in xml file + // look in DDCore/include/Parsers/detail/Dimension.h for arguments + xml_comp_t x_dim = x_det.dimensions(); + double hthick = x_dim.thickness(); + double hzlength = x_dim.z_length()/2.; + double hzph = x_dim.z1(); + int Ncount = x_dim.numsides(); + double agap = x_dim.gap(); + double azmin = x_dim.zmin(); + + // these refer to different fields in the xml file for this detector + xml_comp_t fX_struct( x_det.child( _Unicode(structure) ) ); + xml_comp_t fX_absorb( fX_struct.child( _Unicode(absorb) ) ); + xml_comp_t fX_core1( fX_struct.child( _Unicode(core1) ) ); + xml_comp_t fX_core2( fX_struct.child( _Unicode(core2) ) ); + xml_comp_t fX_hole( fX_struct.child( _Unicode(hole) ) ); + xml_comp_t fX_phdet1( fX_struct.child( _Unicode(phdet1) ) ); + xml_comp_t fX_phdet2( fX_struct.child( _Unicode(phdet2) ) ); + + // detector element for entire detector. + DetElement sdet (det_name, det_id); + Volume motherVol = description.pickMotherVolume(sdet); + Box env_box ((2*Ncount+1)*(hthick+agap+tol),(2*Ncount+1)*(hthick+agap+tol), (hzlength+hzph+tol)); + Volume envelopeVol (det_name, env_box, air); + envelopeVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + Material mat; + Transform3D trafo; + PlacedVolume pv; + + pv = motherVol.placeVolume(envelopeVol, Position(0.,0.,azmin+hzlength+hzph+tol)); + pv.addPhysVolID("system", det_id); + sdet.setPlacement(pv); // associate the placed volume to the detector element + sens.setType("calorimeter"); + + // scint fiber + mat = description.material(fX_core1.materialStr()); + Volume fiber_scint_vol("fiber1", Tube(0.,fX_core1.rmax(), hzlength), mat); + fiber_scint_vol.setAttributes(description,fX_core1.regionStr(),fX_core1.limitsStr(),fX_core1.visStr()); + if ( fX_core1.isSensitive() ) { + fiber_scint_vol.setSensitiveDetector(sens); + } + + // quartz fiber + Tube fiber_quartz_tub(0.,fX_core2.rmax(), hzlength); + Volume fiber_quartz_vol("fiber_quartz", fiber_quartz_tub, description.material(fX_core2.materialStr())); + fiber_quartz_vol.setAttributes(description,fX_core2.regionStr(),fX_core2.limitsStr(),fX_core2.visStr()); + cout<<"fiber_quartz vis is "<