2 #include "art/Framework/Core/EDProducer.h"
3 #include "art/Framework/Core/ModuleMacros.h"
4 #include "art/Framework/Principal/Event.h"
5 #include "fhiclcpp/ParameterSet.h"
6 #include "art/Framework/Principal/Handle.h"
7 #include "canvas/Persistency/Common/Ptr.h"
8 #include "canvas/Persistency/Common/PtrVector.h"
9 #include "art/Framework/Services/Registry/ServiceHandle.h"
10 #include "art_root_io/TFileService.h"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
72 float Distance(
int x1,
int y1,
int x2,
int y2);
74 void Hough(
vector<vector<int>> coords, vector<int> param,
bool save_hits,
int nentry,
75 vector<vector<int>>& lines,
vector<vector<int>>& hit_idx);
78 int range,
vector<art::Ptr<recob::Hit>> hitlist,
122 art::ServiceHandle<art::TFileService>
tfs;
130 produces< std::vector<sbnd::comm::MuonTrack> >();
131 produces< art::Assns<recob::Hit, sbnd::comm::MuonTrack> >();
161 std::unique_ptr<vector<sbnd::comm::MuonTrack>> muon_tracks(
new vector<sbnd::comm::MuonTrack>);
162 std::unique_ptr<art::Assns<recob::Hit, sbnd::comm::MuonTrack>> muon_tracks_assn(
new art::Assns<recob::Hit, sbnd::comm::MuonTrack>);
164 int event = evt.id().event();
165 std::cout <<
"Processing event " <<
event << std::endl;
167 art::Handle<vector<recob::Hit>> hitListHandle;
168 vector<art::Ptr<recob::Hit>> hitlist;
170 art::fill_ptr_vector(hitlist, hitListHandle);
171 nhits = hitlist.size();
174 std::cout <<
"Failed to get recob::Hit data product." << std::endl;
181 for (
int i = 0; i <
nhits; ++i) {
183 int hit_wire = int(wireid.
Wire), hit_peakT = int(hitlist[i]->PeakTime()), hit_plane = wireid.
Plane, hit_tpc = wireid.
TPC;
184 if (hit_plane==2 && hit_peakT>0){
185 vector<int> v{hit_wire,hit_peakT,i};
195 bool save_col_hits =
true;
200 bool muon_in_tpc0 = !(
lines_02.empty());
201 bool muon_in_tpc1 = !(
lines_12.empty());
207 if (muon_in_tpc0 ==
true || muon_in_tpc1 ==
true){
208 for (
int i = 0; i <
nhits; ++i) {
210 int hit_wire = int(wireid.
Wire), hit_peakT = int(hitlist[i]->PeakTime()), hit_tpc = wireid.
TPC, hit_plane = wireid.
Plane;
211 vector<int> v{hit_wire,hit_peakT,i};
212 if (muon_in_tpc0 ==
true){
213 if (hit_plane==0 && hit_tpc==0 && hit_peakT>0)
215 else if (hit_plane==1 && hit_tpc==0 && hit_peakT>0)
218 if (muon_in_tpc1 ==
true){
219 if (hit_plane==0 && hit_tpc==1 && hit_peakT>0)
221 else if (hit_plane==1 && hit_tpc==1 && hit_peakT>0)
225 bool save_ind_hits =
false;
226 vector<vector<int>> ind_empty;
249 bool keep_track =
false;
260 mytrack.
x1_pos = float(endpoint1.X());
261 mytrack.
y1_pos = float(endpoint1.Y());
262 mytrack.
z1_pos = float(endpoint1.Z());
263 mytrack.
x2_pos = float(endpoint2.X());
264 mytrack.
y2_pos = float(endpoint2.Y());
265 mytrack.
z2_pos = float(endpoint2.Z());
270 mytrack.
tpc = (endpoint1.X() < 0)? 0:1;
273 muon_tracks->push_back(mytrack);
274 for (
size_t hit_i=0; hit_i<track_hit_idx.size(); hit_i++){
275 int idx = track_hit_idx[hit_i];
276 util::CreateAssn(*
this, evt, *muon_tracks, hitlist[idx], *muon_tracks_assn);
282 evt.put(std::move(muon_tracks));
283 evt.put(std::move(muon_tracks_assn));
287 return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2) * 1.0);
291 vector<vector<int>>& lines,
vector<vector<int>>& hit_idx){
293 int threshold = param.at(0);
294 int max_gap = param.at(1);
295 int range = param.at(2);
296 int min_length = param.at(3);
297 int muon_length = param.at(4);
301 const int h = 3500;
const int w = 2000;
302 constexpr
int accu_h = h + w + 1 ;
const int accu_w = 180;
303 const int x_c = (w/2);
const int y_c = (h/2);
306 int accu[accu_h][accu_w] = {{0}};
307 int (*adata)[accu_w];
308 adata = &accu[(accu_h-1)/2];
311 vector<vector<int>> data = coords;
312 vector<vector<int>> deaccu;
313 vector<vector<int>> outlines;
314 vector<vector<int>> outhit_idx;
317 int count = coords.size();
318 for ( ; count>0; count--){
319 int idx = rndgen.Uniform(count);
320 int max_val = threshold-1;
321 if ((coords.at(idx)).
empty())
323 int x = coords[idx][0],
y = coords[idx][1], rho = 0, theta = 0;
327 for (
int j=0; j<accu_w; j++){
328 int r = int(round((x-x_c)*cos(j*M_PI/accu_w) + (y-y_c)*sin(j*M_PI/accu_w)));
329 int val = ++(adata[
r][j]);
333 theta = j*180/accu_w;
336 if (max_val < threshold){
337 (coords.at(idx)).clear();
341 vector<vector<int>> endpoint(2, vector<int>(4));
342 vector<int> lines_idx;
344 for (
int k=0;
k<2;
k++){
346 while (
gap < max_gap){
348 if ( (idx+i) == int(data.size()) || (idx+i) <0)
350 if ((data.at(idx+i)).
empty())
352 int x1 = data[idx+i][0], y1 = int(data[idx+i][1]), wire_idx = data[idx+i][2];
354 if (endpoint[
k][0]!= 0){
355 last_x = endpoint[
k][0];
356 diffx =
abs(last_x - x1);
361 int y_val = int(round((rho - (x1 - x_c)*cos(theta*M_PI/180.0))/sin(theta*M_PI/180.0) + y_c));
362 if (
abs(y_val-y1) <= range){
364 endpoint[
k] = {x1, y1, wire_idx, idx+i};
365 (coords.at(idx+i)).clear();
366 (data.at(idx+i)).clear();
368 lines_idx.push_back(wire_idx);
377 for (
int n = (deaccu.size()-1);
n>=0;
n--){
378 int x1 = deaccu[
n][0], y1 = int(deaccu[
n][1]);
379 int y_val = int(round((rho - (x1 - x_c)*cos(theta*M_PI/180.0))/sin(theta*M_PI/180.0) + y_c));
380 if (y1 >= (y_val-range) && y1 <= (y_val+range)){
381 for (
int m=0;
m<accu_w;
m++){
382 int r = int(round((x1-x_c)*cos(
m*M_PI/accu_w) + (y1-y_c)*sin(
m*M_PI/accu_w)));
385 deaccu.erase(deaccu.begin() +
n);
389 int x0_end = endpoint[0][0], y0_end = endpoint[0][1], x1_end = endpoint[1][0], y1_end = endpoint[1][1];
390 int wire0_end = endpoint[0][2], wire1_end = endpoint[1][2];
391 int idx0_end = endpoint[0][3], idx1_end = endpoint[1][3];
392 if ((x0_end==0 && y0_end==0) || (x1_end==0 && y1_end==0))
394 vector<int> outline = {x0_end, y0_end, x1_end, y1_end, wire0_end, wire1_end, idx0_end, idx1_end, rho, theta};
396 outlines.push_back(outline);
398 outhit_idx.push_back(lines_idx);
403 for (
size_t i=0; i<outlines.size(); i++){
405 for (
size_t j=i+1; j<outlines.size() && same ==
false; j++){
406 int xi_coords[2] = {outlines[i][0], outlines[i][2]};
int xj_coords[2] = {outlines[j][0], outlines[j][2]};
407 int yi_coords[2] = {outlines[i][1], outlines[i][3]};
int yj_coords[2] = {outlines[j][1], outlines[j][3]};
408 int rhoi = outlines[i][8], rhoj = outlines[j][8];
409 int thetai = outlines[i][9], thetaj = outlines[j][9];
414 for (
int k=0;
k<2 && same ==
false;
k++){
415 for (
int l=0; l<2 && same ==
false; l++){
417 if ((xi_coords[
k] < (xj_coords[l] + var)) && (xi_coords[
k] > (xj_coords[l] - var)))
419 if ((yi_coords[
k] < (yj_coords[l] + var)) && (yi_coords[
k] > (yj_coords[l] - var)))
421 if ((rhoi < (rhoj + rho_var)) && (rhoi > (rhoj - rho_var)))
423 if ((thetai < (thetaj + theta_var)) && (thetai > (thetaj - theta_var)))
428 outlines[j][2] = outlines[i][0];
429 outlines[j][3] = outlines[i][1];
432 outlines[j][0] = outlines[i][0];
433 outlines[j][1] = outlines[i][1];
438 outlines[j][2] = outlines[i][2];
439 outlines[j][3] = outlines[i][3];
442 outlines[j][0] = outlines[i][2];
443 outlines[j][1] = outlines[i][3];
448 (outlines.at(i)).clear();
450 (outhit_idx.at(j)).insert( (outhit_idx.at(j)).
end(), (outhit_idx.at(i)).
begin(), (outhit_idx.at(i)).
end());
451 (outhit_idx.at(i)).clear();
459 for (
size_t i=0; i < outlines.size(); i++){
460 if ((outlines.at(i)).
empty())
462 int x0_end = outlines[i][0], y0_end = outlines[i][1], x1_end = outlines[i][2], y1_end = outlines[i][3];
464 int y_diff =
abs(y0_end-y1_end);
465 if (y_diff > muon_length){
466 lines.push_back(outlines.at(i));
468 hit_idx.push_back(outhit_idx.at(i));
472 float length =
Distance(x0_end,y0_end,x1_end,y1_end);
473 if (length > min_length){
474 lines.push_back(outlines.at(i));
476 hit_idx.push_back(outhit_idx.at(i));
481 data.clear(); deaccu.clear(); outlines.clear(); outhit_idx.clear();
541 int range,
vector<art::Ptr<recob::Hit>> hitlist,
542 vector<vector<geo::Point_t>>& muon_endpoints,
vector<vector<int>>& muon_hitpeakT,
vector<vector<int>>& muon_hit_idx){
543 if (lines_ind.empty() ==
false){
544 for (
size_t i=0; i<lines_col.size(); i++){
546 if ((lines_col.at(i)).
empty() ==
true)
548 for (
size_t j=0; j < lines_ind.size() && match ==
false; j++){
549 int peakT0_col, peakT1_col, peakT0_ind, peakT1_ind;
550 int wire0_col, wire1_col, wire0_ind, wire1_ind;
552 bool order_col = (lines_col.at(i)).at(1) < (lines_col.at(i)).at(3);
553 peakT0_col = order_col? (lines_col.at(i)).at(1) : (lines_col.at(i)).at(3);
554 peakT1_col = order_col? (lines_col.at(i)).at(3) : (lines_col.at(i)).at(1);
555 wire0_col = order_col? (lines_col.at(i)).at(4) : (lines_col.at(i)).at(5);
556 wire1_col = order_col? (lines_col.at(i)).at(5) : (lines_col.at(i)).at(4);
558 bool order_ind = (lines_ind.at(j)).at(1) < (lines_ind.at(j)).at(3);
559 peakT0_ind = order_ind? (lines_ind.at(j)).at(1) : (lines_ind.at(j)).at(3);
560 peakT1_ind = order_ind? (lines_ind.at(j)).at(3) : (lines_ind.at(j)).at(1);
561 wire0_ind = order_ind? (lines_ind.at(j)).at(4) : (lines_ind.at(j)).at(5);
562 wire1_ind = order_ind? (lines_ind.at(j)).at(5) : (lines_ind.at(j)).at(4);
564 int peakT_range = range;
565 if ( (
abs(peakT0_col - peakT0_ind) < peakT_range) && (
abs(peakT1_col - peakT1_ind) < peakT_range)){
589 if (endpoint1.Mag2() != 0 && endpoint2.Mag2() != 0 ){
590 vector<geo::Point_t> pair{endpoint1,endpoint2};
593 vector<int> v{peakT0_col, peakT1_col};
594 vector<int>
indices = hit_idx.at(i);
599 lines_col.at(i).clear();
609 double col_end1[3], col_end2[3], ind_end1[3], ind_end2[3];
612 if (
abs(ind_end1[1]) > 198 ||
abs(ind_end2[1]) > 198){
613 double ind_y = (
abs(ind_end1[1]) == 199.792) ? ind_end1[1] : ind_end2[1];
614 double ind_z = (
abs(ind_end1[1]) == 199.792) ? ind_end1[2] : ind_end2[2];
615 if (
abs(col_end1[2] - ind_z) < 8){
616 point.SetX(col_end1[0]);
631 muon_type.push_back(0);
636 bool end1_edge = (endpoint1.Y() > 198 || endpoint1.Y() < -198 || endpoint1.Z() > 503 || endpoint1.Z() < 6);
637 bool end2_edge = (endpoint2.Y() > 198 || endpoint2.Y() < -198 || endpoint2.Z() > 503 || endpoint2.Z() < 6);
639 if (end1_edge ==
false && end2_edge ==
true ){
640 muon_type.push_back(1);
641 double dx = dt*0.5*0.16;
642 double true_x = (endpoint2.X() > 0)? (202.05-dx):(-202.05+dx);
643 endpoint2.SetX(true_x);
645 else if (end1_edge ==
true && end2_edge ==
false){
646 muon_type.push_back(2);
647 double dx = dt*0.5*0.16;
648 double true_x = (endpoint1.X() > 0)? (202.05-dx):(-202.05+dx);
649 endpoint1.SetX(true_x);
652 else if ( (endpoint1.Y() > 198 && endpoint2.Y() < -198) || (endpoint1.Y() < -198 && endpoint2.Y() > 198) ){
653 muon_type.push_back(3);
655 else if ( (endpoint1.Z() > 503 && endpoint2.Z() < 6) || (endpoint1.Z() < 6 && endpoint2.Z() > 503)){
656 muon_type.push_back(4);
659 muon_type.push_back(5);
665 vector<vector<double>>& muon_trajectories){
671 double dx = dt*0.5*0.16;
672 double dy = float(pair[1].Y())-float(pair[0].Y());
673 double dz = float(pair[1].Z())-float(pair[0].Z());
675 double theta_xz = atan2(dx,dz) * 180/M_PI;
676 double theta_yz = atan2(dy,dz) * 180/M_PI;
680 vector<double> trajectories{theta_xz, theta_yz};
686 vector<double>& muon_t0){
689 if (muon_type.at(i) == 0 || muon_type.at(i) == 1)
691 else if (muon_type.at(i) == 2)
695 muon_t0.push_back(t0);
700 if (lines.empty()==
false){
701 std::cout <<
"plane = " << plane << std::endl;
702 for (
size_t i=0; i< lines.size(); i++){
703 vector<int> line = lines.at(i);
704 int wire0 = line.at(0), wire1 = line.at(2);
705 int peakT0 = line.at(1), peakT1 = line.at(3);
706 std::cout <<
"wire0, peakT0: (" << wire0 <<
", " << peakT0 <<
")" << std::endl;
707 std::cout <<
"wire1, peakT1: (" << wire1 <<
", " << peakT1 <<
")" << std::endl;
711 std::cout <<
"no lines found for this plane" << std::endl;
void ResetCollectionHitVectors(int n)
vector< vector< int > > hit_11
vector< vector< int > > hit_12
vector< vector< int > > lines_12
void SortEndpoints(vector< vector< geo::Point_t >> &muon_endpoints, vector< vector< int >> muon_hitpeakT, vector< int > &muon_type)
Utilities related to art service access.
vector< vector< int > > hit_01
process_name opflash particleana ie x
art::ServiceHandle< art::TFileService > tfs
bool FixEndpoints(geo::WireID wire_col, geo::WireID wire_ind, geo::Point_t &point)
vector< vector< int > > lines_01
Declaration of signal hit object.
void PrintHoughLines(vector< vector< int >> &lines, int plane)
vector< vector< int > > lines_02
vector< vector< int > > hit_idx_12
Definition of basic raw digits.
void FindTrajectories(vector< vector< geo::Point_t >> muon_endpoints, vector< vector< int >> muon_hitpeakT, vector< vector< double >> &muon_trajectories)
WireID_t Wire
Index of the wire within its plane.
vector< vector< int > > muon_hitpeakT
vector< vector< geo::Point_t > > muon_endpoints
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::vector< int > fKeepMuonTypes
vector< vector< int > > muon_hit_idx
void ResetMuonVariables(int n)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
MuonTrackProducer(fhicl::ParameterSet const &p)
Access the description of detector geometry.
object containing MC truth information necessary for making RawDigits and doing back tracking ...
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
void FindEndpoints(vector< vector< int >> &lines_col, vector< vector< int >> &lines_ind, vector< vector< int >> &hit_idx, int range, vector< art::Ptr< recob::Hit >> hitlist, vector< vector< geo::Point_t >> &muon_endpoints, vector< vector< int >> &muon_hitpeakT, vector< vector< int >> &muon_hit_idx)
process_name opflash particleana ie ie y
void ResetInductionHitVectors(int n)
float Distance(int x1, int y1, int x2, int y2)
Collect all the RawData header files together.
art framework interface to geometry description for auxiliary detectors
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
auto end(FixedBins< T, C > const &) noexcept
vector< vector< int > > lines_11
geo::GeometryCore const * fGeometryService
PlaneID_t Plane
Index of the plane within its TPC.
Description of geometry of one entire detector.
Definition of data types for geometry description.
Encapsulate the geometry of a wire.
auto begin(FixedBins< T, C > const &) noexcept
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
vector< vector< int > > hit_00
void produce(art::Event &evt) override
Encapsulate the construction of a single detector plane.
vector< vector< int > > lines_00
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
constexpr WireID()=default
Default constructor: an invalid TPC ID.
std::string fHitsModuleLabel
vector< vector< int > > hit_idx_02
void Hough(vector< vector< int >> coords, vector< int > param, bool save_hits, int nentry, vector< vector< int >> &lines, vector< vector< int >> &hit_idx)
std::size_t count(Cont const &cont)
TPCID_t TPC
Index of the TPC within its cryostat.
vector< vector< int > > lines_10
vector< vector< int > > hit_02
vector< vector< int > > hit_10
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
bool empty(FixedBins< T, C > const &) noexcept
void reconfigure(fhicl::ParameterSet const &p)
MuonTrackProducer & operator=(MuonTrackProducer const &)=delete
vector< vector< double > > muon_trajectories
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void Findt0(vector< vector< int >> muon_hitpeakT, vector< int > muon_type, vector< double > &muon_t0)