00001 #include "BDTestData.h"
00002
00003 #include <BeamDataUtil/BDEarliest.h>
00004 #include <BeamDataUtil/BDTarget.h>
00005
00006 #include <Validity/VldContext.h>
00007 #include <RawData/RawRecord.h>
00008 #include <RawData/RawBeamMonHeaderBlock.h>
00009 #include <RawData/RawBeamMonBlock.h>
00010 #include <RawData/RawDataBlock.h>
00011 #include <RawData/RawBeamData.h>
00012
00013 #include <SpillTiming/SpillTimeFinder.h>
00014
00015 #include <TFile.h>
00016 #include <TTree.h>
00017 #include <TSystem.h>
00018
00019 #include <iostream>
00020 #include <vector>
00021 #include <list>
00022 using namespace std;
00023
00024
00025 BDTestData::BDTestData()
00026 {
00027 this->Reset();
00028 }
00029 BDTestData::~BDTestData() {}
00030 void BDTestData::Reset()
00031 {
00032 earliest = 0.0;
00033 tortgt = trtgtd = tor101 = tr101d = 0.0;
00034 nbunch = 0;
00035 tgtdist = -99999;
00036 horni = 0;
00037 for (int ind=0; ind<8; ++ind) {
00038 hitgt[ind] = vitgt[ind] = 0.0;
00039 xtgt[ind] = ytgt[ind] = -99999;
00040 }
00041 xsigma = 0.0;
00042 ysigma = 0.0;
00043 }
00044
00045 static void set_toroid(const char* n, float& t, const RawBeamMonBlock& block)
00046 {
00047 t=0.0;
00048 const RawBeamData* d = block[n];
00049 if (d && d->GetDataLength()) t=d->GetData()[0];
00050 if (t>50)
00051 cerr << n << " " << t << endl;
00052 }
00053
00054 bool fill_bdtest(BDTestData& td, const RawBeamMonBlock& block,
00055 const RawBeamMonHeaderBlock& head)
00056 {
00057 td.Reset();
00058
00059 const int trig_event = block.TclkTriggerEvent();
00060 if (trig_event != 0xa9) return false;
00061
00062
00063 BDEarliest earliest;
00064 earliest.SetSpill(head,block);
00065 double dae=0, vme=0;
00066 earliest.GetTimestamps(dae,vme);
00067 if (vme) td.earliest = vme;
00068 else td.earliest = dae;
00069
00070
00071 set_toroid("E:TORTGT",td.tortgt,block);
00072 set_toroid("E:TRTGTD",td.trtgtd,block);
00073 set_toroid("E:TOR101",td.tor101,block);
00074 set_toroid("E:TR101D",td.tr101d,block);
00075
00076 BDTarget targ;
00077 targ.SetSpill(head,block);
00078 vector<double> xp,yp,xi,yi;
00079 targ.BpmProjection(xp,yp,xi,yi);
00080 td.nbunch = xp.size();
00081 for (int ind=0; ind<td.nbunch && ind<8; ++ind) {
00082 td.hitgt[ind] = static_cast<float>(xi[ind]);
00083 td.vitgt[ind] = static_cast<float>(yi[ind]);
00084 td.xtgt[ind] = static_cast<float>(xp[ind]);
00085 td.ytgt[ind] = static_cast<float>(yp[ind]);
00086 }
00087 double xm=0, ym=0, xsig=0, ysig=0;
00088
00089 targ.ProfileProjection(xm,ym,xsig,ysig);
00090 td.xsigma = xsig;
00091 td.ysigma = ysig;
00092 bool is_in=false;
00093 double z_loc = 0;
00094 BDTarget::BeamType beam_type = targ.TargetIn(is_in,z_loc);
00095 if (beam_type == BDTarget::kUnknown || !is_in) {
00096 cerr << "Unknown target location: is_in="<<is_in<<" at " << z_loc << endl;
00097 }
00098 if (!is_in)
00099 td.tgtdist = -1e6;
00100 else td.tgtdist = z_loc;
00101
00102
00103 const char* dev[] = {"E:NSLINA","E:NSLINB","E:NSLINC","E:NSLIND",0};
00104 float horni = 0;
00105 for (int ind=0; dev[ind]; ++ind) {
00106 const RawBeamData* d = block[dev[ind]];
00107 if (d && d->GetDataLength()) horni += d->GetData()[0];
00108 }
00109 td.horni = horni;
00110
00111 td.spilltimend =
00112 SpillTimeFinder::Instance().GetTimeOfNearestSpill(head.GetVldContext());
00113
00114 return true;
00115 }
00116
00117 void convert_raw_to_bdtest(const char* raw_file, const char* output_file)
00118 {
00119 TFile infile(raw_file,"READ");
00120 TTree* intree=(TTree*)(infile.Get("BeamMon"));
00121
00122 TFile outfile(output_file,"RECREATE");
00123 TTree* outtree = new TTree("bdtest", "Beam Monitoring Data");
00124 BDTestData* bdtd = new BDTestData;
00125 outtree->Branch("pot","BDTestData",&bdtd);
00126
00127 RawRecord* record = 0;
00128 int nentries = intree->GetEntries();
00129 for ( Int_t ient = 0; ient < nentries; ient++ ) {
00130 intree -> SetBranchAddress("RawRecord",&record);
00131 intree->GetEntry(ient);
00132
00133 const RawBeamMonBlock* rbmb = 0;
00134 const RawBeamMonHeaderBlock* rbmhb = 0;
00135 TObject *obj = 0;
00136 TIter itr = record->GetRawBlockIter();
00137 while ((obj = itr())) {
00138 const RawBeamMonBlock* b = dynamic_cast<const RawBeamMonBlock*>(obj);
00139 if (b) rbmb = b;
00140 const RawBeamMonHeaderBlock* h = dynamic_cast<const RawBeamMonHeaderBlock*>(obj);
00141 if (h) rbmhb = h;
00142 }
00143
00144 if (!(rbmb && rbmhb)) continue;
00145
00146 if (fill_bdtest(*bdtd,*rbmb,*rbmhb))
00147 outtree->Fill();
00148 }
00149
00150 outfile.cd();
00151 outtree->Write();
00152 outfile.Close();
00153
00154 infile.Close();
00155 }
00156
00157 #include <TGraph.h>
00158 #include <TCanvas.h>
00159 #include <TH1F.h>
00160 #include <TAxis.h>
00161 #include <TGaxis.h>
00162
00163 class BDTDPlotter {
00164 TGraph inst_all,inst_le,inst_pme,inst_phe;
00165 TGraph accu_all,accu_le,accu_pme,accu_phe;
00166 double count_all, count_le, count_pme, count_phe;
00167
00168 public:
00169 BDTDPlotter();
00170
00171 void fill(BDTestData& d);
00172 void write(const char* name);
00173 };
00174
00175 BDTDPlotter::BDTDPlotter()
00176 {
00177 count_all = count_le = count_pme = count_phe = 0.0;
00178 }
00179
00180 void BDTDPlotter::fill(BDTestData& bdtd)
00181 {
00182 double pot = 0.0;
00183 if (pot <= 0.0) pot = bdtd.trtgtd;
00184 if (pot <= 0.0) pot = bdtd.tortgt;
00185 if (pot <= 0.0) pot = bdtd.tr101d;
00186 if (pot <= 0.0) pot = bdtd.tor101;
00187
00188 double ts = bdtd.earliest;
00189
00190 if (ts == 0.0) {
00191 cerr << "Skipping zero timestamp - pot=" << pot << endl;
00192 return;
00193 }
00194 if (pot < 0.0) {
00195 if (pot > -0.1) return;
00196 TDatime dt((time_t)ts);
00197 cerr << "Skipping negative PoT = " << pot
00198 << " at " << Form("%.6f",ts)
00199 << " " << dt.AsSQLString()
00200 << endl;
00201 return;
00202 }
00203
00204 inst_all.SetPoint(inst_all.GetN(),ts,pot);
00205
00206 double accum_pot=0;
00207 if (!accu_all.GetN()) {
00208 accu_all.SetPoint(0,ts,pot);
00209 accum_pot=pot;
00210 }
00211 else {
00212 double accum_ts=0;
00213 accu_all.GetPoint(accu_all.GetN()-1,accum_ts,accum_pot);
00214 accum_pot += pot;
00215 accu_all.SetPoint(accu_all.GetN(),ts,accum_pot);
00216 }
00217 count_all += pot;
00218
00219 double tgtdist = bdtd.tgtdist;
00220
00221
00222
00223 const float dist_cut = 0.2*Munits::meter;
00224 const float le_pos = 0.0*Munits::meter;
00225 const float pme_pos = 1.0*Munits::meter;
00226 const float phe_pos = 2.5*Munits::meter;
00227 if (fabs(tgtdist-le_pos) < dist_cut) {
00228 inst_le.SetPoint(inst_le.GetN(),ts,pot);
00229 accu_le.SetPoint(accu_le.GetN(),ts,accum_pot);
00230 count_le += pot;
00231 }
00232 else if (fabs(tgtdist-pme_pos) < dist_cut) {
00233 inst_pme.SetPoint(inst_pme.GetN(),ts,pot);
00234 accu_pme.SetPoint(accu_pme.GetN(),ts,accum_pot);
00235 count_pme += pot;
00236 }
00237 else if (fabs(tgtdist-phe_pos) < dist_cut) {
00238 inst_phe.SetPoint(inst_phe.GetN(),ts,pot);
00239 accu_phe.SetPoint(accu_phe.GetN(),ts,accum_pot);
00240 count_phe += pot;
00241 }
00242
00243 if (pot > 50)
00244 cerr << accu_all.GetN()
00245 << ": pot=" << pot << " accum_pot=" << accum_pot
00246 << " @ " << Form("%.6f",ts)
00247 << endl;
00248 }
00249
00250 #include <TDatime.h>
00251 #include <TText.h>
00252
00253 void footer()
00254 {
00255 TDatime t;
00256 double x=0.01, y=0.01;
00257 const char* str = Form("Brett Viren, %d/%02d/%02d",t.GetYear(),t.GetMonth(),t.GetDay());
00258 TText tt(x,y,str);
00259 float siz = tt.GetTextSize();
00260 tt.SetTextSize(0.5*siz);
00261 tt.DrawTextNDC(x,y,str);
00262
00263 }
00264
00265 #include <TVirtualPad.h>
00266 #include <TMarker.h>
00267 #include <TPaveText.h>
00268 #include <TImageDump.h>
00269
00270 void legend(double X1, double Y1, double X2, double Y2,
00271 int nlines, int colors[], string keys[],
00272 char type = 'l', int padcolor=0);
00273
00274 void legend(double X1, double Y1, double X2, double Y2,
00275 int nlines, int colors[], string keys[],
00276 char type, int padcolor)
00277 {
00278 TVirtualPad* oldpad = gPad;
00279
00280 TPad* newpad = new TPad("newpad","Legend",X1,Y1,X2,Y2,0,1);
00281 newpad->SetBorderSize(1);
00282 newpad->SetBorderMode(0);
00283 newpad->SetFillColor(padcolor);
00284 newpad->SetFillStyle(4090);
00285 newpad->Draw();
00286 newpad->cd();
00287
00288 double t = 1.0/nlines;
00289
00290 int ind;
00291 for (ind=0; ind < nlines; ++ind) {
00292 double y2 = (1.0 + ind)*t;
00293 double ymid = (0.5 + ind)*t;
00294 double y1 = (0.0 + ind)*t;
00295
00296 switch (type) {
00297 case 'm': {
00298 TMarker marker;
00299 marker.SetMarkerColor(colors[ind]);
00300 if (colors[ind] == 1)
00301 marker.SetMarkerStyle(8);
00302 else
00303 marker.SetMarkerStyle(colors[ind]);
00304 marker.DrawMarker(0.125,ymid);
00305 break;
00306 }
00307 case 'l': default: {
00308 TLine line;
00309 line.SetLineColor(colors[ind]);
00310
00311 line.SetLineWidth(5);
00312 line.DrawLine(0.0,ymid,0.25,ymid);
00313 break;
00314 }
00315 }
00316 TPaveText* pt = new TPaveText(0.25,y1,1.0,y2,"NDC");
00317 pt->SetBorderSize(0);
00318 pt->SetFillColor(0);
00319 pt->SetFillStyle(0);
00320 pt->AddText(keys[ind].c_str());
00321 pt->Draw();
00322
00323 cerr << ind << ": " << colors[ind] << ", " << keys[ind] << endl;
00324 }
00325 newpad->Modified();
00326 newpad->Update();
00327
00328 oldpad->cd();
00329 }
00330
00331 void BDTDPlotter::write(const char* )
00332 {
00333
00334
00335 const float min = 0.0;
00336 const float max = 40.0;
00337 TCanvas* c1 = new TCanvas("c1","npot",640,480);
00338
00339 TPad* pad = new TPad("pad","",0,0,1,1);
00340
00341 pad->SetGrid();
00342 pad->Draw();
00343 pad->cd();
00344
00345 TGraph* inst = &inst_all;
00346 TH1F* hinst = inst->GetHistogram();
00347 TAxis *ainst = hinst->GetXaxis();
00348
00349 TH1F* hfinst = c1->DrawFrame(ainst->GetXmin(), min, ainst->GetXmax(), max);
00350 TAxis* fainst = hfinst->GetXaxis();
00351 fainst->SetTimeDisplay(1);
00352 fainst->SetTimeFormat("%m/%d");
00353 fainst->SetTitle("Date (2005)");
00354 hfinst->GetYaxis()->SetTitle("Protons per Spill (1E12)");
00355 int ndiv = hfinst->GetNdivisions("Y");
00356 hfinst->SetTitle("NuMI Protons");
00357
00358 inst->Draw("B");
00359 c1->cd();
00360 TPad* overlay = new TPad("overlay","",0,0,1,1);
00361 overlay->SetFillStyle(4000);
00362 overlay->SetFillColor(0);
00363 overlay->SetFrameFillStyle(4000);
00364 overlay->Draw();
00365 overlay->cd();
00366
00367 const float large_marker_size = 1;
00368 const float small_marker_size = 0.8;
00369 const int small_line_size = 3;
00370 const char* drawopt = "P";
00371
00372
00373 accu_all.SetLineColor(0);
00374 accu_all.SetLineWidth(5);
00375 accu_all.SetMarkerSize(large_marker_size);
00376 accu_all.SetMarkerStyle(20);
00377
00378 int n_accumulated = accu_all.GetN();
00379 double maxaccum = accu_all.GetY()[n_accumulated-1];
00380 cerr << "Max = " << maxaccum << endl;
00381 double maxscale=1.60;
00382 int expo=20;
00383 double max_pad_scale = maxscale*1e8;
00384
00385 cerr << "using maxscale = " << maxscale << ", expo = "
00386 << expo << " max_pad_scale = " << max_pad_scale << endl;
00387
00388 TH1F* hfaccum = overlay->DrawFrame(fainst->GetXmin(),0,
00389 fainst->GetXmax(),max_pad_scale);
00390 hfaccum->SetNdivisions(0,"X");
00391 hfaccum->SetNdivisions(0,"Y");
00392 TAxis* oainst = hfaccum->GetXaxis();
00393 oainst->SetTimeDisplay(1);
00394 oainst->SetTimeFormat("%m/%d");
00395 oainst->SetLabelOffset(99);
00396
00397 hfaccum->GetYaxis()->SetLabelOffset(99);
00398
00399 accu_all.Draw(drawopt);
00400
00401 TGaxis* axis = new TGaxis(oainst->GetXmax(), 0,
00402 oainst->GetXmax(), max_pad_scale,
00403 0,maxscale, ndiv,"+L");
00404
00405 axis->SetTitle(Form("Total Delivered Protons (1E%d)",expo));
00406 axis->SetTextColor(2);
00407 axis->SetLineColor(2);
00408 axis->SetLabelColor(2);
00409 axis->Draw();
00410
00411 inst_le.SetMarkerColor(2);
00412 inst_le.SetLineWidth(1);
00413 accu_le.SetMarkerColor(2);
00414 accu_le.SetLineColor(2);
00415 accu_le.SetLineWidth(small_line_size);
00416 accu_le.SetMarkerSize(small_marker_size);
00417 accu_le.SetMarkerStyle(20);
00418
00419 inst_pme.SetMarkerColor(4);
00420 inst_pme.SetLineWidth(1);
00421 accu_pme.SetMarkerColor(4);
00422 accu_pme.SetLineColor(4);
00423 accu_pme.SetLineWidth(small_line_size);
00424 accu_pme.SetMarkerSize(small_marker_size);
00425 accu_pme.SetMarkerStyle(20);
00426
00427 inst_phe.SetMarkerColor(6);
00428 inst_phe.SetLineWidth(1);
00429 accu_phe.SetMarkerColor(6);
00430 accu_phe.SetLineColor(6);
00431 accu_phe.SetLineWidth(small_line_size);
00432 accu_phe.SetMarkerSize(small_marker_size);
00433 accu_phe.SetMarkerStyle(20);
00434
00435 if (inst_le.GetN()) {
00436
00437 accu_le.Draw(drawopt);
00438 }
00439
00440 if (inst_pme.GetN()) {
00441
00442 accu_pme.Draw(drawopt);
00443 }
00444
00445 if (inst_phe.GetN()) {
00446
00447 accu_phe.Draw(drawopt);
00448 }
00449
00450 footer();
00451
00452 int colors[] = { 1,2,4,6 };
00453 string keys[] = {
00454 Form("All (%5.2E PoT)",count_all*1e12),
00455 Form("LE (%5.2E PoT)",count_le*1e12),
00456 Form("pME (%5.2E PoT)",count_pme*1e12),
00457 Form("pHE (%5.2E PoT)",count_phe*1e12)
00458 };
00459 legend(.2,.8,.5,.6,4,colors,keys);
00460
00461 c1->Modified();
00462 c1->Update();
00463
00464
00465 #if 0
00466 cerr << "Printing eps\n";
00467 c1->Print("npot.eps");
00468 cerr << "Printing pdf\n";
00469 c1->Print("npot.pdf");
00470 #endif
00471
00472 #if 0
00473 cerr << "Dumping npot.png" << endl;
00474 TImageDump* di = new TImageDump("npot.png");
00475 c1->Paint();
00476 di->Close();
00477
00478 #else
00479 cerr << "Printing npot.png" << endl;
00480 c1->Print("npot.png");
00481 #endif
00482 #if 0
00483 cerr << "Dumping npot.gif" << endl;
00484 di = new TImageDump("npot.gif");
00485 c1->Paint();
00486 di->Close();
00487
00488 #else
00489 cerr << "Printing npot.gif" << endl;
00490 c1->Print("npot.gif");
00491 #endif
00492
00493
00494 cerr << "Writing root file\n";
00495 TFile file("npot.root","RECREATE");
00496 file.cd();
00497 inst->SetName("pot");
00498 inst->Write();
00499 file.Close();
00500
00501 }
00502
00503 void generate_bdtd_plots(const char* input_directory, const char* outfile)
00504 {
00505 void* dir = gSystem->OpenDirectory(input_directory);
00506 if (!dir) {
00507 cerr << "Failed to open directory \"" << input_directory << "\"\n";
00508 return;
00509 }
00510
00511 BDTDPlotter* plotter = new BDTDPlotter;
00512
00513 list<string> file_names;
00514 const char* cptr=0;
00515 while ( (cptr = gSystem->GetDirEntry(dir)) ) if (cptr) file_names.push_back(cptr);
00516 if (!file_names.size()) return;
00517 file_names.sort();
00518 list<string>::iterator it, done = file_names.end();
00519 for (it=file_names.begin(); it != done; ++it) {
00520 string file = *it;
00521 if (string::npos == file.find(".bdtd.root")) {
00522 cerr << "Skipping unmatched file \"" << file << "\"\n";
00523 continue;
00524 }
00525
00526 string path = input_directory;
00527 path += "/" + file;
00528 cerr << "Processing " << path << endl;
00529 TFile tfile(path.c_str(),"READ");
00530 TTree* tree = (TTree*)(tfile.Get("bdtest"));
00531 BDTestData* bd_test_data = 0;
00532 int ninds = tree->GetEntries();
00533 for (int ind=0; ind<ninds; ++ind) {
00534 tree->SetBranchAddress("pot",&bd_test_data);
00535 tree->GetEntry(ind);
00536
00537 plotter->fill(*bd_test_data);
00538 }
00539 tfile.Close();
00540 }
00541
00542 plotter->write(outfile);
00543 }
00544
00545 ClassImp(BDTestData)