9#include <cdc/calibration/WireEfficiencyAlgorithm.h>
11#include <calibration/CalibrationAlgorithm.h>
13#include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
14#include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
16#include <cdc/geometry/CDCGeometryPar.h>
17#include <cdc/dbobjects/CDCBadWires.h>
19#include <framework/database/IntervalOfValidity.h>
20#include <framework/logging/Logger.h>
23#include <TFitResult.h>
26#include <TGraphAsymmErrors.h>
32using namespace TrackFindingCDC;
37 " -------------------------- Wire Efficiency Estimation Algorithm -------------------------\n"
43 B2INFO(
"Creating efficiencies for every layer");
45 unsigned short wireID;
46 unsigned short layerID;
50 auto efftree = getObjectPtr<TTree>(
"efftree");
51 efftree->SetBranchAddress(
"wireID", &wireID);
52 efftree->SetBranchAddress(
"layerID", &layerID);
53 efftree->SetBranchAddress(
"z", &z);
54 efftree->SetBranchAddress(
"isFound", &isFound);
57 B2INFO(
"Building empty efficiency objects");
59 B2INFO(
"Wire Topology found");
61 B2INFO(
"CDC Geometry found");
64 unsigned short layerNo = wireLayer.getICLayer();
65 B2INFO(
"Got layer " << layerNo);
66 std::string m_nameOfLayer = std::string(
"effLayer_").append(std::to_string(layerNo));
67 std::string m_titleOfLayer = std::string(
"Efficiency of wires in layer ").append(std::to_string(layerNo));
68 B2INFO(
"Built names for " << layerNo);
70 unsigned short nzbins = 30 - layerNo / 7;
72 double widbins[2] = { -0.5, cdcgeo.
nWiresInLayer(layerNo) - 0.5};
73 double zbins[2] = {wireLayer.getBackwardZ(), wireLayer.getForwardZ()};
75 B2INFO(
"Built bins for " << layerNo);
77 TEfficiency* effInLayer =
new TEfficiency(m_nameOfLayer.c_str(), m_titleOfLayer.c_str(), nzbins, zbins[0], zbins[1], nwidbins,
78 widbins[0], widbins[1]);
79 B2INFO(
"TEfficiency for " << layerNo <<
"successfully built");
82 B2INFO(
"Teff for layer " << layerNo <<
" was sucessfully listed.");
84 TFile* outputCollection =
new TFile(
"LayerEfficiencies.root",
"RECREATE");
87 B2INFO(
"Filling the efficiencies");
88 const Long64_t nEntries = efftree->GetEntries();
89 B2INFO(
"Number of entries in tree: " << nEntries);
90 for (Long64_t i = 0; i < nEntries; i++) {
92 TEfficiency* efficiencyInLayer = (TEfficiency*)
m_efficiencyList->At(layerID);
93 efficiencyInLayer->Fill(isFound, z, wireID);
96 B2INFO(
"TEfficiencies successfully filled.");
97 outputCollection->Close();
98 B2INFO(
"TEfficiencies successfully saved");
100 if (nEntries > 1000)
return true;
106 B2INFO(
"Beginning detection of bad wires");
108 B2INFO(
"Wire Topology found");
111 unsigned short layerNo = wireLayer.getICLayer();
112 B2INFO(
"Checking layer " << layerNo);
116 auto passed = (TH2F*)efficiencyInLayer->GetPassedHistogram();
117 auto total = (TH2F*)efficiencyInLayer->GetTotalHistogram();
120 if (!total->GetEntries())
continue;
123 double minFitRange = wireLayer.getBackwardZ() + 30;
124 double maxFitRange = wireLayer.getForwardZ() - 30;
125 TF1* constantFunction =
new TF1(
"constantFunction",
"pol0", minFitRange, maxFitRange);
128 auto passedProjectedX = passed->ProjectionX(
"projectionx1");
129 auto totalProjectedX = total->ProjectionX(
"projectionx2");
130 TEfficiency* efficiencyProjectedX =
new TEfficiency(*passedProjectedX, *totalProjectedX);
132 unsigned short minFitBin = passedProjectedX->FindBin(minFitRange) + 1;
133 unsigned short maxFitBin = passedProjectedX->FindBin(maxFitRange) - 1;
136 auto passedProjectedY = passed->ProjectionY(
"projectiony1", minFitRange, maxFitRange);
137 auto totalProjectedY = total->ProjectionY(
"projectiony2", minFitRange, maxFitRange);
138 TEfficiency* efficiencyProjectedY =
new TEfficiency(*passedProjectedY, *totalProjectedY);
141 float totalAverage = 0;
142 int nonZeroWires = 0;
143 for (
int i = 0; i <= passedProjectedY->GetNbinsX(); ++i) {
144 float efficiencyAtBin = efficiencyProjectedY->GetEfficiency(i);
145 if (efficiencyAtBin > 0.4) {
146 totalAverage += efficiencyAtBin;
151 nonZeroWires > 0 ? totalAverage /= nonZeroWires : totalAverage == 0;
153 TGraphAsymmErrors* graphEfficiencyProjected = efficiencyProjectedX->CreateGraph();
155 B2INFO(
"Successfully determined average properties of layer " << layerNo);
156 B2INFO(
"Looping over wires");
159 for (
int i = 0; i <= passed->GetNbinsY(); ++i) {
162 auto singleWirePassed = passed->ProjectionX(
"single wire projection passed", i, i);
163 auto singleWireTotal = total->ProjectionX(
"single wire projection total", i, i);
166 if (!singleWirePassed->Integral(minFitBin, maxFitBin)) {
167 double wireID = passed->GetYaxis()->GetBinCenter(i);
172 TEfficiency* singleWireEfficiency =
new TEfficiency(*singleWirePassed, *singleWireTotal);
173 TGraphAsymmErrors* graphSingleWireEfficiency = singleWireEfficiency->CreateGraph();
176 TFitResultPtr singleWireFitResults = graphSingleWireEfficiency->Fit(constantFunction,
"SQR");
177 double singleWireEfficiencyFromFit = (singleWireFitResults.Get())->Value(0);
178 double singleWireUpErrorFromFit = (singleWireFitResults.Get())->UpperError(0);
181 float p_value =
chiTest(graphSingleWireEfficiency, graphEfficiencyProjected, minFitRange, maxFitRange);
183 bool averageCondition = (0.95 * totalAverage) > (singleWireEfficiencyFromFit + 5 * singleWireUpErrorFromFit);
184 bool pvalueCondition = p_value < 0.01;
185 bool generalCondition = singleWireEfficiencyFromFit < 0.4;
186 if (generalCondition || (averageCondition && pvalueCondition)) {
187 double wireID = passed->GetYaxis()->GetBinCenter(i);
191 B2INFO(
"Bad wires for " << layerNo <<
" recorded");
195 B2INFO(
"Bad wire list sucessfully saved.");
203 unsigned short ndof = 0;
206 int numOfEntries1 = graph1->GetN();
207 int numOfEntries2 = graph2->GetN();
211 for (
int index1 = 0; index1 < numOfEntries1; ++index1) {
213 if (graph1->GetX()[index1] < minValue)
continue;
214 if (graph1->GetX()[index1] > maxValue)
continue;
215 for (
int index2 = 0; index2 < numOfEntries2; ++index2) {
216 if (graph1->GetX()[index1] == graph2->GetX()[index2]) {
218 double chiNumerator = pow(graph1->GetY()[index1] - graph2->GetY()[index2], 2);
219 double chiDenominator = pow(graph1->GetErrorYhigh(index1), 2) + pow(graph1->GetErrorYlow(index1), 2);
220 chi += chiNumerator / chiDenominator;
226 return TMath::Prob(chi, ndof);
232 B2INFO(
"ExpRun used for DB Geometry : " << exprun.first <<
" " << exprun.second);
235 B2INFO(
"Creating CDCGeometryPar object");
238 bool enoughEventsInInput;
243 if (enoughEventsInInput)
return c_OK;
void outputToFile(std::string fileName) const
Output the contents in text file format.
void setWire(const WireID &wid, double eff=0)
Set the wire in the list.
The Class for CDC Geometry Parameters.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
TList * m_efficiencyList
TList of efficiencies.
double chiTest(TGraphAsymmErrors *graph1, TGraphAsymmErrors *graph2, double minVale, double maxValue)
chitest
void detectBadWires()
detects bad wires.
CDCBadWires * m_badWireList
BadWireList that willbe built.
DBObjPtr< CDCGeometry > m_cdcGeo
Geometry of CDC.
WireEfficiencyAlgorithm()
Constructor.
EResult calibrate() override
Run algo on data.
bool buildEfficiencies()
create 2D TEfficiency for each wire and return True if more than 1000 entries
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class representing a sense wire layer in the central drift chamber.
Class representing the sense wire arrangement in the whole of the central drift chamber.
const std::vector< Belle2::TrackFindingCDC::CDCWireLayer > & getWireLayers() const
Getter for the underlying storing layer vector.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
Abstract base class for different kinds of events.