From 538b23f559eb48e25d98a91f142bf8cbe7083c84 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 21 May 2014 18:49:29 +0000 Subject: [PATCH] Please see doc/release.notes --- DDCore/include/DD4hep/Detector.h | 51 +--- .../include/DD4hep/objects/DetectorInterna.h | 4 + DDCore/src/Detector.cpp | 5 + DDCore/src/Evaluator/setSystemOfUnits.cpp | 4 +- DDCore/src/Volumes.cpp | 40 ++- DDCore/src/plugins/Compact2Objects.cpp | 100 ++++--- doc/release.notes | 20 ++ examples/CLICSiD/src/ForwardDetector_geo.cpp | 2 +- .../CLICSiD/src/MultiLayerTracker_geo.cpp | 2 +- examples/CLICSiD/src/SiTrackerBarrel_geo.cpp | 6 +- examples/CLICSiD/src/SiTrackerEndcap2_geo.cpp | 2 +- .../ClientTests/compact/FCC_HcalBarrel.xml | 2 +- .../ClientTests/compact/MaterialTester.xml | 108 +++++++ .../compact/SectorBarrelCalorimeter.xml | 277 ++++++++++++++++++ .../ClientTests/src/FCC_HcalBarrel_geo.cpp | 11 +- .../ClientTests/src/MaterialTester_geo.cpp | 60 ++++ .../ClientTests/src/SectorBarrelCalorimeter.h | 25 ++ .../src/SectorBarrelCalorimeter_geo.cpp | 201 +++++++++++++ 18 files changed, 802 insertions(+), 118 deletions(-) create mode 100644 examples/ClientTests/compact/MaterialTester.xml create mode 100644 examples/ClientTests/compact/SectorBarrelCalorimeter.xml create mode 100644 examples/ClientTests/src/MaterialTester_geo.cpp create mode 100644 examples/ClientTests/src/SectorBarrelCalorimeter.h create mode 100644 examples/ClientTests/src/SectorBarrelCalorimeter_geo.cpp diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index d83f57f58..1befd60ef 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -244,40 +244,6 @@ namespace DD4hep { /// Clone constructor DetElement(Object* data, const std::string& name, const std::string& type); -#if 0 - /// Default constructor - template <typename Q> DetElement(Q* data, const std::string& name, const std::string& type) - : RefObject(data) { - this->assign(data, name, type); - } - - template <typename Q> DetElement(const std::string& name, const std::string& type, int id, const Q&) { - assign(new Q(), name, type); - object<Object>().id = id; - } - - /// Construction function for a new subdetector element - template <typename Q> - static Q* createObject(const std::string& name, const std::string& type, int id) { - DetElement det; - Q *p = new Q(); - Object* o = p; - if (o) { // This should cause a compilation error if Q is - det.assign(p, name, type); // not a subclass of Object, which is mandatoryyyy - } - det.object<Object>().id = id; - return p; - } - - /// Construction function for a new subdetector element - template <typename Q> - static DetElement create(const std::string& name, const std::string& type, int id, Q** ptr = 0) { - Q* p = createObject<Q>(name, type, id); - if (ptr) - *ptr = p; - return DetElement(p); - } -#endif /// Templated constructor for handle conversions template <typename Q> DetElement(const Handle<Q>& e) : RefObject(e) { @@ -401,14 +367,23 @@ namespace DD4hep { /// Access to the detector elements's parent DetElement parent() const; - /// Access to the alignment information + /// Access to the actual alignment information Alignment alignment() const; + /// Access to the survey alignment information + Alignment surveyAlignment() const; /// Access to the conditions information Conditions conditions() const; /// Set detector element for reference transformations. Will delete existing reference trafo. DetElement& setReference(DetElement reference); + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + /// Create cached matrix to transform to parent coordinates + const TGeoHMatrix& parentTransformation() const; + /// Create cached matrix to transform to reference coordinates + const TGeoHMatrix& referenceTransformation() const; + /// Transformation from local coordinates of the placed volume to the world system bool localToWorld(const Position& local, Position& global) const; /// Transformation from local coordinates of the placed volume to the parent system @@ -416,12 +391,6 @@ namespace DD4hep { /// Transformation from local coordinates of the placed volume to arbitrary parent system set as reference bool localToReference(const Position& local, Position& reference) const; - /// Create cached matrix to transform to world coordinates - const TGeoHMatrix& worldTransformation() const; - /// Create cached matrix to transform to parent coordinates - const TGeoHMatrix& parentTransformation() const; - /// Create cached matrix to transform to reference coordinates - const TGeoHMatrix& referenceTransformation() const; /// Transformation from world coordinates of the local placed volume coordinates bool worldToLocal(const Position& global, Position& local) const; /// Transformation from world coordinates of the local placed volume coordinates diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index e0628406d..3c83abe19 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -112,8 +112,12 @@ namespace DD4hep { /**@info: Additional information set externally to facilitate the processing of event data */ /// Basic detector element alignment entry Alignment alignment; + /// Basic detector element alignment entry containing the survey data + Alignment survey; /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements std::vector<Alignment> volume_alignments; + /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements + std::vector<Alignment> volume_surveys; /// The detector elements condition entry Conditions conditions; diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 5aec89bb3..4c75c94a4 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -116,6 +116,11 @@ Alignment DetElement::alignment() const { return access()->alignment; } +/// Access to the survey alignment information +Alignment DetElement::surveyAlignment() const { + return access()->survey; +} + /// Access to the conditions information Conditions DetElement::conditions() const { return access()->conditions; diff --git a/DDCore/src/Evaluator/setSystemOfUnits.cpp b/DDCore/src/Evaluator/setSystemOfUnits.cpp index e785c411b..937de35aa 100644 --- a/DDCore/src/Evaluator/setSystemOfUnits.cpp +++ b/DDCore/src/Evaluator/setSystemOfUnits.cpp @@ -83,8 +83,8 @@ void Evaluator::setSystemOfUnits(double meter, const double pi = 3.14159265358979323846; // Plane angle - //const double rad = 1.; // Geant4 (rad units) - const double rad = 180.0/pi; // Degree units + const double rad = 1.; // Geant4 (rad units) + //const double rad = pi; // Degree units setVariable("radian", rad); setVariable("rad", rad); setVariable("milliradian", milli_ * rad); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 020495a39..efc289fd2 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -478,6 +478,9 @@ Volume::Object* Volume::data() const { } static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) { + if ( !daughter ) { + throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical daughter volume."); + } TGeoVolume* parent = par; TObjArray* a = parent->GetNodes(); Int_t id = a ? a->GetEntries() : 0; @@ -485,6 +488,17 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* string nam = string(daughter->GetName()) + "_placement"; transform->SetName(nam.c_str()); } + TGeoShape* shape = daughter->GetShape(); + // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated.... + if ( shape->IsA() == TGeoShapeAssembly::Class() ) { + TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape; + if ( std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() && + std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() && + std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon() ) { + as->NeedsBBoxRecompute(); + as->ComputeBBox(); + } + } parent->AddNode(daughter, id, transform); geo_node_t* n = (geo_node_t*)parent->GetNode(id); n->geo_node_t::SetUserExtension(new PlacedVolume::Object()); @@ -493,43 +507,27 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* /// Place daughter volume according to generic Transform3D PlacedVolume Volume::placeVolume(const Volume& volume, const Transform3D& trans) const { - if (volume.isValid()) { - return _addNode(m_element, volume, _transform(trans)); - } - throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical volume."); - + return _addNode(m_element, volume, _transform(trans)); } /// Place daughter volume. The position and rotation are the identity PlacedVolume Volume::placeVolume(const Volume& volume) const { - if (volume.isValid()) { - return _addNode(m_element, volume, identityTransform()); - } - throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical volume."); + return _addNode(m_element, volume, identityTransform()); } /// Place un-rotated daughter volume at the given position. PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos) const { - if (volume.isValid()) { - return _addNode(m_element, volume, _translation(pos)); - } - throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical volume."); + return _addNode(m_element, volume, _translation(pos)); } /// Place rotated daughter volume. The position is automatically the identity position PlacedVolume Volume::placeVolume(const Volume& volume, const RotationZYX& rot) const { - if (volume.isValid()) { - return _addNode(m_element, volume, _rotationZYX(rot)); - } - throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical volume."); + return _addNode(m_element, volume, _rotationZYX(rot)); } /// Place rotated daughter volume. The position is automatically the identity position PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation3D& rot) const { - if (volume.isValid()) { - return _addNode(m_element, volume, _rotation3D(rot)); - } - throw runtime_error("DD4hep: Volume: Attempt to assign an invalid physical volume."); + return _addNode(m_element, volume, _rotation3D(rot)); } /// Set the volume's material diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 4c5245b8a..28167f429 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -254,18 +254,31 @@ template <> void Converter<Material>::operator()(xml_h e) const { printout(DEBUG, "Compact", "++ Creating material %s", matname); mat = mix = new TGeoMixture(matname, composites.size(), dens_val); mat->SetRadLen(radlen_val, intlen_val); - for (composites.reset(); composites; ++composites) { - std::string nam = composites.attr < string > (_U(ref)); + size_t ifrac = 0; + vector<double> composite_fractions; + double composite_fractions_total = 0.0; + for (composites.reset(); composites; ++composites) { + std::string nam = composites.attr<string>(_U(ref)); double fraction = composites.attr<double>(_U(n)); if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) - mix->AddElement(comp_mat, fraction); + fraction *= comp_mat->GetA(); else if (0 != (comp_elt = table->FindElement(nam.c_str()))) - mix->AddElement(comp_elt, fraction); + fraction *= comp_elt->A(); else throw_print("Compact2Objects[ERROR]: Creating material:" + mname + " Element missing: " + nam); + composite_fractions_total += fraction; + composite_fractions.push_back(fraction); + } + for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) { + std::string nam = composites.attr<string>(_U(ref)); + double fraction = composite_fractions[ifrac]/composite_fractions_total; + if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) + mix->AddElement(comp_mat, fraction); + else if (0 != (comp_elt = table->FindElement(nam.c_str()))) + mix->AddElement(comp_elt, fraction); } for (fractions.reset(); fractions; ++fractions) { - std::string nam = fractions.attr < string > (_U(ref)); + std::string nam = fractions.attr<string>(_U(ref)); double fraction = fractions.attr<double>(_U(n)); if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) mix->AddElement(comp_mat, fraction); @@ -275,15 +288,18 @@ template <> void Converter<Material>::operator()(xml_h e) const { throw_print("Compact2Objects[ERROR]: Creating material:" + mname + " Element missing: " + nam); } // Update estimated density if not provided. - if (!has_density && mix && 0 == mix->GetDensity()) { + if ( has_density ) { + mix->SetDensity(dens_val); + } + else if (!has_density && mix && 0 == mix->GetDensity()) { double dens = 0.0; - for (composites.reset(); composites; ++composites) { - std::string nam = composites.attr < string > (_U(ref)); + for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) { + std::string nam = composites.attr<string>(_U(ref)); comp_mat = mgr.GetMaterial(nam.c_str()); dens += composites.attr<double>(_U(n)) * comp_mat->GetDensity(); } for (fractions.reset(); fractions; ++fractions) { - std::string nam = fractions.attr < string > (_U(ref)); + std::string nam = fractions.attr<string>(_U(ref)); comp_mat = mgr.GetMaterial(nam.c_str()); dens += composites.attr<double>(_U(n)) * comp_mat->GetDensity(); } @@ -302,7 +318,7 @@ template <> void Converter<Material>::operator()(xml_h e) const { // TGeo has no notion of a material "formula" // Hence, treat the formula the same way as the material itself if (m.hasAttr(_U(formula))) { - string form = m.attr < string > (_U(formula)); + string form = m.attr<string>(_U(formula)); if (form != matname) { medium = mgr.GetMedium(form.c_str()); if (0 == medium) { @@ -327,7 +343,7 @@ template <> void Converter<Atom>::operator()(xml_h e) const { TGeoElement* element = tab->FindElement(eltname.c_str()); if (!element) { xml_ref_t atom(elem.child(_U(atom))); - tab->AddElement(elem.attr < string > (_U(name)).c_str(), elem.attr < string > (_U(formula)).c_str(), elem.attr<int>(_U(Z)), + tab->AddElement(elem.attr<string>(_U(name)).c_str(), elem.attr<string>(_U(formula)).c_str(), elem.attr<int>(_U(Z)), atom.attr<int>(_U(value))); element = tab->FindElement(eltname.c_str()); if (!element) { @@ -345,7 +361,7 @@ template <> void Converter<Atom>::operator()(xml_h e) const { * visible="true"/> */ template <> void Converter<VisAttr>::operator()(xml_h e) const { - VisAttr attr(e.attr < string > (_U(name))); + VisAttr attr(e.attr<string>(_U(name))); float r = e.hasAttr(_U(r)) ? e.attr<float>(_U(r)) : 1.0f; float g = e.hasAttr(_U(g)) ? e.attr<float>(_U(g)) : 1.0f; float b = e.hasAttr(_U(b)) ? e.attr<float>(_U(b)) : 1.0f; @@ -355,7 +371,7 @@ template <> void Converter<VisAttr>::operator()(xml_h e) const { if (e.hasAttr(_U(visible))) attr.setVisible(e.attr<bool>(_U(visible))); if (e.hasAttr(_U(lineStyle))) { - string ls = e.attr < string > (_U(lineStyle)); + string ls = e.attr<string>(_U(lineStyle)); if (ls == "unbroken") attr.setLineStyle(VisAttr::SOLID); else if (ls == "broken") @@ -365,7 +381,7 @@ template <> void Converter<VisAttr>::operator()(xml_h e) const { attr.setLineStyle(VisAttr::SOLID); } if (e.hasAttr(_U(drawingStyle))) { - string ds = e.attr < string > (_U(drawingStyle)); + string ds = e.attr<string>(_U(drawingStyle)); if (ds == "wireframe") attr.setDrawingStyle(VisAttr::WIREFRAME); else if (ds == "solid") @@ -390,7 +406,7 @@ template <> void Converter<VisAttr>::operator()(xml_h e) const { */ template <> void Converter<AlignmentEntry>::operator()(xml_h e) const { xml_comp_t child(e); - string path = e.attr < string > (_U(name)); + string path = e.attr<string>(_U(name)); bool check = e.hasAttr(_U(check)); bool overlap = e.hasAttr(_U(overlap)); AlignmentEntry alignment(path); @@ -416,17 +432,17 @@ template <> void Converter<AlignmentEntry>::operator()(xml_h e) const { * */ template <> void Converter<Region>::operator()(xml_h e) const { - Region region(e.attr < string > (_U(name))); - vector < string > &limits = region.limits(); - string ene = e.attr < string > (_U(eunit)), len = e.attr < string > (_U(lunit)); + Region region(e.attr<string>(_U(name))); + vector<string>&limits = region.limits(); + string ene = e.attr<string>(_U(eunit)), len = e.attr<string>(_U(lunit)); region.setEnergyUnit(ene); region.setLengthUnit(len); - region.setCut(_multiply<double>(e.attr < string > (_U(cut)), len)); - region.setThreshold(_multiply<double>(e.attr < string > (_U(threshold)), ene)); + region.setCut(_multiply<double>(e.attr<string>(_U(cut)), len)); + region.setThreshold(_multiply<double>(e.attr<string>(_U(threshold)), ene)); region.setStoreSecondaries(e.attr<bool>(_U(store_secondaries))); for (xml_coll_t user_limits(e, _U(limitsetref)); user_limits; ++user_limits) - limits.push_back(user_limits.attr < string > (_U(name))); + limits.push_back(user_limits.attr<string>(_U(name))); lcdd.addRegion(region); } @@ -440,12 +456,12 @@ template <> void Converter<Region>::operator()(xml_h e) const { template <> void Converter<Readout>::operator()(xml_h e) const { xml_h id = e.child(_U(id)); xml_h seg = e.child(_U(segmentation), false); - string name = e.attr < string > (_U(name)); + string name = e.attr<string>(_U(name)); Readout ro(name); Ref_t idSpec; if (seg) { // Segmentation is not mandatory! - string type = seg.attr < string > (_U(type)); + string type = seg.attr<string>(_U(type)); Segmentation segment(type, name); if (segment.isValid()) { segment->parameters(); @@ -489,13 +505,13 @@ template <> void Converter<Readout>::operator()(xml_h e) const { * ... </limitset> */ template <> void Converter<LimitSet>::operator()(xml_h e) const { - LimitSet ls(e.attr < string > (_U(name))); + LimitSet ls(e.attr<string>(_U(name))); for (xml_coll_t c(e, _U(limit)); c; ++c) { Limit limit; - limit.particles = c.attr < string > (_U(particles)); - limit.name = c.attr < string > (_U(name)); - limit.content = c.attr < string > (_U(value)); - limit.unit = c.attr < string > (_U(unit)); + limit.particles = c.attr<string>(_U(particles)); + limit.name = c.attr<string>(_U(name)); + limit.content = c.attr<string>(_U(value)); + limit.unit = c.attr<string>(_U(unit)); limit.value = _multiply<double>(limit.content, limit.unit); ls.addLimit(limit); } @@ -509,7 +525,7 @@ template <> void Converter<LimitSet>::operator()(xml_h e) const { * ... </properties> */ template <> void Converter<Property>::operator()(xml_h e) const { - string name = e.attr < string > (_U(name)); + string name = e.attr<string>(_U(name)); LCDD::Properties& prp = lcdd.properties(); if (name.empty()) { throw_print("Failed to convert properties. No name given!"); @@ -519,7 +535,7 @@ template <> void Converter<Property>::operator()(xml_h e) const { prp.insert(make_pair(name, LCDD::PropertyValues())); } for (vector<xml_attr_t>::iterator i = a.begin(); i != a.end(); ++i) { - pair < string, string > val(xml_tag_t(e.attr_name(*i)), e.attr < string > (*i)); + pair < string, string > val(xml_tag_t(e.attr_name(*i)), e.attr<string>(*i)); prp[name].insert(val); } } @@ -534,8 +550,8 @@ template <> void Converter<Property>::operator()(xml_h e) const { */ template <> void Converter<CartesianField>::operator()(xml_h e) const { string msg = "updated"; - string name = e.attr < string > (_U(name)); - string type = e.attr < string > (_U(type)); + string name = e.attr<string>(_U(name)); + string type = e.attr<string>(_U(type)); CartesianField field = lcdd.field(name); if (!field.isValid()) { // The field is not present: We create it and add it to LCDD @@ -552,13 +568,13 @@ template <> void Converter<CartesianField>::operator()(xml_h e) const { // Now update the field structure with the generic part ie. set it's properties CartesianField::Properties& prp = field.properties(); for (xml_coll_t c(e, _U(properties)); c; ++c) { - string props_name = c.attr < string > (_U(name)); + string props_name = c.attr<string>(_U(name)); vector < xml_attr_t > a = c.attributes(); if (prp.find(props_name) == prp.end()) { prp.insert(make_pair(props_name, CartesianField::PropertyValues())); } for (vector<xml_attr_t>::iterator i = a.begin(); i != a.end(); ++i) { - pair < string, string > val(xml_tag_t(c.attr_name(*i)), c.attr < string > (*i)); + pair < string, string > val(xml_tag_t(c.attr_name(*i)), c.attr<string>(*i)); prp[props_name].insert(val); } if (c.hasAttr(_U(global)) && c.attr<bool>(_U(global))) { @@ -582,13 +598,13 @@ template <> void Converter<CartesianField>::operator()(xml_h e) const { * */ template <> void Converter<SensitiveDetector>::operator()(xml_h element) const { - string name = element.attr < string > (_U(name)); + string name = element.attr<string>(_U(name)); try { SensitiveDetector sd = lcdd.sensitiveDetector(name); xml_attr_t type = element.attr_nothrow(_U(type)); if (type) { - sd.setType(element.attr < string > (type)); + sd.setType(element.attr<string>(type)); } xml_attr_t verbose = element.attr_nothrow(_U(verbose)); if (verbose) { @@ -600,7 +616,7 @@ template <> void Converter<SensitiveDetector>::operator()(xml_h element) const { } xml_attr_t limits = element.attr_nothrow(_U(limits)); if (limits) { - string l = element.attr < string > (limits); + string l = element.attr<string>(limits); LimitSet ls = lcdd.limitSet(l); if (!ls.isValid()) { throw_print("Converter<SensitiveDetector>: Request for non-existing limitset:" + l); @@ -609,7 +625,7 @@ template <> void Converter<SensitiveDetector>::operator()(xml_h element) const { } xml_attr_t region = element.attr_nothrow(_U(region)); if (region) { - string r = element.attr < string > (region); + string r = element.attr<string>(region); Region reg = lcdd.region(r); if (!reg.isValid()) { throw_print("Converter<SensitiveDetector>: Request for non-existing region:" + r); @@ -618,7 +634,7 @@ template <> void Converter<SensitiveDetector>::operator()(xml_h element) const { } xml_attr_t hits = element.attr_nothrow(_U(hits_collection)); if (hits) { - sd.setHitsCollection(element.attr < string > (hits)); + sd.setHitsCollection(element.attr<string>(hits)); } xml_attr_t ecut = element.attr_nothrow(_U(ecut)); xml_attr_t eunit = element.attr_nothrow(_U(eunit)); @@ -657,8 +673,8 @@ template <> void Converter<DetElement>::operator()(xml_h element) const { static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES"); static const char* ign_dets = ::getenv("IGNORED_DETECTORS"); static const char* ign_typs = ::getenv("IGNORED_DETECTOR_TYPES"); - string type = element.attr < string > (_U(type)); - string name = element.attr < string > (_U(name)); + string type = element.attr<string>(_U(type)); + string name = element.attr<string>(_U(name)); string name_match = ":" + name + ":"; string type_match = ":" + type + ":"; if (req_dets && !strstr(req_dets, name_match.c_str())) @@ -673,7 +689,7 @@ template <> void Converter<DetElement>::operator()(xml_h element) const { xml_attr_t attr_ro = element.attr_nothrow(_U(readout)); SensitiveDetector sd; if (attr_ro) { - Readout ro = lcdd.readout(element.attr < string > (attr_ro)); + Readout ro = lcdd.readout(element.attr<string>(attr_ro)); if (!ro.isValid()) { throw runtime_error("No Readout structure present for detector:" + name); } diff --git a/doc/release.notes b/doc/release.notes index 3f4948d9e..a0a7742e9 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -1,6 +1,26 @@ DD4hep ---- Release Notes ================================= +2014/05/21 Markus Frank +----------------------- + - Fix material creation from XML + JIRA bug: DD4hep - DDFORHEP-4 + https://sft.its.cern.ch/jira/browse/DDFORHEP-4 + using <composite> in material xml files results in wrong material properties + + - Fix JIRA bug: DD4hep - DDFORHEP-3 + https://sft.its.cern.ch/jira/browse/DDFORHEP-3 + Recursive assemblies result in error in TGeo geometry + Bug results in errors when closing the geometry like: + "Error in <TGeoVoxelFinder::SortAll>: Wrong bounding box for volume SIT_assembly" + + - Provision to store survey constants to the DetElement as an extension + for Alignment calculations (priv. comm. C.Parkes) + + - Fix bug in expression evaluation of angles. + All detector constructors receive angles in "rad". No correction + from degree to rad should be necessary. + 2014/05/21 Frank Gaede ----------------------- - add MaterialManager class providing diff --git a/examples/CLICSiD/src/ForwardDetector_geo.cpp b/examples/CLICSiD/src/ForwardDetector_geo.cpp index 8def1c40c..a76510afb 100644 --- a/examples/CLICSiD/src/ForwardDetector_geo.cpp +++ b/examples/CLICSiD/src/ForwardDetector_geo.cpp @@ -31,7 +31,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { double zinner = dim.inner_z(); double outgoingR = beam.outgoing_r(); double incomingR = beam.incoming_r(); - double xangle = beam.crossing_angle()/tgeo::rad; + double xangle = beam.crossing_angle(); double xangleHalf = xangle/2; double thickness = layering.totalThickness(); double zpos = zinner + thickness/2; diff --git a/examples/CLICSiD/src/MultiLayerTracker_geo.cpp b/examples/CLICSiD/src/MultiLayerTracker_geo.cpp index 24fec0dde..b9906a3f7 100644 --- a/examples/CLICSiD/src/MultiLayerTracker_geo.cpp +++ b/examples/CLICSiD/src/MultiLayerTracker_geo.cpp @@ -38,7 +38,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { Material mat = lcdd.material(x_slice.materialStr()); string s_name= l_name+_toString(m,"_slice%d"); double thickness = x_slice.thickness(); - Tube s_tub(r,r+thickness,z,2*M_PI*tgeo::rad); + Tube s_tub(r,r+thickness,z,2*M_PI); Volume s_vol(s_name, s_tub, mat); r += thickness; diff --git a/examples/CLICSiD/src/SiTrackerBarrel_geo.cpp b/examples/CLICSiD/src/SiTrackerBarrel_geo.cpp index 9b3bea83f..dad884d59 100644 --- a/examples/CLICSiD/src/SiTrackerBarrel_geo.cpp +++ b/examples/CLICSiD/src/SiTrackerBarrel_geo.cpp @@ -10,7 +10,6 @@ #include "DD4hep/Printout.h" using namespace std; -using namespace tgeo; using namespace DD4hep; using namespace DD4hep::Geometry; @@ -80,8 +79,8 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { string lay_nam = det_name+"_"+m_nam+_toString(x_layer.id(),"_layer%d"); Tube lay_tub (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()/2); Volume lay_vol (lay_nam,lay_tub,air); // Create the layer envelope volume. - double phi0 = x_layout.phi0()/tgeo::rad; // Starting phi of first module. - double phi_tilt = x_layout.phi_tilt()/tgeo::rad;// Phi tilt of a module. + double phi0 = x_layout.phi0(); // Starting phi of first module. + double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module. double rc = x_layout.rc(); // Radius of the module center. int nphi = x_layout.nphi(); // Number of modules in phi. double rphi_dr = x_layout.dr(); // The delta radius of every other module. @@ -127,6 +126,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { module_z = -z0; // Reset the Z placement parameter for module. } // Create the PhysicalVolume for the layer. + assembly.setVisAttributes(lcdd.invisible()); pv = assembly.placeVolume(lay_vol); // Place layer in mother pv.addPhysVolID("layer", lay_id); // Set the layer ID. DetElement m_elt(sdet,lay_nam,lay_id); diff --git a/examples/CLICSiD/src/SiTrackerEndcap2_geo.cpp b/examples/CLICSiD/src/SiTrackerEndcap2_geo.cpp index a8bfcd719..0e8cd2be5 100644 --- a/examples/CLICSiD/src/SiTrackerEndcap2_geo.cpp +++ b/examples/CLICSiD/src/SiTrackerEndcap2_geo.cpp @@ -29,7 +29,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { map<string,Volume> modules; PlacedVolume pv; - //assembly.setVisAttributes(lcdd.invisible()); + assembly.setVisAttributes(lcdd.invisible()); sens.setType("tracker"); for(xml_coll_t mi(x_det,_U(module)); mi; ++mi, ++m_id) { diff --git a/examples/ClientTests/compact/FCC_HcalBarrel.xml b/examples/ClientTests/compact/FCC_HcalBarrel.xml index 7c0a430ab..53fa198fe 100644 --- a/examples/ClientTests/compact/FCC_HcalBarrel.xml +++ b/examples/ClientTests/compact/FCC_HcalBarrel.xml @@ -56,7 +56,7 @@ <readouts> <readout name="HcalBarrelHits"> <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> - <id>system:8,barrel:3,module:6,layer:8,slice:5,x:32:-16,y:-16</id> + <id>system:8,barrel:3,stave:8,module:6,layer:8,slice:5,x:46:-8,y:-8</id> </readout> </readouts> diff --git a/examples/ClientTests/compact/MaterialTester.xml b/examples/ClientTests/compact/MaterialTester.xml new file mode 100644 index 000000000..936ecb934 --- /dev/null +++ b/examples/ClientTests/compact/MaterialTester.xml @@ -0,0 +1,108 @@ +<?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"> + + <define> + <constant name="world_size" value="30*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + </define> + + <materials> + <element Z="1" formula="H" name="H" > + <atom type="A" unit="g/mol" value="1.00794" /> + </element> + <material formula="H" name="Hydrogen" state="gas" > + <RL type="X0" unit="cm" value="752776" /> + <NIL type="lambda" unit="cm" value="421239" /> + <D type="density" unit="g/cm3" value="8.3748e-05" /> + <composite n="1" ref="H" /> + </material> + + <element Z="6" formula="C" name="C" > + <atom type="A" unit="g/mol" value="12.0107" /> + </element> + <material formula="C" name="Carbon" state="solid" > + <RL type="X0" unit="cm" value="21.3485" /> + <NIL type="lambda" unit="cm" value="40.1008" /> + <D type="density" unit="g/cm3" value="2" /> + <composite n="1" ref="C" /> + </material> + + <element Z="7" formula="N" name="N" > + <atom type="A" unit="g/mol" value="14.0068" /> + </element> + <material formula="N" name="Nitrogen" state="gas" > + <RL type="X0" unit="cm" value="32602.2" /> + <NIL type="lambda" unit="cm" value="72430.3" /> + <D type="density" unit="g/cm3" value="0.0011652" /> + <composite n="1" ref="N" /> + </material> + + <element Z="8" formula="O" name="O" > + <atom type="A" unit="g/mol" value="15.9994" /> + </element> + <material formula="O" name="Oxygen" state="gas" > + <RL type="X0" unit="cm" value="25713.8" /> + <NIL type="lambda" unit="cm" value="66233.9" /> + <D type="density" unit="g/cm3" value="0.00133151" /> + <composite n="1" ref="O" /> + </material> + + <element Z="18" formula="Ar" name="Ar" > + <atom type="A" unit="g/mol" value="39.9477" /> + </element> + <material formula="Ar" name="Argon" state="gas" > + <RL type="X0" unit="cm" value="11762.1" /> + <NIL type="lambda" unit="cm" value="71926" /> + <D type="density" unit="g/cm3" value="0.00166201" /> + <composite n="1" ref="Ar" /> + </material> + + + <material name="Air"> + <D type="density" unit="g/cm3" value="0.0012"/> + <fraction n="0.754" ref="N"/> + <fraction n="0.234" ref="O"/> + <fraction n="0.012" ref="Ar"/> + </material> + + <material name="Vacuum"> + <D type="density" unit="g/cm3" value="0.00000001" /> + <fraction n="1" ref="H" /> + </material> + <material name="Polystyrene"> + <D value="1.032" unit="g/cm3"/> + <composite n="19" ref="C"/> + <composite n="21" ref="H"/> + </material> + <material name="Polystyrene_FRACTION"> + <D value="1.032" unit="g/cm3"/> + <fraction n="0.077418" ref="H"/> + <fraction n="0.922582" ref="C"/> + </material> + <material name="Polystyrene_COMPOSITE"> + <D value="1.032" unit="g/cm3"/> + <composite n="21" ref="H"/> + <composite n="19" ref="C"/> + </material> + <material name="Polystyrene_CORR_FRACTION"> + <D value="1.032" unit="g/cm3"/> + <fraction n="0.084429" ref="H"/> + <fraction n="0.915571" ref="C"/> + </material> + </materials> + + <detectors> + <detector id="1" name="MaterialTester" type="MaterialTester"> + <test name="Air"/> + <test name="Vacuum"/> + <test name="Polystyrene"/> + <test name="Polystyrene_FRACTION"/> + <test name="Polystyrene_COMPOSITE"/> + <test name="Polystyrene_CORR_FRACTION"/> + </detector> + </detectors> +</lccdd> diff --git a/examples/ClientTests/compact/SectorBarrelCalorimeter.xml b/examples/ClientTests/compact/SectorBarrelCalorimeter.xml new file mode 100644 index 000000000..173632574 --- /dev/null +++ b/examples/ClientTests/compact/SectorBarrelCalorimeter.xml @@ -0,0 +1,277 @@ +<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="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 988 2014-01-30 13:52:22Z markus.frank@cern.ch $"> + <comment>The compact format for the CLIC Silicon Detector used for the conceptual design report</comment> + </info> + + <includes> + <gdmlFile ref="elements.xml"/> + <gdmlFile ref="materials.xml"/> + <pyBuilder ref="../drivers"/> + </includes> + + <define> + <constant name="world_side" value="30000*mm"/> + <constant name="world_x" value="world_side"/> + <constant name="world_y" value="world_side"/> + <constant name="world_z" value="world_side"/> + + <constant name="CrossingAngle" value="0.020*rad"/> + + <constant name="CaloSides" value="8"/> + <constant name="MuonSides" value="8"/> + + <constant name="EcalBarrel_rmin" value="126.50*cm"/> + <constant name="EcalBarrel_zmax" value="176.50*cm"/> + <constant name="EcalEndcap_rmin" value="21.0*cm"/> + <constant name="EcalEndcap_rmax" value="(EcalBarrel_rmin - 1.5*cm) / (cos(pi/CaloSides))"/> <!-- Correction from going from inner circle to outer circle --> + <constant name="EcalEndcap_zmin" value="165.70*cm"/> + + <constant name="HcalBarrel_rmin" value="141.90*cm"/> + <constant name="HcalBarrel_layers" value="(int) 75"/> + <constant name="HcalBarrel_layer_thickness" value="1.0*cm + 0.65*cm"/> + <constant name="HcalEndcap_zmin" value="EcalBarrel_zmax + 4.0*cm"/> <!-- Gap for cables --> + <constant name="HcalEndcap_rmin" value="50.0*cm"/> + <constant name="HcalEndcap_rmax" value="(HcalBarrel_rmin + HcalBarrel_layers * HcalBarrel_layer_thickness) / (cos(pi/CaloSides))"/> <!-- Correction from going from inner circle to outer circle --> + <constant name="HcalEndcap_layers" value="60"/> + <constant name="HcalEndcap_layer_thickness" value="2.0*cm + 0.65*cm"/> + <constant name="HcalEndcap_zmax" value="HcalEndcap_zmin + HcalEndcap_layers * HcalEndcap_layer_thickness"/> + + <constant name="tracking_region_radius" value="EcalBarrel_rmin - 1.0*mm"/> + <constant name="tracking_region_zmax" value="EcalEndcap_zmin - 1.0*mm"/> + <constant name="VXD_CF_sensor" value="0.026*cm"/> + <constant name="VXD_CF_support" value="0.05*cm"/> + + <constant name="SolenoidBarrelInnerRadius" value="HcalEndcap_rmax + 2.0*cm"/> + <constant name="SolenoidCoilOuterZ" value="HcalEndcap_zmax"/> <!-- Aligned with HCAL endcap --> + <constant name="SolenoidBarrelInnerCryostatThickness" value="3.0*cm"/> + <constant name="SolenoidBarrelInnerAirgapThickness" value="11.0*cm"/> + <constant name="SolenoidBarrelAlConductorThickness" value="38.4*cm"/> + <constant name="SolenoidBarrelQuenchbackThickness" value="5.0*cm"/> + <constant name="SolenoidBarrelOuterAirgapThickness" value="18.7*cm"/> + <constant name="SolenoidBarrelOuterCryostatThickness" value="4.0*cm"/> + <constant name="SolenoidEndcapCryostatThickness" value="6.0*cm"/> + <constant name="SolenoidEndcapAirgapThickness" value="12.0*cm"/> + <constant name="SolenoidBarrelOuterZ" value="SolenoidCoilOuterZ+SolenoidEndcapAirgapThickness"/> + <constant name="SolenoidBarrelConductorInnerRadius" value="SolenoidBarrelInnerRadius + SolenoidBarrelInnerCryostatThickness + SolenoidBarrelInnerAirgapThickness"/> + <constant name="SolenoidBarrelOuterCryostatInnerRadius" value="SolenoidBarrelConductorInnerRadius + SolenoidBarrelAlConductorThickness + SolenoidBarrelQuenchbackThickness"/> + <constant name="SolenoidBarrelOuterRadius" value="SolenoidBarrelOuterCryostatInnerRadius + SolenoidBarrelOuterAirgapThickness + SolenoidBarrelOuterCryostatThickness"/> + <constant name="SolenoidalFieldRadius" value="(SolenoidBarrelConductorInnerRadius + SolenoidBarrelAlConductorThickness / 2.0)"/> + + <constant name="MuonBarrel_rmin" value="SolenoidBarrelOuterRadius + 1.0*cm"/> + <constant name="MuonBarrel_zmax" value="SolenoidBarrelOuterZ + SolenoidEndcapCryostatThickness"/> + <constant name="MuonBarrel_layers" value="15"/> + <constant name="MuonBarrel_layer_thickness" value="10.0*cm + 4.0*cm"/> + <constant name="MuonEndcap_zmin" value="MuonBarrel_zmax + 10.0*cm"/> <!-- Space for cables etc. --> + <constant name="MuonEndcap_rmin" value="69.0*cm"/> <!-- Space for QD0 and anti-solenoid--> + <constant name="MuonEndcap_rmax" value="(MuonBarrel_rmin + 57.0*cm + MuonBarrel_layers * MuonBarrel_layer_thickness) / (cos(pi/MuonSides))"/> <!-- Correction from going from inner circle to outer circle --> + <constant name="MuonEndcap_layers" value="18"/> + <constant name="MuonEndcap_layer_thickness" value="10.0*cm + 4.0*cm"/> + <constant name="MuonEndcap_zmax" value="MuonEndcap_zmin + MuonEndcap_layers * MuonEndcap_layer_thickness"/> + + <constant name="LumiCal_rmin" value="6.4*cm"/> + <constant name="LumiCal_rmax" value="EcalEndcap_rmin + 3.0*cm"/> + <constant name="LumiCal_zmin" value="HcalEndcap_zmin"/> + <constant name="LumiCal_thickness" value="20*0.371*cm + 15*0.643*cm"/> + <constant name="LumiCal_zmax" value="LumiCal_zmin + LumiCal_thickness"/> + <constant name="LumiCalElectronics_rmax" value="LumiCal_rmax+5.0*cm"/> + + <constant name="SupportTube_thickness" value="1.0*cm"/> + <constant name="ForwardVacuumValve_thickness" value="36.0*cm"/> + <constant name="ForwardShielding_thickness" value="5.0*cm"/> + <constant name="ForwardMask_thickness" value="10.0*cm"/> + <constant name="ForwardMask_zmin" value="LumiCal_zmax + ForwardShielding_thickness + ForwardVacuumValve_thickness"/> + <constant name="BeamCal_rmax" value="13.0*cm"/> + <constant name="BeamCal_zmin" value="ForwardMask_zmin + ForwardMask_thickness"/> + + <constant name="VertexSupport_r1" value="16.87*cm"/> + <constant name="VertexSupport_r2" value="18.42*cm"/> + <constant name="VertexSupport_zmax" value="89.48*cm"/> + + <constant name="VertexBarrel_zmax" value="10.0*cm"/> + <constant name="VertexBarrel_r1" value="2.7*cm"/> + <constant name="VertexBarrel_r2" value="3.8*cm"/> + <constant name="VertexBarrel_r3" value="5.1*cm"/> + <constant name="VertexBarrel_r4" value="6.4*cm"/> + <constant name="VertexBarrel_r5" value="7.7*cm"/> + + <constant name="CentralBeamPipe_zmax" value="23.0*cm"/> + <constant name="CentralBeamPipe_rmax" value="VertexBarrel_r1 - 0.2*cm"/> + <constant name="CentralBeamPipe_thickness" value="CentralBeamPipe_rmax * 0.02"/> <!-- 1% of the diameter --> + <constant name="CentralBeamPipe_rmin" value="CentralBeamPipe_rmax - CentralBeamPipe_thickness"/> + <constant name="BeamPipe_thickness" value="0.4*cm"/> + <constant name="BeamPipe_endThickness" value="0.1*cm"/> + <constant name="BeamPipe_zmax" value="LumiCal_zmin - 0.5*cm"/> + <constant name="BeamPipe_rmax" value="19.0*cm"/> + <constant name="BeamPipe_rmin" value="BeamPipe_rmax - BeamPipe_thickness"/> + <constant name="bp_cone_slope" value="(BeamPipe_rmax-CentralBeamPipe_rmax)/(tracking_region_zmax-CentralBeamPipe_zmax)"/> + <constant name="BeamPipe_zmin" value="CentralBeamPipe_zmax + (BeamPipe_thickness - CentralBeamPipe_thickness)/bp_cone_slope"/> + <constant name="BeamPipeLiner_thickness" value="0.0*cm"/> + + </define> + <materials> + <material name="TungstenDens23"> + <D value="17.7" unit="g/cm3"/> + <fraction n="0.925" ref="W"/> + <fraction n="0.066" ref="Ni"/> + <fraction n="0.009" ref="Fe"/> + </material> + <material name="TungstenDens24"> + <D value="17.8" unit="g/cm3"/> + <fraction n="0.93" ref="W"/> + <fraction n="0.061" ref="Ni"/> + <fraction n="0.009" ref="Fe"/> + </material> + <material name="TungstenDens25"> + <D value="18.2" unit="g/cm3"/> + <fraction n="0.950" ref="W"/> + <fraction n="0.044" ref="Ni"/> + <fraction n="0.006" ref="Fe"/> + </material> + <material name="CarbonFiber_25percent"> + <D type="density" value="0.375" unit="g/cm3"/> + <fraction n="1.0" ref="CarbonFiber"/> + </material> + <material name="CarbonFiber_15percent"> + <D type="density" value="0.225" unit="g/cm3"/> + <fraction n="1.0" ref="CarbonFiber"/> + </material> + <material name="Rohacell31_50percent"> + <D type="density" value="0.016" unit="g/cm3"/> + <fraction n="1.0" ref="Rohacell31"/> + </material> + <material name="Rohacell31_15percent"> + <D type="density" value="0.0048" unit="g/cm3"/> + <fraction n="1.0" ref="Rohacell31"/> + </material> + <material name="BoratedPolyethylene5"> + <D value="0.93" unit="g/cm3"/> + <fraction n="0.612" ref="C"/> + <fraction n="0.222" ref="O"/> + <fraction n="0.116" ref="H"/> + <fraction n="0.050" ref="B"/> + </material> + <material name="SiliconCarbide"> + <D value="3.1" unit="g/cm3"/> + <composite n="1" ref="Si"/> + <composite n="1" ref="C"/> + </material> + <material name="SiliconCarbide_6percent"> + <D value="0.186" unit="g/cm3"/> + <fraction n="1.0" ref="SiliconCarbide"/> + </material> + <material name="Graphite"> + <D value="1.7" unit="g/cm3"/> + <composite n="1" ref="C"/> + </material> + </materials> + <limits> + <limitset name="cal_limits"> + <limit name="step_length_max" particles="*" value="5.0" unit="mm" /> + </limitset> + </limits> + + <display> + <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> + <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> + <vis name="HcalBarrelVis" alpha="1" r="1" g="1" b="0.1" showDaughters="true" visible="true"/> + <vis name="HcalBarrelStavesVis" alpha="1" r="1" g="0" b="0.3" showDaughters="true" visible="true"/> + <vis name="HcalBarrelLayerVis" alpha="1" r="1" g="0" b="0.5" showDaughters="true" visible="true"/> + <vis name="HcalBarrelSensorVis" alpha="1" r="1" g="1" b="0.7" showDaughters="true" visible="true"/> + + <vis name="HcalEndcapVis" alpha="1" r="1" g="1" b="0.1" showDaughters="false" visible="true"/> + <vis name="HcalEndcapLayerVis" alpha="1" r="1" g="0" b="0.5" showDaughters="false" visible="true"/> + <vis name="SupportTubeVis" r="0.1" g="0.1" b="0.99" showDaughters="false" visible="true"/> + <vis name="TungstenShieldingVis" r="0.99" g="0.1" b="0.2" showDaughters="false" visible="true"/> + + <vis name="SupportVis" r="0.8" g="0.8" b="0" showDaughters="false" visible="true"/> + <vis name="LumiCalVis" showDaughters="false" visible="true"/> + <vis name="GreenVis" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="RedVis" r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="BlueVis" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/> + </display> + + + + <detectors> + <detector id="8" name="HcalBarrel" type="SectorBarrelCalorimeter" readout="HcalBarrelHits" vis="HcalBarrelVis" calorimeterType="HAD_BARREL" gap="0.*cm" material="Steel235"> + <comment>Hadron Calorimeter Barrel</comment> + <dimensions numsides="(int) CaloSides" rmin="HcalBarrel_rmin" rmax="HcalEndcap_rmax" z="EcalBarrel_zmax*2"/> + <staves vis="HcalBarrelStavesVis"/> + <layer repeat="(int) HcalBarrel_layers"> + <slice material = "TungstenDens24" thickness = "1.00*cm" /> + <slice material = "Polystyrene" thickness = "0.50*cm" sensitive = "yes" limits="cal_limits" vis="HcalBarrelSensorVis"/> + <slice material = "Air" thickness = "0.15*cm" /> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="SiTrackerEndcapHits"> + <id>system:8,barrel:3,layer:4,module:14,sensor:2,side:32:-2,strip:20</id> + </readout> + <readout name="SiTrackerBarrelHits"> + <id>system:8,barrel:3,layer:4,module:14,sensor:2,side:32:-2,strip:20</id> + </readout> + <readout name="SiVertexBarrelHits"> + <id>system:8,barrel:3,layer:4,module:14,sensor:2,side:32:-2,strip:24</id> + </readout> + <readout name="SiVertexEndcapHits"> + <id>system:8,barrel:3,layer:4,wedge:6,module:6,sensor:1,side:32:-2,strip:26</id> + </readout> + <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="EcalEndcapHits"> + <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="HcalBarrelHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> + <id>system:8,barrel:3,module:6,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="HcalEndcapHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> + <id>system:8,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="HcalPlugHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> + <id>system:8,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="MuonBarrelHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> + <id>system:8,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="MuonEndcapHits"> + <segmentation type="CartesianGridXY" grid_size_x="3.0*cm" grid_size_y="3.0*cm" /> + <id>system:8,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="SiTrackerForwardHits"> + <id>system:8,barrel:3,layer:4,wedge:6,module:6,sensor:1,side:32:-2,strip:28</id> + </readout> + <readout name="LumiCalHits"> + <segmentation type="CartesianGridXY" grid_size_x="0.35*cm" grid_size_y="0.35*cm" /> + <id>system:8,layer:8,barrel:3,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + <readout name="BeamCalHits"> + <segmentation type="CartesianGridXY" grid_size_x="0.35*cm" grid_size_y="0.35*cm" /> + <id>system:8,layer:8,barrel:3,layer:8,slice:5,x:32:-16,y:-16</id> + </readout> + </readouts> + <fields> + <field name="GlobalSolenoid" type="solenoid" + inner_field="5.0*tesla" + outer_field="-1.5*tesla" + zmax="SolenoidCoilOuterZ" + outer_radius="SolenoidalFieldRadius"> + </field> + </fields> +</lccdd> diff --git a/examples/ClientTests/src/FCC_HcalBarrel_geo.cpp b/examples/ClientTests/src/FCC_HcalBarrel_geo.cpp index 542a93005..69ef731f7 100644 --- a/examples/ClientTests/src/FCC_HcalBarrel_geo.cpp +++ b/examples/ClientTests/src/FCC_HcalBarrel_geo.cpp @@ -24,11 +24,11 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { xml_dim_t x_det_dim(x_det.dimensions()); double inner_r = x_det_dim.rmin(); double outer_r = x_det_dim.rmax(); - //Tube: DDCore/DD4hep/Shapes.h - Tube calo_shape(inner_r,outer_r,x_det_dim.z(),2*M_PI/x_det_dim.phiBins()); - - //Create the detector mother volume - Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,lcdd.air()); + // Tube: DDCore/DD4hep/Shapes.h + //Tube calo_shape(inner_r,outer_r,x_det_dim.z(),0.0,2*M_PI/x_det_dim.phiBins()); + // Create the detector mother volume + //Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,lcdd.air()); + Assembly calo_vol(x_det.nameStr()+"_envelope"); //Set envelope volume attributes calo_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); @@ -116,6 +116,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { tile_seq.placeVolume(tile_vol,Position(0,total_thickness,0)); total_thickness += tile_thickness; if ( tile_xml.isSensitive() ) { + cout << "Set volume " << tile_name << " sensitive...." << endl; tile_vol.setSensitiveDetector(sens); } diff --git a/examples/ClientTests/src/MaterialTester_geo.cpp b/examples/ClientTests/src/MaterialTester_geo.cpp new file mode 100644 index 000000000..8646017fd --- /dev/null +++ b/examples/ClientTests/src/MaterialTester_geo.cpp @@ -0,0 +1,60 @@ +// $Id: ILDExVXD_geo.cpp 673 2013-08-05 10:01:33Z gaede $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +// Framework include files +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Printout.h" + +// ROOT include file +#include "TGeoElement.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + Assembly assembly(det_name+"_assembly"); + DetElement det(det_name,x_det.typeStr(), x_det.id()); + + for(xml_coll_t k(x_det,_Unicode(test)); k; ++k) { + xml_comp_t c = k; + Material mat = lcdd.material(c.nameStr()); + TGeoMaterial* m = mat->GetMaterial(); + printout(INFO,det_name,"+++ Material:%s [%p, %p] Z=%6.2f A=%6.2f D=%9.4f [g/cm3]", + m->GetName(), mat.ptr(), m, m->GetZ(), m->GetA(), m->GetDensity()); + printout(INFO,det_name,"+++ Radiation Length:%9.4f Interaction length:%9.4f Mixture:%s", + m->GetRadLen(), m->GetIntLen(), yes_no(m->IsMixture())); + printout(INFO,det_name,"+++ Elements:%d Index:%d", + m->GetNelements(), m->GetIndex()); + for(Int_t i=0, n=m->GetNelements(); i<n; ++i) { + TGeoElement* e = m->GetElement(i); + Double_t a=0., z=0., w=0.; + m->GetElementProp(a,z,w,i); + printout(INFO,det_name,"+++ ELT[%02d]: %s Z=%3d N=%3d N_eff=%7.2f A=%6.2f Weight=%9.4f ", + i, e->GetName(), e->Z(), e->N(), e->Neff(), e->A(), w); + if ( m->IsMixture() ) { + TGeoMixture* mix = (TGeoMixture*)m; + Int_t* nmix = mix->GetNmixt(); + Double_t* wmix = mix->GetWmixt(); + printout(INFO,det_name,"+++ Zmix:%7.3f Nmix:%3d Amix:%7.3f Wmix:%7.3f", + mix->GetZmixt()[i],nmix ? nmix[i] : -1, + mix->GetAmixt()[i],wmix ? wmix[i] : -1e0); + } + } + } + + + PlacedVolume pv = lcdd.pickMotherVolume(det).placeVolume(assembly); + pv.addPhysVolID("system",x_det.id()); + det.setPlacement(pv); + return det; +} + +DECLARE_DETELEMENT(MaterialTester,create_element); diff --git a/examples/ClientTests/src/SectorBarrelCalorimeter.h b/examples/ClientTests/src/SectorBarrelCalorimeter.h new file mode 100644 index 000000000..02a442a17 --- /dev/null +++ b/examples/ClientTests/src/SectorBarrelCalorimeter.h @@ -0,0 +1,25 @@ +/* + * PolyhedralBarrelCalorimeter.h + * + * Created on: May 19, 2014 + * Author: Nikiforos Nikiforou, CERN + */ + +#ifndef SECTORBARRELCALORIMETER_H_ +#define SECTORBARRELCALORIMETER_H_ + +#include "BarrelDetector.h" +#include "PolyhedralCalorimeter.h" + +namespace DD4hep { +namespace Geometry { + +class SectorBarrelCalorimeter: public BarrelDetector, public PolyhedralCalorimeter { +public: + SectorBarrelCalorimeter(const DetElement& e) : DetElement(e), BarrelDetector(e), PolyhedralCalorimeter(e) {} + virtual ~SectorBarrelCalorimeter() {} +}; + +} /* namespace Geometry */ +} /* namespace DD4hep */ +#endif /* SECTORBARRELCALORIMETER_H_ */ diff --git a/examples/ClientTests/src/SectorBarrelCalorimeter_geo.cpp b/examples/ClientTests/src/SectorBarrelCalorimeter_geo.cpp new file mode 100644 index 000000000..4e9d1dd86 --- /dev/null +++ b/examples/ClientTests/src/SectorBarrelCalorimeter_geo.cpp @@ -0,0 +1,201 @@ +// $Id: PolyhedraBarrelCalorimeter2_geo.cpp 784 2013-09-19 20:05:24Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Layering.h" +#include <limits> + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static void placeStaves(DetElement& parent, + DetElement& stave, + double rmin, + int numsides, + double total_thickness, + Volume envelopeVolume, + double innerAngle, + Volume sectVolume) +{ + double innerRotation = innerAngle; + double offsetRotation = -innerRotation / 2; + double sectCenterRadius = rmin + total_thickness / 2; + double rotX = M_PI / 2; + double rotY = -offsetRotation; + double posX = -sectCenterRadius * std::sin(rotY); + double posY = sectCenterRadius * std::cos(rotY); + + for (int module = 1; module <= numsides; ++module) { + DetElement det = module>1 ? stave.clone(_toString(module,"stave%d")) : stave; + PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Transform3D(RotationZYX(0,rotY,rotX), + Translation3D(-posX,-posY,0))); + // Not a valid volID: pv.addPhysVolID("stave", 0); + pv.addPhysVolID("module",module); + det.setPlacement(pv); + parent.add(det); + rotY -= innerRotation; + posX = -sectCenterRadius * std::sin(rotY); + posY = sectCenterRadius * std::cos(rotY); + } +} + +static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + Layering layering(x_det); + xml_comp_t staves = x_det.staves(); + xml_dim_t dim = x_det.dimensions(); + string det_name = x_det.nameStr(); + string det_type = x_det.typeStr(); + Material air = lcdd.air(); + double totalThickness = layering.totalThickness(); + int totalRepeat = 0; + int totalSlices = 0; + double gap = xml_dim_t(x_det).gap(); + int numSides = dim.numsides(); + double detZ = dim.z(); + double rmin = dim.rmin(); + double rmax = dim.rmax(); + DetElement sdet(det_name,x_det.id()); + DetElement stave("stave1",x_det.id()); + Volume motherVol = lcdd.pickMotherVolume(sdet); + + for(xml_coll_t c(x_det,_U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + totalRepeat += repeat; + totalSlices += x_layer.numChildren(_U(slice)); + } + +// PolyhedraRegular polyhedra(numSides,rmin,rmin+totalThickness,detZ); +// Volume envelopeVol(det_name+"_envelope",polyhedra,air); +// Assembly envelopeVol(det_name+"_envelope"); + + PolyhedraRegular polyhedron(numSides,0.,rmin,detZ+10); + Tube tube(0.,rmin+totalThickness,detZ/2,0,2*M_PI); + + SubtractionSolid sub(tube,polyhedron); + + Volume envelopeVol(det_name+"_envelope",sub,air); + + // Add the subdetector envelope to the structure. + double externalAngle = 2*M_PI/numSides; + double halfExternalAngle = externalAngle/2; + double tan_external = std::tan(externalAngle); + double tan_half = std::tan(halfExternalAngle); + + double half_polyFace = rmin * tan_half; + + double innerFaceLen = sqrt(rmax*rmax - rmin*rmin)+half_polyFace; + double outerFaceLen = (rmin+totalThickness) * tan_external; + double staveThickness = totalThickness; + +// Trapezoid staveTrdOuter(innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2); +// Volume staveOuterVol(det_name+"_stave",staveTrdOuter,air); + Assembly staveOuterVol(det_name+"_stave"); + +// Trapezoid staveTrdInner(innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2); +// Volume staveInnerVol(det_name+"_inner",staveTrdInner,air); + + double layerOuterAngle = (M_PI-externalAngle)/2; + double layerexternalAngle = (M_PI/2 - layerOuterAngle); + double layer_pos_z = -(staveThickness / 2); + double layer_pos_x = 0; + + double layer_dim_x = innerFaceLen/2; + int layer_num = 1; + + double layerR = rmin; + + // Set envelope volume attributes. + envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + for(xml_coll_t c(x_det,_U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); // Get number of times to repeat this layer. + const Layer* lay = layering.layer(layer_num-1); // Get the layer from the layering engine. + // Loop over repeats for this layer. + for (int j = 0; j < repeat; j++) { + string layer_name = det_name+_toString(layer_num,"_layer%d"); + double layer_thickness = lay->thickness(); + DetElement layer(stave,_toString(layer_num,"layer%d"),x_det.id()); + + // Layer position in Z within the stave. + layer_pos_z += layer_thickness / 2; + // Layer box & volume + Volume layer_vol(layer_name, Box(layer_dim_x,detZ/2,layer_thickness/2), air); + + // Create the slices (sublayers) within the layer. + double slice_pos_z = -(layer_thickness / 2); + int slice_number = 1; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = layer_name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = lcdd.material(x_slice.materialStr()); + DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); + + slice_pos_z += slice_thickness / 2; + // Slice volume & box + Volume slice_vol(slice_name,Box(layer_dim_x,detZ/2,slice_thickness/2),slice_material); + + if ( x_slice.isSensitive() ) { + sens.setType("calorimeter"); + slice_vol.setSensitiveDetector(sens); + } + // Set region, limitset, and vis. + slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + // slice PlacedVolume + PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); + slice_phv.addPhysVolID("slice",slice_number); + + slice.setPlacement(slice_phv); + // Increment Z position for next slice. + slice_pos_z += slice_thickness / 2; + // Increment slice number. + ++slice_number; + } + // Set region, limitset, and vis. + layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + // Layer physical volume. + PlacedVolume layer_phv = staveOuterVol.placeVolume(layer_vol,Position((layer_dim_x+layer_pos_x-half_polyFace),0,layer_pos_z)); + layer_phv.addPhysVolID("layer",layer_num); + layer.setPlacement(layer_phv); + + layerR += layer_thickness; + // Increment the layer X dimension. + layer_pos_x = (layerR-rmin)/tan_external; + layer_dim_x = (sqrt(rmax*rmax - layerR*layerR)+half_polyFace - layer_pos_x)/2.0; + cout<<"Rmin: "<< rmin<<" Rmax: "<<rmax<<" half_polyFace: "<<half_polyFace<<" Layer " <<layer_num<<" layerR: "<<layerR<<" layer_dim_x:" <<layer_dim_x<<endl; + // Increment the layer Z position. + layer_pos_z += layer_thickness / 2; + // Increment the layer number. + ++layer_num; + } + } + + // Add stave inner physical volume to outer stave volume. +// staveOuterVol.placeVolume(staveInnerVol); //not needed + // Set the vis attributes of the outer stave section. +// stave.setVisAttributes(lcdd,staves.visStr(),staveOuterVol); //not applicable for Assembly + // Place the staves. + placeStaves(sdet,stave,rmin,numSides,totalThickness,envelopeVol,externalAngle,staveOuterVol); + + double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0; + Transform3D transform(RotationZ(M_PI-(M_PI/numSides)),Translation3D(0,0,z_offset)); + PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,transform); + env_phv.addPhysVolID("system", sdet.id()); + env_phv.addPhysVolID("barrel", 0); + sdet.setPlacement(env_phv); + + //sdet.addExtension<LayerStack>(new Geometry::PolyhedralCalorimeterLayerStack(sdet)); + return sdet; +} + +DECLARE_DETELEMENT(SectorBarrelCalorimeter,create_detector); -- GitLab