00001
00002
00003
00004 #include <iostream>
00005 #include <sstream>
00006
00007
00008 #include "TDirectory.h"
00009 #include "TH1.h"
00010 #include "TH2.h"
00011
00012
00013 #include "AstroUtil/Ast.h"
00014 #include "AstroUtil/AstTime.h"
00015 #include "Registry/Registry.h"
00016 #include "Validity/VldTimeStamp.h"
00017
00018
00019 #include "PhysicsNtuple/Default.h"
00020 #include "PhysicsNtuple/Factory.h"
00021 #include "PhysicsNtuple/Hist/HistMan.h"
00022
00023
00024 #include "PlotTime.h"
00025
00026 REGISTER_ANP_OBJECT(AlgSnarl,PlotTime)
00027
00028 using namespace std;
00029
00030
00031 Anp::HistTime::HistTime()
00032 :fPlot(false),
00033 fNMiss(0),
00034 fDay(0),
00035 fMonth(0),
00036 fYear(0),
00037 fDate(0),
00038 fSecs(0),
00039 fDir(0)
00040 {
00041 }
00042
00043
00044 Anp::HistTime::HistTime(const VldTimeStamp &time)
00045 :fPlot(false),
00046 fNMiss(0),
00047 fDay(0),
00048 fMonth(0),
00049 fYear(0),
00050 fDate(0),
00051 fSecs(0),
00052 fDir(0)
00053 {
00054 fDate = time.GetDate(true, 0, &fYear, &fMonth, &fDay);
00055
00056 const VldTimeStamp btime(fYear, fMonth, fDay, 0, 0, 0);
00057 fSecs = btime.GetSec();
00058 }
00059
00060
00061 Anp::HistTime::~HistTime()
00062 {
00063 }
00064
00065
00066 bool Anp::HistTime::Fill(const Record &record, const VldTimeStamp &time)
00067 {
00068
00069
00070
00071 if(!fPlot) return false;
00072
00073 unsigned int hour = 0, min = 0, sec = 0;
00074
00075 const int time_ = time.GetTime(true, 0, &hour, &min, &sec);
00076
00077 Spill spill;
00078 if (record.GetHeader().TorTgt() > 0.0) spill.protons = record.GetHeader().TorTgt();
00079 else if(record.GetHeader().TrTgtD() > 0.0) spill.protons = record.GetHeader().TrTgtD();
00080 else if(record.GetHeader().Tr101D() > 0.0) spill.protons = record.GetHeader().Tr101D();
00081 else if(record.GetHeader().Tor101() > 0.0) spill.protons = record.GetHeader().Tor101();
00082
00083 spill.nevents = record.GetNEvents();
00084 spill.hour = hour;
00085 spill.seconds = 3600*hour + 60*min + sec;
00086
00087 return fSpill.insert(map<int, Spill>::value_type(time_, spill)).second;
00088 }
00089
00090
00091 bool Anp::HistTime::Make(TDirectory *dir)
00092 {
00093 fPlot = false;
00094
00095 if(!dir) return false;
00096
00097 fDir = dir;
00098
00099 if(fNMiss == 0)
00100 {
00101 fPlot = true;
00102 }
00103 else
00104 {
00105 cerr << "HistTime::Make - missed " << fNMiss << " histograms" << endl;
00106 }
00107
00108 return fPlot;
00109 }
00110
00111
00112 TH1* Anp::HistTime::GetTH1(const std::string &key, const std::string &name)
00113 {
00114 TH1 *h = HistMan::Instance().CreateTH1(key, "kinem");
00115 if(h)
00116 {
00117 Anp::SetDir(h, fDir, name);
00118 }
00119 else
00120 {
00121 ++fNMiss;
00122 }
00123
00124 return h;
00125 }
00126
00127
00128 const pair<int, double> Anp::HistTime::GetSpills(const int hour)
00129 {
00130 pair<int, double> spill(0, 0.0);
00131
00132 for(map<int, Spill>::const_iterator sit = fSpill.begin(); sit != fSpill.end(); ++sit)
00133 {
00134 const Spill &spill_ = sit -> second;
00135
00136 if(hour < 0 || hour == spill_.hour)
00137 {
00138 spill.first += spill_.nevents;
00139 spill.second += spill_.protons;
00140 }
00141 }
00142
00143 return spill;
00144 }
00145
00146
00147 void Anp::HistTime::FillSol(TH1 *h, const string &option)
00148 {
00149 if(!h)
00150 {
00151 cerr << "HistTime::FillSol - invalid TH1 pointer" << endl;
00152 return;
00153 }
00154
00155 const int tsec = 24*3600;
00156 for(map<int, Spill>::const_iterator sit = fSpill.begin(); sit != fSpill.end(); ++sit)
00157 {
00158 const Spill &spill = sit -> second;
00159
00160 if(spill.seconds <= tsec)
00161 {
00162 if(option.find("protons") != string::npos)
00163 {
00164 h -> Fill(spill.seconds/double(tsec), spill.protons);
00165 }
00166 if(option.find("nevents") != string::npos)
00167 {
00168 h -> Fill(spill.seconds/double(tsec), spill.nevents);
00169 }
00170 }
00171 else
00172 {
00173 cerr << "HistTime::Fill - invalid time stamp: " << sit -> first << endl;
00174 }
00175 }
00176 }
00177
00178
00179 void Anp::HistTime::FillSid(TH1 *h, const string &option)
00180 {
00181 if(!h)
00182 {
00183 cerr << "HistTime::FillSid - invalid TH1 pointer" << endl;
00184 return;
00185 }
00186
00187 for(map<int, Spill>::const_iterator sit = fSpill.begin(); sit != fSpill.end(); ++sit)
00188 {
00189 const Spill &spill = sit -> second;
00190 const double hour = spill.seconds/3600.0;
00191
00192 double juld = 0.0, gmst = 0.0, lsid = 0.0;
00193
00194 AstUtil::CalendarToJulian(fYear, fMonth, fDay, hour, juld);
00195 AstUtil::JulianToGAST(juld, gmst);
00196 AstUtil::GSTToLST(gmst, AstUtil::kNearDetLongitude, lsid);
00197
00198 if(lsid < 0.0 || lsid > 24.0)
00199 {
00200 cerr << "HistTime::Fill - invalid time stamp: " << sit -> first << endl;
00201 }
00202 else
00203 {
00204 if(option.find("protons") != string::npos)
00205 {
00206 h -> Fill(lsid/24.0, spill.protons);
00207 }
00208 if(option.find("nevents") != string::npos)
00209 {
00210 h -> Fill(lsid/24.0, spill.nevents);
00211 }
00212 }
00213 }
00214 }
00215
00216
00217 Anp::PlotTime::PlotTime()
00218 :fDirName("time"),
00219 fDir(0),
00220 fPlot(false),
00221 fNMiss(0),
00222 fNFail(0),
00223 fPotCut(1.0e2),
00224 fPotDay(1.0e5),
00225 fPotHour(1.0e4)
00226 {
00227 }
00228
00229
00230 Anp::PlotTime::~PlotTime()
00231 {
00232 }
00233
00234
00235 bool Anp::PlotTime::Run(Record &record)
00236 {
00237
00238 const Header &header = record.GetHeader();
00239 const VldTimeStamp time(header.Sec(), header.NSec());
00240 const int date = time.GetDate();
00241
00242 PlotMap::iterator hit = fMap.find(date);
00243 if(hit == fMap.end())
00244 {
00245 Handle<HistTime> hist(new HistTime(time));
00246
00247
00248
00249
00250 if(!(hist -> Make(fDir)))
00251 {
00252 hist.release();
00253 }
00254
00255 hit = fMap.insert(PlotMap::value_type(date, hist)).first;
00256 }
00257
00258 if((hit -> second).valid())
00259 {
00260 if(!(hit -> second -> Fill(record, time)))
00261 {
00262 ++fNFail;
00263 }
00264 }
00265
00266 return true;
00267 }
00268
00269
00270 void Anp::PlotTime::Config(const Registry ®)
00271 {
00272 const char *value_char = 0;
00273 if(reg.Get("PlotTimeDirName", value_char) && value_char)
00274 {
00275 fDirName = value_char;
00276 }
00277
00278 reg.Get("PlotTimePotCut", fPotCut);
00279 reg.Get("PlotTimePotDay", fPotDay);
00280 reg.Get("PlotTimePotHour", fPotHour);
00281
00282 if(reg.KeyExists("PrintConfig"))
00283 {
00284 cout << "PlotTime::Config" << endl
00285 << " DirName = " << fDirName << endl
00286 << " PotCut = " << fPotCut << endl
00287 << " PotDay = " << fPotDay << endl
00288 << " PotHour = " << fPotHour << endl;
00289 }
00290 }
00291
00292
00293 void Anp::PlotTime::Set(TDirectory *dir)
00294 {
00295 fPlot = false;
00296
00297 if(!dir) return;
00298
00299 fDir = Anp::GetDir(fDirName, dir);
00300
00301 fRatePerDay = PlotTime::GetTH1("rate_per_day");
00302 fRatePerHour = PlotTime::GetTH1("rate_per_hour");
00303 fProtonsDay = PlotTime::GetTH1("protons_day");
00304 fProtonsHour = PlotTime::GetTH1("protons_hour");
00305 fProtonsvsSol = PlotTime::GetTH1("protons_vs_time", "protons_vs_sol");
00306 fProtonsvsSid = PlotTime::GetTH1("protons_vs_time", "protons_vs_sid");
00307 fNEventsDay = PlotTime::GetTH1("nevents_day");
00308 fNEventsHour = PlotTime::GetTH1("nevents_hour");
00309 fNEventsvsSol = PlotTime::GetTH1("nevents_vs_time", "nevents_vs_sol");
00310 fNEventsvsSid = PlotTime::GetTH1("nevents_vs_time", "nevents_vs_sid");
00311
00312 if(fNMiss == 0)
00313 {
00314 fPlot = true;
00315 }
00316 else
00317 {
00318 cerr << "PlotTime::Set - missed " << fNMiss << " histograms" << endl;
00319 }
00320 }
00321
00322
00323 void Anp::PlotTime::End(const DataBlock &)
00324 {
00325 if(!fDir || !fPlot)
00326 {
00327 return;
00328 }
00329
00330 if(fNFail > 0)
00331 {
00332 cout << "PlotTime::End - failed to add " << fNFail << " snarls" << endl;
00333 }
00334
00335 unsigned secs_beg = 0, secs_end = 0;
00336 for(PlotMap::iterator pit = fMap.begin(); pit != fMap.end(); ++pit)
00337 {
00338 Handle<HistTime> hist = pit -> second;
00339
00340 if(pit == fMap.begin())
00341 {
00342 secs_beg = hist -> GetSecs();
00343 secs_end = hist -> GetSecs();
00344 }
00345 else
00346 {
00347 secs_beg = std::min<int>(secs_beg, hist -> GetSecs());
00348 secs_end = std::max<int>(secs_end, hist -> GetSecs());
00349 }
00350 }
00351
00352 const int nhours = 24 + (secs_end - secs_beg)/3600;
00353 const int ndays = 1 + (secs_end - secs_beg)/(24*3600);
00354
00355 TH1 *hday = 0;
00356 TH1 *hhour = 0;
00357
00358 if(nhours > 1)
00359 {
00360 hhour = new TH1D("rate_per_hour_vs_time", "rate_per_hour_vs_time", nhours, 0, nhours);
00361 Anp::SetDir(hhour, fDir);
00362 }
00363 if(ndays > 1)
00364 {
00365 hday = new TH1D("rate_per_day_vs_time", "rate_per_day_vs_time", ndays, 0, ndays);
00366 Anp::SetDir(hday, fDir);
00367 }
00368
00369 for(PlotMap::iterator pit = fMap.begin(); pit != fMap.end(); ++pit)
00370 {
00371 Handle<HistTime> hist = pit -> second;
00372
00373 const double hour = double(hist -> GetSecs() - secs_beg)/3600.0;
00374 const double day = double(hist -> GetSecs() - secs_beg)/(24.0*3600.0);
00375
00376 const pair<int, double> aspill = hist -> GetSpills();
00377
00378 if(aspill.first > 0 && aspill.second > fPotCut)
00379 {
00380 const double drate = aspill.first*fPotDay/aspill.second;
00381 const double derror = drate*(0.01 + std::pow(aspill.first, -0.5));
00382
00383 fNEventsDay -> Fill(aspill.first);
00384 fProtonsDay -> Fill(aspill.second);
00385 fRatePerDay -> Fill(drate);
00386
00387 hist -> FillSol(fProtonsvsSol, "protons");
00388 hist -> FillSol(fNEventsvsSol, "nevents");
00389
00390 hist -> FillSid(fProtonsvsSid, "protons");
00391 hist -> FillSid(fNEventsvsSid, "nevents");
00392
00393 if(hday)
00394 {
00395 const int ibin = hday -> FindBin(day);
00396 hday -> SetBinContent(ibin, drate);
00397 hday -> SetBinError(ibin, derror);
00398 }
00399 }
00400
00401 for(int ihour = 0; ihour < 24; ++ihour)
00402 {
00403 const pair<int, double> hspill = hist -> GetSpills(ihour);
00404
00405 if(hspill.first > 0 && hspill.second > fPotCut)
00406 {
00407 const double hrate = hspill.first*fPotHour/hspill.second;
00408 const double herror = hrate*(0.01 + std::pow(hspill.first, -0.5));
00409
00410 fNEventsHour -> Fill(hspill.first);
00411 fProtonsHour -> Fill(hspill.second);
00412 fRatePerHour -> Fill(hrate);
00413
00414 if(hhour)
00415 {
00416 const int ibin = hhour -> FindBin(hour + ihour);
00417 hhour -> SetBinContent(ibin, hrate);
00418 hhour -> SetBinError(ibin, herror);
00419 }
00420 }
00421 }
00422 }
00423 }
00424
00425
00426 TH1* Anp::PlotTime::GetTH1(const std::string &key, const std::string &name)
00427 {
00428 TH1 *h = HistMan::Instance().CreateTH1(key, "time");
00429 if(h)
00430 {
00431 Anp::SetDir(h, fDir, name);
00432 }
00433 else
00434 {
00435 ++fNMiss;
00436 }
00437
00438 return h;
00439 }