12 #include "art/Framework/Core/EDFilter.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Event.h"
15 #include "art/Framework/Principal/Handle.h"
16 #include "art/Framework/Services/Registry/ServiceHandle.h"
17 #include "canvas/Persistency/Common/FindManyP.h"
18 #include "canvas/Persistency/Common/Ptr.h"
19 #include "canvas/Persistency/Common/PtrVector.h"
20 #include "fhiclcpp/ParameterSet.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
37 #include "TMathBase.h"
43 explicit MuonFilter(fhicl::ParameterSet
const&);
50 std::vector<double>
const fCuts;
63 , fClusterModuleLabel{pset.get<std::string>(
"ClusterModuleLabel")}
64 , fLineModuleLabel{pset.get<std::string>(
"LineModuleLabel")}
65 , fCuts{pset.get<std::vector<double>>(
"Cuts")}
66 , fDCenter{pset.get<
double>(
"DCenter")}
67 , fDelay{pset.get<
double>(
"Delay")}
68 , fTolerance{pset.get<
double>(
"Tolerance")}
69 , fMaxIon{pset.get<
double>(
"MaxIon")}
70 , fIonFactor{pset.get<
double>(
"IonFactor")}
71 , fDeltaWire{pset.get<
int>(
"DeltaWire")}
78 art::ServiceHandle<geo::Geometry const> geom;
79 auto const clockData =
80 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
82 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
90 int vPlane = geom->Nplanes() - 1;
92 int uPlane = vPlane - 1;
94 art::Handle<std::vector<recob::Cluster>> clustHandle;
99 art::PtrVector<recob::Cluster> clusters;
100 clusters.reserve(clustHandle->size());
101 for (
unsigned int i = 0; i < clustHandle->size(); ++i) {
102 clusters.push_back(art::Ptr<recob::Cluster>(clustHandle, i));
104 double indIon(0), colIon(0);
105 std::map<int, int> indMap;
106 std::map<int, int> colMap;
107 std::vector<std::pair<int, int>> rLook;
109 std::vector<std::vector<double>> tGoing;
110 std::vector<std::vector<double>> matched;
111 std::vector<double> pointTemp(6);
112 std::pair<int, int> pairTemp;
116 std::vector<art::Ptr<recob::Hit>> hits = fmh.at(
cluster);
117 for (
unsigned int hit = 0;
hit < hits.size();
hit++) {
118 ionSum += hits[
hit]->PeakAmplitude();
120 if (clusters[
cluster]->View() == uView)
122 else if (clusters[
cluster]->View() == vView)
125 mf::LogInfo(
"MuonFilter") <<
"Ionizations: " << indIon <<
" " << colIon;
126 art::Handle<std::vector<recob::Cluster>> lines;
127 art::PtrVector<recob::Cluster> inductionSegments, collectionSegments;
129 art::PtrVector<recob::Cluster> lineVec;
130 lineVec.reserve(lines->size());
131 for (
unsigned int i = 0; i < lines->size(); ++i) {
132 lineVec.push_back(art::Ptr<recob::Cluster>(lines, i));
135 for (
size_t cl = 0; cl < clusters.size(); cl++) {
136 std::vector<art::Ptr<recob::Hit>> hits = fmh.at(cl);
137 if (hits.size() > 0 && clusters[cl]->View() == uView)
138 inductionSegments.push_back(clusters[cl]);
139 else if (hits.size() > 0 && clusters[cl]->View() == vView)
140 collectionSegments.push_back(clusters[cl]);
146 if (inductionSegments.size() == 0 || collectionSegments.size() == 0) {
147 mf::LogInfo(
"MuonFilter") <<
"At least one plane with no track";
151 for (
unsigned int i = 0; i < inductionSegments.size(); i++) {
152 if (indMap[i])
continue;
153 for (
unsigned int j = 0; j < collectionSegments.size(); j++) {
154 if (colMap[j])
continue;
156 art::Ptr<recob::Cluster> indSeg = inductionSegments[i];
157 art::Ptr<recob::Cluster> colSeg = collectionSegments[j];
159 std::vector<art::Ptr<recob::Hit>> indHits = fmhi.at(i);
161 std::vector<art::Ptr<recob::Hit>> colHits = fmhc.at(j);
163 double trk1Start = indSeg->StartTick() +
fDelay;
164 double trk1End = indSeg->EndTick() +
fDelay;
165 double trk2Start = colSeg->StartTick();
166 double trk2End = colSeg->EndTick();
168 int uPos1 = indSeg->StartWire();
169 int uPos2 = indSeg->EndWire();
170 int const vPos1 = colSeg->StartWire();
171 int const vPos2 = colSeg->EndWire();
172 mf::LogInfo(
"MuonFilter") <<
"I J " << i <<
" " << j;
173 mf::LogInfo(
"MuonFilter")
174 <<
"Start/end " << indSeg->StartWire() <<
" " << colSeg->StartWire() <<
" "
175 << indSeg->EndWire() <<
" " << colSeg->EndWire();
176 mf::LogInfo(
"MuonFilter")
177 <<
"U's " << uPos1 <<
" " << uPos2 <<
"V's " << vPos1 <<
" " << vPos2 <<
" times "
178 << trk1End <<
" " << trk2End <<
" " << trk1Start <<
" " << trk2Start;
187 mf::LogInfo(
"MuonFilter") <<
"Swapped1";
188 std::swap(uPos1, uPos2);
191 if ((TMath::Abs(trk1Start - trk2Start) >
fTolerance &&
192 TMath::Abs(trk1End - trk2End) >
fTolerance) &&
193 (TMath::Abs(trk1Start - trk2End) <
fTolerance &&
194 TMath::Abs(trk1End - trk2Start) <
fTolerance)) {
195 std::swap(trk1Start, trk1End);
196 std::swap(uPos1, uPos2);
197 mf::LogInfo(
"MuonFilter") <<
"Swapped2";
199 mf::LogInfo(
"MuonFilter")
200 <<
"Times: " << trk1Start <<
" " << trk2Start <<
" " << trk1End <<
" " << trk2End;
205 if ((TMath::Abs(trk1Start - trk2Start) <
fTolerance &&
206 TMath::Abs(trk1End - trk2End) <
fTolerance) &&
207 (TMath::Abs(uPos1 - vPos1) <=
fDeltaWire + 2 &&
208 TMath::Abs(uPos2 - vPos2) <=
fDeltaWire + 2)) {
214 double y1, y2, z1, z2;
215 geom->IntersectionPoint(u_wID1, v_wID1, y1, z1);
216 geom->IntersectionPoint(u_wID2, v_wID2, y2, z2);
218 double const x1 = (trk1Start + trk2Start) / 2.0 * drift -
fDCenter;
219 double const x2 = (trk1End + trk2End) / 2.0 * drift -
fDCenter;
220 mf::LogInfo(
"MuonFilter") <<
"Match " << matchNum <<
" " << x1 <<
" " << y1 <<
" " << z1
221 <<
" " << x2 <<
" " << y2 <<
" " << z2;
222 bool x1edge, x2edge, y1edge, y2edge, z1edge, z2edge;
223 indMap[i] = matchNum;
224 colMap[j] = matchNum;
232 x1edge = (TMath::Abs(x1) -
fCuts[0] > 0);
233 x2edge = (TMath::Abs(x2) -
fCuts[0] > 0);
234 y1edge = (TMath::Abs(y1) -
fCuts[1] > 0);
235 y2edge = (TMath::Abs(y2) -
fCuts[1] > 0);
236 z1edge = (TMath::Abs(z1) -
fCuts[2] > 0);
237 z2edge = (TMath::Abs(z2) -
fCuts[2] > 0);
238 if ((x1edge || y1edge || z1edge) && (x2edge || y2edge || z2edge)) {
239 tGoing.push_back(pointTemp);
240 mf::LogInfo(
"MuonFilter") <<
"outside Removed induction ion: ";
242 for (
size_t h = 0;
h < indHits.size();
h++) {
243 mf::LogInfo(
"MuonFilter") << indHits[
h]->PeakAmplitude() <<
" ";
244 indIon -= indHits[
h]->PeakAmplitude();
246 mf::LogInfo(
"MuonFilter") <<
"Removed collection ion: ";
248 for (
size_t h = 0;
h < colHits.size();
h++) {
249 mf::LogInfo(
"MuonFilter") << colHits[
h]->PeakAmplitude() <<
" ";
250 colIon -= colHits[
h]->PeakAmplitude();
252 mf::LogInfo(
"MuonFilter")
253 <<
"Ionization outside track I/C: " << indIon <<
" " << colIon;
255 else if ((x1edge || y1edge || z1edge) && !(x2edge || y2edge || z2edge) &&
257 tGoing.push_back(pointTemp);
258 mf::LogInfo(
"MuonFilter") <<
"stopping Removed induction ion: ";
259 for (
size_t h = 0;
h < indHits.size();
h++) {
260 mf::LogInfo(
"MuonFilter") << indHits[
h]->PeakAmplitude() <<
" ";
261 indIon -= indHits[
h]->PeakAmplitude();
263 mf::LogInfo(
"MuonFilter") <<
"Removed collection ion: ";
264 for (
size_t h = 0;
h < colHits.size();
h++) {
265 mf::LogInfo(
"MuonFilter") << colHits[
h]->PeakAmplitude() <<
" ";
266 colIon -= colHits[
h]->PeakAmplitude();
268 mf::LogInfo(
"MuonFilter")
269 <<
"Ionization outside track I/C: " << indIon <<
" " << colIon;
272 pairTemp = std::make_pair(i, j);
273 mf::LogInfo(
"MuonFilter") <<
"rLook matchnum " << matchNum <<
" " << i <<
" " << j;
274 rLook.push_back(pairTemp);
275 matched.push_back(pointTemp);
284 for (
unsigned int i = 0; i < tGoing.size(); i++)
285 for (
unsigned int j = 0; j < matched.size(); j++) {
286 mf::LogInfo(
"MuonFilter") << tGoing.size() <<
" " << matched.size() <<
" " << i <<
" " << j;
288 if ((tGoing[i][2] <= matched[j][2]) && (tGoing[i][5] >= matched[j][5])) {
289 TVector3
a1(&tGoing[i][0]);
290 TVector3
a2(&tGoing[i][3]);
291 TVector3 b1(&matched[j][0]);
292 distance = TMath::Abs((((a1 - a2).Cross((a1 - a2).Cross(a1 - b1))).Unit()).Dot(a1 - b1));
293 mf::LogInfo(
"MuonFilter") <<
"distance " <<
distance;
295 mf::LogInfo(
"MuonFilter")
296 <<
"Removing delta ion " << rLook.size() <<
" " << rLook[j].first <<
" " << matchNum;
297 std::vector<art::Ptr<recob::Hit>> temp = fmhi.at(rLook[j].
first);
298 for (
unsigned int h = 0;
h < temp.size();
h++)
299 indIon -= temp[
h]->PeakAmplitude();
300 temp = fmhc.at(rLook[j].
second);
301 for (
unsigned int h = 0;
h < temp.size();
h++)
302 colIon -= temp[
h]->PeakAmplitude();
306 mf::LogInfo(
"MuonFilter") <<
"indIon " << indIon *
fIonFactor <<
" colIon " << colIon;
bool filter(art::Event &evt) override
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Declaration of signal hit object.
std::vector< double > const fCuts
int const fDeltaWire
allowed differences in wire number between 2 planes
std::string const fLineModuleLabel
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
MuonFilter(fhicl::ParameterSet const &)
std::string const fClusterModuleLabel
Declaration of cluster object.
Encapsulate the construction of a single detector plane.
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
art framework interface to geometry description