From cb74c41cdbc4d8795a77e9a16001b5d4c4b94f67 Mon Sep 17 00:00:00 2001 From: Markus FRANK <Markus.Frank@cern.ch> Date: Mon, 23 Aug 2021 21:33:53 +0200 Subject: [PATCH] Allow for sensitive actions with multiple readout segmentation in the Geant4Sensitive action sequence --- DDCore/src/plugins/Compact2Objects.cpp | 3 +- DDDetectors/compact/SiD.xml | 10 +- DDG4/include/DDG4/Geant4SensDetAction.h | 29 ++- DDG4/include/DDG4/Geant4SensDetAction.inl | 28 +- DDG4/plugins/Geant4SDActions.cpp | 4 +- DDG4/src/Geant4SensDetAction.cpp | 16 +- .../compact/SiD_ECAL_Parallel_Readout.xml | 61 +++++ .../FCCmachine/BeamInstrumentation.xml | 38 +++ .../compact/FCCmachine/Beampipe.xml | 154 +++++++++++ .../FCCmachine/FCCee_DectDimensions.xml | 243 ++++++++++++++++++ .../compact/FCCmachine/FCCee_DectMaster.xml | 55 ++++ .../compact/FCCmachine/HOMAbsorber.xml | 62 +++++ .../ClientTests/compact/VisAttr_Extend.xml | 61 +++++ .../ClientTests/src/FCC_Mask_o1_v01_geo.cpp | 236 +++++++++++++++++ .../src/FCC_Mask_o1_v01_noRot_geo.cpp | 235 +++++++++++++++++ .../src/FCC_MaterialEnvelope_o1_v01.cpp | 35 +++ .../src/FCC_OtherDetectorHelpers.h | 110 ++++++++ examples/DDCAD/compact/Import_FCC_Machine.xml | 50 ++++ 18 files changed, 1397 insertions(+), 33 deletions(-) create mode 100644 examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml create mode 100644 examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml create mode 100644 examples/ClientTests/compact/FCCmachine/Beampipe.xml create mode 100644 examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml create mode 100644 examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml create mode 100644 examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml create mode 100644 examples/ClientTests/compact/VisAttr_Extend.xml create mode 100644 examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp create mode 100644 examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp create mode 100644 examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp create mode 100644 examples/ClientTests/src/FCC_OtherDetectorHelpers.h create mode 100644 examples/DDCAD/compact/Import_FCC_Machine.xml diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 581f535fe..abc3c8431 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -1462,7 +1462,7 @@ template <> void Converter<DetElementInclude>::operator()(xml_h element) const { xml_coll_t(node, _U(readout)).for_each(Converter<Readout>(this->description)); else if ( tag == "regions" ) xml_coll_t(node, _U(region)).for_each(Converter<Region>(this->description)); - else if ( tag == "limitsets" ) + else if ( tag == "limits" || tag == "limitsets" ) xml_coll_t(node, _U(limitset)).for_each(Converter<LimitSet>(this->description)); else if ( tag == "display" ) xml_coll_t(node,_U(vis)).for_each(Converter<VisAttr>(this->description)); @@ -1569,6 +1569,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const { (Converter<World>(description))(xml_h(compact.child(_U(world)))); if ( open_geometry ) description.init(); + xml_coll_t(compact, _U(limits)).for_each(_U(include), Converter<DetElementInclude>(description)); xml_coll_t(compact, _U(limits)).for_each(_U(limitset), Converter<LimitSet>(description)); printout(DEBUG, "Compact", "++ Converting readout structures..."); diff --git a/DDDetectors/compact/SiD.xml b/DDDetectors/compact/SiD.xml index 2a9e297c2..9110610f1 100644 --- a/DDDetectors/compact/SiD.xml +++ b/DDDetectors/compact/SiD.xml @@ -39,15 +39,9 @@ <limits> - <limitset name="cal_limits"> - <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> - </limitset> - <limitset name="SiTrackerBarrelRegionLimitSet"> - <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> - <limit name="ekin_min" particles="*" value="0.01" unit="MeV" /> - <limit name="range_min" particles="*" value="5.0" unit="mm" /> - </limitset> + <include ref="SiD_Limits.xml"/> </limits> + <regions> <region name="SiTrackerBarrelRegion" eunit="MeV" lunit="mm" cut="0.001" threshold="0.001"> <limitsetref name="SiTrackerBarrelRegionLimitSet"/> diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h index 9ed4d1f76..200ab98f1 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.h +++ b/DDG4/include/DDG4/Geant4SensDetAction.h @@ -123,28 +123,28 @@ namespace dd4hep { private: /// Reference to G4 sensitive detector - Geant4ActionSD* m_sensitiveDetector = 0; + Geant4ActionSD* m_sensitiveDetector { nullptr }; /// Reference to the containing action sequence - Geant4SensDetActionSequence* m_sequence = 0; + Geant4SensDetActionSequence* m_sequence { nullptr }; protected: /// Property: Hit creation mode. Maybe one of the enum HitCreationFlags int m_hitCreationMode = 0; #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__) /// Reference to the detector description object - Detector* m_detDesc {0}; + Detector* m_detDesc { nullptr }; #else /// Reference to the detector description object Detector& m_detDesc; #endif /// Reference to the detector element describing this sensitive element - DetElement m_detector; + DetElement m_detector { }; /// Reference to the sensitive detector element - SensitiveDetector m_sensitive; + SensitiveDetector m_sensitive { }; /// Reference to the readout structure - Readout m_readout; + Readout m_readout { }; /// Reference to segmentation - Segmentation m_segmentation; + Segmentation m_segmentation { }; /// The list of sensitive detector filter objects Actors<Geant4Filter> m_filters; @@ -199,6 +199,9 @@ namespace dd4hep { return detector().readoutGeometry(); } + /// Access the detector desciption object + Detector& detectorDescription() const; + /// Mark the track to be kept for MC truth propagation during hit processing void mark(const G4Track* track) const; @@ -508,11 +511,14 @@ namespace dd4hep { typedef T UserData; protected: /// Property: collection name. If not set default is readout name! - std::string m_collectionName; + std::string m_collectionName { }; + /// Property: segmentation name for parallel readouts. If not set readout segmentation is used! + std::string m_readoutName { }; + /// Collection identifier - size_t m_collectionID = -1; + size_t m_collectionID { 0 }; /// User data block - UserData m_userData; + UserData m_userData { }; protected: /// Define standard assignments and constructors @@ -531,6 +537,9 @@ namespace dd4hep { /// Define collections created by this sensitivie action object virtual void defineCollections(); + /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout() + Readout readout(); + /// Define readout specific hit collection with volume ID filtering /** * Convenience function. To be called by specialized sensitive actions inheriting this class. diff --git a/DDG4/include/DDG4/Geant4SensDetAction.inl b/DDG4/include/DDG4/Geant4SensDetAction.inl index 79ee69084..69d852f3f 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.inl +++ b/DDG4/include/DDG4/Geant4SensDetAction.inl @@ -11,10 +11,11 @@ // //========================================================================== -// Framework include files +/// Framework include files #include "DDG4/Geant4SensDetAction.h" -#include "DD4hep/detail/ObjectsInterna.h" +#include "DD4hep/Detector.h" #include "DD4hep/InstanceCount.h" +#include "DD4hep/detail/ObjectsInterna.h" #include "DDG4/Geant4ReadoutVolumeFilter.h" #include "DDG4/Geant4Data.h" @@ -33,6 +34,7 @@ namespace dd4hep { Detector& description_ref) : Geant4Sensitive(ctxt,nam,det,description_ref), m_collectionName(), m_collectionID(0) { + declareProperty("ReadoutName", m_readoutName); declareProperty("CollectionName", m_collectionName); initialize(); InstanceCount::increment(this); @@ -52,6 +54,21 @@ namespace dd4hep { template <typename T> void Geant4SensitiveAction<T>::finalize() { } + /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout() + template <typename T> Readout Geant4SensitiveAction<T>::readout() { + if ( !m_readoutName.empty() && m_sensitive.readout() == m_readout ) { + m_readout = detectorDescription().readout(m_readoutName); + if ( !m_readout.isValid() ) { + except("+++ Failed to access parallel readout '%s'",m_sensitive.name()); + } + m_segmentation = m_readout.segmentation(); + if ( !m_segmentation.isValid() ) { + except("+++ Failed to access segmentation for readout '%s'",m_readout.name()); + } + } + return m_readout; + } + /// G4VSensitiveDetector interface: Method invoked at the begining of each event. template <typename T> void Geant4SensitiveAction<T>::begin(G4HCofThisEvent* hce) { Geant4Sensitive::begin(hce); @@ -84,7 +101,7 @@ namespace dd4hep { /// Define readout specific hit collection. matching name must be present in readout structure template <typename T> template <typename HIT> size_t Geant4SensitiveAction<T>::defineReadoutCollection(const std::string match_name) { - Readout ro = m_sensitive.readout(); + auto ro = readout(); for(const auto& c : ro->hits ) { if ( c.name == match_name ) { size_t coll_id = defineCollection<HIT>(match_name); @@ -94,7 +111,7 @@ namespace dd4hep { } } except("+++ Custom collection name '%s' not defined in the Readout object: %s.", - m_collectionName.c_str(), ro.name()); + m_collectionName.c_str(), ro.name()); return 0; // Anyhow not reachable. Exception thrown before } @@ -103,8 +120,7 @@ namespace dd4hep { size_t Geant4SensitiveAction<T>::declareReadoutFilteredCollection() { if ( m_collectionName.empty() ) { - Readout ro = m_sensitive.readout(); - return defineCollection<HIT>(ro.name()); + return defineCollection<HIT>(readout().name()); } return defineReadoutCollection<HIT>(m_collectionName); } diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp index f624521f6..8aff2daca 100644 --- a/DDG4/plugins/Geant4SDActions.cpp +++ b/DDG4/plugins/Geant4SDActions.cpp @@ -104,7 +104,7 @@ namespace dd4hep { collection(m_collectionID)->add(hit); mark(h.track); if ( 0 == hit->cellID ) { - hit->cellID = volumeID( step ) ; + hit->cellID = volumeID( step ) ; except("+++ Invalid CELL ID for hit!"); } print("Hit with deposit:%f Pos:%f %f %f ID=%016X", @@ -131,7 +131,7 @@ namespace dd4hep { collection(m_collectionID)->add(hit); mark(h.track); if ( 0 == hit->cellID ) { - hit->cellID = volumeID( spot ) ; + hit->cellID = volumeID( spot ) ; except("+++ Invalid CELL ID for hit!"); } print("Hit with deposit:%f Pos:%f %f %f ID=%016X", diff --git a/DDG4/src/Geant4SensDetAction.cpp b/DDG4/src/Geant4SensDetAction.cpp index 0899d601c..634cd266f 100644 --- a/DDG4/src/Geant4SensDetAction.cpp +++ b/DDG4/src/Geant4SensDetAction.cpp @@ -98,18 +98,17 @@ bool Geant4Filter::operator()(const G4GFlashSpot*) const { } /// Constructor. The detector element is identified by the name -Geant4Sensitive::Geant4Sensitive(Geant4Context* ctxt, const string& nam, DetElement det, Detector& description_ref) - : Geant4Action(ctxt, nam), m_sensitiveDetector(0), m_sequence(0), - m_detDesc(description_ref), m_detector(det), m_sensitive(), m_readout(), m_segmentation() +Geant4Sensitive::Geant4Sensitive(Geant4Context* ctxt, const string& nam, DetElement det, Detector& det_ref) + : Geant4Action(ctxt, nam), m_detDesc(det_ref), m_detector(det) { InstanceCount::increment(this); if (!det.isValid()) { throw runtime_error(format("Geant4Sensitive", "DDG4: Detector elemnt for %s is invalid.", nam.c_str())); } declareProperty("HitCreationMode", m_hitCreationMode = SIMPLE_MODE); - m_sequence = context()->kernel().sensitiveAction(m_detector.name()); - m_sensitive = description_ref.sensitiveDetector(det.name()); - m_readout = m_sensitive.readout(); + m_sequence = context()->kernel().sensitiveAction(m_detector.name()); + m_sensitive = m_detDesc.sensitiveDetector(det.name()); + m_readout = m_sensitive.readout(); m_segmentation = m_readout.segmentation(); } @@ -186,6 +185,11 @@ Geant4SensDetActionSequence& Geant4Sensitive::sequence() const { return *m_sequence; } +/// Access the detector desciption object +Detector& Geant4Sensitive::detectorDescription() const { + return m_detDesc; +} + /// Access HitCollection container names const string& Geant4Sensitive::hitCollectionName(size_t which) const { return sequence().hitCollectionName(which); diff --git a/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml b/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml new file mode 100644 index 000000000..b34032b6f --- /dev/null +++ b/examples/CLICSiD/compact/SiD_ECAL_Parallel_Readout.xml @@ -0,0 +1,61 @@ +<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. + # + #========================================================================== +--> + <info name="clic_sid_cdr" + title="CLIC Silicon Detector CDR" + author="Christian Grefe" + url="https://twiki.cern.ch/twiki/bin/view/CLIC/ClicSidCdr" + status="development" + version="$Id: compact.xml 1374 2014-11-05 10:49:55Z markus.frank@cern.ch $"> + <comment>The compact format for the CLIC Silicon Detector used for the conceptual design report</comment> + </info> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD/SiD_Materials.xml"/> + + <define> + <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiDConstants.xml"/> + </define> + + <limits> + <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD_Limits.xml"/> + </limits> + + <include ref="${DD4hepINSTALL}/DDDetectors/compact/SiD/SiD_EcalBarrel.xml"/> + + <readouts> + <readout name="EcalBarrelHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.5" grid_size_y="3.5" /> + <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id> + </readout> + + <readout name="EcalBarrelHits_0"> + <segmentation type="CartesianGridXY" grid_size_x="1" grid_size_y="1" /> + <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id> + </readout> + + <readout name="EcalBarrelHits_1"> + <segmentation type="CartesianGridXY" grid_size_x="5" grid_size_y="5" /> + <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id> + </readout> + + <readout name="EcalBarrelHits_2"> + <segmentation type="CartesianGridXY" grid_size_x="10" grid_size_y="10" /> + <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id> + </readout> + + </readouts> + +</lccdd> diff --git a/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml b/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml new file mode 100644 index 000000000..99c4aa72c --- /dev/null +++ b/examples/ClientTests/compact/FCCmachine/BeamInstrumentation.xml @@ -0,0 +1,38 @@ +<lccdd> + + <info name="FCCee" + title="FCCee Beam instrumentation: taken correspoding to CLD: BeamInstrumentation_o3_v02_fitShield.xml" + author="nalipour taken from lcgeo" + url="no" + status="development" + version="1.0"> + <comment>A beam instrumentation for FCCee detector based on CLD</comment> + </info> + + <detectors> + <comment>Beampipe Instrumentation</comment> + + + <detector name="CompSol" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="CompSolVis"> + <parameter crossingangle="CrossingAngle" /> + <envelope vis="CoilVis"> + <shape type="Assembly"/> + </envelope> + <section type="Center" start="CompSol_min_z" end="QD0_min_z" rMin1="103*mm" rMin2="180*mm" rMax1="123*mm" rMax2="200*mm" material="SolenoidMixture" name="CompSol" /> + </detector> + + + <detector name="ScreenSol" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="ScreenSolVis"> + <parameter crossingangle="CrossingAngle" /> + <envelope vis="CoilVis"> + <shape type="Assembly"/> + </envelope> + + <section type="Center" start="QD0_min_z" end="QD0_min_z+5*cm" rMin1="SeparatedBeamPipe_rmax+1*mm+5*cm" rMin2="SeparatedBeamPipe_rmax+1*mm+5*cm" rMax1="200*mm" rMax2="200*mm" material="SolenoidMixture" name="CompSol" /> + + <section type="Center" start="QD0_min_z+5*cm" end="QD0_max_z" rMin1="180*mm" rMin2="180*mm" rMax1="200*mm" rMax2="200*mm" material="SolenoidMixture" name="CompSol" /> + </detector> + + + </detectors> +</lccdd> diff --git a/examples/ClientTests/compact/FCCmachine/Beampipe.xml b/examples/ClientTests/compact/FCCmachine/Beampipe.xml new file mode 100644 index 000000000..2f047a8fd --- /dev/null +++ b/examples/ClientTests/compact/FCCmachine/Beampipe.xml @@ -0,0 +1,154 @@ +<lccdd> + + <info name="FCCee" + title="FCCee Beam pipe: taken corresponding to CLD: Beampipe_o4_v04_noNotch_W_n02.xml" + author="nalipour taken from lcgeo" + url="no" + status="development" + version="1.0"> + <comment>A beampipe for FCCee detector based on CLD</comment> + </info> + + <!-- Definition of global dictionary constants --> + <define> + <constant name="beampipegoldwidth" value="BeamPipeGoldWidth"/> + <constant name="beampipegoldtolerance" value="BeamPipeGoldTolerance"/> + </define> + + <!-- Definition of the used visualization attributes --> + <display> + <vis name="BeamPipeVis" alpha="0.0" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="false"/> + <vis name="GoldCoatingVis" alpha="0.0" r="0.0" g="1.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="TubeVis" alpha="1.0" r="1.0" g="0.7" b="0.5" showDaughters="true" visible="true"/> + <vis name="VacVis" alpha="1.0" r="1.0" g="1.0" b="1.0" showDaughters="true" visible="false"/> + </display> + + + <detectors> + + <comment>Part of beampipe made of Beryllium</comment> + + <detector name="BeBeampipe" type="DD4hep_Beampipe_o1_v01" insideTrackingVolume="true" nocore="true" vis="BeamPipeVis"> + <parameter crossingangle="CrossingAngle" /> + <envelope vis="BlueVis"> + <shape type="Assembly"/> + </envelope> + + <section type="Center" start="0*mm" end="CentralBeamPipe_zmax" rMin1="CentralBeamPipe_rmax" rMin2="CentralBeamPipe_rmax" rMax1="CentralBeamPipe_rmax+BeamPipeWidth" rMax2="CentralBeamPipe_rmax+BeamPipeWidth" material="Beryllium" name="VertexInnerBe" /> + + <section type="Center" start="CentralBeamPipe_zmax" end="BePartEnd_z" rMin1="CentralBeamPipe_rmax" rMin2="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone" rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" material="Beryllium" name="FirstConeBe" /> + + </detector> + + <detector name="BeamPipe" type="DD4hep_Beampipe_o1_v01" insideTrackingVolume="true" vis="BeamPipeVis" > + <envelope vis="BlueVis"> + <shape type="Assembly"/> + </envelope> + <parameter crossingangle="CrossingAngle" /> + + + <comment>Golden foil in the inner part of the Be beampipe</comment> + + <section type="Center" start="0*mm" end="CentralBeamPipe_zmax" rMin1="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)" rMin2="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)" rMax1="CentralBeamPipe_rmax-beampipegoldtolerance" rMax2="CentralBeamPipe_rmax-beampipegoldtolerance" material="Gold" name="VertexInnerGold" /> + + <section type="Center" start="CentralBeamPipe_zmax" end="BePartEnd_z" rMin1="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)" rMin2="CentralBeamPipe_rmax-(beampipegoldwidth+beampipegoldtolerance)+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" rMax1="CentralBeamPipe_rmax-beampipegoldtolerance" rMax2="CentralBeamPipe_rmax-beampipegoldtolerance+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" material="Gold" name="FirstConeGold" /> + + <comment>Part of beampipe made of Copper</comment> + + <section type="Center" start="BePartEnd_z" end="SeparatedBeamPipe_z" rMin1="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" rMin2="CentralBeamPipe_rmax+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017" rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017" rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017" material="Copper" name="CopperCone" /> + + + + <section type="PunchedCenter" start="SeparatedBeamPipe_z" end="SeparatedBeamPipe_z+3*mm" rMin1="SeparatedBeamPipe_rmax" rMin2="SeparatedBeamPipe_rmax" rMax1="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.015+(SeparatedBeamPipe_z-BePartEnd_z)*0.015" rMax2="CentralBeamPipe_rmax+BeamPipeWidthFirstCone+(BePartEnd_z-CentralBeamPipe_zmax)*0.017+(SeparatedBeamPipe_z-BePartEnd_z)*0.017 + 3*mm*0.017" material="Copper" name="SplitVacChambers"/> + + + <section type="DnstreamClippedFront" start="SeparatedBeamPipe_z+3.01*mm" end="6000*mm" rMin1="SeparatedBeamPipe_rmax" rMin2="SeparatedBeamPipe_rmax" rMax1="SeparatedBeamPipe_rmax+1*mm" rMax2="SeparatedBeamPipe_rmax+1*mm" material="Copper" name="DownStreamBeamPipe_1"/> + + + <section type="UpstreamClippedFront" start="SeparatedBeamPipe_z+3.01*mm" end="6000*mm" rMin1="SeparatedBeamPipe_rmax" rMin2="SeparatedBeamPipe_rmax" rMax1="SeparatedBeamPipe_rmax+1*mm" rMax2="SeparatedBeamPipe_rmax+1*mm" material="Copper" name="UpStreamBeamPipe_1"/> + + +</detector> +<comment>Full Cone Tungsten Shield</comment> +<detector name="BeamPipeShield" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="TantalumVis" > + <parameter crossingangle="CrossingAngle" /> + + <comment>Before HOM space</comment> + <section type="PunchedCenter" + start="LumiCal_max_z + 5*mm" end="1197.5*mm" + rMin1="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm" + rMin2="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm " + rMax1="SeparatedBeamPipe_rmax + (LumiCal_max_z + 5*mm )*0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth" + rMax2="SeparatedBeamPipe_rmax + (1197.5*mm) * 0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth" + material="Tungsten" name="TaShield_BH2" /> + + + + <comment>After HOM space (1197.5*m - 1298.7*mm) +18 cm as solenoid is now closer to IP </comment> + <section type="PunchedCenter" + start="1298.7*mm" end="QD0_min_z + 18*cm" + rMin1="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm" + rMin2="SeparatedBeamPipe_rmax + BeamPipeWidth + 0.1*mm " + rMax1="SeparatedBeamPipe_rmax + (1298.7*mm )*0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth" + rMax2="SeparatedBeamPipe_rmax + (QD0_min_z + 18*cm) * 0.015 + BeamPipeWidth + 0.1*mm + BeamPipeTantalShieldWidth" + material="Tungsten" name="TaShield_AH" /> + + </detector> +<comment>Asymmetric Tungsten Shield no Rotation</comment> + +<detector name="BeamPipeShield_noRot" type="DD4hep_FCC_Mask_o1_v01_noRot" insideTrackingVolume="true" vis="TantalumVis" > + <parameter crossingangle="CrossingAngle" /> + + <section type="Center" + start="500*mm" end="LumiCal_max_z + 4.9*mm" + rMin1="CentralBeamPipe_rmax + (500.0*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMax1="CentralBeamPipe_rmax + (500.0*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + TopFillerShieldWidth" + rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm-CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth" + Phi1="326*degree" + Phi2="34*degree" + + material="Tungsten" name="TaShieldTopPart" /> + + <comment>was 370</comment> + <section type="Center" + start="330*mm" end="500*mm" + rMin1="CentralBeamPipe_rmax + (330*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMin2="CentralBeamPipe_rmax + (500*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMax1="CentralBeamPipe_rmax + (330*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMax2="CentralBeamPipe_rmax + (500*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + TopFillerShieldWidth" + Phi1="326*degree" + Phi2="34*degree" + + material="Tungsten" name="TaShieldTopPart2" /> + + + <comment>one degree less, to fit lumical window</comment> + <section type="Center" + start="600*mm" end="LumiCal_max_z + 4.9*mm" + rMin1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMax1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + SideFillerShieldWidth" + rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth" + Phi1="34*degree" + Phi2="70*degree" + + material="Tungsten" name="TaShieldFiller1" /> + + <section type="Center" + start="600*mm" end="LumiCal_max_z + 4.9*mm" + rMin1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMin2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm" + rMax1="CentralBeamPipe_rmax + (600*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + SideFillerShieldWidth" + rMax2="CentralBeamPipe_rmax + (LumiCal_max_z + 4.9*mm - CentralBeamPipe_zmax)*0.017 + BeamPipeWidthFirstCone + 0.1*mm + BeamPipeTantalShieldWidth" + Phi1="291*degree" + Phi2="326*degree" + + + material="Tungsten" name="TaShieldFiller2" /> + + + </detector> + + </detectors> +</lccdd> diff --git a/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml b/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml new file mode 100644 index 000000000..2c4ccc181 --- /dev/null +++ b/examples/ClientTests/compact/FCCmachine/FCCee_DectDimensions.xml @@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + + <info name="FCCDectDimensions" + title="master file with includes and world dimension" + author="nalipour" + url="no" + status="development" + version="1.0"> + <comment> + </comment> + </info> + + + <define> + <constant name="world_side" value="6100*mm"/> + <constant name="CrossingAngle" value="0.030*rad"/> + + <constant name="GlobalTrackerReadoutID_DCH" type="string" value="system:1,layer:16,phi:16"/> + <constant name="GlobalTrackerReadoutID" type="string" value="system:5,side:-2,layer:6,module:11,sensor:8"/> + + <constant name="SolenoidField" value="2*tesla"/> + + + <constant name="DetID_NOTUSED" value=" 0"/> + + <constant name="DetID_VXD_Barrel" value=" 1"/> + <constant name="DetID_VXD_Endcap" value=" 2"/> + <constant name="DetID_DCH" value=" 3"/> + <constant name="DetID_Calo_Barrel" value=" 4"/> + <constant name="DetID_Calo_Endcap" value=" 5"/> + <constant name="DetID_Calo_Endcap_2" value=" 6"/> + + <constant name="DetID_HCAL_Barrel" value=" 10"/> + <constant name="DetID_HCAL_Endcap" value=" 11"/> + <constant name="DetID_HCAL_Ring" value=" 12"/> + + <constant name="DetID_Yoke_Barrel" value=" 13"/> + <constant name="DetID_Yoke_Endcap" value=" 14"/> + + <constant name="DetID_LumiCal" value=" 15"/> + <constant name="DetID_LumiCalInstrumentation" value=" 16"/> + <constant name="DetID_LumiCalCooling" value=" 17"/> + <constant name="DetID_LumiCalBackShield" value=" 18"/> + <constant name="DetID_HOMAbsorber" value=" 19"/> + <constant name="DetID_LumiCalNoseShield" value=" 22"/> + + <constant name="BeamPipeWidth" value="1.2*mm" /> + <constant name="BeamPipeWidthFirstCone" value="1.0*mm" /> + <constant name="CentralBeamPipe_zmax" value="12.5*cm"/> + <constant name="BePartEnd_z" value="90.0*cm"/> + <constant name="SeparatedBeamPipe_z" value="1159.97*mm"/> + <constant name="CentralBeamPipe_rmax" value="15.0*mm"/> + <constant name="BeamPipeGoldWidth" value="0.005*mm" /> + <constant name="BeamPipeGoldTolerance" value="0.001*mm" /> <!-- dummy tolerance, some small non zero value --> + + <constant name="InnerTracker_half_length" value="2300*mm" /> + + <constant name="ConeBeamPipe_zmax" value="InnerTracker_half_length" /> + <constant name="ConeBeamPipe_rmax_1" value="InnerTracker_half_length * 0.1 + 1*mm" /> + + <constant name="BigBeamPipe_zmax" value="1120*mm"/> + <constant name="SeparatedBeamPipe_rmax" value="15*mm"/> + <constant name="BeamPipeTantalShieldWidth" value="15*mm"/> + <constant name="SideFillerShieldWidth" value="7*mm"/> + <constant name="TopFillerShieldWidth" value="8*mm"/> + <constant name="BeamPipe_end" value="12500*mm"/> + + + <constant name="size_x" value="60*mm"/> + <constant name="size_y" value="12*mm"/> + <constant name="size_z" value="50*mm"/> + + <constant name="env_safety" value="0.1*mm"/> + + <constant name="Vertex_inner_radius" value="17*mm"/> + <constant name="Vertex_outer_radius" value="111*mm"/> + <constant name="Vertex_half_length" value="302*mm"/> + + <constant name="InnerTracker_inner_radius" value="61*mm"/> + <constant name="InnerTracker_outer_radius" value="696*mm"/> + + <constant name="OuterTracker_inner_radius" value="696*mm"/> + <constant name="OuterTracker_outer_radius" value="2145*mm"/> <!-- to avoid overlap with CaloFace, but it has to be large enough to accommodate OT--> + <constant name="OuterTracker_half_length" value="2300*mm"/> + + <constant name="ECalBarrel_inner_radius" value="2150*mm"/> + <constant name="ECalBarrel_outer_radius" value="2352*mm"/> + <constant name="ECalBarrel_half_length" value="2210*mm"/> + <constant name="ECalBarrel_symmetry" value="12"/> + + <constant name="ECalEndcap_inner_radius" value="340*mm"/> + <constant name="ECalEndcap_outer_radius" value="2350*mm"/> + <constant name="ECalEndcap_min_z" value="2307*mm"/> + <constant name="ECalEndcap_max_z" value="2509*mm"/> + <constant name="ECalEndcap_outer_symmetry" value="12"/> + <constant name="ECalEndcap_inner_symmetry" value="12"/> + + <!-- ECal plug not used --> + <constant name="ECalPlug_inner_radius" value="260*mm"/> + <constant name="ECalPlug_outer_radius" value="380*mm"/> + <constant name="ECalPlug_min_z" value="2307*mm"/> + <constant name="ECalPlug_max_z" value="2509*mm"/> + <constant name="ECalPlug_outer_symmetry" value="12"/> + <constant name="ECalPlug_inner_symmetry" value="12"/> + + <constant name="HCalBarrel_inner_radius" value="2400*mm"/> + <constant name="HCalBarrel_outer_radius" value="3566*mm"/> + <constant name="HCalBarrel_half_length" value="2210*mm"/> + <constant name="HCalBarrel_symmetry" value="12"/> + + <constant name="HCalEndcap_inner_radius" value="340*mm"/> + <constant name="HCalEndcap_outer_radius" value="3566*mm"/> + <constant name="HCalEndcap_min_z" value="2539*mm"/> + <constant name="HCalEndcap_max_z" value="3705*mm"/> + <constant name="HCalEndcap_symmetry" value="12"/> + <constant name="HCalEndcap_zcutout" value="200*mm"/> + <constant name="HCalEndcap_rcutout" value="0*mm"/> + + <constant name="HCalRing_inner_radius" value="2370*mm"/> + <constant name="HCalRing_outer_radius" value="HCalEndcap_outer_radius"/> + <constant name="HCalRing_min_z" value="2353.5*mm"/> + <constant name="HCalRing_max_z" value="HCalEndcap_min_z"/> + <constant name="HCalRing_symmetry" value="12"/> + + <constant name="Solenoid_inner_radius" value="3719*mm"/> + <constant name="Solenoid_outer_radius" value="4272*mm"/> + <constant name="Solenoid_half_length" value="3705*mm"/> + <constant name="Solenoid_Coil_half_length" value="3476*mm"/> + <constant name="Solenoid_Coil_radius" value="3930*mm"/> + + <constant name="YokeBarrel_inner_radius" value="4479*mm"/> + <constant name="YokeBarrel_outer_radius" value="6000*mm"/> + <constant name="YokeBarrel_half_length" value="3755*mm"/> + <constant name="YokeBarrel_symmetry" value="12"/> + + <constant name="YokeEndcap_inner_radius" value="400*mm"/> + <constant name="YokeEndcap_outer_radius" value="6000*mm"/> + <constant name="YokeEndcap_min_z" value="3755*mm"/> + <constant name="YokeEndcap_max_z" value="5300*mm"/> + <constant name="YokeEndcap_outer_symmetry" value="12"/> + <constant name="YokeEndcap_inner_symmetry" value="0"/> + + <constant name="CompSol_min_z" value="1230*mm"/> + + <constant name="LumiCal_max_z" value="1186.5*mm" /> + <constant name="LumiCal_min_z" value="1074*mm"/> + + <constant name="LumiCal_dz" value="(LumiCal_max_z-LumiCal_min_z)/2.0"/> + + <constant name="LumiCal_inner_radius" value="55.0*mm"/> + <constant name="LumiCal_outer_radius" value="112.0*mm- env_safety"/> + + <constant name="LumiCal_Instr_thickness" value="20*mm"/> + <constant name="LumiCal_Instr_inner_radius" value="LumiCal_outer_radius"/> + <constant name="LumiCal_Instr_outer_radius" value="LumiCal_outer_radius+LumiCal_Instr_thickness - env_safety"/> + + <constant name="LumiCal_Cool_thickness" value="9.75*mm"/> + <constant name="LumiCal_Cool_inner_radius" value="LumiCal_Instr_outer_radius"/> + <constant name="LumiCal_Cool_outer_radius" value="LumiCal_Instr_outer_radius+LumiCal_Cool_thickness"/> + + <constant name="Lcal_services_rmax" value="LumiCal_outer_radius+30*mm"/> + <constant name="Lcal_offset_phi" value=" 0."/> + <!--preliminary LumiCal shielding--> + <!--back shielding--> + <constant name="LumiCal_Shield_inner_radius" value="LumiCal_inner_radius"/> + <constant name="LumiCal_Shield_outer_radius" value="LumiCal_outer_radius+LumiCal_Instr_thickness+LumiCal_Cool_thickness"/> + <constant name="LumiCal_shield_dz" value="1.75*mm"/> + <!--nose--> + <constant name="LumiCal_NoseShield_inner_radius" value="LumiCal_inner_radius-5*mm"/> + <constant name="LumiCal_NoseShield_outer_radius" value="LumiCal_inner_radius+10*mm"/> + <constant name="LumiCal_nose_shield_dz" value="12*mm"/> + + <constant name="BeamCal_inner_radius" value="32*mm"/> + <constant name="BeamCal_outer_radius" value="150*mm"/> + <constant name="BeamCal_min_z" value="3181*mm"/> + <constant name="BeamCal_max_z" value="3441*mm"/> + <constant name="BeamCal_dz" value="(BeamCal_max_z-BeamCal_min_z)/2.0"/> + + <constant name="Kicker_inner_radius" value="4*mm"/> + <constant name="Kicker_outer_radius" value="25*mm"/> + <constant name="Kicker_min_z" value="3480*mm"/> + <constant name="Kicker_max_z" value="3780*mm"/> + + <constant name="BPM_inner_radius" value="36*mm"/> + <constant name="BPM_outer_radius" value="55*mm"/> + <constant name="BPM_min_z" value="3790*mm"/> + <constant name="BPM_max_z" value="3880*mm"/> + + <constant name="QD0_min_z" value="2000*mm"/> + <constant name="QD0_max_z" value="5200*mm"/> + <constant name="QD0Coil_outer_radius" value="30*mm"/> + <constant name="CollimatorInFrontOfQD0_dz" value="20*cm"/> + <constant name="CollimatorInFrontOfQD0_radius" value="10*mm"/> + <constant name="CollimatorInFrontOfQD0_dr" value="16*mm"/> + + <constant name="tracker_region_zmax" value="OuterTracker_half_length"/> + <constant name="tracker_region_rmax" value="OuterTracker_outer_radius"/> + + <constant name="GlobalTrackerReadoutID" type="string" value="system:5,side:-2,layer:6,module:11,sensor:8"/> + </define> + + + <limits> + <limitset name="cal_limits"> + <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> + </limitset> + </limits> + <regions> + <region name="BeampipeRegion"/> + <region name="VertexBarrelRegion"/> + <region name="VertexEndcapRegion"/> + </regions> + + + <display> + <vis name="VXDVis" alpha="0.1" r="0.1" g=".5" b=".5" showDaughters="true" visible="false"/> + <vis name="VXDLayerVis" alpha="1.0" r="0.1" g=".5" b=".5" showDaughters="true" visible="true"/> + <vis name="VXDSupportVis" alpha="1.0" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="ITVis" alpha="1.0" r="0.54" g="0.43" b="0.04" showDaughters="true" visible="true"/> + <vis name="OTVis" alpha="1.0" r="0.8" g="0.8" b="0.4" showDaughters="true" visible="false"/> + <vis name="ECALVis" alpha="1.0" r="0.2" g="0.6" b="0" showDaughters="true" visible="true"/> + <vis name="HCALVis" alpha="1.0" r="0.078" g="0.01176" b="0.588" showDaughters="true" visible="true"/> + <vis name="SOLVis" alpha="1.0" r="0.4" g="0.4" b="0.4" showDaughters="true" visible="true"/> + <vis name="YOKEVis" alpha="1.0" r="0.6" g="0.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="LCALInstrVis" alpha="1.0" r="0.35" g="0.0" b="0.47" showDaughters="true" visible="true"/> + <vis name="LCALVis" alpha="1.0" r="0.25" g="0.88" b="0.81" showDaughters="true" visible="true"/> + <vis name="LCALCoolVis" alpha="1.0" r="0.2" g="0.6" b="0" showDaughters="true" visible="true"/> + <vis name="BCALVis" alpha="1.0" r="0.0" g="0.4" b="0.4" showDaughters="true" visible="true"/> + <vis name="KICKVis" alpha="1.0" r="1.0" g="0.498" b="0.0" showDaughters="true" visible="true"/> + <vis name="QD0CoilIVis" alpha="1.0" r="1.0" g="0.498" b="0.0" showDaughters="true" visible="true"/> + <vis name="QD0CoilOVis" alpha="1.0" r="1.0" g="0.25" b="0.0" showDaughters="true" visible="true"/> + <vis name="CompSolVis" alpha="1.0" r="0.5" g="0.5" b="0.0" showDaughters="true" visible="true"/> + <vis name="ScreenSolVis" alpha="1.0" r="1" g="1" b="0" showDaughters="true" visible="true"/> + <vis name="ColliVis" alpha="1.0" r="0.7" g="0.5" b="1" showDaughters="true" visible="true"/> + <vis name="TantalumVis" alpha="1.0" r="1" g="0.5" b="0.5" showDaughters="true" visible="true"/> + <vis name="BPMVis" alpha="1.0" r="0.25" g="0.88" b="0.81" showDaughters="true" visible="true"/> + <vis name="SupportVis" alpha="1" r="0.2" g="0.2" b="0.2" showDaughters="true" visible="true"/> + </display> + +</lccdd> diff --git a/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml b/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml new file mode 100644 index 000000000..a3164bd96 --- /dev/null +++ b/examples/ClientTests/compact/FCCmachine/FCCee_DectMaster.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + + + + <info name="FCCDectMaster" + title="FCCee Machine Elements geometry master file" + author="Niloufar Alipour Tehrani (adapted: G Ganis)" + url="no" + status="development" + version="1.0"> + <comment> + Machine-releated elements for the FCCee Detector concept. + </comment> + </info> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + <materials> + <material name="beam" state="gas"> + <P unit="pascal" value="6.25e-06"/> + <MEE unit="eV" value="38.5760755714278"/> + <D unit="g/cm3" value="1.7e-14"/> + <fraction n="0.36264" ref="H"/> + <fraction n="0.36276" ref="N"/> + <fraction n="0.117748421296248" ref="C"/> + <fraction n="0.156851578703752" ref="O"/> + </material> + <material formula="SolenoidMixture" name="SolenoidMixture" state="solid" > + <RL type="X0" unit="cm" value="1.75749" /> + <NIL type="lambda" unit="cm" value="16.959" /> + <D type="density" unit="g/cm3" value="7.874" /> + <composite n="1" ref="Fe" /> + </material> + + </materials> + + <define> + <constant name="world_size" value="25*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + </define> + + <include ref="./FCCee_DectDimensions.xml" /> + + <include ref="Beampipe.xml"/> + <include ref="BeamInstrumentation.xml"/> + <include ref="HOMAbsorber.xml"/> + +</lccdd> diff --git a/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml b/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml new file mode 100644 index 000000000..dd4688f48 --- /dev/null +++ b/examples/ClientTests/compact/FCCmachine/HOMAbsorber.xml @@ -0,0 +1,62 @@ +<lccdd> + + <info name="FCCee" + title="FCCee Beam instrumentation: taken correspoding to CLD: HOMAbsorber_v00.xml" + author="nalipour taken from lcgeo" + url="no" + status="development" + version="1.0"> + <comment> Higher mode absorber for FCCee detector based on CLD</comment> + </info> + + <detectors> + + <detector name="HOMAbsorber" type="MaterialEnvelope_o1_v01" vis="SeeThrough" id="DetID_HOMAbsorber" insideTrackingVolume="false" > + + <envelope vis="ITVis"> + + <shape type="BooleanShape" operation="Union" material="Iron"> + + <shape type="BooleanShape" operation="Intersection"> + <shape type="Box" dx="world_side" dy="world_side" dz="world_side"/> + <shape type="BooleanShape" operation="Subtraction"> + <shape type="Box" dx="42.5*mm" dy="37.5*mm" dz="(100.67/2.)*mm" material="Iron" /> + <shape type="Cone" rmin1="0" rmax1="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" rmin2="0" rmax2="(1298.665*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" z="(100.665/2.)*mm+0.1*mm"/> + <position x="0" y="0" z="0"/> + </shape> + <position x="0" y="0" z="1198*mm+(100.665/2.)*mm"/> + </shape> + + <shape type="BooleanShape" operation="Intersection"> + <shape type="Box" dx="world_side" dy="world_side" dz="world_side"/> + <shape type="BooleanShape" operation="Subtraction"> + <shape type="Box" dx="42.5*mm" dy="37.5*mm" dz="(100.67/2.)*mm" material="Iron" /> + <shape type="Cone" rmin1="0" rmax1="(1298.665*mm+0.2*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" rmin2="0" rmax2="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.2*mm" z="(100.665/2.)*mm+0.1*mm" /> + <position x="0" y="0" z="0"/> + </shape> + <position x="0" y="0" z="-(1198*mm+(100.665/2.)*mm)"/> + </shape> + + </shape> + + </envelope> + + </detector> + + <detector name="HOMAbsorbers_PunchThrough" type="DD4hep_FCC_Mask_o1_v01" insideTrackingVolume="true" vis="ITVis" > + <parameter crossingangle="CrossingAngle" /> + + <section type="PunchedCenter" + start="1198*mm" + end="1298.665*mm" + rMin1="SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm" + rMin2="SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm " + rMax1="(1198*mm )*0.015+ SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm " + rMax2="(1298.665*mm)*0.015+SeparatedBeamPipe_rmax +BeamPipeWidth+0.1*mm " + material="Iron" name="HOM1" /> + + </detector> + + </detectors> + +</lccdd> diff --git a/examples/ClientTests/compact/VisAttr_Extend.xml b/examples/ClientTests/compact/VisAttr_Extend.xml new file mode 100644 index 000000000..bf6fac329 --- /dev/null +++ b/examples/ClientTests/compact/VisAttr_Extend.xml @@ -0,0 +1,61 @@ +<?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. + # + #========================================================================== +--> + + <info name="alignment_boxes" + title="Alignment test with 2 simple boxes" + author="Markus Frank" + url="http://www.cern.ch/lhcb" + status="development" + version="$Id: compact.xml 513 2013-04-05 14:31:53Z gaede $"> + <comment>Alignment test with 2 simple boxes</comment> + </info> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + + <define> + <constant name="world_side" value="30000"/> + <constant name="world_x" value="world_side"/> + <constant name="world_y" value="world_side"/> + <constant name="world_z" value="world_side"/> + </define> + + <display> + <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> + <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> + <vis name="B1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/> + <vis name="B2_vis" extend="B1_vis" r="0" g="1"/> + </display> + + <detectors> + <comment>Boxes</comment> + <detector id="3" name="B3" type="DD4hep_BoxSegment" vis="B2_vis"> + <comment>Vertical box</comment> + <material name="Steel235"/> + <box x="10" y="20" z="30"/> + <position x="-10" y="30" z="10"/> + <rotation x="0" y="0" z="0"/> + </detector> + <detector id="3" name="B4" type="DD4hep_BoxSegment" vis="B1_vis"> + <comment>Vertical box</comment> + <material name="Steel235"/> + <box x="10" y="20" z="30"/> + <position x="0" y="0" z="0"/> + <rotation x="0" y="0" z="0"/> + </detector> + </detectors> +</lccdd> diff --git a/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp b/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp new file mode 100644 index 000000000..5a6590be5 --- /dev/null +++ b/examples/ClientTests/src/FCC_Mask_o1_v01_geo.cpp @@ -0,0 +1,236 @@ +//==================================================================== +// LCGeo - LC detector models in DD4hep +//-------------------------------------------------------------------- +// Mask based on the Beampipe driver (based on TubeX from Mokka), but not +// filling the centre with Beam vaccum, just places cylinders in arbitrary +// places with different alignments +// A.Sailer, CERN +// $Id$ +//==================================================================== +#include "FCC_OtherDetectorHelpers.h" + + +// todo: remove gaudi logging and properly capture output +#define endmsg std::endl +#define lLog std::cout +namespace MSG { +const std::string ERROR = " Error: "; +const std::string DEBUG = " Debug: "; +const std::string INFO = " Info: "; +} + +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetFactoryHelper.h" +#include <cmath> +#include <string> + +using dd4hep::Assembly; +using dd4hep::ConeSegment; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::Ref_t; +using dd4hep::RotateY; +using dd4hep::RotationY; +using dd4hep::SensitiveDetector; +using dd4hep::Solid; +using dd4hep::SubtractionSolid; +using dd4hep::Transform3D; +using dd4hep::Tube; +using dd4hep::Volume; + +static Ref_t create_element(Detector& theDetector, xml_h xmlHandle, SensitiveDetector /*sens*/) { + //------------------------------------------ + // See comments starting with '//**' for + // hints on porting issues + //------------------------------------------ + + // Access to the XML File + xml_det_t xmlMask = xmlHandle; + const std::string name = xmlMask.nameStr(); + + //-------------------------------- + Assembly envelope(name + "_assembly"); + //-------------------------------- + + DetElement tube(name, xmlMask.id()); + + const double phi1 = 0; + const double phi2 = 360.0 * dd4hep::degree; + + // Parameters we have to know about + dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter)); + const double crossingAngle = xmlParameter.attr<double>(_Unicode(crossingangle)) * 0.5; // only half the angle + + for (xml_coll_t c(xmlMask, Unicode("section")); c; ++c) { + + xml_comp_t xmlSection(c); + + ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr<std::string>(_Unicode(type))); + const double zStart = xmlSection.attr<double>(_Unicode(start)); + const double zEnd = xmlSection.attr<double>(_Unicode(end)); + const double rInnerStart = xmlSection.attr<double>(_Unicode(rMin1)); + const double rInnerEnd = xmlSection.attr<double>(_Unicode(rMin2)); + const double rOuterStart = xmlSection.attr<double>(_Unicode(rMax1)); + const double rOuterEnd = xmlSection.attr<double>(_Unicode(rMax2)); + const double thickness = rOuterStart - rInnerStart; + Material sectionMat = theDetector.material(xmlSection.materialStr()); + const std::string volName = "tube_" + xmlSection.nameStr(); + + lLog << MSG::DEBUG << std::setw(8) << zStart << std::setw(8) << zEnd << std::setw(8) << rInnerStart << std::setw(8) + << rInnerEnd << std::setw(8) << rOuterStart << std::setw(8) << rOuterEnd << std::setw(8) << thickness + << std::setw(8) << crossType << std::setw(15) << volName << std::setw(15) << sectionMat.name() + << endmsg; + + // things which can be calculated immediately + const double zHalf = fabs(zEnd - zStart) * 0.5; // half z length of the cone + const double zPosition = fabs(zEnd + zStart) * 0.5; // middle z position + Material material = sectionMat; + + // this could mess up your geometry, so better check it + if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)) { + throw std::runtime_error(" Mask_o1_v01_geo.cpp : checkForSensibleGeometry() failed "); + } + + const double rotateAngle = + getCurrentAngle(crossingAngle, crossType); // for the placement at +z (better make it const now) + const double mirrorAngle = M_PI - rotateAngle; // for the "mirrored" placement at -z + // the "mirroring" in fact is done by a rotation of (almost) 180 degrees around the y-axis + + switch (crossType) { + case ODH::kCenter: + case ODH::kUpstream: + case ODH::kDnstream: { + // a volume on the z-axis, on the upstream branch, or on the downstream branch + + // absolute transformations for the placement in the world + Transform3D transformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle)); + Transform3D transmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle)); + + // solid for the tube (including vacuum and wall): a solid cone + ConeSegment tubeSolid(zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2); + + // tube consists of vacuum + Volume tubeLog(volName, tubeSolid, material); + tubeLog.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog, transformer); + envelope.placeVolume(tubeLog, transmirror); + + } break; + + case ODH::kPunchedCenter: { + // a cone with one or two inner holes (two tubes are punched out) + + const double rUpstreamPunch = rInnerStart; // just alias names denoting what is meant here + const double rDnstreamPunch = rInnerEnd; // (the database entries are "abused" in this case) + + // relative transformations for the composition of the SubtractionVolumes + Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0)); + Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0)); + + // absolute transformations for the final placement in the world (angles always equal zero and 180 deg) + Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle)); + Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle)); + + // the main solid and the two pieces (only tubes, for the moment) which will be punched out + ConeSegment wholeSolid(zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2); + Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1; + + // the punched subtraction solids can be asymmetric and therefore have to be created twice: + // one time in the "right" way, another time in the "reverse" way, because the "mirroring" + // rotation around the y-axis will not only exchange +z and -z, but also +x and -x + + if (rUpstreamPunch > 1e-6) { // do we need a hole on the upstream branch? + Tube upstreamPunch(0, rUpstreamPunch, 5 * zHalf, phi1, phi2); // a bit longer + tmpSolid0 = SubtractionSolid(wholeSolid, upstreamPunch, upstreamTransformer); + tmpSolid1 = SubtractionSolid(wholeSolid, upstreamPunch, dnstreamTransformer); // [sic] + } else { // dont't do anything, just pass on the unmodified shape + tmpSolid0 = wholeSolid; + tmpSolid1 = wholeSolid; + } + + if (rDnstreamPunch > 1e-6) { // do we need a hole on the downstream branch? + Tube dnstreamPunch(0, rDnstreamPunch, 5 * zHalf, phi1, phi2); // a bit longer + finalSolid0 = SubtractionSolid(tmpSolid0, dnstreamPunch, dnstreamTransformer); + finalSolid1 = SubtractionSolid(tmpSolid1, dnstreamPunch, upstreamTransformer); // [sic] + } else { // dont't do anything, just pass on the unmodified shape + finalSolid0 = tmpSolid0; + finalSolid1 = tmpSolid1; + } + + // tube consists of vacuum (will later have two different daughters) + Volume tubeLog0(volName + "_0", finalSolid0, material); + Volume tubeLog1(volName + "_1", finalSolid1, material); + tubeLog0.setVisAttributes(theDetector, xmlMask.visStr()); + tubeLog1.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog0, placementTransformer); + envelope.placeVolume(tubeLog1, placementTransmirror); + + break; + } + + case ODH::kPunchedUpstream: + case ODH::kPunchedDnstream: { + // a volume on the upstream or downstream branch with two inner holes + // (implemented as a cone from which another tube is punched out) + + const double rCenterPunch = (crossType == ODH::kPunchedUpstream) + ? (rInnerStart) + : (rInnerEnd); // just alias names denoting what is meant here + const double rOffsetPunch = (crossType == ODH::kPunchedDnstream) + ? (rInnerStart) + : (rInnerEnd); // (the database entries are "abused" in this case) + + // relative transformations for the composition of the SubtractionVolumes + Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0)); + Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0)); + + // absolute transformations for the final placement in the world + Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle)); + Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle)); + + // the main solid and the piece (only a tube, for the moment) which will be punched out + ConeSegment wholeSolid(zHalf, rCenterPunch, rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2); + Tube punchSolid(0, rOffsetPunch, 5 * zHalf, phi1, phi2); // a bit longer + + // the punched subtraction solids can be asymmetric and therefore have to be created twice: + // one time in the "right" way, another time in the "reverse" way, because the "mirroring" + // rotation around the y-axis will not only exchange +z and -z, but also +x and -x + SubtractionSolid finalSolid0(wholeSolid, punchSolid, punchTransformer); + SubtractionSolid finalSolid1(wholeSolid, punchSolid, punchTransmirror); + + // tube consists of vacuum (will later have two different daughters) + Volume tubeLog0(volName + "_0", finalSolid0, material); + Volume tubeLog1(volName + "_1", finalSolid1, material); + tubeLog0.setVisAttributes(theDetector, xmlMask.visStr()); + tubeLog1.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog0, placementTransformer); + envelope.placeVolume(tubeLog1, placementTransmirror); + + break; + } + default: { throw std::runtime_error(" Mask_o1_v01_geo.cpp : fatal failure !! ?? "); } + + } // end switch + } // for all xmlSections + + //-------------------------------------- + Volume mother = theDetector.pickMotherVolume(tube); + PlacedVolume pv(mother.placeVolume(envelope)); + pv.addPhysVolID("system", xmlMask.id()); //.addPhysVolID("side", 0 ) ; + + tube.setVisAttributes(theDetector, xmlMask.visStr(), envelope); + + tube.setPlacement(pv); + + return tube; +} +DECLARE_DETELEMENT(DD4hep_FCC_Mask_o1_v01, create_element) diff --git a/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp b/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp new file mode 100644 index 000000000..8f50fa40c --- /dev/null +++ b/examples/ClientTests/src/FCC_Mask_o1_v01_noRot_geo.cpp @@ -0,0 +1,235 @@ +//==================================================================== +// LCGeo - LC detector models in DD4hep +//-------------------------------------------------------------------- +// Mask based on the Beampipe driver (based on TubeX from Mokka), but not +// filling the centre with Beam vaccum, just places cylinders in arbitrary +// places with different alignments +// A.Sailer, CERN +// $Id$ +//==================================================================== +#include "FCC_OtherDetectorHelpers.h" + +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetFactoryHelper.h" +#include <cmath> +#include <string> + +using dd4hep::Assembly; +using dd4hep::ConeSegment; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::Ref_t; +using dd4hep::RotateY; +using dd4hep::RotationY; +using dd4hep::RotateX; +using dd4hep::RotationX; +using dd4hep::SensitiveDetector; +using dd4hep::Solid; +using dd4hep::SubtractionSolid; +using dd4hep::Transform3D; +using dd4hep::Tube; +using dd4hep::Volume; + +static Ref_t create_element(Detector& theDetector, xml_h xmlHandle, SensitiveDetector /*sens*/) { + + //------------------------------------------ + // See comments starting with '//**' for + // hints on porting issues + //------------------------------------------ + + std::cout << "This is the Mask:" << std::endl; + + // Access to the XML File + xml_det_t xmlMask = xmlHandle; + const std::string name = xmlMask.nameStr(); + + //-------------------------------- + Assembly envelope(name + "_assembly"); + //-------------------------------- + + DetElement tube(name, xmlMask.id()); + + // const double phi1 = 0 ; + // const double phi2 = 360.0*dd4hep::degree; + + // Parameters we have to know about + dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter)); + const double crossingAngle = xmlParameter.attr<double>(_Unicode(crossingangle)) * 0.5; // only half the angle + + for (xml_coll_t c(xmlMask, Unicode("section")); c; ++c) { + + xml_comp_t xmlSection(c); + + ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr<std::string>(_Unicode(type))); + const double zStart = xmlSection.attr<double>(_Unicode(start)); + const double zEnd = xmlSection.attr<double>(_Unicode(end)); + const double rInnerStart = xmlSection.attr<double>(_Unicode(rMin1)); + const double rInnerEnd = xmlSection.attr<double>(_Unicode(rMin2)); + const double rOuterStart = xmlSection.attr<double>(_Unicode(rMax1)); + const double rOuterEnd = xmlSection.attr<double>(_Unicode(rMax2)); + const double phi1 = xmlSection.attr<double>(_Unicode(Phi1)); + const double phi2 = xmlSection.attr<double>(_Unicode(Phi2)); + const double thickness = rOuterStart - rInnerStart; + Material sectionMat = theDetector.material(xmlSection.materialStr()); + const std::string volName = "tube_" + xmlSection.nameStr(); + + std::cout << std::setw(8) << zStart << std::setw(8) << zEnd << std::setw(8) << rInnerStart << std::setw(8) + << rInnerEnd << std::setw(8) << rOuterStart << std::setw(8) << rOuterEnd << std::setw(8) << thickness + << std::setw(8) << crossType << std::setw(8) << phi1 << std::setw(8) << phi2 << std::setw(15) << volName + << std::setw(15) << sectionMat.name() << std::endl; + + // things which can be calculated immediately + const double zHalf = fabs(zEnd - zStart) * 0.5; // half z length of the cone + const double zPosition = fabs(zEnd + zStart) * 0.5; // middle z position + Material material = sectionMat; + + // this could mess up your geometry, so better check it + if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)) { + throw std::runtime_error(" Mask_o1_v01_noRot_geo.cpp : checkForSensibleGeometry() failed "); + } + + const double rotateAngle = + getCurrentAngle(crossingAngle, crossType); // for the placement at +z (better make it const now) + const double mirrorAngle = M_PI - rotateAngle; // for the "mirrored" placement at -z + // the "mirroring" in fact is done by a rotation of (almost) 180 degrees around the y-axis + + switch (crossType) { + case ODH::kCenter: + case ODH::kUpstream: + case ODH::kDnstream: { + // a volume on the z-axis, on the upstream branch, or on the downstream branch + + // absolute transformations for the placement in the world, rotate over X + Transform3D transformer(RotationX(rotateAngle), RotateX(Position(0, 0, zPosition), rotateAngle)); + Transform3D transmirror(RotationX(mirrorAngle), RotateX(Position(0, 0, zPosition), mirrorAngle)); + + // solid for the tube (including vacuum and wall): a solid cone + ConeSegment tubeSolid(zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2); + + // tube consists of vacuum + Volume tubeLog(volName, tubeSolid, material); + tubeLog.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog, transformer); + envelope.placeVolume(tubeLog, transmirror); + + } break; + + case ODH::kPunchedCenter: { + // a cone with one or two inner holes (two tubes are punched out) + + const double rUpstreamPunch = rInnerStart; // just alias names denoting what is meant here + const double rDnstreamPunch = rInnerEnd; // (the database entries are "abused" in this case) + + // relative transformations for the composition of the SubtractionVolumes + Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0)); + Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0)); + + // absolute transformations for the final placement in the world (angles always equal zero and 180 deg) + Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle)); + Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle)); + + // the main solid and the two pieces (only tubes, for the moment) which will be punched out + ConeSegment wholeSolid(zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2); + Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1; + + // the punched subtraction solids can be asymmetric and therefore have to be created twice: + // one time in the "right" way, another time in the "reverse" way, because the "mirroring" + // rotation around the y-axis will not only exchange +z and -z, but also +x and -x + + if (rUpstreamPunch > 1e-6) { // do we need a hole on the upstream branch? + Tube upstreamPunch(0, rUpstreamPunch, 5 * zHalf, phi1, phi2); // a bit longer + tmpSolid0 = SubtractionSolid(wholeSolid, upstreamPunch, upstreamTransformer); + tmpSolid1 = SubtractionSolid(wholeSolid, upstreamPunch, dnstreamTransformer); // [sic] + } else { // dont't do anything, just pass on the unmodified shape + tmpSolid0 = wholeSolid; + tmpSolid1 = wholeSolid; + } + + if (rDnstreamPunch > 1e-6) { // do we need a hole on the downstream branch? + Tube dnstreamPunch(0, rDnstreamPunch, 5 * zHalf, phi1, phi2); // a bit longer + finalSolid0 = SubtractionSolid(tmpSolid0, dnstreamPunch, dnstreamTransformer); + finalSolid1 = SubtractionSolid(tmpSolid1, dnstreamPunch, upstreamTransformer); // [sic] + } else { // dont't do anything, just pass on the unmodified shape + finalSolid0 = tmpSolid0; + finalSolid1 = tmpSolid1; + } + + // tube consists of vacuum (will later have two different daughters) + Volume tubeLog0(volName + "_0", finalSolid0, material); + Volume tubeLog1(volName + "_1", finalSolid1, material); + tubeLog0.setVisAttributes(theDetector, xmlMask.visStr()); + tubeLog1.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog0, placementTransformer); + envelope.placeVolume(tubeLog1, placementTransmirror); + + break; + } + + case ODH::kPunchedUpstream: + case ODH::kPunchedDnstream: { + // a volume on the upstream or downstream branch with two inner holes + // (implemented as a cone from which another tube is punched out) + + const double rCenterPunch = (crossType == ODH::kPunchedUpstream) + ? (rInnerStart) + : (rInnerEnd); // just alias names denoting what is meant here + const double rOffsetPunch = (crossType == ODH::kPunchedDnstream) + ? (rInnerStart) + : (rInnerEnd); // (the database entries are "abused" in this case) + + // relative transformations for the composition of the SubtractionVolumes + Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0)); + Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0)); + + // absolute transformations for the final placement in the world + Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle)); + Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle)); + + // the main solid and the piece (only a tube, for the moment) which will be punched out + ConeSegment wholeSolid(zHalf, rCenterPunch, rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2); + Tube punchSolid(0, rOffsetPunch, 5 * zHalf, phi1, phi2); // a bit longer + + // the punched subtraction solids can be asymmetric and therefore have to be created twice: + // one time in the "right" way, another time in the "reverse" way, because the "mirroring" + // rotation around the y-axis will not only exchange +z and -z, but also +x and -x + SubtractionSolid finalSolid0(wholeSolid, punchSolid, punchTransformer); + SubtractionSolid finalSolid1(wholeSolid, punchSolid, punchTransmirror); + + // tube consists of vacuum (will later have two different daughters) + Volume tubeLog0(volName + "_0", finalSolid0, material); + Volume tubeLog1(volName + "_1", finalSolid1, material); + tubeLog0.setVisAttributes(theDetector, xmlMask.visStr()); + tubeLog1.setVisAttributes(theDetector, xmlMask.visStr()); + + // placement of the tube in the world, both at +z and -z + envelope.placeVolume(tubeLog0, placementTransformer); + envelope.placeVolume(tubeLog1, placementTransmirror); + + break; + } + default: { throw std::runtime_error(" Mask_o1_v01_geo.cpp : fatal failure !! ?? "); } + + } // end switch + } // for all xmlSections + + //-------------------------------------- + Volume mother = theDetector.pickMotherVolume(tube); + PlacedVolume pv(mother.placeVolume(envelope)); + pv.addPhysVolID("system", xmlMask.id()); //.addPhysVolID("side", 0 ) ; + + tube.setVisAttributes(theDetector, xmlMask.visStr(), envelope); + + tube.setPlacement(pv); + + return tube; +} + +DECLARE_DEPRECATED_DETELEMENT(DD4hep_FCC_Mask_o1_v01_noRot, create_element) + diff --git a/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp b/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp new file mode 100644 index 000000000..8a8a66589 --- /dev/null +++ b/examples/ClientTests/src/FCC_MaterialEnvelope_o1_v01.cpp @@ -0,0 +1,35 @@ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M. Petric +// A driver just to place a envelope, to placement of dead material +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Layering.h" +#include "XML/Utilities.h" + +using namespace std; + +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::Ref_t; +using dd4hep::SensitiveDetector; + +// workaround for DD4hep v00-14 (and older) +#ifndef DD4HEP_VERSION_GE +#define DD4HEP_VERSION_GE(a, b) 0 +#endif + +static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector) { + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + DetElement sdet(det_name, x_det.id()); + + dd4hep::xml::createPlacedEnvelope(theDetector, e, sdet); + + return sdet; +} + +DECLARE_DETELEMENT(MaterialEnvelope_o1_v01, create_detector) diff --git a/examples/ClientTests/src/FCC_OtherDetectorHelpers.h b/examples/ClientTests/src/FCC_OtherDetectorHelpers.h new file mode 100644 index 000000000..70cc47297 --- /dev/null +++ b/examples/ClientTests/src/FCC_OtherDetectorHelpers.h @@ -0,0 +1,110 @@ +#ifndef Other_Helpers_hh +#define Other_Helpers_hh 1 +//==================================================================== +// LCGeo - LC detector models in DD4hep +//-------------------------------------------------------------------- +// Helper functions used by detector constructers +// A.Sailer, CERN +// $Id$ +//==================================================================== + +#include <iostream> +#include <map> +#include <stdexcept> + +namespace ODH { // OtherDetectorHelpers + +typedef enum { // These constants are also used in the MySQL database: + kCenter = 0, // centered on the z-axis + kUpstream = 1, // on the upstream branch, rotated by half the crossing angle + kDnstream = 2, // on the downstream branch, rotated by half the crossing angle + kPunchedCenter = 3, // centered, with one or two inner holes + kPunchedUpstream = 4, // on the upstream branch, with two inner holes + kPunchedDnstream = 5, // on the downstrem branch, with two inner holes + kUpstreamClippedFront = 6, // upstream, with the front face parallel to the xy-plane + kDnstreamClippedFront = 7, // downstream, with the front face parallel to the xy-plane + kUpstreamClippedRear = 8, // upstream, with the rear face parallel to the xy-plane + kDnstreamClippedRear = 9, // downstream, with the rear face parallel to the xy-plane + kUpstreamClippedBoth = 10, // upstream, with both faces parallel to the xy-plane + kDnstreamClippedBoth = 11, // downstream, with both faces parallel to the xy-plane + kUpstreamSlicedFront = 12, // upstream, with the front face parallel to a tilted piece + kDnstreamSlicedFront = 13, // downstream, with the front face parallel to a tilted piece + kUpstreamSlicedRear = 14, // upstream, with the rear face parallel to a tilted piece + kDnstreamSlicedRear = 15, // downstream, with the rear face parallel to a tilted piece + kUpstreamSlicedBoth = 16, // upstream, with both faces parallel to a tilted piece + kDnstreamSlicedBoth = 17 // downstream, with both faces parallel to a tilted piece +} ECrossType; + +inline ECrossType getCrossType(std::string const& type) { + + std::map<std::string, ODH::ECrossType> CrossTypes; + CrossTypes["Center"] = ODH::kCenter; + CrossTypes["Upstream"] = ODH::kUpstream; + CrossTypes["Dnstream"] = ODH::kDnstream; + CrossTypes["PunchedCenter"] = ODH::kPunchedCenter; + CrossTypes["PunchedUpstream"] = ODH::kPunchedUpstream; + CrossTypes["PunchedDnstream"] = ODH::kPunchedDnstream; + CrossTypes["UpstreamClippedFront"] = ODH::kUpstreamClippedFront; + CrossTypes["DnstreamClippedFront"] = ODH::kDnstreamClippedFront; + CrossTypes["UpstreamClippedRear"] = ODH::kUpstreamClippedRear; + CrossTypes["DnstreamClippedRear"] = ODH::kDnstreamClippedRear; + CrossTypes["UpstreamClippedBoth"] = ODH::kUpstreamClippedBoth; + CrossTypes["DnstreamClippedBoth"] = ODH::kDnstreamClippedBoth; + CrossTypes["UpstreamSlicedFront"] = ODH::kUpstreamSlicedFront; + CrossTypes["DnstreamSlicedFront"] = ODH::kDnstreamSlicedFront; + CrossTypes["UpstreamSlicedRear"] = ODH::kUpstreamSlicedRear; + CrossTypes["DnstreamSlicedRear"] = ODH::kDnstreamSlicedRear; + CrossTypes["UpstreamSlicedBoth"] = ODH::kUpstreamSlicedBoth; + CrossTypes["DnstreamSlicedBoth"] = ODH::kDnstreamSlicedBoth; + + std::map<std::string, ODH::ECrossType>::const_iterator ct = CrossTypes.find(type); + if (ct == CrossTypes.end()) { + throw std::runtime_error("Unknown Crossing Type for this geometry"); + } + return ct->second; +} + +inline bool checkForSensibleGeometry(double crossingAngle, ECrossType crossType) { + if (crossingAngle == 0 && crossType != kCenter) { + std::cout << "Mask: You are trying to build a crossing geometry without a crossing angle.\n" + "This is probably not what you want - better check your geometry data!" + << std::endl; + return false; // premature exit, dd4hep will abort now + } + return true; +} + +inline double getCurrentAngle(double crossingAngle, ECrossType crossType) { + double tmpAngle; + switch (crossType) { + case kUpstream: + case kPunchedUpstream: + case kUpstreamClippedFront: + case kUpstreamClippedRear: + case kUpstreamClippedBoth: + case kUpstreamSlicedFront: + case kUpstreamSlicedRear: + case kUpstreamSlicedBoth: + tmpAngle = -crossingAngle; + break; + case kDnstream: + case kPunchedDnstream: + case kDnstreamClippedFront: + case kDnstreamClippedRear: + case kDnstreamClippedBoth: + case kDnstreamSlicedFront: + case kDnstreamSlicedRear: + case kDnstreamSlicedBoth: + tmpAngle = +crossingAngle; + break; + default: + tmpAngle = 0; + break; + } + + return tmpAngle; +} + +} // namespace + +#endif // Other_Helpers_hh diff --git a/examples/DDCAD/compact/Import_FCC_Machine.xml b/examples/DDCAD/compact/Import_FCC_Machine.xml new file mode 100644 index 000000000..c63a2fa3f --- /dev/null +++ b/examples/DDCAD/compact/Import_FCC_Machine.xml @@ -0,0 +1,50 @@ +<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> + <materials> + <material name="beam" state="gas"> + <P unit="pascal" value="6.25e-06"/> + <MEE unit="eV" value="38.5760755714278"/> + <D unit="g/cm3" value="1.7e-14"/> + <fraction n="0.36264" ref="H"/> + <fraction n="0.36276" ref="N"/> + <fraction n="0.117748421296248" ref="C"/> + <fraction n="0.156851578703752" ref="O"/> + </material> + <material formula="SolenoidMixture" name="SolenoidMixture" state="solid" > + <RL type="X0" unit="cm" value="1.75749" /> + <NIL type="lambda" unit="cm" value="16.959" /> + <D type="density" unit="g/cm3" value="7.874" /> + <composite n="1" ref="Fe" /> + </material> + </materials> + <define> + <constant name="world_size" value="25*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + </define> + + <detectors> + <detector id="1" name="Shape_Collada" type="DD4hep_TestShape_Creator"> + <check> + <shape type="CAD_MultiVolume" ref="./Machine.collada" unit="cm"/> + </check> + </detector> + </detectors> +</lccdd> -- GitLab