11 #include <cdc/calibration/WireEfficiencyAlgorithm.h>
13 #include <calibration/CalibrationAlgorithm.h>
15 #include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
16 #include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
18 #include <cdc/geometry/CDCGeometryPar.h>
19 #include <cdc/dbobjects/CDCBadWires.h>
21 #include <framework/database/IntervalOfValidity.h>
22 #include <framework/logging/Logger.h>
25 #include <TFitResult.h>
28 #include <TGraphAsymmErrors.h>
34 using namespace TrackFindingCDC;
39 " -------------------------- Wire Efficiency Estimation Algorithm -------------------------\n"
45 B2INFO(
"Creating efficiencies for every layer");
47 unsigned short wireID;
48 unsigned short layerID;
52 auto efftree = getObjectPtr<TTree>(
"efftree");
53 efftree->SetBranchAddress(
"wireID", &wireID);
54 efftree->SetBranchAddress(
"layerID", &layerID);
55 efftree->SetBranchAddress(
"z", &z);
56 efftree->SetBranchAddress(
"isFound", &isFound);
59 B2INFO(
"Building empty efficiency objects");
60 static const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
61 B2INFO(
"Wire Topology found");
63 B2INFO(
"CDC Geometry found");
65 for (
const CDCWireLayer& wireLayer : wireTopology.getWireLayers()) {
66 unsigned short layerNo = wireLayer.getICLayer();
67 B2INFO(
"Got layer " << layerNo);
68 std::string m_nameOfLayer = std::string(
"effLayer_").append(std::to_string(layerNo));
69 std::string m_titleOfLayer = std::string(
"Efficiency of wires in layer ").append(std::to_string(layerNo));
70 B2INFO(
"Built names for " << layerNo);
72 unsigned short nzbins = 30 - layerNo / 7;
74 double widbins[2] = { -0.5, cdcgeo.
nWiresInLayer(layerNo) - 0.5};
75 double zbins[2] = {wireLayer.getBackwardZ(), wireLayer.getForwardZ()};
77 B2INFO(
"Built bins for " << layerNo);
79 TEfficiency* effInLayer =
new TEfficiency(m_nameOfLayer.c_str(), m_titleOfLayer.c_str(), nzbins, zbins[0], zbins[1], nwidbins,
80 widbins[0], widbins[1]);
81 B2INFO(
"TEfficiency for " << layerNo <<
"successfully built");
83 m_efficiencyList->Add(effInLayer);
84 B2INFO(
"Teff for layer " << layerNo <<
" was sucessfully listed.");
86 TFile* outputCollection =
new TFile(
"LayerEfficiencies.root",
"RECREATE");
89 B2INFO(
"Filling the efficiencies");
90 const Long64_t nEntries = efftree->GetEntries();
91 B2INFO(
"Number of entries in tree: " << nEntries;);
92 for (Long64_t i = 0; i < nEntries; i++) {
94 TEfficiency* efficiencyInLayer = (TEfficiency*)m_efficiencyList->At(layerID);
95 efficiencyInLayer->Fill(isFound, z, wireID);
97 m_efficiencyList->Write();
98 B2INFO(
"TEfficiencies successfully filled.");
99 outputCollection->Close();
100 B2INFO(
"TEfficiencies successfully saved");
102 if (nEntries > 1000)
return true;
108 B2INFO(
"Beginning detection of bad wires");
109 static const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
110 B2INFO(
"Wire Topology found");
112 for (
const CDCWireLayer& wireLayer : wireTopology.getWireLayers()) {
113 unsigned short layerNo = wireLayer.getICLayer();
114 B2INFO(
"Checking layer " << layerNo);
117 auto efficiencyInLayer = (TEfficiency*)m_efficiencyList->At(layerNo);
118 auto passed = (TH2F*)efficiencyInLayer->GetPassedHistogram();
119 auto total = (TH2F*)efficiencyInLayer->GetTotalHistogram();
122 if (!total->GetEntries())
continue;
125 double minFitRange = wireLayer.getBackwardZ() + 30;
126 double maxFitRange = wireLayer.getForwardZ() - 30;
127 TF1* constantFunction =
new TF1(
"constantFunction",
"pol0", minFitRange, maxFitRange);
130 auto passedProjectedX = passed->ProjectionX(
"projectionx1");
131 auto totalProjectedX = total->ProjectionX(
"projectionx2");
132 TEfficiency* efficiencyProjectedX =
new TEfficiency(*passedProjectedX, *totalProjectedX);
134 unsigned short minFitBin = passedProjectedX->FindBin(minFitRange) + 1;
135 unsigned short maxFitBin = passedProjectedX->FindBin(maxFitRange) - 1;
138 auto passedProjectedY = passed->ProjectionY(
"projectiony1", minFitRange, maxFitRange);
139 auto totalProjectedY = total->ProjectionY(
"projectiony2", minFitRange, maxFitRange);
140 TEfficiency* efficiencyProjectedY =
new TEfficiency(*passedProjectedY, *totalProjectedY);
143 float totalAverage = 0;
144 int nonZeroWires = 0;
145 for (
int i = 0; i <= passedProjectedY->GetNbinsX(); ++i) {
146 float efficiencyAtBin = efficiencyProjectedY->GetEfficiency(i);
147 if (efficiencyAtBin > 0.4) {
148 totalAverage += efficiencyAtBin;
153 nonZeroWires > 0 ? totalAverage /= nonZeroWires : totalAverage == 0;
155 TGraphAsymmErrors* graphEfficiencyProjected = efficiencyProjectedX->CreateGraph();
157 B2INFO(
"Successfully determined average properties of layer " << layerNo);
158 B2INFO(
"Looping over wires");
161 for (
int i = 0; i <= passed->GetNbinsY(); ++i) {
164 auto singleWirePassed = passed->ProjectionX(
"single wire projection passed", i, i);
165 auto singleWireTotal = total->ProjectionX(
"single wire projection total", i, i);
168 if (!singleWirePassed->Integral(minFitBin, maxFitBin)) {
169 double wireID = passed->GetYaxis()->GetBinCenter(i);
174 TEfficiency* singleWireEfficiency =
new TEfficiency(*singleWirePassed, *singleWireTotal);
175 TGraphAsymmErrors* graphSingleWireEfficiency = singleWireEfficiency->CreateGraph();
178 TFitResultPtr singleWireFitResults = graphSingleWireEfficiency->Fit(constantFunction,
"SQR");
179 double singleWireEfficiencyFromFit = (singleWireFitResults.Get())->Value(0);
180 double singleWireUpErrorFromFit = (singleWireFitResults.Get())->UpperError(0);
183 float p_value =
chiTest(graphSingleWireEfficiency, graphEfficiencyProjected, minFitRange, maxFitRange);
185 bool averageCondition = (0.95 * totalAverage) > (singleWireEfficiencyFromFit + 5 * singleWireUpErrorFromFit);
186 bool pvalueCondition = p_value < 0.01;
187 bool generalCondition = singleWireEfficiencyFromFit < 0.4;
188 if (generalCondition || (averageCondition && pvalueCondition)) {
189 double wireID = passed->GetYaxis()->GetBinCenter(i);
193 B2INFO(
"Bad wires for " << layerNo <<
" recorded");
197 B2INFO(
"Bad wire list sucessfully saved.");
205 unsigned short ndof = 0;
208 int numOfEntries1 = graph1->GetN();
209 int numOfEntries2 = graph2->GetN();
213 for (
int index1 = 0; index1 < numOfEntries1; ++index1) {
215 if (graph1->GetX()[index1] < minValue)
continue;
216 if (graph1->GetX()[index1] > maxValue)
continue;
217 for (
int index2 = 0; index2 < numOfEntries2; ++index2) {
218 if (graph1->GetX()[index1] == graph2->GetX()[index2]) {
220 double chiNumerator = pow(graph1->GetY()[index1] - graph2->GetY()[index2], 2);
221 double chiDenominator = pow(graph1->GetErrorYhigh(index1), 2) + pow(graph1->GetErrorYlow(index1), 2);
222 chi += chiNumerator / chiDenominator;
228 return TMath::Prob(chi, ndof);
234 B2INFO(
"ExpRun used for DB Geometry : " << exprun.first <<
" " << exprun.second;);
237 B2INFO(
"Creating CDCGeometryPar object");
240 bool enoughEventsInInput;
245 if (enoughEventsInInput)
return c_OK;