| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

SmartFilterAlg.cc

Go to the documentation of this file.
00001 #include "SmartFilterAlg.h"
00002 
00003 #include "DybKernel/ObjectReg.h"
00004 #include "DybKernel/IRegistrationSequence.h"
00005 #include "Event/HeaderObject.h"
00006 #include "Event/RegistrationSequence.h"
00007 #include "GaudiKernel/DataObject.h"
00008 #include "DataUtilities/DybArchiveList.h"
00009 #include "GaudiKernel/IRndmGenSvc.h"
00010 #include "GaudiKernel/RndmGenerators.h"
00011 
00012 #include <algorithm>
00013 
00014 SmartFilterAlg::SmartFilterAlg(const std::string& name, ISvcLocator* pSvcLocator)
00015   : GaudiAlgorithm(name,pSvcLocator),
00016     m_keepParents(),
00017     m_keepChildren(),
00018     m_archiveSvc(0),
00019     m_keptHeaders(),
00020     m_uniform(0)
00021 {
00022   declareProperty("ClearAll", 
00023                   m_clearAll=false,
00024                   "Clear all data from output");
00025 
00026   declareProperty("KeepLocation", 
00027                   m_keepLocation="",
00028                   "Location in TES where filter begins");
00029 
00030   declareProperty("Prescale", 
00031                   m_prescale=-1,
00032                   "Prescale fraction for filtering");
00033 
00034   declareProperty("KeepAllParents", 
00035                   m_keepAllParents=false,
00036                   "Keep all parent headers of filtered data");
00037 
00038   declareProperty("KeepParents", 
00039                   m_keepParents,
00040                   "List of specific parent headers to keep");
00041 
00042   declareProperty("ParentPrescale", 
00043                   m_parentPrescale=-1,
00044                   "Additional prescale applied to parent headers");
00045 
00046   declareProperty("KeepAllChildren", 
00047                   m_keepAllChildren=false,
00048                   "Keep all children headers of filtered data");
00049 
00050   declareProperty("KeepChildren", 
00051                   m_keepChildren,
00052                   "List of specific child headers to keep");
00053 
00054   declareProperty("ChildrenPrescale", 
00055                   m_childrenPrescale=-1,
00056                   "Additional prescale applied to child headers");
00057   
00058   declareProperty("MaxKeptHistory", 
00059                   m_maxKeptHistory=5,
00060                   "Maximum number of filtered events to search for children");
00061 }
00062 
00063 SmartFilterAlg::~SmartFilterAlg()
00064 {
00065 }
00066 
00067 StatusCode SmartFilterAlg::initialize()
00068 {
00069 
00070   StatusCode sc = service("EventDataArchiveSvc",m_archiveSvc);
00071   if(sc.isFailure()){
00072     warning() << "Failed to access the Archive event store" << endreq;
00073   }
00074 
00075   if(m_prescale>0 || m_parentPrescale>0 || m_childrenPrescale>0){
00076     // Initialize random number service if needed
00077     IRndmGenSvc *rgs = 0;
00078     StatusCode sc;
00079     sc = service("RndmGenSvc",rgs,true); 
00080     if( sc.isFailure() ){
00081       error() << "Failed to get random service" << endreq;
00082       return StatusCode::FAILURE;        
00083     }
00084     m_uniform = new Rndm::Numbers();
00085     sc = m_uniform->initialize(rgs, Rndm::Flat(0,1));
00086     if( sc.isFailure() ) {
00087       error() << "Failed to initialize uniform random numbers" << endreq;
00088       return StatusCode::FAILURE;
00089     }
00090   }
00091 
00092   return StatusCode::SUCCESS;
00093 }
00094 
00095 StatusCode SmartFilterAlg::execute()
00096 {
00097   StatusCode sc;
00098 
00099   DayaBay::RegistrationSequence* regSeq
00100     = get<DayaBay::RegistrationSequence>("/Event/RegistrationSequence");
00101   
00102   IRegistrationSequence::Registrations& registrations 
00103     = const_cast<IRegistrationSequence::Registrations&>(regSeq->registrations()); 
00104   IRegistrationSequence::Registrations::iterator it, 
00105     done = registrations.end();
00106 
00107   // Clear all data, if requested
00108   if(m_clearAll){
00109     for (it = registrations.begin(); it != done; ++it) {
00110       it->setStore(false);
00111     }
00112   }
00113 
00114   if(m_keepLocation.size()==0){
00115     // No more filtering to do...
00116     return StatusCode::SUCCESS;
00117   }
00118 
00119   // Loop over registrations, and look for the header we are filtering
00120   for (it = registrations.begin(); it != done; ++it) {
00121     DataObject* dobj = it->object();
00122     debug() << "Checking object: " << dobj->registry()->identifier() << endreq;
00123     if(dobj->registry()->identifier() != m_keepLocation){
00124       // Not the path we are interested in...
00125       continue;
00126     }
00127     double rand = 0;
00128     if(m_uniform){
00129       rand = (*m_uniform)();
00130     }
00131     if(m_prescale>0 && m_prescale<rand){
00132       // Don't keep this one, prescaled
00133       continue;
00134     }
00135     // We are keeping this entry
00136     it->setStore(true);
00137     debug() << "Keeping: " << dobj->registry()->identifier() << endreq;
00138     
00139     // Look for parent headers to keep
00140     if(m_keepAllParents || m_keepParents.size()>0){
00141       double effectiveParentPrescale = m_parentPrescale;
00142       if(m_prescale>0 && m_parentPrescale>0){
00143         effectiveParentPrescale = m_prescale*m_parentPrescale;
00144       }
00145       if( m_parentPrescale<0 || rand < effectiveParentPrescale ){
00146         sc = this->processParentHeaders(dobj);
00147       }
00148     }
00149     
00150     // Keep a reference so we can check children
00151     if( m_keepAllChildren || m_keepChildren.size()>0 ){      
00152       double effectiveChildrenPrescale = m_childrenPrescale;
00153       if(m_prescale>0 && m_childrenPrescale>0){
00154         effectiveChildrenPrescale = m_prescale*m_childrenPrescale;
00155       }
00156       if( m_childrenPrescale<0 || rand < effectiveChildrenPrescale ){
00157         dobj->addRef();
00158         m_keptHeaders.push_back(dobj);
00159         if(m_keptHeaders.size() > m_maxKeptHistory){
00160           // Remove stale header
00161           m_keptHeaders.front()->release();
00162           m_keptHeaders.pop_front();
00163         }
00164       }
00165     }
00166   } // end loop over registrations
00167 
00168   if( m_keepAllChildren || m_keepChildren.size()>0 ) {
00169     // Loop over registrations again, and look for child headers
00170     for (it = registrations.begin(); it != done; ++it) {
00171       DataObject* childObj = it->object();
00172       debug() << "Checking child: " << childObj->registry()->identifier()
00173              << endreq;
00174       if( !m_keepAllChildren
00175           && std::find(m_keepChildren.begin(),
00176                        m_keepChildren.end(),
00177                        childObj->registry()->identifier() ) 
00178           == m_keepChildren.end() ){
00179         // Not an interesting child
00180         continue;
00181       }
00182       // Is this a child?
00183       if( !this->isChild( childObj ) ) continue;
00184       // This is a child to keep
00185       it->setStore(true);
00186       debug() << "Keeping child: " << childObj->registry()->identifier() 
00187              << endreq;
00188     } // end loop over child candidates
00189   }
00190 
00191   return StatusCode::SUCCESS;
00192 }
00193 
00194 StatusCode SmartFilterAlg::finalize()
00195 {
00196   if(m_archiveSvc){
00197     m_archiveSvc->release();
00198   }
00199   if(m_uniform){
00200     delete m_uniform;
00201     m_uniform=0;
00202   }
00203   return this->GaudiAlgorithm::finalize();
00204 }
00205 
00206 
00207 StatusCode SmartFilterAlg::processParentHeaders(DataObject* dobj)
00208 {
00209   // Helper function to traverse and filter parent headers
00210   DayaBay::IHeader* header = dynamic_cast<DayaBay::IHeader*>(dobj);
00211   if(!header){
00212     error() << "Invalid data object" << endreq;
00213     return StatusCode::FAILURE;
00214   }
00215   // Loop over input headers
00216   for(unsigned int ihIdx=0;ihIdx<header->inputHeaders().size();ihIdx++){
00217     const DayaBay::IHeader* inputHeader = header->inputHeaders()[ihIdx];
00218     const DataObject* tmpObj
00219       = dynamic_cast<const DataObject*>( inputHeader );
00220     DataObject* parentObj = const_cast<DataObject*>(tmpObj);
00221     if( !m_keepAllParents
00222         && std::find(m_keepParents.begin(), 
00223                      m_keepParents.end(),
00224                      parentObj->registry()->identifier())
00225         ==m_keepParents.end()){
00226       // Don't keep this parent
00227       continue;
00228     }
00229     ObjectReg* parentReg = this->findRegistration(parentObj);
00230     if(parentReg){
00231       parentReg->setStore(true);
00232       debug() << "Keeping parent: " << parentObj->registry()->identifier() 
00233              << endreq;
00234       // Don't forget to check the grandparents
00235       StatusCode sc = this->processParentHeaders(parentObj);
00236       if(sc.isFailure()) return sc;
00237     }
00238   }
00239 
00240   return StatusCode::SUCCESS;
00241 }
00242 
00243 ObjectReg* SmartFilterAlg::findRegistration(DataObject* dobj)
00244 {
00245   // Try to find the registration for this data object
00246 
00247   // FIXME: Can't navigate directly to ObjectReg for a given header object. 
00248   //        
00249   // Instead, use the following HACK
00250   // Check all archived regseq. to look for each input header
00251   if(m_archiveSvc){
00252     DybArchiveList* arcRegList = 0;
00253     arcRegList = get<DybArchiveList*>(m_archiveSvc,
00254                                       "/Event/RegistrationSequence");
00255     if(!arcRegList){
00256       error() << "Failed to get archive of registrations sequences" << endreq;
00257       return 0;
00258     }
00259     for(unsigned int regSeqIdx=0; regSeqIdx<arcRegList->size(); regSeqIdx++){
00260       DayaBay::RegistrationSequence* regSeq 
00261         = dynamic_cast<DayaBay::RegistrationSequence*>(
00262                                              arcRegList->dataObject(regSeqIdx));
00263       if(!regSeq){
00264         error() << "Invalid registration sequence in AES!" << endreq;
00265         continue;
00266       }
00267       ObjectReg* objReg = regSeq->registration(dobj);
00268       if(objReg){
00269         // Found it!
00270         return objReg;
00271       }
00272     }
00273   }else{
00274     // Just use current RegSeq
00275     IRegistrationSequence* regSeq 
00276       = get<IRegistrationSequence>("/Event/RegistrationSequence");
00277     if(!regSeq){
00278       error() << "Invalid registration sequence in TES!" << endreq;
00279       return 0;
00280     }
00281     ObjectReg* objReg = regSeq->registration(dobj);
00282     if(objReg){
00283       // Found it!
00284       return objReg;
00285     }
00286   }
00287   warning() << "Failed to find registration for object " 
00288             << dobj->registry()->identifier() << endreq;
00289   return 0;
00290 }
00291 
00292 
00293 bool SmartFilterAlg::isChild(const DataObject* dobj){
00294   // Check if this object is a child of a kept object
00295   const DayaBay::IHeader* header = dynamic_cast<const DayaBay::IHeader*>(dobj);
00296   if(!header){
00297     error() << "Invalid data object" << endreq;
00298     return false;
00299   }
00300   // Loop over input headers
00301   for(unsigned int ihIdx=0;ihIdx<header->inputHeaders().size();ihIdx++){
00302     const DayaBay::IHeader* inputHeader = header->inputHeaders()[ihIdx];
00303     const DataObject* parentObj
00304       = dynamic_cast<const DataObject*>( inputHeader ); 
00305     if(std::find(m_keptHeaders.begin(), 
00306                  m_keptHeaders.end(), 
00307                  parentObj) != m_keptHeaders.end()){
00308       return true;
00309     }
00310     // check ancestors as well
00311     if( this->isChild( parentObj ) ) return true;
00312   }
00313   return false;
00314 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:38:49 2011 for SmartFilter by doxygen 1.4.7