9#include <cdc/calibration/WireEfficiencyAlgorithm.h>
10#include <calibration/CalibrationAlgorithm.h>
11#include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
12#include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
13#include <cdc/geometry/CDCGeometryPar.h>
14#include <cdc/dbobjects/CDCBadWires.h>
15#include <framework/database/IntervalOfValidity.h>
16#include <framework/logging/Logger.h>
18#include <TFitResult.h>
21#include <TGraphAsymmErrors.h>
27using namespace TrackFindingCDC;
31 " -------------------------- Wire Efficiency Estimation Algorithm -------------------------\n"
37 B2INFO(
"Creating efficiencies for every layer");
39 unsigned short wireID;
40 unsigned short layerID;
44 auto efftree = getObjectPtr<TTree>(
"efftree");
45 efftree->SetBranchAddress(
"wireID", &wireID);
46 efftree->SetBranchAddress(
"layerID", &layerID);
47 efftree->SetBranchAddress(
"z", &z);
48 efftree->SetBranchAddress(
"isFound", &isFound);
51 B2INFO(
"Building empty efficiency objects");
53 B2INFO(
"Wire Topology found");
55 B2INFO(
"CDC Geometry found");
58 unsigned short layerNo = wireLayer.getICLayer();
64 unsigned short nzbins = 30 - layerNo / 7;
66 double widbins[2] = { -0.5, cdcgeo.
nWiresInLayer(layerNo) - 0.5};
67 double zbins[2] = {wireLayer.getBackwardZ(), wireLayer.getForwardZ()};
69 TEfficiency* effInLayer =
new TEfficiency(Form(
"effLayer_%d", layerNo), Form(
"Hit efficiency pf L%d ; z (cm) ; IWire ", layerNo),
70 nzbins, zbins[0], zbins[1], nwidbins, widbins[0], widbins[1]);
72 B2INFO(
"Teff for layer " << layerNo <<
" was sucessfully listed.");
74 TFile* outputCollection =
new TFile(
"LayerEfficiencies.root",
"RECREATE");
77 B2INFO(
"Filling the efficiencies");
78 const Long64_t nEntries = efftree->GetEntries();
79 B2INFO(
"Number of entries in tree: " << nEntries);
80 for (Long64_t i = 0; i < nEntries; i++) {
82 TEfficiency* efficiencyInLayer = (TEfficiency*)
m_efficiencyList->At(layerID);
83 efficiencyInLayer->Fill(isFound, z, wireID);
86 B2INFO(
"TEfficiencies successfully filled.");
87 outputCollection->Close();
88 B2INFO(
"TEfficiencies successfully saved");
90 if (nEntries > 1000)
return true;
96 B2INFO(
"Beginning detection of bad wires");
98 B2INFO(
"Wire Topology found");
101 unsigned short layerNo = wireLayer.getICLayer();
102 B2INFO(
"Checking layer " << layerNo);
106 auto passed = (TH2F*)efficiencyInLayer->GetPassedHistogram();
107 auto total = (TH2F*)efficiencyInLayer->GetTotalHistogram();
110 if (!total->GetEntries())
continue;
113 double minFitRange = wireLayer.getBackwardZ() + 30;
114 double maxFitRange = wireLayer.getForwardZ() - 30;
115 TF1* constantFunction =
new TF1(
"constantFunction",
"pol0", minFitRange, maxFitRange);
118 auto passedProjectedX = passed->ProjectionX(
"projectionx1");
119 auto totalProjectedX = total->ProjectionX(
"projectionx2");
120 TEfficiency* efficiencyProjectedX =
new TEfficiency(*passedProjectedX, *totalProjectedX);
122 unsigned short minFitBin = passedProjectedX->FindBin(minFitRange) + 1;
123 unsigned short maxFitBin = passedProjectedX->FindBin(maxFitRange) - 1;
126 auto passedProjectedY = passed->ProjectionY(
"projectiony1", minFitRange, maxFitRange);
127 auto totalProjectedY = total->ProjectionY(
"projectiony2", minFitRange, maxFitRange);
128 TEfficiency* efficiencyProjectedY =
new TEfficiency(*passedProjectedY, *totalProjectedY);
131 float totalAverage = 0;
132 int nonZeroWires = 0;
133 for (
int i = 0; i <= passedProjectedY->GetNbinsX(); ++i) {
134 float efficiencyAtBin = efficiencyProjectedY->GetEfficiency(i);
135 if (efficiencyAtBin > 0.2) {
136 totalAverage += efficiencyAtBin;
141 nonZeroWires > 0 ? totalAverage /= nonZeroWires : totalAverage == 0;
143 TGraphAsymmErrors* graphEfficiencyProjected = efficiencyProjectedX->CreateGraph();
145 B2INFO(
"Successfully determined average properties of layer " << layerNo);
146 B2INFO(
"Looping over wires");
149 for (
int i = 0; i <= passed->GetNbinsY(); ++i) {
152 auto singleWirePassed = passed->ProjectionX(
"single wire projection passed", i, i);
153 auto singleWireTotal = total->ProjectionX(
"single wire projection total", i, i);
156 if (!singleWirePassed->Integral(minFitBin, maxFitBin)) {
157 double wireID = passed->GetYaxis()->GetBinCenter(i);
159 if (wireID < 0 || wireID >= maxWires) {
160 B2ERROR(
"Invalid wireID: " << wireID <<
" for LayerID: " << layerNo
161 <<
". Max wires: " << maxWires);
168 TEfficiency* singleWireEfficiency =
new TEfficiency(*singleWirePassed, *singleWireTotal);
169 TGraphAsymmErrors* graphSingleWireEfficiency = singleWireEfficiency->CreateGraph();
172 TFitResultPtr singleWireFitResults = graphSingleWireEfficiency->Fit(constantFunction,
"SQR");
173 double singleWireEfficiencyFromFit = (singleWireFitResults.Get())->Value(0);
174 double singleWireUpErrorFromFit = (singleWireFitResults.Get())->UpperError(0);
177 float p_value =
chiTest(graphSingleWireEfficiency, graphEfficiencyProjected, minFitRange, maxFitRange);
179 bool averageCondition = (0.95 * totalAverage) > (singleWireEfficiencyFromFit + 3 * singleWireUpErrorFromFit);
180 bool pvalueCondition = p_value < 0.01;
181 bool generalCondition = singleWireEfficiencyFromFit < 0.4;
182 if (generalCondition || (averageCondition && pvalueCondition)) {
183 double wireID = passed->GetYaxis()->GetBinCenter(i);
187 B2INFO(
"Bad wires for " << layerNo <<
" recorded");
191 B2INFO(
"Bad wire list sucessfully saved.");
199 unsigned short ndof = 0;
202 int numOfEntries1 = graph1->GetN();
203 int numOfEntries2 = graph2->GetN();
207 for (
int index1 = 0; index1 < numOfEntries1; ++index1) {
209 if (graph1->GetX()[index1] < minValue)
continue;
210 if (graph1->GetX()[index1] > maxValue)
continue;
211 for (
int index2 = 0; index2 < numOfEntries2; ++index2) {
212 if (graph1->GetX()[index1] == graph2->GetX()[index2]) {
214 double chiNumerator = pow(graph1->GetY()[index1] - graph2->GetY()[index2], 2);
215 double chiDenominator = pow(graph1->GetErrorYhigh(index1), 2) + pow(graph1->GetErrorYlow(index1), 2);
216 chi += chiNumerator / chiDenominator;
222 return TMath::Prob(chi, ndof);
228 B2INFO(
"ExpRun used for DB Geometry : " << exprun.first <<
" " << exprun.second);
231 B2INFO(
"Creating CDCGeometryPar object");
234 bool enoughEventsInInput;
239 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 successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class representating a sense wire layer in the central drift chamber.
Class representating 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.