Skip to content

Commit

Permalink
Add FiberTubeCalorimeter test detector. See #1173
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusFrankATcernch committed Jan 16, 2024
1 parent d3019ab commit 8add72e
Show file tree
Hide file tree
Showing 3 changed files with 328 additions and 32 deletions.
73 changes: 41 additions & 32 deletions DDCore/src/plugins/DetectorCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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() << ") "
Expand Down Expand Up @@ -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());
}
}
}
}
Expand Down Expand Up @@ -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<argc;++iarg) {
Expand All @@ -659,6 +663,7 @@ long DetectorCheck::run(Detector& description,int argc,char** argv) {
bool structure = false;
bool sensitive = false;
bool placements = false;
bool ignore_de = false;
printout(ALWAYS, "DetectorCheck", "++ Processing plugin...");
for(int iarg=0; iarg<argc;++iarg) {
if ( argv[iarg] == 0 ) break;
Expand All @@ -674,6 +679,8 @@ long DetectorCheck::run(Detector& description,int argc,char** argv) {
geometry = true;
else if ( ::strncasecmp(argv[iarg], "-sensitive",4) == 0 )
sensitive = true;
else if ( ::strncasecmp(argv[iarg], "-ignore_detelement",4) == 0 )
ignore_de = true;
else if ( ::strncasecmp(argv[iarg], "-help",4) == 0 )
help(argc, argv);
else
Expand All @@ -685,12 +692,13 @@ long DetectorCheck::run(Detector& description,int argc,char** argv) {
if ( name == "all" || name == "All" || name == "ALL" ) {
for (const auto& det : description.detectors() ) {
printout(INFO, "DetectorCheck", "++ Processing subdetector: %s", det.second.name());
test.check_structure = structure;
test.check_placements = placements;
test.check_volmgr = volmgr;
test.check_geometry = geometry;
test.check_sensitive = sensitive;
test.execute(det.second, 9999);
test.check_structure = structure;
test.check_placements = placements;
test.check_volmgr = volmgr;
test.check_geometry = geometry;
test.check_sensitive = sensitive;
test.ignore_detector = ignore_de;
test.execute(det.second, 9999);
}
return 1;
}
Expand All @@ -702,6 +710,7 @@ long DetectorCheck::run(Detector& description,int argc,char** argv) {
test.check_volmgr = volmgr;
test.check_geometry = geometry;
test.check_sensitive = sensitive;
test.ignore_detector = ignore_de;
test.execute(det, 9999);
}
return 1;
Expand Down
110 changes: 110 additions & 0 deletions examples/ClientTests/compact/FiberTubeCalorimeter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<lccdd>
<info name="SCEPCAL with IDEA"
title="SCEPCAL with IDEA"
author="Sarah Eno"
url="https://twiki.cern.ch/twiki/bin/view/CLIC/xxx"
status="development"
version="1.0">
<comment>The compact format for the SCEPCAL IDEA from Sarah Eno</comment>
</info>

<includes>
<gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
<gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
</includes>

<materials>
<material name="Brass">
<D value="8.73" unit="g/cm3" />
<fraction n="0.75" ref="Cu"/>
<fraction n="0.25" ref="Zn"/>
</material>
</materials>

<define>
<!-- constants for dual readout crystal calorimeter -->
<constant name="DRcrystalwidth" value="1.0*cm"/> <!-- should be 1 -->
<constant name="DRcrystallength" value="20.0*cm"/> <!-- should be 20 normally, 400 for 20 interacion length test-->
<constant name="DRcrystalNsize" value="45"/> <!-- should be 45 -->
<!-- gap between ecal and hcal -->
<constant name="EcalHcalgap" value="0.1*cm"/> <!-- should be small 0.1 mm -->
<!-- constants for dual readout spagetti fiber hcal calorimeter in SCEPCAL -->
<!-- these are radii (or half widths) -->
<constant name="DRFiberAbswidthSCE" value="1.0*mm"/> <!-- should be 1.0 mm -->
<constant name="DRFiberFibwidthSCE" value=".5025*mm"/> <!-- should be 0.5025 mm -->
<constant name="holeoverSCE" value="0.025*mm"/>
<constant name="gapSCE" value="0.0001*mm"/>
<constant name="DRFiberlengthSCE" value="2.*cm"/> <!-- should be 200 cm -->
<constant name="DRFiberNsizeSCE" value="5"/> <!-- should be 136 -->
<!-- 200 crash 190 no crash 195 no crash 197 no crash 199 no crash-->
<!-- crashes when make fiber size smaller -->

<!-- constants for dual readout spagetti fiber hcal calorimeter in IDEA -->
<constant name="DRFiberAbswidthIDEA" value="1.0*mm"/> <!-- should be 1.0 mm -->
<constant name="DRFiberFibwidthIDEA" value="0.5025*mm"/> <!-- should be 0.5025 mm -->
<constant name="holeoverIDEA" value="0.025*mm"/>
<constant name="gapIDEA" value="0.0001*mm"/>
<constant name="DRFiberlengthIDEA" value="400.*cm"/> <!-- should be 200 cm -->
<constant name="DRFiberNsizeIDEA" value="199"/> <!-- should be 150 -->


<!-- constants for dual readout sampling hcal calorimeter -->
<constant name="DRSampAthick" value="4.*mm"/> <!-- should be 20 -->
<constant name="DRSampSthick" value="4.*mm"/> <!-- should be 5 -->
<constant name="DRSampQthick" value="4.*mm"/> <!-- should be 5 -->
<constant name="DRSampxy" value="20.*mm"/> <!-- should be 20 -->
<constant name="DRSampNsize" value="10"/> <!-- should be 5 -->
<constant name="DRSampNlayer" value="200"/> <!-- should be 40 -->
<!-- detector numbering scheme -->
<constant name="Ecal_ID" value="5"/>
<constant name="Hcal_ID" value="6"/>
<constant name="EdgeDet_ID" value="4"/>

<constant name="killthick" value="0.01*cm"/>
<constant name="edgeoffset" value="50*cm"/>

<constant name="world_side" value="DRcrystallength+2*DRFiberlengthIDEA+EcalHcalgap+edgeoffset+10."/>
<constant name="world_x" value="world_side/1.5"/> <!-- should be /4 -->
<constant name="world_y" value="world_side/1.5"/> <!-- should be /4 -->
<constant name="world_z" value="world_side"/>
</define>

<display>
<vis name="AbsVis" alpha="1.0" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="CerenVis" alpha="0.5" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="ScintVis" alpha="0.5" r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
<vis name="phdetVis" alpha="1.0" r="1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
<vis name="towerVis" alpha="0.1" r="0.3" g="0.3" b="0.3" showDaughters="true" visible="true"/>
</display>

<readouts>
<readout name="DRFNoSegment">
<segmentation type="NoSegmentation"/>
<id>system:8,layer:12,tube:12,hole:3,type:3</id>
</readout>
</readouts>

<detectors>
<detector id="Hcal_ID" name="FiberTubeCalorimeter" type="DD4hep_FiberTubeCalorimeter" readout="DRFNoSegment" vis="towerVis">
<!-- here z_length is the absorber length, thickness is length of an end side
z1 is the photodetector length gap is the distance between modules, and dz is how far the fiber sticks out of the absorber.
Nsize is the number of cells to make
zmin is where the dtector goes
-->
<dimensions numsides="DRFiberNsizeSCE"
thickness="DRFiberAbswidthSCE"
z_length="DRFiberlengthSCE"
gap="gapSCE"
zmin="-world_side/2.+2*killthick+edgeoffset+DRcrystallength+EcalHcalgap"
z1="killthick"/>
<structure>
<core1 name="core1" rmax="DRFiberFibwidthSCE" rmin="0.0" material="Polystyrene" vis="ScintVis" sensitive="yes"/>
<core2 name="core2" rmax="DRFiberFibwidthSCE" rmin="0.0" material="Quartz" vis="CerenVis" sensitive="yes"/>
<hole name="hole" rmax="(DRFiberFibwidthSCE+holeoverSCE)" rmin="0.0" material="Air" vis="holeVis" sensitive="yes"/>
<absorb material="Brass" vis="AbsVis" sensitive="yes"/>
<phdet1 name="phdet1" rmax="DRFiberFibwidthSCE" rmin="0.0" material="killMedia2" vis="phdetVis" sensitive="yes"/>
<phdet2 name="phdet2" rmax="DRFiberFibwidthSCE" rmin="0.0" material="killMedia3" vis="phdetVis" sensitive="yes"/>
</structure>
</detector>
</detectors>
</lccdd>
Loading

0 comments on commit 8add72e

Please sign in to comment.