31 #include "CLHEP/Random/RandFlat.h" 32 #include <TStopwatch.h> 55 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 56 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 60 constexpr
double PI = M_PI;
64 #define a2 -2.652905e-4f 66 #define a4 -1.964532e-3f 67 #define a5 1.02575e-2f 68 #define a6 -9.580378e-4f 70 #define _sin(x) ((((((a6 * (x) + a5) * (x) + a4) * (x) + a3) * (x) + a2) * (x) + a1) * (x) + a0) 71 #define _cos(x) _sin(TMath::Pi() * 0.5 - (x)) 76 void Init(
unsigned int dx,
unsigned int dy,
float rhores,
unsigned int numACells);
87 void GetEquation(
float row,
float col,
float& rho,
float& theta)
const;
88 int GetMax(
int& xmax,
int& ymax)
const;
117 template <
typename T>
124 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
128 unchecked_add_range_max(key_begin, key_end, +1, std::numeric_limits<SubCounter_t>::max());
131 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
135 unchecked_add_range_max(key_begin, key_end, -1, std::numeric_limits<SubCounter_t>::max());
138 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
142 PairValue_t max{Base_t::make_const_iterator(Base_t::counter_map.
end(), 0), current_max};
145 cend = Base_t::counter_map.end();
146 while (iCBlock !=
cend) {
148 for (
size_t index = 0; index < block.size(); ++index) {
149 if (block[index] > max.second)
150 max = {Base_t::make_const_iterator(iCBlock, index), block[index]};
157 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
161 return get_max(std::numeric_limits<SubCounter_t>::max());
164 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
172 if (key_begin > key_end)
return value;
174 size_t left = key_end - key_begin;
176 if ((iIP == Base_t::counter_map.
end()) || (iIP->first != key.block)) {
178 iIP = Base_t::counter_map.insert(iIP, {key.block, {}});
181 size_t n = std::min(left, Base_t::NCounters - key.counter);
182 block.fill(key.counter, n, value);
183 if (left -= n <= 0)
break;
190 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
196 return unchecked_set_range(
197 key_begin, key_end, value, Base_t::counter_map.lower_bound(
CounterKey_t(key_begin).block));
200 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
210 PairValue_t max{Base_t::make_const_iterator(Base_t::counter_map.
end(), 0), min_max};
211 if (key_begin > key_end)
return max;
213 size_t left = key_end - key_begin;
215 if ((iIP == Base_t::counter_map.
end()) || (iIP->first != key.block)) {
217 iIP = Base_t::counter_map.insert(iIP, {key.block, {}});
220 size_t n = std::min(left, Base_t::NCounters - key.counter);
224 if (value > max.second) { max = {Base_t::make_const_iterator(iIP, key.counter), value}; }
227 if (left <= 0)
break;
234 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SC>
243 return unchecked_add_range_max(key_begin,
246 Base_t::counter_map.lower_bound(
CounterKey_t(key_begin).block),
253 fMaxLines = pset.
get<
int>(
"MaxLines");
254 fMinHits = pset.
get<
int>(
"MinHits");
255 fSaveAccumulator = pset.
get<
int>(
"SaveAccumulator");
256 fNumAngleCells = pset.
get<
int>(
"NumAngleCells");
257 fMaxDistance = pset.
get<
float>(
"MaxDistance");
258 fMaxSlope = pset.
get<
float>(
"MaxSlope");
259 fRhoZeroOutRange = pset.
get<
int>(
"RhoZeroOutRange");
260 fThetaZeroOutRange = pset.
get<
int>(
"ThetaZeroOutRange");
261 fRhoResolutionFactor = pset.
get<
float>(
"RhoResolutionFactor");
262 fPerCluster = pset.
get<
int>(
"HitsPerCluster");
263 fMissedHits = pset.
get<
int>(
"MissedHits");
264 fMissedHitsDistance = pset.
get<
float>(
"MissedHitsDistance");
265 fMissedHitsToLineSize = pset.
get<
float>(
"MissedHitsToLineSize");
273 CLHEP::HepRandomEngine& engine,
274 std::vector<unsigned int>* fpointId_to_clusterId,
275 unsigned int clusterId,
276 unsigned int* nClusters,
277 std::vector<protoTrack>* linesFound)
279 int nClustersTemp = *nClusters;
282 lariov::ChannelStatusProvider
const* channelStatus =
283 lar::providerFrom<lariov::ChannelStatusService>();
285 unsigned int wire = 0;
286 unsigned int wireMax = 0;
290 std::vector<int> skip;
293 std::vector<double> wire_pitch(num_planes, 0.);
295 auto const p = plane.ID().Plane;
296 wire_pitch[p] = plane.WirePitch();
300 std::vector<double> xyScale(num_planes, 0.);
305 for (
size_t p = 0; p < xyScale.size(); ++p)
306 xyScale[p] = driftVelFactor *
sampling_rate(clockData) / wire_pitch[p];
308 float tickToDist = driftVelFactor *
sampling_rate(clockData);
315 skip.resize(
hits.size());
316 std::vector<int> listofxmax;
317 std::vector<int> listofymax;
318 std::vector<int> hitsTemp;
319 std::vector<int> sequenceHolder;
320 std::vector<int> channelHolder;
321 std::vector<int> currentHits;
322 std::vector<int> lastHits;
323 std::vector<art::Ptr<recob::Hit>> clusterHits;
324 float indcolscaling = 0.;
333 float centerofmassx = 0;
334 float centerofmassy = 0;
336 float intercept = 0.;
348 int accDx(0), accDy(0);
352 unsigned int fMaxWire = 0;
354 unsigned int fMinWire = 99999999;
372 mf::LogInfo(
"HoughBaseAlg") <<
"dealing with " <<
hits.size() <<
" hits";
378 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
387 unsigned int nLinesFound = 0;
388 std::vector<unsigned int> accumPoints(
hits.size(), 0);
393 for (
auto fpointId_to_clusterIdItr = fpointId_to_clusterId->begin();
394 fpointId_to_clusterIdItr != fpointId_to_clusterId->end();
395 fpointId_to_clusterIdItr++)
396 if (*fpointId_to_clusterIdItr == clusterId) count++;
398 unsigned int randInd;
400 CLHEP::RandFlat flat(engine);
407 randInd = (
unsigned int)(flat.fire() *
hits.size());
410 if (fpointId_to_clusterId->at(randInd) != clusterId)
continue;
415 if (skip[randInd] == 1) {
continue; }
418 if (accumPoints[randInd])
continue;
419 accumPoints[randInd] = 1;
422 for (
auto listofxmaxItr = listofxmax.begin(); listofxmaxItr != listofxmax.end();
424 yClearStart = listofymax[listofxmaxItr - listofxmax.begin()] - fRhoZeroOutRange;
425 if (yClearStart < 0) yClearStart = 0;
427 yClearEnd = listofymax[listofxmaxItr - listofxmax.begin()] + fRhoZeroOutRange;
428 if (yClearEnd >= accDy) yClearEnd = accDy - 1;
430 xClearStart = *listofxmaxItr - fThetaZeroOutRange;
431 if (xClearStart < 0) xClearStart = 0;
433 xClearEnd = *listofxmaxItr + fThetaZeroOutRange;
434 if (xClearEnd >= accDx) xClearEnd = accDx - 1;
436 for (y = yClearStart; y <= yClearEnd; ++
y) {
437 for (x = xClearStart; x <= xClearEnd; ++
x) {
444 uint32_t channel =
hits[randInd]->Channel();
445 wireMax =
hits[randInd]->WireID().Wire;
455 double binomProbSum = TMath::BinomialI(1 / (
double)accDx, nAccum, maxCell);
456 if (binomProbSum > 1
e-21)
continue;
460 denom = centerofmassx = centerofmassy = 0;
462 if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
463 for (
int i = -1; i < 2; ++i) {
464 for (
int j = -1; j < 2; ++j) {
465 denom += c.
GetCell(yMax + i, xMax + j);
466 centerofmassx += j * c.
GetCell(yMax + i, xMax + j);
467 centerofmassy += i * c.
GetCell(yMax + i, xMax + j);
470 centerofmassx /= denom;
471 centerofmassy /= denom;
474 centerofmassx = centerofmassy = 0;
477 listofxmax.push_back(xMax);
478 listofymax.push_back(yMax);
481 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
482 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(II) found maximum at (d=" << rho <<
" a=" << theta
484 " from absolute maximum " 485 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
487 slope = -1. / tan(theta);
488 intercept = (rho / sin(theta));
491 if (!std::isinf(slope) && !std::isnan(slope)) {
492 channelHolder.clear();
493 sequenceHolder.clear();
499 for (
auto hitsItr =
hits.cbegin(); hitsItr !=
hits.cend(); ++hitsItr) {
500 wire = (*hitsItr)->WireID().Wire;
501 if (fpointId_to_clusterId->at(hitsItr -
hits.begin()) != clusterId)
continue;
502 channel = (*hitsItr)->Channel();
503 distance = (
std::abs((*hitsItr)->PeakTime() - slope * (float)((*hitsItr)->WireID().Wire) -
505 (std::sqrt(
sqr(xyScale[(*hitsItr)->WireID().Plane] * slope) + 1.)));
506 if (distance < fMaxDistance + (*hitsItr)->RMS() + indcolscaling &&
507 skip[hitsItr -
hits.begin()] != 1) {
508 hitsTemp.push_back(hitsItr -
hits.begin());
509 sequenceHolder.push_back(wire);
510 channelHolder.push_back(channel);
514 if (hitsTemp.size() < 5)
continue;
518 currentHits.push_back(0);
519 for (
auto sequenceHolderItr = sequenceHolder.begin();
520 sequenceHolderItr + 1 != sequenceHolder.end();
521 ++sequenceHolderItr) {
523 while (channelStatus->IsBad(sequenceHolderItr - sequenceHolder.begin() + j))
525 if (sequenceHolder[sequenceHolderItr - sequenceHolder.begin() + 1] -
526 sequenceHolder[sequenceHolderItr - sequenceHolder.begin()] <=
528 currentHits.push_back(sequenceHolderItr - sequenceHolder.begin() + 1);
529 else if (currentHits.size() > lastHits.size()) {
530 lastHits = currentHits;
536 if (currentHits.size() > lastHits.size()) lastHits = currentHits;
540 if (lastHits.size() < (
unsigned int)fMinHits)
continue;
542 if (
std::abs(slope) > fMaxSlope) {
continue; }
546 std::vector<art::Ptr<recob::Hit>> lineHits;
548 for (
auto lastHitsItr = lastHits.begin(); lastHitsItr != lastHits.end(); ++lastHitsItr) {
549 fpointId_to_clusterId->at(hitsTemp[(*lastHitsItr)]) = nClustersTemp - 1;
550 totalQ +=
hits[hitsTemp[(*lastHitsItr)]]->Integral();
551 wire =
hits[hitsTemp[(*lastHitsItr)]]->WireID().Wire;
553 if (!accumPoints[hitsTemp[(*lastHitsItr)]]) count--;
555 skip[hitsTemp[(*lastHitsItr)]] = 1;
557 lineHits.push_back(
hits[hitsTemp[(*lastHitsItr)]]);
560 if (accumPoints[hitsTemp[(*lastHitsItr)]])
563 if (wire < fMinWire) {
565 iMinWire = hitsTemp[(*lastHitsItr)];
567 if (wire > fMaxWire) {
569 iMaxWire = hitsTemp[(*lastHitsItr)];
572 int pnum =
hits[iMinWire]->WireID().Plane;
573 pCornerMin[0] = (
hits[iMinWire]->WireID().Wire) * wire_pitch[pnum];
574 pCornerMin[1] =
hits[iMinWire]->PeakTime() * tickToDist;
575 pCornerMax[0] = (
hits[iMaxWire]->WireID().Wire) * wire_pitch[pnum];
576 pCornerMax[1] =
hits[iMaxWire]->PeakTime() * tickToDist;
578 protoTrackToLoad.
Init(nClustersTemp - 1,
592 linesFound->push_back(protoTrackToLoad);
598 if (nLinesFound > (
unsigned int)fMaxLines)
break;
609 if (fSaveAccumulator) {
610 unsigned char* outPix =
new unsigned char[accDx * accDy];
612 int cell, pix = 0, maxCell = 0;
613 for (
int y = 0; y < accDy; ++
y) {
614 for (
int x = 0; x < accDx; ++
x) {
616 if (cell > maxCell) maxCell = cell;
619 for (
int y = 0; y < accDy; ++
y) {
620 for (
int x = 0; x < accDx; ++
x) {
622 if (maxCell > 0) pix = (int)((1500 * c.
GetCell(y, x)) / maxCell);
623 outPix[y * accDx +
x] = pix;
627 HLSSaveBMPFile(
"houghaccum.bmp", outPix, accDx, accDy);
631 *nClusters = nClustersTemp;
647 if ((x > (
int)
m_dx) || (y > (
int)
m_dy) || x < 0.0 || y < 0.0) {
648 std::array<int, 3> max;
658 if ((x > (
int)
m_dx) || (y > (
int)
m_dy) || x < 0.0 || y < 0.0)
return false;
667 unsigned int numACells)
687 <std::pair<const DistancesMap_t::Key_t, DistancesMap_t::CounterBlock_t>>
704 for (
size_t iAngleStep = 0; iAngleStep <
m_numAngleCells; ++iAngleStep) {
705 double a = iAngleStep * angleStep;
722 for (
unsigned int i = 0; i <
m_accum.size(); i++) {
725 if (max_counter.second > maxVal) {
726 maxVal = max_counter.second;
728 ymax = max_counter.first.key();
742 std::array<int, 3> max;
758 for (
size_t iAngleStep = 1; iAngleStep <
m_numAngleCells; ++iAngleStep) {
788 if (lastDist == dist) {
795 first_dist = dist > lastDist ? lastDist : dist + 1;
796 end_dist = dist > lastDist ? dist : lastDist + 1;
800 if (bSubtract) { distMap.
decrement(first_dist, end_dist); }
805 if (max_counter.second > max_val) {
810 max = {{max_counter.second, max_counter.first.key(), (int)iAngleStep}};
811 max_val = max_counter.second;
834 std::ofstream bmpFile(fileName, std::ios::binary);
835 bmpFile.write(
"B", 1);
836 bmpFile.write(
"M", 1);
837 int bitsOffset = 54 + 256 * 4;
838 int size = bitsOffset + dx * dy;
839 bmpFile.write((
const char*)&size, 4);
841 bmpFile.write((
const char*)&reserved, 4);
842 bmpFile.write((
const char*)&bitsOffset, 4);
844 bmpFile.write((
const char*)&bmiSize, 4);
845 bmpFile.write((
const char*)&dx, 4);
846 bmpFile.write((
const char*)&dy, 4);
848 bmpFile.write((
const char*)&planes, 2);
850 bmpFile.write((
const char*)&bitCount, 2);
852 for (i = 0; i < 6; i++)
853 bmpFile.write((
const char*)&temp, 4);
857 for (i = 0; i < 256; i++) {
858 lutEntry[0] = lutEntry[1] = lutEntry[2] = i;
859 bmpFile.write(lutEntry,
sizeof lutEntry);
862 bmpFile.write((
const char*)pix, dx * dy);
867 std::vector<recob::Cluster>& ccol,
869 CLHEP::HepRandomEngine& engine,
871 std::string
const& label)
873 std::vector<int> skip;
890 std::vector<art::Ptr<recob::Hit>>
hit;
892 for (
auto view : geom->
Views()) {
894 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Analyzing view " << view;
900 while (clusterIter != clusIn.
end()) {
903 <<
"Analyzing cinctr=" << cinctr <<
" which is in view " << (*clusterIter)->View();
907 if ((*clusterIter)->View() == view) hit = fmh.at(cinctr);
910 while (clusterIter != clusIn.
end()) {
911 if ((*clusterIter)->View() == view) {
913 hit = fmh.at(cinctr);
919 if (hit.size() == 0) {
927 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"We have all the hits..." << hit.size();
929 std::vector<double> slopevec;
930 std::vector<ChargeInfo_t> totalQvec;
931 std::vector<art::PtrVector<recob::Hit>> planeClusHitsOut;
932 this->FastTransform(clockData, detProp, hit, planeClusHitsOut, engine, slopevec, totalQvec);
934 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Made it through FastTransform" << planeClusHitsOut.size();
936 for (
size_t xx = 0;
xx < planeClusHitsOut.size(); ++
xx) {
937 auto const&
hits = planeClusHitsOut.at(
xx);
941 const unsigned int ew = LastHit.
WireID().
Wire;
950 ccol.emplace_back(
float(sw),
954 ClusterParamAlgo.StartCharge(gser).value(),
955 ClusterParamAlgo.StartAngle().value(),
956 ClusterParamAlgo.StartOpeningAngle().value(),
961 ClusterParamAlgo.EndCharge(gser).value(),
962 ClusterParamAlgo.EndAngle().value(),
963 ClusterParamAlgo.EndOpeningAngle().value(),
964 ClusterParamAlgo.Integral().value(),
965 ClusterParamAlgo.IntegralStdDev().value(),
966 ClusterParamAlgo.SummedADC().value(),
967 ClusterParamAlgo.SummedADCStdDev().value(),
968 ClusterParamAlgo.NHits(),
969 ClusterParamAlgo.MultipleHitDensity(),
970 ClusterParamAlgo.Width(gser),
977 clusHitsOut.push_back(planeClusHitsOut.at(
xx));
981 if (clusterIter != clusIn.
end()) {
999 CLHEP::HepRandomEngine& engine)
1001 std::vector<double> slopevec;
1002 std::vector<ChargeInfo_t> totalQvec;
1003 return FastTransform(clockData, detProp, clusIn, clusHitsOut, engine, slopevec, totalQvec);
1011 CLHEP::HepRandomEngine& engine,
1012 std::vector<double>& slopevec,
1013 std::vector<ChargeInfo_t>& totalQvec)
1015 std::vector<int> skip;
1018 lariov::ChannelStatusProvider
const* channelStatus =
1019 lar::providerFrom<lariov::ChannelStatusService>();
1021 CLHEP::RandFlat flat(engine);
1023 std::vector<art::Ptr<recob::Hit>>
hit;
1029 hit.push_back((*ii));
1031 if (hit.size() == 0) {
1032 if (fPerCluster) { ++cinctr; }
1041 if (hit.size() == 0) {
1042 if (fPerCluster) { ++cinctr; }
1046 auto const num_planes = geom->
Nplanes(tpcid);
1047 std::vector<double> wire_pitch(num_planes, 0.);
1049 auto const p = plane.ID().Plane;
1050 wire_pitch[p] = plane.WirePitch();
1054 std::vector<double> xyScale(num_planes, 0.);
1059 for (
size_t p = 0; p < xyScale.size(); ++p)
1060 xyScale[p] = driftVelFactor *
sampling_rate(clockData) / wire_pitch[p];
1066 skip.resize(hit.size());
1067 std::vector<int> listofxmax;
1068 std::vector<int> listofymax;
1069 std::vector<int> hitTemp;
1070 std::vector<int> sequenceHolder;
1071 std::vector<int> currentHits;
1072 std::vector<int> lastHits;
1074 float indcolscaling = 0.;
1076 float centerofmassx = 0;
1077 float centerofmassy = 0;
1079 float intercept = 0.;
1086 int accDx(0), accDy(0);
1092 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1095 unsigned int count = hit.size();
1096 std::vector<unsigned int> accumPoints;
1097 accumPoints.resize(hit.size());
1099 unsigned int nLinesFound = 0;
1101 for (; count > 0; count--) {
1104 unsigned int randInd = (
unsigned int)(flat.fire() * hit.size());
1106 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"randInd=" << randInd <<
" and size is " << hit.size();
1109 if (skip.at(randInd) == 1)
continue;
1112 if (accumPoints.at(randInd))
continue;
1113 accumPoints.at(randInd) = 1;
1116 for (
unsigned int i = 0; i < listofxmax.size(); ++i) {
1117 int yClearStart = listofymax.at(i) - fRhoZeroOutRange;
1118 if (yClearStart < 0) yClearStart = 0;
1120 int yClearEnd = listofymax.at(i) + fRhoZeroOutRange;
1121 if (yClearEnd >= accDy) yClearEnd = accDy - 1;
1123 int xClearStart = listofxmax.at(i) - fThetaZeroOutRange;
1124 if (xClearStart < 0) xClearStart = 0;
1126 int xClearEnd = listofxmax.at(i) + fThetaZeroOutRange;
1127 if (xClearEnd >= accDx) xClearEnd = accDx - 1;
1129 for (
y = yClearStart;
y <= yClearEnd; ++
y) {
1130 for (x = xClearStart; x <= xClearEnd; ++
x) {
1138 unsigned int wireMax = hit.at(randInd)->WireID().Wire;
1141 std::array<int, 3> max = c.
AddPointReturnMax(wireMax, (
int)(hit.at(randInd)->PeakTime()));
1142 maxCell = max.at(0);
1148 if (maxCell < fMinHits)
continue;
1151 denom = centerofmassx = centerofmassy = 0;
1153 if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
1154 for (
int i = -1; i < 2; ++i) {
1155 for (
int j = -1; j < 2; ++j) {
1156 int cell = c.
GetCell(yMax + i, xMax + j);
1158 centerofmassx += j * cell;
1159 centerofmassy += i * cell;
1162 centerofmassx /= denom;
1163 centerofmassy /= denom;
1166 centerofmassx = centerofmassy = 0;
1169 listofxmax.push_back(xMax);
1170 listofymax.push_back(yMax);
1173 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1174 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(I) found maximum at (d=" << rho <<
" a=" << theta
1176 " from absolute maximum " 1177 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
1179 slope = -1. / tan(theta);
1180 intercept = (rho / sin(theta));
1191 if (!std::isinf(slope) && !std::isnan(slope)) {
1192 sequenceHolder.clear();
1194 for (
size_t i = 0; i < hit.size(); ++i) {
1195 distance = (TMath::Abs(hit.at(i)->PeakTime() - slope * (double)(hit.at(i)->WireID().Wire) -
1197 (std::sqrt(pow(xyScale[hit.at(i)->WireID().Plane] * slope, 2) + 1)));
1199 if (distance < fMaxDistance + hit.at(i)->RMS() + indcolscaling && skip.at(i) != 1) {
1200 hitTemp.push_back(i);
1201 sequenceHolder.push_back(hit.at(i)->Channel());
1206 if (hitTemp.size() < 2)
continue;
1207 currentHits.clear();
1210 currentHits.push_back(0);
1211 for (
size_t i = 0; i + 1 < sequenceHolder.size(); ++i) {
1213 while ((channelStatus->IsBad(sequenceHolder.at(i) + j)) ==
true)
1215 if (sequenceHolder.at(i + 1) - sequenceHolder.at(i) <= j + fMissedHits)
1216 currentHits.push_back(i + 1);
1217 else if (currentHits.size() > lastHits.size()) {
1218 lastHits = currentHits;
1219 currentHits.clear();
1222 currentHits.clear();
1225 if (currentHits.size() > lastHits.size()) lastHits = currentHits;
1236 int lastHitsChannel = 0;
1237 int nHitsPerChannel = 1;
1239 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"filling the pCorner arrays around here..." 1240 <<
"\n but first, lastHits size is " << lastHits.size()
1241 <<
" and lastHitsChannel=" << lastHitsChannel;
1245 unsigned int lastChannel = hit.at(hitTemp.at(lastHits.at(0)))->Channel();
1247 for (
size_t i = 0; i < lastHits.size() - 1; ++i) {
1248 bool newChannel =
false;
1250 if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() != lastChannel) {
1253 if (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel() == lastChannel) nHitsPerChannel++;
1259 if (slope > 0 || (!newChannel && nHitsPerChannel <= 1)) {
1261 pCorner0[0] = (hit.at(hitTemp.at(lastHits.at(i)))->Channel()) * wire_pitch[0];
1262 pCorner0[1] = hit.at(hitTemp.at(lastHits.at(i)))->PeakTime() * tickToDist;
1263 pCorner1[0] = (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel()) * wire_pitch[0];
1264 pCorner1[1] = hit.at(hitTemp.at(lastHits.at(i + 1)))->PeakTime() * tickToDist;
1265 if (std::sqrt(pow(pCorner0[0] - pCorner1[0], 2) + pow(pCorner0[1] - pCorner1[1], 2)) >
1266 fMissedHitsDistance)
1270 else if (slope < 0 && newChannel && nHitsPerChannel > 1) {
1273 (hit.at(hitTemp.at(lastHits.at(lastHitsChannel)))->Channel()) * wire_pitch[0];
1274 pCorner0[1] = hit.at(hitTemp.at(lastHits.at(lastHitsChannel)))->PeakTime() * tickToDist;
1275 pCorner1[0] = (hit.at(hitTemp.at(lastHits.at(i + 1)))->Channel()) * wire_pitch[0];
1276 pCorner1[1] = hit.at(hitTemp.at(lastHits.at(i + 1)))->PeakTime() * tickToDist;
1277 if (std::sqrt(pow(pCorner0[0] - pCorner1[0], 2) + pow(pCorner0[1] - pCorner1[1], 2)) >
1278 fMissedHitsDistance)
1280 lastChannel = hit.at(hitTemp.at(lastHits.at(i)))->Channel();
1281 lastHitsChannel = i + 1;
1282 nHitsPerChannel = 0;
1286 if ((
double)missedHits / ((
double)lastHits.size() - 1) > fMissedHitsToLineSize)
continue;
1288 clusterHits.
clear();
1289 if (lastHits.size() < 5)
continue;
1294 for (
size_t i = 0; i < lastHits.size(); ++i) {
1295 clusterHits.
push_back(hit.at(hitTemp.at(lastHits.at(i))));
1296 integralQ.
add(clusterHits.
back()->Integral());
1297 summedQ.
add(clusterHits.
back()->SummedADC());
1298 skip.at(hitTemp.at(lastHits.at(i))) = 1;
1301 if (
std::abs(slope) > fMaxSlope)
continue;
1303 clusHitsOut.push_back(clusterHits);
1304 slopevec.push_back(slope);
1305 totalQvec.emplace_back(integralQ.
Sum(),
1315 if (nLinesFound > (
unsigned int)fMaxLines)
break;
1321 if (fSaveAccumulator) {
1323 int cell, pix = 0, maxCell = 0;
1324 for (
y = 0;
y < accDy; ++
y) {
1325 for (x = 0; x < accDx; ++
x) {
1327 if (cell > maxCell) maxCell = cell;
1331 std::unique_ptr<unsigned char[]> outPix(
new unsigned char[accDx * accDy]);
1332 unsigned int PicIndex = 0;
1333 for (
y = 0;
y < accDy; ++
y) {
1334 for (x = 0; x < accDx; ++
x) {
1336 if (maxCell > 0) pix = (int)((1500 * c.
GetCell(
y, x)) / maxCell);
1337 outPix[PicIndex++] = pix;
1341 HLSSaveBMPFile(
"houghaccum.bmp", outPix.get(), accDx, accDy);
1348 return clusHitsOut.size();
1364 c.
Init(dx, dy, fRhoResolutionFactor, fNumAngleCells);
1366 for (
unsigned int i = 0; i <
hits.size(); ++i) {
1381 float centerofmassx = 0.;
1382 float centerofmassy = 0.;
1385 if (xMax > 0 && yMax > 0 && xMax + 1 < accDx && yMax + 1 < accDy) {
1386 for (
int i = -1; i < 2; ++i) {
1387 for (
int j = -1; j < 2; ++j) {
1388 denom += c.
GetCell(yMax + i, xMax + j);
1389 centerofmassx += j * c.
GetCell(yMax + i, xMax + j);
1390 centerofmassy += i * c.
GetCell(yMax + i, xMax + j);
1393 centerofmassx /= denom;
1394 centerofmassy /= denom;
1397 centerofmassx = centerofmassy = 0;
1401 c.
GetEquation(yMax + centerofmassy, xMax + centerofmassx, rho, theta);
1402 MF_LOG_DEBUG(
"HoughBaseAlg") <<
"Transform(III) found maximum at (d=" << rho <<
" a=" << theta
1404 " from absolute maximum " 1405 << c.
GetCell(yMax, xMax) <<
" at (d=" << yMax <<
", a=" << xMax
1407 slope = -1. / tan(theta);
1408 intercept = rho / sin(theta);
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
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
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.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
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.
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
The data type to uniquely identify a TPC.
Description of geometry of one entire detector.
Declaration of cluster object.
Detector simulation of raw signals on wires.
constexpr TPCID const & asTPCID() const
Conversion to TPCID (for convenience of notation).
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.
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
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 >>())
std::set< View_t > const & Views() const
Returns a list of possible views in the detector.
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
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
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)