57 std::vector<std::vector<unsigned int>> matchedclusters;
64 std::vector<std::vector<TH1D>> signals(nplanes);
66 std::vector<std::vector<unsigned int>> Cls(nplanes);
67 std::vector<std::vector<CluLen>> clulens(nplanes);
69 for (
size_t iclu = 0; iclu < clusterlist.size(); ++iclu) {
73 float w0 = clusterlist[iclu]->StartWire();
74 float w1 = clusterlist[iclu]->EndWire();
75 float t0 = clusterlist[iclu]->StartTick();
76 float t1 = clusterlist[iclu]->EndTick();
84 clusterlist[iclu]->
Plane().Cryostat);
88 clusterlist[iclu]->
Plane().Cryostat);
89 clulen.length =
std::hypot((w0 - w1) * wire_pitch, x0 -
x1);
91 switch (clusterlist[iclu]->
View()) {
93 if (
fEnableU) clulens[0].push_back(clulen);
96 if (
fEnableV) clulens[1].push_back(clulen);
99 if (
fEnableZ) clulens[2].push_back(clulen);
106 for (
size_t i = 0; i < clulens.size(); ++i) {
107 std::sort(clulens[i].
begin(), clulens[i].
end(), SortByLength);
108 for (
size_t j = 0; j < clulens[i].size(); ++j) {
109 Cls[i].push_back(clulens[i][j].
index);
113 for (
int i = 0; i < nplanes; ++i) {
114 for (
size_t ic = 0; ic < Cls[i].size(); ++ic) {
116 Form(
"sig_%d_%d", i,
int(ic)), Form(
"sig_%d_%d", i,
int(ic)), nts + 100, -100, nts);
118 Form(
"sigint_%d_%d", i,
int(ic)), Form(
"sigint_%d_%d", i,
int(ic)), nts + 100, -100, nts);
119 std::vector<art::Ptr<recob::Hit>> hitlist =
fm.at(Cls[i][ic]);
120 std::sort(hitlist.begin(), hitlist.end(),
SortByWire);
122 for (
auto theHit = hitlist.begin(); theHit != hitlist.end(); theHit++) {
124 double time = (*theHit)->PeakTime();
126 (*theHit)->WireID().Plane, (*theHit)->WireID().TPC, (*theHit)->WireID().Cryostat);
128 double charge = (*theHit)->Integral();
129 int bin = sig.FindBin(time);
130 sig.SetBinContent(bin, sig.GetBinContent(bin) + charge);
131 for (
int j = bin; j <= sig.GetNbinsX(); ++j) {
132 sigint.SetBinContent(j, sigint.GetBinContent(j) + charge);
135 if (sigint.Integral()) sigint.Scale(1. / sigint.GetBinContent(sigint.GetNbinsX()));
136 signals[i].push_back(sigint);
141 std::vector<int> matched(clusterlist.size());
142 for (
size_t i = 0; i < clusterlist.size(); ++i)
145 for (
int i = 0; i < nplanes - 1; ++i) {
146 for (
int j = i + 1; j < nplanes; ++j) {
147 for (
size_t c1 = 0;
c1 < Cls[i].size(); ++
c1) {
148 for (
size_t c2 = 0; c2 < Cls[j].size(); ++c2) {
151 if (clusterlist[Cls[i][
c1]]->
View() == clusterlist[Cls[j][c2]]->View())
continue;
153 if (clusterlist[Cls[i][
c1]]->
Plane().Cryostat !=
154 clusterlist[Cls[j][c2]]->Plane().Cryostat)
156 if (clusterlist[Cls[i][
c1]]->
Plane().TPC != clusterlist[Cls[j][c2]]->Plane().TPC)
159 if (matched[Cls[i][
c1]] == 1 && matched[Cls[j][c2]] == 1)
continue;
162 if (signals[i][
c1].Integral() && signals[j][c2].Integral())
163 ks = signals[i][
c1].KolmogorovTest(&signals[j][c2]);
166 <<
"One of the two clusters appears to be empty: " << clusterlist[Cls[i][
c1]]->ID()
167 <<
" " << clusterlist[Cls[j][c2]]->ID() <<
" " << i <<
" " << j <<
" " <<
c1 <<
" " 168 << c2 <<
" " << signals[i][
c1].Integral() <<
" " << signals[j][c2].Integral();
177 for (
size_t l = 0;
l < matchedclusters.size(); ++
l) {
178 for (
size_t m = 0;
m < matchedclusters[
l].size(); ++
m) {
179 if (matchedclusters[
l][
m] == Cls[i][
c1]) {
183 else if (matchedclusters[
l][
m] == Cls[j][c2]) {
191 bool matchview =
false;
193 for (
size_t ii = 0; ii < matchedclusters[imatch].size(); ++ii) {
194 if (clusterlist[matchedclusters[imatch][ii]]->
View() ==
195 clusterlist[Cls[i][
c1]]->View()) {
198 if (
fm.at(Cls[i][
c1]).size() >
fm.at(matchedclusters[imatch][ii]).size()) {
199 matched[matchedclusters[imatch][ii]] = 0;
200 matchedclusters[imatch][ii] = Cls[i][
c1];
201 matched[Cls[i][
c1]] = 1;
206 matchedclusters[imatch].push_back(Cls[i][c1]);
207 matched[Cls[i][
c1]] = 1;
211 bool matchview =
false;
212 for (
size_t jj = 0; jj < matchedclusters[imatch].size(); ++jj) {
213 if (clusterlist[matchedclusters[imatch][jj]]->
View() ==
214 clusterlist[Cls[j][c2]]->View()) {
217 if (
fm.at(Cls[j][c2]).size() >
fm.at(matchedclusters[imatch][jj]).size()) {
218 matched[matchedclusters[imatch][jj]] = 0;
219 matchedclusters[imatch][jj] = Cls[j][c2];
220 matched[Cls[j][c2]] = 1;
225 matchedclusters[imatch].push_back(Cls[j][c2]);
226 matched[Cls[j][c2]] = 1;
231 std::vector<unsigned int>
tmp;
232 tmp.push_back(Cls[i][c1]);
233 tmp.push_back(Cls[j][c2]);
234 matchedclusters.push_back(tmp);
235 matched[Cls[i][
c1]] = 1;
236 matched[Cls[j][c2]] = 1;
244 for (
size_t i = 0; i < matchedclusters.size(); ++i) {
245 if (matchedclusters[i].
size())
247 for (
size_t j = 0; j < matchedclusters[i].size(); ++j) {
252 return matchedclusters;
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
code to link reconstructed objects back to the MC truth information
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
AdcChannelData::View View
double GetXTicksOffset(int p, int t, int c) const
Planes which measure Z direction.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
bool SortByWire(art::Ptr< recob::Hit > const &h1, art::Ptr< recob::Hit > const &h2)
unsigned int NumberTimeSamples() const
double ConvertTicksToX(double ticks, int p, int t, int c) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
QTextStream & bin(QTextStream &s)
static constexpr double fm
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
recob::tracking::Plane Plane