5 #define ZDCNLCalibration_cxx
19 Long64_t numEntries =
m_tree->GetEntriesFast();
21 unsigned int countPassed = 0;
23 int lastLumiBlock = -1;
24 int LBStartEntry = -1;
35 if (lastLumiBlock > -1) {
47 std::cout <<
"From a total of " << numEntries <<
" entries, " << countPassed <<
" were selected for analysis" << std::endl;
74 static TH1D* snHist =
new TH1D(
"ZDCNLCalibSNHist",
"", 200, 0, 2000);
84 for ( LBEvtMap::const_iterator iter =
LBStart; iter != LBEnd; ++iter) {
85 unsigned int entryStart = iter->second.first;
86 unsigned int entryEnd = iter->second.second;
91 std::cout <<
"Error reading entry " <<
entry <<
", quitting" << std::endl;
92 throw std::runtime_error(
"Error reading entry for ZDCNLCalibration");
95 if (!trigger)
continue;
98 if ((testMask & 0xf) != 0xf)
continue;
101 snHist->Fill(sumAmp);
105 int ibin = snHist->GetMaximumBin();
106 double center = snHist->GetBinCenter(ibin);
107 double maxCounts = snHist->GetBinContent(ibin);
109 static TF1* gaussFunc =
new TF1(
"gaussFunc",
"gaus", 100, 2000);
111 gaussFunc->SetParameters(maxCounts, center, 100);
112 snHist->Fit(
"gaussFunc",
"",
"", center*0.7, center*1.3);
114 double gaussMean = gaussFunc->GetParameter(1);
115 double gaussWidth = gaussFunc->GetParameter(2);
117 double cutLow = gaussMean -2.*gaussWidth;
118 double cutHigh = gaussMean + 2*gaussWidth;
121 std::cout <<
"SN cut range = " << cutLow <<
" to " << cutHigh << std::endl;
124 return std::pair<float, float>(cutLow, cutHigh);
127 std::pair<std::pair<float, float>,std::pair<float, float> >
130 static TH1D* sntnHist =
new TH1D(
"ZDCNLCalibSNTNHist",
"", 200, 0, 2000);
140 for ( LBEvtMap::const_iterator iter =
LBStart; iter != LBEnd; ++iter) {
141 unsigned int entryStart = iter->second.first;
142 unsigned int entryEnd = iter->second.second;
147 std::cout <<
"Error reading entry " <<
entry <<
", quitting" << std::endl;
148 throw std::runtime_error(
"Error reading entry for ZDCNLCalibration");
151 if (!trigger)
continue;
154 if ((testMask & 0xf) != 0xf)
continue;
157 sntnHist->Fill(sumAmp);
161 int ibin = sntnHist->GetMaximumBin();
162 double center = sntnHist->GetBinCenter(ibin);
163 double maxCounts = sntnHist->GetBinContent(ibin);
165 static TF1* twogaussFunc =
new TF1(
"twogaussFunc",
"[0]*exp(-pow((x-[1])/[2],2)/2.) + [3]*exp(-pow((x-[4])/[5],2)/2.)", 100, 2000);
167 twogaussFunc->SetParameters(maxCounts, center, 100, maxCounts/2, 2*center, 200);
168 sntnHist->Fit(
"twogaussFunc",
"",
"", center*0.7, 2*center*1.3);
170 double gaussMean1 = twogaussFunc->GetParameter(1);
171 double gaussMean2 = twogaussFunc->GetParameter(4);
173 double gaussWidth1 = std::abs(twogaussFunc->GetParameter(2));
174 double gaussWidth2 = std::abs(twogaussFunc->GetParameter(5));
176 double cutLow1 = gaussMean1 -2.*gaussWidth1;
177 double cutHigh1 = gaussMean1 + 2*gaussWidth1
179 double cutLow2 = gaussMean2 -2.*gaussWidth2;
180 double cutHigh2 = gaussMean2 + 2*gaussWidth2;
182 if (cutHigh1 > cutLow2) {
183 double middle = 0.5*(cutHigh1 + cutLow2);
189 std::cout <<
"SN cut range = " << cutLow1 <<
" to " << cutHigh1 << std::endl;
190 std::cout <<
"TN cut range = " << cutLow2 <<
" to " << cutHigh2 << std::endl;
193 return std::pair<std::pair<float, float>, std::pair<float, float> >(std::pair<float, float>(cutLow1, cutHigh1),
194 std::pair<float, float>(cutLow2, cutHigh2));
198 size_t LBLow,
size_t LBHigh, std::array<int, 4> maxPowerModule,
199 const std::vector<std::pair<double, double> >& nNeutERange,
200 bool excludeHE,
float heSumThresh,
float HEDeweight)
202 std::for_each(maxPowerModule.begin(), maxPowerModule.end(),
205 std::cout <<
"Found max power = 0, quitting" << std::endl;
212 size_t numWeights =
std::accumulate(maxPowerModule.begin(), maxPowerModule.end(), 0);
213 size_t arrayDim = 4*m_maxNLPower;
215 size_t arrayDim2D = arrayDim*arrayDim;
217 size_t numNeutMax = nNeutERange.size();
219 std::vector<double> sumsHE(arrayDim, 0);
220 std::vector<double> sums2DHE(arrayDim2D, 0);
222 std::vector<std::vector<double> > sumsNeutVec(numNeutMax, std::vector<double>(arrayDim, 0));
223 std::vector<std::vector<double> > sums2DNeutVec(numNeutMax, std::vector<double>(arrayDim2D, 0));
225 LBEvtMap::const_iterator
LBStart = m_LumiBlockEvtMap.lower_bound(LBLow);
226 LBEvtMap::const_iterator LBEnd = m_LumiBlockEvtMap.upper_bound(LBHigh);
230 const bool& triggerOpp = (
side == 1 ? L1_ZDC_C : L1_ZDC_A);
231 const bool& triggerSame = (
side == 1 ? L1_ZDC_A : L1_ZDC_C);
233 std::vector<int> numNeutEvent(numNeutMax, 0);
238 std::string calibName = (calibInput !=
"" ? calibInput :
"default");
241 for ( LBEvtMap::const_iterator iter =
LBStart; iter != LBEnd; ++iter) {
242 unsigned int entryStart = iter->second.first;
243 unsigned int entryEnd = iter->second.second;
246 Long64_t
nb = m_tree->GetEntry(
entry);
248 std::cout <<
"Error reading entry " <<
entry <<
", quitting" << std::endl;
249 throw std::runtime_error(
"Error reading entry for ZDCNLCalibration");
252 int testMask = zdc_ZdcModuleMask >>
side*4;
253 if ((testMask & 0xf) != 0xf)
continue;
255 double sumAmp = CalculateEnergy(zdc_ZdcModuleAmp[
side],
calib);
257 if (triggerSame && sumAmp > heSumThresh && !excludeHE) {
258 AddToSums(sumsHE, sums2DHE, zdc_ZdcModuleAmp[
side]);
264 if (triggerOpp && sumAmp > nNeutERange[0].
first && sumAmp < nNeutERange[0].
second) {
265 AddToSums(sumsNeutVec[0], sums2DNeutVec[0], zdc_ZdcModuleAmp[
side]);
269 for (
size_t iNNeut = 1; iNNeut < numNeutMax; iNNeut++) {
270 if (sumAmp > nNeutERange[iNNeut].
first && sumAmp < nNeutERange[iNNeut].
second) {
271 AddToSums(sumsNeutVec[iNNeut], sums2DNeutVec[iNNeut], zdc_ZdcModuleAmp[
side]);
272 numNeutEvent[iNNeut]++;
278 if (m_debugLevel >= 0) {
279 std::cout <<
"Statistics for side " <<
side <<
", lb range = " << LBLow <<
", " << LBHigh
280 <<
" : # high energy events = " << numHEEvent;
282 for (
size_t iNNeut = 0; iNNeut < numNeutMax; iNNeut++) {
283 std::cout <<
", # of " +
std::to_string(iNNeut) +
" N events = " << numNeutEvent[iNNeut];
286 std::cout << std::endl;
292 for (
size_t iNNeut = 0; iNNeut < numNeutMax; iNNeut++) {
293 if (numNeutEvent[iNNeut] == 0) {
294 std::cout <<
"Found no " +
std::to_string(iNNeut) +
"N events, quitting" << std::endl;
298 std::for_each(sumsNeutVec[iNNeut].
begin(), sumsNeutVec[iNNeut].
end(), [&](
double&
sum) {
sum /= numNeutEvent[iNNeut];});
299 std::for_each(sums2DNeutVec[iNNeut].
begin(), sums2DNeutVec[iNNeut].
end(), [&](
double&
sum) {
sum /= numNeutEvent[iNNeut];});
303 if (numHEEvent == 0) {
304 std::cout <<
"Found no high-energy events, quitting" << std::endl;
308 std::for_each(sumsHE.begin(), sumsHE.end(), [&](
double&
sum) {sum /= numHEEvent;});
309 std::for_each(sums2DHE.begin(), sums2DHE.end(), [&](
double&
sum) {sum /= numHEEvent;});
315 size_t numFitParams = numWeights;
316 TMatrixD minimMatrix(numFitParams, numFitParams);
317 TVectorD minimVector(numFitParams);
319 FillMinimizationData(minimMatrix, minimVector, maxPowerModule, HEDeweight,
320 sumsNeutVec, sumsHE, sums2DNeutVec, sums2DHE);
322 if (m_debugLevel >= 2) {
323 std::cout <<
"Dumping matrix equation: " << std::endl;
329 std::cout << std::scientific << std::setw(9) << std::setprecision(2) << minimMatrix(
index1,
index2) <<
" ";
332 std::cout <<
"| | w_" <<
index1 <<
" = | " << minimVector(
index1) << std::endl;
334 std::cout << std::endl;
338 TDecompLU lu(minimMatrix);
341 bool status = lu.Solve(minimVector);
344 std::cout <<
"Minimization failed for side " <<
side <<
", lb range "
345 << LBLow <<
", " << LBHigh << endl;
350 calibData.
LBEnd = LBHigh;
353 for (
size_t module : {0, 1, 2, 3}) {
356 for (
size_t power = 0; power < maxPowerModule[
module]; power++) {
357 calibData.
weights.at(
module).at(power) = minimVector(weightIndex++);
359 if (m_debugLevel >= 0) {
360 std::cout <<
"Weight for module,power " <<
module <<
", " << power <<
" = " << calibData.
weights.at(
module).at(power)
368 AddCalibration(
side, calibOutput, calibData);
374 std::string calibName = (
name !=
"" ?
name :
"default");
378 std::cout <<
"Testing calibration for side " <<
side <<
"name: " << calibName << std::endl;
382 for (
int module : {0, 1, 2, 3}) {
390 static std::array<float, 4> treeRawAmp;
391 static std::array<float, 4> treeCalibAmp;
392 static float treeRawSum, treeCalibSum, treeRawSumOpp;
393 static unsigned int treeEventNumber;
394 static bool passedSN, passedTN, passedHE;
398 m_testTree =
new TTree(
"ZDCNLCalibTest",
"ZDCNLCalibTest");
401 m_testTree->Branch(
"EventNumber", &treeEventNumber,
"eventNumber/I");
407 m_testTree->Branch(
"RawSum", &treeRawSum,
"RawSum/f");
408 m_testTree->Branch(
"CalibSum", &treeCalibSum,
"CalibSum/f");
409 m_testTree->Branch(
"RawAmp", &treeRawAmp[0],
"RawAmp[4]/f");
410 m_testTree->Branch(
"CalibAmp", &treeCalibAmp[0],
"CalibAmp[4]/f");
411 m_testTree->Branch(
"RawSumOpp", &treeRawSumOpp,
"RawSumOpp/f");
417 for ( LBEvtMap::const_iterator iter =
LBStart; iter != LBEnd; ++iter) {
418 unsigned int entryStart = iter->second.first;
419 unsigned int entryEnd = iter->second.second;
424 std::cout <<
"Error reading entry " <<
entry <<
", quitting" << std::endl;
425 throw std::runtime_error(
"Error reading entry for ZDCNLCalibration");
429 if ((testMask & 0xf) != 0xf)
continue;
435 float sumCalibAmp = 0;
436 float weightIndex = 0;
438 std::array<double, 4> calibAmpModule = {0, 0, 0, 0};
441 std::cout <<
"TestCalibration:: dumping calibration results for event " <<
count << std::endl;
444 for (
size_t module : {0, 1, 2, 3}) {
448 for (
size_t power = 0; power <
calib.weights[
module].size(); power++) {
461 std::cout <<
"Module " <<
module <<
" : raw, calibrated energy = " << std::fixed << amp <<
", " <<
energy << std::endl;
466 std::cout <<
"Total: raw, calibrated energy = " << std::fixed << sumAmp <<
", " << sumCalibAmp << std::endl;
471 treeCalibSum = sumCalibAmp;
485 std::array<int, 4> maxPowerModule,
float HEDeweight,
486 const std::vector<std::vector<double> >& sums1DVec,
const std::vector<double>& sumsHE,
487 const std::vector<std::vector<double> >& sums2DVec,
const std::vector<double>& sumsHE2D)
489 size_t numWeights = minimVector.GetNrows();
490 size_t numColumns = minimMatrix.GetNcols();
491 size_t numRows = minimMatrix.GetNrows();
492 size_t numNeutMax = sums1DVec.size();
494 if (numRows != numWeights || numColumns != numWeights){
495 throw std::runtime_error(
"ZDCNLCalibration::FillMinimizationData; incompatible row/col numbers");
500 double sumFracSqr = 0;
501 for (
size_t module : {0, 1, 2, 3}) {
510 for (
size_t module1 : {0, 1, 2, 3}) {
511 for (
size_t power1 = 0; power1 < maxPowerModule[module1]; power1++) {
516 for (
size_t module2 : {0, 1, 2, 3}) {
517 for (
size_t power2 = 0; power2 < maxPowerModule[module2]; power2++) {
521 unsigned int sum2DIndex = sumIndexOffset + power2;
523 std::for_each(sums2DVec.begin(), sums2DVec.end(), [&] (
const std::vector<double>& sums) {element += 2*sums.at(sum2DIndex);});
531 double sum = sumsHE2D.at(sumIndexOffset + power2);
534 if (module2 == module1) element += 2*
sum;
537 element += 2*sumFracSqr*
sum;
542 std::cout <<
"Filling module 1, power 1 = " << module1 <<
", " << power1 <<
", module 2, power 2 = "
543 << module2 <<
", " << power2 <<
" with sum at index " << sumIndexOffset + power2
544 <<
", value = " << minimMatrix(
index1,
index2) << std::endl;
556 for (
unsigned int iNNeut = 0; iNNeut < numNeutMax; iNNeut++) {
561 std::cout <<
"Filling vector module , power = " << module1 <<
", " << power1 <<
" with sum at index " << sum1DIndex
562 <<
", value = " << minimVector[
index1] << std::endl;