diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h index ed8de7473bd0c43308c913b7f5f8c1e33512f002..5416f2824883e469b5aca0598d73b3c59e2b49d4 100644 --- a/DDCore/include/DD4hep/GeoHandler.h +++ b/DDCore/include/DD4hep/GeoHandler.h @@ -46,6 +46,7 @@ namespace DD4hep { public: typedef std::set<TGeoVolume*> VolumeSet; + typedef std::vector<TGeoVolume*> VolumeVector; typedef std::set<const TGeoVolume*> ConstVolumeSet; typedef std::vector<std::pair<std::string, TGeoMatrix*> > TransformSet; typedef std::set<TGeoShape*> SolidSet; @@ -61,7 +62,8 @@ namespace DD4hep { struct GeometryInfo { SolidSet solids; - VolumeSet volumes; + VolumeSet volumeSet; + VolumeVector volumes; TransformSet trafos; VisRefs vis; Fields fields; diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index ede1603ce17e46d62aa6e9659050b807bcde9004..82183a724ab404ddde39a21062700d366e635c2d 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -213,7 +213,7 @@ namespace DD4hep { double GetRmin() const { return GetRmin1(); } double GetRmax() const { return GetRmax1(); } }; - struct Tube : public Solid_type</*TGeoTubeSeg */ MyConeSeg> { + struct Tube : public Solid_type<TGeoTubeSeg /* MyConeSeg */> { protected: void make(const std::string& name,double rmin,double rmax,double z,double startPhi,double deltaPhi); @@ -449,6 +449,11 @@ namespace DD4hep { * @version 1.0 */ struct PolyhedraRegular : public Solid_type<TGeoPgon> { + protected: + /// Helper function to create holy hedron + void _create(const std::string& name, int nsides, double rmin, double rmax, + double zpos, double zneg, double start, double delta); + public: /// Constructor to be used when reading the already parsed object template <typename Q> PolyhedraRegular(const Handle<Q>& e) : Solid_type<Implementation>(e) {} diff --git a/DDCore/include/XML/DocumentHandler.h b/DDCore/include/XML/DocumentHandler.h index 85c038d6721618313c476fa188aa6c77ad556840..c7f9a74932e5fe06be2958100a754b5ff5225c73 100644 --- a/DDCore/include/XML/DocumentHandler.h +++ b/DDCore/include/XML/DocumentHandler.h @@ -41,6 +41,8 @@ namespace DD4hep { DocumentHandler(); /// Default destructor virtual ~DocumentHandler(); + // Create new XML document by parsing empty xml buffer + Document create(const char* tag, const char* comment=0) const; /// Load XML file and parse it. virtual Document load(const std::string& fname) const; /// Load secondary XML file with relative addressing with respect to handle diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index 138a4ea454bf511137069029a87d66e26f45c2db..c571231bd5f3ba56f8787da88cde548b210a791c 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -7,11 +7,6 @@ namespace DD4hep { namespace XML { extern const Tag_t Unicode_PI; extern const Tag_t Unicode_TWOPI; - UNICODE(value); - UNICODE(radian); - UNICODE(ref); - - UNICODE(0); UNICODE(1); UNICODE(2); @@ -35,6 +30,7 @@ namespace DD4hep { namespace XML { UNICODE(alpha2); UNICODE(alpha3); UNICODE(alpha4); + UNICODE(arb8); UNICODE(assembly); UNICODE(atom); UNICODE(attributes); @@ -43,11 +39,11 @@ namespace DD4hep { namespace XML { UNICODE(b); UNICODE(B); - UNICODE(box); UNICODE(barrel); UNICODE(barrel_envelope); UNICODE(beampipe); UNICODE(beta); + UNICODE(box); UNICODE(c); UNICODE(C); @@ -72,6 +68,7 @@ namespace DD4hep { namespace XML { UNICODE(d); UNICODE(D); UNICODE(define); + UNICODE(delta); UNICODE(deltaphi); UNICODE(deltatheta); UNICODE(depth); @@ -104,6 +101,7 @@ namespace DD4hep { namespace XML { UNICODE(end_modules); UNICODE(endcap); UNICODE(endphi); + UNICODE(epsilon); UNICODE(eunit); UNICODE(end_x); UNICODE(end_y); @@ -152,6 +150,7 @@ namespace DD4hep { namespace XML { UNICODE(header); UNICODE(height); UNICODE(hits_collection); + UNICODE(hype); UNICODE(i); UNICODE(I); @@ -240,6 +239,7 @@ namespace DD4hep { namespace XML { UNICODE(outer_radius); UNICODE(outer_z); UNICODE(outgoing_r); + UNICODE(outst); UNICODE(p); UNICODE(P); @@ -273,12 +273,15 @@ namespace DD4hep { namespace XML { UNICODE(R); UNICODE(r_size); UNICODE(r0); + UNICODE(rad); + UNICODE(radian); UNICODE(radius); UNICODE(radiator); UNICODE(rbg); UNICODE(rc); UNICODE(readout); UNICODE(readouts); + UNICODE(ref); UNICODE(reflect); UNICODE(reflect_rot); UNICODE(region); @@ -371,7 +374,24 @@ namespace DD4hep { namespace XML { UNICODE(v); UNICODE(V); + UNICODE(v1x); + UNICODE(v1y); + UNICODE(v2x); + UNICODE(v2y); + UNICODE(v3x); + UNICODE(v3y); + UNICODE(v4x); + UNICODE(v4y); + UNICODE(v5x); + UNICODE(v5y); + UNICODE(v6x); + UNICODE(v6y); + UNICODE(v7x); + UNICODE(v7y); + UNICODE(v8x); + UNICODE(v8y); UNICODE(Vacuum); + UNICODE(value); UNICODE(verbose); UNICODE(version); UNICODE(vis); diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h index cd666d4bb55fdf7f0b0206bf535fdad2308aa8ae..c36db45b6c7e478f14eebe73abd73934c6597101 100644 --- a/DDCore/include/XML/XMLDetector.h +++ b/DDCore/include/XML/XMLDetector.h @@ -62,6 +62,16 @@ namespace DD4hep { /// Access rotation constants: angle double angle() const; + /// Access rotation constants: angle + double alpha() const; + /// Access rotation constants: angle + double beta() const; + /// Access rotation constants: angle + double gamma() const; + /// Access rotation constants: angle + double delta() const; + /// Access rotation constants: angle + double epsilon() const; /// Access rotation constants: theta double theta() const; /// Access rotation constants: thetaBins @@ -83,6 +93,15 @@ namespace DD4hep { /// Access Tube parameters: deltaphi double deltaphi() const; + /// Access parameters: b + double b() const; + /// Access parameters: B + double B() const; + /// Access parameters: g + double g() const; + /// Access parameters: G + double G() const; + /// Access parameters: r double r() const; /// Access parameters: r, if not present returns default @@ -288,6 +307,11 @@ namespace DD4hep { /// Access attribute values: outer_field double outer_field() const; + /// Access attribute values: visible + bool visible() const; + /// Access attribute values: show_daughters + bool show_daughters() const; + /// Access child element with tag "dimensions" as Dimension object Dimension dimensions(bool throw_if_not_present=true) const; /// Child access: position @@ -305,6 +329,8 @@ namespace DD4hep { /// Access name attribute as STL string std::string nameStr() const; + /// Access ref attribute as a string + std::string refStr() const; /// Access type attribute as STL string std::string typeStr() const; /// Access module attribute as STL string @@ -349,7 +375,7 @@ namespace DD4hep { struct DetElement : public Dimension { /// Constructor from Handle DetElement(Handle_t e) : Dimension(e) {} - /// Access undrlying XML handle object + /// Access underlying XML handle object Handle_t handle() const { return m_element; } /// Access parameters: id diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 7916eaba459b9717181343acc2463788867b542e..28393cf8ac66e44b160633bf4c655fcd206cf6f2 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -374,6 +374,8 @@ namespace DD4hep { /// Add reference child as a new child node. The obj must have the "name" attribute! Handle_t setRef(const XmlChar* tag, const XmlChar* ref); + /// Add reference child as a new child node. The obj must have the "name" attribute! + Handle_t setRef(const XmlChar* tag, const std::string& ref); /*** DOM Element child handling */ @@ -606,8 +608,12 @@ namespace DD4hep { bool hasChild(const XmlChar* tag) const { return m_element.hasChild(tag); } /// Set the reference attribute to the node (adds attribute ref="ref-name") Attribute setRef(const XmlChar* tag, const XmlChar* refname) const; + /// Set the reference attribute to the node (adds attribute ref="ref-name") + Attribute setRef(const XmlChar* tag, const std::string& refname) const; /// Access the value of the reference attribute of the node (attribute ref="ref-name") const XmlChar* getRef(const XmlChar* tag) const; + /// Add comment node to the element + void addComment(const char* text) const; }; /** @class RefElement XMLElements.h XML/XMLElements.h diff --git a/DDCore/include/XML/config.h b/DDCore/include/XML/config.h index 81dd70ede4bd67e58b4a6e119bad80972be8c2b3..f36432d0f677a2563e66bc26dcd8c6960e9a4825 100644 --- a/DDCore/include/XML/config.h +++ b/DDCore/include/XML/config.h @@ -36,10 +36,7 @@ namespace DD4hep { namespace XML { #ifdef __TIXML__ #define XML_IMPLEMENTATION_TYPE " TinyXML DOM mini-parser " -#define XML_HEADER_DECLARATION "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" #else // Xerces-C #define XML_IMPLEMENTATION_TYPE " Apache Xerces-C DOM Parser" -#define XML_HEADER_DECLARATION #endif // __TIXML__ - #endif // DD4HEP_XML_CONFIG_H diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp index f41acade92fd6c464665b83e83d382d7bfd07f53..0740c9abb331eff5ccb4944135088e6edaea43db 100644 --- a/DDCore/src/GeoHandler.cpp +++ b/DDCore/src/GeoHandler.cpp @@ -82,7 +82,10 @@ GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) { //SensitiveDetector det = vol.sensitiveDetector(); // Note : assemblies and the world do not have a real volume nor a material - if ( v ) info.volumes.insert(v); + if ( v && info.volumeSet.find(v) == info.volumeSet.end() ) { + info.volumeSet.insert(v); + info.volumes.push_back(v); + } if ( m ) info.materials.insert(m); if ( dynamic_cast<Volume::Object*>(v) ) { if ( vis.isValid() ) info.vis.insert(vis.ptr()); diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index 26eb3c3b492a6bd2c82a4725a2bcb2d7b7a93a1c..24d48e7792a2889b80beb2dfd3bf94e5ec8b8b3a 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -137,34 +137,47 @@ namespace { GeoScan& operator()() { GeoHandler::Data& data = *m_data; string nam; + cout << "++ Patching names of anonymous shapes...." << endl; for(GeoHandler::Data::const_reverse_iterator i=data.rbegin(); i != data.rend(); ++i) { const GeoHandler::Data::mapped_type& v = (*i).second; for(GeoHandler::Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) { const TGeoNode* n = *j; - TGeoVolume* v = n->GetVolume(); - TGeoShape* s = v->GetShape(); - if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { + TGeoVolume* v = n->GetVolume(); + TGeoShape* s = v->GetShape(); + const char* sn = s->GetName(); + if ( 0 == sn || 0 == ::strlen(sn) ) { nam = v->GetName(); nam += "_shape"; s->SetName(nam.c_str()); } - else { - nam = s->GetName(); + else if ( 0 == ::strcmp(sn,s->IsA()->GetName()) ) { + nam = v->GetName(); + nam += "_shape"; + s->SetName(nam.c_str()); } - if ( s->IsA()->Class() == TGeoCompositeShape::Class() ) { + else { + nam = sn; + if ( nam.find("_shape") == string::npos ) nam += "_shape"; + s->SetName(nam.c_str()); + } + if ( s->IsA() == TGeoCompositeShape::Class() ) { TGeoCompositeShape* c = (TGeoCompositeShape*)s; const TGeoBoolNode* boolean = c->GetBoolNode(); - s = boolean->GetLeftShape(); - if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { - nam = v->GetName(); - nam += "_left"; - s->SetName(nam.c_str()); - } - s = boolean->GetRightShape(); - if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { - nam = v->GetName(); - nam += "_right"; - s->SetName(nam.c_str()); + s = boolean->GetLeftShape(); + sn = s->GetName(); + if ( 0 == sn || 0 == ::strlen(sn) ) { + s->SetName((nam+"_left").c_str()); + } + else if ( 0 == ::strcmp(sn,s->IsA()->GetName()) ) { + s->SetName((nam+"_left").c_str()); + } + s = boolean->GetRightShape(); + sn = s->GetName(); + if ( 0 == sn || 0 == ::strlen(sn) ) { + s->SetName((nam+"_right").c_str()); + } + else if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) { + s->SetName((nam+"_right").c_str()); } } } @@ -206,7 +219,8 @@ void LCDDImp::endDocument() { //gGeoManager->SetTopVolume(m_worldVol); mgr->CloseGeometry(); m_world.setPlacement(PlacedVolume(mgr->GetTopNode())); - ShapePatcher(m_world)(); + ShapePatcher patcher(m_world); + patcher(); } } diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp index 9a506f65bbc299278be2c3fa66584633e2a3e346..6aa2598bed561a2db552b2944e12f075a5458a2b 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -169,7 +169,7 @@ VisAttr::VisAttr(const string& name) { assign(obj, name, "vis"); obj->color = 2; setLineStyle(SOLID); - setDrawingStyle(WIREFRAME); + setDrawingStyle(SOLID); setShowDaughters(true); setAlpha(0.1f); } diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index caecf029c7aaf9b5f5f2d5d61894a59294327031..7545fbadf07eb148db189b162dd98d3c8894c797 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -186,17 +186,17 @@ ConeSegment& ConeSegment::setDimensions(double dz, double rmin1, double rmax1, d void Tube::make(const string& name, double rmin, double rmax, double z, double startPhi, double deltaPhi) { //_assign((TGeoTubeSeg*)new TGeoTube(rmin,rmax,z),name,"tube"); - //_assign(new TGeoTubeSeg(rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube"); - MyConeSeg* s = new MyConeSeg(); - _assign(s,name,"tube"); - setDimensions(rmin,rmax,z,startPhi,deltaPhi); + _assign(new TGeoTubeSeg(rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube"); + //MyConeSeg* s = new MyConeSeg(); + //_assign(s,name,"tube"); + //setDimensions(rmin,rmax,z,startPhi,deltaPhi); } /// Set the tube dimensions Tube& Tube::setDimensions(double rmin, double rmax, double z, double startPhi, double deltaPhi) { - //double params[] = {rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi}; - double params[] = {z,rmin,rmax,rmin,rmax,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi}; + double params[] = {rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi}; + //double params[] = {z,rmin,rmax,rmin,rmax,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi}; _setDimensions(params); return *this; } @@ -375,8 +375,9 @@ Trap& Trap::setDimensions(double z,double theta,double phi, return *this; } -/// Constructor to be used when creating a new object -PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen) +/// Helper function to create holy hedron +void PolyhedraRegular::_create(const string& name, int nsides, double rmin, double rmax, + double zpos, double zneg, double start, double delta) { if ( rmin<0e0 || rmin>rmax ) throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); @@ -384,71 +385,38 @@ PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); _assign(new TGeoPgon(),name,"polyhedra",false); double params[] = { - RAD_2_DEGREE * 2 * M_PI, + 0, RAD_2_DEGREE * 2 * M_PI, double(nsides), 2e0, - zlen/2e0,rmin,rmax, - -zlen/2e0,rmin,rmax + zpos,rmin,rmax, + zneg,rmin,rmax }; _setDimensions(¶ms[0]); } +/// Constructor to be used when creating a new object +PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen) +{ + _create(name,nsides,rmin,rmax,zlen/2,-zlen/2,0,2*M_PI); +} + /// Constructor to be used when creating a new object PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double zlen) { - if ( rmin<0e0 || rmin>rmax ) - throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); - else if ( rmax<0e0 ) - throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); - _assign(new TGeoPgon(),"polyhedra",false); - double params[] = { - RAD_2_DEGREE * 2 * M_PI, - RAD_2_DEGREE * 2 * M_PI, - double(nsides), - 2e0, - zlen/2e0,rmin,rmax, - -zlen/2e0,rmin,rmax - }; - _setDimensions(¶ms[0]); + _create("",nsides,rmin,rmax,zlen/2,-zlen/2,0,2*M_PI); } /// Constructor to be used when creating a new object PolyhedraRegular::PolyhedraRegular(int nsides, double phistart, double rmin, double rmax, double zlen) { - if ( rmin<0e0 || rmin>rmax ) - throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); - else if ( rmax<0e0 ) - throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); - _assign(new TGeoPgon(),"polyhedra",false); - double params[] = { - RAD_2_DEGREE * phistart, - RAD_2_DEGREE * 2 * M_PI, - double(nsides), - 2e0, - zlen/2e0,rmin,rmax, - -zlen/2e0,rmin,rmax - }; - _setDimensions(¶ms[0]); + _create("",nsides,rmin,rmax,zlen/2,-zlen/2,phistart,2*M_PI); } /// Constructor to be used when creating a new object PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double zplanes[2]) { - if ( rmin<0e0 || rmin>rmax ) - throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!"); - else if ( rmax<0e0 ) - throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!"); - _assign(new TGeoPgon(),"polyhedra",false); - double params[] = { - RAD_2_DEGREE * 2 * M_PI, - RAD_2_DEGREE * 2 * M_PI, - double(nsides), - 2e0, - zplanes[0],rmin,rmax, - zplanes[1],rmin,rmax - }; - _setDimensions(¶ms[0]); + _create("",nsides,rmin,rmax,zplanes[0],zplanes[1],0,2*M_PI); } /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation @@ -548,8 +516,8 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2) /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans) { TGeoHMatrix* tr = new TGeoHMatrix(); - Double_t* t = tr->GetTranslation(); - Double_t* r = tr->GetRotationMatrix(); + Double_t* t = tr->GetTranslation(); + Double_t* r = tr->GetRotationMatrix(); trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]); TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),tr); _assign(new TGeoCompositeShape("",inter),"intersection"); @@ -557,8 +525,8 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c /// Constructor to be used when creating a new object. Position is identity. IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos) { - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); - TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",inter),"intersection"); } @@ -566,9 +534,9 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot) { TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE); - TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); + TGeoCombiTrans* trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0); trans->SetRotation(rotation.Inverse()); - TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); + TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans); _assign(new TGeoCompositeShape("",inter),"intersection"); } diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index c113328ad3ce0582339d59a9b2d2a2118c355d05..03e0ef4ed20b9c3473d7d840762713894dc2d0d9 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -326,3 +326,16 @@ int DocumentHandler::output(Document doc, const std::string& fname) const { } #endif + +/// Create new XML document by parsing empty xml buffer +Document DocumentHandler::create(const char* tag, const char* comment) const { + string top(tag); + string empty = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; + empty += "<"+top+"/>\0\0"; + Document doc = parse(empty.c_str(),empty.length()+1); + if ( comment ) { + Element top_elt = doc.root(); + top_elt.addComment(comment); + } + return doc; +} diff --git a/DDCore/src/XML/XMLDetector.cpp b/DDCore/src/XML/XMLDetector.cpp index e865ede691c2f69342f0431adb4a3e1e71513682..d8a254dfa2c8bc3088ab88ab87506f2f0e3327ec 100644 --- a/DDCore/src/XML/XMLDetector.cpp +++ b/DDCore/src/XML/XMLDetector.cpp @@ -66,6 +66,10 @@ XML_ATTR_ACCESSOR(int,id) XML_ATTR_ACCESSOR(double,outer_z) XML_ATTR_ACCESSOR(double,inner_z) + XML_ATTR_ACCESSOR(double,b) + XML_ATTR_ACCESSOR(double,g) + XML_ATTR_ACCESSOR(double,B) + XML_ATTR_ACCESSOR(double,G) XML_ATTR_ACCESSOR(double,r) XML_ATTR_ACCESSOR_DOUBLE(r) XML_ATTR_ACCESSOR(double,R) @@ -79,6 +83,11 @@ XML_ATTR_ACCESSOR(int,id) XML_ATTR_ACCESSOR(double,inner_radius) XML_ATTR_ACCESSOR(double,angle) + XML_ATTR_ACCESSOR(double,alpha) + XML_ATTR_ACCESSOR(double,beta) + XML_ATTR_ACCESSOR(double,gamma) + XML_ATTR_ACCESSOR(double,delta) + XML_ATTR_ACCESSOR(double,epsilon) XML_ATTR_ACCESSOR(double,theta) XML_ATTR_ACCESSOR(int,thetaBins) XML_ATTR_ACCESSOR(double,psi) @@ -133,6 +142,9 @@ XML_ATTR_ACCESSOR(int,id) XML_ATTR_ACCESSOR(double,inner_field) XML_ATTR_ACCESSOR(double,outer_field) XML_ATTR_ACCESSOR(int,type) + + XML_ATTR_ACCESSOR(bool,visible) + XML_ATTR_ACCESSOR(bool,show_daughters) #if 0 XML_ATTR_ACCESSOR(double,) XML_ATTR_ACCESSOR(double,) @@ -157,6 +169,10 @@ string Dimension::nameStr() const { return m_element.attr<string>(_U(name)); } +string Dimension::refStr() const { + return m_element.attr<string>(_U(ref)); +} + string Dimension::typeStr() const { return m_element.attr<string>(_U(type)); } diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index b42272692c2b92dd7ce5d4e5d51e0e71776af993..217d8c9e776c531538a0494952bc02b7dddd565d 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -454,8 +454,8 @@ vector<Attribute> Handle_t::attributes() const { #else xercesc::DOMNamedNodeMap* l = _E(m_node)->getAttributes(); for(XmlSize_t i=0, n=l->getLength(); i<n; ++i) { - xercesc::DOMNode* node = l->item(i); - attrs.push_back(Attribute(node)); + xercesc::DOMNode* n = l->item(i); + attrs.push_back(Attribute(n)); } #endif } @@ -704,6 +704,11 @@ Handle_t Handle_t::setRef(const XmlChar* tag, const XmlChar* ref_name) { return ref; } +/// Add reference child as a new child node. The obj must have the "name" attribute! +Handle_t Handle_t::setRef(const XmlChar* tag, const string& ref_name) { + return setRef(tag,Strng_t(ref_name).ptr()); +} + /// Checksum (sub-)tree of a xml document/tree static unsigned int adler32(unsigned int adler,const char* buf,size_t len) { #define DO1(buf,i) {s1 +=(unsigned char)buf[i]; s2 += s1;} @@ -828,8 +833,13 @@ Attribute Element::getAttr(const XmlChar* name) const { } /// Set the reference attribute to the node (adds attribute ref="ref-name") -Attribute Element::setRef(const XmlChar* tag, const XmlChar* refname) const { - return setChild(tag).setAttr(Unicode_ref,refname); +Attribute Element::setRef(const XmlChar* tag, const XmlChar* ref_name) const { + return setChild(tag).setAttr(Unicode_ref,ref_name); +} + +/// Set the reference attribute to the node (adds attribute ref="ref-name") +Attribute Element::setRef(const XmlChar* tag, const string& ref_name) const { + return setRef(tag,Strng_t(ref_name).ptr()); } /// Access the value of the reference attribute of the node (attribute ref="ref-name") @@ -846,10 +856,19 @@ Handle_t Element::addChild(const XmlChar* tag) const { /// Check if a child with the required tag exists - if not create it and add it to the current node Handle_t Element::setChild(const XmlChar* t) const { - Elt_t e = m_element.child(t); + Elt_t e = m_element.child(t,false); return e ? Handle_t(e) : addChild(t); } +/// Add comment node to the element +void Element::addComment(const char* text) const { +#ifdef DD4HEP_USE_TINYXML + _N(m_element)->appendChild(new TiXmlComment(text)); +#else + _N(m_element)->appendChild(_D(document().m_doc)->createComment(Strng_t(text))); +#endif +} + RefElement::RefElement(const Document& document, const XmlChar* type, const XmlChar* name) : Element(document, type) { diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 9d9681c776b95f209111054b00971e365df1c8fa..763ea5f37380666b0bb634bc7c6a6bc2b69e63a1 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -148,7 +148,7 @@ static Ref_t create_SolenoidField(lcdd_t& lcdd, xml_h e) { obj.assign(ptr,c.nameStr(),c.typeStr()); return obj; } -DECLARE_XMLELEMENT(SolenoidMagnet,create_SolenoidField); +DECLARE_XMLELEMENT(solenoid,create_SolenoidField); static Ref_t create_DipoleField(lcdd_t& /* lcdd */, xml_h e) { xml_comp_t c(e); @@ -374,24 +374,28 @@ template <> void Converter<VisAttr>::operator()(xml_h e) const { 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; attr.setColor(r,g,b); - if ( e.hasAttr(_U(alpha)) ) attr.setAlpha(e.attr<float>(_U(alpha))); - if ( e.hasAttr(_U(visible)) ) attr.setVisible(e.attr<bool>(_U(visible))); - if ( e.hasAttr(_U(lineStyle)) ) { + if ( e.hasAttr(_U(alpha)) ) attr.setAlpha(e.attr<float>(_U(alpha))); + if ( e.hasAttr(_U(visible)) ) attr.setVisible(e.attr<bool>(_U(visible))); + if ( e.hasAttr(_U(lineStyle)) ) { string ls = e.attr<string>(_U(lineStyle)); - if ( ls == "unbroken" ) attr.setLineStyle(VisAttr::SOLID); - if ( ls == "broken" ) attr.setLineStyle(VisAttr::DASHED); + if ( ls == "unbroken" ) attr.setLineStyle(VisAttr::SOLID); + else if ( ls == "broken" ) attr.setLineStyle(VisAttr::DASHED); } else { attr.setLineStyle(VisAttr::SOLID); } - if ( e.hasAttr(_U(drawingStyle)) ) { + if ( e.hasAttr(_U(drawingStyle)) ) { string ds = e.attr<string>(_U(drawingStyle)); - if ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME); + if ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME); + else if ( ds == "solid" ) attr.setDrawingStyle(VisAttr::SOLID); } else { - attr.setDrawingStyle(VisAttr::WIREFRAME); + attr.setDrawingStyle(VisAttr::SOLID); } - if ( e.hasAttr(_U(showDaughters)) ) attr.setShowDaughters(e.attr<bool>(_U(showDaughters))); + if ( e.hasAttr(_U(showDaughters)) ) + attr.setShowDaughters(e.attr<bool>(_U(showDaughters))); + else + attr.setShowDaughters(true); lcdd.addVisAttribute(attr); } diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp index a4f7a877bb15cb4607b54b764797f1727cb8d0c7..df4186f2bf93bb27e3308073974a110122a38a97 100644 --- a/DDCore/src/plugins/LCDDConverter.cpp +++ b/DDCore/src/plugins/LCDDConverter.cpp @@ -17,26 +17,30 @@ #include "TROOT.h" #include "TColor.h" #include "TGeoShape.h" -#include "TGeoEltu.h" + +#include "TGeoArb8.h" +#include "TGeoBoolNode.h" +#include "TGeoCompositeShape.h" #include "TGeoCone.h" +#include "TGeoEltu.h" +#include "TGeoHype.h" +#include "TGeoMatrix.h" #include "TGeoParaboloid.h" #include "TGeoPara.h" #include "TGeoPcon.h" #include "TGeoPgon.h" +#include "TGeoShapeAssembly.h" #include "TGeoSphere.h" #include "TGeoTorus.h" -#include "TGeoTube.h" #include "TGeoTrd1.h" #include "TGeoTrd2.h" -#include "TGeoArb8.h" -#include "TGeoMatrix.h" -#include "TGeoBoolNode.h" -#include "TGeoCompositeShape.h" -#include "TGeoShapeAssembly.h" +#include "TGeoTube.h" + #include "TGeoNode.h" #include "TClass.h" #include "TMath.h" #include "Reflex/PluginService.h" +#include <fstream> #include <iostream> #include <iomanip> @@ -47,16 +51,14 @@ using namespace std; namespace { typedef Position XYZRotation; XYZRotation getXYZangles(const Double_t* r) { - static Double_t rad = DEGREE_2_RAD; Double_t cosb = sqrt(r[0]*r[0] + r[1]*r[1]); if (cosb > 0.00001) { - return XYZRotation(atan2(r[5], r[8])*rad, atan2(-r[2], cosb)*rad, atan2(r[1], r[0])*rad); + return XYZRotation(atan2(r[5], r[8]), atan2(-r[2], cosb), atan2(r[1], r[0])); } - return XYZRotation(atan2(-r[7], r[4])*rad,atan2(-r[2], cosb)*rad,0); + return XYZRotation(atan2(-r[7], r[4]),atan2(-r[2], cosb),0); } } - void LCDDConverter::GeometryInfo::check(const string& name, const TNamed* n,map<string,const TNamed*>& m) const { map<string,const TNamed*>::const_iterator i=m.find(name); if ( i != m.end() ) { @@ -112,7 +114,9 @@ xml_h LCDDConverter::handleMaterial(const string& name, const TGeoMedium* medium obj.setAttr(_U(type),"density"); geo.checkMaterial(name,medium); - + if ( name == "B" ) { + cout << "Converting material:" << name << endl; + } if ( m->IsMixture() ) { TGeoMixture* mix=(TGeoMixture*)m; const double *wmix = mix->GetWmixt(); @@ -132,6 +136,7 @@ xml_h LCDDConverter::handleMaterial(const string& name, const TGeoMedium* medium } else { TGeoElement *elt = m->GetElement(0); + cout << "Converting non mixing material:" << name << endl; xml_elt_t atom(geo.doc,_U(atom)); handleElement(elt->GetName(),elt); mat.append(atom); @@ -157,81 +162,93 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c const TGeoBBox* s = (const TGeoBBox*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(box))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(x),s->GetDX()*CM_2_MM); - solid.setAttr(_U(y),s->GetDY()*CM_2_MM); - solid.setAttr(_U(z),s->GetDZ()*CM_2_MM); + solid.setAttr(_U(x), 2*s->GetDX()*CM_2_MM); + solid.setAttr(_U(y), 2*s->GetDY()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDZ()*CM_2_MM); solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoTube::Class() ) { const TGeoTube* s = (const TGeoTube*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM); - solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM); - solid.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.setAttr(_U(startphi),0e0); - solid.setAttr(_U(deltaphi),2*M_PI); + solid.setAttr(_U(rmin), s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), s->GetRmax()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); + solid.setAttr(_U(startphi), 0e0); + solid.setAttr(_U(deltaphi), 2*M_PI); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoEltu::Class() ) { const TGeoEltu* s = (const TGeoEltu*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(eltube))); + solid.setAttr(_U(name), Unicode(name)); + solid.setAttr(_U(dx), s->GetA() *CM_2_MM); + solid.setAttr(_U(dy), s->GetB() *CM_2_MM); + solid.setAttr(_U(dz), s->GetDz()*CM_2_MM); + solid.setAttr(_U(lunit),"mm"); + } + else if ( shape->IsA() == TGeoTubeSeg::Class() ) { + const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape; + geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(dx),s->GetA()*CM_2_MM); - solid.setAttr(_U(dy),s->GetB()*CM_2_MM); - solid.setAttr(_U(dz),s->GetDz()*CM_2_MM); + solid.setAttr(_U(rmin), s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), s->GetRmax()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo + solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD); + solid.setAttr(_U(deltaphi), s->GetPhi2()*DEGREE_2_RAD); + solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoTubeSeg::Class() ) { const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM); - solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM); - solid.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD); - solid.setAttr(_U(deltaphi),s->GetPhi2()*DEGREE_2_RAD); + solid.setAttr(_U(rmin), s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), s->GetRmax()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo + solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD); + solid.setAttr(_U(deltaphi), s->GetPhi2()*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } - else if ( shape->IsA() == TGeoTrd1::Class() ) { - const TGeoTrd1* s = (const TGeoTrd1*)shape; - geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trd))); + else if ( shape->IsA() == TGeoHype::Class() ) { + const TGeoHype* s = (const TGeoHype*)shape; + geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(hype))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(x1),s->GetDx1()*CM_2_MM); - solid.setAttr(_U(x2),s->GetDx2()*CM_2_MM); - solid.setAttr(_U(y1),s->GetDy()*CM_2_MM); - solid.setAttr(_U(y2),s->GetDy()*CM_2_MM); - solid.setAttr(_U(z), s->GetDz()*CM_2_MM); + solid.setAttr(_U(rmin), 2*s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), 2*s->GetRmax()*CM_2_MM); + solid.setAttr(_U(outst), 2*s->GetStOut()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo + solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoTrd2::Class() ) { const TGeoTrd2* s = (const TGeoTrd2*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trd))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(x1),s->GetDx1()*CM_2_MM); - solid.setAttr(_U(x2),s->GetDx2()*CM_2_MM); - solid.setAttr(_U(y1),s->GetDy1()*CM_2_MM); - solid.setAttr(_U(y2),s->GetDy2()*CM_2_MM); - solid.setAttr(_U(z), s->GetDz()*CM_2_MM); + solid.setAttr(_U(x1), 2*s->GetDx1()*CM_2_MM); + solid.setAttr(_U(x2), 2*s->GetDx2()*CM_2_MM); + solid.setAttr(_U(y1), 2*s->GetDy1()*CM_2_MM); + solid.setAttr(_U(y2), 2*s->GetDy2()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz() *CM_2_MM); // Full zlen in GDML, half zlen in TGeo solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoTrap::Class() ) { const TGeoTrap* s = (const TGeoTrap*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trap))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(x1),s->GetBl1()*CM_2_MM); - solid.setAttr(_U(x2),s->GetTl1()*CM_2_MM); - solid.setAttr(_U(x3),s->GetBl2()*CM_2_MM); - solid.setAttr(_U(x4),s->GetTl2()*CM_2_MM); - solid.setAttr(_U(y1),s->GetH1()*CM_2_MM); - solid.setAttr(_U(y2),s->GetH2()*CM_2_MM); - solid.setAttr(_U(z),s->GetDz()*CM_2_MM); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo + solid.setAttr(_U(x1), 2*s->GetBl1()*CM_2_MM); + solid.setAttr(_U(x2), 2*s->GetTl1()*CM_2_MM); + solid.setAttr(_U(x3), 2*s->GetBl2()*CM_2_MM); + solid.setAttr(_U(x4), 2*s->GetTl2()*CM_2_MM); + solid.setAttr(_U(y1), 2*s->GetH1()*CM_2_MM); + solid.setAttr(_U(y2), 2*s->GetH2()*CM_2_MM); solid.setAttr(_U(alpha1),s->GetAlpha1()*DEGREE_2_RAD); solid.setAttr(_U(alpha2),s->GetAlpha2()*DEGREE_2_RAD); - solid.setAttr(_U(theta),s->GetTheta()*DEGREE_2_RAD); - solid.setAttr(_U(phi),s->GetPhi()*DEGREE_2_RAD); + solid.setAttr(_U(theta), s->GetTheta()*DEGREE_2_RAD); + solid.setAttr(_U(phi), s->GetPhi()*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } @@ -239,23 +256,24 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c const TGeoPara* s = (const TGeoPara*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(para))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(x),s->GetX()*CM_2_MM); - solid.setAttr(_U(y),s->GetY()*CM_2_MM); - solid.setAttr(_U(z),s->GetZ()*CM_2_MM); + solid.setAttr(_U(x), s->GetX()*CM_2_MM); + solid.setAttr(_U(y), s->GetY()*CM_2_MM); + solid.setAttr(_U(z), s->GetZ()*CM_2_MM); solid.setAttr(_U(alpha),s->GetAlpha()*DEGREE_2_RAD); solid.setAttr(_U(theta),s->GetTheta()*DEGREE_2_RAD); - solid.setAttr(_U(phi),s->GetPhi()*DEGREE_2_RAD); + solid.setAttr(_U(phi), s->GetPhi()*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } else if ( shape->IsA() == TGeoPgon::Class() ) { const TGeoPgon* s = (const TGeoPgon*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(polyhedra))); - solid.setAttr(_U(name),Unicode(name)); + solid.setAttr(_U(name), Unicode(name)); solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD); solid.setAttr(_U(deltaphi),s->GetDphi()*DEGREE_2_RAD); - solid.setAttr(_U(aunit),"rad"); - solid.setAttr(_U(lunit),"mm"); + solid.setAttr(_U(numsides),s->GetNedges()); + solid.setAttr(_U(aunit), "rad"); + solid.setAttr(_U(lunit), "mm"); for( size_t i=0; i<s->GetNz(); ++i ) { zplane = xml_elt_t(geo.doc,_U(zplane)); zplane.setAttr(_U(rmin),s->GetRmin(i)*CM_2_MM); @@ -280,39 +298,33 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c solid.append(zplane); } } - else if ( shape->IsA() == TGeoCone::Class() ) { - const TGeoCone* s = (const TGeoCone*)shape; - geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(cone))); + else if ( shape->IsA() == TGeoConeSeg::Class() ) { + const TGeoConeSeg* s = (const TGeoConeSeg*)shape; + geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(polycone))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.setAttr(_U(rmin1),s->GetRmin1()*CM_2_MM); - solid.setAttr(_U(rmax1),s->GetRmax1()*CM_2_MM); - solid.setAttr(_U(rmin2),s->GetRmin2()*CM_2_MM); - solid.setAttr(_U(rmax2),s->GetRmax2()*CM_2_MM); - solid.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.setAttr(_U(startphi),0e0); - solid.setAttr(_U(deltaphi),2*M_PI); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); + solid.setAttr(_U(rmin1), s->GetRmin1()*CM_2_MM); + solid.setAttr(_U(rmin2), s->GetRmin2()*CM_2_MM); + solid.setAttr(_U(rmax1), s->GetRmax1()*CM_2_MM); + solid.setAttr(_U(rmax2), s->GetRmax2()*CM_2_MM); + solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD); + solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } - else if ( shape->IsA() == TGeoConeSeg::Class() ) { - const TGeoConeSeg* s = (const TGeoConeSeg*)shape; + else if ( shape->IsA() == TGeoCone::Class() ) { + const TGeoCone* s = (const TGeoCone*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(cone))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD); - solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD); + solid.setAttr(_U(z), 2*s->GetDz()*CM_2_MM); + solid.setAttr(_U(rmin1), s->GetRmin1()*CM_2_MM); + solid.setAttr(_U(rmax1), s->GetRmax1()*CM_2_MM); + solid.setAttr(_U(rmin2), s->GetRmin2()*CM_2_MM); + solid.setAttr(_U(rmax2), s->GetRmax2()*CM_2_MM); + solid.setAttr(_U(startphi),0e0); + solid.setAttr(_U(deltaphi),2*M_PI); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); - zplane = xml_elt_t(geo.doc,_U(zplane)); - zplane.setAttr(_U(rmin),s->GetRmin1()*CM_2_MM); - zplane.setAttr(_U(rmax),s->GetRmax1()*CM_2_MM); - zplane.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.append(zplane); - zplane = xml_elt_t(geo.doc,_U(zplane)); - zplane.setAttr(_U(rmin),s->GetRmin2()*CM_2_MM); - zplane.setAttr(_U(rmax),s->GetRmax2()*CM_2_MM); - zplane.setAttr(_U(z),s->GetDz()*CM_2_MM); - solid.append(zplane); } else if ( shape->IsA() == TGeoParaboloid::Class() ) { const TGeoParaboloid* s = (const TGeoParaboloid*)shape; @@ -326,13 +338,13 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c else if ( shape->IsA() == TGeoSphere::Class() ) { const TGeoSphere* s = (const TGeoSphere*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(sphere))); - solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM); - solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM); - solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD); - solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD); - solid.setAttr(_U(starttheta),s->GetTheta1()*DEGREE_2_RAD); - solid.setAttr(_U(deltatheta),(s->GetTheta2()-s->GetTheta1())*DEGREE_2_RAD); + solid.setAttr(_U(name), Unicode(name)); + solid.setAttr(_U(rmin), s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), s->GetRmax()*CM_2_MM); + solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD); + solid.setAttr(_U(deltaphi), (s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD); + solid.setAttr(_U(starttheta), s->GetTheta1()*DEGREE_2_RAD); + solid.setAttr(_U(deltatheta), (s->GetTheta2()-s->GetTheta1())*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } @@ -340,26 +352,54 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c const TGeoTorus* s = (const TGeoTorus*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(torus))); solid.setAttr(_U(name),Unicode(name)); - solid.setAttr(_U(rtor),s->GetR()); - solid.setAttr(_U(rmin),s->GetRmin()); - solid.setAttr(_U(rmax),s->GetRmax()); - solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD); - solid.setAttr(_U(deltaphi),s->GetDphi()*DEGREE_2_RAD); + solid.setAttr(_U(rtor), s->GetR()*CM_2_MM); + solid.setAttr(_U(rmin), s->GetRmin()*CM_2_MM); + solid.setAttr(_U(rmax), s->GetRmax()*CM_2_MM); + solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD); + solid.setAttr(_U(deltaphi), s->GetDphi()*DEGREE_2_RAD); solid.setAttr(_U(aunit),"rad"); solid.setAttr(_U(lunit),"mm"); } + else if ( shape->IsA() == TGeoArb8::Class() ) { + TGeoArb8* s = (TGeoArb8*)shape; + const double* vtx = s->GetVertices(); + geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(arb8))); + solid.setAttr(_U(name),Unicode(name)); + solid.setAttr(_U(v1x),vtx[0]*CM_2_MM); + solid.setAttr(_U(v1y),vtx[1]*CM_2_MM); + solid.setAttr(_U(v2x),vtx[2]*CM_2_MM); + solid.setAttr(_U(v2y),vtx[3]*CM_2_MM); + solid.setAttr(_U(v3x),vtx[4]*CM_2_MM); + solid.setAttr(_U(v3y),vtx[5]*CM_2_MM); + solid.setAttr(_U(v4x),vtx[6]*CM_2_MM); + solid.setAttr(_U(v4y),vtx[7]*CM_2_MM); + solid.setAttr(_U(v5x),vtx[8]*CM_2_MM); + solid.setAttr(_U(v5y),vtx[9]*CM_2_MM); + solid.setAttr(_U(v6x),vtx[10]*CM_2_MM); + solid.setAttr(_U(v6y),vtx[11]*CM_2_MM); + solid.setAttr(_U(v7x),vtx[12]*CM_2_MM); + solid.setAttr(_U(v7y),vtx[13]*CM_2_MM); + solid.setAttr(_U(v8x),vtx[14]*CM_2_MM); + solid.setAttr(_U(v8y),vtx[15]*CM_2_MM); + solid.setAttr(_U(dz), s->GetDz()*CM_2_MM); + solid.setAttr(_U(lunit),"mm"); + } else if ( shape->IsA() == TGeoShapeAssembly::Class() ) { TGeoShapeAssembly* s = (TGeoShapeAssembly*)shape; geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(assembly))); solid.setAttr(_U(name),Unicode(name)); } else if ( shape->IsA() == TGeoCompositeShape::Class() ) { + char text[32]; const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape; const TGeoBoolNode* boolean = s->GetBoolNode(); TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); - TGeoMatrix* m = boolean->GetRightMatrix(); - xml_h left = handleSolid(name+"_left", boolean->GetLeftShape()); - xml_h right = handleSolid(name+"_right",boolean->GetRightShape()); + TGeoMatrix* rm = boolean->GetRightMatrix(); + TGeoMatrix* lm = boolean->GetLeftMatrix(); + TGeoShape* ls = boolean->GetLeftShape(); + TGeoShape* rs = boolean->GetRightShape(); + xml_h left = handleSolid(ls->GetName(),ls); + xml_h right = handleSolid(rs->GetName(),rs); xml_h first(0), second(0); if ( !left ) { throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:"+name); @@ -376,11 +416,12 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c solid = xml_elt_t(geo.doc,_U(intersection)); xml_h obj; + geo.doc_solids.append(solid); solid.append(first=xml_elt_t(geo.doc,_U(first))); solid.setAttr(_U(name),Unicode(name)); - first.setAttr(_U(ref),name+"_left"); - XYZRotation rot = getXYZangles(boolean->GetLeftMatrix()->Inverse().GetRotationMatrix()); - const double *tr = boolean->GetLeftMatrix()->GetTranslation(); + first.setAttr(_U(ref),ls->GetName()); + XYZRotation rot = getXYZangles(lm->Inverse().GetRotationMatrix()); + const double *tr = lm->GetTranslation(); if ((tr[0] != 0.0) || (tr[1] != 0.0) || (tr[2] != 0.0)) { first.append(obj=xml_elt_t(geo.doc,_U(firstposition))); @@ -390,26 +431,25 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape) c } if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) { first.append(obj=xml_elt_t(geo.doc,_U(firstrotation))); - obj.setAttr(_U(x),rot.X()); - obj.setAttr(_U(y),rot.Y()); - obj.setAttr(_U(z),rot.Z()); + obj.setAttr(_U(x),rot.X()*DEGREE_2_RAD); + obj.setAttr(_U(y),rot.Y()*DEGREE_2_RAD); + obj.setAttr(_U(z),rot.Z()*DEGREE_2_RAD); } - - rot = getXYZangles(boolean->GetRightMatrix()->Inverse().GetRotationMatrix()); - tr = boolean->GetRightMatrix()->GetTranslation(); + TGeoMatrix& rinv = rm->Inverse(); + rot = getXYZangles(rinv.GetRotationMatrix()); + tr = rm->GetTranslation(); solid.append(second=xml_elt_t(geo.doc,_U(second))); - second.setAttr(_U(ref),name+"_right"); + second.setAttr(_U(ref),rs->GetName()); + ::sprintf(text,"_%p_",rm); + string rnam = rs->GetName(); + rnam += text; if ((tr[0] != 0.0) || (tr[1] != 0.0) || (tr[2] != 0.0)) { - first.append(obj=xml_elt_t(geo.doc,_U(position))); - obj.setAttr(_U(x),tr[0]*CM_2_MM); - obj.setAttr(_U(y),tr[1]*CM_2_MM); - obj.setAttr(_U(z),tr[2]*CM_2_MM); + xml_ref_t pos = handlePosition(rnam+"pos",rm); + solid.setRef(_U(positionref),pos.name()); } if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) { - first.append(obj=xml_elt_t(geo.doc,_U(rotation))); - obj.setAttr(_U(x),rot.X()); - obj.setAttr(_U(y),rot.Y()); - obj.setAttr(_U(z),rot.Z()); + xml_ref_t rot = handleRotation(rnam+"rot",&rinv); + solid.setRef(_U(rotationref),rot.name()); } } if ( !solid ) { @@ -427,26 +467,25 @@ xml_h LCDDConverter::handlePosition(const std::string& name, const TGeoMatrix* t GeometryInfo& geo = data(); xml_h pos = geo.xmlPositions[trafo]; if ( !pos ) { - static xml_h identity; const double* tr = trafo->GetTranslation(); - if ( tr[0] != 0 || tr[1] != 0 || tr[2] != 0 ) { + if ( tr[0] != 0.0 || tr[1] != 0.0 || tr[2] != 0.0 ) { geo.checkPosition(name,trafo); geo.doc_define.append(pos=xml_elt_t(geo.doc,_U(position))); pos.setAttr(_U(name),name); - pos.setAttr(_U(x),tr[0]); - pos.setAttr(_U(y),tr[1]); - pos.setAttr(_U(z),tr[2]); + pos.setAttr(_U(x),tr[0]*CM_2_MM); + pos.setAttr(_U(y),tr[1]*CM_2_MM); + pos.setAttr(_U(z),tr[2]*CM_2_MM); } - else if ( identity ) { - pos = identity; + else if ( geo.identity_pos ) { + pos = geo.identity_pos; } else { - geo.doc_define.append(identity=xml_elt_t(geo.doc,_U(position))); - identity.setAttr(_U(name),"identity_pos"); - identity.setAttr(_U(x),0); - identity.setAttr(_U(y),0); - identity.setAttr(_U(z),0); - pos = identity; + geo.doc_define.append(geo.identity_pos=xml_elt_t(geo.doc,_U(position))); + geo.identity_pos.setAttr(_U(name),"identity_pos"); + geo.identity_pos.setAttr(_U(x),0); + geo.identity_pos.setAttr(_U(y),0); + geo.identity_pos.setAttr(_U(z),0); + pos = geo.identity_pos; geo.checkPosition("identity_pos",0); } geo.xmlPositions[trafo] = pos; @@ -459,26 +498,27 @@ xml_h LCDDConverter::handleRotation(const std::string& name, const TGeoMatrix* t GeometryInfo& geo = data(); xml_h rot = geo.xmlRotations[trafo]; if ( !rot ) { - static xml_h identity; - XYZRotation r = getXYZangles(trafo->Inverse().GetRotationMatrix()); - if ( r.X() != 0 || r.Y() != 0 || r.Z() != 0 ) { + XYZRotation r = getXYZangles(trafo->GetRotationMatrix()); + if ( r.X() != 0.0 || r.Y() != 0.0 || r.Z() != 0.0 ) { geo.checkRotation(name,trafo); geo.doc_define.append(rot=xml_elt_t(geo.doc,_U(rotation))); rot.setAttr(_U(name),name); rot.setAttr(_U(x),r.X()); rot.setAttr(_U(y),r.Y()); rot.setAttr(_U(z),r.Z()); + rot.setAttr(_U(unit),"rad"); } - else if ( identity ) { - rot = identity; + else if ( geo.identity_rot ) { + rot = geo.identity_rot; } else { - geo.doc_define.append(identity=xml_elt_t(geo.doc,_U(rotation))); - identity.setAttr(_U(name),"identity_rot"); - identity.setAttr(_U(x),0); - identity.setAttr(_U(y),0); - identity.setAttr(_U(z),0); - rot = identity; + geo.doc_define.append(geo.identity_rot=xml_elt_t(geo.doc,_U(rotation))); + geo.identity_rot.setAttr(_U(name),"identity_rot"); + geo.identity_rot.setAttr(_U(x),0); + geo.identity_rot.setAttr(_U(y),0); + geo.identity_rot.setAttr(_U(z),0); + geo.identity_rot.setAttr(_U(unit),"rad"); + rot = geo.identity_rot; geo.checkRotation("identity_rot",0); } geo.xmlRotations[trafo] = rot; @@ -506,34 +546,63 @@ xml_h LCDDConverter::handleVolume(const string& name, const TGeoVolume* volume) geo.checkVolume(name,volume); geo.doc_structure.append(vol=xml_elt_t(geo.doc,_U(volume))); vol.setAttr(_U(name),n); - vol.setRef(_U(solidref),sol.name()); if ( m ) { - xml_ref_t med = handleMaterial(m->GetName(),m); + string mat_name = m->GetName(); + xml_ref_t med = handleMaterial(mat_name,m); vol.setRef(_U(materialref),med.name()); } + vol.setRef(_U(solidref),sol.name()); + geo.xmlVolumes[v] = vol; + const TObjArray* dau = ((TGeoVolume*)v)->GetNodes(); + if ( dau && dau->GetEntries() > 0 ) { + for(Int_t i=0, n=dau->GetEntries(); i<n; ++i) { + TGeoNode* node = (TGeoNode*)dau->At(i); + handlePlacement(node->GetName(),node); + } + } if ( geo.doc_header && dynamic_cast<const Volume::Object*>(volume) ) { Region reg = _v.region(); LimitSet lim = _v.limitSet(); VisAttr vis = _v.visAttributes(); SensitiveDetector det = _v.sensitiveDetector(); - if ( vis.isValid() ) { - xml_ref_t data = handleVis(vis.name(),vis.ptr()); - vol.setRef(_U(visref),data.name()); + if ( det.isValid() ) { + xml_ref_t data = handleSensitive(det.name(),det.ptr()); + vol.setRef(_U(sdref),data.name()); + } + if ( reg.isValid() ) { + xml_ref_t data = handleRegion(reg.name(),reg.ptr()); + vol.setRef(_U(regionref),data.name()); } if ( lim.isValid() ) { xml_ref_t data = handleLimitSet(lim.name(),lim.ptr()); vol.setRef(_U(limitsetref),data.name()); } - if ( reg.isValid() ) { - xml_ref_t data = handleRegion(reg.name(),reg.ptr()); - vol.setRef(_U(regionref),data.name()); + if ( vis.isValid() ) { + xml_ref_t data = handleVis(vis.name(),vis.ptr()); + vol.setRef(_U(visref),data.name()); } - if ( det.isValid() ) { - xml_ref_t data = handleSensitive(det.name(),det.ptr()); - vol.setRef(_U(sdref),data.name()); + } + } + return vol; +} + +/// Dump logical volume in GDML format to output stream +xml_h LCDDConverter::handleVolumeVis(const string& name, const TGeoVolume* volume) const { + GeometryInfo& geo = data(); + xml_h vol = geo.xmlVolumes[volume]; + if ( !vol ) { + const TGeoVolume* v = volume; + Volume _v = Ref_t(v); + if ( dynamic_cast<const Volume::Object*>(volume) ) { + VisAttr vis = _v.visAttributes(); + if ( vis.isValid() ) { + geo.doc_structure.append(vol=xml_elt_t(geo.doc,_U(volume))); + vol.setAttr(_U(name),v->GetName()); + xml_ref_t data = handleVis(vis.name(),vis.ptr()); + vol.setRef(_U(visref),data.name()); + geo.xmlVolumes[v] = vol; } } - geo.xmlVolumes[v] = vol; } return vol; } @@ -581,22 +650,22 @@ xml_h LCDDConverter::handlePlacement(const string& name, const TGeoNode* node) c GeometryInfo& geo = data(); xml_h place = geo.xmlPlacements[node]; if ( !place ) { - TGeoMatrix* t = node->GetMatrix(); + TGeoMatrix* m = node->GetMatrix(); TGeoVolume* v = node->GetVolume(); - xml_ref_t vol = xml_h(geo.xmlVolumes[v]); - xml_h mot = geo.xmlVolumes[node->GetMotherVolume()]; + xml_ref_t vol = xml_h(geo.xmlVolumes[v]); + xml_h mot = geo.xmlVolumes[node->GetMotherVolume()]; place = xml_elt_t(geo.doc,_U(physvol)); if ( mot ) { // Beware of top level volume! mot.append(place); } place.setRef(_U(volumeref),vol.name()); - if ( t ) { + if ( m ) { char text[32]; ::sprintf(text,"_%p_pos",node); - xml_ref_t pos = handlePosition(name+text,t); + xml_ref_t pos = handlePosition(name+text,m); ::sprintf(text,"_%p_rot",node); - xml_ref_t rot = handleRotation(name+text,t); + xml_ref_t rot = handleRotation(name+text,m); place.setRef(_U(positionref),pos.name()); place.setRef(_U(rotationref),rot.name()); } @@ -669,7 +738,7 @@ xml_h LCDDConverter::handleSensitive(const string& name, const TNamed* sens_det) sensdet.setAttr(_U(name),sd.name()); sensdet.setAttr(_U(ecut),sd.energyCutoff()); sensdet.setAttr(_U(eunit),"MeV"); - sensdet.setAttr(_U(verbose),sd.verbose()); + sensdet.setAttr(_U(verbose),int(sd.verbose() ? 1 : 0)); sensdet.setAttr(_U(hits_collection),sd.hitsCollection()); if ( sd.combineHits() ) sensdet.setAttr(_U(combine_hits),sd.combineHits()); Readout ro = sd.readout(); @@ -687,6 +756,7 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec GeometryInfo& geo = data(); xml_h id = geo.xmlIdSpecs[id_spec]; if ( !id ) { + int length=0, start=0; IDDescriptor desc = Ref_t(id_spec); geo.doc_idDict.append(id=xml_elt_t(geo.doc,_U(idspec))); id.setAttr(_U(name),name); @@ -694,12 +764,15 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec for(IDDescriptor::FieldMap::const_iterator i=m.begin(); i!=m.end(); ++i) { xml_h idfield = xml_elt_t(geo.doc,_U(idfield)); const IDDescriptor::Field& f = (*i).second; + start = f.first; + length = f.second<0 ? -f.second : f.second; idfield.setAttr(_U(signed),f.second<0 ? true : false); idfield.setAttr(_U(label),(*i).first); - idfield.setAttr(_U(length),f.second<0 ? -f.second : f.second); - idfield.setAttr(_U(start),f.first); + idfield.setAttr(_U(length),length); + idfield.setAttr(_U(start),start); id.append(idfield); } + id.setAttr(_U(length),length+start); geo.xmlIdSpecs[id_spec] = id; } return id; @@ -724,11 +797,12 @@ xml_h LCDDConverter::handleVis(const string& name, const TNamed* v) const { else if ( style == VisAttr::DASHED ) vis.setAttr(_U(line_style),"broken"); if ( draw == VisAttr::SOLID ) - vis.setAttr(_U(line_style),"solid"); + vis.setAttr(_U(drawing_style),"solid"); else if ( draw == VisAttr::WIREFRAME ) - vis.setAttr(_U(line_style),"wireframe"); + vis.setAttr(_U(drawing_style),"wireframe"); xml_h col = xml_elt_t(geo.doc,_U(color)); + attr.rgb(r,g,b); col.setAttr(_U(alpha),attr.alpha()); col.setAttr(_U(R),r); col.setAttr(_U(G),g); @@ -746,15 +820,14 @@ xml_h LCDDConverter::handleField(const std::string& name, const TNamed* f) con if ( !field ) { Ref_t fld(f); string type = f->GetTitle(); - field=xml_elt_t(geo.doc,_U(field)); + field=xml_elt_t(geo.doc,Unicode(type)); field.setAttr(_U(name),f->GetName()); - field.setAttr(_U(type),type); fld = ROOT::Reflex::PluginService::Create<TNamed*>(type+"_Convert2LCDD",&m_lcdd,&field,&fld); - cout << (fld.isValid() ? "Converted" : "FAILED to convert ") - << " electromagnetic field:" << f->GetName() << " of type " << f->GetTitle() << endl; + cout << "++ " << (fld.isValid() ? "Converted" : "FAILED to convert ") + << " electromagnetic field:" << f->GetName() << " of type " << type << endl; if ( !fld.isValid() ) { throw runtime_error("Failed to locate plugin to convert electromagnetic field:"+ - string(f->GetName())+" of type "+string(f->GetTitle())); + string(f->GetName())+" of type "+type); } geo.doc_fields.append(field); } @@ -848,8 +921,7 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { collect(top,geo); m_checkOverlaps = false; - const char empty_gdml[] = XML_HEADER_DECLARATION - "<!-- \n" + const char* comment = "\n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" " ++++ Linear collider detector description GDML in C++ ++++\n" " ++++ DD4hep Detector description generator. ++++\n" @@ -857,31 +929,32 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { " ++++ Parser:" XML_IMPLEMENTATION_TYPE " ++++\n" " ++++ ++++\n" " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - "-->\n" - "<gdml " - "xmlns:xs=\"http://www/w3.org/2001/XMLSchema-instance\"\n" - "xsi:noNamespaceSchemaLocation=\"http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd\">\n" - "</gdml>\0\0"; - + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; - xml_elt_t elt(0); - geo.doc = docH.parse(empty_gdml,sizeof(empty_gdml)); + geo.doc = docH.create("gdml",comment); geo.doc_root = geo.doc.root(); + geo.doc_root.setAttr(Unicode("xmlns:xs"),"http://www.w3.org/2001/XMLSchema-instance"); + geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"), + "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd"); + // geo.doc = docH.create("gdml_simple_extension",comment); + // geo.doc_root.setAttr(Unicode("xmlns:gdml_simple_extension"),"http://www.example.org"); + // geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"), + // "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd"); geo.doc_root.append(geo.doc_define = xml_elt_t(geo.doc,_U(define))); geo.doc_root.append(geo.doc_materials = xml_elt_t(geo.doc,_U(materials))); geo.doc_root.append(geo.doc_solids = xml_elt_t(geo.doc,_U(solids))); geo.doc_root.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure))); geo.doc_root.append(geo.doc_setup = xml_elt_t(geo.doc,_U(setup))); - elt = xml_elt_t(geo.doc,_U(world)); - elt.setAttr(_U(ref),lcdd.worldVolume().name()); - geo.doc_setup.append(elt); - + geo.doc_setup.setRef(_U(world),lcdd.worldVolume().name()); + geo.doc_setup.setAttr(_U(name),Unicode("Default")); + geo.doc_setup.setAttr(_U(version),Unicode("1.0")); // Ensure that all required materials are present in the Geant4 material table +#if 0 const LCDD::HandleMap& mat = lcdd.materials(); for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i) geo.materials.insert(dynamic_cast<TGeoMedium*>((*i).second.ptr())); +#endif // Start creating the objects for materials, solids and log volumes. handle(this, geo.materials, &LCDDConverter::handleMaterial); @@ -896,9 +969,6 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { handle(this, geo.volumes, &LCDDConverter::handleVolume); cout << "++ Handled " << geo.volumes.size() << " volumes." << endl; - // Now place all this stuff appropriately - handleRMap(this, *m_data, &LCDDConverter::handlePlacement); - m_checkNames.clear(); handle(this, geo.volumes, &LCDDConverter::checkVolumes); return geo.doc; @@ -906,7 +976,7 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { /// Create geometry conversion -xml_doc_t LCDDConverter::createLCDD(DetElement top) { +xml_doc_t LCDDConverter::createVis(DetElement top) { LCDD& lcdd = m_lcdd; if ( !top.isValid() ) { throw runtime_error("Attempt to call createLCDD with an invalid geometry!"); @@ -917,10 +987,7 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { collect(top,geo); m_checkOverlaps = false; - #define ns_location "http://www.lcsim.org.schemas/lcdd/1.0" - - const char empty_lcdd[] = XML_HEADER_DECLARATION - "<!-- \n" + const char comment[] = "\n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" " ++++ Linear collider detector description LCDD in C++ ++++\n" " ++++ DD4hep Detector description generator. ++++\n" @@ -928,22 +995,51 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { " ++++ Parser:" XML_IMPLEMENTATION_TYPE " ++++\n" " ++++ ++++\n" " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - "-->\n" - "<lcdd " - "xmlns:lcdd=\"" ns_location "\"\n" - "xmlns:xs=\"http://www/w3.org/2001/XMLSchema-instance\"\n" - ">\n" - "</lcdd>\0\0"; + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; + XML::DocumentHandler docH; + xml_elt_t elt(0); + geo.doc = docH.create("visualization",comment); + geo.doc_root = geo.doc.root(); + geo.doc_root.append(geo.doc_display = xml_elt_t(geo.doc,_U(display))); + geo.doc_root.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure))); + + handle(this, geo.volumes, &LCDDConverter::collectVolume); + handle(this, geo.volumes, &LCDDConverter::handleVolumeVis); + cout << "++ Handled " << geo.volumes.size() << " volumes." << endl; + return geo.doc; +} + +/// Create geometry conversion +xml_doc_t LCDDConverter::createLCDD(DetElement top) { + LCDD& lcdd = m_lcdd; + if ( !top.isValid() ) { + throw runtime_error("Attempt to call createLCDD with an invalid geometry!"); + } + + GeometryInfo& geo = *(m_dataPtr=new GeometryInfo); + m_data->clear(); + collect(top,geo); + m_checkOverlaps = false; + const char comment[] = "\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + " ++++ Linear collider detector description LCDD in C++ ++++\n" + " ++++ DD4hep Detector description generator. ++++\n" + " ++++ ++++\n" + " ++++ Parser:" XML_IMPLEMENTATION_TYPE " ++++\n" + " ++++ ++++\n" + " ++++ M.Frank CERN/LHCb ++++\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; xml_elt_t elt(0); - geo.doc = docH.parse(empty_lcdd,sizeof(empty_lcdd)); - //doc->setXmlStandalone(true); - //doc->setStrictErrorChecking(true); + geo.doc = docH.create("lcdd",comment); geo.doc_root = geo.doc.root(); + geo.doc_root.setAttr(Unicode("xmlns:lcdd"), + "http://www.lcsim.org/schemas/lcdd/1.0"); + geo.doc_root.setAttr(Unicode("xmlns:xs"),"http://www.w3.org/2001/XMLSchema-instance"); + geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"), + "http://www.lcsim.org/schemas/lcdd/1.0/lcdd.xsd"); - //Box worldSolid(doc,_U(world_box)); geo.doc_root.append(geo.doc_header = xml_elt_t(geo.doc,_U(header))); geo.doc_root.append(geo.doc_idDict = xml_elt_t(geo.doc,_U(iddict))); geo.doc_root.append(geo.doc_detectors = xml_elt_t(geo.doc,_U(sensitive_detectors))); @@ -952,23 +1048,22 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { geo.doc_root.append(geo.doc_display = xml_elt_t(geo.doc,_U(display))); geo.doc_root.append(geo.doc_gdml = xml_elt_t(geo.doc,_U(gdml))); geo.doc_root.append(geo.doc_fields = xml_elt_t(geo.doc,_U(fields))); - //elt = xml_elt_t(); geo.doc_gdml.append(geo.doc_define = xml_elt_t(geo.doc,_U(define))); geo.doc_gdml.append(geo.doc_materials = xml_elt_t(geo.doc,_U(materials))); geo.doc_gdml.append(geo.doc_solids = xml_elt_t(geo.doc,_U(solids))); geo.doc_gdml.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure))); geo.doc_gdml.append(geo.doc_setup = xml_elt_t(geo.doc,_U(setup))); - elt = xml_elt_t(geo.doc,_U(world)); - elt.setAttr(_U(ref),lcdd.worldVolume().name()); - geo.doc_setup.append(elt); - + geo.doc_setup.setRef(_U(world),lcdd.worldVolume().name()); + geo.doc_setup.setAttr(_U(name),Unicode("Default")); + geo.doc_setup.setAttr(_U(version),Unicode("1.0")); // Ensure that all required materials are present in the Geant4 material table +#if 0 const LCDD::HandleMap& mat = lcdd.materials(); for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i) geo.materials.insert(dynamic_cast<TGeoMedium*>((*i).second.ptr())); - +#endif const LCDD::HandleMap& fld = lcdd.fields(); for(LCDD::HandleMap::const_iterator i=fld.begin(); i!=fld.end(); ++i) geo.fields.insert((*i).second.ptr()); @@ -1002,12 +1097,8 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { handle(this, geo.fields, &LCDDConverter::handleField); cout << "++ Handled " << geo.fields.size() << " fields." << endl; - // Now place all this stuff appropriately - handleRMap(this, *m_data, &LCDDConverter::handlePlacement); - m_checkNames.clear(); handle(this, geo.volumes, &LCDDConverter::checkVolumes); - #if 0 //==================== Fields handleProperties(m_lcdd.properties()); @@ -1039,5 +1130,43 @@ static long create_lcdd(LCDD& lcdd, int argc, char** argv) { return dump_output(wr.createLCDD(lcdd.world()),argc,argv); } +static long create_vis(LCDD& lcdd, int argc, char** argv) { + LCDDConverter wr(lcdd); + return dump_output(wr.createVis(lcdd.world()),argc,argv); +} + +static long create_visASCII(LCDD& lcdd, int argc, char** argv) { + LCDDConverter wr(lcdd); + xml_doc_t doc = wr.createVis(lcdd.world()); + LCDDConverter::GeometryInfo& geo = wr.data(); + map<string,xml_comp_t> vis; + for(xml_coll_t c(geo.doc_display,_U(vis)); c; ++c) + vis.insert(make_pair(xml_comp_t(c).nameStr(),xml_comp_t(c))); + + const char* sep = ";"; + ofstream os(argv[0]); + for(xml_coll_t c(geo.doc_structure,_U(volume)); c; ++c) { + xml_comp_t vol = c; + xml_comp_t r = c.child(_U(visref)); + xml_comp_t v = (*vis.find(r.refStr())).second; + xml_comp_t c = v.child(_U(color)); + os << "vol:" << vol.nameStr() << sep + << "vis:" << v.nameStr() << sep + << "visible:" << v.visible() << sep + << "r:" << c.R() << sep + << "g:" << c.G() << sep + << "b:" << c.B() << sep + << "alpha:" << c.alpha() << sep + << "line_style:" << v.attr<string>(_U(line_style)) << sep + << "drawing_style:" << v.attr<string>(_U(drawing_style)) << sep + << "show_daughters:" << v.show_daughters() << sep + << endl; + } + os.close(); + return 1; +} + +DECLARE_APPLY(DD4hepGeometry2VIS, create_vis); +DECLARE_APPLY(DD4hepGeometry2VISASCII, create_visASCII); DECLARE_APPLY(DD4hepGeometry2GDML,create_gdml); DECLARE_APPLY(DD4hepGeometry2LCDD,create_lcdd); diff --git a/DDCore/src/plugins/LCDDConverter.h b/DDCore/src/plugins/LCDDConverter.h index ef72f9c1bd1cf00b5b304d40733ef49e8b6f4bb8..5d1511fe05fde7b2a0fb076c7d1cab5de574a4c6 100644 --- a/DDCore/src/plugins/LCDDConverter.h +++ b/DDCore/src/plugins/LCDDConverter.h @@ -89,6 +89,7 @@ namespace DD4hep { void checkMaterial(const std::string& name,const TNamed* n) const { check(name,n,checks.materials); } xml_doc_t doc; + xml_h identity_rot, identity_pos; xml_elt_t doc_root, doc_header, doc_idDict, doc_detectors, doc_limits, doc_regions, doc_display, doc_gdml, doc_fields, doc_define, doc_materials, doc_solids, doc_structure, doc_setup; GeometryInfo(); @@ -120,6 +121,9 @@ namespace DD4hep { /// Create geometry conversion in LCDD format xml_doc_t createLCDD(DetElement top); + /// Create geometry conversion in Vis format + xml_doc_t createVis(DetElement top); + /// Add header information in LCDD format virtual void handleHeader() const; @@ -134,7 +138,8 @@ namespace DD4hep { /// Convert the geometry type logical volume into the corresponding Xml object(s). virtual xml_h handleVolume(const std::string& name, const TGeoVolume* volume) const; - virtual void collectVolume(const std::string& name, const TGeoVolume* volume) const; + virtual xml_h handleVolumeVis(const std::string& name, const TGeoVolume* volume) const; + virtual void collectVolume(const std::string& name, const TGeoVolume* volume) const; /// Convert the geometry type volume placement into the corresponding Xml object(s). virtual xml_h handlePlacement(const std::string& name, const TGeoNode* node) const; diff --git a/DDCore/src/plugins/LCDDFields.cpp b/DDCore/src/plugins/LCDDFields.cpp index 221f046af9a1d0b71ae52345bec222fcd7b36433..28f781f776b9ddfc3083e3eb0bd3f617da0dd8dc 100644 --- a/DDCore/src/plugins/LCDDFields.cpp +++ b/DDCore/src/plugins/LCDDFields.cpp @@ -49,7 +49,7 @@ static Ref_t convert_solenoid(LCDD& lcdd, xml_h field, Ref_t object) { field.setAttr(_U(zmax),s->maxZ); return object; } -DECLARE_XML_PROCESSOR(SolenoidMagnet_Convert2LCDD,convert_solenoid); +DECLARE_XML_PROCESSOR(solenoid_Convert2LCDD,convert_solenoid); static Ref_t convert_dipole(LCDD& lcdd, xml_h field, Ref_t object) { char text[128];