#include #include #include #include #include #include #include #include // #include // if c++ 11 is not available #include // #include "boost/tuple/tuple.hpp" // #include #include "TH2D.h" #include "TApplication.h" #include "TCanvas.h" #include "TString.h" #include "TGraph.h" #include "TEllipse.h" #include "TF1.h" #include "TMath.h" #include "PndAhTools.h" #include "PndAhHoughTransform.h" // #include "PndAhMultipeakAnalysis.h" #include "PndAhConformalMap.h" class PndAhIterativeMaximumDeleter { public: PndAhIterativeMaximumDeleter(); PndAhIterativeMaximumDeleter(houghInfo & info, unsigned int iterations = 1) : fVX(info.x), fVY(info.y), fVR(info.r), fMaxAngle(info.maxAngle), fEveryXDegrees(info.everyXDegrees), fVerbose(info.verbose), fIterations(iterations) {DoEverthing();}; PndAhIterativeMaximumDeleter(std::vector x, std::vector y, std::vector r, double maxAngle = 360, double everyXDegrees = 30, bool verbose = false) : fVX(x), fVY(y), fVR(r), fMaxAngle(maxAngle), fEveryXDegrees(everyXDegrees), fVerbose(verbose) {DoEverthing();}; ~PndAhIterativeMaximumDeleter(); void SetIterations(unsigned int iterations = 1) {fIterations = iterations;}; std::vector GetMaxBins() {return fVMaxBins;}; std::vector > GetMaxCoordinates() {return fVMaxCoordinates;} std::vector GetHoughHistograms() {return fVHoughHists;}; std::vector > GetBorderXCoordinates() {return fBorderXCoordinates;}; protected: void DoEverthing() { PrintEverything(); std::cout << " -- Before Iterating -- " << std::endl; for (int i = 0; i < fIterations; ++i) { std::cout << " -- Starting Iteration " << i << std::endl; if (PndAhHoughTransform::vectorsAreEmpty(fVX, fVY, fVR)) { break; } else { PndAhHoughTransform * hough = new PndAhHoughTransform(fVX, fVY, fVR, fMaxAngle, fEveryXDegrees, fVerbose, true); // std::cout << " -- Getting Histogram." << std::endl; TH2D * houghHist = hough->GetHistogram(true, "houghIt" + PndAhTools::numberToString(i)); if (stopIterating(houghHist)) break; // some stop criterion is reached // std::cout << " -- Getting Max Passings." << std::endl; std::vector passingHits = generateListOfMaxPassingHits(hough, houghHist); // std::cout << " -- passingHits.size() = " << passingHits.size() << std::endl; sortMaxPassingHits(passingHits); removeMaxPassingHits(passingHits); fVHoughHists.push_back(houghHist); fVMaxBins.push_back(getHistMaxBinNumber(houghHist)); fVMaxCoordinates.push_back(getHistMaximumCoordinates(houghHist)); // std::cout << " -- Ending Iteration " << i << std::endl; } } // std::cout << " -- After Iterating -- " << std::endl; } bool stopIterating(TH2D * hist) { if (stopCriterion_histIsBelowZThreshold(hist, 3)) return true; return false; } bool stopCriterion_histIsBelowZThreshold(TH2D * hist, double threshold) { return hist->GetMaximum() <= threshold; } void PrintEverything() { std::cout << "fVX.size() = " << fVX.size() << std::endl; std::cout << "fMaxAngle = " << fMaxAngle << std::endl; std::cout << "fEveryXDegrees = " << fEveryXDegrees << std::endl; std::cout << "fVerbose = " << fVerbose << std::endl; if (fIterations) std::cout << "fIterations = " << fIterations << std::endl; } int getHistMaxBinNumber(TH2D * hist) { return hist->GetMaximumBin(); } std::pair getHistMaximumCoordinates(TH2D * hist) { int x, y, z; hist->GetMaximumBin(x, y, z); double xCoordinate = hist->GetXaxis()->GetBinCenter(x); double yCoordinate = hist->GetYaxis()->GetBinCenter(y); return std::make_pair(xCoordinate, yCoordinate); } std::vector generateListOfMaxPassingHits(PndAhHoughTransform * ht, TH2D * houghHist) { std::multimap binIdsAndHitIds = ht->GetBinIdHitId(); int maxBinId = getHistMaxBinNumber(houghHist); // std::cout << " -- maxBinId = " << maxBinId << std::endl; // if (houghHist->GetBinContent(maxBinId) < 0.0001) { // this only works as long as there are no negative bin contents! // std::cout << " -- It's the end of the world!" << std::endl; // fHistIsEmpty = true; // std::vector emptyVector; // return emptyVector; // } std::multimap::iterator itLow, itUp; itLow = binIdsAndHitIds.lower_bound(maxBinId); itUp = binIdsAndHitIds.upper_bound(maxBinId); std::vector vOfGoodIds; for (std::multimap::iterator it = itLow; it != itUp; ++it) { vOfGoodIds.push_back((*it).second); } return vOfGoodIds; } void sortMaxPassingHits(std::vector & list) { // PndAhTools::printVector(list); std::sort(list.begin(), list.end()); // PndAhTools::printVector(list); std::reverse(list.begin(), list.end()); // PndAhTools::printVector(list); } void removeMaxPassingHits(std::vector list) { double tempXInner, tempXOuter; bool firstLoop = true; for (std::vector::iterator it = list.begin(); it < list.end(); it++) { double currentXvalue = fVX.at((*it)); // std::cout << " -- removeMaxPassingHits -- currentXvalue = " << currentXvalue << std::endl; if (firstLoop) { // std::cout << " -- removeMaxPassingHits -- firstLoop" << std::endl; tempXInner = currentXvalue; tempXOuter = currentXvalue; firstLoop = false; } // std::cout << " -- removeMaxPassingHits -- abs(tempXInner), abs(tempXOuter), abs(currentXvalue)" << std::abs(tempXInner) << ", " << std::abs(tempXOuter) << ", " << std::abs(currentXvalue) << std::endl; if (std::abs(currentXvalue) < std::abs(tempXInner)) tempXInner = currentXvalue; if (std::abs(currentXvalue) > std::abs(tempXOuter)) tempXOuter = currentXvalue; // std::cout << " -- (*it) = " << (*it) << std::endl; // std::cout << " -- fVX.size() = " << fVX.size() << std::endl; fVX.erase(fVX.begin() + (*it)); fVY.erase(fVY.begin() + (*it)); fVR.erase(fVR.begin() + (*it)); // std::cout << " -- removed for (*it) = " << (*it) << std::endl; } // std::cout << " -- removeMaxPassingHits -- " << tempXInner << ", " << tempXOuter << std::endl; fBorderXCoordinates.push_back(std::make_pair(tempXInner, tempXOuter)); // std::cout << " -- End of removeMaxPassingHits()" << std::endl; } private: std::vector fVX; std::vector fVY; std::vector fVR; double fMaxAngle; double fEveryXDegrees; double fVerbose; unsigned int fIterations; std::vector fVMaxBins; std::vector > fVMaxCoordinates; std::vector fVHoughHists; std::vector > fBorderXCoordinates; // inner, outer // bool fHistIsEmpty; }; TGraph vectorsToGraph(std::vector x, std::vector y) { TGraph vectorGraph; for (int i = 0; i < x.size(); ++i) { vectorGraph.SetPoint(i, x[i], y[i]); } vectorGraph.SetMarkerStyle(31); return vectorGraph; } TF1 * houghParametersToLine(double r, double alpha) { TF1 * equation = new TF1("houghLine", "[0]/sin([1]) - x*cos([1])/sin([1])"); equation->SetParameter(0, r); equation->SetParameter(1, alpha * TMath::DegToRad()); return equation; } std::vector vectorsToEllipses(std::vector x, std::vector y, std::vector r) { std::vector ellipses; for (int i = 0; i < x.size(); ++i) { TEllipse * thisEllipse = new TEllipse(x[i], y[i], r[i], r[i]); thisEllipse->SetFillStyle(0); ellipses.push_back(thisEllipse); } return ellipses; } std::vector maximaToTracks(std::vector > vOfMaxima, std::vector > vOfBorders) { std::vector tempVector; // std::vector >::iterator itMax = vOfMaxima.begin(); // std::vector >::iterator itBorder = vOfBorders.begin(); for (std::vector >::iterator itMax = vOfMaxima.begin(), itBorder = vOfBorders.begin(); itMax != vOfMaxima.end() && itBorder != vOfBorders.end(); itMax++, itBorder++) { // initializing two distinct iterators here only works because they are of the same type - if they are not, the iterators have to be initialized outside the for loop individually. another way of taking care of this kind of thing is using zip operators double currentMaxAlpha = std::get<0>(*itMax); double currentMaxRho = std::get<1>(*itMax); TF1 * currentTrack = houghParametersToLine(currentMaxRho, currentMaxAlpha); double currentInnerLimit = std::get<0>(*itBorder) * 0.95; double currentOuterLimit = std::get<1>(*itBorder) * 1.05; currentTrack->SetRange(currentInnerLimit, currentOuterLimit); tempVector.push_back(currentTrack); } return tempVector; } int main(int argc, char** argv) { double everyXDegrees = 1; if (argc > 1) everyXDegrees = static_cast(atof(argv[1])); int readInUpToLineNumber = 20; if (argc > 2) readInUpToLineNumber = static_cast(atof(argv[2])); // std::vector origX, origY, origR; // PndAhTools::readPoints("real_data.txt", origX , origY, origR, readInUpToLineNumber); // PndAhConformalMap * confMap = new PndAhConformalMap(origX, origY, origR); // std::vector x = confMap->GetConfMappedXVector(); // std::vector y = confMap->GetConfMappedYVector(); // std::vector r = confMap->GetConfMappedRVector(); std::vector x, y, r; PndAhTools::readPoints("real_data.txt", x , y, r, readInUpToLineNumber); std::vector fakeR(x.size()); std::fill(fakeR.begin(), fakeR.end(), 0.); unsigned int maximumIterations = 8; houghInfo currentHoughInfo; currentHoughInfo.x = x; currentHoughInfo.y = y; currentHoughInfo.r = fakeR; currentHoughInfo.maxAngle = 180.; currentHoughInfo.everyXDegrees = everyXDegrees; currentHoughInfo.verbose = false; PndAhIterativeMaximumDeleter * myDeleter = new PndAhIterativeMaximumDeleter(currentHoughInfo, maximumIterations); auto maxBins = myDeleter->GetMaxBins(); std::vector houghHists = myDeleter->GetHoughHistograms(); unsigned int nHist = houghHists.size(); TApplication * theApp = new TApplication("app", &argc, argv, 0, -1); TCanvas * cHough = new TCanvas("cHough","cHough",5,5,1000,800); PndAhTools::ROOT::divideCanvas(cHough, (int)nHist, 2); for (int i = 0; i < nHist; ++i) { cHough->cd(i + 1); houghHists[i]->Draw("COLZ"); } TCanvas * cPoints = new TCanvas("cPoints", "cPoints", 0, 0, 500, 500); TGraph hitPoints = vectorsToGraph(x, y); hitPoints.Draw("AP"); std::vector hitEllipses = vectorsToEllipses(x, y, r); for(std::vector::iterator it = hitEllipses.begin(); it != hitEllipses.end(); it++) { (*it)->Draw("SAME"); } auto maxCoordinates = myDeleter->GetMaxCoordinates(); auto borderXCoordinates = myDeleter->GetBorderXCoordinates(); std::vector vOfTracks = maximaToTracks(maxCoordinates, borderXCoordinates); Color_t someColors[] = {kBlue, kGreen, kRed, kOrange, kMagenta}; int tempI = 0; for(std::vector::iterator it = vOfTracks.begin(); it != vOfTracks.end(); it++) { (*it)->SetLineColor(someColors[tempI++]); (*it)->Draw("SAME"); } theApp->Run(); return 1; }