diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp index 107c60c06d751cfdc8aaa62141aca11fbe400f6b..2ec4b8e1d72a8dcb83102e511b6885ae29a3c6c7 100644 --- a/DDCore/src/DetectorImp.cpp +++ b/DDCore/src/DetectorImp.cpp @@ -648,7 +648,25 @@ namespace { } } }; - + void build_reflections(TGeoManager* mgr) { + TGeoIterator next(mgr->GetTopVolume()); + TGeoNode *node; + while ((node=next())) { + TGeoMatrix* m = node->GetMatrix(); + if (m->IsReflection()) { + Volume vol(node->GetVolume()); + TGeoMatrix* mclone = new TGeoCombiTrans(*m); + mclone->RegisterYourself(); + // Reflect just the rotation component + mclone->ReflectZ(kFALSE, kTRUE); + TGeoNodeMatrix* nodematrix = (TGeoNodeMatrix*)node; + nodematrix->SetMatrix(mclone); + printout(INFO,"Detector","Reflecting volume: %s ",vol.name()); + Volume refl = vol.reflect(vol.sensitiveDetector()); + node->SetVolume(refl.ptr()); + } + } + } } /// Finalize/close the geometry @@ -672,6 +690,7 @@ void DetectorImp::endDocument(bool close_geometry) { /// Since we allow now for anonymous shapes, /// we will rename them to use the name of the volume they are assigned to mgr->CloseGeometry(); + build_reflections(mgr); } ShapePatcher patcher(m_volManager, m_world); patcher.patchShapes(); diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 2fd8a248858e8cfe6dcaa10cee78e458c1e206e3..bb44dcfe8e5af30c1257b95c2055bb4d27d335b3 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -619,22 +619,20 @@ PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* } } } + geo_node_t* n {nullptr}; + TString nam_id = TString::Format("%s_%d", daughter->GetName(), id); if ( s_verifyCopyNumbers ) { - for (Int_t i=0, m=parent->GetNdaughters(); i < m; i++) { - TGeoNode *n = (TGeoNode*)parent->GetNode(i); - if ( n->GetNumber() == id ) { - printout(ERROR,"PlacedVolume", - "++ Severe error: %s Attempt to add already exiting copy number %d %s", - parent->GetName(), n->GetNumber(), n->GetName()); - break; - } + n = static_cast<geo_node_t*>(parent->GetNode(nam_id)); + if ( n != 0 ) { + printout(ERROR,"PlacedVolume","++ Attempt to place already exiting node %s",(const char*)nam_id); } } - geo_node_t* n {nullptr}; /* n = */ parent->AddNode(daughter, id, transform); - //n = static_cast<geo_node_t*>(parent->GetNode(id)); //n = static_cast<geo_node_t*>(parent->GetNode(nam_id)); n = static_cast<geo_node_t*>(parent->GetNodes()->Last()); + if ( nam_id != n->GetName() ) { + printout(ERROR,"PlacedVolume","++ FAILED to place node %s",(const char*)nam_id); + } n->geo_node_t::SetUserExtension(new PlacedVolume::Object()); return PlacedVolume(n); } diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index 0af71d7481e7284e1798769c58638b2b24b8d6f9..c7cfdaebcba13b29bad4796332793e36f9250d58 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -585,7 +585,7 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c Solid s_sh(sh->GetShape()); G4VSolid* scaled = (G4VSolid*)handleSolid(s_sh.name(), s_sh.ptr()); solid = new G4ReflectedSolid(scaled->GetName() + "_refl", - scaled, G4Scale3D(vals[0],vals[1],vals[2])); + scaled, G4Scale3D(vals[0],vals[1],vals[2])); } else if (isa == TGeoCompositeShape::Class()) { const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape; @@ -771,14 +771,16 @@ void* Geant4Converter::handleAssembly(const string& name, const TGeoNode* node) return 0; } Geant4GeometryInfo& info = data(); - Geant4AssemblyVolume* g4 = nullptr; // info.g4AssemblyVolumes[node]; - + Geant4AssemblyVolume* g4 = info.g4AssemblyVolumes[node]; + if ( g4 ) { + printout(ALWAYS, "Geant4Converter", "+++ Assembly: **** : Re-using existing assembly: %s",node->GetName()); + } if ( !g4 ) { g4 = new Geant4AssemblyVolume(); for(Int_t i=0; i < mot_vol->GetNdaughters(); ++i) { - TGeoNode* d = mot_vol->GetNode(i); - TGeoVolume* dau_vol = d->GetVolume(); - TGeoMatrix* tr = d->GetMatrix(); + TGeoNode* dau = mot_vol->GetNode(i); + TGeoVolume* dau_vol = dau->GetVolume(); + TGeoMatrix* tr = dau->GetMatrix(); MyTransform3D transform(tr->GetTranslation(),tr->IsRotation() ? tr->GetRotationMatrix() : s_identity_rot); if ( is_left_handed(tr) ) { @@ -790,27 +792,27 @@ void* Geant4Converter::handleAssembly(const string& name, const TGeoNode* node) } if ( dau_vol->IsA() == TGeoVolumeAssembly::Class() ) { - Geant4GeometryMaps::AssemblyMap::iterator assIt = info.g4AssemblyVolumes.find(d); - if ( assIt == info.g4AssemblyVolumes.end() ) { + Geant4GeometryMaps::AssemblyMap::iterator ia = info.g4AssemblyVolumes.find(dau); + if ( ia == info.g4AssemblyVolumes.end() ) { printout(FATAL, "Geant4Converter", "+++ Invalid child assembly at %s : %d parent: %s child:%s", - __FILE__, __LINE__, name.c_str(), d->GetName()); + __FILE__, __LINE__, name.c_str(), dau->GetName()); return 0; } - g4->placeAssembly(d,(*assIt).second,transform); + g4->placeAssembly(dau,(*ia).second,transform); printout(lvl, "Geant4Converter", "+++ Assembly: AddPlacedAssembly : dau:%s " "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f", dau_vol->GetName(), mot_vol->GetName(), transform.dx(), transform.dy(), transform.dz()); } else { - Geant4GeometryMaps::VolumeMap::iterator volIt = info.g4Volumes.find(dau_vol); - if ( volIt == info.g4Volumes.end() ) { + Geant4GeometryMaps::VolumeMap::iterator iv = info.g4Volumes.find(dau_vol); + if ( iv == info.g4Volumes.end() ) { printout(FATAL,"Geant4Converter", "+++ Invalid child volume at %s : %d parent: %s child:%s", - __FILE__, __LINE__, name.c_str(), d->GetName()); + __FILE__, __LINE__, name.c_str(), dau->GetName()); except("Geant4Converter", "+++ Invalid child volume at %s : %d parent: %s child:%s", - __FILE__, __LINE__, name.c_str(), d->GetName()); + __FILE__, __LINE__, name.c_str(), dau->GetName()); } - g4->placeVolume(d,(*volIt).second, transform); + g4->placeVolume(dau,(*iv).second, transform); printout(lvl, "Geant4Converter", "+++ Assembly: AddPlacedVolume : dau:%s " "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f", dau_vol->GetName(), mot_vol->GetName(), @@ -842,11 +844,11 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) TGeoVolume* new_vol = new_node->GetVolume(); TGeoMatrix* old_tr = old_node->GetMatrix(); TGeoMatrix* new_tr = new_node->GetMatrix(); - printout(ALWAYS, "Geant4Converter", "+++ Placement: **** OLD: %s vol: %s %s NEW: %s vol: %s %s", + printout(ALWAYS, "Geant4Converter", "+++ Placement: **** Reuse: OLD: %s vol: %s %s NEW: %s vol: %s %s", old_node->GetName(), old_vol->GetName(), is_left_handed(old_tr) ? " REFLECTED" : "NOT REFLECTED", new_node->GetName(), new_vol->GetName(), is_left_handed(new_tr) ? " REFLECTED" : "NOT REFLECTED"); } - g4 = nullptr; + //g4 = nullptr; if (!g4) { TGeoVolume* mot_vol = node->GetMotherVolume(); TGeoMatrix* tr = node->GetMatrix(); @@ -917,15 +919,15 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) // First 2 cases can be combined. // Leave them separated for debugging G4ReflectionFactory for now... if ( node_is_reflected && !pvPlaced.second ) - return info.g4Placements[node] = pvPlaced.first; + return info.g4Placements[node] = pvPlaced.first; else if ( !node_is_reflected && !pvPlaced.second ) - return info.g4Placements[node] = pvPlaced.first; - G4LogicalVolume* g4refMoth = G4ReflectionFactory::Instance()->GetReflectedLV(g4mot); + return info.g4Placements[node] = pvPlaced.first; + //G4LogicalVolume* g4refMoth = G4ReflectionFactory::Instance()->GetReflectedLV(g4mot); // Now deal with valid pvPlaced.second ... if ( node_is_reflected ) - return info.g4Placements[node] = pvPlaced.first; + return info.g4Placements[node] = pvPlaced.first; else if ( !node_is_reflected ) - return info.g4Placements[node] = pvPlaced.first; + return info.g4Placements[node] = pvPlaced.first; g4 = pvPlaced.second ? pvPlaced.second : pvPlaced.first; } info.g4Placements[node] = g4; diff --git a/examples/ClientTests/compact/NestedBoxReflection.xml b/examples/ClientTests/compact/NestedBoxReflection.xml index abc1dfa743234d84d48c1d6a70de8c5b16345c7d..de44bad6e336777e79b9eb67fa6e5f10875f20e7 100644 --- a/examples/ClientTests/compact/NestedBoxReflection.xml +++ b/examples/ClientTests/compact/NestedBoxReflection.xml @@ -36,6 +36,7 @@ <detectors> <detector id="1" name="NestedBox" type="NestedBoxReflection" readout="NestedBoxHits" vis="VisibleGreen" limits="cal_limits"> <comment>A box with 3 boxes inside spanning a coordinate system</comment> + <assembly/> <dimensions x="50*cm" y="70*cm" z="90*cm"/> <xxxreflect_z/> <no-reflect name="ReflectionY"> diff --git a/examples/ClientTests/src/NestedBoxReflection_geo.cpp b/examples/ClientTests/src/NestedBoxReflection_geo.cpp index d10ae6f5f389798e56be564a9120c84b3e7b346d..937ab6c3b9aea273dafc30c6f027c69dad9a44ef 100644 --- a/examples/ClientTests/src/NestedBoxReflection_geo.cpp +++ b/examples/ClientTests/src/NestedBoxReflection_geo.cpp @@ -162,7 +162,7 @@ namespace { sensitive.setType("tracker"); box_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),"VisibleGrey"); - if ( x_box.typeStr() == "assembly" ) + if ( x_det.hasChild(_U(assembly)) ) v_det = Assembly(x_det.nameStr()+"_det"); else v_det = Volume(x_det.nameStr()+"_det",Box(2.5*bx,2.5*by,2.5*bz),description.air());