13 #include "art/Utilities/ToolMacros.h" 
   25 namespace ShowerRecoTools {
 
   37     void FinddEdxLength(std::vector<double>& dEdx_vec, std::vector<double>& dEdx_val);
 
   41     art::ServiceHandle<geo::Geometry> 
fGeom;
 
   81     , fCalorimetryAlg(pset.
get<fhicl::ParameterSet>(
"CalorimetryAlg"))
 
   82     , fMinAngleToWire(pset.
get<float>(
"MinAngleToWire"))
 
   83     , fShapingTime(pset.
get<float>(
"ShapingTime"))
 
   84     , fMinDistCutOff(pset.
get<float>(
"MinDistCutOff"))
 
   85     , fMaxDist(pset.
get<float>(
"MaxDist"))
 
   86     , fdEdxTrackLength(pset.
get<float>(
"dEdxTrackLength"))
 
   87     , fdEdxCut(pset.
get<float>(
"dEdxCut"))
 
   88     , fUseMedian(pset.
get<
bool>(
"UseMedian"))
 
   89     , fCutStartPosition(pset.
get<
bool>(
"CutStartPosition"))
 
   90     , fT0Correct(pset.
get<
bool>(
"T0Correct"))
 
   91     , fSCECorrectPitch(pset.
get<
bool>(
"SCECorrectPitch"))
 
   92     , fSCECorrectEField(pset.
get<
bool>(
"SCECorrectEField"))
 
   93     , fSCEInputCorrected(pset.
get<
bool>(
"SCEInputCorrected"))
 
   94     , fPFParticleLabel(pset.
get<art::InputTag>(
"PFParticleLabel"))
 
   95     , fVerbose(pset.
get<int>(
"Verbose"))
 
   96     , fShowerStartPositionInputLabel(pset.
get<
std::string>(
"ShowerStartPositionInputLabel"))
 
   97     , fInitialTrackSpacePointsInputLabel(pset.
get<
std::string>(
"InitialTrackSpacePointsInputLabel"))
 
   98     , fInitialTrackInputLabel(pset.
get<
std::string>(
"InitialTrackInputLabel"))
 
   99     , fShowerdEdxOutputLabel(pset.
get<
std::string>(
"ShowerdEdxOutputLabel"))
 
  100     , fShowerBestPlaneOutputLabel(pset.
get<
std::string>(
"ShowerBestPlaneOutputLabel"))
 
  101     , fShowerdEdxVecOutputLabel(pset.
get<
std::string>(
"ShowerdEdxVecOutputLabel"))
 
  104       throw cet::exception(
"ShowerTrajPointdEdx")
 
  105         << 
"Can only correct for SCE if input is already corrected" << std::endl;
 
  121         mf::LogError(
"ShowerTrajPointdEdx") << 
"Start position not set, returning " << std::endl;
 
  126         mf::LogError(
"ShowerTrajPointdEdx")
 
  127           << 
"Initial Track Spacepoints is not set returning" << std::endl;
 
  131       if (
fVerbose) mf::LogError(
"ShowerTrajPointdEdx") << 
"Initial Track is not set" << std::endl;
 
  136     std::vector<art::Ptr<recob::SpacePoint>> tracksps;
 
  139     if (tracksps.empty()) {
 
  141         mf::LogWarning(
"ShowerTrajPointdEdx") << 
"no spacepointsin the initial track" << std::endl;
 
  146     auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(
fPFParticleLabel);
 
  149     const art::FindManyP<recob::Hit>& fmsp =
 
  153     TVector3 ShowerStartPosition = {-999, -999, -999};
 
  163       auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(
fPFParticleLabel);
 
  164       const art::FindManyP<anab::T0>& fmpfpt0 =
 
  166       std::vector<art::Ptr<anab::T0>> pfpT0Vec = fmpfpt0.at(pfparticle.key());
 
  167       if (pfpT0Vec.size() == 1) { pfpT0Time = pfpT0Vec.front()->Time(); }
 
  171     std::map<int, std::vector<double>> dEdx_vec;
 
  172     std::map<int, std::vector<double>> dEdx_vecErr;
 
  173     std::map<int, int> num_hits;
 
  176       dEdx_vec[plane_id.Plane] = {};
 
  177       dEdx_vecErr[plane_id.Plane] = {};
 
  178       num_hits[plane_id.Plane] = 0;
 
  181     auto const clockData =
 
  182       art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
 
  184       art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
 
  187     for (
auto const sp : tracksps) {
 
  190       std::vector<art::Ptr<recob::Hit>> hits = fmsp.at(sp.key());
 
  193           mf::LogWarning(
"ShowerTrajPointdEdx")
 
  194             << 
"no hit for the spacepoint. This suggest the find many is wrong." << std::endl;
 
  197       const art::Ptr<recob::Hit> 
hit = hits[0];
 
  203       if (TPC != vtxTPC) { 
continue; }
 
  207       double dist_from_start = (pos - ShowerStartPosition).Mag();
 
  216       unsigned int index = 999;
 
  217       double MinDist = 999;
 
  221         TVector3 TrajPosition = {
 
  222           TrajPositionPoint.X(), TrajPositionPoint.Y(), TrajPositionPoint.Z()};
 
  228         const TVector3 
dist = pos - TrajPosition;
 
  230         if (dist.Mag() < MinDist && dist.Mag() < 
MaxDist * wirepitch) {
 
  231           MinDist = dist.Mag();
 
  237       if (index == 999) { 
continue; }
 
  240       TVector3 TrajPosition = {TrajPositionPoint.X(), TrajPositionPoint.Y(), TrajPositionPoint.Z()};
 
  243       TVector3 TrajPositionStart = {
 
  244         TrajPositionStartPoint.X(), TrajPositionStartPoint.Y(), TrajPositionStartPoint.Z()};
 
  247       if ((TrajPosition - TrajPositionStart).Mag() == 0) { 
continue; }
 
  248       if ((TrajPosition - ShowerStartPosition).Mag() == 0) { 
continue; }
 
  250       if ((TrajPosition - TrajPositionStart).Mag() < 
fMinDistCutOff * wirepitch) { 
continue; }
 
  254       TVector3 TrajDirection = {
 
  255         TrajDirection_vec.X(), TrajDirection_vec.Y(), TrajDirection_vec.Z()};
 
  260       TVector3 TrajDirectionYZ = {0, TrajDirection_vec.Y(), TrajDirection_vec.Z()};
 
  261       TVector3 PlaneDirection = 
fGeom->Plane(planeid).GetIncreasingWireDirection();
 
  264         if (
fVerbose) mf::LogWarning(
"ShowerTrajPointdEdx") << 
"remove from angle cut" << std::endl;
 
  270       double distance_in_x = TrajDirection.X() * (wirepitch / TrajDirection.Dot(PlaneDirection));
 
  271       double time_taken = 
std::abs(distance_in_x / velocity);
 
  275         if (
fVerbose) mf::LogWarning(
"ShowerTrajPointdEdx") << 
"move for shaping time" << std::endl;
 
  279       if ((TrajPosition - TrajPositionStart).Mag() > 
dEdxTrackLength) { 
continue; }
 
  282       ++num_hits[planeid.
Plane];
 
  285       double trackpitch = (TrajDirection * (wirepitch / TrajDirection.Dot(PlaneDirection))).Mag();
 
  289           trackpitch, pos, TrajDirection.Unit(), hit->WireID().TPC);
 
  293       double dQdx = hit->Integral() / trackpitch;
 
  296       double localEField = 
detProp.Efield();
 
  301         clockData, 
detProp, dQdx, hit->PeakTime(), planeid.
Plane, pfpT0Time, localEField);
 
  304       dEdx_vec[planeid.
Plane].push_back(dEdx);
 
  309     int best_plane = -std::numeric_limits<int>::max();
 
  310     for (
auto const& [plane, numHits] : num_hits) {
 
  311       if (
fVerbose > 2) 
std::cout << 
"Plane: " << plane << 
" with size: " << numHits << std::endl;
 
  312       if (numHits > max_hits) {
 
  318     if (best_plane < 0) {
 
  320         mf::LogError(
"ShowerTrajPointdEdx") << 
"No hits in any plane, returning " << std::endl;
 
  329     std::map<int, std::vector<double>> dEdx_vec_cut;
 
  331       dEdx_vec_cut[plane_id.Plane] = {};
 
  334     for (
auto& dEdx_plane : dEdx_vec) {
 
  335       FinddEdxLength(dEdx_plane.second, dEdx_vec_cut[dEdx_plane.first]);
 
  339     std::vector<double> dEdx_val;
 
  340     std::vector<double> dEdx_valErr;
 
  341     for (
auto const& dEdx_plane : dEdx_vec_cut) {
 
  343       if ((dEdx_plane.second).empty()) {
 
  344         dEdx_val.push_back(-999);
 
  345         dEdx_valErr.push_back(-999);
 
  350         dEdx_val.push_back(TMath::Median((dEdx_plane.second).size(), &(dEdx_plane.second)[0]));
 
  354         double dEdx_mean = 0;
 
  355         for (
auto const& 
dEdx : dEdx_plane.second) {
 
  356           if (
dEdx > 10 || 
dEdx < 0) { 
continue; }
 
  359         dEdx_val.push_back(dEdx_mean / (
float)(dEdx_plane.second).size());
 
  364       std::cout << 
"#Best Plane: " << best_plane << std::endl;
 
  365       for (
unsigned int plane = 0; plane < dEdx_vec.size(); plane++) {
 
  366         std::cout << 
"#Plane: " << plane << 
" #" << std::endl;
 
  367         std::cout << 
"#Median: " << dEdx_val[plane] << 
" #" << std::endl;
 
  369           for (
auto const& 
dEdx : dEdx_vec_cut[plane]) {
 
  394     if (dEdx_vec.size() < 4) {
 
  399     bool upperbound = 
false;
 
  402     int upperbound_int = 0;
 
  403     if (dEdx_vec[0] > 
fdEdxCut) { ++upperbound_int; }
 
  404     if (dEdx_vec[1] > 
fdEdxCut) { ++upperbound_int; }
 
  405     if (dEdx_vec[2] > 
fdEdxCut) { ++upperbound_int; }
 
  406     if (upperbound_int > 1) { upperbound = 
true; }
 
  408     dEdx_val.push_back(dEdx_vec[0]);
 
  409     dEdx_val.push_back(dEdx_vec[1]);
 
  410     dEdx_val.push_back(dEdx_vec[2]);
 
  412     for (
unsigned int dEdx_iter = 2; dEdx_iter < dEdx_vec.size(); ++dEdx_iter) {
 
  418       double dEdx = dEdx_vec[dEdx_iter];
 
  423           dEdx_val.push_back(dEdx);
 
  429           if (dEdx_iter < dEdx_vec.size() - 1) {
 
  430             if (dEdx_vec[dEdx_iter + 1] > 
fdEdxCut) {
 
  432                 std::cout << 
"Next dEdx hit is good removing hit" << dEdx << std::endl;
 
  437           if (dEdx_iter < dEdx_vec.size() - 2) {
 
  438             if (dEdx_vec[dEdx_iter + 2] > 
fdEdxCut) {
 
  440                 std::cout << 
"Next Next dEdx hit is good removing hit" << dEdx << std::endl;
 
  450           dEdx_val.push_back(dEdx);
 
  456           if (dEdx_iter < dEdx_vec.size() - 1) {
 
  457             if (dEdx_vec[dEdx_iter + 1] > 
fdEdxCut) {
 
  459                 std::cout << 
"Next dEdx hit is good removing hit " << dEdx << std::endl;
 
  464           if (dEdx_iter < dEdx_vec.size() - 2) {
 
  465             if (dEdx_vec[dEdx_iter + 2] > 
fdEdxCut) {
 
  467                 std::cout << 
"Next Next dEdx hit is good removing hit " << dEdx << std::endl;
 
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. 
 
double SCECorrectPitch(double const &pitch, TVector3 const &pos, TVector3 const &dir, unsigned int const &TPC) const 
 
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
 
static constexpr Flag_t NoPoint
The trajectory point is not defined. 
 
Point_t const & LocationAtPoint(size_t i) const 
 
The data type to uniquely identify a Plane. 
 
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
 
size_t NumberTrajectoryPoints() const 
Various functions related to the presence and the number of (valid) points. 
 
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
 
double SCECorrectEField(double const &EField, TVector3 const &pos) const 
 
bool CheckElement(const std::string &Name) const 
 
The data type to uniquely identify a TPC. 
 
PlaneID_t Plane
Index of the plane within its TPC. 
 
int GetElement(const std::string &Name, T &Element) const 
 
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
 
Provides recob::Track data product. 
 
constexpr TPCID const & asTPCID() const 
Conversion to TPCID (for convenience of notation). 
 
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
 
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const 
 
PointFlags_t const & FlagsAtPoint(size_t i) const 
 
Vector_t DirectionAtPoint(size_t i) const 
 
2D representation of charge deposited in the TDC/wire plane 
 
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. 
 
BEGIN_PROLOG could also be cout
 
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track: 
 
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const