diff --git a/DDCore/include/DD4hep/Printout.h b/DDCore/include/DD4hep/Printout.h index 9eee1dbb0d334337bf2618391d46c4b84c4681ee..d143b3d76eed642548d9e0abdf4bc3a38d8ddd03 100644 --- a/DDCore/include/DD4hep/Printout.h +++ b/DDCore/include/DD4hep/Printout.h @@ -16,8 +16,9 @@ // C/C++ include files #include <cstdio> #include <cstdlib> -#include <iostream> #include <map> +#include <string> +#include <iostream> /* * DD4hep namespace declaration @@ -54,6 +55,30 @@ namespace DD4hep { */ int printout(PrintLevel severity, const char* src, const char* fmt, ...); + /** Calls the display action + * @arg severity [int,read-only] Display severity flag (see enum) + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ + int printout(PrintLevel severity, const std::string& src, const char* fmt, ...); + + /** Calls the display action + * @arg severity [int,read-only] Display severity flag (see enum) + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ + int printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...); + + /** Calls the display action + * @arg severity [int,read-only] Display severity flag (see enum) + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ + int printout(PrintLevel severity, const char* src, const std::string& fmt, ...); + /// Set new print level. Returns the old print level PrintLevel setPrintLevel(PrintLevel new_level); diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h index e6732bf82a0bb1322c776bb253782c706b701400..f5ea1784317c5774f5bcd34f9ca34255cff136f4 100644 --- a/DDCore/include/DD4hep/VolumeManager.h +++ b/DDCore/include/DD4hep/VolumeManager.h @@ -238,7 +238,7 @@ namespace DD4hep { * already created hits which have a VolumeID attached. */ /// Lookup the context, which belongs to a registered physical volume. - Context* lookupContext(VolumeID volume_id) const throw(); + Context* lookupContext(VolumeID volume_id) const; /// Lookup a physical (placed) volume identified by its 64 bit hit ID PlacedVolume lookupPlacement(VolumeID volume_id) const; /// Lookup a top level subdetector detector element according to a contained 64 bit hit ID diff --git a/DDCore/src/Printout.cpp b/DDCore/src/Printout.cpp index 33b83905954837ad5c9feeba3d3c75ef9efdc3a3..0037fa1885bc8bbb8923ccbe5e8397a08186d1a5 100644 --- a/DDCore/src/Printout.cpp +++ b/DDCore/src/Printout.cpp @@ -26,6 +26,7 @@ static DD4hep::output_function_t print_func = _the_printer; /** Calls the display action * @arg severity [int,read-only] Display severity flag + * @arg src [string,read-only] Information source (component, etc.) * @arg fmt [string,read-only] Format string for ellipsis args * @return Status code indicating success or failure */ @@ -43,6 +44,66 @@ int DD4hep::printout(PrintLevel severity, const char* src, const char* fmt, ...) return 1; } +/** Calls the display action + * @arg severity [int,read-only] Display severity flag + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ +int DD4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, ...) { + if ( severity >= print_lvl ) { // receives: + va_list args; // - the log level + va_start( args, fmt); // - a standard C formatted + char str[4096]; // string (like printf) + size_t len = vsnprintf(str,sizeof(str)-2,fmt,args); + va_end (args); + str[len] = '\n'; + str[len+1] = '\0'; + print_func(print_arg,severity,src.c_str(),str); + } + return 1; +} + + +/** Calls the display action + * @arg severity [int,read-only] Display severity flag + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ +int DD4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, ...) { + if ( severity >= print_lvl ) { // receives: + va_list args; // - the log level + va_start( args, fmt); // - a standard C formatted + char str[4096]; // string (like printf) + size_t len = vsnprintf(str,sizeof(str)-2,fmt.c_str(),args); + va_end (args); + str[len] = '\n'; + str[len+1] = '\0'; + print_func(print_arg,severity,src,str); + } + return 1; +} + +/** Calls the display action + * @arg severity [int,read-only] Display severity flag + * @arg src [string,read-only] Information source (component, etc.) + * @arg fmt [string,read-only] Format string for ellipsis args + * @return Status code indicating success or failure + */ +int DD4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...) { + if ( severity >= print_lvl ) { // receives: + va_list args; // - the log level + va_start( args, fmt); // - a standard C formatted + char str[4096]; // string (like printf) + size_t len = vsnprintf(str,sizeof(str)-2,fmt.c_str(),args); + va_end (args); + str[len] = '\n'; + str[len+1] = '\0'; + print_func(print_arg,severity,src.c_str(),str); + } + return 1; +} /// Set new print level. Returns the old print level DD4hep::PrintLevel DD4hep::setPrintLevel(PrintLevel new_level) { diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index b19bb806247313c3dead4c7460746db34f39a3d2..db361fa8e399b6c24d41d3a5ff1df0bf627e48e1 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -12,6 +12,7 @@ #include "DD4hep/LCDD.h" // C/C++ includes +#include <set> #include <cmath> #include <sstream> #include <iomanip> @@ -29,64 +30,27 @@ namespace { typedef VolumeManager::VolumeID VolumeID; typedef vector<const TGeoNode*> Chain; - struct DetCtxt { - DetElement detector; - Chain chain; - SensitiveDetector sd; - DetCtxt() {} - ~DetCtxt() {} - }; - typedef map<TNamed*,DetCtxt*> DetContext; /// Reference to the LCDD instance LCDD& m_lcdd; /// Reference to the volume manager to be populated VolumeManager m_volManager; - /// Flag - bool m_add; - - DetContext m_detContext; + /// Set of already added entries + set<VolumeID> m_entries; /// Default constructor - Populator(LCDD& lcdd, VolumeManager vm) : m_lcdd(lcdd), m_volManager(vm), m_add(true) {} + Populator(LCDD& lcdd, VolumeManager vm) : m_lcdd(lcdd), m_volManager(vm) {} /// Populate the Volume manager - void populate(DetElement e, bool add=true) { - m_add = add; + void populate(DetElement e) { const DetElement::Children& c = e.children(); for(DetElement::Children::const_iterator i=c.begin(); i!=c.end(); ++i) { DetElement de = (*i).second; PlacedVolume pv = de.placement(); if ( pv.isValid() ) { Chain chain; + SensitiveDetector sd; PlacedVolume::VolIDs ids; - m_detContext.clear(); - scanPhysicalVolume(de, de, pv, ids, chain); - if ( add ) { - for(DetContext::const_iterator di=m_detContext.begin(); di != m_detContext.end(); ++di) { - Chain det_chain; - PlacedVolume::VolIDs ids; - DetElement det = (*di).second->detector; - const Chain& chain = (*di).second->chain; - if ( !det.parent().isValid() ) continue; - for(Chain::const_iterator ci=chain.begin(); ci!=chain.end(); ++ci) { - PlacedVolume pv = Ref_t(*ci); - det_chain.push_back(*ci); - ids.PlacedVolume::VolIDs::Base::insert(ids.end(),pv.volIDs().begin(),pv.volIDs().end()); - if ( pv.ptr() == det.placement().ptr() ) break; - } - if ( !ids.empty() ) { - stringstream log; - IDDescriptor iddesc = (*di).second->sd.readout().idSpec(); - pair<VolumeID,VolumeID> code = encoding(iddesc, ids); - log << det.path() << " encoding:" << code.first << "," << code.second << " ids:"; - for(size_t m=0; m<ids.size(); ++m) - log << ids[m].first << "=" << ids[m].second << " "; - printout(DEBUG,"VolumeManager","++ Add DetElements:%s",log.str().c_str()); - add_entry((*di).second->sd, de, det, det.placement().ptr(), ids, det_chain); - } - } - } - for(DetContext::const_iterator di=m_detContext.begin(); di != m_detContext.end(); ++di) - delete (*di).second; + m_entries.clear(); + scanPhysicalVolume(de, de, pv, ids, sd, chain); continue; } printout(WARNING,"VolumeManager","++ Detector element %s of type %s has no placement.", @@ -109,25 +73,21 @@ namespace { } /// Scan a single physical volume and look for sensitive elements below size_t scanPhysicalVolume(DetElement parent, DetElement e, PlacedVolume pv, - PlacedVolume::VolIDs ids, Chain& chain) + PlacedVolume::VolIDs ids, SensitiveDetector& sd, Chain& chain) { const TGeoNode* node = pv.ptr(); size_t count = 0; if ( node ) { Volume vol = pv.volume(); chain.push_back(node); - ids.PlacedVolume::VolIDs::Base::insert(ids.end(),pv.volIDs().begin(),pv.volIDs().end()); + PlacedVolume::VolIDs pv_ids = pv.volIDs(); + ids.PlacedVolume::VolIDs::Base::insert(ids.end(),pv_ids.begin(),pv_ids.end()); if ( vol.isSensitive() ) { - SensitiveDetector sd = vol.sensitiveDetector(); - Readout ro = sd.readout(); + sd = vol.sensitiveDetector(); + Readout ro = sd.readout(); if ( ro.isValid() ) { - if ( m_add ) { - add_entry(parent, e, node, ids, chain); - ++count; - } - else { - find_entry(parent, e, node, ids, chain); - } + add_entry(sd, parent, e, node, ids, chain); + ++count; } else { printout(WARNING,"VolumeManager", @@ -143,10 +103,13 @@ namespace { DetElement de_dau = findElt(e,daughter); if ( de_dau.isValid() ) { Chain dau_chain; - cnt = scanPhysicalVolume(parent, de_dau, pv_dau, ids, dau_chain); + cnt = scanPhysicalVolume(parent, de_dau, pv_dau, ids, sd, dau_chain); } else { - cnt = scanPhysicalVolume(parent, e, pv_dau, ids, chain); + cnt = scanPhysicalVolume(parent, e, pv_dau, ids, sd, chain); + } + if ( count == 0 && cnt>0 && !pv_ids.empty() ) { + add_entry(sd, parent, e, node, ids, chain); } count += cnt; } @@ -174,7 +137,7 @@ namespace { } void add_entry(DetElement parent, DetElement e,const TGeoNode* n, - const PlacedVolume::VolIDs& ids, const Chain& nodes) + const PlacedVolume::VolIDs& ids, const Chain& nodes) { Volume vol = PlacedVolume(n).volume(); SensitiveDetector sd = vol.sensitiveDetector(); @@ -190,36 +153,29 @@ namespace { VolumeManager section = m_volManager.addSubdetector(parent,ro); pair<VolumeID,VolumeID> code = encoding(iddesc, ids); - // This is the block, we effectively have to save for each physical volume with a VolID - VolumeManager::Context* context = new VolumeManager::Context; - DetElement::Object& o = parent._data(); - context->identifier = code.first; - context->mask = code.second; - context->detector = parent; - context->element = e; - context->placement = Ref_t(n); - context->volID = ids; - context->path = nodes; - for(size_t i=nodes.size(); i>1; --i) { // Omit the placement of the parent DetElement - TGeoMatrix* m = nodes[i-1]->GetMatrix(); - context->toWorld.MultiplyLeft(m); - } - context->toDetector = context->toWorld; - context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); - context->toWorld.MultiplyLeft(o.worldTransformation()); - if ( parent.path().find("HcalBarrel") != string::npos ) print_node(sd,parent,e,n,ids,nodes); - if ( !section.adoptPlacement(context) ) { - print_node(sd,parent,e,n,ids,nodes); - } - if ( e.placement().ptr() != n ) { - DetContext::const_iterator di = m_detContext.find(e.ptr()); - if ( di == m_detContext.end() ) { - DetCtxt* c = new DetCtxt(); - c->detector = e; - c->chain = nodes; - c->sd = sd; - m_detContext[e.ptr()] = c; + if ( m_entries.find(code.first) == m_entries.end() ) { + // This is the block, we effectively have to save for each physical volume with a VolID + VolumeManager::Context* context = new VolumeManager::Context; + DetElement::Object& o = parent._data(); + context->identifier = code.first; + context->mask = code.second; + context->detector = parent; + context->element = e; + context->placement = Ref_t(n); + context->volID = ids; + context->path = nodes; + for(size_t i=nodes.size(); i>1; --i) { // Omit the placement of the parent DetElement + TGeoMatrix* m = nodes[i-1]->GetMatrix(); + context->toWorld.MultiplyLeft(m); } + context->toDetector = context->toWorld; + context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); + context->toWorld.MultiplyLeft(o.worldTransformation()); + //if ( parent.id() == 8 ) print_node(sd,parent,e,n,ids,nodes); + if ( !section.adoptPlacement(context) ) { + print_node(sd,parent,e,n,ids,nodes); + } + m_entries.insert(code.first); } } void find_entry(DetElement parent, DetElement e,const TGeoNode* n, @@ -287,7 +243,7 @@ namespace { pair<VolumeID,VolumeID> code = encoding(en, ids); IDDescriptor::VolumeID volume_id = code.first; - if ( !sensitive ) return; + //if ( !sensitive ) return; ++s_count; stringstream log; log << s_count << ": " << e.name() << " de:" << e.ptr() << " ro:" << ro.ptr() @@ -345,6 +301,10 @@ VolumeManager::Context* VolumeManager::Object::search(const VolIdentifier& id) Volumes::const_iterator i = volumes.find(id); if ( i != volumes.end() ) context = (*i).second; + else if ( sysID == 8 ) { + //for(i=volumes.begin(); i!=volumes.end();++i) + // cout << (void*)(*i).first << " " << (*i).second->placement.name() << endl; + } return context; } @@ -368,7 +328,6 @@ VolumeManager::VolumeManager(LCDD& lcdd, const string& nam, DetElement elt, Read o.top = ptr; o.flags = flags; p.populate(elt); - p.populate(elt,false); } } @@ -487,7 +446,7 @@ bool VolumeManager::adoptPlacement(VolumeID sys_id, Context* context) { #endif if ( i == o.volumes.end() ) { o.volumes[vid] = context; - o.phys_volumes[pv.ptr()] = context; + //o.phys_volumes[pv.ptr()] = context; err << "Inserted new volume:" << setw(6) << left << o.volumes.size() << " Ptr:" << (void*)context->placement.ptr() << " [" << context->placement.name() << "]" @@ -556,7 +515,7 @@ bool VolumeManager::adoptPlacement(Context* context) { } /// Lookup the context, which belongs to a registered physical volume. -VolumeManager::Context* VolumeManager::lookupContext(VolumeID volume_id) const throw() { +VolumeManager::Context* VolumeManager::lookupContext(VolumeID volume_id) const { if ( isValid() ) { Context* c = 0; const Object& o = _data(); @@ -576,7 +535,10 @@ VolumeManager::Context* VolumeManager::lookupContext(VolumeID volume_id) const return c; } } - throw runtime_error("VolumeManager::lookupContext: Failed to search Volume context [Unknown identifier]"); + stringstream err; + err << "VolumeManager::lookupContext: Failed to search Volume context [Unknown identifier]" + << (void*)volume_id; + throw runtime_error(err.str()); } throw runtime_error("VolumeManager::lookupContext: Failed to search Volume context [Invalid Manager Handle]"); } diff --git a/DDExamples/UtilityApps/src/plugin_runner.cpp b/DDExamples/UtilityApps/src/plugin_runner.cpp index b6eb0bd1de80c31aa4ec9e75c9d86e221b3f9a0f..6fc2963a8c7624214c96ca958f9d6196034d426d 100644 --- a/DDExamples/UtilityApps/src/plugin_runner.cpp +++ b/DDExamples/UtilityApps/src/plugin_runner.cpp @@ -31,6 +31,8 @@ int main(int argc,char** argv) { bool volmgr = false; bool destroy = false; vector<char*> geo_files; + vector<char*> arg; + arg.push_back("plugin_runner"); for(int i=1; i<argc;++i) { if ( argv[i][0]=='-' ) { if ( strncmp(argv[i],"-input",2)==0 ) @@ -42,7 +44,7 @@ int main(int argc,char** argv) { else if ( strncmp(argv[i],"-volmgr",2)==0 ) volmgr = true; else - usage(); + arg.push_back(argv[i]); } else { usage(); @@ -50,14 +52,14 @@ int main(int argc,char** argv) { } if ( geo_files.empty() || plugin.empty() ) usage(); - + arg.push_back(0); LCDD& lcdd = dd4hep_instance(); // Load compact files run_plugin(lcdd,"DD4hepCompactLoader",int(geo_files.size()),&geo_files[0]); // Create volume manager and populate it required if ( volmgr ) run_plugin(lcdd,"DD4hepVolumeManager",0,0); // Execute plugin - run_plugin(lcdd,plugin.c_str(),0,0); + run_plugin(lcdd,plugin.c_str(),(int)(arg.size()-1),&arg[0]); if ( destroy ) delete &lcdd; return 0; }