// // $Id: geometry_management.cpp,v 1.10 2007/11/05 19:46:07 snyder Exp $ // // File: geometry_management.cpp // Purpose: // Created: 11-MAY-1998 John Hobbs // // $Revision: 1.10 $ // // #include "geometry_management/geometry_management.hpp" #include "ErrorLogger/ErrorLog.h" #include "d0_mcpp/MCKineChunk.hpp" #include "edm/AbsTSelector.hpp" #include "edm/Event.hpp" #include "edm/TKey.hpp" #include "framework/Registry.hpp" #include "framework/Result.hpp" #include "framework/interfaces/RunNumber.hpp" #include "geometry_db/GeometryVersionRecord.hpp" #include "geometry_management/GeometryManager.hpp" #include "prod_history/HistoryChunk.hpp" #include "prod_history/HistorySelector.hpp" #include "rcp/RCP.hpp" #include "smtdata/SmtDataChunk.hpp" #include using namespace fwk; using namespace edm; using namespace std; // Global definitions static ErrorLog theLog; // Define a chunk selector which looks for d0Sim or d0gstar prod_history class MCHistorySel: public AbsTSelector { public: MCHistorySel(const string theProg): _theProg(theProg) {} bool match(const HistoryChunk& chunk) const { string progname = chunk.program(); return progname == _theProg; } AbsTSelector* cloneT() const { return new MCHistorySel(_theProg); } private: string _theProg; }; // Define a function to extract the smt data chunk version. This is passed // to the silicon channel geometer to implement version checking. This // introduces a physical coupling to the silicon_geometry. Sorry, dudes #include "silicon_geometry/channel/SiChannelGeometer.hpp" #include "smtdata/SmtDataChunk.hpp" static int smt_data_version(const edm::Event &anEvt) { edm::TKey key; edm::THandle chunk = key.find(anEvt); if ( !chunk.isValid() ) return -1; else return chunk->version(); } // Constructors/Destructors geometry_management::geometry_management(Context* context): fwk::Package(context), fwk::Decide(context) // // Purpose: Initialize the geometry package. This must include all instructions // necessary to implement run dependence and geometry sources. Very little // is actually handled in the package. Most of the work is done by the // framework independent GeometryManager. // Arguements: // Returns: // { d0om_init("geometry_management"); RCP myRCP = packageRCP(); if( GeometryManager::make_instance(myRCP,0) ) _theManager = GeometryManager::get_instance(); else ERRLOGTO(theLog,ELfatal,"geometry_management") << ", instantating manager." << endmsg; // Well, since SMT has to have the event to decide versions, we'll hard // code a call to the channel geometer here. Bummer, huh SiChannelGeometer *siCG = SiChannelGeometer::get_instance(); if( siCG ) siCG->smt_data_version_function(smt_data_version); } Result geometry_management::makeDecision(const edm::Event& event, fwk::WorkQueue &wq) // // Purpose: Pass the event number to the GeometryManager so it can decide // if there is any action to be taken. // Arguements: // Returns: // { // These are passed in. GeometryVersionRecord::recType rt(GeometryVersionRecord::UNKNOWN); int runnum=event.collisionID().runNumber(); // Figure out if it's data or MC. Right now the only way is by looking // for a bunch of chunks -- and it's not even unique... // All MC has an MCKINE chunk or a HistoryChunk with d0gstar or d0sim... const TKey mcKey; const TKey phKey(MCHistorySel("d0gstar")); const TKey simKey(MCHistorySel("D0Sim")); const TKey recoKey(MCHistorySel("D0reco")); THandle mckine = mcKey.find(event); THandle mcprod = phKey.find(event); THandle simprod = simKey.find(event); THandle recoprod = recoKey.find(event); // and build a vector of all the version information. If any of pmc, psim // or preco are missing, put in p00.00.00 string vnull("p00.00.00"); vector vtags(3); if( mcprod.cptr() ) vtags[0]=mcprod->prod_version(); else vtags[0]=vnull; if( simprod.cptr() ) vtags[1]=simprod->prod_version(); else vtags[1]=vnull; if( recoprod.cptr() ) vtags[2]=recoprod->prod_version(); else vtags[2]=vnull; // Now massage to get rid of outdated pmc, psim and preco release tags. // Arbitrarily decide to convert them to the 'modern' format, pii.jj.kk const string p("p"),pmc("pmc"),psim("psim"),preco("preco"); if( vtags[0].substr(0,3) == pmc ) vtags[0] = p + vtags[0].substr(3,8); if( vtags[1].substr(0,4) == psim ) vtags[1] = p + vtags[1].substr(4,8); if( vtags[2].substr(0,5) == preco ) vtags[2] = p + vtags[2].substr(5,8); // Decide if it's data or MC. bool data = !HistorySelector::is_monte_carlo(event); //bool data = !mckine.cptr() && !mcprod.cptr() && !simprod.cptr(); // Notify the real code for data (easy)... if( data ) rt = GeometryVersionRecord::DATA; else rt = GeometryVersionRecord::MC; if (! (data && runnum < 100000) ) { // Run 2 started with run number 100000. // Run numbers less than that are not valid for data. // read_event_daq uses such invalid run numbers as flags --- // but it turns out they can escape. As a workaround, filter them // out here. // A valid run no. _theManager->check_geometry(rt,runnum,vtags,&event); } return(Result::success); } fwk::Result geometry_management::makeDecision(fwk::WorkQueue& wq) { return Result::success; } string geometry_management::packageName() const // // Purpose: Return the (standardized) package name. // { return package_name(); } // and do it again, this time always accessible. string geometry_management::package_name() { return "geometry_management"; } string geometry_management::version() { return "$Name: v01-00-10"; } // Register this package with the Framwork FWK_REGISTRY_IMPL(geometry_management, "$Name: v01-00-10")