--- /dev/null
+/**
+ * @file ChargeSpektrumFunctions.c
+ * @brief This file contains functions used in ChargeSpectrum
+ *
+ * It is used, to make #ChargeSpectrum.c shorter and easier to maintain
+ * Generally speaking, all type of helper functions are here. For example for comparing plots of different Runs or write ourt summary tables.
+ *
+ */
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+#include <TPaveText.h>
+#include <TLatex.h>
+#include <THStack.h>
+#include <TCanvas.h>
+#include <TH2C.h>
+#include <TTimeStamp.h>
+#include <TGraphErrors.h>
+#include "help.h"
+#include "HistogramType.h"
+#include "Run.h"
+
+using namespace std;
+
+Int_t* ReadRunList();
+Int_t ReadRunList(std::vector<int>*);
+void InterpreteUserInput(TString, std::vector<int>*, std::vector<Bool_t>*, std::vector<Bool_t>*, std::vector<Bool_t>*, TString* analysisis);
+Bool_t plotAllRuns(vector<HistogramType*>*, Bool_t unZoom);
+// vector wich is used to save a good title by the function FindGoodTitle()
+vector<TString> headerStringsVector;
+// vector wich is used to save good legend entries by the function FindGoodTitle()
+vector<TString> legendStringsVector;
+TString folderadd;
+/**
+ * @brief This functions analyzis the runs given for camparison and finds simmilarities and differences
+ *
+ * @input ptCompareHistogramClassVector a Vector of type HistogramType
+ *
+ * After finding the simmilarities and differences a suggestion for the overall title is given.
+ * If findind a common nominator fails it return a false value
+ *
+ */
+Bool_t FindGoodTitle(vector<HistogramType*>* ptCompareHistogramClassVector, vector<TH1FO*>* ptCompareHistogramVector = 0);
+Bool_t FindGoodTitle(vector<TH1FO*>* ptCompareHistogramVector);
+Bool_t FindGoodTitle();
+
+
+
+/** @brief A function to plot TH1F histograms of different runs into one file
+ *
+ * You push in #ChargeSpectrum.c a pointer of the type TH1F into the vector #compareHistogramVector and then
+ * you can compare different histograms of the different runs.
+ *
+ * Call #writeObservableToFile() in #ChargeSpectrum.c to create a file with all the TH1F histogram data
+ *
+ */
+/** @brief Prints a line with fixed width in the summary table */
+template<typename varType> string printTableElement(varType t1, varType t2, const int precision=1);
+
+/** @brief A function to compare one type of histogram TH1F, plots them in same canvas
+ *
+ * You must push TH1F pointers to #compareHistogramVector to be able to use this
+ *
+ */
+Bool_t CompareHistograms(vector<TH1FO*>* ptCompareHistogramVector, TString titlestr = "", TString YAxisTitle = "");
+
+Bool_t writeOneHistogramTypeToFile(vector<HistogramType*>*);
+
+
+/** @brief A function to setup file path and other variables
+ *
+ */
+void Init(TString);
+
+
+/** @brief A function to plot ntuplöe data into a canvas
+ *
+ */
+TCanvas* plot1DData(std::vector<TNtupleO*>* ntuplepvectorpointer, Bool_t verbose=0, Bool_t logscale=0, TString titlestr="", TString legendstr="" );
+
+/** @brief A function to write data from TNtuple to a file. File is save with the prefix "Oberservable_" in the result folder
+ * */
+Bool_t writeNTupleVectorToFile(std::vector<TNtupleO*>* ntuplepvectorpointer);
+
+Bool_t writeObservableToFile(vector<TH1FO*>* ptCompareHistogramVector);
+
+// Write one histogram to its own file
+Bool_t writeHistogramToFile(TH1FO* onehistogram);
+/** @brief A vector able to hold pointer of type #Run::histogramstruct
+ *
+ * You push in pointer of the type Run::histogramstruct in ChargeSpectrum.C and then
+ * compare different histograms of the same run.
+ *
+ * See Run::plotCompareHistograms( ) for more information and usage.
+ *
+ */
+/** @brief Prints a summary table with all the analyzed run data */
+Bool_t printSummaryTable(vector<HistogramType*>*);
+/** @brief Tests if all runs in vector are from same type, calibrated or not calibrated */
+Bool_t testifMixingCalibration(vector<HistogramType*>*);
+/** @brief Turns a value into a string with fixed precision */
+string to_str_w_prec(const Float_t a_value, int precision = 1);
+vector<HistogramType*> compareHistogramClassVectorMABSBot;
+//vector<HistogramType*> compareHistogramClassVector, compareHistogramClassVector2, compareHistogramClassVector3, compareHistogramClassVector4, compareHistogramClassVector5, compareHistogramClassVector6, compareHistogramClassVector7, compareHistogramClassVector8, compareHistogramClassVector9, compareHistogramClassVectorMABSBot;
+vector< vector<HistogramType*> > compareHistogramClassVectorVector;
+//vector<TH1FO*> compareHistogramVector, compareHistogramVector2, compareHistogramVector3, compareHistogramVector4, compareHistogramVector5, compareHistogramVector6, compareHistogramVector7, compareHistogramVector8, compareHistogramVector9;
+vector< vector<TH1FO*> > compareHistogramVectorVector;
+// vector<TNtupleO*> ntupleVector, ntupleVector2, ntupleVector3, ntupleVector4, ntupleVector5, ntupleVector6, ntupleVector7, ntupleVector8, ntupleVector9;
+vector< vector<TNtupleO*> > ntupleVectorVector;
+TString ownpath = "";
+TString savepathresults;
+TString analysisType = "";
+
+void setCustomPath(TString setOwnpath)
+{
+ ownpath = setOwnpath;
+}
+
+void ChargeSpektrum(Int_t runnumber)
+{
+ cout << endl << colorred << "Given parameters have wrong format, please enter integer run numbers devided by '" << colorreset << colorwhite << "," << colorreset << colorred << "' and surrounded by '" << colorreset << colorwhite << "\"" << colorreset << colorred << "'." << endlr;
+ cout << "For example run: root -l 'ChargeSpektrum.c+(\"342815,342816\")'" << endl;
+ exit(1);
+}
+
+void ChargeSpektrum(Int_t runnumber, Int_t runnumber2)
+{
+ cout << endl << colorred << "Given parameters have wrong format, please enter integer run numbers devided by '" << colorreset << colorwhite << "," << colorreset << colorred << "' and surrounded by '" << colorreset << colorwhite << "\"" << colorreset << colorred << "'." << endlr;
+ cout << "For example run: " << colorwhite << "root -l 'ChargeSpektrum.c+(\"342815,342816\")'" << endl;
+ exit(1);
+}
+
+void Init()
+{
+ // FindGoodTitle();
+ TTimeStamp timestamp = TTimeStamp();
+ savepathresults = Form("./results/%d%06d %s", (int)timestamp.GetDate(kFALSE), (int)timestamp.GetTime(kFALSE), analysisType.Data());
+
+}
+
+// in the command line one can add labels, by printing a equal sign '=' and a string escaped by the question sign '§', for example:
+// root -l -b -q 'ChargeSpektrum.c+("40100=§5 V§,40097=§10 V§,40091=§20 V§,40103=§30 V§,40106=§40 V§")'
+void InterpreteUserInput(TString runnumber, std::vector<int> *runList, std::vector<Bool_t> *runListForceAnalysis, std::vector<TString> *runListCustomTitle, std::vector<TString> *sumuprunList, TString *analysisis)
+{
+ if (runnumber.Length() > 0)
+ {
+ if (runnumber.Contains("-")) {
+ TObjArray* runarray = runnumber.Tokenize("-");
+ if (runarray->GetEntries()==2)
+ {
+ TObjString* tempstrobj;
+ tempstrobj=static_cast<TObjString*>(runarray->At(0));
+ if (tempstrobj->GetString().Length()>0)
+ {
+ Int_t tempintstart = tempstrobj->GetString().Atoi();
+ tempstrobj=static_cast<TObjString*>(runarray->At(1));
+ if (tempstrobj->GetString().Length()>0)
+ {
+ TString tempstrend = tempstrobj->GetString().ReplaceAll("!","");
+ Int_t tempintend = tempstrend.Atoi();
+ if (tempintend-tempintstart > 0)
+ {
+ for (Int_t i=tempintstart; i <= tempintend; i++)
+ {
+ runList->push_back(i);
+ if (runnumber.Contains("!")) {
+ runListForceAnalysis->push_back(kTRUE);
+ } else {
+ runListForceAnalysis->push_back(kFALSE);
+ }
+ numberRuns++;
+ }
+ }
+ else
+ cout << coloryellow << "Invalid run number range "<< colorreset << colorwhite << tempintstart << " till " << tempintend << endlr;
+ }
+ else
+ cout << coloryellow << "Invalid run number "<< colorreset << colorwhite << tempstrobj->GetString() << endlr;
+
+ }
+ else
+ cout << coloryellow << "Invalid run number "<< colorreset << colorwhite << tempstrobj->GetString() << endlr;
+ }
+ else
+ {
+ cout << endl << colorred << "Given parameters have wrong format, please enter integer run numbers devided by '" << colorreset << colorwhite << "," << colorreset << colorred << " or 2 runnumbers devided by " << colorreset << colorwhite << "-" << colorreset << colorred << "' and surrounded by '" << colorreset << colorwhite << "\"" << colorreset << colorred << "'." << endlr;
+ cout << "For example run: " << colorwhite << "root -l 'ChargeSpektrum.c+(\"342815,342816\")'" << endl;
+ exit(1);
+ }
+
+ } else {
+ TObjArray* runarray = runnumber.Tokenize(","); // seperate run numbers by ','
+ if (runarray->GetEntries()>0)
+ {
+ TObjString* tempstrobj;
+ for (Int_t i=0; i < runarray->GetEntries(); i++)
+ {
+ tempstrobj=static_cast<TObjString*>(runarray->At(i));
+ if (tempstrobj->GetString().Length()>0)
+ {
+ TString sumrunsstr = "";
+ TObjArray* sumrunarray = tempstrobj->GetString().Tokenize("+");
+ TObjString* sumuprunsstrobj;
+ for (Int_t j=0; j < sumrunarray->GetEntries(); j++)
+ {
+ sumuprunsstrobj=static_cast<TObjString*>(sumrunarray->At(j));
+ TString currunnumberstr = sumuprunsstrobj->GetString();
+ Int_t tempint = currunnumberstr.Atoi();
+ if (tempint > 0)
+ {
+ runList->push_back(tempint);
+ if (currunnumberstr.Contains("!"))
+ runListForceAnalysis->push_back(kTRUE);
+ else
+ runListForceAnalysis->push_back(kFALSE);
+ if (currunnumberstr.Contains("=")) {
+ cout << colorcyan << currunnumberstr << " ---> " << " Index: " << currunnumberstr.Index("§") << " ---> " << currunnumberstr(currunnumberstr.Index("§")+2,currunnumberstr.Length()-currunnumberstr.Index("§")-4) << endlr;
+ runListCustomTitle->push_back(currunnumberstr(currunnumberstr.Index("§")+2,currunnumberstr.Length()-currunnumberstr.Index("§")-4));
+ } else {
+ runListCustomTitle->push_back("");
+ }
+ sumrunsstr.Append(Form("%d,",tempint));
+ numberRuns++;
+ }
+ else
+ cout << coloryellow << "Invalid run number "<< colorreset << colorwhite << tempint << endlr;
+ }
+ sumuprunList->push_back(sumrunsstr);
+ }
+ else
+ cout << coloryellow << "Invalid run number "<< colorreset << colorwhite << tempstrobj->GetString() << endlr;
+ }
+ }
+ else
+ {
+ cout << endl << colorred << "Given parameters have wrong format, please enter integer run numbers devided by '" << colorreset << colorwhite << "," << colorreset << colorred << "' and surrounded by '" << colorreset << colorwhite << "\"" << colorreset << colorred << "'." << endlr;
+ cout << "For example run: " << colorwhite << "root -l 'ChargeSpektrum.c+(\"342815,342816\")'" << endl;
+ exit(1);
+ }
+ }
+ if (runnumber.Contains(";")) {
+ *analysisis = runnumber(runnumber.First(";")+1,runnumber.Length());
+ analysisis->ToLower();
+ // cout << colorcyan << "*analysisis: " << *analysisis << endlr;
+ }
+ }
+ else
+ {
+ /// number of runs to be analyzed, number of lines read by @c ReadRunList()
+ ReadRunList(runList);
+ }
+}
+
+
+Int_t ReadRunList(std::vector<int>* runlist)
+{
+ std::ifstream file("runlist.txt");
+ Int_t row;
+ while (file >> row)
+ {
+ try
+ {
+ if (row > 0)
+ {
+ runlist->push_back(row);
+ numberRuns++;
+ }
+ }
+ catch(...)
+ {
+ cout << "File ended";
+ }
+ }
+ return numberRuns;
+}
+
+
+
+TCanvas*
+plot1DData(std::vector<TNtupleO*>* ntuplepvectorpointer, Bool_t verbose, Bool_t logscale, TString titlestr, TString legendstr )
+{
+ if (ntuplepvectorpointer != nullptr)
+ {
+ if (ntuplepvectorpointer->size() > 0) {
+ TNtupleO* ntuplepointer = ntuplepvectorpointer->at(0);
+ if (ntuplepointer->GetEntries() > 0) {
+
+ vector<HistogramType*> compareHistogramClassVector;
+ Float_t x_minimum =999999999;
+ Float_t x_maximum =0;
+ Float_t y_minimum =999999999;
+ Float_t y_maximum =0;
+ for (UInt_t ntuplei=0; ntuplei < ntuplepvectorpointer->size(); ntuplei++)
+ {
+ TNtupleO* curTuple = ntuplepvectorpointer->at(ntuplei);
+ if (curTuple->itsHistogramType != 0)
+ compareHistogramClassVector.push_back(curTuple->itsHistogramType);
+ x_minimum = x_minimum > curTuple->GetMinimum("x")?curTuple->GetMinimum("x"):x_minimum;
+ x_maximum = x_maximum < curTuple->GetMaximum("x")?curTuple->GetMaximum("x"):x_maximum;
+ y_minimum = y_minimum > curTuple->GetMinimum("y")?curTuple->GetMinimum("y"):y_minimum;
+ y_maximum = y_maximum < curTuple->GetMaximum("y")?curTuple->GetMaximum("y"):y_maximum;
+ }
+ FindGoodTitle(&compareHistogramClassVector);
+ gROOT->SetStyle("RadHard_NoTitle");
+
+ TString legendEntry;
+
+ TPaveText *owntitle = new TPaveText(0.15,0.9,0.930401,0.995,"nbNDC");
+ owntitle->SetFillStyle(0);
+ owntitle->SetBorderSize(0);
+ owntitle->SetTextAlign(22);
+ owntitle->SetTextSize(0.04);
+ owntitle->SetTextFont(42);
+
+ // legend entries
+ Float_t height = ntuplepvectorpointer->size() * 0.03;
+ // TLegend* leg1 = new TLegend(0.3,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ TLegend* leg1 = new TLegend(0.6,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ leg1->SetTextSize(0.025);
+ leg1->SetFillStyle(1001);
+ leg1->SetTextFont(132);
+ leg1->SetFillColor(0);
+ leg1->SetBorderSize(0);
+
+ TString canvastitle = Form("%s", ntuplepointer->GetName());
+ TTimeStamp* time = new TTimeStamp();
+ TString canvasname = Form("%s_%d",ntuplepointer->GetName(),(int)time->GetNanoSec()/100000);
+ //TString canvasname = Form("%d",time->GetNanoSec());
+ if (titlestr.Length()>0)
+ canvastitle = titlestr;
+ TCanvas* canvas = new TCanvas(canvasname, canvastitle, 1200, 700);
+ TPad *grid = new TPad("grid","",0,0,1,1);
+ grid->Draw();
+ grid->cd();
+ grid->SetGrid();
+ grid->SetFillStyle(4000);
+
+ if (logscale) {
+ gPad->SetLogy(1);
+ }
+
+ for(UInt_t runi=0;runi<ntuplepvectorpointer->size();runi++) // loop over runs or other stacked elements in vector<TNtuple*>
+ {
+ TNtupleO* ntuplepointer = ntuplepvectorpointer->at(runi);
+ ntuplepointer->SetLineColor(compareHistogramClassVector.at(runi)->color);
+ ntuplepointer->SetLineWidth(2);
+ ntuplepointer->Draw("x:y:xerr:yerr","","goff");
+
+ if (legendStringsVector.size() > 0)
+ legendEntry = Form("%s %s", ntuplepointer->Title.Data(), legendStringsVector.at(runi).Data());
+ leg1->AddEntry(ntuplepointer, legendEntry, "l");
+ leg1->Draw("SAME");
+
+ TGraphErrors *gr = new TGraphErrors(ntuplepointer->GetEntries(),ntuplepointer->GetV1(),ntuplepointer->GetV2(),ntuplepointer->GetV3(),ntuplepointer->GetV4());
+ if ( ntuplepointer->Title.Length() > 0 ) { gr->SetTitle(ntuplepointer->Title); } else { gr->SetTitle("");}
+ if ( ntuplepointer->xaxisTitle.Length() > 0 ) { gr->GetXaxis()->SetTitle(ntuplepointer->xaxisTitle); } else { gr->GetXaxis()->SetTitle("");}
+ if ( ntuplepointer->yaxisTitle.Length() > 0 ) { gr->GetYaxis()->SetTitle(ntuplepointer->yaxisTitle); } else { gr->GetYaxis()->SetTitle("");}
+ if (ntuplepointer->itsHistogramType != 0) gr->SetMarkerColor(ntuplepointer->itsHistogramType->color); else gr->SetMarkerColor(runi); gr->SetMarkerStyle(21);
+ if (!runi) gr->Draw("ALP"); else gr->Draw("LP");
+ gr->GetXaxis()->SetRangeUser(x_minimum*0.9,x_maximum*1.1);
+ gr->GetYaxis()->SetRangeUser(y_minimum*0.9,y_maximum*1.1);
+
+ owntitle->Clear();
+ owntitle->AddText(trimRunnumberAtBegin(ntuplepvectorpointer->at(runi)->GetName()));
+ if (headerStringsVector.size() > 0) {
+ owntitle->Clear();
+ owntitle->AddText(Form("%s", headerStringsVector.at(1).Data()));
+ owntitle->AddText(headerStringsVector.at(2));
+ }
+ owntitle->Draw("SAME");
+ }
+ canvas->Update();
+ // canvas -> SaveAs( savepathresults + "/" + runcode + " " + onehistogram->GetName() + ".eps");
+
+ TImageDump *img = new TImageDump(savepathresults + folderadd + "/" + ntuplepointer->GetName() + ".png");
+ canvas->Paint();
+ img->Close();
+
+ writeNTupleVectorToFile(ntuplepvectorpointer);
+ return canvas;
+ }
+ }
+ }
+ return nullptr;
+}
+
+
+Bool_t writeNTupleVectorToFile(std::vector<TNtupleO*>* ntuplepvectorpointer)
+{
+ if (ntuplepvectorpointer != nullptr)
+ {
+ if (ntuplepvectorpointer->size() > 0) {
+ TNtupleO* ntuplepointer = ntuplepvectorpointer->at(0);
+ system("mkdir \""+ savepathresults + folderadd + "/\"" + " -p");
+ TString filename = savepathresults + folderadd + "/" + Form("Observable_%s.dat", ntuplepointer->GetName());
+
+ TString header = "";
+ for(UInt_t runi=0;runi<ntuplepvectorpointer->size();runi++) // loop over runs or other stacked elements in vector<TNtupleO*>
+ {
+ header += "x\ty\txerr\tyerr\t";
+ }
+ fstream* fout = new fstream(filename,ios::out);
+ *fout << header << endl;
+
+ // find max entries
+ Int_t maxEntries = 0;
+ for(UInt_t runi=0;runi<ntuplepvectorpointer->size();runi++) {
+ ntuplepointer = ntuplepvectorpointer->at(runi);
+ maxEntries = (ntuplepointer->GetEntries() > maxEntries)?ntuplepointer->GetEntries():maxEntries;
+ }
+
+
+ TString outline="";
+ for(int i=0;i < maxEntries;i++) {
+ for(UInt_t runi=0;runi<ntuplepvectorpointer->size();runi++) // loop over runs or other stacked elements in vector<TNtupleO*>
+ {
+ ntuplepointer = ntuplepvectorpointer->at(runi);
+ ntuplepointer->GetEntry(i);
+ Float_t *p = ntuplepointer->GetArgs();
+ outline+=Form("%.2f\t%.2f\t%.2f\t%.2f\t", p[0], p[1], p[2], p[3]);
+ }
+ *fout<<outline<<endl;
+ outline="";
+ }
+ fout->close();
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+Bool_t writeOneHistogramTypeToFile(vector<HistogramType*>* ptCompareHistogramClassVector)
+{
+ if (ptCompareHistogramClassVector->size() > 0)
+ {
+ system("mkdir \""+ savepathresults + folderadd + "/\"" + " -p");
+
+ TString filename = Form("%s%s/Spectrum_%d_%s", savepathresults.Data(), folderadd.Data(), ptCompareHistogramClassVector->at(0)->labbook->runnumber, ptCompareHistogramClassVector->at(0)->histogramdescription.Data());
+
+ TString header = "";
+ for(UInt_t runi=0;runi<ptCompareHistogramClassVector->size();runi++) // loop over runs read from file
+ {
+ if (ptCompareHistogramClassVector->at(runi) != nullptr)
+ {
+ // header += Form("#%s, %s\n", ptCompareHistogramClassVector->at(runi)->humanreadablestr.Data(), ptCompareHistogramClassVector->at(runi)->histogramdescription.Data());
+ }
+ }
+ filename+=".dat";
+ fstream* fout = new fstream(filename,ios::out);
+ for(UInt_t runi=0;runi<ptCompareHistogramClassVector->size();runi++) // loop over runs read from file
+ {
+ header += Form("Energy\tSeed\tSum\tVeto\t");
+ }
+ header += Form("\n");
+ for(UInt_t runi=0;runi<ptCompareHistogramClassVector->size();runi++) // loop over runs read from file
+ {
+ header += Form("%s\t\t\t\t", ptCompareHistogramClassVector->at(runi)->iscalibrated?"e":"ADU");
+ }
+ header += Form("\n");
+ for(UInt_t runi=0;runi<ptCompareHistogramClassVector->size();runi++) // loop over runs read from file
+ {
+ header += Form("%s\t%s\t%s\t%s\t", ptCompareHistogramClassVector->at(runi)->humanreadablestr.Data(), ptCompareHistogramClassVector->at(runi)->humanreadablestr.Data(), ptCompareHistogramClassVector->at(runi)->humanreadablestr.Data(), ptCompareHistogramClassVector->at(runi)->humanreadablestr.Data());
+ }
+ *fout << header << endl;
+ TString outline;
+ for(Int_t bin=1;bin<=ptCompareHistogramClassVector->at(0)->Seed->GetNbinsX();bin++)
+ {
+ outline ="";
+ for(UInt_t runi=0;runi<ptCompareHistogramClassVector->size();runi++) // loop over runs read from file
+ {
+ outline+=Form("%.1f\t%.1f\t%.1f\t%.1f\t", ptCompareHistogramClassVector->at(runi)->Seed->GetBinCenter(bin), ptCompareHistogramClassVector->at(runi)->Seed->GetBinContent(bin), (*ptCompareHistogramClassVector->at(runi)->Sum)->GetBinContent(bin), ptCompareHistogramClassVector->at(runi)->Veto->GetBinContent(bin));
+ }
+ *fout<<outline<<endl;
+ }
+ fout->close();
+ return 0;
+
+ }
+ return 0;
+}
+
+
+Bool_t writeHistogramToFile(TH1FO* onehistogram)
+{
+ Run* runp = onehistogram->itsHistogramType->run;
+ system("mkdir \""+ runp->savepathresults + "\" -p");
+ TString filename= runp->savepathresults + "/" + runp->runcode + " " + onehistogram->GetName() + " hist.dat";
+ fstream* fout = new fstream(filename,ios::out);
+
+ TString header = Form("#bin [ADU]\tCounts");
+ *fout << header << endl;
+
+ TString outline;
+ for(Int_t bin=1;bin<=onehistogram->GetNbinsX();bin++)
+ {
+ outline=Form("%.3f\t%.3f", onehistogram->GetBinCenter(bin), onehistogram->GetBinContent(bin));
+ *fout<<outline<<endl;
+ }
+ fout->close();
+ return 0;
+}
+
+
+Bool_t writeObservableToFile(vector<TH1FO*>* ptCompareHistogramVector)
+{
+ if (numberRuns>0)
+ {
+
+ TH1FO* histogrampfirst = ptCompareHistogramVector->at(0);
+ system("mkdir \""+ savepathresults + folderadd + "/\"" + " -p");
+ TString filename = savepathresults + folderadd + "/Spectra " + histogrampfirst->GetName();
+ TString header = "";
+ for(Int_t runi=0;runi<numberRuns;runi++) // loop over runs read from file
+ {
+ if (runs[runi] != nullptr)
+ {
+ if (!runs[runi]->error)
+ {
+ filename+= Form("_%d",runs[runi]->labbook.runnumber);
+ header += Form("#%s, %lu frames\n", runs[runi]->humanreadablestr.Data(), runs[runi]->frames_found);
+ }
+ }
+ }
+ filename+=".dat";
+ fstream* fout = new fstream(filename,ios::out);
+ header += Form("#");
+ for (vector<TH1FO*>::iterator curHistogram = ptCompareHistogramVector->begin(); curHistogram != ptCompareHistogramVector->end(); curHistogram++) {
+ header += Form("bin\t%s\t",(*curHistogram)->GetName());
+ }
+ *fout << header << endl;
+ TString outline;
+ for(Int_t bin=1;bin<=histogrampfirst->GetNbinsX();bin++)
+ {
+ outline ="";
+ for (vector<TH1FO*>::iterator curHistogram = ptCompareHistogramVector->begin(); curHistogram != ptCompareHistogramVector->end(); curHistogram++) {
+ outline+=Form("%.1f\t%.1f\t", (*curHistogram)->GetBinCenter(bin), (*curHistogram)->GetBinContent(bin));
+ }
+ *fout<<outline<<endl;
+ }
+ fout->close();
+
+
+ // for (vector<TH1FO*>::iterator curHistogram = ptCompareHistogramVector->begin(); curHistogram != ptCompareHistogramVector->end(); curHistogram++) {
+ // writeHistogramToFile(curHistogram);
+ // }
+ return 0;
+
+ }
+ return 0;
+}
+
+Bool_t CompareHistograms(vector<TH1FO*>* ptCompareHistogramVector, TString titlestr, TString YAxisTitle)
+{
+ if (ptCompareHistogramVector->size() > 0)
+ {
+ FindGoodTitle(ptCompareHistogramVector);
+ cout << "Returned from find good title" << endlr;
+
+ gROOT->SetStyle("RadHard_NoTitle");
+
+ // legend entries
+ Float_t height = ptCompareHistogramVector->size() * 0.03;
+ // TLegend* leg1 = new TLegend(0.3,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ TLegend* leg1 = new TLegend(0.1,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ leg1->SetTextSize(0.025);
+ leg1->SetNColumns(3);
+ leg1->SetFillStyle(1001);
+ leg1->SetTextFont(132);
+ leg1->SetFillColor(0);
+ leg1->SetBorderSize(0);
+
+ TString legendEntry;
+
+ TPaveText *owntitle = new TPaveText(0.15,0.9,0.930401,0.995,"nbNDC");
+ owntitle->SetFillStyle(0);
+ owntitle->SetBorderSize(0);
+ owntitle->SetTextAlign(22);
+ owntitle->SetTextSize(0.04);
+ owntitle->SetTextFont(42);
+
+ Float_t lastbin1=0;
+ Float_t heighestval1=0;
+ TString canvastitle = Form("%s", trimRunnumberAtBegin(ptCompareHistogramVector->at(0)->GetName()).Data());
+ TTimeStamp* time = new TTimeStamp();
+ TString canvasname = Form("%s_%d",ptCompareHistogramVector->at(0)->GetName(),(int)time->GetNanoSec()/100000);
+ //TString canvasname = Form("%d",time->GetNanoSec());
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramVector->size(); histogrami++)
+ {
+ TH1F* curhistogramclone = (TH1F*) ptCompareHistogramVector->at(histogrami)->Clone();
+ heighestval1 = (curhistogramclone->GetMaximum()>heighestval1?curhistogramclone->GetMaximum():heighestval1);
+ canvastitle+= Form("_%s",getRunnumberAtBegin(curhistogramclone->GetName()).Data());
+ }
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramVector->size(); histogrami++)
+ {
+ TH1F* curhistogramclone = (TH1F*) ptCompareHistogramVector->at(histogrami)->Clone();
+ lastbin1 = (curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval1/20,1))>lastbin1)?curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval1/20,1)):lastbin1;
+ }
+ TCanvas* canvas = new TCanvas(canvasname, canvastitle, 1200, 700);
+ TPad *grid = new TPad("grid","",0,0,1,1);
+ grid->Draw();
+ grid->cd();
+ grid->SetGrid();
+ grid->SetFillStyle(4000);
+
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramVector->size(); histogrami++)
+ {
+ TH1F* curhistogramclone = (TH1F*) ptCompareHistogramVector->at(histogrami)->Clone();
+ if (titlestr.Length() > 0) curhistogramclone->SetName(titlestr);
+ if (YAxisTitle.Length() > 0) curhistogramclone->SetYTitle(YAxisTitle);
+ curhistogramclone->SetLineColor(rootcolors[histogrami%13]);
+ curhistogramclone->SetLineWidth(curhistogramclone->GetLineWidth()+1);
+ curhistogramclone->Draw("SAME");
+
+ // legendEntry = Form("%s %s", getRunnumberAtBegin(curhistogramclone->GetName()).Data(), curhistogramclone->GetTitle());
+ legendEntry = Form("%s", curhistogramclone->GetTitle());
+ if (legendStringsVector.size() > 0) {
+ legendEntry = Form("%s", legendStringsVector.at(histogrami).Data());
+ }
+ leg1->AddEntry(curhistogramclone, legendEntry, "l");
+ leg1->Draw("SAME");
+
+ curhistogramclone->SetAxisRange(0,lastbin1*1.1,"X");
+ // curhistogramclone->GetYaxis()->UnZoom();
+ curhistogramclone->GetYaxis()->SetRangeUser(1,heighestval1*1.4);
+ if (curhistogramclone->GetNbinsX() < 20) {
+ curhistogramclone->GetXaxis()->UnZoom();
+ curhistogramclone->GetYaxis()->UnZoom();
+ }
+ // canvas->Update();
+
+ owntitle->Clear();
+ owntitle->AddText(trimRunnumberAtBegin(curhistogramclone->GetName()));
+ if (headerStringsVector.size() > 0) {
+ owntitle->Clear();
+ owntitle->AddText(Form("%s", headerStringsVector.at(1).Data()));
+ owntitle->AddText(headerStringsVector.at(2));
+ }
+ owntitle->Draw("SAME");
+
+ // gPad->SetLogy(1);
+ // curhistogramclone->GetYaxis()->UnZoom();
+ }
+ canvas->Update();
+ // gPad->Modified(); gPad->Update();
+ MSaveBigPNG(canvas, savepathresults + folderadd + "/" + canvastitle + ".png");
+
+ TImageDump *img = new TImageDump(savepathresults + folderadd + "/" + canvastitle + ".png");
+ canvas->Paint();
+ img->Close();
+
+ TFile *f = new TFile(savepathresults + folderadd + "/" + canvastitle + ".root","RECREATE");
+ f->cd();
+ f->Append(canvas);
+ //f->Append(img);
+ f->Write();
+
+ return 0;
+ }
+ return 1;
+}
+
+/** @brief sets the style for the ROOT plots
+ *
+ * This code block is used to init the global ROOT plotting style, it is included in the ChargeSpectrum main function
+ */
+Bool_t setStyle()
+{
+ ////////////////////////////////////////////////////////////////////////////
+ // //
+ // who: Pete Alonzi (lpa2a@virginia.edu) //
+ // what: rootlogon file (~/.rootlogon.C) //
+ // when: last update: 2009_June_11 //
+ // where: galileo.phys.virginia.edu //
+ // why: change the default root canvas to acceptable configuration //
+ // //
+ // This file is run when you open root. //
+ // Just place it in your home directory and it works automatically. //
+ // If you make a change to this file simply start //
+ // a new root session and the changes will be implemented. //
+ // //
+ // If you did not install roofit then there will be an error //
+ // message when you login, it can be ignored. //
+ // //
+ ////////////////////////////////////////////////////////////////////////////
+
+ // Definition of new styles
+ TStyle *Nab_collaboration = new TStyle("RadHard_AutoTitle","How we like it");
+ TStyle *Nab_collaboration_work = new TStyle("RadHard_NoTitle","How we like it without title");
+
+ // Set the default parameters for style Nab_collaboration
+ Nab_collaboration->SetCanvasBorderMode(0); // Removes Canvas Border
+ Nab_collaboration->SetPadBorderMode(0); // Removes Pad Border
+ Nab_collaboration->SetCanvasColor(0); // Changes Canvas color to white
+ Nab_collaboration->SetPadColor(0); // Changes Pad color to white
+ Nab_collaboration->SetStatColor(0); // Changes Stats bg color to white
+ Nab_collaboration->SetTitleFillColor(0); // Changes Title bg color to white
+ Nab_collaboration->SetLabelFont(42,"xyz"); // Changes Label Font
+ Nab_collaboration->SetTitleFont(42,"xyz"); // Changes Axis Title Font
+ Nab_collaboration->SetPadTickX(1); // Sets tic marks on both horizontal axes
+ Nab_collaboration->SetPadTickY(1); // Sets tic marks on both vertical axes
+ Nab_collaboration->SetTickLength(0.018,"xyz"); // Sets tic length
+ Nab_collaboration->SetOptStat(0); // Turns off Statistics display
+ Nab_collaboration->SetOptTitle(-1); // Turns off Title display
+ Nab_collaboration->SetHistLineWidth(2); // Changes Histogram Line width
+ Nab_collaboration->SetFrameBorderMode(0); // Removes the Frame Border
+ Nab_collaboration->SetFrameFillStyle(0);
+ Nab_collaboration->SetCanvasDefH(494); // Sets Default Canva Height
+ Nab_collaboration->SetCanvasDefW(800); // Sets Default Canvas Width
+ Nab_collaboration->SetPalette(1);
+
+
+ // The next for commands set the default margin size
+ // n.b. the margins do not take axis labels into account! grr!!
+ Nab_collaboration->SetPadTopMargin(0.1); // Set Margin Top
+ Nab_collaboration->SetPadRightMargin(0.1); // Set Margin Right
+ Nab_collaboration->SetPadBottomMargin(0.1); // Set Margin Bottom
+ Nab_collaboration->SetPadLeftMargin(0.1); // Set Margin Left
+
+ //make a nice palette
+ int NRGBs = 7, NCont = 999;
+ Nab_collaboration->SetNumberContours(NCont);
+ Double_t stops[7] = { 0.00, 0.10, 0.25, 0.45, 0.60, 0.75, 1.00 };
+ Double_t red[7] = { 1.00, 0.00, 0.00, 0.00, 0.97, 0.97, 0.10 };
+ Double_t green[7] = { 1.00, 0.97, 0.30, 0.40, 0.97, 0.00, 0.00 };
+ Double_t blue[7] = { 1.00, 0.97, 0.97, 0.00, 0.00, 0.00, 0.00 };
+ TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
+
+ // Make Nab_collaboration_work a copy of Nab_collaboration and remove stats
+ Nab_collaboration->Copy(*Nab_collaboration_work);
+ //Nab_collaboration_work->SetOptStat(1);
+ Nab_collaboration_work->SetOptTitle(0);
+ Nab_collaboration_work->SetPadTopMargin(0.1);
+ Nab_collaboration_work->SetPadRightMargin(0.1);
+
+ // Select Which Style to
+ gROOT->SetStyle("RadHard_AutoTitle");
+ // gROOT->SetStyle("Nab_Collaboration");
+
+
+ // Use the RooFit functions
+ // using namespace RooFit;
+
+ // Force Root to run Nab_collaboration/Nab_collaboration_work style
+ gROOT->ForceStyle();
+
+ return 1;
+}
+
+
+Bool_t CompareLeageCurrent(vector<HistogramType*>* ptCompareHistogramClassVector)
+{
+ if (ptCompareHistogramClassVector->size() > 0)
+ {
+ gROOT->SetStyle("RadHard_NoTitle");
+ if (testifMixingCalibration(ptCompareHistogramClassVector)) return 1;
+
+ // legend entries
+ Float_t height = ptCompareHistogramClassVector->size() * 0.055;
+ TLegend* leg1 = new TLegend(0.6,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ leg1->SetTextSize(0.035);
+ leg1->SetFillStyle(0);
+ leg1->SetTextFont(132);
+ leg1->SetFillColor(0);
+ leg1->SetBorderSize(0);
+ TString legendEntry;
+
+ TPaveText *owntitle = new TPaveText(0.15,0.9,0.930401,0.995,"nbNDC");
+ owntitle->SetFillStyle(0);
+ owntitle->SetBorderSize(0);
+ owntitle->SetTextAlign(22);
+ owntitle->SetTextSize(0.04);
+ owntitle->SetTextFont(42);
+
+ TString canvastitle = "SummaryLeakeCurrent"+ptCompareHistogramClassVector->at(0)->histogramdescription;
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ canvastitle+= Form("_%d",curhistogramclassp->labbook->runnumber);
+ }
+ TTimeStamp* time = new TTimeStamp();
+ TString canvasname = Form("%d",(int)time->GetNanoSec()/100000);
+ TCanvas* canvas = new TCanvas(canvasname, canvastitle, 1200, 700);
+
+ int numberofhistogramclasses = ptCompareHistogramClassVector->size();
+ double lowestxvalue = 1e50;
+ double heighestxvalue = 0;
+
+
+ // std::vector<Float_t> sortedXValues;
+ // for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ // sortedXValues.push_back((*curHistogramClass)->labbook->radDoseNonIon);
+ // }
+ // std::sort(sortedXValues.begin(),sortedXValues.end());
+ // double xbins[numberofhistogramclasses+1];
+ // for(int i=0; i < numberofhistogramclasses; i++){
+ // xbins[i] = sortedXValues.at(i) - 0.5;
+ // }
+ // xbins[numberofhistogramclasses]=sortedXValues.at(numberofhistogramclasses-1);
+
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ lowestxvalue = lowestxvalue>(*curHistogramClass)->labbook->radDoseNonIon?(*curHistogramClass)->labbook->radDoseNonIon:lowestxvalue;
+ heighestxvalue = heighestxvalue<(*curHistogramClass)->labbook->radDoseNonIon?(*curHistogramClass)->labbook->radDoseNonIon:heighestxvalue;
+ // cout << heighestxvalue << " " << lowestxvalue << " " << (*curHistogramClass)->labbook->radDoseNonIon << endl;
+ }
+ // cout << "----" << endl;
+ //double stepsizex = (heighestxvalue-lowestxvalue)/(numberofhistogramclasses);
+ double stepsizex = 1;
+ Int_t numberbins = (heighestxvalue-lowestxvalue)/stepsizex;
+ // if (stepsizex == 0)
+ // stepsizex = 1;
+ // cout << "stepsizex: " << stepsizex << endl;
+ double xbins[numberbins+2];
+ for(int i=0; i <= numberbins+1; i++){
+ xbins[i] = lowestxvalue+stepsizex*i-stepsizex/2;
+ }
+
+ double heighestyvalue = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ Int_t lastbinabovezero = (*curHistogramClass)->LeakageCurrentInPixelSorted->FindLastBinAbove(0);
+ double curheightyvalue = (*curHistogramClass)->LeakageCurrentInPixelSorted->GetBinContent(lastbinabovezero);
+ heighestyvalue = heighestyvalue<curheightyvalue?curheightyvalue:heighestyvalue;
+ // cout << curheightyvalue << " " << heighestyvalue << " "<< endl;
+ }
+ heighestyvalue*=1.05;
+ double stepsizey = heighestyvalue/10000.0;
+ // cout << "stepsizey: " << stepsizey << endl;
+ double ybins[10001];
+ for(int i=0; i <= 10000; i++){
+ ybins[i] = (double)stepsizey*i-stepsizey/2;
+ }
+
+ TH2F *hcandle = new TH2F(canvasname+"1","Comparison Leakage current ",numberbins+1, xbins, 10000, ybins);
+ Double_t const probabilities[] = {0.3415/2, 0.5, 1-0.3415/2}; // sigma/2 from gaus to the left and to the right //{0.17, 0.5, 1-0.17};
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ for (Int_t pixeli=0; (*curHistogramClass)->LeakageCurrentInPixelSorted->GetBinContent(pixeli) != 0; pixeli++) {
+ // cout << pixeli << " " << (*curHistogramClass)->LeakageCurrentInPixelSorted->GetBinContent(pixeli) << " ";
+ hcandle->Fill((*curHistogramClass)->labbook->radDoseNonIon,(*curHistogramClass)->LeakageCurrentInPixelSorted->GetBinContent(pixeli));
+ // hcandle->Fill((*curHistogramClass)->labbook->radDoseNonIon,1.5);
+ }
+ legendEntry = Form("%f", (*curHistogramClass)->labbook->radDoseNonIon);
+ // leg1->AddEntry(curhistogramclone, legendEntry, "l");
+ }
+ // hcandle->GetXaxis()->SetTitle("Non ionizing radiation damage [10^{13} n_{eq}/cm^{2}]]");
+ hcandle->GetXaxis()->SetTitle("Radiation damage [10^{13} n/cm^{2}]]");
+ if (ptCompareHistogramClassVector->at(0)->iscalibrated) {
+ hcandle->GetYaxis()->SetTitle("Charge [fA]");
+ } else {
+ hcandle->GetYaxis()->SetTitle("Charge [ADU]");
+ }
+ hcandle->GetXaxis()->CenterTitle();
+ hcandle->GetYaxis()->CenterTitle();
+ hcandle->GetYaxis()->SetNdivisions(1010);
+ hcandle->SetBarWidth(1);
+ hcandle->SetLineWidth(2);
+ hcandle->Draw("CANDLEX(012311)");
+ gPad->SetLogy(1);
+ gPad->SetGridy(1);
+
+
+ owntitle->Clear();
+ owntitle->AddText("Leakage current comparison");
+ owntitle->Draw("SAME");
+
+ // leg1->Draw("SAME");
+
+ canvas->Update();
+ MSaveBigPNG(canvas,savepathresults + folderadd + "/" + canvastitle + ".png",1);
+
+ TImageDump *img = new TImageDump(savepathresults + folderadd + "/" + canvastitle + ".png");
+ canvas->Paint();
+ img->Close();
+
+ TFile *f = new TFile(savepathresults + folderadd + "/" + canvastitle + ".root","RECREATE");
+ f->cd();
+ f->Append(canvas);
+ //f->Append(img);
+ f->Write();
+
+ // gROOT->SetStyle("RadHard_AutoTitle");
+ return 0;
+ }
+ return 1;
+}
+
+Bool_t testifMixingCalibration(vector<HistogramType*>* ptCompareHistogramClassVector) {
+ if ( !ptCompareHistogramClassVector->size() )
+ {
+ // cout << colorwhite << ptCompareHistogramClassVector->size() << endl;
+ // cout << colorred << "plotCompareHistograms(): No plots to compare, please push them into the vector: CompareHistogramClassVector" << endlr;
+ return 1;
+ }
+ Bool_t calibrated = true;
+ Bool_t uncalibrated = true;
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ calibrated = calibrated && ptCompareHistogramClassVector->at(histogrami)->iscalibrated;
+ uncalibrated = uncalibrated && !ptCompareHistogramClassVector->at(histogrami)->iscalibrated;
+ // cout << colorcyan << ptCompareHistogramClassVector->at(histogrami)->histogramdescription << endlr;
+ }
+ // cout << "Calibrated " << (calibrated?"Yes":"No") << endl;
+ // cout << "Uncalibrated " << (uncalibrated?"Yes":"No") << endl;
+ if ( !(calibrated != uncalibrated)) // XOR operator !=
+ {
+ cout << colorred << "plotCompareHistograms(): Mixing of calibrated and uncalibrated histograms when comparing plots. Aborting." << endlr;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief Plots all runs pushed into a vector together in one canvas
+ *
+ * @input ptCompareHistogramClassVector a Vector of type HistogramType
+ *
+ * Plots all runs pushed into the input vector in one canvas, shows Seed, Sum, Veto and Noise spectra
+ *
+ */
+Bool_t plotAllRuns(vector<HistogramType*>* ptCompareHistogramClassVector, Bool_t unZoom = kFALSE)
+{
+ if (ptCompareHistogramClassVector->size()>0)
+ {
+ FindGoodTitle(ptCompareHistogramClassVector);
+
+ gROOT->SetStyle("RadHard_NoTitle");
+ if (testifMixingCalibration(ptCompareHistogramClassVector)) return 1;
+
+ // legend entries
+ Float_t height = ptCompareHistogramClassVector->size() * 0.055;
+ TLegend* leg1 = new TLegend(0.6,0.89-height,0.95,0.89);//(0.6,0.7,0.89,0.89);
+ leg1->SetTextSize(0.035);
+ leg1->SetFillStyle(0);
+ leg1->SetTextFont(132);
+ leg1->SetFillColor(0); leg1->SetBorderSize(0);
+ TLegend* leg2 = (TLegend*) leg1->Clone();
+ TLegend* leg3 = (TLegend*) leg1->Clone();
+ TLegend* leg4 = (TLegend*) leg1->Clone();
+ leg4->SetX1(0.4);
+ TString legendEntry;
+
+ TPaveText *owntitle = new TPaveText(0.15,0.9,0.930401,0.995,"nbNDC");
+ owntitle->SetFillStyle(0);
+ owntitle->SetBorderSize(0);
+ owntitle->SetTextAlign(22);
+ owntitle->SetTextSize(0.04);
+ owntitle->SetMargin(0.07);
+ owntitle->SetTextFont(42);
+ TPaveText *owntitle2 = (TPaveText*)owntitle->Clone();
+ TPaveText *owntitle3 = (TPaveText*)owntitle->Clone();
+ TPaveText *owntitle4 = (TPaveText*)owntitle->Clone();
+
+ Float_t lastbin1=0;
+ Float_t lastbin2=0;
+ Float_t lastbin3=0;
+ Float_t lastbin4=0;
+ Float_t heighestval1=0;
+ Float_t heighestval2=0;
+ Float_t heighestval3=0;
+ Float_t heighestval4=0;
+ TString canvastitle = ptCompareHistogramClassVector->at(0)->histogramdescription;
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ canvastitle+= Form("_%d",curhistogramclassp->labbook->runnumber);
+ }
+ TTimeStamp* time = new TTimeStamp();
+
+ TString canvasname = Form("Summary_%s_%d",ptCompareHistogramClassVector->at(0)->run->runcode.Data(),(int)time->GetNanoSec()/100000);
+ //TString canvasname = Form("%d",time->GetNanoSec());
+ TCanvas* canvas = new TCanvas(canvasname, canvastitle, 1200, 700);
+ canvas->Divide(2,2);
+ THStack *hs = new THStack("hs","Sum spectra");
+
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ TH1F* curhistogramclone = (TH1F*) curhistogramclassp->Seed->Clone();
+ Float_t posMaxValHist = curhistogramclone->GetXaxis()->GetXmax();
+ curhistogramclone->GetXaxis()->UnZoom();
+ if (!unZoom)
+ curhistogramclone->GetXaxis()->SetRange(curhistogramclone->GetXaxis()->FindBin(curhistogramclassp->noisethresholdborder),curhistogramclone->GetXaxis()->FindBin(posMaxValHist)); // look only for maxima with x greater than noiseborder, cut away noise
+ heighestval1 = (curhistogramclone->GetMaximum()>heighestval1?curhistogramclone->GetMaximum():heighestval1);
+
+
+ curhistogramclone = (TH1F*) (*curhistogramclassp->Sum)->Clone();
+ posMaxValHist = curhistogramclone->GetXaxis()->GetXmax();
+ curhistogramclone->GetXaxis()->UnZoom();
+ if (!unZoom)
+ curhistogramclone->GetXaxis()->SetRange(curhistogramclone->GetXaxis()->FindBin(curhistogramclassp->noisethresholdborder),curhistogramclone->GetXaxis()->FindBin(posMaxValHist)); // look only for maxima with x greater than noiseborder, cut away noise
+
+
+ heighestval2 = (curhistogramclone->GetMaximum()>heighestval2?curhistogramclone->GetMaximum():heighestval2);
+
+ curhistogramclone = (TH1F*) curhistogramclassp->Veto->Clone();
+ posMaxValHist = curhistogramclone->GetXaxis()->GetXmax();
+ curhistogramclone->GetXaxis()->UnZoom();
+ if (!unZoom)
+ curhistogramclone->GetXaxis()->SetRange(curhistogramclone->GetXaxis()->FindBin(curhistogramclassp->noisethresholdborder),curhistogramclone->GetXaxis()->FindBin(posMaxValHist)); // look only for maxima with x greater than noiseborder, cut away noise
+ heighestval3 = (curhistogramclone->GetMaximum()>heighestval3?curhistogramclone->GetMaximum():heighestval3);
+
+ curhistogramclone = (TH1F*) curhistogramclassp->Noise->Clone();
+ curhistogramclone->GetXaxis()->UnZoom();
+ heighestval4 = (curhistogramclone->GetMaximum()>heighestval4?curhistogramclone->GetMaximum():heighestval4);
+ }
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ TH1F* curhistogramclone = (TH1F*) curhistogramclassp->Seed->Clone();
+ lastbin1 = (curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval1/20,1))>lastbin1)?curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval1/20,1)):lastbin1;
+
+ curhistogramclone = (TH1F*) (*curhistogramclassp->Sum)->Clone();
+ lastbin2 = (curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval2/20,1))>lastbin2)?curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval2/20,1)):lastbin2;
+
+ curhistogramclone = (TH1F*) curhistogramclassp->Veto->Clone();
+ lastbin3 = (curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval3/20,1))>lastbin3)?curhistogramclone->GetBinCenter(curhistogramclone->FindLastBinAbove(heighestval3/20,1)):lastbin3;
+ }
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ TH1F* curhistogramclone;
+
+ canvas->cd(1);
+ curhistogramclone = (TH1F*) curhistogramclassp->Seed->Clone();
+ // TLatex Tl;
+ // Tl.SetNDC();
+ // Tl.DrawText(0.3, 0.2, "Titel titel");
+ //TPaveText *t = new TPaveText(0.0, 0.9, 0.3, 1.0, "brNDC"); // left-up
+ curhistogramclone->SetLineColor(rootcolors[histogrami%13]);
+ //curhistogramclone->GetXaxis()->SetRange(0,curhistogramclone->GetXaxis()->GetNbins());
+ curhistogramclone->Draw("SAME");
+ // legendEntry = Form("%d %s", curhistogramclassp->labbook->runnumber, curhistogramclone->GetTitle());
+ legendEntry = Form("%s", curhistogramclone->GetTitle());
+ if (legendStringsVector.size() > 0)
+ legendEntry = Form("%s", legendStringsVector.at(histogrami).Data());
+ leg1->AddEntry(curhistogramclone, legendEntry, "l");
+ leg1->Draw("SAME");
+ curhistogramclone->SetAxisRange(0,lastbin1*1.1,"X");
+ curhistogramclone->SetAxisRange(0,heighestval1*1.1,"Y");
+ curhistogramclone->GetYaxis()->SetRangeUser(1,heighestval1*1.2);
+ // gPad->SetLogy(1);
+ gPad->SetGrid(1);
+ gPad->SetGridy(1);
+ owntitle->Clear();
+ if (headerStringsVector.size() > 0) {
+ owntitle->AddText(Form("%s, %s", trimRunnumberAtBegin(curhistogramclone->GetName()).Data(), headerStringsVector.at(1).Data()));
+ owntitle->AddText(headerStringsVector.at(2));
+ }
+ owntitle->Draw("SAME");
+
+ canvas->cd(2);
+ curhistogramclone = (TH1F*) (*curhistogramclassp->Sum)->Clone();
+ curhistogramclone->SetLineColor(rootcolors[histogrami%13]);
+ curhistogramclone->Draw("SAME");
+ hs->Add(curhistogramclone);
+ legendEntry = Form("%s", curhistogramclone->GetTitle());
+ if (legendStringsVector.size() > 0)
+ legendEntry = Form("%s", legendStringsVector.at(histogrami).Data());
+ leg2->AddEntry(curhistogramclone, legendEntry, "l");
+ leg2->Draw("SAME");
+ // hs->Add(leg1);
+ curhistogramclone->SetAxisRange(0,lastbin2*1.1,"X");
+ curhistogramclone->SetAxisRange(0,heighestval2*1.1,"Y");
+ // heighestval2 = (curhistogramclone->GetMaximum()>heighestval2?curhistogramclone->GetMaximum():heighestval2);
+ curhistogramclone->GetYaxis()->SetRangeUser(1,heighestval2*1.2);
+ curhistogramclone->Draw("SAME");
+ // gPad->SetLogy(1);
+ gPad->SetGrid(1);
+ gPad->SetGridy(1);
+
+ owntitle2->Clear();
+ if (headerStringsVector.size() > 0) {
+ owntitle2->AddText(Form("%s, %s",trimRunnumberAtBegin(curhistogramclone->GetName()).Data(), headerStringsVector.at(1).Data()));
+ owntitle2->AddText(headerStringsVector.at(2));
+ }
+ owntitle2->Draw("SAME");
+
+ canvas->cd(3);
+ curhistogramclone = (TH1F*) curhistogramclassp->Veto->Clone();
+ curhistogramclone->SetLineColor(rootcolors[histogrami%13]);
+ curhistogramclone->Draw("SAME");
+ legendEntry = Form("%s", curhistogramclone->GetTitle());
+ if (legendStringsVector.size() > 0)
+ legendEntry = Form("%s", legendStringsVector.at(histogrami).Data());
+ leg3->AddEntry(curhistogramclone, legendEntry, "l");
+ leg3->Draw("SAME");
+ curhistogramclone->SetAxisRange(1,lastbin3*1.1,"X");
+ curhistogramclone->SetAxisRange(1,heighestval3*1.1,"Y");
+ // heighestval3 = (curhistogramclone->GetMaximum()>heighestval3?curhistogramclone->GetMaximum():heighestval3);
+ curhistogramclone->GetYaxis()->SetRangeUser(0,heighestval3*1.2);
+ curhistogramclone->Draw("SAME");
+ gPad->SetGrid(1);
+ gPad->SetGridy(1);
+
+ owntitle3->Clear();
+ if (headerStringsVector.size() > 0) {
+ owntitle3->AddText(Form("%s, %s",trimRunnumberAtBegin(curhistogramclone->GetName()).Data(), headerStringsVector.at(1).Data()));
+ owntitle3->AddText(headerStringsVector.at(2));
+ }
+ owntitle3->Draw("SAME");
+
+ canvas->cd(4);
+ curhistogramclone = (TH1F*) curhistogramclassp->Noise->Clone();
+ curhistogramclone->SetLineColor(rootcolors[histogrami%13]);
+ curhistogramclone->Draw("SAME");
+ legendEntry = Form("%d Noise: %.2f + %.2f - %.2f",curhistogramclassp->labbook->runnumber, curhistogramclassp->avgNoise, curhistogramclassp->avgNoisePlus, curhistogramclassp->avgNoiseMinus);
+ leg4->AddEntry(curhistogramclone, legendEntry, "l");
+ leg4->Draw();
+ curhistogramclone->GetYaxis()->SetRangeUser(0,heighestval4*1.2);
+
+ owntitle4->Clear();
+ if (headerStringsVector.size() > 0) {
+ owntitle4->AddText(Form("%s, %s",trimRunnumberAtBegin(curhistogramclone->GetName()).Data(), headerStringsVector.at(1).Data()));
+ owntitle4->AddText(headerStringsVector.at(2));
+ }
+ owntitle4->Draw("SAME");
+ }
+ canvas->cd(0);
+ //TText T; T.SetTextFont(42); T.SetTextAlign(21);
+ // canvas->cd(2); hs->Draw("nostack same");// T.DrawTextNDC(.5,.95,"Option \"nostack\"");
+ // canvas->BuildLegend();
+ canvas->Update();
+ MSaveBigPNG(canvas,savepathresults + folderadd + "/Big_" + canvastitle + ".png",2);
+
+ TImageDump *img = new TImageDump(savepathresults + folderadd + "/" + canvastitle + ".png");
+ canvas->Paint();
+ img->Close();
+
+ MSaveBigPNG(canvas,"lastrun.png");
+
+ TFile *f = new TFile(savepathresults + folderadd + "/" + canvastitle + ".root","RECREATE");
+ f->cd();
+ f->Append(canvas);
+ //f->Append(img);
+ f->Write();
+
+ // gROOT->SetStyle("RadHard_AutoTitle");
+
+ headerStringsVector.clear();
+ legendStringsVector.clear();
+ return 0;
+ }
+ return 1;
+}
+
+Bool_t FindGoodTitle() {
+ vector<HistogramType*> compareHistogramClassVector;
+ for(Int_t runi=0;runi<numberRuns;runi++) // loop over runs read from file
+ {
+ if (runs[runi] != nullptr)
+ {
+ if (!runs[runi]->error)
+ {
+ compareHistogramClassVector.push_back(runs[runi]->histogram);
+ }
+ }
+ }
+ return FindGoodTitle(&compareHistogramClassVector);
+}
+
+Bool_t FindGoodTitle(vector<TH1FO*>* ptCompareHistogramVector) {
+ vector<HistogramType*> compareHistogramClassVector;
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramVector->size(); histogrami++)
+ {
+ TH1FO* curHistogram = ptCompareHistogramVector->at(histogrami);
+ if (curHistogram->itsHistogramType != 0) {
+ compareHistogramClassVector.push_back(curHistogram->itsHistogramType);
+ }
+ }
+ return FindGoodTitle(&compareHistogramClassVector, ptCompareHistogramVector);
+}
+
+Bool_t FindGoodTitle(vector<HistogramType*>* ptCompareHistogramClassVector, vector<TH1FO*>* ptCompareHistogramVector) {
+
+ // Title with everything included:
+ //
+ // Spectrum type, Source, Chip generation, Pixel number, Pixel Pitch, Pixel comment
+ // Temperature, Ionizing radiation, Non-ionizing radiation, Readout Speed, Depletion voltage
+ // Annealing, System
+
+ Bool_t same_Source = kTRUE;
+ Bool_t same_NonIonRad = kTRUE;
+ Bool_t same_IonRad = kTRUE;
+ Bool_t same_ChipNum = kTRUE;
+ Bool_t same_ChipGen = kTRUE;
+ //Bool_t same_Spectra = kTRUE;
+ Bool_t same_Matrix= kTRUE;
+ Bool_t same_Temp = kTRUE;
+ Bool_t same_Clock = kTRUE;
+ Bool_t same_Depletion = kTRUE;
+ Bool_t same_RunNumber = kTRUE;
+ Bool_t same_HistType = kTRUE;
+ //Bool_t same_Annealing = kTRUE;
+ //Bool_t same_System = kTRUE;
+
+ Bool_t mayBeSameRun = kFALSE;
+ if (ptCompareHistogramVector != 0)
+ if (ptCompareHistogramVector->size() == ptCompareHistogramClassVector->size())
+ {
+ mayBeSameRun = kTRUE; // no different classes were provided, only some TH1F histograms. Classes were constructed afterwards
+ // same_RunNumber = kTRUE;
+ }
+
+ // cout << "Trying to find good title" << endlr;
+
+ headerStringsVector.clear();
+ legendStringsVector.clear();
+
+ if (ptCompareHistogramClassVector->size() == 0 )
+ return 1;
+
+ if (ptCompareHistogramClassVector->at(0) == 0 )
+ return 1;
+
+ HistogramType* firsthistogramclassp = ptCompareHistogramClassVector->at(0);
+ labbooksctruct firstlabbook = firsthistogramclassp->run->labbook;
+ pixelinfo firstpixelinfo = firsthistogramclassp->run->curpixelinfo;
+ TH1FO* firsthistogramp = 0;
+
+ if (ptCompareHistogramClassVector->size() == 1) {
+ TString title1 = Form(" %s, %s, %s, %.0fx%.0f #mum^{2} pitch, %s\nT=%.0f {}^{o}C, %.1f MRad, %.1f*10^{13} n_{eq}/cm^{2}, %.2f Mhz", firstlabbook.source.Data(),
+ firstlabbook.chipGen.Data(), firstlabbook.matrix.Data(), firstpixelinfo.pitchX, firstpixelinfo.pitchY, firstpixelinfo.comment.Data(),
+ firstlabbook.tempSens, firstlabbook.radDoseIon, firstlabbook.radDoseNonIon, firstlabbook.clock);
+ if (firstlabbook.depletionV >= 0)
+ title1 += Form(", U_{dep}=%.1f V", firstlabbook.depletionV);
+
+ TString title2 = Form("%s", firstlabbook.comment.Data());
+
+ headerStringsVector.push_back(title1);
+ TObjArray *humanreadablestrings = trimRunnumberAtBegin(title1).Tokenize("\n");
+ headerStringsVector.push_back(((TObjString *)(humanreadablestrings->At(0)))->String());
+ headerStringsVector.push_back(((TObjString *)(humanreadablestrings->At(1)))->String());
+ headerStringsVector.push_back(title2);
+
+ } else {
+ if (mayBeSameRun)
+ firsthistogramp = ptCompareHistogramVector->at(0);
+
+ for (UInt_t histogrami=1; histogrami < ptCompareHistogramClassVector->size(); histogrami++) {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ labbooksctruct curlabbook = curhistogramclassp->run->labbook;
+ pixelinfo curpixelinfo = curhistogramclassp->run->curpixelinfo;
+ TH1FO* curhistogramp = 0;
+ if (mayBeSameRun)
+ curhistogramp = ptCompareHistogramVector->at(histogrami);
+
+ if (!curlabbook.source.EqualTo(firstlabbook.source))
+ same_Source = kFALSE;
+ if (!curlabbook.chipGen.EqualTo(firstlabbook.chipGen))
+ same_ChipGen = kFALSE;
+ if (!curlabbook.matrix.EqualTo(firstlabbook.matrix)) {
+ same_Matrix = kFALSE;
+ }
+ if (firstlabbook.tempSens > 0) { // allow 10 % difference
+ if (curlabbook.tempSens > firstlabbook.tempSens*1.1 || curlabbook.tempSens < firstlabbook.tempSens*0.9)
+ same_Temp = kFALSE;
+ } else {
+ if (curlabbook.tempSens < firstlabbook.tempSens*1.1 || curlabbook.tempSens > firstlabbook.tempSens*0.9)
+ same_Temp = kFALSE;
+ }
+ if (curlabbook.radDoseIon != firstlabbook.radDoseIon)
+ same_IonRad = kFALSE;
+ if (curlabbook.radDoseNonIon != firstlabbook.radDoseNonIon)
+ same_NonIonRad = kFALSE;
+ if (!curlabbook.chip.EqualTo(firstlabbook.chip))
+ same_ChipNum = kFALSE;
+ if (curlabbook.clock != firstlabbook.clock)
+ same_Clock = kFALSE;
+ if (curlabbook.depletionV != firstlabbook.depletionV)
+ same_Depletion= kFALSE;
+ // if (curlabbook.system != firstlabbook.system)
+ // same_System = kFALSE;
+ if (curlabbook.runnumber != firstlabbook.runnumber)
+ same_RunNumber= kFALSE;
+
+ if ( curhistogramp != 0 ) // different histogram types
+ if (!(trimRunnumberAtBegin(curhistogramp->GetName()).EqualTo(trimRunnumberAtBegin(firsthistogramp->GetName()))))
+ same_HistType = kFALSE;
+ }
+
+ // // DEBUG
+ // cout << colorcyan << "same_Source: " << same_Source << endlr;
+ // cout << colorcyan << "same_NonIonRad: " << same_NonIonRad << endlr;
+ // cout << colorcyan << "same_IonRad: " << same_IonRad << endlr;
+ // cout << colorcyan << "same_ChipNum: " << same_ChipNum << endlr;
+ // cout << colorcyan << "same_ChipGen: " << same_ChipGen << endlr;
+ // cout << colorcyan << "same_Matrix: " << same_Matrix << endlr;
+ // cout << colorcyan << "same_Temp: " << same_Temp << endlr;
+ // cout << colorcyan << "same_Clock: " << same_Clock << endlr;
+ // cout << colorcyan << "same_Depletion: " << same_Depletion << endlr;
+ // cout << colorcyan << "same_HistType: " << same_HistType << endlr;
+ // cout << colorcyan << "same_RunNumber: " << same_RunNumber << endlr;
+ // cout << colorcyan << "mayBeSameRun: " << mayBeSameRun << endlr;
+
+ // construct header string
+ TString title1 = "";
+ if (same_RunNumber)
+ title1.Append(Form(", %d", firstlabbook.runnumber));
+ if (same_HistType && mayBeSameRun)
+ title1.Append(Form(", %s", trimRunnumberAtBegin(firsthistogramp->GetName()).Data()));
+ if (same_Source)
+ title1.Append(Form(", %s", firstlabbook.source.Data()));
+ if (same_ChipGen)
+ title1.Append(Form(", %s", firstlabbook.chipGen.Data()));
+ if (same_Matrix)
+ title1.Append(Form(", %s, %.0fx%.0f #mum^{2} pitch, %s", firstlabbook.matrix.Data(), firstpixelinfo.pitchX, firstpixelinfo.pitchY, firstpixelinfo.comment.Data()));
+ title1.Append(Form("\n"));
+ if (same_Temp)
+ title1.Append(Form("T=%.0f {}^{o}C", firstlabbook.tempSens));
+ if (same_IonRad && firstlabbook.radDoseIon != 0)
+ title1.Append(Form(", %.1f MRad", firstlabbook.radDoseIon));
+ if (same_NonIonRad && firstlabbook.radDoseNonIon != 0)
+ title1.Append(Form(", %.1f*10^{13} n_{eq}/cm^{2}", firstlabbook.radDoseNonIon));
+ if (same_Clock)
+ title1.Append(Form(", %.2f Mhz", firstlabbook.clock));
+ if (same_Depletion && firstlabbook.depletionV >= 0)
+ title1.Append(Form(", U_{dep}=%.1f V", firstlabbook.depletionV));
+
+ // cout << colorred << title1 << endlr;
+ if (title1.Length() > 3)
+ title1 = title1.Remove(0,2); // remove trailing " ,"
+ headerStringsVector.push_back(title1);
+ // TObjArray *humanreadablestrings = trimRunnumberAtBegin(title1).Tokenize("\n");
+ TObjArray *humanreadablestrings = title1.Tokenize("\n");
+ headerStringsVector.push_back(((TObjString *)(humanreadablestrings->At(0)))->String());
+ headerStringsVector.push_back(((TObjString *)(humanreadablestrings->At(1)))->String());
+
+ // legend creation
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++) {
+ TString legendstr = "";
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ labbooksctruct curlabbook = curhistogramclassp->run->labbook;
+ pixelinfo curpixelinfo = curhistogramclassp->run->curpixelinfo;
+ TH1FO* curhistogramp = 0;
+ if (mayBeSameRun)
+ curhistogramp = ptCompareHistogramVector->at(histogrami);
+
+ // if (!same_RunNumber) { if (legendstr.Length()) legendstr.Append(", ");
+ // legendstr.Append(Form("%d", curhistogramclassp->labbook->runnumber)); }
+ if (!same_HistType && mayBeSameRun) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%s", trimRunnumberAtBegin(curhistogramp->GetName()).Data())); }
+ if (!same_Source) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%s", curlabbook.source.Data())); }
+ if (!same_ChipGen) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%s", curlabbook.chipGen.Data())); }
+ if (!same_ChipNum) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("Chip# %s", curlabbook.chip.Data())); }
+ if (!same_Matrix) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%s, %.0fx%.0f #mum^{2} pitch, %s", curlabbook.matrix.Data(), curpixelinfo.pitchX, curpixelinfo.pitchY, curpixelinfo.comment.Data())); }
+ if (!same_Temp) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("T=%.0f {}^{o}C", curlabbook.tempSens)); }
+ if (!same_IonRad && curlabbook.radDoseIon != 0) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%.1f MRad", firstlabbook.radDoseIon)); }
+ if (!same_NonIonRad && curlabbook.radDoseNonIon != 0) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%.1f*10^{13} n_{eq}/cm^{2}", curlabbook.radDoseNonIon)); }
+ if (!same_Clock) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("%.2f Mhz", curlabbook.clock)); }
+ if (!same_Depletion && curlabbook.depletionV >= 0) { if (legendstr.Length()) { legendstr.Append(", "); }
+ legendstr.Append(Form("U_{dep}=%.1f V", curlabbook.depletionV)); }
+
+ legendStringsVector.push_back(legendstr);
+ // cout << colorred << legendstr << endlr;
+ }
+ } // end else ptCompareHistogramClassVector->size() == 1
+
+ // Folder name suffix
+ folderadd = "";
+ if (same_RunNumber) {
+ folderadd.Append(Form(" %d", firstlabbook.runnumber)); }
+ if (same_HistType && mayBeSameRun && firsthistogramp != 0) {
+ folderadd.Append(Form(" %s", trimRunnumberAtBegin(firsthistogramp->GetName()).Data())); }
+ if (same_Source) {
+ folderadd.Append(Form(" %s", firstlabbook.source.Data())); }
+ if (same_ChipGen) {
+ folderadd.Append(Form(" %s", firstlabbook.chipGen.Data())); }
+ if (same_Matrix) {
+ folderadd.Append(Form("-%s", firstlabbook.matrix.Data())); }
+ if (!same_Matrix) {
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ folderadd.Append(Form(" -%s", ptCompareHistogramClassVector->at(histogrami)->labbook->matrix.Data()));
+ }
+ if (same_Depletion && firstlabbook.depletionV >= 0) {
+ folderadd.Append(Form(" %.1fV", firstlabbook.depletionV)); }
+ if (!same_Depletion && firstlabbook.depletionV >= 0) {
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++) {
+ folderadd.Append(Form(" %.1fV", ptCompareHistogramClassVector->at(histogrami)->labbook->depletionV)); } }
+ if (same_Temp) {
+ folderadd.Append(Form(" %.0fC", firstlabbook.tempSens)); }
+ if (same_IonRad && firstlabbook.radDoseIon != 0) {
+ folderadd.Append(Form("%.1fMRad", firstlabbook.radDoseIon)); }
+ if (same_NonIonRad && firstlabbook.radDoseNonIon != 0) {
+ folderadd.Append(Form(" %.1fe13neq", firstlabbook.radDoseNonIon)); }
+ if (same_Clock) {
+ folderadd.Append(Form(" %.2fMhz", firstlabbook.clock)); }
+ if (!same_Clock) {
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++) {
+ folderadd.Append(Form(" %.2fMhz", ptCompareHistogramClassVector->at(histogrami)->labbook->clock)); } }
+
+ removeForbiddenChar(&folderadd);
+ system("mkdir \""+ savepathresults + folderadd + "/\"" + " -p");
+ // cout << colorred << savepathresults << folderadd << endlr;
+ return false;
+}
+
+
+/**
+ * @brief This functions prints a summary table of runs pushed into the ptCompareHistogramClassVector
+ *
+ * @input ptCompareHistogramClassVector a Vector of type HistogramType
+ *
+ * Prints a summary table and compares some observables
+ *
+ */
+Bool_t printSummaryTable(vector<HistogramType*>* ptCompareHistogramClassVector)
+{
+ if (ptCompareHistogramClassVector->size()>0)
+ {
+ if (testifMixingCalibration(ptCompareHistogramClassVector)) return 1;
+
+ TString filename = savepathresults + folderadd + "/" + "/Summary"+ptCompareHistogramClassVector->at(0)->histogramdescription;
+ TString filecontent = "";
+ for(Int_t runi=0;runi<numberRuns;runi++) // loop over runs read from file
+ {
+ if (runs[runi] != nullptr)
+ {
+ if (!runs[runi]->error)
+ {
+ filename+= Form("_%d",runs[runi]->labbook.runnumber);
+ }
+ }
+ }
+ filename+=".txt";
+ fstream* fout = new fstream(filename,ios::out);
+
+ const int width = 15;
+ cout << endlr << colorwhite << right << setw(width*11) << setfill('=') << " " << endl;
+ cout << left << setw(width*1) << setfill(' ') << "Cut type: "<< left << setw(width*8) << setfill(' ') << ptCompareHistogramClassVector->at(0)->histogramdescription << endl; filecontent += Form("Cut type: %s\n", ptCompareHistogramClassVector->at(0)->histogramdescription.Data());
+ cout << left << setw(width-5) << setfill(' ') << "Runnumber"; filecontent += Form("Runnumber\t");
+ cout << left << setw(width-5) << setfill(' ') << "Frames"; filecontent += Form("Frames\t");
+ cout << left << setw(width-10) << setfill(' ') << "Chp#"; filecontent += Form("Chp#\t");
+ Bool_t printtemp = 1; // always print temperature
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ if ((*curHistogramClass)->labbook->temp != ptCompareHistogramClassVector->at(0)->labbook->temp)
+ printtemp = 1;
+ }
+ if (printtemp)
+ cout << left << setw(width-8) << setfill(' ') << "Temp"; filecontent += Form("Temp\t");
+ cout << left << setw(width-10) << setfill(' ') << "Mtrx"; filecontent += Form("Mtrx\t");
+ Float_t printradion = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++)
+ printradion += (*curHistogramClass)->labbook->radDoseIon;
+ if (printradion > 0) { cout << left << setw(width-5) << setfill(' ') << "Rad. ion"; filecontent += Form("Rad. ion\t"); }
+ Float_t printradnonion = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++)
+ printradnonion += (*curHistogramClass)->labbook->radDoseNonIon;
+ if (printradnonion > 0) { cout << left << setw(width-8) << setfill(' ') << "N.Rad"; filecontent += Form("N.Rad\t"); }
+ Float_t printCCE = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++) {
+ printCCE += (*curHistogramClass)->CCE_in_Perc_1; printCCE += (*curHistogramClass)->CCE_in_Perc_25;
+ }
+ if (printCCE > 0) { cout << left << setw(width) << setfill(' ') << "CCE_1"; filecontent += Form("CCE_1\t"); }
+ if (printCCE > 0) { cout << left << setw(width) << setfill(' ') << "CCE_25"; filecontent += Form("CCE_25\t"); }
+ Float_t printStoN = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++)
+ printStoN += (*curHistogramClass)->StoN;
+ if (printStoN > 0) { cout << left << setw(width) << setfill(' ') << "S/N"; filecontent += Form("S/N\t"); }
+ Float_t printIntegral = 0;
+ for (vector<HistogramType*>::iterator curHistogramClass = ptCompareHistogramClassVector->begin(); curHistogramClass != ptCompareHistogramClassVector->end(); curHistogramClass++)
+ printIntegral += (*curHistogramClass)->sr90IntegralVal;
+ if (printIntegral > 0.0) { cout << left << setw(width+1) << setfill(' ') << "Integral"; filecontent += Form("Integral\t"); }
+ //cout << left << setw(width) << setfill(' ') << "Seed Peak"; filecontent += Form("Seed Peak\t");
+ //cout << left << setw(width) << setfill(' ') << "Veto Peak"; filecontent += Form("Veto Peak\t");
+ // cout << left << setw(width+2) << setfill(' ') << "Veto Integral"; filecontent += Form("Veto Integral\t");
+ // cout << left << setw(width+2) << setfill(' ') << "Sum Integral"; filecontent += Form("Veto Integral\t");
+ Float_t printRTSpixel = 1;
+ if (printRTSpixel > 0) { cout << left << setw(width-2) << setfill(' ') << "RTS pixel"; filecontent += Form("RTS pixel\t"); }
+ Float_t printSeedIntegral = 1;
+ if (printSeedIntegral > 0) { cout << left << setw(width) << setfill(' ') << "Seed integral"; filecontent += Form("Seed integral\t"); }
+ Float_t printLeakage = 1;
+ if (printLeakage > 0) { cout << left << setw(width+2) << setfill(' ') << "Leakage"; filecontent += Form("Leakage cur.\t"); }
+ cout << left << setw(width-2) << setfill(' ') << "Noise"; filecontent += Form("Noise\t");
+ Float_t printnsethr = 0;
+ if (printnsethr > 0) {cout << left << setw(width) << setfill(' ') << "Noise threshold"; filecontent += Form("Noise threshold\t"); }
+ cout << endl; filecontent += Form("\n");
+ for (UInt_t histogrami=0; histogrami < ptCompareHistogramClassVector->size(); histogrami++)
+ {
+ HistogramType* curhistogramclassp = ptCompareHistogramClassVector->at(histogrami);
+ cout << left << setw(width-5) << setfill(' ') << curhistogramclassp->labbook->runnumber; filecontent += Form("%d\t", curhistogramclassp->labbook->runnumber);
+ // cout << "1" << endl;
+ cout << left << setw(width-5) << setfill(' ') << to_str_w_prec(curhistogramclassp->frames_found); filecontent += Form("%s\t", to_str_w_prec(curhistogramclassp->frames_found).c_str());
+ // cout << "2" << endl;
+ cout << left << setw(width-10) << setfill(' ') << curhistogramclassp->labbook->chip; filecontent += Form("%s\t", curhistogramclassp->labbook->chip.Data());
+ if (printtemp) { cout << left << setw(width-8) << setfill(' ') << curhistogramclassp->labbook->temp; filecontent += Form("%.1f\t", curhistogramclassp->labbook->temp); }
+ // cout << "!" << endl;
+ cout << left << setw(width-10) << setfill(' ') << curhistogramclassp->labbook->matrix; filecontent += Form("%s\t", curhistogramclassp->labbook->matrix.Data());
+ if (printradion > 0) { cout << left << setw(width-5) << setfill(' ') << curhistogramclassp->labbook->radDoseIon; filecontent += Form("%.1f\t", curhistogramclassp->labbook->radDoseIon); }
+ if (printradnonion > 0) { cout << left << setw(width-8) << setfill(' ') << curhistogramclassp->labbook->radDoseNonIon; filecontent += Form("%.1f\t", curhistogramclassp->labbook->radDoseNonIon); }
+ if (printCCE > 0) { cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->CCE_in_Perc_1,ptCompareHistogramClassVector->at(0)->CCE_in_Perc_1); filecontent += Form("%s\t", printTableElement(curhistogramclassp->CCE_in_Perc_1,ptCompareHistogramClassVector->at(0)->CCE_in_Perc_1).c_str()); }
+ if (printCCE > 0) { cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->CCE_in_Perc_25,ptCompareHistogramClassVector->at(0)->CCE_in_Perc_25); filecontent += Form("%s\t", printTableElement(curhistogramclassp->CCE_in_Perc_25,ptCompareHistogramClassVector->at(0)->CCE_in_Perc_25).c_str()); }
+ if (printStoN > 0) { cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->StoN,ptCompareHistogramClassVector->at(0)->StoN); filecontent += Form("%s\t", printTableElement(curhistogramclassp->StoN,ptCompareHistogramClassVector->at(0)->StoN).c_str()); }
+ if (printIntegral > 0.0) { cout << left << setw(width+1) << setfill(' ') << printTableElement(curhistogramclassp->sr90IntegralVal,ptCompareHistogramClassVector->at(0)->sr90IntegralVal); filecontent += Form("%s\t", printTableElement(curhistogramclassp->sr90IntegralVal,ptCompareHistogramClassVector->at(0)->sr90IntegralVal).c_str()); }
+ //cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->posSeed,ptCompareHistogramClassVector->at(0)->posSeed); filecontent += Form("%s\t", printTableElement(curhistogramclassp->posSeed,ptCompareHistogramClassVector->at(0)->posSeed).c_str());
+ //cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->posVeto,ptCompareHistogramClassVector->at(0)->posVeto); filecontent += Form("%s\t", printTableElement(curhistogramclassp->posVeto,ptCompareHistogramClassVector->at(0)->posVeto).c_str());
+ // cout << left << setw(width+2) << setfill(' ') << printTableElement(curhistogramclassp->integralVeto,ptCompareHistogramClassVector->at(0)->integralVeto,2); filecontent += Form("%s\t", printTableElement(curhistogramclassp->integralVeto,ptCompareHistogramClassVector->at(0)->integralVeto,4).c_str());
+ // cout << left << setw(width+2) << setfill(' ') << printTableElement(curhistogramclassp->integralSum,ptCompareHistogramClassVector->at(0)->integralSum,2); filecontent += Form("%s\t", printTableElement(curhistogramclassp->integralSum,ptCompareHistogramClassVector->at(0)->integralSum,4).c_str());
+ if (printRTSpixel > 0) { cout << left << setw(width-2) << setfill(' ') << printTableElement((float)curhistogramclassp->RTSpixel.size(),(float)ptCompareHistogramClassVector->at(0)->RTSpixel.size(),0); filecontent += Form("%s\t", printTableElement((float)curhistogramclassp->RTSpixel.size(),(float)ptCompareHistogramClassVector->at(0)->RTSpixel.size(),0).c_str()); }
+ if (printSeedIntegral > 0) { cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->integralSeed,ptCompareHistogramClassVector->at(0)->integralSeed); filecontent += Form("%s\t", printTableElement(curhistogramclassp->integralSeed,ptCompareHistogramClassVector->at(0)->integralSeed).c_str()); }
+ if (printLeakage > 0.0) { cout << left << setw(width+2) << setfill(' ') << printTableElement((float)curhistogramclassp->medianLeakageCurrent,(float)ptCompareHistogramClassVector->at(0)->medianLeakageCurrent,2); filecontent += Form("%s\t", printTableElement((float)curhistogramclassp->medianLeakageCurrent,(float)ptCompareHistogramClassVector->at(0)->medianLeakageCurrent,1).c_str()); }
+ cout << left << setw(width-2) << setfill(' ') << printTableElement(curhistogramclassp->avgNoise,ptCompareHistogramClassVector->at(0)->avgNoise); filecontent += Form("%s\t", printTableElement(curhistogramclassp->avgNoise,ptCompareHistogramClassVector->at(0)->avgNoise).c_str());
+ if (printnsethr > 0) { cout << left << setw(width) << setfill(' ') << printTableElement(curhistogramclassp->noisethresholdborder,ptCompareHistogramClassVector->at(0)->noisethresholdborder); filecontent += Form("%s\t", printTableElement(curhistogramclassp->noisethresholdborder,ptCompareHistogramClassVector->at(0)->noisethresholdborder).c_str()); }
+ cout << "" << endl; filecontent += Form("\n");
+ }
+ cout << right << setw(width*11) << setfill('=') << " " << endl;
+ *fout << filecontent << endl;
+ fout->close();
+ }
+ return 0;
+}
+
+template<typename varType> string printTableElement(varType t1, varType t2, const int precision)
+{
+ float percentage = t1/t2*100.0;
+ string value = to_str_w_prec(t1, precision) + " (" + to_str_w_prec(percentage,0) + "%)";
+ return value;
+}
+
+string to_str_w_prec(const Float_t a_value, const int precision)
+{
+ std::ostringstream out;
+ if (abs(a_value) > 1 && abs(a_value) < 10000) {
+ out << std::fixed << std::setprecision(precision) << a_value;
+ } else {
+ out << std::scientific << std::setprecision(precision) << a_value << std::fixed; out.setf(ios_base::fixed);
+ }
+ return out.str();
+}
+