//----------------------------------------------------------- // // Description: // Driver programm for the pandaroot-CUDA interface // // // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Felix Boehmer TU Munich (original author) // // //----------------------------------------------------------- #include #include "TFile.h" #include "TTree.h" #include "TBranch.h" #include "TH1F.h" #include "PndTpcDigi.h" #include "TClonesArray.h" #include "TCanvas.h" #include "TApplication.h" #include "TROOT.h" #include "TSystem.h" #include "TStyle.h" #include "TH2D.h" #include "TBox.h" #include "TStopwatch.h" #include #include #include #include #include #include #include #include "Hough5DNode.h" #include "fastHoughGPU_IFC.h" bool getBit(char* c, int n) { int i = (int) (c[n>>3] & (1 << (n & 7))); return (bool) i; } void clearBit(char* c, int n) { c[n>>3] = c[n>>3] & ~(1 << (n & 7 )); } //helper functor for node sorting bool compareNodes (Hough5DNode* n1, Hough5DNode* n2) { return (n1->getVote() > n2->getVote()); } int main(int argc, char** argv) { extern char *optarg; int c; int TREE_DEPTH = 6; //number of space divisions int THRESHOLD = 40; int THREADS = 320; float SCALE =0.90f; uint cutoffDec = 7; uint cutoffLevel = 4; int minCL = 5; int dynLevel = 5; bool tracking = false; float m_Max = 1.f; float m_Min = -1.f; float t_Max = 5.f; float t_Min = -5.f; float phi_Min = 0.f; float phi_Max = 180.f; float theta_Min = 20.f; float theta_Max = 160.f; float c_Min = -0.5f; float c_Max = 0.5f; // float m_Max = 10.f; // float m_Min = -10.f; // float t_Max = 200.f; // float t_Min = -200.f; // float phi_Min = 0.f; // float phi_Max = 180.f; // float theta_Min = 20.f; // float theta_Max = 160.f; // float c_Min = -1.f; // float c_Max = 1.f; float mins[5] = {phi_Min, theta_Min, c_Min, m_Min, t_Min}; float maxs[5] = {phi_Max, theta_Max, c_Max, m_Max, t_Max}; while ((c = getopt(argc, argv, "t:d:T:l:s:c:cl")) != -1) switch (c) { case 't': THRESHOLD = atoi(optarg); break; case 'd': TREE_DEPTH = atoi(optarg); break; case 'T': THREADS = atoi(optarg); break; case 'l': dynLevel = atoi(optarg); break; case 's': tracking = true; break; case 'c': cutoffDec = atoi(optarg); break; case 'cl': cutoffLevel = atoi(optarg); break; default : std::cout<<"\n\nFast Hough Transformation on the GPU -------\n\n" <<"Options:\n\n" <<" -d: Tree Depth - when to abort the algorithm\n" <<" -t: Threshold - Minimal number of votes required" <<" unti dynamic thresholding kicks in\n" <<" -l: Starting level for dynamic thresholding\n" <<" -T: Number of threads per kernel block (default:" <<" 128)\n" <<" -s: Search for tracks after FHT search is finished\n" <<" -c: First decimal of fraction of nodes to kill in " <<" cutoff\n" <<" -cl: Level at which to start cutoff\n" <IsZombie()) { std::cerr<<"Input file "<Get("cbmsim"); TClonesArray* _clusters = new TClonesArray("PndTpcCluster"); reco_tree->SetBranchAddress("PndTpcCluster", &_clusters); reco_tree->GetEntry(EVENT); int size = _clusters->GetEntriesFast(); if(size<10) { std::cerr<<"Not enough clusters in data ("< clusterList; std::vector riemannListRZ; //loop over clusters -------------------------------------------------- for(int c=0; cAt(c)); clusterList.push_back(cl); TVector3 pos = cl->pos(); if(pos.X() < 0.) continue; riemannListRZ.push_back(TVector3(pos.Perp(), 0., pos.Z())); } // PLOT RZ Hough Histogram -------------------------------------------- TH2D* houghRZ = new TH2D("vfg", "RZ hough space", 500, m_Min, m_Max, 500, t_Min, t_Max); double tBinWidth = (t_Max - t_Min)/500; for(unsigned int rp=0; rpFill(M,T); } } TStopwatch timer; timer.Start(); // FAST HOUGH SEARCH -------------------------------------------------- //instantiate interface object: fastHoughGPU_IFC* IFC = new fastHoughGPU_IFC(40, 10000000); int nClusters = riemannListRZ.size(); char* root_hitlist = (char*) malloc(nClusters/sizeof(char) + 1); //size of one node-hitlist in units of char int chunk = nClusters/(sizeof(char)*8) + 1; //initialize virgin hitlist to 1-bits only memset(root_hitlist,0xFF,chunk); //set up the IFC IFC->setKernelPars(THREADS); IFC->initClusters(clusterList); IFC->initParameterSpace(mins, maxs); IFC->setCutoff((float)cutoffDec/10); IFC->setCutoffLevel(cutoffLevel); std::vector* nodelist= new std::vector(); unsigned int* votes; IFC->setHitList(root_hitlist,1); //init rood node std::cout<<"Init root node: "<push_back(root); IFC->testIntersection(nodelist,0,THRESHOLD); votes = IFC->getVotes(); std::cout<<"\nroot node received "<* last_nodes = new std::vector(); // float thresh_min=35; // float thresh_step = (THRESHOLD-thresh_min)/TREE_DEPTH; // std::cout<<"thresh_step: "<* new_nodes = new std::vector(); //avoid resizing new_nodes->reserve(MAXSIZE); std::cout << nodelist->size(); std::cout.flush(); new_hitlist = (char*) malloc(count*32*chunk); std::cout << " " << (void*) new_hitlist << std::endl; if(l>1) old_hitlist = IFC->getHitList(); int counter=0; //create new nodes for(int n=0; nsize(); ++n) { // for(int c=0; cgetSonArray(); if(l=THRESHOLD) { the_node->setVotes(votes[n]); //copy this nodes' hitlist to the new one //son hitlist duplication happens in the IFC memcpy(new_hitlist+chunk*counter, old_hitlist+n*chunk, chunk); for(int s=0; s<32; s++) { new_nodes->push_back(new Hough5DNode(sons+5*s,l,nClusters)); } counter++; } else { delete (*nodelist)[n]; (*nodelist)[n] = NULL; } } //dynamic thresholding based on last generation's vote else { if(votes[n] >= ((*last_nodes)[(int)n/32])->getVote()*SCALE) { memcpy(new_hitlist+chunk*counter, old_hitlist+n*chunk, chunk); counter++; the_node->setVotes(votes[n]); for(int s=0; s<32; ++s) { new_nodes->push_back(new Hough5DNode(sons+5*s,l,nClusters)); } } else { delete (*nodelist)[n]; (*nodelist)[n] = NULL; } } //not necessary? free(sons); } for(int x=0; xsize(); x++) delete (*last_nodes)[x]; if(l<=TREE_DEPTH-1) last_nodes->clear(); int lcount=0; for(int n=0; nsize(); n++) if((*nodelist)[n] != NULL) { lcount++; last_nodes->push_back((*nodelist)[n]); } std::cout<<"setting hitlist"<setHitList(new_hitlist,counter); free(new_hitlist); std::cout<<"Added "<size()<<" last_nodes" <<" (count="<clear(); nodelist=new_nodes; //for(int i=0; isize(); i++) // last_nodes->at(i)->print(); //std::cout<<"Calling Intersect-Kernel with THRESHOLD: " //<testIntersection(nodelist,l,THRESHOLD); //else //IFC->testIntersection(*nodelist,l,35); //IFC->testIntersection(*nodelist,l,THRESHOLD-l*thresh_step); votes = IFC->getVotes(); count=0; for(int k=0; ksize(); ++k) { if(l<5) { if(votes[k] >= THRESHOLD) count++; } else if(votes[k] >= last_nodes->at((int)k/32)->getVote()*SCALE) count++; } std::cout<<"LEVEL "<size()<<" checked the test"<size(); x++){ (nodelist->at(x))->setVotes(votes[x]); } // --------------------- END FHT ------------------------------------------------ timer.Stop(); TFile* file = new TFile("plots.root"); TH2D* phic = (TH2D*)file->Get("phic_80"); std::vector boxlist; for(int n=0; nsize(); n++) { //(solution_list[s])->print(); //if((*nodelist)[n]->getVote() > last_nodes->at((int)n/32)->getVote()*SCALE) { if((*nodelist)[n]->getVote() >= THRESHOLD*0.85) { float* center = ((*nodelist)[n])->getCenter(); float length = ((*nodelist)[n])->getSideLength(); float x1 = (center[3] - 0.5*length)*(m_Max-m_Min); float x2 = (center[3] + 0.5*length)*(m_Max-m_Min); float y1 = (center[4] - 0.5*length)*(t_Max-t_Min); float y2 = (center[4] + 0.5*length)*(t_Max-t_Min); boxlist.push_back(new TBox(x1,y1,x2,y2)); } } gStyle->SetPalette(1); gROOT->SetStyle("Plain"); TCanvas* canv = new TCanvas(); //canv->SetGrayscale(); houghRZ->Draw(); for(int b=0; bSetLineColor(kPink+10); (boxlist[b])->SetFillStyle(0); (boxlist[b])->Draw("l"); } std::vector boxlist2; for(int s=0; ssize(); s++) { //if(nodelist->at(s)->getVote() > last_nodes->at((int)s/32)->getVote()*SCALE) { if(nodelist->at(s)->getVote() >= THRESHOLD*0.85) { float* center = (nodelist->at(s))->getCenter(); float length = (nodelist->at(s))->getSideLength(); float x1 = (center[0] - 0.5*length)*(phi_Max-phi_Min) +90; float x2 = (center[0] + 0.5*length)*(phi_Max-phi_Min) +90; float y1 = (center[2] - 0.5*length)*(c_Max-c_Min); float y2 = (center[2] + 0.5*length)*(c_Max-c_Min); boxlist2.push_back(new TBox(x1,y1,x2,y2)); } } TCanvas* canv2 = new TCanvas(); phic->Draw("COLZ"); for(int b=0; bSetLineColor(kPink+10); (boxlist2[b])->SetFillStyle(0); (boxlist2[b])->Draw("l"); } TH2D* sebastian_stinkt = new TH2D("seb", "Sebastian riecht streng", 100,phi_Min,phi_Max, 100, m_Min, m_Max); TCanvas* canv3 = new TCanvas(); std::vector boxlist3; //sparse->Projection(0,3)->Draw("COLZ"); sebastian_stinkt->Draw(); for(int s=0; ssize(); s++) { if(nodelist->at(s)->getVote() >= THRESHOLD*0.85) { float* center = (nodelist->at(s))->getCenter(); float length = (nodelist->at(s))->getSideLength(); float x1 = (center[0] - 0.5*length)*(phi_Max-phi_Min) +90; float x2 = (center[0] + 0.5*length)*(phi_Max-phi_Min) +90; float y1 = (center[3] - 0.5*length)*(m_Max-m_Min); float y2 = (center[3] + 0.5*length)*(m_Max-m_Min); boxlist3.push_back(new TBox(x1,y1,x2,y2)); } } for(int b=0; bSetLineColor(kPink+10); (boxlist3[b])->SetFillStyle(0); (boxlist3[b])->Draw("l"); } //PURGE NODES AND EXTRACT CLUSTERS -------------------------- if(tracking) { //make new clusterList std::vector finalClist; for(int i=0; ipos(); if(pos.X()>0) finalClist.push_back(clusterList[i]); } assert(finalClist.size() == nClusters); bool cont=true; char* hitlist = IFC->getHitList(); //list of clusters for each found track std::vector*> solutions; std::vector hists; std::vector colors; colors.push_back(kGreen); colors.push_back(kGreen-9); colors.push_back(kSpring+8); colors.push_back(kOrange-2); colors.push_back(kOrange+7); colors.push_back(kRed+3); colors.push_back(kRed); colors.push_back(kMagenta+2); colors.push_back(kBlue-6); colors.push_back(kBlue+1); colors.push_back(kAzure-3); //set votes in node objects for(int n=0; nsize(); n++) if((*nodelist)[n]->getVote()>0) { int c=0; for(int v=0; vsetHit(v); c++; } assert(c==(*nodelist)[n]->getVote()); } //extract tracks until solutions have less clusters than minCL while(cont) { //sort nodes by final votes sort((*nodelist).begin(), (*nodelist).end(), compareNodes); //extract clusters from best node bool* bestHitList = nodelist->front()->getHitList(); std::cout<front()->getVote()<* sol = new std::vector(); for(int c=0; cpush_back(finalClist[c]); if(sol->size()size(); n++) if((*nodelist)[n]->checkHit(p)) (*nodelist)[n]->removeHit(p); } solutions.push_back(sol); } TCanvas* blub = new TCanvas(); //blub->Divide(3,2); for(int i=0; isize(); p++) { TVector3 pos = (solutions[i])->at(p)->pos(); hists.back()->Fill(pos.X(), pos.Y()); } std::cout<<"\nFound Track with "<<(solutions[i])->size() <<" clusters"<SetMarkerColor(colors[i]); hists.back()->SetMarkerStyle(20); hists.back()->SetMarkerSize(0.5); //blub->cd(i+1); //hists.back()->SetLineWidth(3); if(i>0) hists.back()->Draw("same"); else hists.back()->Draw(); } } std::cout<<"Track qualification: more than "<SetReturnFromRun(true); //gApplication->Terminate(); gSystem->Run(); }