DrumCalib.cc
Go to the documentation of this file.
1 #include <TFile.h>
2 #include <TChain.h>
3 #include <TTree.h>
4 #include <TGraph.h>
5 
6 #include <cmath>
7 #include <iomanip>
8 #include <cstdlib>
9 #include <iostream>
10 #include <string>
11 #include <map>
12 #include <vector>
13 #include <sstream>
14 #include <fstream>
15 using namespace std;
16 
17 struct Parameters {
18  string fileNames;
19 } gParameters;
20 
21 struct RunInfo{
22  RunInfo() : nTotalPhotons(0) {}
23  string offlineRev;
24  string configList;
25  string md5;
26  unsigned int nTotalPhotons;
27 };
28 
29 struct CalibResult {
30  double calib;
31  double calibErr;
32  double nPhotGen;
33  double nPhotPixel;
35 };
36 
37 map<int, RunInfo> ReadRunInfo(const string& fileNames);
38 void CalibrateTel(ostream& calibXml, const int index, const RunInfo runInfo);
39 map<int, CalibResult> CalibrateTelescope(TChain* data);
40 
41 
42 
43 // ------------------------------------------------------------
44 int main(int argc, char** argv) {
45 
46  if (argc<2) {
47  cout << " Please run: DrumCalib <input-files>\n" << endl;
48  return 5;
49  }
50  gParameters.fileNames = string(argv[1]);
51  cout << "Reading from: \"" << gParameters.fileNames << "\"" <<endl;
52  map<int, RunInfo> runs = ReadRunInfo(gParameters.fileNames);
53 
54 
55  ofstream calibXml("FSimulationCalibConfig.generated.xml.in");
56  calibXml << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n\n"
57  << "<FSimulationCalibConfig xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
58  << " xsi:noNamespaceSchemaLocation='@XMLSCHEMALOCATION@/FSimulationCalibConfig.xsd'>\n\n"
59  << " <!-- these are used for the flatfielding -->\n\n";
60 
61 
62  for (map<int, RunInfo>::const_iterator iRun = runs.begin();
63  iRun != runs.end(); ++iRun) {
64 
65  const int index = iRun->first;
66  const RunInfo run = iRun->second;
67 
68 
69  calibXml << " <!-- \n"
70  << " This set of calibration constants was generated using Offline revision "
71  << run.offlineRev << "\n"
72  << " with the following set of configuration parameters:\n";
73  calibXml << "\"" << run.configList << "\"\n"
74  << " The following Md5-hex-digest encodes this list:\n"
75  << " -->\n";
76  calibXml << " <EndToEnd signature=\"" << run.md5 << "\"> \n"
77  << " <calibration>" << endl;
78 
79 
80  CalibrateTel(calibXml, index, run);
81  }
82 
83  calibXml << "</FSimulationCalibConfig>\n";
84  calibXml.close();
85 
86  cout << "-----------------------------------------------------------------------------" << endl;
87  cout << "Telescope(s) calibrated! Output in file \"FSimulationCalibConfig.generated.xml.in\"." << endl;
88 
89  return 0;
90 }
91 
92 
93 // ------------------------------------------------------------
94 map<int, RunInfo> ReadRunInfo(const string& fileNames) {
95 
96  TChain* runInfo = new TChain("runInfo");
97  runInfo->Add(fileNames.c_str());
98 
99  int index;
100  unsigned int nPhotTotal;
101  char md5[1000];
102  char offline_rev[100];
103  char config[1000000];
104  runInfo->SetBranchAddress("index", &index);
105  runInfo->SetBranchAddress("nPhotonsTot", &nPhotTotal);
106  runInfo->SetBranchAddress("md5", md5);
107  runInfo->SetBranchAddress("offline_rev", offline_rev);
108  runInfo->SetBranchAddress("config", config);
109 
110  map<int, RunInfo> run;
111  for (int i=0; i<runInfo->GetEntries(); ++i) {
112 
113  runInfo->GetEntry(i);
114 
115  if (run.count(index)) {
116  run[index].nTotalPhotons += nPhotTotal;
117  if (run[index].offlineRev != string(offline_rev) ||
118  run[index].configList != config ||
119  run[index].md5 != md5) {
120  cout << " ERROR: Input data mismatch ! " << endl;
121  exit(1);
122  }
123 
124  } else {
125 
126  run[index].nTotalPhotons = nPhotTotal;
127  run[index].offlineRev = offline_rev;
128  run[index].configList = config;
129  run[index].md5 = md5;
130 
131  }
132 
133  }
134 
135  return run;
136 }
137 
138 
139 
140 // -----------------------------------------------------------------------
141 void CalibrateTel(ostream& calibXml, const int index, const RunInfo runInfo) {
142 
143  const bool writeErrorsToXml = false;
144 
145  cout << "Calibrate telescope, index = " << index << endl;
146 
147  const int eyeId = index / 100;
148  const int telId = index % 100;
149 
150  ostringstream dataName;
151  dataName << "drumData_" << index;
152 
153  TChain* drumData = new TChain(dataName.str().c_str());
154  drumData->Add(gParameters.fileNames.c_str());
155 
156  map<int, CalibResult> constants = CalibrateTelescope(drumData);
157 
158  /*
159  // find largst pixel id
160  int maxPixelId = 0;
161  for (map<int, CalibResult>::const_iterator iCal = constants.begin();
162  iCal != constants.end(); ++iCal) {
163  if (iCal->first>maxPixelId)
164  maxPixelId = iCal->first;
165  }
166  vector<double>
167  */
168 
169  double meanError = 0;
170  for (map<int, CalibResult>::const_iterator iCal = constants.begin();
171  iCal != constants.end(); ++iCal) {
172 
173  const int pixelId = iCal->first;
174  const CalibResult calData = iCal->second;
175 
176  const double calib = calData.calib;
177  const double calibErr = calData.calibErr;
178 
179 
180  cout << " pixel id=" << setw(4) << pixelId
181  << " s=" << setw(10) << fixed << calib
182  << " +- " << setw(10) << calibErr << " [ph/ADC]"
183  << "\n";
184 
185 
186  calibXml << " " << setprecision(16) << setw(18) << calib;
187  if (writeErrorsToXml)
188  calibXml << " <!-- +- " << setw(18) << calibErr << " -->";
189  calibXml << "\n";
190 
191  meanError += calibErr;
192 
193  } // end loop pixels
194 
195  if (constants.size())
196  meanError /= constants.size();
197 
198  calibXml << " <!-- mean calib. uncertainty: " << setw(18) << meanError << " -->";
199 
200 
201  calibXml << " </calibration>\n"
202  " </EndToEnd>\n\n";
203 
204 
205 } // end of CalculateCalibrationConstants
206 
207 
208 
209 // ---------------------------------------------------------------------------------
210 map<int, CalibResult> CalibrateTelescope(TChain* drumData) {
211 
212  int pixelId;
213  double nGen, nPix, calib, calibErr, electronicsFactor;
214  drumData->SetBranchAddress("id", &pixelId);
215  drumData->SetBranchAddress("nGen", &nGen);
216  drumData->SetBranchAddress("nPix", &nPix);
217  drumData->SetBranchAddress("calib", &calib);
218  drumData->SetBranchAddress("calibErr", &calibErr);
219  drumData->SetBranchAddress("electronicsFactor", &electronicsFactor);
220 
221 
222  map<int, int> counter;
223  map<int, CalibResult> constants;
224 
225  // count photons
226  for (int i=0; i<drumData->GetEntries(); ++i) {
227 
228  drumData->GetEntry(i);
229 
230  if (counter.count(pixelId)) {
231  counter[pixelId]++;
232  constants[pixelId].nPhotGen += nGen;
233  constants[pixelId].nPhotPixel += nPix;
234  if (constants[pixelId].electronicsFactor != electronicsFactor) {
235  cout << "ERROR: incompatible pixel data found!" << endl;
236  exit(2);
237  }
238  } else {
239  counter[pixelId] = 1;
240  constants[pixelId].nPhotGen = nGen;
241  constants[pixelId].nPhotPixel = nPix;
242  constants[pixelId].electronicsFactor = electronicsFactor;
243  constants[pixelId].calib = 0;
244  constants[pixelId].calibErr = 0;
245  }
246  }
247 
248  // check pixel data
249  bool first = true;
250  double fact = 0;
251  for (map<int, int>::const_iterator iPix = counter.begin();
252  iPix != counter.end(); ++iPix ) {
253  if (first) {
254  fact = iPix->second;
255  } else {
256  if (fact != iPix->second) {
257  cout << "ERROR: incompatible number of pixels found in input data " << endl;
258  exit(3);
259  }
260  }
261  }
262 
263  // compute calibration constants
264  for (map<int, CalibResult>::iterator iPix = constants.begin();
265  iPix != constants.end(); ++iPix ) {
266 
267  CalibResult& dat = iPix->second;
268 
269  const double epsilon = double(dat.nPhotPixel) / dat.nPhotGen;
270  const double epsilonErr = sqrt((epsilon - epsilon*epsilon) / dat.nPhotGen);
271 
272  // const double pixelSignal = pixelPhotons * qEff * gain; // add electronics [ph -> ADC]
273  // const double calib = flux_drum_perp * diaArea * pixelSolid / pixelSignal;
274 
275  const double calib = 1 / (epsilon * dat.electronicsFactor);
276  const double calibErr = epsilonErr / (epsilon * epsilon * dat.electronicsFactor);
277 
278  dat.calib = calib;
279  dat.calibErr = calibErr;
280 
281  cout << "gen=" << dat.nPhotGen << " pix=" << dat.nPhotPixel << " eps=" << epsilon << endl;
282  }
283 
284  return constants;
285 }
string offlineRev
Definition: DrumCalib.cc:23
RunInfo()
Definition: DrumCalib.cc:22
double nPhotGen
Definition: DrumCalib.cc:32
int exit
Definition: dump1090.h:237
int main(int argc, char *argv[])
Definition: DBSync.cc:58
struct Parameters gParameters
fwk::VModule::ResultFlag(fwk::VModule::* run)(evt::Event &)
Definition: fwkPython.cc:59
double calibErr
Definition: DrumCalib.cc:31
void CalibrateTel(ostream &calibXml, const int index, const RunInfo runInfo)
Definition: DrumCalib.cc:141
uint16_t * data
Definition: dump1090.h:228
string md5
Definition: DrumCalib.cc:25
unsigned int nTotalPhotons
Definition: DrumCalib.cc:26
double calib
Definition: DrumCalib.cc:30
double nPhotPixel
Definition: DrumCalib.cc:33
double electronicsFactor
Definition: DrumCalib.cc:34
string configList
Definition: DrumCalib.cc:24
string fileNames
Definition: DrumCalib.cc:18
map< int, CalibResult > CalibrateTelescope(TChain *data)
Definition: DrumCalib.cc:210
map< int, RunInfo > ReadRunInfo(const string &fileNames)
Definition: DrumCalib.cc:94

, generated on Tue Sep 26 2023.