diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 3db7993c79a1a8aa770e8d0683f060077f65cf92..d6e60d6185bcb14b085ebfcc69fc2b73c88c601b 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -93,7 +93,14 @@ namespace DD4hep { typedef Ref_t Parent; typedef std::map<std::string,DetElement> Children; typedef std::vector<PlacedVolume> Placements; - + + enum { + COPY_NONE = 0, + COPY_PLACEMENT = 1<<0, + COPY_PARENT = 1<<1, + COPY_ALIGNMENT = 1<<2, + LAST + } CopyParameters; struct Object { unsigned int magic; int id; @@ -103,15 +110,16 @@ namespace DD4hep { Readout readout; Alignment alignment; Conditions conditions; + PlacedVolume placement; Placements placements; Parent parent; Children children; /// Default constructor Object(); /// Construct new empty object - virtual Value<TNamed,Object>* construct(int new_id) const; + virtual Value<TNamed,Object>* construct(int new_id, int flag) const; /// Deep object copy to replicate DetElement trees e.g. for reflection - virtual void deepCopy(const Object& source, int new_id); + virtual void deepCopy(const Object& source, int new_id, int flag); }; /// Additional data accessor @@ -166,10 +174,16 @@ namespace DD4hep { /// Assign readout definition DetElement& setReadout(const Readout& readout); + /// Access to the physical volume of this detector element + PlacedVolume placement() const; + /// Set the physical volumes of the detector element + DetElement& setPlacement(const PlacedVolume& volume); + /// Access the physical volumes of the detector element Placements placements() const; /// Set the physical volumes of the detector element DetElement& addPlacement(const PlacedVolume& volume); + /// Access to the logical volume of the placements (all daughters have the same!) Volume volume() const; diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index c6bba7bcd726c1b5dd443e642d937b433392c8a2..bfe18cdb8862623ca5f9c170fae737991cd9fe47 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -17,29 +17,33 @@ using namespace DD4hep::Geometry; /// Default constructor DetElement::Object::Object() : magic(magic_word()), id(0), combine_hits(0), readout(), - alignment(), placements(), parent(), children() + alignment(), placement(), placements(), parent(), children() { } /// Construct new empty object -Value<TNamed,DetElement::Object>* DetElement::Object::construct(int new_id) const { +Value<TNamed,DetElement::Object>* DetElement::Object::construct(int new_id, int flag) const { Value<TNamed,Object>* obj = new Value<TNamed,Object>(); - obj->deepCopy(*this,new_id); + obj->deepCopy(*this,new_id,flag); return obj; } /// Deep object copy to replicate DetElement trees e.g. for reflection -void DetElement::Object::deepCopy(const Object& source, int new_id) { +void DetElement::Object::deepCopy(const Object& source, int new_id, int flag) { id = new_id; combine_hits = source.combine_hits; readout = source.readout; volume = source.volume; alignment = Alignment(); conditions = Conditions(); - placements = Placements(); - parent = DetElement(); + parent = ((flag©_PARENT) == COPY_PARENT) ? source.parent : DetElement(); + placement = ((flag©_PLACEMENT) == COPY_PLACEMENT) ? source.placement : PlacedVolume(); + + placements = ((flag©_PLACEMENT) == COPY_PLACEMENT) ? source.placements : Placements(); for(DetElement::Children::const_iterator i=source.children.begin(); i != source.children.end(); ++i) { - DetElement child = (*i).second.clone((*i).second->GetName()); + const DetElement::Object& d = (*i).second._data(); + const TNamed* pc = (*i).second.ptr(); + DetElement child(d.construct(d.id,COPY_PLACEMENT|COPY_PARENT),pc->GetName(),pc->GetTitle()); children.insert(make_pair((*i).first,child)); } } @@ -129,18 +133,45 @@ DetElement::Placements DetElement::placements() const { DetElement DetElement::clone(const string& new_name) const { if ( isValid() ) { - return DetElement(_data().construct(_data().id), new_name, ptr()->GetTitle()); + return DetElement(_data().construct(_data().id,COPY_NONE), new_name, ptr()->GetTitle()); } throw runtime_error("DetElement::clone: Self is not defined - clone failed! [Invalid Handle]"); } DetElement DetElement::clone(const string& new_name, int new_id) const { if ( isValid() ) { - return DetElement(_data().construct(new_id), new_name, ptr()->GetTitle()); + return DetElement(_data().construct(new_id, COPY_NONE), new_name, ptr()->GetTitle()); } throw runtime_error("DetElement::clone: Self is not defined - clone failed! [Invalid Handle]"); } +/// Access to the physical volume of this detector element +PlacedVolume DetElement::placement() const { + if ( isValid() ) { + Object& o = _data(); + if ( o.placement.isValid() ) { + return o.placement; + } + } + return PlacedVolume(); +} + +/// Set the physical volumes of the detector element +DetElement& DetElement::setPlacement(const PlacedVolume& placement) { + if ( isValid() ) { + if ( placement.isValid() ) { + Object& o = _data(); + o.placement = placement; + o.volume = placement.volume(); + placement.setDetElement(*this); + return *this; + } + throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]"); + } + throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]"); +} + + DetElement& DetElement::addPlacement(const PlacedVolume& placement) { if ( isValid() ) { if ( placement.isValid() ) { diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index de6da0f03363a85086b1b69d9a2a699f7e570e11..76aed073971246e8b4f57c8987aca08c29e39fc3 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -17,6 +17,9 @@ #include "TGeoMatrix.h" #include "TGeoMedium.h" +#include "TGeoVoxelFinder.h" +#include "TGeoShapeAssembly.h" + // C/C++ include files #include <climits> #include <iostream> @@ -81,12 +84,98 @@ namespace DD4hep { namespace Geometry { : public _VolWrap<TGeoVolume>, public Volume::Object { Value(const char* name, TGeoShape* s=0, TGeoMedium* m=0) : _VolWrap<TGeoVolume>(name,s,m) {magic = magic_word();} virtual ~Value() {} + virtual TGeoVolume* MakeCopyVolume(TGeoShape *newshape) { + // make a copy of this volume. build a volume with same name, shape and medium + TGeoVolume *vol = new Value<TGeoVolume,Volume::Object>(GetName(), newshape, fMedium); + vol->SetVisibility(IsVisible()); + vol->SetLineColor(GetLineColor()); + vol->SetLineStyle(GetLineStyle()); + vol->SetLineWidth(GetLineWidth()); + vol->SetFillColor(GetFillColor()); + vol->SetFillStyle(GetFillStyle()); + vol->SetField(fField); + if (fFinder) vol->SetFinder(fFinder); + CloneNodesAndConnect(vol); + ((TObject*)vol)->SetBit(kVolumeClone); + return vol; + } + TGeoVolume* CloneVolume() const { + TGeoVolume *vol = new Value<TGeoVolume,Volume::Object>(GetName(), fShape, fMedium); + Int_t i; + // copy volume attributes + vol->SetLineColor(GetLineColor()); + vol->SetLineStyle(GetLineStyle()); + vol->SetLineWidth(GetLineWidth()); + vol->SetFillColor(GetFillColor()); + vol->SetFillStyle(GetFillStyle()); + // copy other attributes + Int_t nbits = 8*sizeof(UInt_t); + for (i=0; i<nbits; i++) + vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i)); + for (i=14; i<24; i++) + vol->SetBit(1<<i, TestBit(1<<i)); + + // copy field + vol->SetField(fField); + // Set bits + for (i=0; i<nbits; i++) + vol->SetBit(1<<i, TObject::TestBit(1<<i)); + vol->SetBit(kVolumeClone); + // copy nodes + // CloneNodesAndConnect(vol); + vol->MakeCopyNodes(this); + // if volume is divided, copy finder + vol->SetFinder(fFinder); + // copy voxels + TGeoVoxelFinder *voxels = 0; + if (fVoxels) { + voxels = new TGeoVoxelFinder(vol); + vol->SetVoxelFinder(voxels); + } + // copy option, uid + vol->SetOption(fOption); + vol->SetNumber(fNumber); + vol->SetNtotal(fNtotal); + return vol; + } }; template <> struct Value<TGeoVolumeAssembly,Assembly::Object> : public _VolWrap<TGeoVolumeAssembly>, public Assembly::Object { Value(const char* name) : _VolWrap<TGeoVolumeAssembly>(name,0,0) { magic = magic_word(); } virtual ~Value() {} + + TGeoVolume *CloneVolume() const { + TGeoVolume *vol = new Value<TGeoVolumeAssembly,Assembly::Object>(GetName()); + Int_t i; + // copy other attributes + Int_t nbits = 8*sizeof(UInt_t); + for (i=0; i<nbits; i++) + vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i)); + for (i=14; i<24; i++) + vol->SetBit(1<<i, TestBit(1<<i)); + + // copy field + vol->SetField(fField); + // Set bits + for (i=0; i<nbits; i++) + vol->SetBit(1<<i, TObject::TestBit(1<<i)); + vol->SetBit(kVolumeClone); + // make copy nodes + vol->MakeCopyNodes(this); + ((TGeoShapeAssembly*)vol->GetShape())->NeedsBBoxRecompute(); + // copy voxels + TGeoVoxelFinder *voxels = 0; + if (fVoxels) { + voxels = new TGeoVoxelFinder(vol); + vol->SetVoxelFinder(voxels); + } + // copy option, uid + vol->SetOption(fOption); + vol->SetNumber(fNumber); + vol->SetNtotal(fNtotal); + return vol; + } }; }}