//cluster finder for the GEM IROC //author: philipp gadow (bachelor student) E18/E12 //terrible performance, incredibly slow! #include "TpcClusterFinderSimpleALICE.h" #include #include #include #include "assert.h" #include "TpcPadPlane.h" #include "TpcPad.h" #include "TpcCluster.h" #include "TpcDigi.h" #include "TpcDigiMapper.h" #include "TpcDigiAmplitude.h" #include "McId.h" #include "McIdCollection.h" #include "TpcPrelimCluster.h" #include "TStopwatch.h" #ifdef TESTCHAMBER #include "Pedestals.h" #endif //constructor -------------------------------------------------------------------------------------- TpcClusterFinderSimpleALICE::TpcClusterFinderSimpleALICE(TpcPadPlane* p, std::vector* ob, unsigned int timeslice, double G, double C) : fpadplane(p), foutput_buffer(ob), fdt(timeslice), noXclust(false), splitDigis(0), fG(G), fC(C), maxClusterSlice(4000), sectorize(true), fnSectors(1), zJitter(0.1), verbose(false) { // construct sector map std::vector ids=fpadplane->GetSectorIds(); fnSectors=ids.size(); for(unsigned int is=0;is(); } std::cout<<"TpcClusterFinderSimpleALICE: " < borderPads; // pads that lie at sector borders nPads = fpadplane->GetNPads(); // loop over pads and find pads at borders for (unsigned int iPad=0; iPadGetPad(iPad); sectorID = pad->sectorId(); fpadIDsectorIDmap[iPad] = new std::vector (1, sectorID); //loop over neighbors nNeighbors = pad->nNeighbours(); for (unsigned int ineigh=0; ineighGetPad(pad->getNeighbour(ineigh))->sectorId(); if (neighID == sectorID) continue; borderPads.push_back(iPad); break; } } double overlap(1.1); double x, y; unsigned int padId, padIdNeigh, nPadsInArea;; // loop over digis at borders for (unsigned int i=0; iGetPad(padId)->sectorId(); std::vector buffer; fpadplane->GetPadXY(padId, x, y); fpadplane->GetPadList(x, y, overlap, buffer); // loop over pads in area nPadsInArea = buffer.size(); for (unsigned int iPad=0; iPadpadId(); if ( (std::find(fpadIDsectorIDmap[padIdNeigh]->begin(), fpadIDsectorIDmap[padIdNeigh]->end(), sectorID)) == fpadIDsectorIDmap[padIdNeigh]->end() ){ fpadIDsectorIDmap[padIdNeigh]->push_back(sectorID); } } } std::cout<<"... done"<* sectorIDs; for (unsigned int iPad=0; iPadsize(); ++i){ std::cout<<(*sectorIDs)[i]<<" "; } std::cout<<"\n"; }*/ //this block is to define the z jitter McId dummyID(1,1,0); McIdCollection dummyColl; dummyColl.AddID(dummyID); TVector3 zDiff1,zDiff2; TpcDigi zDiffDigi1(1,1,1,dummyColl),zDiffDigi2(1,2,1,dummyColl); try { TpcDigiMapper::getInstance()->map(&zDiffDigi1,zDiff1); TpcDigiMapper::getInstance()->map(&zDiffDigi2,zDiff2); } catch(const std::exception& ex) { std::cout<*>::iterator secIt=fsectormap.begin(); while(secIt!=fsectormap.end()){ delete secIt->second; ++secIt; } fsectormap.clear(); std::map*>::iterator padIDIt=fpadIDmap.begin(); while(padIDIt!=fpadIDmap.end()){ delete padIDIt->second; ++padIDIt; } fpadIDmap.clear(); } void TpcClusterFinderSimpleALICE::process(std::vector& alldigis) { unsigned int nalldigi = alldigis.size(); if(nalldigi<3) return; if(sectorize && fnSectors>1){ std::cerr<<"processing digis sectorwise"<* >::iterator secIt=fsectormap.begin(); while(secIt!=fsectormap.end()){ // loop over sectors secIt->second->reserve(nalldigi/fsectormap.size()+250); ++secIt; } // end loop over sectors std::vector* sectorIDs; // sectorize on pad plane for(int idi=0;idipadId()]; for(unsigned int i=0; isize(); ++i){ fsectormap[(*sectorIDs)[i]]->push_back(alldigis[idi]); } } // end loop over digis // now process each sector independently secIt=fsectormap.begin(); while(secIt!=fsectormap.end()){ // loop over sectors processSector(*(secIt->second), secIt->first); secIt->second->clear(); // clean up ++secIt; } // end loop over sectors } else { // std::cerr<<"processing all digis"< &neighbourpaddigis, unsigned int firstpadidinrow, unsigned int lastpadidinrow, unsigned int timewindow){ TStopwatch timeformaxsearch; timeformaxsearch.Start(); unsigned int rdigipadID = rdigi->padId(); neighbourpaddigis.clear(); // look at digis in left pad if they are adjacent in time if (rdigipadID > firstpadidinrow && rdigipadID < lastpadidinrow){ unsigned int nleft = fpadIDmap[rdigipadID -1]->size(); for (unsigned int ileft = 0; ileft < nleft; ileft++){ if (fpadIDmap[rdigipadID -1]->at(ileft)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID -1]->at(ileft)->t() >= rdigi->t()-timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID -1]->at(ileft)); } } unsigned int nright = fpadIDmap[rdigipadID +1]->size(); for (unsigned int iright = 0; iright < nright; iright++){ if (fpadIDmap[rdigipadID +1]->at(iright)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID +1]->at(iright)->t() >= rdigi->t()- timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID +1]->at(iright)); } } unsigned int nsame = fpadIDmap[rdigipadID]->size(); for (unsigned int isame = 0; isame < nsame; isame++){ if (fpadIDmap[rdigipadID]->at(isame)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID]->at(isame)->t() >= rdigi->t()- timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID]->at(isame)); } } } // look at digis in right pad if they are adjacent in time if (rdigipadID == lastpadidinrow){ unsigned int nleft = fpadIDmap[rdigipadID -1]->size(); for (unsigned int ileft = 0; ileft < nleft; ileft++){ if (fpadIDmap[rdigipadID -1]->at(ileft)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID -1]->at(ileft)->t() >= rdigi->t()-timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID -1]->at(ileft)); } } unsigned int nsame = fpadIDmap[rdigipadID]->size(); for (unsigned int isame = 0; isame < nsame; isame++){ if (fpadIDmap[rdigipadID]->at(isame)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID]->at(isame)->t() >= rdigi->t()- timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID]->at(isame)); } } } // look at digis on the same pad if they are adjacent in time if (rdigipadID == firstpadidinrow){ unsigned int nright = fpadIDmap[rdigipadID +1]->size(); for (unsigned int iright = 0; iright < nright; iright++){ if (fpadIDmap[rdigipadID +1]->at(iright)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID +1]->at(iright)->t() >= rdigi->t()- timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID +1]->at(iright)); } } unsigned int nsame = fpadIDmap[rdigipadID]->size(); for (unsigned int isame = 0; isame < nsame; isame++){ if (fpadIDmap[rdigipadID]->at(isame)->t() <= rdigi->t() + timewindow && fpadIDmap[rdigipadID]->at(isame)->t() >= rdigi->t()- timewindow){ neighbourpaddigis.push_back(fpadIDmap[rdigipadID]->at(isame)); } } } double rdigiamp = rdigi->amp(); //check if there is a local maximum: unsigned int nNeighbours = neighbourpaddigis.size(); for (unsigned int ineigh = 0; ineigh < nNeighbours; ineigh++){ if (neighbourpaddigis[ineigh]->amp() > rdigiamp){ timeformaxsearch.Stop(); Double_t mtime = timeformaxsearch.CpuTime(); timeformaxsearch.Reset(); std::cout << " fail ... it takes " << mtime << " to search for maximum"<= 4 && irow < 7) padsInRow = 70; if (irow >= 7 && irow < 10) padsInRow = 72; if (irow >=10 && irow < 13) padsInRow = 74; if (irow >=13 && irow < 16) padsInRow = 76; if (irow >=16 && irow < 19) padsInRow = 78; if (irow >=19 && irow < 22) padsInRow = 80; if (irow >=22 && irow < 25) padsInRow = 82; if (irow >=25 && irow < 28) padsInRow = 84; if (irow >=28 && irow < 31) padsInRow = 86; if (irow >=31 && irow < 34) padsInRow = 88; if (irow >=34 && irow < 37) padsInRow = 90; if (irow >=37 && irow < 40) padsInRow = 92; if (irow >=40 && irow < 43) padsInRow = 94; if (irow >=43 && irow < 46) padsInRow = 96; if (irow >=46 && irow < 49) padsInRow = 98; if (irow >=49 && irow < 52) padsInRow = 100; if (irow >=52 && irow < 55) padsInRow = 102; if (irow >=55 && irow < 58) padsInRow = 104; if (irow >=58 && irow < 61) padsInRow = 106; if (irow >=61 && irow < 63) padsInRow = 108; return padsInRow; } //The actual cluster finder (does not utilize the neighbours as in the pad plane for they can be wrong at the edges, does not use prelimclusters) void TpcClusterFinderSimpleALICE::processSector(std::vector& digis, int sectorID) { std::sort(digis.begin(),digis.end(),TpcDigiPadID()); // sort digis in padIDs unsigned int ndigi=digis.size(); if(ndigi<3) return; //make this configurable? TStopwatch timer; timer.Start(); // write all digis sorted in padIDs in the great fpadIDmap unsigned int npads = fpadplane->GetNPads(); // iterate over each padID and create a vector for the digis for each pad for (unsigned int ipadID = 0; ipadID < npads; ipadID++){ fpadIDmap[ipadID] = new std::vector(); } // the digis are sorted for their padIDs, so iterate over them for(unsigned int idigiP=0; idigiPpadId()]->push_back(tempDigi); if(verbose){ std::cout <<"padid: "<padId()<<"size: "<< fpadIDmap[tempDigi->padId()]->size() << std::endl; } } //end of digiloop timer.Stop(); Double_t ctime = timer.CpuTime(); timer.Reset(); std::cout << " it takes " << ctime << " to make fpadIDmap"< digisInRow; // find last and first pad in row if (irow>0){ firstpadidInRow += padsinrow(irow-1); } lastpadidInRow += padsinrow(irow); if(verbose){ std::cout <<"first and last pad: " <begin(), (fpadIDmap[iPad])->end()); } std::stable_sort(digisInRow.begin(),digisInRow.end(),TpcDigiAmplitude()); timer.Start(); for (unsigned int idigi = 0;idigi < digisInRow.size(); idigi++){ // check digis in one row for local maxima TpcDigi* rdigi = digisInRow[idigi]; std::vector neighbourpaddigis; if (islocalmaximum(rdigi, neighbourpaddigis, firstpadidInRow, lastpadidInRow, 1)){ // if it is a local maximum, the neighbourpads vector will be filled with the neighbouring digis // calculate pos, sig and amp from the local maximum and the adjacent digis TVector3 pos, sig; pos.SetXYZ(0,0,0); sig.SetXYZ(0,0,0); double amp = 0; unsigned int ndigisincluster = neighbourpaddigis.size(); // loop over digis to calculate cog TpcDigi* adigi; TVector3 thispos; for(unsigned int id=0;idamp(); try{ TpcDigiMapper::getInstance()->map(adigi,thispos); } catch(const std::exception& ex) { std::cout<getGas()->Dl(); double Dt = TpcDigiMapper::getInstance()->getGas()->Dt(); double driftl = fabs(pos.z() - TpcDigiMapper::getInstance()->zGem()); double diffSigmaT = Dt * Dt * driftl; double diffSigmaL = Dl * Dl * driftl; double dx, dy; TpcDigiMapper::getInstance()->padsize(neighbourpaddigis[0]->padId(),dx,dy); TVector3 df, thissig; //old error calc starts here for(unsigned int id=0; idamp(); try { TpcDigiMapper::getInstance()->map(adigi,thispos); } catch(const std::exception& ex) { std::cout<isSaturated()){ clu->setSaturation(true); } clu->addDigi(neighbourpaddigis[i], 1); //MUST ADD DIGI WEIGHTING! } foutput_buffer->push_back(clu); if(verbose){ std::cout<<"cluster saved, now we have #clusters: " << foutput_buffer->size()<GetPad(rdigi->padId())->sectorId() == sectorID){ TpcCluster* clu = new TpcCluster(pos,sig,amp,sectorID); //add digis to cluster for(unsigned int i=0;iisSaturated()){ clu->setSaturation(true); } clu->addDigi(neighbourpaddigis[i], 1); //MUST ADD DIGI WEIGHTING! } foutput_buffer->push_back(clu); if(verbose){ std::cout<<"cluster saved, with sectorid and now we have #clusters: " << foutput_buffer->size()<