// AtlasPoolEventDataset.cxx #include "dataset_atlaspool/AtlasPoolEventDataset.h" #include #include #include #include #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" #include "dataset_util/Environment.h" #include "dataset_base/DatasetCreator.h" #include "dataset_id/DatasetId.h" #include "dataset_file/FileManagementSystem.h" #include "dataset_base/SingleFileDataset.h" #include "dataset_atlaspool/DataHeaderList.h" #include "dataset_atlaspool/AtlasClidMap.h" #include "SealBase/SharedLibrary.h" #include "GaudiKernel/GenericAddress.h" #include "SGTools/TransientAddress.h" #include "EventInfo/EventInfo.h" #include "EventInfo/EventID.h" using std::string; using std::vector; using std::ostream; using std::cout; using std::cerr; using std::endl; using std::ofstream; using std::istringstream; using dset::Url; using dset::FileManagementSystem; using dset::Location; using dset::Dataset; using dset::DatasetCreator; using dset::DataHeaderList; using dset::GenericDataset; using dset::SingleFileDataset; using dset::AtlasPoolEventDataset; using dset::AtlasClidMap; typedef std::vector DheList; typedef SingleFileDataset::Name Name; //********************************************************************** // Local data. //********************************************************************** namespace { // For debugging. int verbose = 0; // This is presently defined in AthenaPoolCnvSvc.cxx but we don't want // to bring in that dependency. unsigned char xxxPool_StorageType = 0x47; } // end unnamed namespace //********************************************************************** // Helper functions. //********************************************************************** namespace { // Register promoter. int AtlasPoolEventDataset_xml_stat = GenericDataset:: register_promoter("AtlasPoolEventDataset", dset::promote); // Single-file dataset creator. const Dataset* sfcreate(Url file, Name content, DatasetId pid) { AtlasPoolEventDataset* pdst = new AtlasPoolEventDataset(file, content, false); if ( pid.is_valid() ) { pdst->set_parent_id(pid); } pdst->lock(); return pdst; } // Register this creator. int AtlasPoolEventDataset_sfreg = SingleFileDataset:: register_creator("AtlasPoolEventDataset", sfcreate); } // end unnamed namespace //********************************************************************** // Member functions. //********************************************************************** // Constructor. AtlasPoolEventDataset:: AtlasPoolEventDataset(Url lurl, string datatype, bool locked) { string prefix = "AtlasPoolEventDataset::ctor: "; m_inconsistent = false; set_fulltype("AtlasPoolEventDataset"); set_id(); if ( ! lurl.is_valid() ) { cerr << prefix << "Invalid input URL:" << endl; cerr << " " << lurl << endl; set_error(11); return; } // Resolve the URL. FileManagementSystem& fms = FileManagementSystem::default_instance(); Url purl = fms.get(lurl); if ( ! purl.is_valid() ) { cerr << prefix << "Unable to resolve input URL:" << endl; cerr << " " << lurl << endl; cerr << fms << endl; set_error(12); return; } // Set the location. Location loc; loc.files().push_back(lurl); set_location(loc); assert( location().files().size() == 1 ); // Set the content. // Loop over event headers. DataHeaderList dhl(purl.to_string()); DataHeaderList::Iterator idh = dhl.iterator(); bool first_event = true; ContentIdList cids; ContentIdList dups; EventIdList eids; // Determine if we should use existing event ID's or generate new ID's. string snewids = Environment::current().value("DIAL_APEDS_ASSIGN_EVENT_IDS"); bool assign_evids = snewids.size(); int assigned_run = 0; int assigned_event = 0; // To set a unique run number, we count on the ATLAS convention that the // file name has unique ID UID with format fname = *._UID.* // or the dial convention fname = *dial_lfUID if ( assign_evids ) { string fname = purl.to_string(); string srun; // First try ATLAS convention. string::size_type ipos = fname.find("._"); if ( ipos != string::npos ) { string::size_type jpos = fname.find(".", ipos+2); if ( jpos != string::npos ) { srun = fname.substr(ipos+2, jpos-ipos+2); } } // Then DIAL convention. if ( ! srun.size() ) { ipos = fname.find("dial_lf"); srun = fname.substr(ipos+7); } istringstream ssrun(srun); ssrun >> assigned_run; if ( assigned_run <= 0 ) { set_error(19); cerr << "AtlasPoolEventDataset: " << "Unable to extract run from purl name" << endl; cerr << " " << fname << endl; return; } cout << "AtlasPoolEventDataset:" << endl; cout << " File " << fname << endl; cout << " assigned run number " << assigned_run << endl; cout << " Unset DIAL_APEDS_ASSIGN_EVENT_IDS to prevent reassignment." << endl; } while ( idh.next() ) { DataHeader& dh = *idh; int run = 0; int evt = 0; ContentIdList newcids; // Loop over data header elements. for ( DheList::const_iterator idhe=dh.begin(); idhe!=dh.end(); ++idhe ) { const DataHeaderElement& dhe = *idhe; SG::TransientAddress* ptadd = dhe.getAddress(xxxPool_StorageType); assert( ptadd != 0 ); // Fetch type and key. CLID clid = ptadd->clID(); string key = ptadd->name(); AtlasClidMap::Name clname = AtlasClidMap::name(clid); if ( clname == "" ) { cerr << "--- Unable to find name for class ID " << clid << endl; set_error(12); break; } // If EventInfo, fetch run and event numbers. if ( clname == "EventInfo" ) { assert( run==0 && evt==0 ); IOpaqueAddress* pio = ptadd->address(); assert( pio != 0 ); string token = *(pio->par()); //string token = *(pio->par()+1); // For ATLAS 8.1.0 pool::Ref pevi(dhl.data_service(), token); run = pevi->event_ID()->run_number(); evt = pevi->event_ID()->event_number(); //std::cout << "--- Run-event = " << run << " " << evt << std::endl; // Skip data headers. } else if ( clname == "DataHeader" ) { // Record all other content. } else { //std::cout << "--- Type-key = " << clname << " " << key << std::endl; ContentId cid(clname, key); if ( ! cid.is_valid() ) { cerr << "--- Unknown type-key = " << clname << "-" << key << std::endl; set_error(13); break; } ContentIdList::const_iterator icid = newcids.find(cid); if ( icid == newcids.end() ) { newcids.insert(cid); } else { ContentIdList::const_iterator idup = dups.find(cid); if ( idup != dups.end() ) { dups.insert(cid); cerr << "--- Duplicate type-key = " << clname << "-" << key << std::endl; } //02dec04 -- apparently this is ok //cerr << newcids << endl; //set_error(14); //break; } } } if ( ! is_valid() ) break; // First event copy the content. if ( first_event ) { cids = newcids; } else { if ( newcids != cids ) { // Allow inconsisten content if DIAL_ALLOW_INCONSISTENT_CONTENT // is set to a nonblank value. static bool envallow = Environment::current(). value("DIAL_ALLOW_INCONSISTENT_CONTENT").size(); // First time broadcast an error. if ( ! m_inconsistent ) { string action = "Merging"; if ( ! envallow ) action = "Exiting because of"; m_inconsistent = true; ofstream fout("AtlasPoolEventDataset.log"); fout << "Error in AtlasPoolEventDataset: inconsistent content"; fout << endl << endl; fout << cids << endl; fout << endl; fout << newcids << endl; if ( envallow ) { cerr << "Merging inconsistent content"; cerr << "--see AtlasPoolEventDataset.log" << endl; cerr << " Unset DIAL_ALLOW_INCONSISTENT_CONTENT to disallow"; cerr << " inconsistent content.\n"; cerr << " Future occurences will not be reported" << endl; } else { cerr << "AtlasPoolEventDataset: Found inconsistent content.\n"; cerr << " See AtlasPoolEventDataset.log for details.\n"; cerr << " Set DIAL_ALLOW_INCONSISTENT_CONTENT to allow"; cerr << " inconsistent content.\n"; cerr << " Exiting due to this error." << endl; } } if ( ! envallow ) { set_error(15); break; } for ( ContentIdList::const_iterator inew=newcids.begin(); inew!=newcids.end(); ++inew ) { cids.insert(*inew); } } } // Record the event ID. if ( assign_evids ) { EventId eid(assigned_run, ++assigned_event); assert( eid.is_valid() ); eids.insert(eid); } else { EventId eid(run, evt); if ( eids.contains(eid) ) { set_error(16); break; } eids.insert(eid); } // Loop over input data header elements. //for ( DheList::const_iterator idhe=dh.beginInputDataHeader(); // idhe!=dh.endInputDataHeader(); ++idhe ) { first_event = false; } if ( is_valid() ) { Content con("AtlasPoolEventDataset", datatype, cids, eids); int stat = set_content(con); assert( con.size() == 1 ); set_evstate_first(); assert( stat == 0 ); } // Lock the dataset. if ( locked ) lock(); } //********************************************************************** // Generic dataset constructor. AtlasPoolEventDataset::AtlasPoolEventDataset(const GenericDataset& gen) : GenericDataset(gen) { if ( fulltype() != "AtlasPoolEventDataset" ) set_error(11); } //********************************************************************** // Destructor. AtlasPoolEventDataset::~AtlasPoolEventDataset() { } //********************************************************************** // Select content. // Not yet supported. // We might create a new event collection. int AtlasPoolEventDataset::select(const Content&) { return 1; } //**********************************************************************