00001 #include "PulserTimingPoint.h"
00002 #include "RawData/RawLITimingSummaryBlock.h"
00003 #include "RawData/RawLITimingSummary.h"
00004 #include "Plex/PlexHandle.h"
00005 #include "MessageService/MsgService.h"
00006 #include "DatabaseInterface/DbiWriter.h"
00007 #include <cassert>
00008 #include <fstream>
00009 #include <set>
00010 #include "PulserTimeDrift.h"
00011
00012 CVSID("$Id: PulserTimingPoint.cxx,v 1.9 2007/03/01 17:06:40 rhatcher Exp $");
00013
00014 using namespace std;
00015
00016 PulserTimingPoint::PulserTimingPoint()
00017 {
00018
00019 }
00020
00021 PulserTimingPoint::PulserTimingPoint(const RawLITimingSummaryBlock* startblock)
00022 {
00026 assert(startblock);
00027
00028 fCalibType = startblock->GetCalibType();
00029 fCalibPoint = startblock->GetCalibPoint();
00030 fPulserBox = startblock->GetPulserBox();
00031 fLed = startblock->GetLed();
00032 fPulseHeight = startblock->GetPulseHeight();
00033 fPulses = startblock->GetPulses();
00034 fPeriod = startblock->GetPeriod();
00035 fTotalCount = startblock->GetCount();
00036 fStartContext = fEndContext = startblock->GetVldContext();
00037
00038 fValidChannels.clear();
00039 ValidChannelList_t::iterator vcit = fValidChannels.end();
00040
00041 PlexHandle plex(fStartContext);
00042 PlexLedId led(fStartContext.GetDetector(),fPulserBox,fLed);
00043
00044
00045 const std::vector<PlexStripEndId>& ends = plex.GetAllStripEnds();
00046 for(UInt_t i=0;i<ends.size();i++) {
00047 if(plex.GetLedId(ends[i])==led) {
00048 RawChannelId rcid = plex.GetRawChannelId(ends[i]);
00049 UInt_t chindex = PulserTimeDrift::GetIndex(rcid);
00050 vcit = fValidChannels.insert(vcit,chindex);
00051 }
00052 }
00053
00054
00055 fMaxEntries = fMinEntries = 0;
00056 AddSummaryBlock(startblock);
00057 }
00058
00059
00060 PulserTimingPoint::~PulserTimingPoint()
00061 {
00062 ChannelMap_t::iterator it;
00063 for(it = fChannelMap.begin(); it!=fChannelMap.end(); it++) {
00064 if(it->second) delete it->second;
00065 }
00066 fChannelMap.clear();
00067 }
00068
00069 Bool_t PulserTimingPoint::AddSummaryBlock(const RawLITimingSummaryBlock* sumblock)
00070 {
00075 assert(sumblock);
00076 if(fCalibType !=sumblock->GetCalibType()) return false;
00077 if(fCalibPoint!=sumblock->GetCalibPoint()) return false;
00078 if(fPulserBox !=sumblock->GetPulserBox()) return false;
00079 if(fLed !=sumblock->GetLed()) return false;
00080
00081
00082 fEndContext = sumblock->GetVldContext();
00083 fTotalCount += sumblock->GetCount();
00084
00085
00086
00087
00088
00089
00090
00091 std::map<UInt_t,Int_t> whichToUse;
00092 std::map<UInt_t,Int_t>::iterator useItr;
00093
00094 for(Int_t i=0;i<sumblock->GetNumberOfSummaries(); i++) {
00095 const RawLITimingSummary* summary = sumblock->At(i);
00096 if(!summary) continue;
00097
00098 UInt_t chindex = PulserTimeDrift::GetIndex(summary->GetChannel());
00099 if(!ChannelBelongsToPoint(chindex)) continue;
00100
00101 useItr = whichToUse.find(chindex);
00102 if(useItr==whichToUse.end()) {
00103
00104 whichToUse[chindex] = i;
00105 } else {
00106 int index2 = useItr->second;
00107 if(sumblock->At(i)->GetEntries() > sumblock->At(index2)->GetEntries())
00108 useItr->second = i;
00109 }
00110 }
00111
00112 fMaxEntries = -1;
00113 fMinEntries = 1e10;
00114
00115 for(Int_t i=0;i<sumblock->GetNumberOfSummaries();i++) {
00116 const RawLITimingSummary* summary = sumblock->At(i);
00117 if(!summary) continue;
00118
00119 UInt_t chindex = PulserTimeDrift::GetIndex(summary->GetChannel());
00120 if(!ChannelBelongsToPoint(chindex)) continue;
00121
00122
00123 if(whichToUse[chindex]==i) {
00124
00125 ChannelMap_t::iterator it = fChannelMap.find(chindex);
00126 if(it==fChannelMap.end()) {
00127
00128
00129 it =
00130 fChannelMap.insert(ChannelMap_t::value_type
00131 (chindex,new PulserTimeDrift(fPulserBox,chindex))
00132 ).first;
00133 }
00134 it->second->Add(summary->GetEntries(),
00135 summary->GetMean(),
00136 summary->GetRms() );
00137
00138
00139 if(it->second->GetEntries() > fMaxEntries)
00140 fMaxEntries = it->second->GetEntries();
00141 if(it->second->GetEntries() < fMinEntries)
00142 fMinEntries = it->second->GetEntries();
00143 }
00144 }
00145
00146 return true;
00147 }
00148
00149 Bool_t PulserTimingPoint::PointTimedOut(const VldTimeStamp& currentTime,
00150 double timeout)
00151 {
00156
00157
00158 int currentSec = currentTime.GetSec();
00159 int currentNsec= currentTime.GetNanoSec();
00160 int endSec = fEndContext.GetTimeStamp().GetSec();
00161 int endNsec= fEndContext.GetTimeStamp().GetNanoSec();
00162
00163 double dt = (double)(currentSec-endSec) + 1e-9*(double)(currentNsec-endNsec);
00164 if(dt>timeout) return true;
00165 return false;
00166 }
00167
00168
00169 Bool_t PulserTimingPoint::PointIsFinished()
00170 {
00176
00177
00178 if(fMinEntries >= fPulses) return true;
00179
00180
00181
00182 return false;
00183 }
00184
00185
00186 Bool_t PulserTimingPoint::PointIsGood()
00187 {
00194
00195
00196 if(fCalibType!=1) return false;
00197
00198 int badChips = 0;
00199 int goodChips = 0;
00200
00201
00202
00203 ChannelMap_t::iterator it;
00204 for(it = fChannelMap.begin(); it!=fChannelMap.end(); it++) {
00205
00206 if(it->second->GetEntries() < (float)(fPulses)*0.9) {
00207 MSG("PulserTiming",Msg::kInfo) << "Channel "
00208 << it->second->GetRawChannelId().AsString()
00209 << " has only " << it->second->GetEntries()
00210 << " and point expected " << fPulses << " entries."
00211 << std::endl;
00212 badChips++;
00213 } else
00214 goodChips++;
00215 }
00216
00217 bool retval = true;
00218
00219 if(badChips>0)
00220 MSG("PulserTiming",Msg::kWarning) << "--->" << badChips
00221 << "Bad chips, "
00222 << goodChips << " good chips on " << AsString() << endl;
00223
00224
00225 if((goodChips<1)||(badChips>10)) {
00226 MSG("PulserTiming",Msg::kWarning) << "--->Point is judged bad. Storing anyway. " << AsString() << endl;
00227
00228
00229 }
00230
00231
00232 return retval;
00233 }
00234
00235 Bool_t PulserTimingPoint::WriteToTextfile(const char* name)
00236 {
00237 const char* filename = Form("%s_%d_%d",
00238 name,
00239 fPulserBox,
00240 fLed);
00241 ofstream outfile(filename);
00242 outfile << "CalibType: \t" << fCalibType << endl;
00243 outfile << "CalibPoint: \t" << fCalibPoint << endl;
00244 outfile << "PulserBox: \t" << fPulserBox << endl;
00245 outfile << "Led: \t" << fLed << endl;
00246 outfile << "PulseHeight:\t" << fPulseHeight << endl;
00247 outfile << "PulseWidth: \t" << fPulseWidth << endl;
00248 outfile << "Pulses: \t" << fPulses << endl;
00249 outfile << "Period: \t" << fPeriod << endl;
00250 outfile << "TotalCounts:\t" << fTotalCount << endl;
00251 outfile << "Start: \t" << fStartContext.AsString() << endl;
00252 outfile << "End: \t" << fEndContext.AsString() << endl;
00253 outfile << endl << endl << endl << endl;
00254
00255 outfile << "Entries: \t" << fChannelMap.size() << endl;
00256
00257 for(ChannelMap_t::iterator it=fChannelMap.begin();
00258 it!=fChannelMap.end();
00259 it++) {
00260 outfile << Form("%10d ",it->first)
00261 << Form("%8d " ,(int)(it->second->GetEntries()))
00262 << Form("%6.2f ",it->second->GetMean())
00263 << Form("%6.2f ",it->second->GetRms())
00264 << it->second->GetRawChannelId().AsString()
00265 << endl;
00266 }
00267
00268 outfile.close();
00269 return true;
00270 }
00271
00272 Bool_t PulserTimingPoint::WriteToDatabase()
00273 {
00274 VldTimeStamp endtime = fStartContext.GetTimeStamp();
00275 VldTimeStamp offset(60*60*24*30*2,0);
00276 endtime.Add(offset);
00277
00278 VldRange range(fStartContext.GetDetector(),
00279 fStartContext.GetSimFlag(),
00280 fStartContext.GetTimeStamp(),
00281 endtime,
00282 "Automatic generation of time drift. $Id ");
00283
00284 Int_t aggNo = fPulserBox;
00285 Int_t task = fLed;
00286 std::string comment("Automatic generation of time drift. $Id ");
00287
00288 MSG("PulserTiming",Msg::kInfo) << "Writing pulser table. Aggregate(Crate) = " << aggNo
00289 << " Task(Led) = " << task << endl;
00290 MSG("PulserTiming",Msg::kDebug) << " VldRange = " << range.AsString() << endl;
00291 MSG("PulserTiming",Msg::kDebug) << " Comment = " << comment << endl;
00292
00293 DbiWriter<PulserTimeDrift> writer(range,
00294 aggNo,
00295 task,
00296 fStartContext.GetTimeStamp(),
00297 0,
00298 ""
00299 );
00300
00301 for(ChannelMap_t::iterator it=fChannelMap.begin();
00302 it!=fChannelMap.end();
00303 it++) {
00304 if(it->second) writer << *(it->second);
00305 }
00306
00307 writer.Close();
00308
00309 return true;
00310 }
00311
00312
00313 Bool_t PulserTimingPoint::ChannelBelongsToPoint(UInt_t chindex)
00314 {
00315 if(fValidChannels.find(chindex)==fValidChannels.end()) return false;
00316 return true;
00317 }
00318
00319
00320 const char* PulserTimingPoint::AsString()
00321 {
00322 return Form("Point: PulserBox %2d LED %2d %s",
00323 fPulserBox,
00324 fLed,
00325 fEndContext.AsString()
00326 );
00327 }