#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; struct Parameters { string fileNames; } gParameters; struct RunInfo{ RunInfo() : nTotalPhotons(0) {} string offlineRev; string configList; string md5; unsigned int nTotalPhotons; }; struct CalibResult { double calib; double calibErr; double nPhotGen; double nPhotPixel; double electronicsFactor; }; map ReadRunInfo(const string& fileNames); void CalibrateTel(ostream& calibXml, const int index, const RunInfo runInfo); map CalibrateTelescope(TChain* data); // ------------------------------------------------------------ int main(int argc, char** argv) { if (argc<2) { cout << " Please run: DrumCalib \n" << endl; return 5; } gParameters.fileNames = string(argv[1]); cout << "Reading from: \"" << gParameters.fileNames << "\"" < runs = ReadRunInfo(gParameters.fileNames); ofstream calibXml("FSimulationCalibConfig.generated.xml.in"); calibXml << "\n\n" << "\n\n" << " \n\n"; for (map::const_iterator iRun = runs.begin(); iRun != runs.end(); ++iRun) { const int index = iRun->first; const RunInfo run = iRun->second; calibXml << " \n"; calibXml << " \n" << " " << endl; CalibrateTel(calibXml, index, run); } calibXml << "\n"; calibXml.close(); cout << "-----------------------------------------------------------------------------" << endl; cout << "Telescope(s) calibrated! Output in file \"FSimulationCalibConfig.generated.xml.in\"." << endl; return 0; } // ------------------------------------------------------------ map ReadRunInfo(const string& fileNames) { TChain* runInfo = new TChain("runInfo"); runInfo->Add(fileNames.c_str()); int index; unsigned int nPhotTotal; char md5[1000]; char offline_rev[100]; char config[1000000]; runInfo->SetBranchAddress("index", &index); runInfo->SetBranchAddress("nPhotonsTot", &nPhotTotal); runInfo->SetBranchAddress("md5", md5); runInfo->SetBranchAddress("offline_rev", offline_rev); runInfo->SetBranchAddress("config", config); map run; for (int i=0; iGetEntries(); ++i) { runInfo->GetEntry(i); if (run.count(index)) { run[index].nTotalPhotons += nPhotTotal; if (run[index].offlineRev != string(offline_rev) || run[index].configList != config || run[index].md5 != md5) { cout << " ERROR: Input data mismatch ! " << endl; exit(1); } } else { run[index].nTotalPhotons = nPhotTotal; run[index].offlineRev = offline_rev; run[index].configList = config; run[index].md5 = md5; } } return run; } // ----------------------------------------------------------------------- void CalibrateTel(ostream& calibXml, const int index, const RunInfo runInfo) { const bool writeErrorsToXml = false; cout << "Calibrate telescope, index = " << index << endl; const int eyeId = index / 100; const int telId = index % 100; ostringstream dataName; dataName << "drumData_" << index; TChain* drumData = new TChain(dataName.str().c_str()); drumData->Add(gParameters.fileNames.c_str()); map constants = CalibrateTelescope(drumData); /* // find largst pixel id int maxPixelId = 0; for (map::const_iterator iCal = constants.begin(); iCal != constants.end(); ++iCal) { if (iCal->first>maxPixelId) maxPixelId = iCal->first; } vector */ double meanError = 0; for (map::const_iterator iCal = constants.begin(); iCal != constants.end(); ++iCal) { const int pixelId = iCal->first; const CalibResult calData = iCal->second; const double calib = calData.calib; const double calibErr = calData.calibErr; cout << " pixel id=" << setw(4) << pixelId << " s=" << setw(10) << fixed << calib << " +- " << setw(10) << calibErr << " [ph/ADC]" << "\n"; calibXml << " " << setprecision(16) << setw(18) << calib; if (writeErrorsToXml) calibXml << " "; calibXml << "\n"; meanError += calibErr; } // end loop pixels if (constants.size()) meanError /= constants.size(); calibXml << " "; calibXml << " \n" " \n\n"; } // end of CalculateCalibrationConstants // --------------------------------------------------------------------------------- map CalibrateTelescope(TChain* drumData) { int pixelId; double nGen, nPix, calib, calibErr, electronicsFactor; drumData->SetBranchAddress("id", &pixelId); drumData->SetBranchAddress("nGen", &nGen); drumData->SetBranchAddress("nPix", &nPix); drumData->SetBranchAddress("calib", &calib); drumData->SetBranchAddress("calibErr", &calibErr); drumData->SetBranchAddress("electronicsFactor", &electronicsFactor); map counter; map constants; // count photons for (int i=0; iGetEntries(); ++i) { drumData->GetEntry(i); if (counter.count(pixelId)) { counter[pixelId]++; constants[pixelId].nPhotGen += nGen; constants[pixelId].nPhotPixel += nPix; if (constants[pixelId].electronicsFactor != electronicsFactor) { cout << "ERROR: incompatible pixel data found!" << endl; exit(2); } } else { counter[pixelId] = 1; constants[pixelId].nPhotGen = nGen; constants[pixelId].nPhotPixel = nPix; constants[pixelId].electronicsFactor = electronicsFactor; constants[pixelId].calib = 0; constants[pixelId].calibErr = 0; } } // check pixel data bool first = true; double fact = 0; for (map::const_iterator iPix = counter.begin(); iPix != counter.end(); ++iPix ) { if (first) { fact = iPix->second; } else { if (fact != iPix->second) { cout << "ERROR: incompatible number of pixels found in input data " << endl; exit(3); } } } // compute calibration constants for (map::iterator iPix = constants.begin(); iPix != constants.end(); ++iPix ) { CalibResult& dat = iPix->second; const double epsilon = double(dat.nPhotPixel) / dat.nPhotGen; const double epsilonErr = sqrt((epsilon - epsilon*epsilon) / dat.nPhotGen); // const double pixelSignal = pixelPhotons * qEff * gain; // add electronics [ph -> ADC] // const double calib = flux_drum_perp * diaArea * pixelSolid / pixelSignal; const double calib = 1 / (epsilon * dat.electronicsFactor); const double calibErr = epsilonErr / (epsilon * epsilon * dat.electronicsFactor); dat.calib = calib; dat.calibErr = calibErr; cout << "gen=" << dat.nPhotGen << " pix=" << dat.nPhotPixel << " eps=" << epsilon << endl; } return constants; }