31 #include "CLHEP/Random/RandFlat.h" 32 #include <TStopwatch.h> 56 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 57 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 61 constexpr
double PI = M_PI;
65 #define a2 -2.652905e-4f 67 #define a4 -1.964532e-3f 68 #define a5 1.02575e-2f 69 #define a6 -9.580378e-4f 71 #define _sin(x) ((((((a6 * (x) + a5) * (x) + a4) * (x) + a3) * (x) + a2) * (x) + a1) * (x) + a0) 72 #define _cos(x) _sin(TMath::Pi() * 0.5 - (x)) 77 void Init(
unsigned int dx,
unsigned int dy,
float rhores,
unsigned int numACells);
88 void GetEquation(
float row,
float col,
float& rho,
float& theta)
const;
89 int GetMax(
int& xmax,
int& ymax)
const;
118 template <
typename T>
125 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
129 unchecked_add_range_max(key_begin, key_end, +1, std::numeric_limits<SubCounter_t>::max());
132 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
136 unchecked_add_range_max(key_begin, key_end, -1, std::numeric_limits<SubCounter_t>::max());
139 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
143 PairValue_t max{Base_t::make_const_iterator(Base_t::counter_map.
end(), 0), current_max};
146 cend = Base_t::counter_map.end();
147 while (iCBlock !=
cend) {
149 for (
size_t index = 0; index < block.size(); ++index) {
150 if (block[index] > max.second)
151 max = {Base_t::make_const_iterator(iCBlock, index), block[index]};
158 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
162 return get_max(std::numeric_limits<SubCounter_t>::max());
165 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
173 if (key_begin > key_end)
return value;
175 size_t left = key_end - key_begin;
177 if ((iIP == Base_t::counter_map.
end()) || (iIP->first != key.block)) {
179 iIP = Base_t::counter_map.insert(iIP, {key.block, {}});
182 size_t n = std::min(left, Base_t::NCounters - key.counter);
183 block.fill(key.counter, n, value);
184 if (left -= n <= 0)
break;
191 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
197 return unchecked_set_range(
198 key_begin, key_end, value, Base_t::counter_map.lower_bound(
CounterKey_t(key_begin).block));
201 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
211 PairValue_t max{Base_t::make_const_iterator(Base_t::counter_map.
end(), 0), min_max};
212 if (key_begin > key_end)
return max;
214 size_t left = key_end - key_begin;
216 if ((iIP == Base_t::counter_map.
end()) || (iIP->first != key.block)) {
218 iIP = Base_t::counter_map.insert(iIP, {key.block, {}});
221 size_t n = std::min(left, Base_t::NCounters - key.counter);
225 if (value > max.second) { max = {Base_t::make_const_iterator(iIP, key.counter), value}; }
228 if (left <= 0)
break;
235 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
244 return unchecked_add_range_max(key_begin,
247 Base_t::counter_map.lower_bound(
CounterKey_t(key_begin).block),
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");
274 CLHEP::HepRandomEngine& engine,
275 std::vector<unsigned int>* fpointId_to_clusterId,
276 unsigned int clusterId,
277 unsigned int* nClusters,
278 std::vector<protoTrack>* linesFound)
280 int nClustersTemp = *nClusters;
282 lariov::ChannelStatusProvider
const* channelStatus =
283 lar::providerFrom<lariov::ChannelStatusService>();
285 unsigned int wire = 0;
286 unsigned int wireMax = 0;
292 std::vector<int> skip;
294 auto const num_planes = wireReadoutGeom.Nplanes(wireid.
asPlaneID().
asTPCID());
295 std::vector<double> wire_pitch(num_planes, 0.);
297 auto const p = plane.ID().Plane;
298 wire_pitch[p] = plane.WirePitch();
302 std::vector<double> xyScale(num_planes, 0.);
307 for (
size_t p = 0; p < xyScale.size(); ++p)
308 xyScale[p] = driftVelFactor *
sampling_rate(clockData) / wire_pitch[p];
310 float tickToDist = driftVelFactor *
sampling_rate(clockData);
314 const int dx = wireReadoutGeom.Plane(wireid.
asPlaneID()).Nwires();
317 skip.resize(
hits.size());
318 std::vector<int> listofxmax;
319 std::vector<int> listofymax;
320 std::vector<int> hitsTemp;
321 std::vector<int> sequenceHolder;
322 std::vector<int> channelHolder;
323 std::vector<int> currentHits;
324 std::vector<int> lastHits;
325 std::vector<art::Ptr<recob::Hit>> clusterHits;
326 float indcolscaling = 0.;
335 float centerofmassx = 0;
336 float centerofmassy = 0;
338 float intercept = 0.;
350 int accDx(0), accDy(0);
354 unsigned int fMaxWire = 0;
356 unsigned int fMinWire = 99999999;
374 mf::LogInfo(
"HoughBaseAlg") <<
"dealing with " <<
hits.size() <<
" hits";
380 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
389 unsigned int nLinesFound = 0;
390 std::vector<unsigned int> accumPoints(
hits.size(), 0);
395 for (
auto fpointId_to_clusterIdItr = fpointId_to_clusterId->begin();
396 fpointId_to_clusterIdItr != fpointId_to_clusterId->end();
397 fpointId_to_clusterIdItr++)
398 if (*fpointId_to_clusterIdItr == clusterId) count++;
400 unsigned int randInd;
402 CLHEP::RandFlat flat(engine);
409 randInd = (
unsigned int)(flat.fire() *
hits.size());
412 if (fpointId_to_clusterId->at(randInd) != clusterId)
continue;
417 if (skip[randInd] == 1) {
continue; }
420 if (accumPoints[randInd])
continue;
421 accumPoints[randInd] = 1;
424 for (
auto listofxmaxItr = listofxmax.begin(); listofxmaxItr != listofxmax.end();
426 yClearStart = listofymax[listofxmaxItr - listofxmax.begin()] - fRhoZeroOutRange;
427 if (yClearStart < 0) yClearStart = 0;
429 yClearEnd = listofymax[listofxmaxItr - listofxmax.begin()] + fRhoZeroOutRange;
430 if (yClearEnd >= accDy) yClearEnd = accDy - 1;
432 xClearStart = *listofxmaxItr - fThetaZeroOutRange;
433 if (xClearStart < 0) xClearStart = 0;
435 xClearEnd = *listofxmaxItr + fThetaZeroOutRange;
436 if (xClearEnd >= accDx) xClearEnd = accDx - 1;
438 for (y = yClearStart; y <= yClearEnd; ++
y) {
439 for (x = xClearStart; x <= xClearEnd; ++
x) {
446 uint32_t channel =
hits[randInd]->Channel();
447 wireMax =
hits[randInd]->WireID().Wire;
457 double binomProbSum = TMath::BinomialI(1 / (
double)accDx, nAccum, maxCell);
458 if (binomProbSum > 1
e-21)
continue;
462 denom = centerofmassx = centerofmassy = 0;
464 if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
465 for (
int i = -1; i < 2; ++i) {
466 for (
int j = -1; j < 2; ++j) {
467 denom += c.
GetCell(yMax + i, xMax + j);
468 centerofmassx += j * c.
GetCell(yMax + i, xMax + j);
469 centerofmassy += i * c.
GetCell(yMax + i, xMax + j);
472 centerofmassx /= denom;
473 centerofmassy /= denom;
476 centerofmassx = centerofmassy = 0;
479 listofxmax.push_back(xMax);
480 listofymax.push_back(yMax);
483 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
484 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(II) found maximum at (d=" << rho <<
" a=" << theta
486 " from absolute maximum " 487 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
489 slope = -1. / tan(theta);
490 intercept = (rho / sin(theta));
493 if (!std::isinf(slope) && !std::isnan(slope)) {
494 channelHolder.clear();
495 sequenceHolder.clear();
501 for (
auto hitsItr =
hits.cbegin(); hitsItr !=
hits.cend(); ++hitsItr) {
502 wire = (*hitsItr)->WireID().Wire;
503 if (fpointId_to_clusterId->at(hitsItr -
hits.begin()) != clusterId)
continue;
504 channel = (*hitsItr)->Channel();
505 distance = (
std::abs((*hitsItr)->PeakTime() - slope * (float)((*hitsItr)->WireID().Wire) -
507 (std::sqrt(
sqr(xyScale[(*hitsItr)->WireID().Plane] * slope) + 1.)));
508 if (distance < fMaxDistance + (*hitsItr)->RMS() + indcolscaling &&
509 skip[hitsItr -
hits.begin()] != 1) {
510 hitsTemp.push_back(hitsItr -
hits.begin());
511 sequenceHolder.push_back(wire);
512 channelHolder.push_back(channel);
516 if (hitsTemp.size() < 5)
continue;
520 currentHits.push_back(0);
521 for (
auto sequenceHolderItr = sequenceHolder.begin();
522 sequenceHolderItr + 1 != sequenceHolder.end();
523 ++sequenceHolderItr) {
525 while (channelStatus->IsBad(sequenceHolderItr - sequenceHolder.begin() + j))
527 if (sequenceHolder[sequenceHolderItr - sequenceHolder.begin() + 1] -
528 sequenceHolder[sequenceHolderItr - sequenceHolder.begin()] <=
530 currentHits.push_back(sequenceHolderItr - sequenceHolder.begin() + 1);
531 else if (currentHits.size() > lastHits.size()) {
532 lastHits = currentHits;
538 if (currentHits.size() > lastHits.size()) lastHits = currentHits;
542 if (lastHits.size() < (
unsigned int)fMinHits)
continue;
544 if (
std::abs(slope) > fMaxSlope) {
continue; }
548 std::vector<art::Ptr<recob::Hit>> lineHits;
550 for (
auto lastHitsItr = lastHits.begin(); lastHitsItr != lastHits.end(); ++lastHitsItr) {
551 fpointId_to_clusterId->at(hitsTemp[(*lastHitsItr)]) = nClustersTemp - 1;
552 totalQ +=
hits[hitsTemp[(*lastHitsItr)]]->Integral();
553 wire =
hits[hitsTemp[(*lastHitsItr)]]->WireID().Wire;
555 if (!accumPoints[hitsTemp[(*lastHitsItr)]]) count--;
557 skip[hitsTemp[(*lastHitsItr)]] = 1;
559 lineHits.push_back(
hits[hitsTemp[(*lastHitsItr)]]);
562 if (accumPoints[hitsTemp[(*lastHitsItr)]])
565 if (wire < fMinWire) {
567 iMinWire = hitsTemp[(*lastHitsItr)];
569 if (wire > fMaxWire) {
571 iMaxWire = hitsTemp[(*lastHitsItr)];
574 int pnum =
hits[iMinWire]->WireID().Plane;
575 pCornerMin[0] = (
hits[iMinWire]->WireID().Wire) * wire_pitch[pnum];
576 pCornerMin[1] =
hits[iMinWire]->PeakTime() * tickToDist;
577 pCornerMax[0] = (
hits[iMaxWire]->WireID().Wire) * wire_pitch[pnum];
578 pCornerMax[1] =
hits[iMaxWire]->PeakTime() * tickToDist;
580 protoTrackToLoad.
Init(nClustersTemp - 1,
594 linesFound->push_back(protoTrackToLoad);
600 if (nLinesFound > (
unsigned int)fMaxLines)
break;
611 if (fSaveAccumulator) {
612 unsigned char* outPix =
new unsigned char[accDx * accDy];
614 int cell, pix = 0, maxCell = 0;
615 for (
int y = 0; y < accDy; ++
y) {
616 for (
int x = 0; x < accDx; ++
x) {
618 if (cell > maxCell) maxCell = cell;
621 for (
int y = 0; y < accDy; ++
y) {
622 for (
int x = 0; x < accDx; ++
x) {
624 if (maxCell > 0) pix = (int)((1500 * c.
GetCell(y, x)) / maxCell);
625 outPix[y * accDx +
x] = pix;
629 HLSSaveBMPFile(
"houghaccum.bmp", outPix, accDx, accDy);
633 *nClusters = nClustersTemp;
649 if ((x > (
int)
m_dx) || (y > (
int)
m_dy) || x < 0.0 || y < 0.0) {
650 std::array<int, 3> max;
660 if ((x > (
int)
m_dx) || (y > (
int)
m_dy) || x < 0.0 || y < 0.0)
return false;
669 unsigned int numACells)
689 <std::pair<const DistancesMap_t::Key_t, DistancesMap_t::CounterBlock_t>>
706 for (
size_t iAngleStep = 0; iAngleStep <
m_numAngleCells; ++iAngleStep) {
707 double a = iAngleStep * angleStep;
724 for (
unsigned int i = 0; i <
m_accum.size(); i++) {
727 if (max_counter.second > maxVal) {
728 maxVal = max_counter.second;
730 ymax = max_counter.first.key();
744 std::array<int, 3> max;
760 for (
size_t iAngleStep = 1; iAngleStep <
m_numAngleCells; ++iAngleStep) {
790 if (lastDist == dist) {
797 first_dist = dist > lastDist ? lastDist : dist + 1;
798 end_dist = dist > lastDist ? dist : lastDist + 1;
802 if (bSubtract) { distMap.
decrement(first_dist, end_dist); }
807 if (max_counter.second > max_val) {
812 max = {{max_counter.second, max_counter.first.key(), (int)iAngleStep}};
813 max_val = max_counter.second;
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;
841 bmpFile.write((
const char*)&size, 4);
843 bmpFile.write((
const char*)&reserved, 4);
844 bmpFile.write((
const char*)&bitsOffset, 4);
846 bmpFile.write((
const char*)&bmiSize, 4);
847 bmpFile.write((
const char*)&dx, 4);
848 bmpFile.write((
const char*)&dy, 4);
850 bmpFile.write((
const char*)&planes, 2);
852 bmpFile.write((
const char*)&bitCount, 2);
854 for (i = 0; i < 6; i++)
855 bmpFile.write((
const char*)&temp, 4);
859 for (i = 0; i < 256; i++) {
860 lutEntry[0] = lutEntry[1] = lutEntry[2] = i;
861 bmpFile.write(lutEntry,
sizeof lutEntry);
864 bmpFile.write((
const char*)pix, dx * dy);
869 std::vector<recob::Cluster>& ccol,
871 CLHEP::HepRandomEngine& engine,
873 std::string
const& label)
875 std::vector<int> skip;
893 std::vector<art::Ptr<recob::Hit>>
hit;
895 for (
auto view : wireReadoutGeom.Views()) {
897 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Analyzing view " << view;
903 while (clusterIter != clusIn.
end()) {
906 <<
"Analyzing cinctr=" << cinctr <<
" which is in view " << (*clusterIter)->View();
910 if ((*clusterIter)->View() == view) hit = fmh.at(cinctr);
913 while (clusterIter != clusIn.
end()) {
914 if ((*clusterIter)->View() == view) {
916 hit = fmh.at(cinctr);
922 if (hit.size() == 0) {
930 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"We have all the hits..." << hit.size();
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);
937 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Made it through FastTransform" << planeClusHitsOut.size();
939 for (
size_t xx = 0;
xx < planeClusHitsOut.size(); ++
xx) {
940 auto const&
hits = planeClusHitsOut.at(
xx);
944 const unsigned int ew = LastHit.
WireID().
Wire;
953 ccol.emplace_back(
float(sw),
957 ClusterParamAlgo.StartCharge(gser).value(),
958 ClusterParamAlgo.StartAngle().value(),
959 ClusterParamAlgo.StartOpeningAngle().value(),
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),
980 clusHitsOut.push_back(planeClusHitsOut.at(
xx));
984 if (clusterIter != clusIn.
end()) {
1002 CLHEP::HepRandomEngine& engine)
1004 std::vector<double> slopevec;
1005 std::vector<ChargeInfo_t> totalQvec;
1006 return FastTransform(clockData, detProp, clusIn, clusHitsOut, engine, slopevec, totalQvec);
1014 CLHEP::HepRandomEngine& engine,
1015 std::vector<double>& slopevec,
1016 std::vector<ChargeInfo_t>& totalQvec)
1018 std::vector<int> skip;
1021 lariov::ChannelStatusProvider
const* channelStatus =
1022 lar::providerFrom<lariov::ChannelStatusService>();
1024 CLHEP::RandFlat flat(engine);
1026 std::vector<art::Ptr<recob::Hit>>
hit;
1032 hit.push_back((*ii));
1034 if (hit.size() == 0) {
1035 if (fPerCluster) { ++cinctr; }
1044 if (hit.size() == 0) {
1045 if (fPerCluster) { ++cinctr; }
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();
1057 std::vector<double> xyScale(num_planes, 0.);
1062 for (
size_t p = 0; p < xyScale.size(); ++p)
1063 xyScale[p] = driftVelFactor *
sampling_rate(clockData) / wire_pitch[p];
1066 int dx = wireReadoutGeom.Plane(wireid.
asPlaneID()).Nwires();
1069 skip.resize(hit.size());
1070 std::vector<int> listofxmax;
1071 std::vector<int> listofymax;
1072 std::vector<int> hitTemp;
1073 std::vector<int> sequenceHolder;
1074 std::vector<int> currentHits;
1075 std::vector<int> lastHits;
1077 float indcolscaling = 0.;
1079 float centerofmassx = 0;
1080 float centerofmassy = 0;
1082 float intercept = 0.;
1089 int accDx(0), accDy(0);
1095 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1098 unsigned int count = hit.size();
1099 std::vector<unsigned int> accumPoints;
1100 accumPoints.resize(hit.size());
1102 unsigned int nLinesFound = 0;
1104 for (; count > 0; count--) {
1107 unsigned int randInd = (
unsigned int)(flat.fire() * hit.size());
1109 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"randInd=" << randInd <<
" and size is " << hit.size();
1112 if (skip.at(randInd) == 1)
continue;
1115 if (accumPoints.at(randInd))
continue;
1116 accumPoints.at(randInd) = 1;
1119 for (
unsigned int i = 0; i < listofxmax.size(); ++i) {
1120 int yClearStart = listofymax.at(i) - fRhoZeroOutRange;
1121 if (yClearStart < 0) yClearStart = 0;
1123 int yClearEnd = listofymax.at(i) + fRhoZeroOutRange;
1124 if (yClearEnd >= accDy) yClearEnd = accDy - 1;
1126 int xClearStart = listofxmax.at(i) - fThetaZeroOutRange;
1127 if (xClearStart < 0) xClearStart = 0;
1129 int xClearEnd = listofxmax.at(i) + fThetaZeroOutRange;
1130 if (xClearEnd >= accDx) xClearEnd = accDx - 1;
1132 for (
y = yClearStart;
y <= yClearEnd; ++
y) {
1133 for (x = xClearStart; x <= xClearEnd; ++
x) {
1141 unsigned int wireMax = hit.at(randInd)->WireID().Wire;
1144 std::array<int, 3> max = c.
AddPointReturnMax(wireMax, (
int)(hit.at(randInd)->PeakTime()));
1145 maxCell = max.at(0);
1151 if (maxCell < fMinHits)
continue;
1154 denom = centerofmassx = centerofmassy = 0;
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);
1161 centerofmassx += j * cell;
1162 centerofmassy += i * cell;
1165 centerofmassx /= denom;
1166 centerofmassy /= denom;
1169 centerofmassx = centerofmassy = 0;
1172 listofxmax.push_back(xMax);
1173 listofymax.push_back(yMax);
1176 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1177 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(I) found maximum at (d=" << rho <<
" a=" << theta
1179 " from absolute maximum " 1180 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
1182 slope = -1. / tan(theta);
1183 intercept = (rho / sin(theta));
1194 if (!std::isinf(slope) && !std::isnan(slope)) {
1195 sequenceHolder.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) -
1200 (std::sqrt(pow(xyScale[hit.at(i)->WireID().Plane] * slope, 2) + 1)));
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());
1209 if (hitTemp.size() < 2)
continue;
1210 currentHits.clear();
1213 currentHits.push_back(0);
1214 for (
size_t i = 0; i + 1 < sequenceHolder.size(); ++i) {
1216 while ((channelStatus->IsBad(sequenceHolder.at(i) + j)) ==
true)
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();
1225 currentHits.clear();
1228 if (currentHits.size() > lastHits.size()) lastHits = currentHits;
1239 int lastHitsChannel = 0;
1240 int nHitsPerChannel = 1;
1242 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"filling the pCorner arrays around here..." 1243 <<
"\n but first, lastHits size is " << lastHits.size()
1244 <<
" and lastHitsChannel=" << lastHitsChannel;
1248 unsigned int lastChannel = hit.at(hitTemp.at(lastHits.at(0)))->Channel();
1250 for (
size_t i = 0; i < lastHits.size() - 1; ++i) {
1251 bool newChannel =
false;
1253 if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() != lastChannel) {
1256 if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() == lastChannel) nHitsPerChannel++;
1262 if (slope > 0 || (!newChannel && nHitsPerChannel <= 1)) {
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)) >
1269 fMissedHitsDistance)
1273 else if (slope < 0 && newChannel && nHitsPerChannel > 1) {
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)) >
1281 fMissedHitsDistance)
1283 lastChannel = hit.at(hitTemp.at(lastHits.at(i)))->Channel();
1284 lastHitsChannel = i + 1;
1285 nHitsPerChannel = 0;
1289 if ((
double)missedHits / ((
double)lastHits.size() - 1) > fMissedHitsToLineSize)
continue;
1291 clusterHits.
clear();
1292 if (lastHits.size() < 5)
continue;
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;
1304 if (
std::abs(slope) > fMaxSlope)
continue;
1306 clusHitsOut.push_back(clusterHits);
1307 slopevec.push_back(slope);
1308 totalQvec.emplace_back(integralQ.
Sum(),
1318 if (nLinesFound > (
unsigned int)fMaxLines)
break;
1324 if (fSaveAccumulator) {
1326 int cell, pix = 0, maxCell = 0;
1327 for (
y = 0;
y < accDy; ++
y) {
1328 for (x = 0; x < accDx; ++
x) {
1330 if (cell > maxCell) maxCell = cell;
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) {
1339 if (maxCell > 0) pix = (int)((1500 * c.
GetCell(
y, x)) / maxCell);
1340 outPix[PicIndex++] = pix;
1344 HLSSaveBMPFile(
"houghaccum.bmp", outPix.get(), accDx, accDy);
1351 return clusHitsOut.size();
1364 int dx = wireReadoutGeom.Nwires(
geo::PlaneID{0, 0, 0});
1367 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1369 for (
unsigned int i = 0; i <
hits.size(); ++i) {
1384 float centerofmassx = 0.;
1385 float centerofmassy = 0.;
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);
1396 centerofmassx /= denom;
1397 centerofmassy /= denom;
1400 centerofmassx = centerofmassy = 0;
1404 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1405 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(III) found maximum at (d=" << rho <<
" a=" << theta
1407 " from absolute maximum " 1408 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
1410 slope = -1. / tan(theta);
1411 intercept = rho / sin(theta);
Utilities related to art service access.
typename Traits_t::CounterBlock_t CounterBlock_t
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Encapsulate the construction of a single cyostat .
KEY Key_t
type of counter key in the map
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
The data type to uniquely identify a Plane.
double Temperature() const
In kelvin.
constexpr auto abs(T v)
Returns the absolute value of the argument.
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)
unsigned int ReadOutWindowSize() const
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
geo::View_t View() const
View for the plane of the hit.
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
Cluster finding and building.
Classes gathering simple statistics.
Weight_t RMS() const
Returns the root mean square.
static const SentryArgument_t Sentry
An instance of the sentry object.
void ImportHits(util::GeometryUtilities const &gser, Iter begin, Iter end)
Calls SetHits() with the hits in the sequence.
double Efield(unsigned int planegap=0) const
kV/cm
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
typename data_t::const_iterator const_iterator
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
void push_back(Ptr< U > const &p)
Signal from induction planes.
Weight_t Sum() const
Returns the weighted sum of the values.
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
T get(std::string const &key) const
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Aggressive allocator reserving a lot of memory in advance.
unsigned int NumberTimeSamples() const
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
The data type to uniquely identify a TPC.
Description of the physical geometry of one entire detector.
Declaration of cluster object.
Detector simulation of raw signals on wires.
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
float PeakTime() const
Time of the signal peak, in tick units.
Encapsulate the construction of a single detector plane .
double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Contains all timing reference information for the detector.
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 >>())
HoughBaseAlg(fhicl::ParameterSet const &pset)
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
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)
2D representation of charge deposited in the TDC/wire plane
constexpr PlaneID const & planeID() const
Counter_t SubCounter_t
Type of the subcounter (that is, the actual counter)
Interface to class computing cluster parameters.
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
Collects statistics on a single quantity (weighted)
art framework interface to geometry description
constexpr TPCID const & asTPCID() const
Conversion to PlaneID (for convenience of notation).
Encapsulate the construction of a single detector plane .
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).