File indexing completed on 2025-01-18 09:14:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include "DDDB/DDDBTags.h"
0022 #include "DDDB/DDDBHelper.h"
0023 #include "DDDB/DDDBReader.h"
0024 #include "DDDB/DDDBDimension.h"
0025 #include "DDDB/DDDBConversion.h"
0026 #include "DDDBConfig.h"
0027
0028 #include "DD4hep/Detector.h"
0029 #include "DD4hep/Path.h"
0030
0031 #include "DD4hep/ConditionsData.h"
0032 #include "DD4hep/DetectorTools.h"
0033 #include "DD4hep/InstanceCount.h"
0034 #include "DD4hep/detail/ConditionsInterna.h"
0035
0036 #include "DDCond/ConditionsPool.h"
0037
0038
0039 #include "TGeoManager.h"
0040
0041
0042 #include <climits>
0043 #include <iostream>
0044 #include <iomanip>
0045 #include <set>
0046
0047 using namespace std;
0048 using namespace dd4hep;
0049 using namespace dd4hep::DDDB;
0050
0051
0052 namespace dd4hep {
0053
0054
0055 namespace {
0056 static DDDB2Objects::PrintConfig s_config;
0057 }
0058
0059
0060 DDDB2Objects::PrintConfig& DDDB2Objects::PrintConfig::instance() {
0061 return s_config;
0062 }
0063
0064
0065 namespace {
0066
0067 struct DDDBDetElem;
0068 typedef detail::ConditionObject GeoCondition;
0069 typedef cond::ConditionsManager ConditionsManager;
0070 typedef cond::ConditionsPool ConditionsPool;
0071 typedef cond::AbstractMap AbstractMap;
0072
0073
0074 struct Context {
0075 typedef set<string> StringSet;
0076
0077 Context(Detector& l, DDDB::DDDBHelper* h) : description(l), geo(h->detectorDescription()), helper(h) {
0078 reader = h->reader<DDDB::DDDBReader>();
0079 print = s_config;
0080 }
0081 ~Context() {
0082
0083 }
0084 template <typename T, typename Q>
0085 static const Q find(const typename std::map<T,Q>& m, const T& match) {
0086 typename std::map<T,Q>::const_iterator i = m.find(match);
0087 return (i != m.end()) ? (*i).second : 0;
0088 }
0089 template <typename T> void collect(const string& id, T* s);
0090 template <typename T,typename Q> void collect(const string& id, T* s, Q* c);
0091 Detector& description;
0092 DDDB::dddb* geo = 0;
0093 DDDB::DDDBHelper* helper = 0;
0094 DDDB::DDDBReader* reader = 0;
0095 typedef std::map<DDDBIsotope*, TGeoIsotope*> Isotopes;
0096 typedef std::map<DDDBElement*, TGeoElement*> Elements;
0097 typedef std::map<DDDBMaterial*, TGeoMedium*> Materials;
0098 typedef std::map<DDDBShape*, TGeoShape*> Shapes;
0099 typedef std::map<DDDBLogVol*, TGeoVolume*> Volumes;
0100 typedef std::map<DDDBPhysVol*, TGeoNode*> Placements;
0101 typedef std::map<std::string, DetElement> DetectorMap;
0102 typedef std::map<std::string, TGeoVolume*> VolumeMap;
0103 typedef std::map<DetElement, DDDBCatalog*> DetectorElements;
0104
0105 Isotopes isotopes;
0106 Elements elements;
0107 Materials materials;
0108 Shapes shapes;
0109 Volumes volumes;
0110 VolumeMap volumePaths;
0111 Placements placements;
0112 DetElement detectors;
0113 DetectorMap catalogPaths;
0114 DetectorElements detelements;
0115 Volume lvDummy;
0116 ConditionsManager manager;
0117 const IOVType* epoch = 0;
0118 DDDB2Objects::PrintConfig print;
0119 int unmatched_deltas = 0;
0120 int delta_conditions = 0;
0121 int matched_conditions = 0;
0122 int unmatched_conditions = 0;
0123 int badassigned_conditions = 0;
0124 bool conditions_only = false;
0125
0126 static PlacedVolume placement(DetElement de) {
0127 if ( de.isValid() ) {
0128 PlacedVolume p = de.placement();
0129 if ( p.isValid() ) return p;
0130 return placement(de.parent());
0131 }
0132 return PlacedVolume(0);
0133 }
0134 static bool volumePlaced(Volume par_vol, Volume vol) {
0135 if ( par_vol.isValid() && vol.isValid() && par_vol.ptr() == vol.ptr() ) {
0136 for(int i=0; i < vol->GetNdaughters(); ++i) {
0137 TGeoNode* dau = vol->GetNode(i);
0138 TGeoVolume* v = dau->GetVolume();
0139 if ( v == vol.ptr() ) return true;
0140 }
0141 }
0142 return false;
0143 }
0144
0145 TGeoNode* supportPlacement(TGeoVolume* parent, const string& npath) {
0146 if ( !npath.empty() ) {
0147 size_t idx = npath.find('/');
0148 if ( idx == string::npos ) {
0149 for(int i=0; i<parent->GetNdaughters(); ++i) {
0150 TGeoNode* dau = parent->GetNode(i);
0151 if ( npath == dau->GetTitle() ) {
0152 return dau;
0153 }
0154 }
0155 return 0;
0156 }
0157 TGeoNode* dau = supportPlacement(parent, npath.substr(0,idx));
0158 if ( dau ) {
0159 return supportPlacement(dau->GetVolume(), npath.substr(idx+1));
0160 }
0161 }
0162 return 0;
0163 }
0164
0165 PlacedVolume supportPlacement(DetElement parent, const string& npath) {
0166 Volume par_vol = parent.volume();
0167 return par_vol.isValid() ? supportPlacement(par_vol.ptr(), npath) : 0;
0168 }
0169 };
0170
0171 template <typename T> struct CNV : public Converter<T,T*> {
0172 public:
0173 typedef Converter<T,T*> Base_t;
0174
0175 CNV(Detector& l, void* p, void* o=0) : Converter<T,T*>(l,p,o) {}
0176 template<typename Q> CNV<Q> cnv() const { return CNV<Q>(this->description,this->param,this->optional); }
0177 void* convert(T* obj) const;
0178 template<typename Q> Q get(const string& ) const {
0179 throw runtime_error("NOT implemented virtual call ! CNV<"+
0180 typeName(typeid(T))+">::get<"+typeName(typeid(Q))+">(string)");
0181 }
0182 void operator()(T* obj) const { convert(obj); }
0183 void operator()(const pair<string,T*>& arg) const {
0184 Increment<T> incr;
0185 try {
0186 if ( arg.second ) {
0187 operator()(arg.second);
0188 return;
0189 }
0190 Context* c = (Context*)this->Base_t::param;
0191 if ( c && c->reader && c->reader->isBlocked(arg.first) )
0192 return;
0193 printout(INFO,typeName(typeid(T)),"SKIP invalid object: %s",arg.first.c_str());
0194 }
0195 catch(const exception& e) {
0196 printout(INFO,typeName(typeid(T)),"Failed to convert object: %s",e.what());
0197 }
0198 catch(...) {
0199 printout(INFO,typeName(typeid(T)),"Failed to convert object.");
0200 }
0201 }
0202 };
0203 }
0204
0205 namespace {
0206 static UInt_t unique_mat_id = 0xAFFEFEED;
0207
0208 template <> void* CNV<GeoCondition>::convert(GeoCondition *object) const;
0209 template <> void* CNV<DDDBIsotope>::convert(DDDBIsotope *object) const;
0210 template <> void* CNV<DDDBElement>::convert(DDDBElement *object) const;
0211 template <> void* CNV<DDDBMaterial>::convert(DDDBMaterial *object) const;
0212 template <> void* CNV<DDDBBooleanOperation>::convert(DDDBBooleanOperation *object) const;
0213 template <> void* CNV<DDDBShape>::convert(DDDBShape *object) const;
0214 template <> void* CNV<DDDBDetElem>::convert(DDDBDetElem *object) const;
0215 template <> void* CNV<DDDBLogVol>::convert(DDDBLogVol *object) const;
0216 template <> void* CNV<DDDBCatalog>::convert(DDDBCatalog *object) const;
0217 template <> void* CNV<dddb>::convert(dddb *obj) const;
0218
0219 template <> template <> Material CNV<DDDBMaterial>::get<Material>(const string& material_name) const;
0220 template <> template <> DDDBLogVol* CNV<DDDBLogVol>::get<DDDBLogVol*>(const string& obj) const;
0221 template <> template <> Volume CNV<DDDBLogVol>::get<Volume>(const string& obj) const;
0222
0223
0224 template <> void* CNV<GeoCondition>::convert(GeoCondition *obj) const {
0225 if ( obj ) {
0226 typedef IOV::Key _K;
0227 Context* context = _param<Context>();
0228 Condition cond = obj;
0229 AbstractMap& d = cond.get<AbstractMap>();
0230 DDDBDocument* doc = d.option<DDDBDocument>();
0231 _K::first_type since = doc->context.valid_since;
0232 _K::second_type until = doc->context.valid_until;
0233 _K iov_key(since,until);
0234 auto e = context->helper->getConditionEntry(obj->value);
0235
0236
0237 if ( obj->testFlag(Condition::ALIGNMENT_DELTA) ) {
0238 const pair<string,OpaqueDataBlock>& block = *(d.params.begin());
0239 Delta delta = block.second.get<Delta>();
0240 string typ = obj->type, add = obj->address, val = obj->value;
0241 int flg = obj->flags;
0242
0243 obj->~ConditionObject();
0244 new(obj) Condition::Object(e.second,typ);
0245 cond.setFlag(flg);
0246 cond->address = add;
0247 cond->value = val;
0248 cond.bind<Delta>() = delta;
0249 ++context->delta_conditions;
0250 if ( !e.first.isValid() )
0251 ++context->unmatched_deltas;
0252 }
0253 if ( e.first.isValid() ) {
0254 cond->SetName(e.second.c_str());
0255 cond->hash = ConditionKey::KeyMaker(e.first.key(),detail::hash32(cond.name())).hash;
0256 printout(DEBUG,"DDDB","Insert condition: %s # %s --> %16llX",
0257 e.first.path().c_str(),cond.name(),cond.key());
0258 printout(DEBUG,"DDDB"," %s -> %s",cond->value.c_str(),cond->address.c_str());
0259 ++context->matched_conditions;
0260 }
0261 else {
0262
0263
0264 ++context->unmatched_conditions;
0265 }
0266 ConditionsPool* pool = context->manager.registerIOV(*(context->epoch), iov_key);
0267 context->manager.registerUnlocked(*pool, cond);
0268
0269 }
0270 return obj;
0271 }
0272
0273
0274 template <> void* CNV<DDDBIsotope>::convert(DDDBIsotope *o) const {
0275 Context* context = _param<Context>();
0276 TGeoIsotope* iso = Context::find(context->isotopes, o);
0277 if ( !iso ) {
0278 iso = TGeoIsotope::FindIsotope(o->c_name());
0279 if ( !iso ) iso = new TGeoIsotope(o->c_name(),o->Z,o->A,o->density);
0280 context->isotopes.insert(make_pair(o,iso));
0281 if ( context->print.materials ) dddb_print(iso);
0282 }
0283 return iso;
0284 }
0285
0286
0287 TGeoElement* createElement(const char* nam, Context* context, DDDBElement *o) {
0288 TGeoElementTable* t = TGeoElement::GetElementTable();
0289 TGeoElement* e = t->FindElement(nam);
0290 if ( !e ) {
0291 size_t iso_count = 0;
0292 for(auto i = o->isotopes.begin(); i != o->isotopes.end(); ++i) ++iso_count;
0293 if ( 0 == iso_count )
0294 e = new TGeoElement(nam,o->symbol.c_str(),o->atom.Zeff,o->atom.A,o->density);
0295 else
0296 e = new TGeoElement(nam,o->symbol.c_str(), iso_count);
0297
0298 for(auto i = o->isotopes.begin(); i != o->isotopes.end(); ++i) {
0299 auto iso = context->geo->isotopes.find((*i).first);
0300 if ( iso == context->geo->isotopes.end() ) {
0301 printout(ERROR,"DDDB","++ Invalid isotope: %s [Ignore Isotope]",(*i).first.c_str());
0302 continue;
0303 }
0304 DDDBIsotope* isotope = (*iso).second;
0305 TGeoIsotope* geo_iso =
0306 (TGeoIsotope*)CNV<DDDBIsotope>(context->description,context).convert(isotope);
0307 if ( !geo_iso ) {
0308 printout(ERROR,"DDDB","++ Invalid isotope: %s [Ignore Isotope]",(*iso).first.c_str());
0309 continue;
0310 }
0311 e->AddIsotope(geo_iso, (*i).second);
0312 }
0313 t->AddElement(e);
0314 e = t->FindElement(nam);
0315 if ( !e ) {
0316 except("Cnv<Element>","Failed to insert Element: %s into table!", nam);
0317 return 0;
0318 }
0319 if ( context->print.materials ) dddb_print(e);
0320 }
0321 DDDBMaterial* material = Context::find(context->geo->materials,string(nam));
0322 if ( !material ) {
0323 TGeoManager& mgr = context->description.manager();
0324 if ( !mgr.GetMaterial(nam) || !mgr.GetMedium(nam) ) {
0325 DDDBMaterialComponent comp;
0326 material = new DDDBMaterial;
0327 material->name = nam;
0328 material->density = o->density;
0329 comp.name = nam;
0330 comp.fractionmass = 1.0;
0331 material->components.push_back(comp);
0332 context->geo->materials.insert(make_pair(nam,material));
0333 CNV<DDDBMaterial>(context->description,context)(material);
0334 }
0335 }
0336 return e;
0337 }
0338
0339
0340 template <> void* CNV<DDDBElement>::convert(DDDBElement *object) const {
0341 Context* context = _param<Context>();
0342 TGeoElement* e = Context::find(context->elements, object);
0343 if ( !e ) {
0344 e = createElement(object->c_name(), context, object);
0345 context->elements.insert(make_pair(object,e));
0346 if ( !object->symbol.empty() && object->symbol != object->name ) {
0347 DDDBElement* esym = Context::find(context->geo->elements, object->symbol);
0348 if ( !esym ) {
0349 esym = new DDDBElement(*object);
0350 esym->name = object->symbol;
0351 context->geo->elements.insert(make_pair(object->symbol,esym));
0352 }
0353 TGeoElement* es = Context::find(context->elements, esym);
0354 if ( !es ) {
0355 es = createElement(esym->c_name(), context, esym);
0356 context->elements.insert(make_pair(esym, es));
0357 }
0358 }
0359 }
0360 return e;
0361 }
0362
0363
0364 template <> void* CNV<DDDBMaterial>::convert(DDDBMaterial *object) const {
0365 Context* context = _param<Context>();
0366 TGeoMedium* medium = Context::find(context->materials, object);
0367 if ( !medium ) {
0368 const char* name = object->c_name();
0369 TGeoManager& mgr = description.manager();
0370 TGeoElementTable* tab = TGeoElement::GetElementTable();
0371 TGeoMaterial* mat = mgr.GetMaterial(name);
0372 TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat);
0373
0374 medium = mgr.GetMedium(name);
0375 if ( 0 == mat ) {
0376 DDDBMaterial::Components& comp = object->components;
0377
0378 mat = mix = new TGeoMixture(name, comp.size(), object->density);
0379 if ( object->radlen > 0 && object->lambda > 0 )
0380 mat->SetRadLen(object->radlen, object->lambda);
0381 else if ( object->radlen > 0 )
0382 mat->SetRadLen(object->radlen);
0383 if ( object->pressure > 0 )
0384 mat->SetPressure(object->pressure);
0385 if ( object->temperature > 0 )
0386 mat->SetTemperature(object->temperature);
0387 for(auto i = comp.begin(); i != comp.end(); ++i) {
0388 DDDBMaterialComponent& c=(*i);
0389 TGeoElement* e = tab->FindElement(c.c_name());
0390 if ( e && c.natoms>0 ) {
0391 mix->AddElement(e, c.natoms);
0392 continue;
0393 }
0394 else if ( e && c.fractionmass >= 0 ) {
0395 mix->AddElement(e, c.fractionmass);
0396 continue;
0397 }
0398 else if ( c.fractionmass >= 0 ) {
0399 Material mm = this->get<Material>(c.name);
0400 mix->AddElement(mm->GetMaterial(), c.fractionmass);
0401 continue;
0402 }
0403 }
0404 }
0405
0406 if (0 == medium) {
0407 --unique_mat_id;
0408 medium = new TGeoMedium(name, unique_mat_id, mat);
0409 medium->SetTitle("material");
0410 medium->SetUniqueID(unique_mat_id);
0411 }
0412 context->materials.insert(make_pair(object,medium));
0413 if ( context->print.materials ) dddb_print(medium);
0414 }
0415 return medium;
0416 }
0417
0418
0419 template <> template <>
0420 Material CNV<DDDBMaterial>::get<Material>(const string& material_name) const {
0421 Context* context = _param<Context>();
0422 TGeoManager& mgr = description.manager();
0423 TGeoMedium* gmed = mgr.GetMedium(material_name.c_str());
0424 if ( gmed ) {
0425 return Material(gmed);
0426 }
0427 TGeoMaterial* gmat = mgr.GetMaterial(material_name.c_str());
0428 if ( gmat ) {
0429 --unique_mat_id;
0430 gmed = new TGeoMedium(material_name.c_str(), unique_mat_id, gmat);
0431 gmed->SetTitle("material");
0432 gmed->SetUniqueID(unique_mat_id);
0433 if ( context->print.materials ) dddb_print(gmed);
0434 return Material(gmed);
0435 }
0436 DDDBMaterial* mat = Context::find(context->geo->materials,material_name);
0437 if ( !mat ) {
0438 string mat_name = material_name;
0439 size_t idx;
0440 if ( mat_name.empty() )
0441 mat_name = "Air";
0442 else if ( (idx=mat_name.rfind('/')) != string::npos ) {
0443 mat_name = mat_name.substr(idx+1);
0444 }
0445 mat = Context::find(context->geo->materials,mat_name);
0446 }
0447 if ( !mat ) {
0448 if ( context->print.materials ) {
0449 printout(ERROR,"Cnv<Material>",
0450 "++ Failed to find component material: %s "
0451 "---> Material table dump.", material_name.c_str());
0452 for(auto im=context->geo->materials.begin(); im != context->geo->materials.end(); ++im)
0453 dddb_print((*im).second);
0454 }
0455 except("Materials","++ Undefined material %s",material_name.c_str());
0456 }
0457 TGeoMedium* medium = (TGeoMedium*)CNV<DDDBMaterial>(context->description,context).convert(mat);
0458 return Material(medium);
0459 }
0460
0461
0462 template <> void* CNV<DDDBShape>::convert(DDDBShape *object) const {
0463 Context* context = _param<Context>();
0464 Solid shape = Context::find(context->shapes, object);
0465 if ( !shape ) {
0466 if ( object->id == "/dd/Geometry/LHCb/lvLHCb" ) {
0467 shape = description.worldVolume().solid();
0468 }
0469 else if ( object->type == DDDBAssembly::type() ) {
0470 except("Cnv<Shape>","++ Assembly shapes cannot be converted!");
0471 }
0472 else if ( object->type == DDDBBox::type() ) {
0473 shape = Box(object->s.box.x, object->s.box.y, object->s.box.z).ptr();
0474 }
0475 else if ( object->type == DDDBCons::type() ) {
0476 const DDDBCons& c = object->s.cons;
0477 shape = Cone(c.sizeZ,
0478 c.innerRadiusMZ, c.outerRadiusMZ,
0479 c.innerRadiusPZ, c.outerRadiusPZ).ptr();
0480 }
0481 else if ( object->type == DDDBConeSegment::type() ) {
0482 const DDDBConeSegment& o = object->s.coneSegment;
0483 shape = ConeSegment(o.sizeZ,
0484 o.innerRadiusMZ, o.outerRadiusMZ,
0485 o.innerRadiusPZ, o.outerRadiusPZ,
0486 o.start, o.delta).ptr();
0487 }
0488 else if ( object->type == DDDBEllipticalTube::type() ) {
0489 const DDDBEllipticalTube& o = object->s.ellipticalTube;
0490 shape = EllipticalTube(o.a, o.b, o.dz).ptr();
0491 }
0492 else if ( object->type == DDDBTubs::type() ) {
0493 const DDDBTubs& t = object->s.tubs;
0494 shape = Tube(t.innerRadius, t.outerRadius, t.sizeZ, t.start, t.delta);
0495 }
0496 else if ( object->type == DDDBPolycone::type() ) {
0497 DDDBPolycone& o = object->s.polycone;
0498 TGeoPcon* pc = new TGeoPcon(o.start, o.delta, object->zplanes.size());
0499 for(size_t iz=0; iz< object->zplanes.size(); ++iz) {
0500 const DDDBZPlane& plane = object->zplanes[iz];
0501 pc->DefineSection(iz, plane.z, plane.innerRadius, plane.outerRadius);
0502 }
0503 shape = pc;
0504 }
0505 else if ( object->type == DDDBPolygon::type() ) {
0506 DDDBPolygon& o = object->s.polygon;
0507 shape = PolyhedraRegular(o.nsides, o.start, o.innerRadius, o.outerRadius, o.z);
0508 }
0509 else if ( object->type == DDDBSphere::type() ) {
0510 const DDDBSphere& o = object->s.sphere;
0511 shape = Sphere(o.rmin, o.rmax, o.theta, o.theta+o.delta_theta, o.phi, o.phi+o.delta_phi);
0512 }
0513
0514
0515
0516
0517 else if ( object->type == DDDBParaboloid::type() ) {
0518 const DDDBParaboloid& o = object->s.paraboloid;
0519 shape = Paraboloid(o.rlow, o.rhigh, o.dz).ptr();
0520 }
0521 else if ( object->type == DDDBHyperboloid::type() ) {
0522 const DDDBHyperboloid& o = object->s.hyperboloid;
0523 shape = Hyperboloid(o.rmin, o.rmax, o.stIn, o.stOut, o.dz).ptr();
0524 }
0525 else if ( object->type == DDDBTRD::type() ) {
0526 const DDDBTRD& o = object->s.trd;
0527 shape = Trapezoid(o.x1, o.x2, o.y1, o.y2, o.z).ptr();
0528 }
0529 else if ( object->type == DDDBTrap::type() ) {
0530 const DDDBTrap& o = object->s.trap;
0531 shape = Trap(o.dz, o.theta, o.phi,
0532 o.h1, o.bl1, o.tl1, o.alpha1,
0533 o.h2, o.bl2, o.tl2, o.alpha2);
0534 }
0535 else if ( object->type == DDDBBooleanUnion::type() ||
0536 object->type == DDDBBooleanSubtraction::type() ||
0537 object->type == DDDBBooleanIntersection::type() ) {
0538 shape = context->lvDummy.solid();
0539 DDDBShape::Operations::const_iterator i;
0540 DDDBShape* left_shape = object->s.boolean.first;
0541 Solid left_solid = (TGeoShape*)convert(left_shape);
0542 if ( !left_solid.isValid() ) {
0543 except("Cnv<Shape>","++ %s: Unknown left boolean shape creation:%s -> %d",
0544 object->c_name(), left_shape->c_name(), left_shape->type);
0545 }
0546 shape = left_solid;
0547 for(i=object->boolean_ops.begin(); i != object->boolean_ops.end(); ++i) {
0548 DDDBShape* right_shape = (*i).shape;
0549 Solid right_solid = (TGeoShape*)convert(right_shape);
0550 const Transform3D& trafo = (*i).trafo;
0551 if ( !right_solid.isValid() ) {
0552 except("Cnv<Shape>","++ %s: Unknown right boolean shape creation:%s -> %d",
0553 object->c_name(), right_shape->c_name(), right_shape->type);
0554 }
0555 shape = Solid();
0556 if ( object->type == DDDBBooleanUnion::type() )
0557 shape = UnionSolid(left_solid, right_solid, trafo);
0558 else if ( object->type == DDDBBooleanSubtraction::type() )
0559 shape = SubtractionSolid(left_solid, right_solid, trafo);
0560 else if ( object->type == DDDBBooleanIntersection::type() )
0561 shape = IntersectionSolid(left_solid, right_solid, trafo);
0562 if ( !shape.isValid() ) {
0563 except("Cnv<Shape>","++ %s: Unknown boolean shape creation:%d",
0564 object->c_name(), object->type);
0565 }
0566 left_solid = shape;
0567 }
0568 }
0569 if ( !shape ) {
0570 except("Cnv<Shape>","++ Undefined shape conversion %s [id:%d]",
0571 object->c_id(), object->type);
0572 }
0573 shape->SetTitle(object->path.c_str());
0574 if ( context->print.shapes ) {
0575 printout(INFO,"Cnv<Shape>","++ Converted shape: %s",object->c_id());
0576 }
0577 context->shapes.insert(make_pair(object, shape));
0578 }
0579 return shape;
0580 }
0581
0582 inline PlacedVolume place_daughter(const char* pv, Volume mother, Volume daughter, const Transform3D& tr) {
0583 PlacedVolume place = mother.placeVolume(daughter, tr);
0584
0585 place->SetTitle(pv);
0586 return place;
0587 }
0588
0589 inline void __check_physvol_instances__(int n) {
0590 if ( n <= 0 ) {
0591 printout(WARNING,"Cnv<PhysVol>","++ Invalid replication constant in ParamPhysVolXD:%d",n);
0592 }
0593 }
0594
0595
0596 template <> void* CNV<DDDBLogVol>::convert(DDDBLogVol *object) const {
0597 struct VolumeDepth {};
0598 Increment<VolumeDepth> depth;
0599 Context* context = _param<Context>();
0600 Volume mother = Context::find(context->volumes, object);
0601
0602 if ( !mother.isValid() ) {
0603 if ( depth.counter() >= context->print.max_volume_depth ) {
0604 mother = context->lvDummy;
0605 context->volumes.insert(make_pair(object, mother.ptr()));
0606 context->volumePaths[object->path] = mother.ptr();
0607 printout(WARNING,"Cnv<LogVol>","++ Ignore placements below level:%d -> %s",
0608 depth.counter(), object->path.c_str());
0609 return mother;
0610 }
0611 DDDBShape* shape = Context::find(context->geo->shapes,object->shape);
0612 if ( object->shape.empty() || shape->type == DDDBAssembly::type() ) {
0613 mother = Assembly(object->name);
0614 }
0615 else {
0616 Solid s = (TGeoShape*)cnv<DDDBShape>().convert(shape);
0617 if ( s.isValid() ) {
0618 Material m = cnv<DDDBMaterial>().get<Material>(object->material);
0619 mother = Volume(object->name, s, m);
0620 }
0621 }
0622 mother->SetTitle(object->path.c_str());
0623 VisAttr vis = context->helper->visAttr(object->path);
0624 if ( vis.isValid() ) {
0625 if ( context->print.vis ) {
0626 printout(INFO,"Cnv<LogVol>","++ Vol:%s Vis:%s",mother->GetTitle(), vis.name());
0627 }
0628 mother.setVisAttributes(vis);
0629 }
0630 else {
0631 mother->SetVisibility(kTRUE);
0632 mother->SetVisLeaves(kTRUE);
0633 mother->SetVisContainers(kTRUE);
0634 mother->SetFillColor(kRed);
0635 }
0636 context->volumes.insert(make_pair(object, mother.ptr()));
0637 context->volumePaths[object->path] = mother.ptr();
0638
0639 for(auto i=object->physvols.begin(); i!=object->physvols.end(); ++i) {
0640 DDDBPhysVol* pv = *i;
0641 PlacedVolume place = context->find(context->placements, pv);
0642 if ( !place.isValid() ) {
0643 Volume daughter = this->get<Volume>(pv->logvol);
0644 if ( !daughter.isValid() ) {
0645 if ( context->reader && context->reader->isBlocked(pv->c_id()) )
0646 continue;
0647 printout(WARNING,"Cnv<PhysVol>","++ Failed to convert placement: %s."
0648 " Unknown daughter vol:%s.",pv->c_id(), pv->logvol.c_str());
0649 continue;
0650 }
0651 int num_places = 0;
0652 const char* pv_name = pv->name.c_str();
0653 switch(pv->type) {
0654 case DDDBPhysVol::PHYSVOL_REGULAR: {
0655 place = place_daughter(pv_name, mother, daughter, pv->trafo);
0656 num_places = 1;
0657 break;
0658 }
0659 case DDDBPhysVol::PHYSVOL_PARAM1D: {
0660 DDDBParamPhysVol* pDim = (DDDBParamPhysVol*)pv;
0661 Transform3D tr;
0662 Position pos1, p1;
0663 RotationZYX rot1, r1;
0664 pDim->trafo1.GetDecomposition(r1,p1);
0665 pDim->trafo.GetDecomposition(rot1,pos1);
0666 __check_physvol_instances__(pDim->number1);
0667 for(int k=0; k<pDim->number1; ++k) {
0668 pos1 += p1;
0669 rot1 *= r1;
0670 tr = Transform3D(rot1, pos1);
0671 place = place_daughter(pv_name, mother, daughter, tr);
0672 ++num_places;
0673 }
0674 break;
0675 }
0676 case DDDBPhysVol::PHYSVOL_PARAM2D: {
0677 DDDBParamPhysVol2D* pDim = (DDDBParamPhysVol2D*)pv;
0678 Position pos1, pos2, p1, p2;
0679 RotationZYX rot1, rot2, r1, r2;
0680 Transform3D tr;
0681 __check_physvol_instances__(pDim->number1);
0682 __check_physvol_instances__(pDim->number2);
0683 pDim->trafo1.GetDecomposition(r1, p1);
0684 pDim->trafo2.GetDecomposition(r2, p2);
0685 pDim->trafo.GetDecomposition(rot1,pos1);
0686 for(int k=0; k < pDim->number1; ++k) {
0687 pos1 += p1;
0688 rot1 *= r1;
0689 pos2 = pos1;
0690 rot2 = rot1;
0691 for(int l=0; l < pDim->number2; ++l) {
0692 pos2 += p2;
0693 rot2 *= r2;
0694 tr = Transform3D(rot2, pos2);
0695 place = place_daughter(pv_name, mother, daughter, tr);
0696 ++num_places;
0697 }
0698 }
0699 break;
0700 }
0701 case DDDBPhysVol::PHYSVOL_PARAM3D: {
0702 DDDBParamPhysVol3D* pDim = (DDDBParamPhysVol3D*)pv;
0703 Position pos1, pos2, pos3, p1, p2, p3;
0704 RotationZYX rot1, rot2, rot3, r1, r2, r3;
0705 Transform3D tr;
0706 __check_physvol_instances__(pDim->number1);
0707 __check_physvol_instances__(pDim->number2);
0708 __check_physvol_instances__(pDim->number3);
0709 pDim->trafo1.GetDecomposition(r1, p1);
0710 pDim->trafo2.GetDecomposition(r2, p2);
0711 pDim->trafo2.GetDecomposition(r3, p3);
0712 pDim->trafo.GetDecomposition(rot1,pos1);
0713 for(int k=0; k < pDim->number1; ++k) {
0714 pos1 += p1;
0715 rot1 *= r1;
0716 pos2 = pos1;
0717 rot2 = rot1;
0718 for(int l=0; l < pDim->number2; ++l) {
0719 pos2 += p2;
0720 rot2 *= r2;
0721 pos3 = pos2;
0722 rot3 = rot2;
0723 for(int m=0; m < pDim->number3; ++m) {
0724 pos3 += p3;
0725 rot3 *= r3;
0726 tr = Transform3D(rot3, pos3);
0727 place = place_daughter(pv_name, mother, daughter, tr);
0728 ++num_places;
0729 }
0730 }
0731 }
0732 break;
0733 }
0734 default:
0735 printout(ERROR,"Cnv<PhysVol>","++ \tUnknown ParamPhysVol type: %d",pv->type);
0736 break;
0737 }
0738 context->placements.insert(make_pair(pv, place.ptr()));
0739 if ( context->print.physvol ) {
0740 Position pos;
0741 pv->trafo.GetTranslation(pos);
0742 printout(INFO,"Cnv<PhysVol>","++ Converted physVol: depth:%d typ:%d places:%d [%p lv:%p] %s",
0743 depth.counter(), pv->type, num_places, (void*)place.ptr(), (void*)daughter.ptr(),
0744 mother->GetTitle());
0745 printout(INFO,"Cnv<PhysVol>","++ \tPosition: x=%f y=%f z=%f %p -> %s",
0746 pos.X(), pos.Y(), pos.Z(), (void*)pv, pv->c_name());
0747 }
0748 }
0749 }
0750 if ( context->print.logvol ) {
0751 printout(INFO,"Cnv<LogVol>","++ Converted logVol: [%p -> %p] %s NDau:%d",
0752 (void*)object, (void*)mother.ptr(), object->path.c_str(),
0753 mother->GetNdaughters());
0754 }
0755 }
0756 return mother.ptr();
0757 }
0758
0759
0760 template <> template <>
0761 DDDBLogVol* CNV<DDDBLogVol>::get<DDDBLogVol*>(const string& nam) const {
0762 Context* context = _param<Context>();
0763 DDDBLogVol* lv = Context::find(context->geo->volumes,nam);
0764 if ( lv ) {
0765 return lv;
0766 }
0767 lv = Context::find(context->geo->volumePaths,nam);
0768 if ( lv ) {
0769 return lv;
0770 }
0771 pair<const DDDBCatalog*,string> cat = context->geo->geometry->parent(nam);
0772 if ( cat.first ) {
0773 const DDDBCatalog* c = cat.first;
0774 dddb::Volumes::const_iterator iv = c->logvols.find(cat.second);
0775 if ( iv != c->logvols.end() ) {
0776 lv = (*iv).second;
0777 return lv;
0778 }
0779 #if 0
0780 for(iv = c->logvols.begin(); iv != c->logvols.end(); ++iv)
0781 printout(WARNING,"Cnv<LogVol>","++ %s --volume--> %s",
0782 c->id.c_str(), (*iv).second->name.c_str());
0783 #endif
0784 }
0785 printout(WARNING,"Cnv<LogVol>","++ Undefined logical volume: %s", nam.c_str());
0786 return 0;
0787 }
0788
0789
0790 template <> template <>
0791 Volume CNV<DDDBLogVol>::get<Volume>(const string& nam) const {
0792 DDDBLogVol* lv = this->get<DDDBLogVol*>(nam);
0793 if ( lv ) {
0794 return (TGeoVolume*)this->convert(lv);
0795 }
0796 return Volume(0);
0797 }
0798
0799 template <> void* CNV<DDDBCatalog>::convert(DDDBCatalog *object) const {
0800 Context* context = _param<Context>();
0801 dddb* geo = context->geo;
0802 Context::DetectorMap::const_iterator j=context->catalogPaths.find(object->path);
0803 if ( j != context->catalogPaths.end() ) {
0804 return (*j).second.ptr();
0805 }
0806 Volume vol;
0807 DDDBCatalog* support = 0;
0808 DetElement det, parent_element;
0809 if ( context->print.detelem ) {
0810 printout(INFO,"CNV<Catalog>","++ Starting catalog %p %s [cref:%d/%d lref:%d/%d lv:%s sup:%s np:%s] Cond:%s ",
0811 (void*)object,
0812 object->path.c_str(),
0813 int(object->catalogrefs.size()),
0814 int(object->catalogs.size()),
0815 int(object->logvolrefs.size()),
0816 int(object->logvols.size()),
0817 object->logvol.empty() ? "--" : object->logvol.c_str(),
0818 object->support.empty() ? "--" : object->support.c_str(),
0819 object->npath.empty() ? "--" : object->npath.c_str(),
0820 object->condition.c_str());
0821 }
0822 if ( object->path == "/dd/Structure" ) {
0823 const DDDBBox& o = geo->world;
0824 printout(WARNING,"World","World: %g %g %g",o.x,o.y,o.z);
0825 _toDictionary("world_x",_toString(o.x));
0826 _toDictionary("world_y",_toString(o.y));
0827 _toDictionary("world_z",_toString(o.z));
0828 description.init();
0829 det = description.world();
0830 vol = description.worldVolume();
0831 context->detectors = det;
0832 }
0833 else if ( object->path.find("/dd/TrackfitGeometry") == 0 ) {
0834 return 0;
0835 }
0836 else if ( object->path.find("/dd/Geometry") == 0 ) {
0837 context->catalogPaths[object->path] = det;
0838 }
0839 else if ( object->path.find("/dd/Structure") == 0 ) {
0840 det = DetElement(object->name,object->type,0);
0841 det.addExtension<DDDBCatalog>(object->addRef());
0842 if ( !object->support.empty() ) {
0843 try {
0844 j = context->catalogPaths.find(object->support);
0845 if ( j != context->catalogPaths.end() ) {
0846 parent_element = (*j).second;
0847 parent_element.add(det);
0848 }
0849 else {
0850 dddb::Catalogs::const_iterator i=geo->catalogPaths.find(object->support);
0851 if ( i != geo->catalogPaths.end() ) {
0852 support = (*i).second;
0853 parent_element = (DetElement::Object*)this->convert(support);
0854 parent_element.add(det);
0855 }
0856 else {
0857 pair<const DDDBCatalog*,string> cat = context->geo->structure->parent(object->support);
0858 if ( cat.first ) {
0859 const DDDBCatalog* c = cat.first;
0860 dddb::Catalogs::const_iterator icc = c->catalogs.find(cat.second);
0861 if ( icc != c->catalogs.end() ) {
0862 support = (*icc).second;
0863 parent_element = (DetElement::Object*)this->convert(support);
0864 parent_element.add(det);
0865 }
0866 }
0867 }
0868 }
0869 }
0870 catch(const std::exception& e) {
0871 printout(ERROR,"CNV<DetElem>","++ EXCEPTION: %s",e.what());
0872 }
0873 }
0874 if ( !parent_element.isValid() ) {
0875 printout(ERROR,"CNV<DetElem>","++ Unknown parent: %s",object->support.c_str());
0876 }
0877 }
0878
0879 if ( det.isValid() ) {
0880 if ( !object->logvol.empty() ) {
0881 CNV<DDDBLogVol> conv(description,param);
0882
0883 vol = conv.get<Volume>(object->logvol);
0884
0885
0886 if ( !object->npath.empty() ) {
0887 PlacedVolume place = context->supportPlacement(parent_element, object->npath);
0888 if ( !place.isValid() ) {
0889 printout(WARNING,"CNV<DetElem>","++ %s Placement: %s",
0890 object->path.c_str(), object->logvol.c_str());
0891 printout(WARNING,"CNV<DetElem>",
0892 "++ --> INVALID PLACEMENT... Vol.N-path: %s",
0893 object->npath.c_str());
0894 }
0895 else {
0896 det.setPlacement(place);
0897 }
0898 }
0899 else {
0900 PlacedVolume par_place = context->placement(parent_element);
0901 Volume par_vol = par_place.volume();
0902 if ( context->volumePlaced(par_vol, vol) ) {
0903 printout(WARNING,"CNV<DetElem>","++ %s : Volume already placed %s -> %s",
0904 det.path().c_str(), par_vol->GetTitle(), vol->GetTitle());
0905 }
0906 PlacedVolume det_place = par_vol.placeVolume(vol);
0907 det.setPlacement(det_place);
0908 }
0909 }
0910 if ( !det.placement().isValid() ) {
0911
0912 }
0913 }
0914 if ( det.isValid() ) {
0915 context->detelements[det] = object;
0916 context->catalogPaths[object->path] = det;
0917 }
0918 for_each(object->logvolrefs.begin(), object->logvolrefs.end(), CNV<DDDBLogVol>(description,param,det.ptr()));
0919 for_each(object->catalogrefs.begin(), object->catalogrefs.end(), *this);
0920
0921 #if 0
0922 for(DDDBCatalog::LvRefs::const_iterator i=object->logvolrefs.begin(); i!=object->logvolrefs.end(); ++i) {
0923 DDDBLogVol* lv = (*i).second;
0924 string lp = object->path+"/"+lv->name;
0925 Volume gv = Context::find(context->volumes, lv);
0926 context->volumePaths[lp] = gv.ptr();
0927 }
0928 #endif
0929
0930 if ( !object->condition.empty() ) {
0931 bool res;
0932 char text[64];
0933 ::snprintf(text,sizeof(text)," %%%lds -> %%s",long(object->condition.length()));
0934 printout(DEBUG,"DDDB","+ Match Align %s -> %s",object->condition.c_str(), object->path.c_str());
0935 printout(DEBUG,"DDDB",text,"",det.path().c_str());
0936 res = context->helper->addConditionEntry(object->condition,det,align::Keys::deltaName);
0937 if ( !res ) {
0938 printout(DEBUG,"DDDB","++ Conditions entry with key:%s already exists!",
0939 object->condition.c_str());
0940 ++context->badassigned_conditions;
0941 }
0942 }
0943 if ( !object->conditioninfo.empty() ) {
0944 bool res;
0945 for( const auto& i : object->conditioninfo ) {
0946 printout(DEBUG,"DDDB","+ Match Cond %s -> %s",i.second.c_str(), object->path.c_str());
0947 res = context->helper->addConditionEntry(i.second, det, i.first);
0948 if ( !res ) {
0949 printout(DEBUG,"DDDB","++ Conditions entry with key:%s already exists!",
0950 i.second.c_str());
0951 ++context->badassigned_conditions;
0952 }
0953 }
0954 }
0955 if ( context->print.detelem ) {
0956 printout(INFO,"CNV<Catalog>","++ Converting catalog %p -> %p [cref:%d/%d lref:%d/%d lv:%s [%p] sup:%s np:%s] %s ",
0957 (void*)object, det.ptr(),
0958 int(object->catalogrefs.size()),
0959 int(object->catalogs.size()),
0960 int(object->logvolrefs.size()),
0961 int(object->logvols.size()),
0962 object->logvol.empty() ? "--" : object->logvol.c_str(),
0963 vol.ptr(),
0964 object->support.empty() ? "--" : object->support.c_str(),
0965 object->npath.empty() ? "--" : object->npath.c_str(),
0966 object->path.c_str());
0967 int cnt = 0;
0968 for( const auto& v : object->catalogrefs ) {
0969 if ( v.second )
0970 printout(INFO,"CNV<DE>:cref","++ DE:%s ref[%2d]: %p -> %s",
0971 object->path.c_str(), cnt, v.second, v.second->c_name());
0972 else
0973 printout(INFO,"CNV<DE>:cref","++ DE:%s ref[%2d]: ??????", object->path.c_str(), cnt);
0974 ++cnt;
0975 }
0976 cnt = 0;
0977 for( const auto& v : object->logvolrefs ) {
0978 DDDBLogVol* lv = v.second;
0979 Volume geoVol = Context::find(context->volumes, lv);
0980 if ( lv )
0981 printout(INFO,"CNV<DE>:lref","++ DE:%s ref[%2d]: %p / %s -> %p [%s]",
0982 object->path.c_str(), cnt, (void*)lv, lv->c_name(),
0983 (void*)geoVol.ptr(), geoVol.isValid() ? geoVol->GetName() : "????");
0984 else
0985 printout(INFO,"CNV<DE>:lref","++ DE:%s ref[%2d]: ??????", object->path.c_str(), cnt);
0986 ++cnt;
0987 }
0988 cnt = 0;
0989 for( const auto& v : object->logvols ) {
0990 DDDBLogVol* lv = v.second;
0991 if ( lv ) {
0992 Volume geoVol = Context::find(context->volumes, lv);
0993 printout(INFO,"CNV<DE>:lvol","++ DE:%s ref[%2d]: %p / %s -> %p [%s]",
0994 object->path.c_str(), cnt, (void*)lv, lv->c_id(),
0995 (void*)geoVol.ptr(), geoVol.isValid() ? geoVol->GetName() : "????");
0996 }
0997 else
0998 printout(INFO,"CNV<DE>:lvol","++ DE:%s ref[%2d]: ??????", object->path.c_str(), cnt);
0999 ++cnt;
1000 }
1001 if ( vol && !object->npath.empty() ) {
1002 for(int i=0; i<vol->GetNdaughters(); ++i) {
1003 TGeoNode* dau = vol->GetNode(i);
1004 printout(INFO,"CNV<DE>:npath","++ DE:%s npath:%s Dau[%2d]: %s",
1005 object->path.c_str(), object->npath.c_str(),
1006 i, dau->GetName());
1007 }
1008 }
1009 }
1010 return det.ptr();
1011 }
1012
1013 template <> void* CNV<dddb>::convert(dddb *obj) const {
1014 Context* context = _param<Context>();
1015 if ( !context->conditions_only ) {
1016 Volume world = description.worldVolume();
1017
1018 for_each(obj->isotopes.begin(), obj->isotopes.end(), cnv<DDDBIsotope>());
1019 printout(INFO,"DDDB2Object","++ Converted %d isotopes.",int(obj->isotopes.size()));
1020 for_each(obj->elements.begin(), obj->elements.end(), cnv<DDDBElement>());
1021 printout(INFO,"DDDB2Object","++ Converted %d elements.",int(obj->elements.size()));
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 if ( obj->top ) {
1032 if ( !context->lvDummy.isValid() ) {
1033 description.manager().SetVisLevel(context->print.max_volume_depth);
1034 context->lvDummy = Volume("Dummy",Box(0.0001,0.0001, 0.0001),description.vacuum());
1035 context->lvDummy.setVisAttributes(description.invisible());
1036 }
1037 if ( !world.isValid() ) {
1038 string top = "/dd/Geometry/LHCb/lvLHCb";
1039 const DDDBLogVol* lv = Context::find(obj->volumePaths,top);
1040 if ( !lv ) {
1041 except("DDDB2dd4hep","++ No World volume defined.");
1042 }
1043 const DDDBShape* s = Context::find(obj->shapes,lv->id);
1044 if ( !s ) {
1045 except("DDDB2dd4hep","++ No Shape for the world volume defined.");
1046 }
1047 obj->world = s->s.box;
1048 }
1049
1050 cnv<DDDBCatalog>().convert(obj->top);
1051 if ( !world.isValid() && description.worldVolume().isValid() ) {
1052 description.endDocument();
1053 }
1054
1055 if ( !context->manager.isValid() ) {
1056 ConditionsManager manager = ConditionsManager::from(description);
1057 manager["PoolType"] = "DD4hep_ConditionsLinearPool";
1058 manager["LoaderType"] = "DD4hep_Conditions_dddb_Loader";
1059 manager["UserPoolType"] = "DD4hep_ConditionsMapUserPool";
1060 manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool";
1061 manager.initialize();
1062 pair<bool,const IOVType*> e = manager.registerIOVType(0, "epoch");
1063 context->manager = manager;
1064 context->epoch = e.second;
1065 }
1066 }
1067 }
1068 if ( !context->manager.isValid() ) {
1069 ConditionsManager manager = ConditionsManager::from(description);
1070 pair<bool,const IOVType*> e = manager.registerIOVType(0, "epoch");
1071 context->manager = manager;
1072 context->epoch = e.second;
1073 }
1074 for_each(obj->conditions.begin(),obj->conditions.end(), cnv<GeoCondition>());
1075
1076 return obj;
1077 }
1078 }
1079
1080
1081 namespace DDDB {
1082 long dddb_2_dd4hep(Detector& description, int , char** ) {
1083 DDDBHelper* helper = description.extension<DDDBHelper>(false);
1084 if ( helper ) {
1085 Context context(description, helper);
1086 CNV<dddb> cnv(description,&context);
1087 cnv(make_pair(string("World"),context.geo));
1088 printout(INFO,"DDDB","+========================= Conversion summary =========================+");
1089 printout(INFO,"DDDB","++ Converted %8d isotopes.", int(context.isotopes.size()));
1090 printout(INFO,"DDDB","++ Converted %8d elements.", int(context.elements.size()));
1091 printout(INFO,"DDDB","++ Converted %8d materials.", int(context.materials.size()));
1092 printout(INFO,"DDDB","++ Converted %8d shapes.", int(context.shapes.size()));
1093 printout(INFO,"DDDB","++ Converted %8d logical volumes.", int(context.volumes.size()));
1094 printout(INFO,"DDDB","++ Converted %8d placements.", int(context.placements.size()));
1095 printout(INFO,"DDDB","++ Converted %8d detector elements.",int(context.detelements.size()));
1096 printout(INFO,"DDDB","++ Converted %8d conditions.",
1097 context.geo ? int(context.geo->conditions.size()) : 0);
1098 printout(INFO,"DDDB","++ MATCHED %8d conditions.", context.matched_conditions);
1099 printout(INFO,"DDDB","++ UNMATCHED %8d conditions. [Could not determine DetElement]",
1100 context.unmatched_conditions);
1101 printout(INFO,"DDDB","++ BADASSIGN %8d conditions. [Could not determine DetElement]",
1102 context.badassigned_conditions);
1103 printout(INFO,"DDDB","++ DELTAS %8d conditions.", context.delta_conditions);
1104 printout(INFO,"DDDB","++ DELTAS %8d (unmatched).", context.unmatched_deltas);
1105 printout(INFO,"DDDB","+======================================================================+");
1106 helper->setDetectorDescription(0);
1107 return 1;
1108 }
1109 except("DDDB","++ No DDDBHelper instance installed. Geometry conversion failed!");
1110 return 1;
1111 }
1112 long dddb_conditions_2_dd4hep(Detector& description, int , char** ) {
1113 DDDBHelper* helper = description.extension<DDDBHelper>(false);
1114 if ( helper ) {
1115 Context context(description, helper);
1116 context.print.condition = false;
1117 context.conditions_only = true;
1118 CNV<dddb> cnv(description,&context);
1119 cnv(make_pair(string(),context.geo));
1120 helper->setDetectorDescription(0);
1121 return 1;
1122 }
1123 except("DDDB","++ No DDDBHelper instance installed. Geometry conversion failed!");
1124 return 1;
1125 }
1126
1127 }
1128 }
1129 DECLARE_APPLY(DDDB_2dd4hep,dddb_2_dd4hep)
1130 DECLARE_APPLY(DDDB_Conditions2dd4hep,dddb_conditions_2_dd4hep)