28 closeName.append(
"]");
54 fDetProp = lar::providerFrom<detinfo::DetectorPropertiesService>();
62 Double_t Red[2] = { 1.00, 0.00 };
63 Double_t Green[2] = { 1.00, 0.00 };
64 Double_t Blue[2] = { 1.00, 0.00 };
65 Double_t Length[2] = { 0.00, 1.00 };
66 TColor::CreateGradientColorTable(2, Length, Red, Green, Blue, 1000);
67 gStyle->SetOptStat(110000);
70 std::ostringstream oss;
71 oss <<
"BlurredImages_Run" << run <<
"_Subrun" << subrun;
84 for (
int i = 1; i <= 4; i++) {
88 std::ostringstream oss;
89 oss <<
"Event " << event;
93 l.DrawLatex(0.1, 0.1, oss.str().c_str());
120 int wire = bin % image.size();
121 int tick = bin / image.size();
128 std::vector<std::vector<int> >
const& allClusterBins,
132 for (
std::vector<std::vector<int> >::
const_iterator clustIt = allClusterBins.begin(); clustIt != allClusterBins.end(); clustIt++) {
133 std::vector<int> bins = *clustIt;
138 mf::LogInfo(
"BlurredClustering") <<
"Cluster made from " << bins.size() <<
" bins, of which " << clusHits.
size() <<
" were real hits";
142 mf::LogVerbatim(
"BlurredClustering") <<
"Cluster of size " << clusHits.
size() <<
" not saved since it is smaller than the minimum cluster size, set to " <<
fMinSize;
146 clusters.push_back(clusHits);
159 int histWire =
GlobalWire((*hitIt)->WireID());
160 if ((*hitIt)->PeakTime() < lowerTick) lowerTick = (*hitIt)->PeakTime();
161 if ((*hitIt)->PeakTime() > upperTick) upperTick = (*hitIt)->PeakTime();
162 if (histWire < lowerWire) lowerWire = histWire;
163 if (histWire > upperWire) upperWire = histWire;
182 int tick = (int)(*hitIt)->PeakTime();
183 float charge = (*hitIt)->Integral();
208 return (ybin * image.size()) + xbin;
214 int x = bin % image.size();
215 int y = bin / image.size();
217 return image.at(x).at(y);
223 std::pair<int,int> deadWires = std::make_pair<int,int>(0,0);
225 int lower_bin = width / 2;
226 int upper_bin = (width+1) / 2;
245 double nhits=0, sumx=0., sumy=0., sumx2=0., sumxy=0.;
246 for (
unsigned int wireIt = 0; wireIt <
fHitMap.size(); ++wireIt) {
247 for (
unsigned int tickIt = 0; tickIt <
fHitMap.at(wireIt).size(); ++tickIt) {
248 if (
fHitMap[wireIt][tickIt].isNull())
259 double gradient = (nhits * sumxy - sumx * sumy) / (nhits * sumx2 - sumx * sumx);
262 TVector2 unit = TVector2(1,gradient).Unit();
265 if (std::isnan(gradient))
266 unit = TVector2(0,1);
286 std::vector<double> times;
289 const int nbinsx = blurred.size();
290 const int nbinsy = blurred.at(0).size();
291 const int nbins = nbinsx * nbinsy;
294 std::vector<bool> used(nbins);
295 std::vector<std::pair<double, int> > values;
298 for (
int xbin = 0; xbin < nbinsx; ++xbin) {
299 for (
int ybin = 0; ybin < nbinsy; ++ybin) {
306 std::sort(values.rbegin(), values.rend());
322 double blurred_binval = values[niter].first;
327 int bin = values[niter++].second;
335 cluster.push_back(bin);
340 times.push_back(time);
348 for (
unsigned int clusBin = 0; clusBin < cluster.size(); ++clusBin) {
352 binx = cluster[clusBin] % nbinsx;
353 biny = ((cluster[clusBin] - binx) / nbinsx) % nbinsy;
358 if ( (
x == binx and
y == biny) or (
x >= nbinsx or
y >= nbinsy) or (
x < 0 or
y < 0) )
363 if (bin >= nbinsx * nbinsy or bin < 0)
373 if (time > 0 && times.size() > 0 && !
PassesTimeCut(times, time))
379 cluster.push_back(bin);
382 times.push_back(time);
398 for (
unsigned int i = 0; i < cluster.size(); i++)
399 used[cluster[i]] =
false;
404 for (
unsigned int clusBin = 0; clusBin < cluster.size(); clusBin++) {
407 for (
int x = -1;
x <= 1;
x++) {
408 for (
int y = -1;
y <= 1;
y++) {
409 if (!
x && !
y)
continue;
412 int neighbouringBin = cluster[clusBin] +
x + (
y * nbinsx);
413 if (neighbouringBin < nbinsx || neighbouringBin % nbinsx == 0 || neighbouringBin % nbinsx == nbinsx - 1 || neighbouringBin >= nbinsx * (nbinsy - 1))
420 used[neighbouringBin] =
true;
421 cluster.push_back(neighbouringBin);
424 times.push_back(time);
433 mf::LogVerbatim(
"Blurred Clustering") <<
"Size of cluster after filling in holes: " << cluster.size();
441 for (
int clusBin = cluster.size() - 1; clusBin >= 0; clusBin--) {
442 bin = cluster[clusBin];
445 if (bin < nbinsx || bin % nbinsx == 0 || bin % nbinsx == nbinsx - 1 || bin >= nbinsx * (nbinsy - 1))
continue;
451 cluster.erase(cluster.begin() + clusBin);
460 mf::LogVerbatim(
"Blurred Clustering") <<
"Size of cluster after removing peninsulas: " << cluster.size();
465 for (
unsigned int i = 0; i < cluster.size(); i++)
466 used[cluster[i]] =
false;
471 allcluster.push_back(cluster);
476 return allcluster.size();
482 double globalWire = -999;
486 double wireCentre[3];
498 if (wireID.
TPC == 0 or wireID.
TPC == 1) globalWire = wireID.
Wire;
499 else if (wireID.
TPC == 2 or wireID.
TPC == 3 or wireID.
TPC == 4 or wireID.
TPC == 5) globalWire = nwires + wireID.
Wire;
500 else if (wireID.
TPC == 6 or wireID.
TPC == 7) globalWire = (2*nwires) + wireID.
Wire;
501 else mf::LogError(
"BlurredClusterAlg") <<
"Error when trying to find a global induction plane coordinate for TPC " << wireID.
TPC <<
" (geometry " <<
fDetector <<
")";
506 int block = wireID.
TPC / 4;
507 globalWire = (nwires*block) + wireID.
Wire;
510 double wireCentre[3];
517 return std::round(globalWire);
527 int blur_wire, blur_tick, sigma_wire, sigma_tick;
531 int width = 2 * blur_wire + 1;
532 int height = 2 * blur_tick + 1;
533 int nbinsx = image.size();
534 int nbinsy = image.at(0).size();
537 std::vector<std::vector<double> > copy(nbinsx, std::vector<double>(nbinsy, 0));
540 for (
int x = 0;
x < nbinsx; ++
x) {
541 for (
int y = 0;
y < nbinsy; ++
y) {
543 if (image[
x][
y] == 0)
547 int tick_scale = TMath::Sqrt(TMath::Power(
fHitMap[
x][
y]->RMS(),2) + TMath::Power(sigma_tick,2)) / (double)sigma_tick;
549 std::vector<double> correct_kernel =
fAllKernels[sigma_wire][sigma_tick*tick_scale];
558 int dead_wires_passed = num_deadwires.first;
570 for (
int blurx = -(width/2+num_deadwires.first); blurx < (width+1)/2+num_deadwires.second; ++blurx) {
571 for (
int blury = -height/2*tick_scale; blury < ((((height+1)/2)-1)*tick_scale)+1; ++blury) {
577 dead_wires_passed -= 1;
581 if (
x + blurx >= 0 and
x + blurx < nbinsx and y + blury >= 0 and
y + blury < nbinsy)
582 copy[
x+blurx][
y+blury] += weight * image[
x][
y];
585 dead_wires_passed += 1;
607 double time = -10000;
625 for (
int sigma_wire = 1; sigma_wire <=
fSigmaWire; ++sigma_wire) {
629 std::vector<double> kernel(
fKernelWidth*fKernelHeight,0);
636 double sig2i = 2. * sigma_wire * sigma_wire;
637 double sig2j = 2. * sigma_tick * sigma_tick;
640 double value = 1. / sqrt(sig2i * M_PI) * exp(-i * i / sig2i) * 1. / sqrt(sig2j * M_PI) * exp(-j * j / sig2j);
641 kernel.at(key) =
value;
659 hist->SetXTitle(
"Wire number");
660 hist->SetYTitle(
"Tick number");
661 hist->SetZTitle(
"Charge");
663 for (
unsigned int imageWireIt = 0; imageWireIt < image.size(); ++imageWireIt) {
665 for (
unsigned int imageTickIt = 0; imageTickIt < image.at(imageWireIt).size(); ++imageTickIt) {
667 hist->Fill(wire, tick, image.at(imageWireIt).at(imageTickIt));
677 unsigned int neighbours = 0;
680 for (
int x = -1;
x <= 1;
x++) {
681 for (
int y = -1;
y <= 1;
y++) {
682 if (!
x && !
y)
continue;
685 int neighbouringBin = bin +
x + (
y * nbinsx);
688 if (used.at(neighbouringBin))
709 std::vector<std::vector<int> > allClusterBins;
717 std::vector<int> clusterBins;
727 clusterBins.push_back(bin);
730 allClusterBins.push_back(clusterBins);
733 SaveImage(image, allClusterBins, pad, tpc, plane);
737 std::vector<std::vector<int> > allClusterBins;
738 SaveImage(image, allClusterBins, pad, tpc, plane);
748 stage =
"Stage 1: Unblurred";
751 stage =
"Stage 2: Blurred";
754 stage =
"Stage 3: Blurred with clusters overlaid";
757 stage =
"Stage 4: Output clusters";
760 stage =
"Unknown stage";
764 std::stringstream title;
765 title << stage <<
" -- TPC " << tpc <<
", Plane " << plane;
767 image->SetName(title.str().c_str());
768 image->SetTitle(title.str().c_str());
769 image->DrawCopy(
"colz");
773 for (
std::vector<std::vector<int> >::
const_iterator it = allClusterBins.begin(); it != allClusterBins.end(); it++, clusterNum++) {
774 std::vector<int> bins = *it;
775 TMarker mark(0, 0, 20);
776 mark.SetMarkerColor(clusterNum);
777 mark.SetMarkerSize(0.1);
786 mark.SetMarkerStyle(24);
789 image->GetBinXYZ(bin,wire,tick,z);
791 mark.SetMarkerStyle(20);
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void FindBlurringParameters(int &blurwire, int &blurtick, int &sigmawire, int &sigmatick)
Dynamically find the blurring radii and Gaussian sigma in each dimension.
void SaveImage(TH2F *image, std::vector< art::PtrVector< recob::Hit > > const &allClusters, int pad, int tpc, int plane)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
unsigned int fNeighboursThreshold
int FindClusters(std::vector< std::vector< double > > const &image, std::vector< std::vector< int > > &allcluster)
Find clusters in the histogram.
BlurredClusteringAlg(fhicl::ParameterSet const &pset)
virtual unsigned int ReadOutWindowSize() const =0
std::pair< int, int > DeadWireCount(int wire_bin, int width)
std::vector< std::vector< double > > GaussianBlur(std::vector< std::vector< double > > const &image)
Applies Gaussian blur to image.
void reconfigure(fhicl::ParameterSet const &p)
std::vector< std::vector< art::Ptr< recob::Hit > > > fHitMap
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
geo::WireID WireID() const
Initial tdc tick for hit.
The data type to uniquely identify a Plane.
unsigned int NumNeighbours(int nx, std::vector< bool > const &used, int bin)
Determines the number of clustered neighbours of a hit.
CryostatID_t Cryostat
Index of cryostat.
unsigned int MaxWires() const
Returns the largest number of wires among all planes in this detector.
WireID_t Wire
Index of the wire within its plane.
double GetTimeOfBin(std::vector< std::vector< double > > const &image, int bin)
Returns the hit time of a hit in a particular bin.
std::string fDebugPDFName
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Cluster finding and building.
art::ServiceHandle< geo::Geometry > fGeom
std::vector< bool > fDeadWires
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.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
bool PassesTimeCut(std::vector< double > const ×, double time)
Determine if a hit is within a time threshold of any other hits in a cluster.
void CreateDebugPDF(int run, int subrun, int event)
Create the PDF to save debug images.
void push_back(Ptr< U > const &p)
Signal from induction planes.
int ConvertWireTickToBin(std::vector< std::vector< double > > const &image, int xbin, int ybin)
Converts an xbin and a ybin to a global bin number.
T get(std::string const &key) const
PlaneID_t Plane
Index of the plane within its TPC.
art::PtrVector< recob::Hit > ConvertBinsToRecobHits(std::vector< std::vector< double > > const &image, std::vector< int > const &bins)
Converts a vector of bins into a hit selection - not all the hits in the bins vector are real hits...
data_t::iterator iterator
Detector simulation of raw signals on wires.
void MakeKernels()
Makes all the kernels which could be required given the tuned parameters.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
std::string value(boost::any const &)
TH2F * MakeHistogram(std::vector< std::vector< double > > const &image, TString name)
Converts a 2D vector in a histogram for the debug pdf.
art::Ptr< recob::Hit > ConvertBinToRecobHit(std::vector< std::vector< double > > const &image, int bin)
Converts a bin into a recob::Hit (not all of these bins correspond to recob::Hits - some are fake hit...
std::vector< std::vector< double > > ConvertRecobHitsToVector(std::vector< art::Ptr< recob::Hit > > const &hits)
Takes hit map and returns a 2D vector representing wire and tick, filled with the charge...
std::vector< std::vector< std::vector< double > > > fAllKernels
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
virtual ~BlurredClusteringAlg()
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
double ConvertBinToCharge(std::vector< std::vector< double > > const &image, int bin)
Returns the charge stored in the global bin value.
lariov::ChannelStatusProvider const & fChanStatus
detinfo::DetectorProperties const * fDetProp
void ConvertBinsToClusters(std::vector< std::vector< double > > const &image, std::vector< std::vector< int > > const &allClusterBins, std::vector< art::PtrVector< recob::Hit > > &clusters)
Takes a vector of clusters (itself a vector of hits) and turns them into clusters using the initial h...
Event finding and building.
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
Returns the specified wire.
int GlobalWire(geo::WireID const &wireID)
Find the global wire position.