00001 #include "BDUniquify.h"
00002 #include "BDEarliest.h"
00003
00004 #include <RawData/RawBeamData.h>
00005 #include <RawData/RawBeamMonBlock.h>
00006 #include <RawData/RawBeamMonHeaderBlock.h>
00007 #include <RawData/RawRecord.h>
00008 #include <MinosObjectMap/MomNavigator.h>
00009 #include <Validity/VldTimeStamp.h>
00010
00011 #include <TIterator.h>
00012
00013 #include <algorithm>
00014 #include <list>
00015 #include <cmath>
00016 using namespace std;
00017
00018 BDUniquify::BDUniquify(size_t qsize)
00019 : fSize(qsize)
00020 {
00021 }
00022
00023 static size_t count_good(const BDUniquify::BlockPair &p)
00024 {
00025 vector<string> names = p.second->GetNames();
00026 size_t siz = names.size();
00027 VldTimeStamp vts = (*p.first).GetTimeStamp();
00028 int bad = 0;
00029 for (size_t ind=0; ind<siz; ++ind) {
00030 const RawBeamData* rbd = (*p.second)[names[ind]];
00031 if (!rbd) continue;
00032
00033 VldTimeStamp tmp(rbd->GetSeconds(),rbd->GetMsecs()*1000000);
00034 if (fabs(vts - tmp) > 0.5) ++bad;
00035 }
00036 return siz-bad;
00037 }
00038
00039
00040 bool block_pair_less(const BDUniquify::BlockPair& a,
00041 const BDUniquify::BlockPair& b)
00042 {
00043
00044
00045 size_t sa = count_good(a);
00046 size_t sb = count_good(b);
00047
00048 if (sa == sb)
00049 return a.first->GetSpillCountNum() > b.first->GetSpillCountNum();
00050
00051 return sa > sb;
00052 }
00053
00054 vector<BDUniquify::BlockPair>
00055 BDUniquify::GetUniqueBlocks(const MomNavigator &mom)
00056 {
00057 static BDEarliest earliest;
00058
00059 list<BDUniquify::BlockPair> res;
00060
00061
00062 TObject* tobj=0;
00063 TIter fragiter = mom.FragmentIter();
00064 while( ( tobj = fragiter.Next() ) ) {
00065 const RawRecord* rawrec = dynamic_cast<const RawRecord*>(tobj);
00066 if (!rawrec) continue;
00067
00068 BlockPair p;
00069
00070
00071 TIter blockiter = rawrec->GetRawBlockIter();
00072 while( ( tobj = blockiter.Next() ) ) {
00073 if (!p.first)
00074 p.first = dynamic_cast<const RawBeamMonHeaderBlock*>(tobj);
00075 if (!p.second)
00076 p.second = dynamic_cast<const RawBeamMonBlock*>(tobj);
00077 }
00078
00079 if (!p.first || !p.second) continue;
00080
00081 earliest.SetSpill(*p.first,*p.second);
00082 double dae=0,vme=0;
00083 earliest.GetTimestamps(dae, vme);
00084 if (dae<1 && vme<1) continue;
00085
00086 res.push_back(p);
00087 }
00088
00089
00090 res.sort(block_pair_less);
00091
00092 vector<BDUniquify::BlockPair> ret;
00093 list<BDUniquify::BlockPair>::iterator it, done = res.end();
00094 for (it=res.begin(); it != done; ++it) {
00095 BDUniquify::BlockPair p = *it;
00096 VldTimeStamp vts = p.first->GetTimeStamp();
00097 int event = p.second->TclkTriggerEvent();
00098 int delay = p.second->TclkTriggerDelay();
00099 if (! this->IsUnique(vts, event, delay)) continue;
00100
00101 this->AddTimeStamp(vts,event,delay);
00102 ret.push_back(p);
00103 }
00104
00105 return ret;
00106
00107 }
00108
00109 void BDUniquify::AddTimeStamp(const VldTimeStamp& vts, int event, int delay)
00110 {
00111 int key = event<<24 + delay;
00112 deque<VldTimeStamp>& vtsl = fPastSpills[key];
00113 vtsl.push_front(vts);
00114 while (vtsl.size() > fSize) vtsl.pop_back();
00115 }
00116
00117 bool BDUniquify::IsUnique(const VldTimeStamp& vts, int event, int delay)
00118 {
00119 int key = event<<24 + delay;
00120 map<int,deque<VldTimeStamp> >::iterator it = fPastSpills.find(key);
00121
00122 if (it == fPastSpills.end()) return true;
00123
00124 deque<VldTimeStamp> &vtsl = it->second;
00125
00126 size_t siz = vtsl.size();
00127 for (size_t ind=0; ind<siz; ++ind) {
00128 if (fabs(vtsl[ind]-vts) < 0.5) return false;
00129 }
00130
00131 return true;
00132 }