LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
cluster::HoughBaseAlg Class Reference

#include "HoughBaseAlg.h"

Classes

struct  ChargeInfo_t
 Data structure collecting charge information to be filled in cluster. More...
 

Public Member Functions

 HoughBaseAlg (fhicl::ParameterSet const &pset)
 
virtual ~HoughBaseAlg ()=default
 
size_t FastTransform (const std::vector< art::Ptr< recob::Cluster >> &clusIn, std::vector< recob::Cluster > &ccol, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, CLHEP::HepRandomEngine &engine, art::Event const &evt, std::string const &label)
 
size_t Transform (const detinfo::DetectorClocksData &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &hits, CLHEP::HepRandomEngine &engine, std::vector< unsigned int > *fpointId_to_clusterId, unsigned int clusterId, unsigned int *nClusters, std::vector< protoTrack > *protoTracks)
 
size_t FastTransform (detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &clusIn, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, CLHEP::HepRandomEngine &engine)
 
size_t FastTransform (detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &clusIn, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, CLHEP::HepRandomEngine &engine, std::vector< double > &slope, std::vector< ChargeInfo_t > &totalQ)
 
size_t Transform (std::vector< art::Ptr< recob::Hit >> const &hits)
 
size_t Transform (detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &hits, double &slope, double &intercept)
 

Private Member Functions

void HLSSaveBMPFile (char const *, unsigned char *, int, int)
 

Private Attributes

int fMaxLines
 Max number of lines that can be found. More...
 
int fMinHits
 
int fSaveAccumulator
 Save bitmap image of accumulator for debugging? More...
 
int fNumAngleCells
 that fall into the "correct" bin will be small and consistent with noise. More...
 
float fMaxDistance
 Max distance that a hit can be from a line to be considered part of that line. More...
 
float fMaxSlope
 Max slope a line can have. More...
 
int fRhoZeroOutRange
 Range in rho over which to zero out area around previously found lines in the accumulator. More...
 
int fThetaZeroOutRange
 Range in theta over which to zero out area around previously found lines in the accumulator. More...
 
float fRhoResolutionFactor
 Factor determining the resolution in rho. More...
 
int fPerCluster
 
int fMissedHits
 
float fMissedHitsDistance
 Distance between hits in a hough line before a hit is considered missed. More...
 
float fMissedHitsToLineSize
 Ratio of missed hits to line size for a line to be considered a fake. More...
 

Friends

class HoughTransformClus
 

Detailed Description

Definition at line 455 of file HoughBaseAlg.h.

Constructor & Destructor Documentation

cluster::HoughBaseAlg::HoughBaseAlg ( fhicl::ParameterSet const &  pset)
explicit

Definition at line 252 of file HoughBaseAlg.cxx.

References util::abs(), cluster::HoughTransform::AddPointReturnMax(), geo::WireID::asPlaneID(), geo::PlaneID::asTPCID(), detinfo::DetectorPropertiesData::DriftVelocity(), e, detinfo::DetectorPropertiesData::Efield(), Get, fhicl::ParameterSet::get(), cluster::HoughTransform::GetAccumSize(), cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), hits(), cluster::HoughTransform::Init(), protoTrack::Init(), geo::kInduction, MF_LOG_DEBUG, detinfo::DetectorPropertiesData::NumberTimeSamples(), detinfo::sampling_rate(), cluster::HoughTransform::SetCell(), sqr(), cluster::HoughTransform::SubtractPoint(), detinfo::DetectorPropertiesData::Temperature(), Transform(), lar::dump::vector(), w, x, and y.

253 {
254  fMaxLines = pset.get<int>("MaxLines");
255  fMinHits = pset.get<int>("MinHits");
256  fSaveAccumulator = pset.get<int>("SaveAccumulator");
257  fNumAngleCells = pset.get<int>("NumAngleCells");
258  fMaxDistance = pset.get<float>("MaxDistance");
259  fMaxSlope = pset.get<float>("MaxSlope");
260  fRhoZeroOutRange = pset.get<int>("RhoZeroOutRange");
261  fThetaZeroOutRange = pset.get<int>("ThetaZeroOutRange");
262  fRhoResolutionFactor = pset.get<float>("RhoResolutionFactor");
263  fPerCluster = pset.get<int>("HitsPerCluster");
264  fMissedHits = pset.get<int>("MissedHits");
265  fMissedHitsDistance = pset.get<float>("MissedHitsDistance");
266  fMissedHitsToLineSize = pset.get<float>("MissedHitsToLineSize");
267 }
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:534
int fMaxLines
Max number of lines that can be found.
Definition: HoughBaseAlg.h:519
float fMissedHitsDistance
Distance between hits in a hough line before a hit is considered missed.
Definition: HoughBaseAlg.h:542
int fNumAngleCells
that fall into the "correct" bin will be small and consistent with noise.
Definition: HoughBaseAlg.h:523
int fSaveAccumulator
Save bitmap image of accumulator for debugging?
Definition: HoughBaseAlg.h:522
float fMaxDistance
Max distance that a hit can be from a line to be considered part of that line.
Definition: HoughBaseAlg.h:528
float fMaxSlope
Max slope a line can have.
Definition: HoughBaseAlg.h:529
int fRhoZeroOutRange
Range in rho over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:531
int fThetaZeroOutRange
Range in theta over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:533
float fMissedHitsToLineSize
Ratio of missed hits to line size for a line to be considered a fake.
Definition: HoughBaseAlg.h:544
virtual cluster::HoughBaseAlg::~HoughBaseAlg ( )
virtualdefault

Member Function Documentation

size_t cluster::HoughBaseAlg::FastTransform ( const std::vector< art::Ptr< recob::Cluster >> &  clusIn,
std::vector< recob::Cluster > &  ccol,
std::vector< art::PtrVector< recob::Hit >> &  clusHitsOut,
CLHEP::HepRandomEngine &  engine,
art::Event const &  evt,
std::string const &  label 
)

Definition at line 868 of file HoughBaseAlg.cxx.

References art::PtrVector< T >::end(), Get, hits(), cluster::ClusterParamsImportWrapper< Algo >::ImportHits(), MF_LOG_DEBUG, recob::Hit::PeakTime(), geo::WireID::planeID(), recob::Cluster::Sentry, recob::Hit::SigmaPeakTime(), sw, recob::Hit::View(), geo::WireID::Wire, recob::Hit::WireID(), and xx.

Referenced by cluster::HoughLineFinder::produce().

874 {
875  std::vector<int> skip;
876 
877  art::FindManyP<recob::Hit> fmh(clusIn, evt, label);
878 
879  geo::GeometryCore const* geom = lar::providerFrom<geo::Geometry>();
880  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
881  HoughTransform c;
882 
883  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
884  auto const detProp =
886  util::GeometryUtilities const gser{*geom, wireReadoutGeom, clockData, detProp};
887 
888  // prepare the algorithm to compute the cluster characteristics;
889  // we use the "standard" one here; configuration would happen here,
890  // but we are using the default configuration for that algorithm
891  ClusterParamsImportWrapper<StandardClusterParamsAlg> ClusterParamAlgo;
892 
893  std::vector<art::Ptr<recob::Hit>> hit;
894 
895  for (auto view : wireReadoutGeom.Views()) {
896 
897  MF_LOG_DEBUG("HoughBaseAlg") << "Analyzing view " << view;
898 
899  art::PtrVector<recob::Cluster>::const_iterator clusterIter = clusIn.begin();
900  int clusterID = 0; //the unique ID of the cluster
901 
902  size_t cinctr = 0;
903  while (clusterIter != clusIn.end()) {
904 
905  MF_LOG_DEBUG("HoughBaseAlg")
906  << "Analyzing cinctr=" << cinctr << " which is in view " << (*clusterIter)->View();
907 
908  hit.clear();
909  if (fPerCluster) {
910  if ((*clusterIter)->View() == view) hit = fmh.at(cinctr);
911  }
912  else {
913  while (clusterIter != clusIn.end()) {
914  if ((*clusterIter)->View() == view) {
915 
916  hit = fmh.at(cinctr);
917  } // end if cluster is in correct view
918  clusterIter++;
919  ++cinctr;
920  } //end loop over clusters
921  } //end if not fPerCluster
922  if (hit.size() == 0) {
923  if (fPerCluster) {
924  clusterIter++;
925  ++cinctr;
926  }
927  continue;
928  }
929 
930  MF_LOG_DEBUG("HoughBaseAlg") << "We have all the hits..." << hit.size();
931 
932  std::vector<double> slopevec;
933  std::vector<ChargeInfo_t> totalQvec;
934  std::vector<art::PtrVector<recob::Hit>> planeClusHitsOut;
935  this->FastTransform(clockData, detProp, hit, planeClusHitsOut, engine, slopevec, totalQvec);
936 
937  MF_LOG_DEBUG("HoughBaseAlg") << "Made it through FastTransform" << planeClusHitsOut.size();
938 
939  for (size_t xx = 0; xx < planeClusHitsOut.size(); ++xx) {
940  auto const& hits = planeClusHitsOut.at(xx);
941  recob::Hit const& FirstHit = *hits.front();
942  recob::Hit const& LastHit = *hits.back();
943  const unsigned int sw = FirstHit.WireID().Wire;
944  const unsigned int ew = LastHit.WireID().Wire;
945 
946  // feed the algorithm with all the cluster hits
947  ClusterParamAlgo.ImportHits(gser, hits);
948 
949  // create the recob::Cluster directly in the vector;
950  // NOTE usually we would use cluster::ClusterCreator to save some typing
951  // and some mistakes. In this case, we don't want to pull in the
952  // dependency on ClusterFinder, where ClusterCreator currently lives
953  ccol.emplace_back(float(sw), // start_wire
954  0., // sigma_start_wire
955  FirstHit.PeakTime(), // start_tick
956  FirstHit.SigmaPeakTime(), // sigma_start_tick
957  ClusterParamAlgo.StartCharge(gser).value(),
958  ClusterParamAlgo.StartAngle().value(),
959  ClusterParamAlgo.StartOpeningAngle().value(),
960  float(ew), // end_wire
961  0., // sigma_end_wire,
962  LastHit.PeakTime(), // end_tick
963  LastHit.SigmaPeakTime(), // sigma_end_tick
964  ClusterParamAlgo.EndCharge(gser).value(),
965  ClusterParamAlgo.EndAngle().value(),
966  ClusterParamAlgo.EndOpeningAngle().value(),
967  ClusterParamAlgo.Integral().value(),
968  ClusterParamAlgo.IntegralStdDev().value(),
969  ClusterParamAlgo.SummedADC().value(),
970  ClusterParamAlgo.SummedADCStdDev().value(),
971  ClusterParamAlgo.NHits(),
972  ClusterParamAlgo.MultipleHitDensity(),
973  ClusterParamAlgo.Width(gser),
974  clusterID,
975  FirstHit.View(),
976  FirstHit.WireID().planeID(),
978 
979  ++clusterID;
980  clusHitsOut.push_back(planeClusHitsOut.at(xx));
981  }
982 
983  hit.clear();
984  if (clusterIter != clusIn.end()) {
985  clusterIter++;
986  ++cinctr;
987  }
988  // listofxmax.clear();
989  // listofymax.clear();
990  } // end loop over clusters
991 
992  } // end loop over views
993 
994  return ccol.size();
995 }
Double_t xx
Definition: macro.C:12
size_t FastTransform(const std::vector< art::Ptr< recob::Cluster >> &clusIn, std::vector< recob::Cluster > &ccol, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, CLHEP::HepRandomEngine &engine, art::Event const &evt, std::string const &label)
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:286
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:174
void hits()
Definition: readHits.C:15
typename data_t::const_iterator const_iterator
Definition: PtrVector.h:55
Description of the physical geometry of one entire detector.
Definition: GeometryCore.h:91
Detector simulation of raw signals on wires.
Float_t sw
Definition: plot.C:20
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:226
#define MF_LOG_DEBUG(id)
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
Definition: Hit.h:230
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
constexpr PlaneID const & planeID() const
Definition: geo_types.h:471
TCEvent evt
Definition: DataStructs.cxx:8
size_t cluster::HoughBaseAlg::FastTransform ( detinfo::DetectorClocksData const &  clockData,
detinfo::DetectorPropertiesData const &  detProp,
std::vector< art::Ptr< recob::Hit >> const &  clusIn,
std::vector< art::PtrVector< recob::Hit >> &  clusHitsOut,
CLHEP::HepRandomEngine &  engine 
)

Definition at line 998 of file HoughBaseAlg.cxx.

1003 {
1004  std::vector<double> slopevec;
1005  std::vector<ChargeInfo_t> totalQvec;
1006  return FastTransform(clockData, detProp, clusIn, clusHitsOut, engine, slopevec, totalQvec);
1007 }
size_t FastTransform(const std::vector< art::Ptr< recob::Cluster >> &clusIn, std::vector< recob::Cluster > &ccol, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, CLHEP::HepRandomEngine &engine, art::Event const &evt, std::string const &label)
size_t cluster::HoughBaseAlg::FastTransform ( detinfo::DetectorClocksData const &  clockData,
detinfo::DetectorPropertiesData const &  detProp,
std::vector< art::Ptr< recob::Hit >> const &  clusIn,
std::vector< art::PtrVector< recob::Hit >> &  clusHitsOut,
CLHEP::HepRandomEngine &  engine,
std::vector< double > &  slope,
std::vector< ChargeInfo_t > &  totalQ 
)
Todo:
explain where the 0.001 comes from
Todo:
: the collection plane's characteristic hit width's are,
Todo:
: on average, about 5 time samples wider than the induction plane's.
Todo:
: this is hard-coded for now.
Todo:
should it really be wire_pitch[0] in the if statements below, or the pitch for the plane of the hit?

Definition at line 1010 of file HoughBaseAlg.cxx.

References util::abs(), lar::util::StatCollector< T, W >::add(), cluster::HoughTransform::AddPointReturnMax(), geo::WireID::asPlaneID(), geo::PlaneID::asTPCID(), art::PtrVector< T >::back(), art::PtrVector< T >::clear(), detinfo::DetectorPropertiesData::DriftVelocity(), detinfo::DetectorPropertiesData::Efield(), Get, cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), cluster::HoughTransform::Init(), geo::kInduction, MF_LOG_DEBUG, art::PtrVector< T >::push_back(), detinfo::DetectorPropertiesData::ReadOutWindowSize(), lar::util::StatCollector< T, W >::RMS(), detinfo::sampling_rate(), cluster::HoughTransform::SetCell(), lar::util::StatCollector< T, W >::Sum(), detinfo::DetectorPropertiesData::Temperature(), lar::dump::vector(), x, and y.

1017 {
1018  std::vector<int> skip;
1019 
1020  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
1021  lariov::ChannelStatusProvider const* channelStatus =
1022  lar::providerFrom<lariov::ChannelStatusService>();
1023 
1024  CLHEP::RandFlat flat(engine);
1025 
1026  std::vector<art::Ptr<recob::Hit>> hit;
1027 
1028  size_t cinctr = 0;
1029  hit.clear();
1030  for (std::vector<art::Ptr<recob::Hit>>::const_iterator ii = clusIn.begin(); ii != clusIn.end();
1031  ii++)
1032  hit.push_back((*ii)); // this is new
1033 
1034  if (hit.size() == 0) {
1035  if (fPerCluster) { ++cinctr; }
1036  return -1;
1037  }
1038 
1039  geo::WireID const& wireid = hit.at(0)->WireID();
1040  auto const& tpcid = wireid.asPlaneID().asTPCID();
1041 
1042  geo::SigType_t sigt = wireReadoutGeom.SignalType(wireid);
1043 
1044  if (hit.size() == 0) {
1045  if (fPerCluster) { ++cinctr; }
1046  return -1; // continue;
1047  }
1048 
1049  auto const num_planes = wireReadoutGeom.Nplanes(tpcid);
1050  std::vector<double> wire_pitch(num_planes, 0.);
1051  for (auto const& plane : wireReadoutGeom.Iterate<geo::PlaneGeo>(tpcid)) {
1052  auto const p = plane.ID().Plane;
1053  wire_pitch[p] = plane.WirePitch();
1054  }
1055 
1056  //factor to make x and y scale the same units
1057  std::vector<double> xyScale(num_planes, 0.);
1058 
1060  double driftVelFactor = 0.001 * detProp.DriftVelocity(detProp.Efield(), detProp.Temperature());
1061 
1062  for (size_t p = 0; p < xyScale.size(); ++p)
1063  xyScale[p] = driftVelFactor * sampling_rate(clockData) / wire_pitch[p];
1064 
1065  int x = 0, y = 0;
1066  int dx = wireReadoutGeom.Plane(wireid.asPlaneID()).Nwires(); // number of wires
1067  const int dy = detProp.ReadOutWindowSize(); // number of time samples.
1068  skip.clear();
1069  skip.resize(hit.size());
1070  std::vector<int> listofxmax;
1071  std::vector<int> listofymax;
1072  std::vector<int> hitTemp; //indecies ofcandidate hits
1073  std::vector<int> sequenceHolder; //channels of hits in list
1074  std::vector<int> currentHits; //working vector of hits
1075  std::vector<int> lastHits; //best list of hits
1076  art::PtrVector<recob::Hit> clusterHits;
1077  float indcolscaling = 0.; //a parameter to account for the different
1078  //characteristic hit width of induction and collection plane
1079  float centerofmassx = 0;
1080  float centerofmassy = 0;
1081  float denom = 0;
1082  float intercept = 0.;
1083  float slope = 0.;
1084  //this array keeps track of the hits that have already been associated with a line.
1085  int xMax = 0;
1086  int yMax = 0;
1087  float rho;
1088  float theta;
1089  int accDx(0), accDy(0);
1090 
1091  HoughTransform c;
1092  //Init specifies the size of the two-dimensional accumulator
1093  //(based on the arguments, number of wires and number of time samples).
1094  //adds all of the hits (that have not yet been associated with a line) to the accumulator
1095  c.Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1096 
1097  // count is how many points are left to randomly insert
1098  unsigned int count = hit.size();
1099  std::vector<unsigned int> accumPoints;
1100  accumPoints.resize(hit.size());
1101  int nAccum = 0;
1102  unsigned int nLinesFound = 0;
1103 
1104  for (; count > 0; count--) {
1105 
1106  // The random hit we are examining
1107  unsigned int randInd = (unsigned int)(flat.fire() * hit.size());
1108 
1109  MF_LOG_DEBUG("HoughBaseAlg") << "randInd=" << randInd << " and size is " << hit.size();
1110 
1111  // Skip if it's already in a line
1112  if (skip.at(randInd) == 1) continue;
1113 
1114  // If we have already accumulated the point, skip it
1115  if (accumPoints.at(randInd)) continue;
1116  accumPoints.at(randInd) = 1;
1117 
1118  // zeroes out the neighborhood of all previous lines
1119  for (unsigned int i = 0; i < listofxmax.size(); ++i) {
1120  int yClearStart = listofymax.at(i) - fRhoZeroOutRange;
1121  if (yClearStart < 0) yClearStart = 0;
1122 
1123  int yClearEnd = listofymax.at(i) + fRhoZeroOutRange;
1124  if (yClearEnd >= accDy) yClearEnd = accDy - 1;
1125 
1126  int xClearStart = listofxmax.at(i) - fThetaZeroOutRange;
1127  if (xClearStart < 0) xClearStart = 0;
1128 
1129  int xClearEnd = listofxmax.at(i) + fThetaZeroOutRange;
1130  if (xClearEnd >= accDx) xClearEnd = accDx - 1;
1131 
1132  for (y = yClearStart; y <= yClearEnd; ++y) {
1133  for (x = xClearStart; x <= xClearEnd; ++x) {
1134  c.SetCell(y, x, 0);
1135  }
1136  }
1137  } // end loop over size of listxmax
1138 
1139  //find the weightiest cell in the accumulator.
1140  int maxCell = 0;
1141  unsigned int wireMax = hit.at(randInd)->WireID().Wire;
1142 
1143  // Add the randomly selected point to the accumulator
1144  std::array<int, 3> max = c.AddPointReturnMax(wireMax, (int)(hit.at(randInd)->PeakTime()));
1145  maxCell = max.at(0);
1146  xMax = max.at(1);
1147  yMax = max.at(2);
1148  nAccum++;
1149 
1150  // Continue if the biggest maximum for the randomly selected point is smaller than fMinHits
1151  if (maxCell < fMinHits) continue;
1152 
1153  // Find the center of mass of the 3x3 cell system (with maxCell at the center).
1154  denom = centerofmassx = centerofmassy = 0;
1155 
1156  if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
1157  for (int i = -1; i < 2; ++i) {
1158  for (int j = -1; j < 2; ++j) {
1159  int cell = c.GetCell(yMax + i, xMax + j);
1160  denom += cell;
1161  centerofmassx += j * cell;
1162  centerofmassy += i * cell;
1163  }
1164  }
1165  centerofmassx /= denom;
1166  centerofmassy /= denom;
1167  }
1168  else
1169  centerofmassx = centerofmassy = 0;
1170 
1171  //fill the list of cells that have already been found
1172  listofxmax.push_back(xMax);
1173  listofymax.push_back(yMax);
1174 
1175  // Find the lines equation
1176  c.GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1177  MF_LOG_DEBUG("HoughBaseAlg") << "Transform(I) found maximum at (d=" << rho << " a=" << theta
1178  << ")"
1179  " from absolute maximum "
1180  << c.GetCell(yMax, xMax) << " at (d=" << yMax << ", a=" << xMax
1181  << ")";
1182  slope = -1. / tan(theta);
1183  intercept = (rho / sin(theta));
1184  double distance;
1188  if (sigt == geo::kInduction)
1189  indcolscaling = 5.;
1190  else
1191  indcolscaling = 0.;
1192 
1193  // note this doesn't work for wrapped wire planes!
1194  if (!std::isinf(slope) && !std::isnan(slope)) {
1195  sequenceHolder.clear();
1196  hitTemp.clear();
1197  for (size_t i = 0; i < hit.size(); ++i) {
1198  distance = (TMath::Abs(hit.at(i)->PeakTime() - slope * (double)(hit.at(i)->WireID().Wire) -
1199  intercept) /
1200  (std::sqrt(pow(xyScale[hit.at(i)->WireID().Plane] * slope, 2) + 1)));
1201 
1202  if (distance < fMaxDistance + hit.at(i)->RMS() + indcolscaling && skip.at(i) != 1) {
1203  hitTemp.push_back(i);
1204  sequenceHolder.push_back(hit.at(i)->Channel());
1205  }
1206 
1207  } // end loop over hits
1208 
1209  if (hitTemp.size() < 2) continue;
1210  currentHits.clear();
1211  lastHits.clear();
1212  int j;
1213  currentHits.push_back(0);
1214  for (size_t i = 0; i + 1 < sequenceHolder.size(); ++i) {
1215  j = 1;
1216  while ((channelStatus->IsBad(sequenceHolder.at(i) + j)) == true)
1217  j++;
1218  if (sequenceHolder.at(i + 1) - sequenceHolder.at(i) <= j + fMissedHits)
1219  currentHits.push_back(i + 1);
1220  else if (currentHits.size() > lastHits.size()) {
1221  lastHits = currentHits;
1222  currentHits.clear();
1223  }
1224  else
1225  currentHits.clear();
1226  }
1227 
1228  if (currentHits.size() > lastHits.size()) lastHits = currentHits;
1229 
1230  // Check if lastHits has hits with big gaps in it
1231  // lastHits[i] is ordered in increasing channel and then increasing peak time,
1232  // as a consequence, if the line has a negative slope and there are multiple hits in the line for a channel,
1233  // we have to go back to the first hit (in terms of lastHits[i]) of that channel to find the distance
1234  // between hits
1235  //std::cout << "New line" << std::endl;
1236  double tickToDist = detProp.DriftVelocity(detProp.Efield(), detProp.Temperature());
1237  tickToDist *= 1.e-3 * sampling_rate(clockData); // 1e-3 is conversion of 1/us to 1/ns
1238  int missedHits = 0;
1239  int lastHitsChannel = 0; //lastHits.at(0);
1240  int nHitsPerChannel = 1;
1241 
1242  MF_LOG_DEBUG("HoughBaseAlg") << "filling the pCorner arrays around here..."
1243  << "\n but first, lastHits size is " << lastHits.size()
1244  << " and lastHitsChannel=" << lastHitsChannel;
1245 
1246  double pCorner0[2];
1247  double pCorner1[2];
1248  unsigned int lastChannel = hit.at(hitTemp.at(lastHits.at(0)))->Channel();
1249 
1250  for (size_t i = 0; i < lastHits.size() - 1; ++i) {
1251  bool newChannel = false;
1252  if (slope < 0) {
1253  if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() != lastChannel) {
1254  newChannel = true;
1255  }
1256  if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() == lastChannel) nHitsPerChannel++;
1257  }
1258 
1261 
1262  if (slope > 0 || (!newChannel && nHitsPerChannel <= 1)) {
1263 
1264  pCorner0[0] = (hit.at(hitTemp.at(lastHits.at(i)))->Channel()) * wire_pitch[0];
1265  pCorner0[1] = hit.at(hitTemp.at(lastHits.at(i)))->PeakTime() * tickToDist;
1266  pCorner1[0] = (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel()) * wire_pitch[0];
1267  pCorner1[1] = hit.at(hitTemp.at(lastHits.at(i + 1)))->PeakTime() * tickToDist;
1268  if (std::sqrt(pow(pCorner0[0] - pCorner1[0], 2) + pow(pCorner0[1] - pCorner1[1], 2)) >
1270  missedHits++;
1271  }
1272 
1273  else if (slope < 0 && newChannel && nHitsPerChannel > 1) {
1274 
1275  pCorner0[0] =
1276  (hit.at(hitTemp.at(lastHits.at(lastHitsChannel)))->Channel()) * wire_pitch[0];
1277  pCorner0[1] = hit.at(hitTemp.at(lastHits.at(lastHitsChannel)))->PeakTime() * tickToDist;
1278  pCorner1[0] = (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel()) * wire_pitch[0];
1279  pCorner1[1] = hit.at(hitTemp.at(lastHits.at(i + 1)))->PeakTime() * tickToDist;
1280  if (std::sqrt(pow(pCorner0[0] - pCorner1[0], 2) + pow(pCorner0[1] - pCorner1[1], 2)) >
1282  missedHits++;
1283  lastChannel = hit.at(hitTemp.at(lastHits.at(i)))->Channel();
1284  lastHitsChannel = i + 1;
1285  nHitsPerChannel = 0;
1286  }
1287  }
1288 
1289  if ((double)missedHits / ((double)lastHits.size() - 1) > fMissedHitsToLineSize) continue;
1290 
1291  clusterHits.clear();
1292  if (lastHits.size() < 5) continue;
1293 
1294  // reduce rounding errors by using double (RMS is very sensitive to them)
1295  lar::util::StatCollector<double> integralQ, summedQ;
1296 
1297  for (size_t i = 0; i < lastHits.size(); ++i) {
1298  clusterHits.push_back(hit.at(hitTemp.at(lastHits.at(i))));
1299  integralQ.add(clusterHits.back()->Integral());
1300  summedQ.add(clusterHits.back()->ROISummedADC());
1301  skip.at(hitTemp.at(lastHits.at(i))) = 1;
1302  }
1303  //protection against very steep uncorrelated hits
1304  if (std::abs(slope) > fMaxSlope) continue;
1305 
1306  clusHitsOut.push_back(clusterHits);
1307  slopevec.push_back(slope);
1308  totalQvec.emplace_back(integralQ.Sum(),
1309  integralQ.RMS(), // TODO biased value; should unbias?
1310  summedQ.Sum(),
1311  summedQ.RMS() // TODO biased value; should unbias?
1312  );
1313 
1314  } // end if !std::isnan
1315 
1316  nLinesFound++;
1317 
1318  if (nLinesFound > (unsigned int)fMaxLines) break;
1319 
1320  } // end loop over hits
1321 
1322  // saves a bitmap image of the accumulator (useful for debugging),
1323  // with scaling based on the maximum cell value
1324  if (fSaveAccumulator) {
1325  //finds the maximum cell in the accumulator for image scaling
1326  int cell, pix = 0, maxCell = 0;
1327  for (y = 0; y < accDy; ++y) {
1328  for (x = 0; x < accDx; ++x) {
1329  cell = c.GetCell(y, x);
1330  if (cell > maxCell) maxCell = cell;
1331  }
1332  }
1333 
1334  std::unique_ptr<unsigned char[]> outPix(new unsigned char[accDx * accDy]);
1335  unsigned int PicIndex = 0;
1336  for (y = 0; y < accDy; ++y) {
1337  for (x = 0; x < accDx; ++x) {
1338  //scales the pixel weights based on the maximum cell value
1339  if (maxCell > 0) pix = (int)((1500 * c.GetCell(y, x)) / maxCell);
1340  outPix[PicIndex++] = pix;
1341  }
1342  }
1343 
1344  HLSSaveBMPFile("houghaccum.bmp", outPix.get(), accDx, accDy);
1345  } // end if saving accumulator
1346 
1347  hit.clear();
1348  lastHits.clear();
1349  listofxmax.clear();
1350  listofymax.clear();
1351  return clusHitsOut.size();
1352 }
Float_t x
Definition: compare.C:6
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:534
Float_t y
Definition: compare.C:6
constexpr auto abs(T v)
Returns the absolute value of the argument.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
Weight_t RMS() const
Returns the root mean square.
int fMaxLines
Max number of lines that can be found.
Definition: HoughBaseAlg.h:519
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
float fMissedHitsDistance
Distance between hits in a hough line before a hit is considered missed.
Definition: HoughBaseAlg.h:542
reference back()
Definition: PtrVector.h:387
int fNumAngleCells
that fall into the "correct" bin will be small and consistent with noise.
Definition: HoughBaseAlg.h:523
int fSaveAccumulator
Save bitmap image of accumulator for debugging?
Definition: HoughBaseAlg.h:522
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
Signal from induction planes.
Definition: geo_types.h:147
Weight_t Sum() const
Returns the weighted sum of the values.
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:67
float fMaxDistance
Max distance that a hit can be from a line to be considered part of that line.
Definition: HoughBaseAlg.h:528
float fMaxSlope
Max slope a line can have.
Definition: HoughBaseAlg.h:529
int fRhoZeroOutRange
Range in rho over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:531
Detector simulation of raw signals on wires.
#define MF_LOG_DEBUG(id)
int fThetaZeroOutRange
Range in theta over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:533
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
void clear()
Definition: PtrVector.h:533
Collects statistics on a single quantity (weighted)
float fMissedHitsToLineSize
Ratio of missed hits to line size for a line to be considered a fake.
Definition: HoughBaseAlg.h:544
constexpr TPCID const & asTPCID() const
Conversion to PlaneID (for convenience of notation).
Definition: geo_types.h:409
void add(Data_t value, Weight_t weight=Weight_t(1.0))
Adds one entry with specified value and weight.
void HLSSaveBMPFile(char const *, unsigned char *, int, int)
constexpr PlaneID const & asPlaneID() const
Conversion to WireID (for convenience of notation).
Definition: geo_types.h:466
void cluster::HoughBaseAlg::HLSSaveBMPFile ( char const *  ,
unsigned char *  ,
int  ,
int   
)
private

Definition at line 834 of file HoughBaseAlg.cxx.

References util::size().

835 {
836  std::ofstream bmpFile(fileName, std::ios::binary);
837  bmpFile.write("B", 1);
838  bmpFile.write("M", 1);
839  int bitsOffset = 54 + 256 * 4;
840  int size = bitsOffset + dx * dy; //header plus 256 entry LUT plus pixels
841  bmpFile.write((const char*)&size, 4);
842  int reserved = 0;
843  bmpFile.write((const char*)&reserved, 4);
844  bmpFile.write((const char*)&bitsOffset, 4);
845  int bmiSize = 40;
846  bmpFile.write((const char*)&bmiSize, 4);
847  bmpFile.write((const char*)&dx, 4);
848  bmpFile.write((const char*)&dy, 4);
849  short planes = 1;
850  bmpFile.write((const char*)&planes, 2);
851  short bitCount = 8;
852  bmpFile.write((const char*)&bitCount, 2);
853  int i, temp = 0;
854  for (i = 0; i < 6; i++)
855  bmpFile.write((const char*)&temp, 4); // zero out optional color info
856  // write a linear LUT
857  char lutEntry[4]; // blue,green,red
858  lutEntry[3] = 0; // reserved part
859  for (i = 0; i < 256; i++) {
860  lutEntry[0] = lutEntry[1] = lutEntry[2] = i;
861  bmpFile.write(lutEntry, sizeof lutEntry);
862  }
863  // write the actual pixels
864  bmpFile.write((const char*)pix, dx * dy);
865 }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
size_t cluster::HoughBaseAlg::Transform ( const detinfo::DetectorClocksData clockData,
detinfo::DetectorPropertiesData const &  detProp,
std::vector< art::Ptr< recob::Hit >> const &  hits,
CLHEP::HepRandomEngine &  engine,
std::vector< unsigned int > *  fpointId_to_clusterId,
unsigned int  clusterId,
unsigned int *  nClusters,
std::vector< protoTrack > *  protoTracks 
)

Referenced by HoughBaseAlg().

size_t cluster::HoughBaseAlg::Transform ( std::vector< art::Ptr< recob::Hit >> const &  hits)
size_t cluster::HoughBaseAlg::Transform ( detinfo::DetectorPropertiesData const &  detProp,
std::vector< art::Ptr< recob::Hit >> const &  hits,
double &  slope,
double &  intercept 
)
Todo:
could eventually refine this method to throw out hits that are
Todo:
far from the hough line and refine the fit

Definition at line 1355 of file HoughBaseAlg.cxx.

References cluster::HoughTransform::AddPointReturnMax(), Get, cluster::HoughTransform::GetAccumSize(), cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), cluster::HoughTransform::GetMax(), hits(), cluster::HoughTransform::Init(), MF_LOG_DEBUG, and detinfo::DetectorPropertiesData::ReadOutWindowSize().

1359 {
1360  HoughTransform c;
1361 
1362  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
1363 
1364  int dx = wireReadoutGeom.Nwires(geo::PlaneID{0, 0, 0}); // number of wires
1365  const int dy = detProp.ReadOutWindowSize(); // number of time samples.
1366 
1367  c.Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1368 
1369  for (unsigned int i = 0; i < hits.size(); ++i) {
1370  c.AddPointReturnMax(hits[i]->WireID().Wire, (int)(hits[i]->PeakTime()));
1371  } // end loop over hits
1372 
1373  //gets the actual two-dimensional size of the accumulator
1374  int accDx = 0;
1375  int accDy = 0;
1376  c.GetAccumSize(accDy, accDx);
1377 
1378  //find the weightiest cell in the accumulator.
1379  int xMax = 0;
1380  int yMax = 0;
1381  c.GetMax(yMax, xMax);
1382 
1383  //find the center of mass of the 3x3 cell system (with maxCell at the center).
1384  float centerofmassx = 0.;
1385  float centerofmassy = 0.;
1386  float denom = 0.;
1387 
1388  if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
1389  for (int i = -1; i < 2; ++i) {
1390  for (int j = -1; j < 2; ++j) {
1391  denom += c.GetCell(yMax + i, xMax + j);
1392  centerofmassx += j * c.GetCell(yMax + i, xMax + j);
1393  centerofmassy += i * c.GetCell(yMax + i, xMax + j);
1394  }
1395  }
1396  centerofmassx /= denom;
1397  centerofmassy /= denom;
1398  }
1399  else
1400  centerofmassx = centerofmassy = 0;
1401 
1402  float rho = 0.;
1403  float theta = 0.;
1404  c.GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1405  MF_LOG_DEBUG("HoughBaseAlg") << "Transform(III) found maximum at (d=" << rho << " a=" << theta
1406  << ")"
1407  " from absolute maximum "
1408  << c.GetCell(yMax, xMax) << " at (d=" << yMax << ", a=" << xMax
1409  << ")";
1410  slope = -1. / tan(theta);
1411  intercept = rho / sin(theta);
1412 
1415 
1416  return hits.size();
1417 }
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:534
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
int fNumAngleCells
that fall into the "correct" bin will be small and consistent with noise.
Definition: HoughBaseAlg.h:523
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
#define MF_LOG_DEBUG(id)

Friends And Related Function Documentation

friend class HoughTransformClus
friend

Definition at line 514 of file HoughBaseAlg.h.

Member Data Documentation

float cluster::HoughBaseAlg::fMaxDistance
private

Max distance that a hit can be from a line to be considered part of that line.

Definition at line 528 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fMaxLines
private

Max number of lines that can be found.

Definition at line 519 of file HoughBaseAlg.h.

float cluster::HoughBaseAlg::fMaxSlope
private

Max slope a line can have.

Definition at line 529 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fMinHits
private

Min number of hits in the accumulator to consider (number of hits required to be considered a line).

Definition at line 520 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fMissedHits
private

Number of wires that are allowed to be missed before a line is broken up into segments

Definition at line 539 of file HoughBaseAlg.h.

float cluster::HoughBaseAlg::fMissedHitsDistance
private

Distance between hits in a hough line before a hit is considered missed.

Definition at line 542 of file HoughBaseAlg.h.

float cluster::HoughBaseAlg::fMissedHitsToLineSize
private

Ratio of missed hits to line size for a line to be considered a fake.

Definition at line 544 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fNumAngleCells
private

that fall into the "correct" bin will be small and consistent with noise.

Number of angle cells in the accumulator (a measure of the angular resolution of the line finder). If this number is too large than the number of votes

Definition at line 523 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fPerCluster
private

Tells the original Hough algorithm to look at clusters individually, or all hits at once

Definition at line 536 of file HoughBaseAlg.h.

float cluster::HoughBaseAlg::fRhoResolutionFactor
private

Factor determining the resolution in rho.

Definition at line 534 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fRhoZeroOutRange
private

Range in rho over which to zero out area around previously found lines in the accumulator.

Definition at line 531 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fSaveAccumulator
private

Save bitmap image of accumulator for debugging?

Definition at line 522 of file HoughBaseAlg.h.

int cluster::HoughBaseAlg::fThetaZeroOutRange
private

Range in theta over which to zero out area around previously found lines in the accumulator.

Definition at line 533 of file HoughBaseAlg.h.


The documentation for this class was generated from the following files: