LArSoft  v06_85_00
Liquid Argon Software toolkit - http://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 ()
 
size_t FastTransform (const std::vector< art::Ptr< recob::Cluster > > &clusIn, std::vector< recob::Cluster > &ccol, std::vector< art::PtrVector< recob::Hit > > &clusHitsOut, art::Event const &evt, std::string const &label)
 
size_t Transform (std::vector< art::Ptr< recob::Hit > > const &hits, std::vector< unsigned int > *fpointId_to_clusterId, unsigned int clusterId, unsigned int *nClusters, std::vector< protoTrack > *protoTracks)
 
size_t FastTransform (std::vector< art::Ptr< recob::Hit >> &clusIn, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut)
 
size_t FastTransform (std::vector< art::Ptr< recob::Hit >> &clusIn, std::vector< art::PtrVector< recob::Hit >> &clusHitsOut, std::vector< double > &slope, std::vector< ChargeInfo_t > &totalQ)
 
size_t Transform (std::vector< art::Ptr< recob::Hit > > const &hits)
 
size_t Transform (std::vector< art::Ptr< recob::Hit > > const &hits, double &slope, double &intercept)
 
virtual void reconfigure (fhicl::ParameterSet const &pset)
 

Protected 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
 
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 550 of file HoughBaseAlg.h.

Constructor & Destructor Documentation

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

Definition at line 211 of file HoughBaseAlg.cxx.

References reconfigure().

212 {
213  this->reconfigure(pset);
214 }
virtual void reconfigure(fhicl::ParameterSet const &pset)
cluster::HoughBaseAlg::~HoughBaseAlg ( )
virtual

Definition at line 217 of file HoughBaseAlg.cxx.

218 {
219 }

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,
art::Event const &  evt,
std::string const &  label 
)

Definition at line 1051 of file HoughBaseAlg.cxx.

References lar::util::StatCollector< T, W >::add(), cluster::HoughTransform::AddPointReturnMax(), art::PtrVector< T >::back(), art::PtrVector< T >::clear(), geo::GeometryCore::Cryostat(), art::PtrVector< T >::end(), fMaxDistance, fMaxLines, fMaxSlope, fMinHits, fMissedHits, fMissedHitsDistance, fMissedHitsToLineSize, fNumAngleCells, fPerCluster, fRhoResolutionFactor, fRhoZeroOutRange, fSaveAccumulator, fThetaZeroOutRange, cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), hits(), HLSSaveBMPFile(), cluster::ClusterParamsImportWrapper< Algo >::ImportHits(), cluster::HoughTransform::Init(), geo::kInduction, LOG_DEBUG, max, geo::GeometryCore::Nplanes(), geo::PlaneGeo::Nwires(), recob::Hit::PeakTime(), geo::TPCGeo::Plane(), geo::WireID::planeID(), art::PtrVector< T >::push_back(), lar::util::StatCollector< T, W >::RMS(), recob::Cluster::Sentry, cluster::HoughTransform::SetCell(), recob::Hit::SigmaPeakTime(), geo::GeometryCore::SignalType(), lar::util::StatCollector< T, W >::Sum(), sw, geo::CryostatGeo::TPC(), lar::dump::vector(), recob::Hit::View(), geo::GeometryCore::Views(), geo::WireID::Wire, recob::Hit::WireID(), geo::GeometryCore::WirePitch(), x, xx, and y.

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

1056 {
1057  std::vector<int> skip;
1058 
1059  art::FindManyP<recob::Hit> fmh(clusIn, evt, label);
1060 
1061  geo::GeometryCore const* geom = lar::providerFrom<geo::Geometry>();
1062  // const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
1063 // lariov::ChannelStatusProvider const* channelStatus
1064 // = lar::providerFrom<lariov::ChannelStatusService>();
1065  HoughTransform c;
1066 
1067  // Get the random number generator
1069  CLHEP::HepRandomEngine & engine = rng -> getEngine();
1070  CLHEP::RandFlat flat(engine);
1071 
1072  // prepare the algorithm to compute the cluster characteristics;
1073  // we use the "standard" one here; configuration would happen here,
1074  // but we are using the default configuration for that algorithm
1075  ClusterParamsImportWrapper<StandardClusterParamsAlg> ClusterParamAlgo;
1076 
1077  std::vector< art::Ptr<recob::Hit> > hit;
1078 
1079  for(auto view : geom->Views() ){
1080 
1081  LOG_DEBUG("HoughBaseAlg") << "Analyzing view " << view;
1082 
1083  art::PtrVector<recob::Cluster>::const_iterator clusterIter = clusIn.begin();
1084  int clusterID = 0;//the unique ID of the cluster
1085 
1086  size_t cinctr = 0;
1087  while(clusterIter != clusIn.end()) {
1088 
1089  LOG_DEBUG("HoughBaseAlg") << "Analyzing cinctr=" << cinctr << " which is in view " << (*clusterIter)->View();
1090 
1091  hit.clear();
1092  if(fPerCluster){
1093  if((*clusterIter)->View() == view) hit = fmh.at(cinctr);
1094  }
1095  else{
1096  while(clusterIter != clusIn.end()){
1097  if( (*clusterIter)->View() == view ){
1098 
1099  hit = fmh.at(cinctr);
1100  }// end if cluster is in correct view
1101  clusterIter++;
1102  ++cinctr;
1103  }//end loop over clusters
1104  }//end if not fPerCluster
1105  if(hit.size() == 0){
1106  if(fPerCluster){
1107  clusterIter++;
1108  ++cinctr;
1109  }
1110  continue;
1111  }
1112 
1113  LOG_DEBUG("HoughBaseAlg") << "We have all the hits..." << hit.size();
1114 
1115  /*
1116  //factor to make x and y scale the same units
1117  double xyScale = .001*detprop->DriftVelocity(detprop->Efield(),detprop->Temperature());
1118  xyScale *= detprop->SamplingRate()/geom->WirePitch(p,t,cs);
1119 
1120  int x, y;
1121  int dx = geom->Cryostat(cs).TPC(t).Plane(p).Nwires();//number of wires
1122  const int dy = detprop->ReadOutWindowSize(); // number of time samples.
1123  skip.clear();
1124  skip.resize(hit.size());
1125  std::vector<int> listofxmax;
1126  std::vector<int> listofymax;
1127  std::vector<int> hitTemp; //indecies ofcandidate hits
1128  std::vector<int> sequenceHolder; //channels of hits in list
1129  std::vector<int> currentHits; //working vector of hits
1130  std::vector<int> lastHits; //best list of hits
1131  art::PtrVector<recob::Hit> clusterHits;
1132  double indcolscaling = 0.; //a parameter to account for the different
1133  //characteristic hit width of induction and collection plane
1134  double centerofmassx = 0;
1135  double centerofmassy = 0;
1136  double denom = 0;
1137  double intercept=0.;
1138  double slope = 0.;
1139  //this array keeps track of the hits that have already been associated with a line.
1140  int xMax = 0;
1141  int yMax = 0;
1142  double rho;
1143  double theta;
1144  int accDx(0), accDy(0);
1145 
1146 
1147  //Init specifies the size of the two-dimensional accumulator
1148  //(based on the arguments, number of wires and number of time samples).
1149  //adds all of the hits (that have not yet been associated with a line) to the accumulator
1150  c.Init(dx,dy,fRhoResolutionFactor,fNumAngleCells);
1151 
1152 
1153  // count is how many points are left to randomly insert
1154  unsigned int count = hit.size();
1155  std::vector<unsigned int> accumPoints;
1156  accumPoints.resize(hit.size());
1157  int nAccum = 0;
1158  unsigned int nLinesFound = 0;
1159 
1160  for( ; count > 0; count--){
1161 
1162 
1163  // The random hit we are examining
1164  unsigned int randInd = (unsigned int)(flat.fire()*hit.size());
1165 
1166  // Skip if it's already in a line
1167  if(skip[randInd]==1)
1168  continue;
1169 
1170  // If we have already accumulated the point, skip it
1171  if(accumPoints[randInd])
1172  continue;
1173  accumPoints[randInd]=1;
1174 
1175  // zeroes out the neighborhood of all previous lines
1176  for(unsigned int i = 0; i < listofxmax.size(); ++i){
1177  int yClearStart = listofymax[i] - fRhoZeroOutRange;
1178  if (yClearStart < 0) yClearStart = 0;
1179 
1180  int yClearEnd = listofymax[i] + fRhoZeroOutRange;
1181  if (yClearEnd >= accDy) yClearEnd = accDy - 1;
1182 
1183  int xClearStart = listofxmax[i] - fThetaZeroOutRange;
1184  if (xClearStart < 0) xClearStart = 0;
1185 
1186  int xClearEnd = listofxmax[i] + fThetaZeroOutRange;
1187  if (xClearEnd >= accDx) xClearEnd = accDx - 1;
1188 
1189  for (y = yClearStart; y <= yClearEnd; ++y){
1190  for (x = xClearStart; x <= xClearEnd; ++x){
1191  c.SetCell(y,x,0);
1192  }
1193  }
1194  }// end loop over size of listxmax
1195 
1196  //find the weightiest cell in the accumulator.
1197  int maxCell = 0;
1198  unsigned int wireMax = hit[randInd]->WireID().Wire;
1199  xMax = 0;
1200  yMax = 0;
1201 
1202  // Add the randomly selected point to the accumulator
1203  maxCell = c.AddPointReturnMax(wireMax, (int)(hit[randInd]->PeakTime()), &yMax, &xMax, fMinHits);
1204  nAccum++;
1205 
1206  // Continue if the biggest maximum for the randomly selected point is smaller than fMinHits
1207  if (maxCell < fMinHits)
1208  continue;
1209 
1210  // Find the center of mass of the 3x3 cell system (with maxCell at the center).
1211  denom = centerofmassx = centerofmassy = 0;
1212 
1213  if(xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy){
1214  for(int i = -1; i < 2; ++i){
1215  for(int j = -1; j < 2; ++j){
1216  denom += c.GetCell(yMax+i,xMax+j);
1217  centerofmassx += j*c.GetCell(yMax+i,xMax+j);
1218  centerofmassy += i*c.GetCell(yMax+i,xMax+j);
1219  }
1220  }
1221  centerofmassx /= denom;
1222  centerofmassy /= denom;
1223  }
1224  else centerofmassx = centerofmassy = 0;
1225 
1226  //fill the list of cells that have already been found
1227  listofxmax.push_back(xMax);
1228  listofymax.push_back(yMax);
1229 
1230  // Find the lines equation
1231  c.GetEquation(yMax+centerofmassy, xMax+centerofmassx, rho, theta);
1232  //c.GetEquation(yMax, xMax, rho, theta);
1233  slope = -1./tan(theta);
1234  intercept = (rho/sin(theta));
1235  //mf::LogVerbatim("HoughBaseAlg") << std::endl;
1236  //mf::LogVerbatim("HoughBaseAlg") << "slope: " << slope << " intercept: " << intercept << std::endl;
1237  //mf::LogInfo("HoughBaseAlg") << "slope: " << slope << " intercept: " << intercept;
1238  double distance;
1242  if(sigt == geo::kInduction)
1243  indcolscaling = 5.;
1244  else
1245  indcolscaling = 0.;
1246  // What is this?
1247  indcolscaling = 0;
1248 
1249  if(!std::isinf(slope) && !std::isnan(slope)){
1250  sequenceHolder.clear();
1251  hitTemp.clear();
1252  for(size_t i = 0; i < hit.size(); ++i){
1253  distance = (TMath::Abs(hit[i]->PeakTime()-slope*(double)(hit[i]->WireID().Wire)-intercept)/(std::sqrt(pow(xyScale*slope,2)+1)));
1254 
1255  if(distance < fMaxDistance+hit[i]->RMS()+indcolscaling && skip[i]!=1){
1256  hitTemp.push_back(i);
1257  sequenceHolder.push_back(hit[i]->Channel());
1258  }
1259 
1260  }// end loop over hits
1261 
1262  if(hitTemp.size() < 2) continue;
1263  currentHits.clear();
1264  lastHits.clear();
1265  int j;
1266  currentHits.push_back(0);
1267  for(size_t i = 0; i + 1 < sequenceHolder.size(); ++i){
1268  j = 1;
1269  while((channelStatus->IsBad(sequenceHolder[i]+j)) == true) j++;
1270  if(sequenceHolder[i+1]-sequenceHolder[i] <= j + fMissedHits) currentHits.push_back(i+1);
1271  else if(currentHits.size() > lastHits.size()) {
1272  lastHits = currentHits;
1273  currentHits.clear();
1274  }
1275  else currentHits.clear();
1276  }
1277 
1278 
1279  if(currentHits.size() > lastHits.size()) lastHits = currentHits;
1280 
1281 
1282 
1283 
1284  // Check if lastHits has hits with big gaps in it
1285  uint32_t channel = hit[0]->Channel();
1286  double wirePitch = geom->WirePitch(geom->View(channel));
1287  double wire_dist = wirePitch;
1288  double tickToDist = detprop->DriftVelocity(detprop->Efield(),detprop->Temperature());
1289  tickToDist *= 1.e-3 * detprop->SamplingRate(); // 1e-3 is conversion of 1/us to 1/ns
1290  //std::cout << "New line" << std::endl;
1291  int missedHits=0;
1292  for(size_t i = 0; i < lastHits.size()-1; ++i) {
1293  //std::cout << hit[hitTemp[lastHits[i]]]->Channel() << std::endl;
1294  double pCorner0[2];
1295  pCorner0[0] = (hit[hitTemp[lastHits[i]]]->Channel())*wire_dist;
1296  pCorner0[1] = hit[hitTemp[lastHits[i]]]->PeakTime()*tickToDist;
1297  double pCorner1[2];
1298  pCorner1[0] = (hit[hitTemp[lastHits[i+1]]]->Channel())*wire_dist;
1299  pCorner1[1] = hit[hitTemp[lastHits[i+1]]]->PeakTime()*tickToDist;
1300  //std::cout << std::sqrt( pow(pCorner0[0]-pCorner1[0],2) + pow(pCorner0[1]-pCorner1[1],2)) << std::endl;
1301  if(std::sqrt( pow(pCorner0[0]-pCorner1[0],2) + pow(pCorner0[1]-pCorner1[1],2)) > fMissedHitsDistance )
1302  missedHits++;
1303  }
1304  //std::cout << "missedHits " << missedHits << std::endl;
1305  //std::cout << "lastHits.size() " << lastHits.size() << std::endl;
1306  //std::cout << "missedHits/lastHits.size() " << (double)missedHits/(double)lastHits.size() << std::endl;
1307  if((double)missedHits/(double)lastHits.size() > fMissedHitsToLineSize)
1308  continue;
1309 
1310 
1311 
1312 
1313 
1314  clusterHits.clear();
1315  double totalQ = 0.;
1316  if(lastHits.size() < 5) continue;
1317 
1318 
1319  for(size_t i = 0; i < lastHits.size(); ++i) {
1320  clusterHits.push_back(hit[hitTemp[lastHits[i]]]);
1321  totalQ += clusterHits.back()->Integral();
1322  skip[hitTemp[lastHits[i]]]=1;
1323  }
1324  //protection against very steep uncorrelated hits
1325  if(std::abs(slope)>fMaxSlope
1326  && std::abs((*clusterHits.begin())->Channel()-
1327  clusterHits[clusterHits.size()-1]->Channel())>=0
1328  )
1329  continue;
1330 
1331 
1332 
1333  unsigned int sw = (*clusterHits.begin())->WireID().Wire;
1334  unsigned int ew = (*(clusterHits.end()-1))->WireID().Wire;
1335 
1336  recob::Cluster cluster(sw, 0.,
1337  (*clusterHits.begin())->PeakTime(), 0.,
1338  ew, 0.,
1339  (clusterHits[clusterHits.size()-1])->PeakTime(), 0.,
1340  slope, 0.,
1341  -999., 0.,
1342  totalQ,
1343  geom->View((*clusterHits.begin())->Channel()),
1344  clusterID);
1345 
1346  ++clusterID;
1347  ccol.push_back(cluster);
1348  clusHitsOut.push_back(clusterHits);
1349 
1350  //Turn off hit sharing. T. Yang 9/14/12
1351  // //allow double assignment of first and last hits
1352  // for(size_t i = 0; i < lastHits.size(); ++i){
1353  // if(skip[hitTemp[lastHits[i]]] ==1){
1354  // channel = hit[hitTemp[lastHits[i]]]->Channel();
1355  // if( channel == sc || channel == ec) skip[i] = 0;
1356  // }
1357  // }
1358 
1359  }// end if !std::isnan
1360 
1361  nLinesFound++;
1362 
1363  if(nLinesFound>(unsigned int)fMaxLines)
1364  break;
1365 
1366 
1367  }// end loop over hits*/
1368 
1369  std::vector<double> slopevec;
1370  std::vector<ChargeInfo_t> totalQvec;
1371  std::vector< art::PtrVector<recob::Hit> > planeClusHitsOut;
1372  this->FastTransform(hit,planeClusHitsOut,slopevec,totalQvec );
1373 
1374  LOG_DEBUG("HoughBaseAlg") << "Made it through FastTransform" << planeClusHitsOut.size();
1375 
1376  for(size_t xx = 0; xx < planeClusHitsOut.size(); ++xx){
1377  auto const& hits = planeClusHitsOut.at(xx);
1378  recob::Hit const& FirstHit = *hits.front();
1379  recob::Hit const& LastHit = *hits.back();
1380  const unsigned int sw = FirstHit.WireID().Wire;
1381  const unsigned int ew = LastHit.WireID().Wire;
1382 // ChargeInfo_t const& charge_info = totalQvec.at(xx); // delegating to algos
1383 
1384  // feed the algorithm with all the cluster hits
1385  ClusterParamAlgo.ImportHits(hits);
1386 
1387  // create the recob::Cluster directly in the vector;
1388  // NOTE usually we would use cluster::ClusterCreator to save some typing and
1389  // some mistakes. In this case, we don't want to pull in the dependency on
1390  // ClusterFinder, where ClusterCreator currently lives
1391  ccol.emplace_back(
1392  float(sw), // start_wire
1393  0., // sigma_start_wire
1394  FirstHit.PeakTime(), // start_tick
1395  FirstHit.SigmaPeakTime(), // sigma_start_tick
1396  ClusterParamAlgo.StartCharge().value(), // start_charge
1397  ClusterParamAlgo.StartAngle().value(), // start_angle
1398  ClusterParamAlgo.StartOpeningAngle().value(), // start_opening
1399  float(ew), // end_wire
1400  0., // sigma_end_wire,
1401  LastHit.PeakTime(), // end_tick
1402  LastHit.SigmaPeakTime(), // sigma_end_tick
1403  ClusterParamAlgo.EndCharge().value(), // end_charge
1404  ClusterParamAlgo.EndAngle().value(), // end_angle
1405  ClusterParamAlgo.EndOpeningAngle().value(), // end_opening
1406  ClusterParamAlgo.Integral().value(), // integral
1407  ClusterParamAlgo.IntegralStdDev().value(), // integral_stddev
1408  ClusterParamAlgo.SummedADC().value(), // summedADC
1409  ClusterParamAlgo.SummedADCStdDev().value(), // summedADC_stddev
1410  ClusterParamAlgo.NHits(), // n_hits
1411  ClusterParamAlgo.MultipleHitDensity(), // multiple_hit_density
1412  ClusterParamAlgo.Width(), // width
1413  clusterID, // ID
1414  FirstHit.View(), // view
1415  FirstHit.WireID().planeID(), // plane
1416  recob::Cluster::Sentry // sentry
1417  );
1418 
1419  ++clusterID;
1420  clusHitsOut.push_back(planeClusHitsOut.at(xx));
1421  }
1422 
1423 
1424  hit.clear();
1425  // lastHits.clear();
1426  if(clusterIter != clusIn.end()){
1427  clusterIter++;
1428  ++cinctr;
1429  }
1430  // listofxmax.clear();
1431  // listofymax.clear();
1432  }//end loop over clusters
1433 
1434  }// end loop over views
1435 
1436  return ccol.size();
1437 
1438 }
PlaneID const & planeID() const
Definition: geo_types.h:355
Double_t xx
Definition: macro.C:12
const std::string label
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
size_t FastTransform(const std::vector< art::Ptr< recob::Cluster > > &clusIn, std::vector< recob::Cluster > &ccol, std::vector< art::PtrVector< recob::Hit > > &clusHitsOut, art::Event const &evt, std::string const &label)
std::set< geo::View_t > const & Views() const
Returns a list of possible views in the detector.
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:233
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
void hits()
Definition: readHits.C:15
Description of geometry of one entire detector.
Detector simulation of raw signals on wires.
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
Float_t sw
Definition: plot.C:23
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
#define LOG_DEBUG(id)
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
Definition: Hit.h:220
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
size_t cluster::HoughBaseAlg::FastTransform ( std::vector< art::Ptr< recob::Hit >> &  clusIn,
std::vector< art::PtrVector< recob::Hit >> &  clusHitsOut 
)
size_t cluster::HoughBaseAlg::FastTransform ( std::vector< art::Ptr< recob::Hit >> &  clusIn,
std::vector< art::PtrVector< recob::Hit >> &  clusHitsOut,
std::vector< double > &  slope,
std::vector< ChargeInfo_t > &  totalQ 
)
void cluster::HoughBaseAlg::HLSSaveBMPFile ( char const *  ,
unsigned char *  ,
int  ,
int   
)
protected

Definition at line 1015 of file HoughBaseAlg.cxx.

Referenced by FastTransform(), and Transform().

1016 {
1017  std::ofstream bmpFile(fileName, std::ios::binary);
1018  bmpFile.write("B", 1);
1019  bmpFile.write("M", 1);
1020  int bitsOffset = 54 +256*4;
1021  int size = bitsOffset + dx*dy; //header plus 256 entry LUT plus pixels
1022  bmpFile.write((const char *)&size, 4);
1023  int reserved = 0;
1024  bmpFile.write((const char *)&reserved, 4);
1025  bmpFile.write((const char *)&bitsOffset, 4);
1026  int bmiSize = 40;
1027  bmpFile.write((const char *)&bmiSize, 4);
1028  bmpFile.write((const char *)&dx, 4);
1029  bmpFile.write((const char *)&dy, 4);
1030  short planes = 1;
1031  bmpFile.write((const char *)&planes, 2);
1032  short bitCount = 8;
1033  bmpFile.write((const char *)&bitCount, 2);
1034  int i, temp = 0;
1035  for (i=0; i<6; i++)
1036  bmpFile.write((const char *)&temp, 4); // zero out optional color info
1037  // write a linear LUT
1038  char lutEntry[4]; // blue,green,red
1039  lutEntry[3] = 0; // reserved part
1040  for (i=0; i<256; i++)
1041  {
1042  lutEntry[0] = lutEntry[1] = lutEntry[2] = i;
1043  bmpFile.write(lutEntry, sizeof lutEntry);
1044  }
1045  // write the actual pixels
1046  bmpFile.write((const char *)pix, dx*dy);
1047 }
void cluster::HoughBaseAlg::reconfigure ( fhicl::ParameterSet const &  pset)
virtual

Definition at line 222 of file HoughBaseAlg.cxx.

References fMaxDistance, fMaxLines, fMaxSlope, fMinHits, fMissedHits, fMissedHitsDistance, fMissedHitsToLineSize, fNumAngleCells, fPerCluster, fRhoResolutionFactor, fRhoZeroOutRange, fSaveAccumulator, fThetaZeroOutRange, and fhicl::ParameterSet::get().

Referenced by HoughBaseAlg(), cluster::fuzzyClusterAlg::reconfigure(), and cluster::HoughLineFinder::reconfigure().

223 {
224  fMaxLines = pset.get< int >("MaxLines" );
225  fMinHits = pset.get< int >("MinHits" );
226  fSaveAccumulator = pset.get< int >("SaveAccumulator" );
227  fNumAngleCells = pset.get< int >("NumAngleCells" );
228  fMaxDistance = pset.get< float >("MaxDistance" );
229  fMaxSlope = pset.get< float >("MaxSlope" );
230  fRhoZeroOutRange = pset.get< int >("RhoZeroOutRange" );
231  fThetaZeroOutRange = pset.get< int >("ThetaZeroOutRange" );
232  fRhoResolutionFactor = pset.get< float >("RhoResolutionFactor" );
233  fPerCluster = pset.get< int >("HitsPerCluster" );
234  fMissedHits = pset.get< int >("MissedHits" );
235  fMissedHitsDistance = pset.get< float >("MissedHitsDistance" );
236  fMissedHitsToLineSize = pset.get< float >("MissedHitsToLineSize" );
237  return;
238 }
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:625
int fMaxLines
Max number of lines that can be found.
Definition: HoughBaseAlg.h:613
float fMissedHitsDistance
Distance between hits in a hough line before a hit is considered missed.
Definition: HoughBaseAlg.h:630
int fSaveAccumulator
Save bitmap image of accumulator for debugging?
Definition: HoughBaseAlg.h:616
float fMaxDistance
Max distance that a hit can be from a line to be considered part of that line.
Definition: HoughBaseAlg.h:621
float fMaxSlope
Max slope a line can have.
Definition: HoughBaseAlg.h:622
int fRhoZeroOutRange
Range in rho over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:623
int fThetaZeroOutRange
Range in theta over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:624
float fMissedHitsToLineSize
Ratio of missed hits to line size for a line to be considered a fake.
Definition: HoughBaseAlg.h:631
size_t cluster::HoughBaseAlg::Transform ( std::vector< art::Ptr< recob::Hit > > const &  hits,
std::vector< unsigned int > *  fpointId_to_clusterId,
unsigned int  clusterId,
unsigned int *  nClusters,
std::vector< protoTrack > *  protoTracks 
)
Todo:
provide comment about where the 0.001 comes from

characteristic hit width of induction and collection plane

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.

Outline of PPHT, J. Matas et. al.

LOOP over hits, picking a random one Enter the point into the accumulator IF it is already in the accumulator or part of a line, skip it Store it in a vector of points that have been chosen

Find max value in accumulator; IF above threshold, create a line Subtract points in line from accumulator

END LOOP over hits, picking a random one

Init specifies the size of the two-dimensional accumulator (based on the arguments, number of wires and number of time samples).

Adds all of the hits to the accumulator

count is how many points are left to randomly insert

Get the random number generator

The random hit we are examining unsigned int randInd = rand() % hits.size();

If the point isn't in the current fuzzy cluster, skip it

Skip if it's already in a line

If we have already accumulated the point, skip it

zeroes out the neighborhood of all previous lines

end loop over size of listxmax

Find the weightiest cell in the accumulator.

Add the randomly selected point to the accumulator

The threshold calculation, see http://www.via.cornell.edu/ece547/projects/Hough/webpage/statistics.html accDx is the number of rho bins,m_rowLength

The threshold calculation using a Poisson distribution instead

Continue if the biggest maximum for the randomly selected point is smaller than fMinHits

Find the center of mass of the 3x3 cell system (with maxCell at the center).

fill the list of cells that have already been found

end iterator over hits

std::cout << "nClusters: " << *nClusters << std::endl;

Subtract points from the accumulator that have already been used

std::cout << std::endl; std::cout << "pCornerMin[0]: " << pCornerMin[0] << " pCornerMin[1]: " << pCornerMin[1] << std::endl; std::cout << "pCornerMax[0]: " << pCornerMax[0] << " pCornerMax[1]: " << pCornerMax[1] << std::endl;

end if !std::isnan

end loop over hits

Definition at line 248 of file HoughBaseAlg.cxx.

References cluster::HoughTransform::AddPointReturnMax(), geo::GeometryCore::Cryostat(), e, fMaxDistance, fMaxLines, fMaxSlope, fMinHits, fMissedHits, fNumAngleCells, fRhoResolutionFactor, fRhoZeroOutRange, fSaveAccumulator, fThetaZeroOutRange, cluster::HoughTransform::GetAccumSize(), cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), hits(), HLSSaveBMPFile(), protoTrack::Init(), cluster::HoughTransform::Init(), geo::kInduction, LOG_DEBUG, max, geo::GeometryCore::Nplanes(), geo::PlaneGeo::Nwires(), geo::TPCGeo::Plane(), cluster::HoughTransform::SetCell(), geo::GeometryCore::SignalType(), sqr(), cluster::HoughTransform::SubtractPoint(), geo::CryostatGeo::TPC(), w, geo::GeometryCore::WirePitch(), x, and y.

Referenced by cluster::fuzzyClusterAlg::run_fuzzy_cluster().

255 {
256 
257  int nClustersTemp = *nClusters;
258 
259  geo::GeometryCore const* geom = lar::providerFrom<geo::Geometry>();
260  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
261  lariov::ChannelStatusProvider const* channelStatus
262  = lar::providerFrom<lariov::ChannelStatusService>();
263 
264  // uint32_t channel = hits[0]->Channel();
265  unsigned int wire = 0;
266  unsigned int wireMax = 0;
267  unsigned int cs=hits[0]->WireID().Cryostat;
268  unsigned int t=hits[0]->WireID().TPC;
269  geo::WireID const& wireid = hits[0]->WireID();
270 
271 
272  //mf::LogInfo("HoughBaseAlg") << "nClusters is: " << *nClusters;
273 
274 
275  geo::SigType_t sigt = geom->SignalType(wireid);
276  std::vector<int> skip;
277 
278  std::vector<double> wire_pitch(geom->Nplanes(t, cs), 0.);
279  for (size_t p = 0; p < wire_pitch.size(); ++p) {
280  wire_pitch[p] = geom->WirePitch(p);
281  }
282 
283  //factor to make x and y scale the same units
284  std::vector<double> xyScale(geom->Nplanes(t, cs), 0.);
285 
287  double driftVelFactor = 0.001*detprop->DriftVelocity(detprop->Efield(),detprop->Temperature());
288 
289  for(size_t p = 0; p < xyScale.size(); ++p)
290  xyScale[p] = driftVelFactor * detprop->SamplingRate()/wire_pitch[p];
291 
292  float tickToDist = driftVelFactor * detprop->SamplingRate();
293  //tickToDist *= 1.e-3 * detprop->SamplingRate(); // 1e-3 is conversion of 1/us to 1/ns
294 
295 
296  //mf::LogInfo("HoughBaseAlg") << "xyScale: " << xyScale;
297  //mf::LogInfo("HoughBaseAlg") << "tickToDist: " << tickToDist;
298 
299  int x, y;
300  //unsigned int channel, plane, wire, tpc, cstat;
301  //there must be a better way to find which plane a cluster comes from
302  const int dx = geom->Cryostat(hits[0]->WireID().Cryostat).TPC(hits[0]->WireID().TPC).Plane(hits[0]->WireID().Plane).Nwires();//number of wires
303  // const int dy = detprop->ReadOutWindowSize(); // number of time samples.
304  const int dy = detprop->NumberTimeSamples();//number of time samples.
305  skip.clear();
306  skip.resize(hits.size());
307  std::vector<int> listofxmax;
308  std::vector<int> listofymax;
309  std::vector<int> hitsTemp; //indecies ofcandidate hits
310  std::vector<int> sequenceHolder; //wire numbers of hits in list
311  std::vector<int> channelHolder; //channels of hits in list
312  std::vector<int> currentHits; //working vector of hits
313  std::vector<int> lastHits; //best list of hits
314  std::vector<art::Ptr<recob::Hit> > clusterHits;
315  float indcolscaling = 0.; //a parameter to account for the different
320  if(sigt == geo::kInduction)
321  indcolscaling = 0.;
322  else
323  indcolscaling = 1.;
324  //indcolscaling = 0;
325  float centerofmassx = 0;
326  float centerofmassy = 0;
327  float denom = 0;
328  float intercept=0.;
329  float slope = 0.;
330  //this array keeps track of the hits that have already been associated with a line.
331  int xMax = 0;
332  int yMax = 0;
333  int yClearStart;
334  int yClearEnd;
335  int xClearStart;
336  int xClearEnd;
337  int maxCell = 0;
338  float rho;
339  float theta;
340  int accDx(0), accDy(0);
341  float pCornerMin[2];
342  float pCornerMax[2];
343  //float pCorner0[2];
344  //float pCorner1[2];
345  //bool newChannel = false;
346  //unsigned int lastChannel;
347 
348  unsigned int fMaxWire = 0;
349  int iMaxWire = 0;
350  unsigned int fMinWire = 99999999;
351  int iMinWire = -1;
352 
353 
354 
355 
370 
371  mf::LogInfo("HoughBaseAlg") << "dealing with " << hits.size() << " hits";
372 
373  HoughTransform c;
374 
377  c.Init(dx,dy,fRhoResolutionFactor,fNumAngleCells);
379  //mf::LogInfo("HoughBaseAlg") << "Beginning PPHT";
380 
381  c.GetAccumSize(accDy, accDx);
382 
383  // Define the prototrack object
384  protoTrack protoTrackToLoad;
385 
386 
387  // The number of lines we've found
388  unsigned int nLinesFound = 0;
389  std::vector<unsigned int> accumPoints(hits.size(),0);
390  int nAccum = 0;
391 
393  int count = 0;
394  for(auto fpointId_to_clusterIdItr = fpointId_to_clusterId->begin(); fpointId_to_clusterIdItr != fpointId_to_clusterId->end();fpointId_to_clusterIdItr++)
395  if(*fpointId_to_clusterIdItr == clusterId)
396  count++;
397 
398  unsigned int randInd;
399 
402  CLHEP::HepRandomEngine & engine = rng -> getEngine();
403  CLHEP::RandFlat flat(engine);
404  TStopwatch w;
405  //float timeTotal = 0;
406 
407  for( ; count > 0; ){
408 
411  randInd = (unsigned int)(flat.fire()*hits.size());
412 
413  //std::cout << count << " " << randInd << std::endl;
414 
416  if(fpointId_to_clusterId->at(randInd) != clusterId)
417  continue;
418 
419  --count;
420 
422  if(skip[randInd]==1){
423  continue;
424  }
425 
427  if(accumPoints[randInd])
428  continue;
429  accumPoints[randInd]=1;
430 
432  for(auto listofxmaxItr = listofxmax.begin(); listofxmaxItr != listofxmax.end(); ++listofxmaxItr) {
433  yClearStart = listofymax[listofxmaxItr-listofxmax.begin()] - fRhoZeroOutRange;
434  if (yClearStart < 0) yClearStart = 0;
435 
436  yClearEnd = listofymax[listofxmaxItr-listofxmax.begin()] + fRhoZeroOutRange;
437  if (yClearEnd >= accDy) yClearEnd = accDy - 1;
438 
439  xClearStart = *listofxmaxItr - fThetaZeroOutRange;
440  if (xClearStart < 0) xClearStart = 0;
441 
442  xClearEnd = *listofxmaxItr + fThetaZeroOutRange;
443  if (xClearEnd >= accDx) xClearEnd = accDx - 1;
444 
445  for (y = yClearStart; y <= yClearEnd; ++y){
446  for (x = xClearStart; x <= xClearEnd; ++x){
447  c.SetCell(y,x,0);
448  }
449  }
450  }
451 
453  uint32_t channel = hits[randInd]->Channel();
454  wireMax = hits[randInd]->WireID().Wire;
455 
457  //w.Start();
458  std::array<int, 3> max = c.AddPointReturnMax(wireMax, (int)(hits[randInd]->PeakTime()));
459  maxCell = max[0];
460  xMax = max[1];
461  yMax = max[2];
462  //w.Stop();
463  //std::cout << "Real Time: " << w.RealTime() << std::endl;
464  //timeTotal += w.CpuTime();
465  ++nAccum;
466 
467  //mf::LogVerbatim("HoughBaseAlg") << "cout: " << count << " maxCell: " << maxCell << std::endl;
468  //mf::LogVerbatim("HoughBaseAlg") << "xMax: " << xMax << " yMax: " << yMax << std::endl;
469 
472  //TF1 *threshGaus = new TF1("threshGaus","(1/([0]*std::sqrt(2*TMath::Pi())))*exp(-0.5*pow(((x-[1])/[0]),2))");
473  //double sigma = std::sqrt(((double)nAccum/(double)accDx)*(1-1/(double)accDx));
474  //double mean = (double)nAccum/(double)accDx;
475  //threshGaus->SetParameter(0,sigma);
476  //threshGaus->SetParameter(1,mean);
477  //mf::LogVerbatim("HoughBaseAlg") << "threshGaus mean: " << mean << " sigma: " << sigma << " accDx: " << accDx << std::endl;
478  //mf::LogVerbatim("HoughBaseAlg") << "nAccum: " << nAccum << std::endl;
479  //mf::LogVerbatim("HoughBaseAlg") << "threshGaus integral range: " << mean-2*sigma << " to " << maxCell << std::endl;
480  //mf::LogVerbatim("HoughBaseAlg") << "threshGaus integral: " << threshGaus->Integral(mean-2*sigma,maxCell) << std::endl;
481  //mf::LogVerbatim("HoughBaseAlg") << "threshGaus integral: " << threshGaus->Integral(0,maxCell) << std::endl;
482 
483 
485  //double poisProbSum = 0;
486  //for(int j = 0; j <= maxCell; j++){
487  //double poisProb = TMath::Poisson(j,mean);
488  //poisProbSum+=poisProb;
489  //mf::LogVerbatim("HoughBaseAlg") << "Poisson: " << poisProb << std::endl;
490  //}
491  //mf::LogVerbatim("HoughBaseAlg") << "Poisson prob sum: " << poisProbSum << std::endl;
492  //mf::LogVerbatim("HoughBaseAlg") << "Probability it is higher: " << 1-poisProbSum << std::endl;
493 
494  // Continue if the probability of finding a point, (1-poisProbSum) is the probability of finding a
495  // value of maxCell higher than what it currently is
496  //if( (1-poisProbSum) > 1e-13)
497  //continue;
498 
499 
500  // The threshold calculation using a Binomial distribution instead
501  double binomProbSum = TMath::BinomialI(1/(double)accDx,nAccum,maxCell);
502  //std::cout << "nAccum: " << nAccum << std::endl;
503  //std::cout << "maxCell: " << maxCell << std::endl;
504  //std::cout << "BinomialI: " << binomProbSum << std::endl;
505  //std::cout << std::endl;
506  //mf::LogVerbatim("HoughBaseAlg") << "Probability it is higher: " << 1-binomProbSum << std::endl;
507  //Continue if the probability of finding a point, (1-poisProbSum) is the probability of finding a
508  //value of maxCell higher than what it currently is
509  if( binomProbSum > 1e-21)
510  continue;
511 
512 
513 
515  //if (maxCell < fMinHits)
516  //continue;
517 
518 
520  denom = centerofmassx = centerofmassy = 0;
521 
522  if(xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy){
523  for(int i = -1; i < 2; ++i){
524  for(int j = -1; j < 2; ++j){
525  denom += c.GetCell(yMax+i,xMax+j);
526  centerofmassx += j*c.GetCell(yMax+i,xMax+j);
527  centerofmassy += i*c.GetCell(yMax+i,xMax+j);
528  }
529  }
530  centerofmassx /= denom;
531  centerofmassy /= denom;
532  }
533  else centerofmassx = centerofmassy = 0;
534 
536  listofxmax.push_back(xMax);
537  listofymax.push_back(yMax);
538 
539  // Find the lines equation
540  c.GetEquation(yMax+centerofmassy, xMax+centerofmassx, rho, theta);
541  LOG_DEBUG("HoughBaseAlg")
542  << "Transform(II) found maximum at (d=" << rho << " a=" << theta << ")"
543  " from absolute maximum " << c.GetCell(yMax,xMax)
544  << " at (d=" << yMax << ", a=" << xMax << ")";
545  slope = -1./tan(theta);
546  intercept = (rho/sin(theta));
547  float distance;
548 
549  if(!std::isinf(slope) && !std::isnan(slope)){
550  channelHolder.clear();
551  sequenceHolder.clear();
552  fMaxWire = 0;
553  iMaxWire = 0;
554  fMinWire = 99999999;
555  iMinWire = -1;
556  hitsTemp.clear();
557  for(auto hitsItr = hits.cbegin(); hitsItr != hits.cend(); ++hitsItr){
558  wire = (*hitsItr)->WireID().Wire;
559  if(fpointId_to_clusterId->at(hitsItr - hits.begin()) != clusterId)
560  continue;
561  channel = (*hitsItr)->Channel();
562  distance = (std::abs((*hitsItr)->PeakTime()-slope*(float)((*hitsItr)->WireID().Wire)-intercept)/(std::sqrt(sqr(xyScale[(*hitsItr)->WireID().Plane]*slope)+1.)));
563  if(distance < fMaxDistance+(*hitsItr)->RMS()+indcolscaling && skip[hitsItr-hits.begin()]!=1){
564  hitsTemp.push_back(hitsItr-hits.begin());
565  sequenceHolder.push_back(wire);
566  channelHolder.push_back(channel);
567  }
568  }
569 
570  if(hitsTemp.size() < 5) continue;
571  currentHits.clear();
572  lastHits.clear();
573  int j;
574  currentHits.push_back(0);
575  for(auto sequenceHolderItr = sequenceHolder.begin(); sequenceHolderItr+1 != sequenceHolder.end(); ++sequenceHolderItr) {
576  j = 1;
577  while(channelStatus->IsBad(sequenceHolderItr-sequenceHolder.begin()+j)) j++;
578  if(sequenceHolder[sequenceHolderItr-sequenceHolder.begin()+1]-sequenceHolder[sequenceHolderItr-sequenceHolder.begin()] <= j + fMissedHits) currentHits.push_back(sequenceHolderItr-sequenceHolder.begin()+1);
579  else if(currentHits.size() > lastHits.size()) {
580  lastHits = currentHits;
581  currentHits.clear();
582  }
583  else currentHits.clear();
584  }
585  if(currentHits.size() > lastHits.size()) lastHits = currentHits;
586 
587  clusterHits.clear();
588 
589  //if(lastHits.size() < 5) continue;
590  if(lastHits.size() < (unsigned int)fMinHits) continue;
591 
592 
593 
594 
595 
596 
597 
605  //int missedHits=0;
606  //int lastHitsChannel = 0;
607  //fMaxWire = 0;
608  //iMaxWire = 0;
609  //fMinWire = 99999999;
610  //iMinWire = -1;
611  //newChannel = false;
612  //lastChannel = hits[hitsTemp[lastHits[0]]]->Channel();
613  //for(auto lastHitsItr = lastHits.begin(); lastHitsItr != lastHits.end()-1; ++lastHitsItr) {
614 
615  //newChannel = false;
616  //if(slope < 0){
617  //if(hits[hitsTemp[*lastHitsItr+1]]->Channel() != lastChannel){
618  //newChannel = true;
619  //}
620  //}
621  //if(slope > 0 || !newChannel){
622 
624  //pCorner0[0] = (hits[hitsTemp[*lastHitsItr]]->Channel())*wire_dist;
625  //pCorner0[1] = hits[hitsTemp[*lastHitsItr]]->PeakTime()*tickToDist;
626  //pCorner1[0] = (hits[hitsTemp[*lastHitsItr+1]]->Channel())*wire_dist;
627  //pCorner1[1] = hits[hitsTemp[*lastHitsItr+1]]->PeakTime()*tickToDist;
630  //if((pCorner0[0]-pCorner1[0])*(pCorner0[0]-pCorner1[0]) + (pCorner0[1]-pCorner1[1])*(pCorner0[1]-pCorner1[1]) > fMissedHitsDistance*fMissedHitsDistance)
631  //missedHits++;
633  //} else if (slope < 0 && newChannel){
636  //pCorner0[0] = (hits[hitsTemp[lastHits[lastHitsChannel]]]->Channel())*wire_dist;
637  //pCorner0[1] = hits[hitsTemp[lastHits[lastHitsChannel]]]->PeakTime()*tickToDist;
638  //pCorner1[0] = (hits[hitsTemp[*lastHitsItr+1]]->Channel())*wire_dist;
639  //pCorner1[1] = hits[hitsTemp[*lastHitsItr+1]]->PeakTime()*tickToDist;
642  //if((pCorner0[0]-pCorner1[0])*(pCorner0[0]-pCorner1[0]) + (pCorner0[1]-pCorner1[1])*(pCorner0[1]-pCorner1[1]) > fMissedHitsDistance*fMissedHitsDistance)
643  //missedHits++;
644  //lastChannel=hits[hitsTemp[*lastHitsItr+1]]->Channel();
645  //lastHitsChannel=lastHitsItr-lastHits.begin()+1;
646  //}
647  //}
651  //if((float)missedHits/((float)lastHits.size()-1) > fMissedHitsToLineSize)
652  //continue;
653 
654 
655 
656 
657 
658 
659 
660  if(std::abs(slope)>fMaxSlope ){
661  continue;
662  }
663 
664  //std::cout << std::endl;
665  //std::cout << "Found line!" << std::endl
666  //<< "Slope: " << slope << std::endl
667  //<< "Intercept: " << intercept << std::endl
668  //<< "Number of hits: " << lastHits.size() << std::endl
669  //<< "Wire: " << fMinWire << " Peak time: "
670  //<< hits[iMinWire]->PeakTime() << std::endl
671  //<< "Wire: " << fMaxWire << " Peak time: "
672  //<< hits[iMaxWire]->PeakTime() << std::endl;
673 
674 
675  // Add new line to list of lines
676  float totalQ = 0;
677  std::vector< art::Ptr<recob::Hit> > lineHits;
678  nClustersTemp++;
680  for(auto lastHitsItr = lastHits.begin(); lastHitsItr != lastHits.end(); ++lastHitsItr) {
681  fpointId_to_clusterId->at(hitsTemp[(*lastHitsItr)]) = nClustersTemp-1;
682  //clusterHits.push_back(hits[hitsTemp[(*lastHitsItr)]]);
683  //totalQ += clusterHits.back()->Integral();
684  totalQ += hits[hitsTemp[(*lastHitsItr)]]->Integral();
685  wire = hits[hitsTemp[(*lastHitsItr)]]->WireID().Wire;
686 
687  if(!accumPoints[hitsTemp[(*lastHitsItr)]])
688  count--;
689 
690  skip[hitsTemp[(*lastHitsItr)]]=1;
691 
692  lineHits.push_back(hits[hitsTemp[(*lastHitsItr)]]);
693 
694 
696  if(accumPoints[hitsTemp[(*lastHitsItr)]])
697  c.SubtractPoint(wire, (int)(hits[hitsTemp[(*lastHitsItr)]]->PeakTime()));
698 
699  if(wire < fMinWire){
700  fMinWire = wire;
701  iMinWire = hitsTemp[(*lastHitsItr)];
702  }
703  if(wire > fMaxWire){
704  fMaxWire = wire;
705  iMaxWire = hitsTemp[(*lastHitsItr)];
706  }
707  }
708  int pnum = hits[iMinWire]->WireID().Plane;
709  pCornerMin[0] = (hits[iMinWire]->WireID().Wire)*wire_pitch[pnum];
710  pCornerMin[1] = hits[iMinWire]->PeakTime()*tickToDist;
711  pCornerMax[0] = (hits[iMaxWire]->WireID().Wire)*wire_pitch[pnum];
712  pCornerMax[1] = hits[iMaxWire]->PeakTime()*tickToDist;
713 
717  protoTrackToLoad.Init(nClustersTemp-1,
718  pnum,
719  slope,
720  intercept,
721  totalQ,
722  pCornerMin[0],
723  pCornerMin[1],
724  pCornerMax[0],
725  pCornerMax[1],
726  iMinWire,
727  iMaxWire,
728  fMinWire,
729  fMaxWire,
730  lineHits);
731  linesFound->push_back(protoTrackToLoad);
732 
733  }
734 
735 
736  nLinesFound++;
737 
738  if(nLinesFound>(unsigned int)fMaxLines)
739  break;
740 
741  }
742 
743  //std::cout << "Average cpu time: " << timeTotal/nAccum << std::endl;
744  //std::cout << "Total cpu time: " << timeTotal << std::endl;
745 
746 
747 
748 
749 
750  lastHits.clear();
751 
752  listofxmax.clear();
753  listofymax.clear();
754 
755  // saves a bitmap image of the accumulator (useful for debugging),
756  // with scaling based on the maximum cell value
757  if(fSaveAccumulator){
758  unsigned char *outPix = new unsigned char [accDx*accDy];
759  //finds the maximum cell in the accumulator for image scaling
760  int cell, pix = 0, maxCell = 0;
761  for (int y = 0; y < accDy; ++y){
762  for (int x = 0; x < accDx; ++x){
763  cell = c.GetCell(y,x);
764  if (cell > maxCell) maxCell = cell;
765  }
766  }
767  for (int y = 0; y < accDy; ++y){
768  for (int x = 0; x < accDx; ++x){
769  //scales the pixel weights based on the maximum cell value
770  if(maxCell > 0)
771  pix = (int)((1500*c.GetCell(y,x))/maxCell);
772  outPix[y*accDx + x] = pix;
773  }
774  }
775 
776  HLSSaveBMPFile("houghaccum.bmp", outPix, accDx, accDy);
777  delete [] outPix;
778  }// end if saving accumulator
779 
780  *nClusters=nClustersTemp;
781 
782  return 1;
783 }
Float_t x
Definition: compare.C:6
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:625
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Float_t y
Definition: compare.C:6
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
int fMaxLines
Max number of lines that can be found.
Definition: HoughBaseAlg.h:613
int fSaveAccumulator
Save bitmap image of accumulator for debugging?
Definition: HoughBaseAlg.h:616
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
Int_t max
Definition: plot.C:27
Signal from induction planes.
Definition: geo_types.h:92
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
float fMaxDistance
Max distance that a hit can be from a line to be considered part of that line.
Definition: HoughBaseAlg.h:621
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
float fMaxSlope
Max slope a line can have.
Definition: HoughBaseAlg.h:622
Description of geometry of one entire detector.
int fRhoZeroOutRange
Range in rho over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:623
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
unsigned int Nwires() const
Number of wires in this plane.
Definition: PlaneGeo.h:250
void Init(unsigned int num=999999, unsigned int pnum=999999, float slope=999999, float intercept=999999, float totalQTemp=-999999, float Min0=999999, float Min1=999999, float Max0=-999999, float Max1=-999999, int iMinWireTemp=999999, int iMaxWireTemp=-999999, int minWireTemp=999999, int maxWireTemp=-999999, std::vector< art::Ptr< recob::Hit >> hitsTemp=std::vector< art::Ptr< recob::Hit >>())
Definition: HoughBaseAlg.h:234
#define LOG_DEBUG(id)
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:298
int fThetaZeroOutRange
Range in theta over which to zero out area around previously found lines in the accumulator.
Definition: HoughBaseAlg.h:624
Float_t e
Definition: plot.C:34
recob::tracking::Plane Plane
Definition: TrackState.h:17
Float_t w
Definition: plot.C:23
T sqr(T v)
void HLSSaveBMPFile(char const *, unsigned char *, int, int)
size_t cluster::HoughBaseAlg::Transform ( std::vector< art::Ptr< recob::Hit > > const &  hits)
size_t cluster::HoughBaseAlg::Transform ( 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 1874 of file HoughBaseAlg.cxx.

References cluster::HoughTransform::AddPointReturnMax(), fNumAngleCells, fRhoResolutionFactor, cluster::HoughTransform::GetAccumSize(), cluster::HoughTransform::GetCell(), cluster::HoughTransform::GetEquation(), cluster::HoughTransform::GetMax(), hits(), cluster::HoughTransform::Init(), LOG_DEBUG, geo::GeometryCore::Nwires(), and detinfo::DetectorProperties::ReadOutWindowSize().

1877 {
1878  HoughTransform c;
1879 
1881  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
1882 
1883  int dx = geom->Nwires(0); //number of wires
1884  const int dy = detprop->ReadOutWindowSize(); // number of time samples.
1885 
1886  c.Init(dx,dy,fRhoResolutionFactor,fNumAngleCells);
1887 
1888  for(unsigned int i=0;i < hits.size(); ++i){
1889  c.AddPointReturnMax(hits[i]->WireID().Wire, (int)(hits[i]->PeakTime()));
1890  }// end loop over hits
1891 
1892  //gets the actual two-dimensional size of the accumulator
1893  int accDx = 0;
1894  int accDy = 0;
1895  c.GetAccumSize(accDy, accDx);
1896 
1897  //find the weightiest cell in the accumulator.
1898  int xMax = 0;
1899  int yMax = 0;
1900  c.GetMax(yMax,xMax);
1901 
1902  //find the center of mass of the 3x3 cell system (with maxCell at the center).
1903  float centerofmassx = 0.;
1904  float centerofmassy = 0.;
1905  float denom = 0.;
1906 
1907  if(xMax > 0 && yMax > 0 && xMax+1 < accDx && yMax+1 < accDy){
1908  for(int i = -1; i < 2; ++i){
1909  for(int j = -1; j < 2; ++j){
1910  denom += c.GetCell(yMax+i,xMax+j);
1911  centerofmassx += j*c.GetCell(yMax+i,xMax+j);
1912  centerofmassy += i*c.GetCell(yMax+i,xMax+j);
1913  }
1914  }
1915  centerofmassx /= denom;
1916  centerofmassy /= denom;
1917  }
1918  else centerofmassx = centerofmassy = 0;
1919 
1920  float rho = 0.;
1921  float theta = 0.;
1922  c.GetEquation(yMax+centerofmassy, xMax+centerofmassx, rho, theta);
1923  LOG_DEBUG("HoughBaseAlg")
1924  << "Transform(III) found maximum at (d=" << rho << " a=" << theta << ")"
1925  " from absolute maximum " << c.GetCell(yMax,xMax)
1926  << " at (d=" << yMax << ", a=" << xMax << ")";
1927  slope = -1./tan(theta);
1928  intercept = rho/sin(theta);
1929 
1932 
1933  return hits.size();
1934 }
virtual unsigned int ReadOutWindowSize() const =0
float fRhoResolutionFactor
Factor determining the resolution in rho.
Definition: HoughBaseAlg.h:625
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
#define LOG_DEBUG(id)

Friends And Related Function Documentation

friend class HoughTransformClus
friend

Definition at line 635 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 621 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

int cluster::HoughBaseAlg::fMaxLines
private

Max number of lines that can be found.

Definition at line 613 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

float cluster::HoughBaseAlg::fMaxSlope
private

Max slope a line can have.

Definition at line 622 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

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 614 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

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 628 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

float cluster::HoughBaseAlg::fMissedHitsDistance
private

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

Definition at line 630 of file HoughBaseAlg.h.

Referenced by FastTransform(), and reconfigure().

float cluster::HoughBaseAlg::fMissedHitsToLineSize
private

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

Definition at line 631 of file HoughBaseAlg.h.

Referenced by FastTransform(), and reconfigure().

int cluster::HoughBaseAlg::fNumAngleCells
private

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 that fall into the "correct" bin will be small and consistent with noise.

Definition at line 617 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

int cluster::HoughBaseAlg::fPerCluster
private

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

Definition at line 626 of file HoughBaseAlg.h.

Referenced by FastTransform(), and reconfigure().

float cluster::HoughBaseAlg::fRhoResolutionFactor
private

Factor determining the resolution in rho.

Definition at line 625 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

int cluster::HoughBaseAlg::fRhoZeroOutRange
private

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

Definition at line 623 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

int cluster::HoughBaseAlg::fSaveAccumulator
private

Save bitmap image of accumulator for debugging?

Definition at line 616 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().

int cluster::HoughBaseAlg::fThetaZeroOutRange
private

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

Definition at line 624 of file HoughBaseAlg.h.

Referenced by FastTransform(), reconfigure(), and Transform().


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