diff --git a/DDCore/src/DetElement.cpp b/DDCore/src/DetElement.cpp index 2fdaea5e51839b585e9919f83ecbc3387c864c63..aa0eedd27b8920fe1e7e7a9df7a0222db5f952cd 100644 --- a/DDCore/src/DetElement.cpp +++ b/DDCore/src/DetElement.cpp @@ -267,7 +267,7 @@ DetElement DetElement::clone(const string& new_name) const { DetElement DetElement::clone(const string& new_name, int new_id) const { Object* o = access(); - Object* n = o->clone(new_id, COPY_NONE); + Object* n = o->clone(new_id, COPY_PLACEMENT); n->SetName(new_name.c_str()); n->SetTitle(o->GetTitle()); return n; diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index ed5dd5cbd2838258590669b1d2c00e7dfadb21aa..758afb4ab7c8746d0a625615a2fc77f304667197 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -118,7 +118,7 @@ DetElementObject* DetElementObject::clone(int new_id, int flg) const { obj->children.clear(); for (const auto& i : children ) { const DetElementObject& d = i.second._data(); - DetElement c = d.clone(d.id, DetElement::COPY_PLACEMENT); + DetElement c = d.clone(obj->id, DetElement::COPY_PLACEMENT); c->SetName(d.GetName()); c->SetTitle(d.GetTitle()); bool r = obj->children.emplace(c.name(), c).second; @@ -137,21 +137,24 @@ DetElementObject* DetElementObject::clone(int new_id, int flg) const { pair<DetElement,Volume> DetElementObject::reflect(const std::string& new_name, int new_id, SensitiveDetector sd) { struct ChildMapper { std::map<TGeoNode*,TGeoNode*> nodes; - void match(DetElement de) { - auto i = nodes.find(de.placement().ptr()); - if ( i == nodes.end() ) { + void match(DetElement de_det, DetElement de_ref) const { + auto k = nodes.find(de_det.placement().ptr()); + printout(INFO,"","Match %s %p ",de_det.name(), de_det.placement().ptr()); + if ( k == nodes.end() ) { except("DetElement","reflect: Something went wrong when reflecting the source volume!"); } - de.setPlacement((*i).second); - const auto& childrens = de.children(); - for( const auto& c : childrens ) - match(c.second); + de_ref.setPlacement((*k).second); + const auto& childrens_det = de_det.children(); + const auto& childrens_ref = de_ref.children(); + for(auto i=childrens_det.begin(), j=childrens_ref.begin(); i!=childrens_det.end(); ++i, ++j) + match((*i).second, (*j).second); } void map(TGeoNode* n1, TGeoNode* n2) { if ( nodes.find(n1) == nodes.end() ) { TGeoVolume* v1 = n1->GetVolume(); TGeoVolume* v2 = n2->GetVolume(); nodes.insert(make_pair(n1,n2)); + printout(INFO,"","Map %p --- %p ",n1,n2); for(Int_t i=0; i<v1->GetNdaughters(); ++i) map(v1->GetNode(i), v2->GetNode(i)); } @@ -162,12 +165,13 @@ pair<DetElement,Volume> DetElementObject::reflect(const std::string& new_name, i Volume vol = det.volume(); TGeoVolume* vol_det = vol.ptr(); TGeoVolume* vol_ref = vol.reflect(sd); - const auto& childrens = det.children(); + const auto& childrens_det = det.children(); + const auto& childrens_ref = det_ref.children(); for(Int_t i=0; i<vol_det->GetNdaughters(); ++i) mapper.map(vol_det->GetNode(i), vol_ref->GetNode(i)); - for(const auto& c : childrens) - mapper.match(c.second); + for(auto i=childrens_det.begin(), j=childrens_ref.begin(); i!=childrens_det.end(); ++i, ++j) + mapper.match((*i).second, (*j).second); return make_pair(det_ref,vol_ref); } diff --git a/DDDetectors/src/ReflectedDetector_geo.cpp b/DDDetectors/src/ReflectedDetector_geo.cpp index cb717643eb34ee1d3dc84038d56d5feb4d8fbb42..3d7bb5bd1984df841dbe6bb0fd091bb14ff8cbe5 100644 --- a/DDDetectors/src/ReflectedDetector_geo.cpp +++ b/DDDetectors/src/ReflectedDetector_geo.cpp @@ -26,8 +26,9 @@ using namespace dd4hep::detail; static Ref_t create_element(Detector& description, xml_h e, Ref_t sens) { xml_det_t x_det (e); SensitiveDetector sd = sens; - xml_dim_t pos = x_det.child(_U(position),false); - xml_dim_t rot = x_det.child(_U(rotation),false); + xml_dim_t x_pos = x_det.child(_U(position),false); + xml_dim_t x_rot = x_det.child(_U(rotation),false); + xml_dim_t x_refl = x_det.child(_U(reflect),false); string ref_nam = x_det.attr<string>(_U(sdref)); DetElement ref_det = description.detector(ref_nam); auto refl = ref_det.reflect(x_det.nameStr(), x_det.id(), sd); @@ -45,31 +46,33 @@ static Ref_t create_element(Detector& description, xml_h e, Ref_t sens) { sd.setType(sd_typ.typeStr()); } PlacedVolume pv; + RotationZYX rot3D; + Position tr3D; + Transform3D transform3D; Volume mother = description.pickMotherVolume(sdet); - if ( pos && rot ) { - pv = mother.placeVolume(vol,Transform3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)),Position(pos.x(0),pos.y(0),pos.z(0)))); - printout(INFO,"ReflectedDet","Transform3D placement at pos: %f %f %f rot: %f %f %f", - pos.x(0),pos.y(0),pos.z(0), rot.x(0),rot.y(0),rot.z(0)); + if ( x_pos ) { + tr3D = Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)); } - else if ( rot ) { - printout(INFO,"ReflectedDet","Rotation placement at %f %f %f",rot.x(0),rot.y(0),rot.z(0)); - pv = mother.placeVolume(vol,RotationZYX(rot.z(0),rot.y(0),rot.x(0))); + if ( x_rot ) { + rot3D = RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)); } - else if ( pos ) { - printout(INFO,"ReflectedDet","Positional placing at %f %f %f",pos.x(0),pos.y(0),pos.z(0)); - pv = mother.placeVolume(vol,Position(pos.x(0),pos.y(0),pos.z(0))); - } - else { + if ( !x_pos && !x_rot ) { auto ref_pv = ref_det.placement(); - RotationZYX rot3D; - Position tr3D; matrix::_decompose(ref_pv.matrix(), tr3D, rot3D); tr3D = tr3D * (-1.0 / dd4hep::mm); - rot3D = rot3D * RotationZ(); - pv = mother.placeVolume(vol, Transform3D(rot3D, tr3D)); - printout(INFO,"ReflectedDet","Transform3D placement at pos: %f %f %f rot: %f %f %f", - tr3D.X(),tr3D.Y(),tr3D.Z(), rot3D.Phi(),rot3D.Theta(),rot3D.Psi()); } + if ( x_refl && ::toupper(x_refl.attr<string>(_U(type))[0]) == 'Z' ) + transform3D = Transform3D(Rotation3D( 1., 0., 0., 0., 1., 0., 0., 0., -1.) * rot3D, tr3D); + else if ( x_refl && ::toupper(x_refl.attr<string>(_U(type))[0]) == 'Y' ) + transform3D = Transform3D(Rotation3D( 1., 0., 0., 0., -1., 0., 0., 0., 1.) * rot3D, tr3D); + else if ( x_refl && ::toupper(x_refl.attr<string>(_U(type))[0]) == 'X' ) + transform3D = Transform3D(Rotation3D(-1., 0., 0., 0., 1., 0., 0., 0., 1.) * rot3D, tr3D); + else // Z is default + transform3D = Transform3D(Rotation3D( 1., 0., 0., 0., 1., 0., 0., 0., -1.) * rot3D, tr3D); + pv = mother.placeVolume(vol, transform3D); + printout(INFO,"ReflectedDet","Transform3D placement at pos: %f %f %f rot: %f %f %f", + tr3D.X(),tr3D.Y(),tr3D.Z(), rot3D.Phi(),rot3D.Theta(),rot3D.Psi()); + if ( x_det.hasAttr(_U(id)) ) { pv.addPhysVolID("system",x_det.id()); } diff --git a/examples/ClientTests/compact/CheckShape.xml b/examples/ClientTests/compact/CheckShape.xml index 287fcefcf003e30a1b5eceb06d77bc1f3a0a459b..eb9130685a2056516c8077eb68b224549260857c 100644 --- a/examples/ClientTests/compact/CheckShape.xml +++ b/examples/ClientTests/compact/CheckShape.xml @@ -50,6 +50,7 @@ <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> <vis name="Shape1_vis_20" alpha="0.2" r="0.9" g="0.8" b="0.8" showDaughters="true" visible="true"/> + <vis name="ShapeGray_vis_50" alpha="0.5" r="0.9" g="0.8" b="0.8" showDaughters="true" visible="true"/> <vis name="Shape1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/> <vis name="Shape2_vis" alpha="1.0" r="0" g="1" b="0" showDaughters="true" visible="true"/> <vis name="Shape3_vis" alpha="1.0" r="0" g="0" b="1" showDaughters="true" visible="true"/> diff --git a/examples/ClientTests/compact/Check_Shape_Box_Reflect_DetElement.xml b/examples/ClientTests/compact/Check_Shape_Box_Reflect_DetElement.xml new file mode 100644 index 0000000000000000000000000000000000000000..7c60ec4edc3e78e28bb4ee32fbd1f6e54664df16 --- /dev/null +++ b/examples/ClientTests/compact/Check_Shape_Box_Reflect_DetElement.xml @@ -0,0 +1,44 @@ +<lccdd> + <includes> + <gdmlFile ref="CheckShape.xml"/> + </includes> + + <detectors> + <detector id="1" name="AssemblyDetector" parent="/world" type="DD4hep_VolumeAssembly" vis="ShapeGray_vis_50"> + <envelope material="Air"> + <shape name="BiggerBox" type="Box" dx="100" dy="100" dz="100"/> + </envelope> + <position x="0" y="0" z="0"/> + <volume name="lvSmallerBox1" material="Air" vis="Shape1_vis"> + <shape type="Box" dx="5" dy="5" dz="5"/> + </volume> + <volume name="lvSmallerBox2" material="Air" vis="Shape2_vis"> + <shape type="Box" dx="10" dy="10" dz="10"/> + </volume> + <volume name="lvSmallerBox3" material="Air" vis="Shape3_vis"> + <shape type="Box" dx="20" dy="20" dz="20"/> + </volume> + <physvol element="Smaller1" volume="lvSmallerBox1"> + <position x="0" y="0" z="0"/> + </physvol> + <physvol element="Smaller2" volume="lvSmallerBox2"> + <position x="-90" y="-90" z="-90"/> + </physvol> + <physvol element="Smaller3" volume="lvSmallerBox3"> + <position x="80" y="80" z="80"/> + </physvol> + </detector> + <detector id="2" name="AssemblyReflected_Z" type="DD4hep_ReflectedDetector" sdref="AssemblyDetector"> + <reflect type="Z"/> + <position x="0" y="0" z="-200"/> + </detector> + <detector id="3" name="AssemblyReflected_Y" type="DD4hep_ReflectedDetector" sdref="AssemblyDetector"> + <reflect type="Y"/> + <position x="0" y="200" z="0"/> + </detector> + <detector id="4" name="AssemblyReflected_X" type="DD4hep_ReflectedDetector" sdref="AssemblyDetector"> + <reflect type="X"/> + <position x="200" y="0" z="0"/> + </detector> + </detectors> +</lccdd>