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
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
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
00116 return StatusCode::SUCCESS;
00117 }
00118
00119
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
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
00133 continue;
00134 }
00135
00136 it->setStore(true);
00137 debug() << "Keeping: " << dobj->registry()->identifier() << endreq;
00138
00139
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
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
00161 m_keptHeaders.front()->release();
00162 m_keptHeaders.pop_front();
00163 }
00164 }
00165 }
00166 }
00167
00168 if( m_keepAllChildren || m_keepChildren.size()>0 ) {
00169
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
00180 continue;
00181 }
00182
00183 if( !this->isChild( childObj ) ) continue;
00184
00185 it->setStore(true);
00186 debug() << "Keeping child: " << childObj->registry()->identifier()
00187 << endreq;
00188 }
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
00210 DayaBay::IHeader* header = dynamic_cast<DayaBay::IHeader*>(dobj);
00211 if(!header){
00212 error() << "Invalid data object" << endreq;
00213 return StatusCode::FAILURE;
00214 }
00215
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
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
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
00246
00247
00248
00249
00250
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
00270 return objReg;
00271 }
00272 }
00273 }else{
00274
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
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
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
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
00311 if( this->isChild( parentObj ) ) return true;
00312 }
00313 return false;
00314 }