94#include <TDirectory.h>
98#include <TGraphErrors.h>
101#include <TPaveText.h>
104void readPedeHists(Option_t *option =
"",
const char *txtFile =
"millepede.his");
116 void Write(
const char *rootFileName);
117 void Print(
const char *printFileName);
121 bool readBasic(std::ifstream &aStream, T &outValue);
123 bool readBasicVector(std::ifstream &aStream, std::vector<T> &outVector);
124 bool proceedTo(std::ifstream &aStream,
const TString &pattern);
128 std::pair<TGraph *,Option_t*>
readNextGraph(std::ifstream &file);
129 bool readNext(std::ifstream &file, TH1 *&hist, std::pair<TGraph*,Option_t*> &graphOpt);
130 void read(std::ifstream &stream);
140 theStream(txtFile, ios::in)
143 ::Error(
"ReadPedeHists::ReadPedeHists",
"file %s could not be opened", txtFile);
155 const int aChar = aStream.get();
156 if (!aStream.good())
return false;
162 if (aStream.eof())
return false;
167 if (aStream.fail()) {
176 ::Error(
"ReadPedeHists::readBasic",
"Should never come here!");
185 for (
unsigned int i = 0;
i < outVector.size(); ++
i) {
186 if (!
readBasic(aStream, outVector[
i]))
return false;
195 if (pattern.IsNull())
return true;
196 const char *method =
"ReadPedeHists::proceedTo";
200 line.ReadLine(aStream);
201 if (line.Contains(pattern)) {
202 line.ReplaceAll(pattern,
"");
203 line.ReplaceAll(
" ",
"");
204 if (!line.IsNull()) {
205 ::Warning(method,
"line contains also '%s'", line.Data());
209 ::Warning(method,
"skipping line '%s'", line.Data());
211 }
while (!aStream.eof());
213 ::Error(method,
"pattern '%s' not found", pattern.Data());
219 Int_t &version, Int_t &
type, TString &title)
223 const char *method =
"ReadPedeHists::readNumVersTypeTitle";
225 ::Error(method,
"failed reading hist number");
228 if (!
readBasic(file, key) || key !=
"version") {
229 ::Error(method,
"expect key 'version', got '%s'", key.c_str());
232 ::Error(method,
"failed reading version");
235 if (!
readBasic(file, key) || key !=
"type") {
236 ::Error(method,
"expect key 'type', got '%s'", key.c_str());
238 if (!
readBasic(file,
type)) ::Error(method,
"failed reading type");
240 title.ReadLine(file);
241 Ssiz_t len = title.Length();
242 while (len != kNPOS && len > 0 && title[--len] ==
' ') {}
244 title += Form(
" (version %d)", version);
258 const char *method =
"ReadPedeHists::readNextHist";
261 if (num == -1 || version == -1 ||
type == -1) {
262 ::Error(method,
"Problems reading hist number, version or type, so skip it.");
271 std::vector<Float_t> nBinsUpLow(3, -1.);
272 std::vector<Int_t> underInOver(3, -1);
273 std::vector<Float_t> binContent;
274 Float_t min = 0., max = 0., mean = 0.,
sigma = 0.;
278 if (key ==
"bins,") {
280 if (!
readBasic(file, key) || key !=
"limits") {
281 ::Error(method,
"expect key 'limits', got (%s)", key.c_str());
283 ::Error(method,
"failed reading nBins, xLow, xUp (%f %f %f)",
284 nBinsUpLow[0], nBinsUpLow[1], nBinsUpLow[2]);
286 binContent.resize(
static_cast<unsigned int>(nBinsUpLow[0]));
288 }
else if (key ==
"out-low") {
290 if (!
readBasic(file, key) || key !=
"inside"
291 || !
readBasic(file, key) || key !=
"out-high") {
292 ::Error(method,
"expected keys 'inside' and 'out-high', got (%s)", key.c_str());
294 || underInOver[1] == -1 || underInOver[2] == -1) {
295 ::Error(method,
"failed reading under-, 'in-' and overflow (%d %d %d)",
296 underInOver[0], underInOver[1], underInOver[2]);
298 }
else if (key ==
"bincontent") {
300 if (nBinsUpLow[0] == -1.) {
301 ::Error(method,
"n(bins) (key 'bins') not yet set, bin content cannot be read");
303 ::Error(method,
"failed reading bincontent ");
305 }
else if (key ==
"minmax") {
308 ::Error(method,
"failed reading min or max (%f %f)", min, max);
310 }
else if (key ==
"meansigma") {
313 ::Error(method,
"failed reading mean or sigma (%f %f)", mean,
sigma);
315 }
else if (key ==
"end") {
320 ::Error(method,
"unknown key '%s', try next word", key.c_str());
325 if (nBinsUpLow[1] == nBinsUpLow[2]) {
326 nBinsUpLow[2] = nBinsUpLow[1] + 1.;
327 ::Error(method,
"Hist %d (version %d): same upper and lower edge (%f), set upper %f.",
328 num, version, nBinsUpLow[1], nBinsUpLow[2]);
330 TH1 *h =
new TH1F(Form(
"hist%d_version%d", num, version), title,
331 binContent.size(), nBinsUpLow[1], nBinsUpLow[2]);
332 h->SetBinContent(0, underInOver[0]);
333 for (UInt_t iBin = 1; iBin <= binContent.size(); ++iBin) {
334 h->SetBinContent(iBin, binContent[iBin - 1]);
336 h->SetBinContent(binContent.size() + 1, underInOver[2]);
337 h->SetEntries(underInOver[0] + underInOver[1] + underInOver[2]);
341 h->SetXTitle(
"log_{10}");
342 }
else if (
type != 1) {
343 ::Warning(method,
"Unknown histogram type %d.",
type);
347 Double_t stats[11] = {0.};
349 stats[0] = stats[1] = h->GetEntries();
350 stats[2] = mean * stats[0];
351 stats[3] = (
sigma *
sigma + mean * mean) * stats[0];
355 TPaveText *text =
new TPaveText(.175, .675, .45, .875,
"NDC");
356 text->AddText(Form(
"min = %g", min));
357 text->AddText(Form(
"max = %g", max));
358 text->SetTextAlign(12);
359 text->SetBorderSize(1);
360 h->GetListOfFunctions()->Add(text);
373 Option_t *drawOpt = 0;
381 const char *method =
"ReadPedeHists::readNextGraph";
384 if (num == -1 || version == -1 ||
type == -1) {
385 ::Error(method,
"Problems reading graph number, version or type, so skip it.");
387 return std::make_pair(graph, drawOpt);
394 if (type < 1 || type > 5) {
395 ::Error(method,
"Unknown xy-data type %d, so skip graph.",
type);
400 UInt_t numPoints = 0;
401 std::vector<Float_t> content;
405 if (key ==
"stored") {
406 if (!
readBasic(file, key) || key !=
"not-stored") {
407 ::Error(method,
"expected key 'not-stored', got '%s'", key.c_str());
408 }
else if (!
readBasic(file, numPoints)) {
409 ::Error(method,
"failed reading number of points (%d)", numPoints);
411 }
else if (key ==
"x-y") {
412 if (type < 1 || type > 3) {
413 ::Error(method,
"expect key x-y-dx-dy for type %d, found x-y",
type);
415 content.resize(numPoints * 2);
417 ::Error(method,
"failed reading x-y content%s",
418 (!numPoints ?
" since n(points) (key 'stored') not yet set" :
""));
420 }
else if (key ==
"x-y-dx-dy") {
421 if (type < 4 || type > 5) {
422 ::Error(method,
"expect key x-y for type %d, found x-y-dx-dy",
type);
424 content.resize(numPoints * 4);
426 ::Error(method,
"failed reading x-y-dx-dy content%s",
427 (!numPoints ?
" since n(points) (key 'stored') not yet set" :
""));
429 }
else if (key ==
"end") {
434 ::Error(method,
"unknown key '%s', try next word", key.c_str());
440 TGraphErrors *graphE =
new TGraphErrors(numPoints);
441 for (
unsigned int i = 0;
i < content.size();
i += 4) {
442 graphE->SetPoint (
i/4, content[
i] , content[
i+1]);
443 graphE->SetPointError(
i/4, content[
i+2], content[
i+3]);
447 }
else if (
type >= 1 &&
type <= 3) {
448 graph =
new TGraph(numPoints);
449 for (
unsigned int i = 0;
i < content.size();
i += 2) {
450 graph->SetPoint(
i/2, content[
i], content[
i+1]);
454 }
else if (
type == 2) {
456 }
else if (
type == 3) {
459 if (TString(drawOpt).Contains(
"P")) graph->SetMarkerStyle(20);
462 if (graph) graph->SetNameTitle(Form(
"graph%d_version%d", num, version), title);
463 return std::make_pair(graph, drawOpt);
468 std::pair<TGraph*,Option_t*> &graphOpt)
476 if (file.eof())
break;
478 if (file.fail() || (
type !=
"Histogram" &&
type !=
"XY-Data")) {
481 if (line !=
"" && line.Length() != line.CountChar(
' ')) {
482 ::Error(
"ReadPedeHists::readNext",
483 "Expect 'Histogram' or 'XY-Data', but failed, line is '%s'",
485 if (
proceedTo(file,
"end of")) line.ReadLine(file);
491 if (hist || graphOpt.first)
break;
494 return (hist || graphOpt.first);
504 std::pair<TGraph*, Option_t*> graphOpt(0,0);
505 while (
readNext(file, hist, graphOpt)) {
516 const Int_t nHistX = 3;
517 const Int_t nPixelX = 700;
518 const Int_t nHistY = 2;
519 const Int_t nPixelY = 500;
520 Int_t last = nHistX * nHistY;
524 if (last >= nHistX * nHistY) {
526 theCanvases.push_back(
new TCanvas(Form(
"hists%d", iH),
"",
527 canCorner, canCorner, nPixelX, nPixelY));
536 last = nHistX * nHistY;
539 if (last >= nHistX * nHistY) {
541 theCanvases.push_back(
new TCanvas(Form(
"graphs%d", iH),
"",
542 canCorner, canCorner, nPixelX, nPixelY));
556 if (iC == iE)
return;
558 theCanvases.front()->Print(Form(
"%s[", printFileName));
560 (*iC)->Print(printFileName);
563 theCanvases.front()->Print(Form(
"%s]", printFileName));
572 ::Info(
"ReadPedeHists::Write",
"(Re-)Creating ROOT file %s.", rootFileName);
574 TDirectory *oldDir = gDirectory;
575 TFile *rootFile = TFile::Open(rootFileName,
"RECREATE");
577 for (std::vector<TH1*>::iterator iH =
theHists.begin(), iE =
theHists.end();
582 for (std::vector<std::pair<TGraph*,Option_t*> >::iterator iG =
theGraphOpts.begin(),
584 (*iG).first->Write();
600 const bool oldBatch = gROOT->IsBatch();
601 if (opt.Contains(
"nodraw")) {
602 opt.ReplaceAll(
"nodraw",
"");
603 gROOT->SetBatch(
true);
608 if (opt.Contains(
"print")) {
609 opt.ReplaceAll(
"print",
"");
610 reader.
Print(TString(Form(
"%s.ps", txtFile)));
613 if (opt.Contains(
"write")) {
614 opt.ReplaceAll(
"write",
"");
615 reader.
Write(TString(Form(
"%s.root", txtFile)));
618 gROOT->SetBatch(oldBatch);
619 opt.ReplaceAll(
" ",
"");
621 ::Warning(
"readPedeHists",
"Unknown option '%s', know 'nodraw', 'print' and 'write'.",
void readNumVersTypeTitle(std::ifstream &file, Int_t &num, Int_t &version, Int_t &type, TString &title)
std::vector< TCanvas * > theCanvases
bool readBasicVector(std::ifstream &aStream, std::vector< T > &outVector)
bool readNext(std::ifstream &file, TH1 *&hist, std::pair< TGraph *, Option_t * > &graphOpt)
std::vector< TH1 * > theHists
TH1 * readNextHist(std::ifstream &file)
void read(std::ifstream &stream)
std::vector< std::pair< TGraph *, Option_t * > > theGraphOpts
void Write(const char *rootFileName)
ReadPedeHists(const char *txtFile)
bool proceedTo(std::ifstream &aStream, const TString &pattern)
void Print(const char *printFileName)
std::pair< TGraph *, Option_t * > readNextGraph(std::ifstream &file)
bool readBasic(std::ifstream &aStream, T &outValue)
real(mps), dimension(nplan) sigma
measurement sigma (hit)
void readPedeHists(Option_t *option="", const char *txtFile="millepede.his")