--- /dev/null
+#include "Run.h"
+using namespace std;
+
+Run::Run( void )
+{
+ cout << "\033[1;31mError while initializing Run class, please provide a runnumber to the class!\033[0m\n";
+ exit(EXIT_FAILURE);
+}
+
+Run::~Run( void)
+{
+ db->Close();
+ delete processed;
+ rootfile->Close();
+}
+
+Run::Run(Int_t runnumber)
+{
+ labbook.runnumber = runnumber;
+
+ db = TSQLServer::Connect(SERVERPATH,SERVERUSER,SERVERPWD);
+ //db = TSQLServer::Connect("mysql://jspc29.x-matter.uni-frankfurt.de","radhard","mimosa88");
+ try
+ {
+ string selectquery = "select System,TempCooling,COALESCE(TempChipStart,-10000) as TempChipStart,COALESCE(TempChipEnd,-10000) as TempChipEnd,ChipNum,RadiationSource,Matrix,Clock,StorePath,ChipGen,COALESCE(VetoPeak,-1) as VetoPeak from radhard.labbook WHERE runnumber=" + numberToString<>(labbook.runnumber);
+ res = db->Query(prepareSQLStatement(selectquery));
+ nrows = res->GetRowCount();
+ if (nrows > 0)
+ {
+ rowsql = res->Next();
+ labbook.system = (rowsql->GetField(0) != NULL)?std::string(rowsql->GetField(0)):"";
+ labbook.temp = (rowsql->GetField(1) != NULL)?atof(rowsql->GetField(1)):-272;
+ labbook.tempSens = (rowsql->GetField(2) != NULL)?atof(rowsql->GetField(2)):-272;
+ labbook.chip = (rowsql->GetField(4) != NULL)?std::string(rowsql->GetField(4)):"";
+ labbook.source = (rowsql->GetField(5) != NULL)?std::string(rowsql->GetField(5)):"";
+ labbook.matrix = (rowsql->GetField(6) != NULL)?std::string(rowsql->GetField(6)):"";
+ labbook.clock = (rowsql->GetField(7) != NULL)?atoi(rowsql->GetField(7)):100;
+ labbook.storepath = (rowsql->GetField(8) != NULL)?std::string(rowsql->GetField(8)):"";
+ // replace windows drive notation with linux style
+ if (labbook.storepath.Length() > 0)
+ {
+ storepathLinux = labbook.storepath;
+ storepathLinux = storepathLinux.ReplaceAll("H:","/jspc53_H");
+ storepathLinux = storepathLinux.ReplaceAll("h:","/jspc53_H");
+ storepathLinux = storepathLinux.ReplaceAll("U:","/jspc53_U");
+ storepathLinux = storepathLinux.ReplaceAll("u:","/jspc53_U");
+ storepathLinux = storepathLinux.ReplaceAll("F:","/jspc12_F");
+ storepathLinux = storepathLinux.ReplaceAll("f:","/jspc12_F");
+ storepathLinux = storepathLinux.ReplaceAll("O:","/d/garlic");
+ storepathLinux = storepathLinux.ReplaceAll("o:","/d/garlic");
+ storepathLinux = storepathLinux.ReplaceAll("\\","/");
+ }
+ labbook.chipGen = (rowsql->GetField(9) != NULL)?std::string(rowsql->GetField(9)):"";
+ labbook.posVetoDB = (rowsql->GetField(10) != NULL)?atoi(rowsql->GetField(10)):-1;
+ delete res;
+ if (labbook.chip.Length() > 0 && labbook.chipGen.Length() > 0) // versuche infos zum Chip aus der ChipDatenbank zu bekommen
+ {
+ res = db->Query(prepareSQLStatement("select epi_thickness, resistivity, `ChipRadiation Ion`, `ChipRadiation NonIon` from radhard.chips WHERE no='" + numberToString<>(labbook.chip) + "' AND chipgen='" + numberToString<>(labbook.chipGen) + "'"));
+ nrows = res->GetRowCount();
+ if (nrows > 0)
+ {
+ rowsql = res->Next();
+ labbook.epi_thickness = (rowsql->GetField(0) != NULL)?atol(rowsql->GetField(0)):-1;
+ labbook.resistivity = (rowsql->GetField(1) != NULL)?atof(rowsql->GetField(1)):-1;
+ labbook.radDoseIon = (rowsql->GetField(2) != NULL)?atof(rowsql->GetField(2)):-1;
+ labbook.radDoseNonIon = (rowsql->GetField(3) != NULL)?atof(rowsql->GetField(3)):-1;
+ delete res;
+ }
+ }
+ if (!(labbook.posVetoDB > 0) && (labbook.source != "Fe55")) // no veto peak position found for this run
+ {
+ getVetoPeakPositionFromFe55Run();
+ }
+ setSystemInfo();
+ generateReadableRunCode();
+ runexistsinDB = 1;
+ }
+ else
+ {
+ cout << "\033[1;31mNo database data for run " << numberToString<>(labbook.runnumber) << " found!\033[0m" << endl;
+ }
+ }
+ catch(...)
+ {
+ cout << "\033[1;31mError while reading laboratory book (run number " << numberToString<>(labbook.runnumber) << ")!\033[0m\n";
+ }
+
+}
+
+Bool_t Run::analyzeRun(Bool_t force)
+{
+ if (runexistsinDB)
+ {
+ processed = new MAPS(this);
+ if (!runAllreadyAnalyzed() || force)
+ {
+ /// progress meter, temporal variable
+ ULong_t progress_tmp=-1;
+ /// progress meter
+ Float_t progress;
+ processed->InitialDynNoise();
+ int start = 0;
+ int nframes = processed->GetNumberFrames();
+ for(int i=0; i<nframes;i++) // TODO remove 100000
+ {
+ processed->getFrame(i);
+ processed->filterCommonMode();
+ processed->hitana();
+ processed->regetDynNoise();
+ progress = (Int_t)(((i-start)*100)/(nframes-1)*10);
+// if (progress!=progress_tmp) { print_progress( (((i-start)*100.)/(nframes-1)) ); progress_tmp=progress;}
+ }
+ cout << processed->plus << " vs. " << processed->minus << " : " << (processed->plus*1.0)/processed->minus<< endl;
+ // print a dummy file to indicate, that a root file was created once
+ fstream* fout = new fstream(storepathLinux + "/rootfilecreated",std::ios::out);
+ *fout << "" << endl;
+ fout->close();
+ }
+ else
+ {
+ cout << "\033[1;33mSkipped analysis of run " << labbook.runnumber << ", I think the root file for this run allready exists.\033[0m" << endl;
+ }
+// binNoise();
+// binSeedSumVeto();
+
+// TString rootfilepath = storepathLinux + Form ("/RUN_%i_i.root", labbook.runnumber);
+// rootfile = new TFile(rootfilepath);
+// if (!(rootfile->IsZombie()))
+// {
+// runexistsAsRootFile = 1;
+// initNoise();
+// }
+// else
+// {
+// // if we cannot open the file, print an error messageForm("hist%i",nHistNtuple) and return immediatly
+// cout << "\033[1;31mError: cannot open " << rootfilepath << "\033[0m\n";
+// exit(0);
+// }
+
+ }
+}
+
+
+Bool_t Run::analyzeFrame(Int_t frame)
+{
+ if (runexistsinDB)
+ {
+ processed = new MAPS(this);
+ int entries = processed->GetNumberFrames();
+ if (frame < entries)
+ {
+ processed->InitialDynNoise(100);
+ processed->getFrame(frame);
+// processed->filterCommonMode();
+ processed->hitana();
+ processed->plotFrame(frame);
+ binNoise();
+ }
+ else
+ {
+ cout << "\033[1;33mFrame number too big, max frame: " << entries << "\033[0m" << endl;
+ }
+
+ }
+}
+
+// generateSeedSpectrum()
+// {
+// /// pointer to the TTree of "hit"
+// TTree* hitNtuple = (TTree*) f->Get("hit");
+// }
+
+Bool_t Run::runAllreadyAnalyzed()
+{
+ return checkFileExists(storepathLinux + "/rootfilecreated");
+}
+
+Bool_t Run::checkFileExists(TString file)
+{
+ struct stat buffer;
+ return (stat (file.Data(), &buffer) == 0);
+}
+
+Bool_t Run::generateReadableRunCode()
+{
+ runcode = Form("%i_", labbook.runnumber);
+ if (labbook.chip.Length() < 2)
+ runcode+= "0" + labbook.chip;
+ else
+ runcode+= labbook.chip;
+ if (labbook.radDoseIon > 0)
+ runcode+= Form("RI%.0f",labbook.radDoseIon*10);
+ else
+ runcode+= Form("RI0%.0f",labbook.radDoseIon);
+ if (labbook.radDoseNonIon > 0)
+ runcode+= Form("Rn%.0f",labbook.radDoseNonIon*1000);
+ else
+ runcode+= Form("Rn0%.0f",labbook.radDoseNonIon);
+ runcode+= labbook.matrix;
+ if (labbook.resistivity > 0)
+ runcode+= Form("HR%d",labbook.resistivity);
+ string tempstring = labbook.source.Data();
+ tempstring = removePunctuation(tempstring);
+ tempstring = removeNumbers(tempstring);
+ tempstring = tempstring.substr(0,4);
+ runcode+= tempstring;
+ runcode+= Form("%+.0f", labbook.temp*10);
+ runcode+= Form("%+.0f", labbook.tempSens*10);
+ runcode+= Form("%03i", labbook.clock);
+ runcode+= Form("%c", labbook.system[0]);
+ if (dividedmatrix)
+ {
+ if (upperpart)
+ runcode+= Form("_m%.0f-%.0f_", devided_upper_matr_min, devided_upper_matr_max);
+ else
+ runcode+= Form("_m%.0f-%.0f_", devided_lower_matr_min, devided_lower_matr_max);
+ }
+}
+
+string Run::removeNumbers(std::string x)
+{
+ //Remove all numbers
+ x.erase(
+ std::remove_if(x.begin(), x.end(), (int(*)(int))isdigit),
+ x.end());
+
+ return x;
+}
+
+string Run::removePunctuation(std::string x)
+{
+ x.erase(
+ std::remove_if(x.begin(), x.end(), (int(*)(int))ispunct),
+ x.end());
+ return x;
+}
+
+
+template <typename T>
+string Run::numberToString ( T number )
+{
+ stringstream ss;
+ ss << number;
+ return ss.str();
+}
+
+Float_t Run::stringToNumber ( string Text )
+{
+ stringstream ss;
+ for ( string::const_iterator i=Text.begin(); i!=Text.end(); ++i )
+ if ( isdigit(*i) || *i=='-' || *i=='+' || *i=='.' ) // *i=='e' ||
+ ss << *i;
+ Float_t result;
+ return ss >> result ? result : 0;
+}
+
+void Run::setSystemInfo()
+{
+ sensorinfostruct sensorinfoMi34USB;
+ sensorinfoMi34USB.columns=64;
+ sensorinfoMi34USB.rows=8;
+ sensorinfostruct sensorinfoMi34PXI;
+ sensorinfoMi34PXI.columns=64;
+ sensorinfoMi34PXI.rows=16;
+
+ if (labbook.system.EqualTo("USB")) // && labbook.chipGen.EqualTo("34") )
+ sensorinfocurrent=sensorinfoMi34USB;
+ else if (labbook.system.EqualTo("PXI")) // && labbook.chipGen.EqualTo("34") )
+ sensorinfocurrent=sensorinfoMi34PXI;
+}
+
+template <typename T>
+char const* Run::prepareSQLStatement( T statement )
+{
+ stringstream ss;
+ ss << statement;
+ cout << ss.str() << endl << endl; // for debugging
+ return ss.str().c_str();
+}
+
+void Run::getVetoPeakPositionFromFe55Run()
+{
+ try
+ {
+ // query database and print results
+ res = db->Query(prepareSQLStatement("select COALESCE(VetoPeak,-1) as VetoPeak, runnumber from radhard.labbook WHERE ChipNum='" + numberToString<>(labbook.chip) + "' AND RadiationSource='Fe55' AND Matrix='" + numberToString<>(labbook.matrix) + "' AND TempCooling=" + to_str_w_prec(labbook.temp,3) + " AND System='" + numberToString<>(labbook.system) + "'"));
+ nrows = res->GetRowCount();
+ if (nrows > 0)
+ {
+ do {
+ rowsql = res->Next();
+ Fe55run.posVeto = (rowsql->GetField(0) != NULL)?atof(rowsql->GetField(0)):-1;
+ Fe55run.posVetorunnumber = (rowsql->GetField(0) != NULL && rowsql->GetField(1) != NULL)?atoi(rowsql->GetField(1)):0;
+ } while (posVeto == -1 && (--nrows)!=0);
+ delete res;
+ }
+ else
+ {
+ cout << "No matching data for the position of the calibration peak for run number " << numberToString<>(labbook.runnumber) << " when considering the right temperature of " << numberToString<>(labbook.temp) << " °C." << endl;
+ }
+ if (!(Fe55run.posVeto > 0)) // no calibration peak found
+ {
+ res = db->Query(prepareSQLStatement("select COALESCE(VetoPeak,-1) as VetoPeak, runnumber, TempCooling from radhard.labbook WHERE ChipNum='" + numberToString<>(labbook.chip) + "' AND RadiationSource='Fe55' AND Matrix='" + numberToString<>(labbook.matrix) + "' AND System='" + numberToString<>(labbook.system) + "'"));
+ nrows = res->GetRowCount();
+ if (nrows > 0)
+ {
+ do {
+ rowsql = res->Next();
+ Fe55run.posVeto = (rowsql->GetField(0) != NULL)?atof(rowsql->GetField(0)):-1;
+ Fe55run.posVetorunnumber = (rowsql->GetField(0) != NULL && rowsql->GetField(1) != NULL)?atoi(rowsql->GetField(1)):0;
+ Fe55run.temperature = (rowsql->GetField(2) != NULL)?atof(rowsql->GetField(2)):-1;
+ } while (Fe55run.posVeto == -1 && (--nrows)!=0);
+ delete res;
+ if (Fe55run.posVeto > 0) // calibration peak found, but not for this temperature
+ {
+ cout << "Found a calibration peak for runnumber " << labbook.runnumber << ", but not with the correct temperature." << endl;
+ cout << "Temperature of run: \t" << labbook.temp << endl;
+ cout << ", but of calibration peak run:\t" << Fe55run.temperature << ", taken from run number: " << Fe55run.posVetorunnumber << endl;
+ }
+ }
+ else
+ {
+ cout << "No matching data for the position of the calibration peak for run number " << labbook.runnumber << "" << endl;
+ }
+ }
+ }
+ catch(...)
+ {
+ cout << "\033[1;31mError while reading laboratory book (run number " << labbook.runnumber << ")!\033[0m\n";
+ }
+}
+
+void Run::constructUpdateString(string *sqlupdatequery, const string databasevaluename, const Float_t value, const int precision=3)
+{
+ if (value>0)
+ {
+ if ((*sqlupdatequery).length() > 0)
+ *sqlupdatequery+= ", ";
+ *sqlupdatequery += "`" + databasevaluename + "`="+ to_str_w_prec(value, precision);
+ }
+}
+
+void Run::updateDatabase() {
+ string sqlupdatequery = "";
+ constructUpdateString(&sqlupdatequery, "Gain", gain);
+ constructUpdateString(&sqlupdatequery, "SumPeak", posSum);
+ constructUpdateString(&sqlupdatequery, "SeedPeak", posSeed);
+ constructUpdateString(&sqlupdatequery, "VetoPeak", posVeto);
+ constructUpdateString(&sqlupdatequery, "Avg.Noise", NoiseAvg, 2);
+ constructUpdateString(&sqlupdatequery, "Avg.Noise+", NoiseAvgPlus, 2);
+ constructUpdateString(&sqlupdatequery, "Avg.Noise-", NoiseAvgMinus, 2);
+ constructUpdateString(&sqlupdatequery, "CCE_1", CCE_in_Perc_1);
+ constructUpdateString(&sqlupdatequery, "CCE_25", CCE_in_Perc_25);
+
+ if (sqlupdatequery.length()>0)
+ {
+ try
+ {
+ sqlupdatequery = "UPDATE `labbook` SET " + sqlupdatequery + " WHERE `runnumber`=" + numberToString<>(labbook.runnumber);
+ Bool_t sucess = db->Exec(prepareSQLStatement(sqlupdatequery));
+ if (!sucess)
+ {
+ cout << "\033[1;31mError while writing laboratory book TO SQL database (run number " << labbook.runnumber << ")!\033[0m\n";
+ }
+ }
+ catch(...)
+ {
+ cout << "\033[1;31mError while writing laboratory book TO SQL database (run number " << labbook.runnumber << ")!\033[0m\n";
+ //exit(EXIT_FAILURE);
+ }
+ }
+}
+
+string Run::to_str_w_prec(const Float_t a_value, int precision = 3)
+{
+ std::ostringstream out;
+ out << std::setprecision(precision) << a_value;
+ return out.str();
+}
+
+
+
+Bool_t Run::binNoise()
+{
+ Float_t noise;
+ TBranch* noiseBranch;
+ 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};
+
+ processed->fDynNoiseTree->SetBranchAddress("noise", &noise, &noiseBranch);
+
+ // create histogram
+ if (labbook.system == "PXI")
+ histogram.Noise = new TH1F("Noise " + runcode, "Noise" + runcode, 150, 0, 150);
+ else
+ histogram.Noise = new TH1F("Noise " + runcode, "Noise" + runcode, 100, 0, 10);
+
+ for (Int_t cnt=0; cnt<processed->fDynNoiseTree->GetEntries(); cnt++) {
+ processed->fDynNoiseTree->GetEntry(cnt);
+ histogram.Noise->Fill(noise);
+ }
+
+ histogram.Noise->GetQuantiles( 3, noisequantiles, probabilities);
+ if (labbook.system == "PXI")
+ for (int j=0; j<3; j++)
+ noisequantiles[j] /= 16.0; // TODO analyze PXI scales
+
+ return false;
+}
+
+Bool_t Run::binSeedSumVeto()
+{
+ /// framenumber
+ UInt_t framen;
+ /// number of hits in current frame
+ UInt_t hitsInframe;
+ /// pixel number of seed pixel, position on sensor
+ UInt_t seedPixel[10000];
+ /// Array of CLUSTERSIZE * CLUSTERSIZE clusters, seed pixel in the middle
+ Float_t pixelcluster[5*5][10000];
+
+ for (Int_t framei=0; framei<processed->fHitTree->GetEntries(); framei++) // loop over all frames
+ {
+ processed->fHitTree->GetEntry(framei);
+ // account only frames with less then 10 hits
+ cout << processed->fFrameInfo.hits << endl;
+// if (processed->fFrameInfo.hits<10)
+// {
+ }
+}
+
+Bool_t Run::plotNoise()
+{
+ return plot1DHistogram(histogram.Noise);
+}
+
+Bool_t Run::plot1DHistogram(TH1F* histogram, TString titlestr, TString legendstr)
+{
+ TCanvas* canvas = new TCanvas();
+ canvas->SetTitle(runcode + " " + titlestr);
+ histogram->Draw();
+ TLegend* leg = new TLegend(0.5,0.5,0.89,0.89);//(0.6,0.7,0.89,0.89);
+ leg->SetFillStyle(0);
+ leg->AddEntry((TObject*) 0, runcode + " " + legendstr, "");
+ leg->SetTextSize(0.03);
+ leg->Draw();
+ return 0;
+}
\ No newline at end of file