// @(#) $Id$ // Author: Anders Vestbo //*-- Copyright © ALICE HLT Group /** \class AliL3HoughTransformer
//_____________________________________________________________
// AliL3HoughTransformer
//
// Hough transformation class
//
*/ #include "AliL3StandardIncludes.h" #include "AliL3Logging.h" #include "AliL3HoughTransformer.h" #include "AliL3MemHandler.h" #include "AliL3Transform.h" #include "AliL3DigitData.h" #include "AliL3HistogramAdaptive.h" #if __GNUC__ == 3 using namespace std; #endif ClassImp(AliL3HoughTransformer) AliL3HoughTransformer::AliL3HoughTransformer() { //Default constructor fParamSpace = 0; fDoMC = kFALSE;; fEtaOverlap=kFALSE; #ifdef do_mc fTrackID = 0; #endif } AliL3HoughTransformer::AliL3HoughTransformer(Int_t slice,Int_t patch,Int_t netasegments,Bool_t DoEtaOverlap,Bool_t /*DoMC*/) : AliL3HoughBaseTransformer(slice,patch,netasegments) { //Normal constructor fParamSpace = 0; fDoMC = kFALSE; fEtaOverlap = DoEtaOverlap; fDoMC=kFALSE; #ifdef do_mc fTrackID = 0; #endif } AliL3HoughTransformer::~AliL3HoughTransformer() { // Dtor DeleteHistograms(); #ifdef do_mc if(fTrackID) { for(Int_t i=0; i ptmax) { cerr<<"AliL3HoughTransformer::CreateHistograms: Error in ptrange "<GetNbinsX()+2)*(hist->GetNbinsY()+2); cout<<"Transformer: Allocating "<Reset(); #ifdef do_mc if(fDoMC) { AliL3Histogram *hist = fParamSpace[0]; Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2); for(Int_t i=0; i= GetNEtaSegments() || etaindex < 0) return 0; if(!fParamSpace[etaindex]) return 0; return fParamSpace[etaindex]; } Double_t AliL3HoughTransformer::GetEta(Int_t etaindex,Int_t /*slice*/) const { // Return eta calculated in the middle of the eta slice Double_t etaslice = (GetEtaMax()-GetEtaMin())/GetNEtaSegments(); Double_t eta=0; if(fEtaOverlap) { Int_t index = etaindex + 1; eta=(Double_t)((index)*etaslice); } else eta=(Double_t)((etaindex+0.5)*etaslice); return eta; } void AliL3HoughTransformer::TransformCircle() { //Transform the input data with a circle HT. //The function loops over all the data, and transforms each pixel with the equations: // //kappa = 2/r*sin(phi - phi0) // //where r = sqrt(x*x +y*y), and phi = arctan(y/x) // //Each pixel then transforms into a curve in the (kappa,phi0)-space. In order to find //which histogram in which the pixel should be transformed, the eta-value is calculated //and the proper histogram index is found by GetEtaIndex(eta). AliL3DigitRowData *tempPt = GetDataPointer(); if(!tempPt) { LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data") <<"No input data "<fDigitData; if(i != (Int_t)tempPt->fRow) { cerr<<"AliL3HoughTransform::TransformCircle : Mismatching padrow numbering "<fRow<fNDigit; j++) { UShort_t charge = digPt[j].fCharge; UChar_t pad = digPt[j].fPad; UShort_t time = digPt[j].fTime; if((Int_t)charge <= GetLowerThreshold()) continue; if((Int_t)charge > GetUpperThreshold()) charge = GetUpperThreshold(); Int_t sector,row; Float_t xyz[3]; //Transform data to local cartesian coordinates: AliL3Transform::Slice2Sector(GetSlice(),i,sector,row); AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time); //Calculate the eta: Double_t eta = AliL3Transform::GetEta(xyz); //Get the corresponding index, which determines which histogram to fill: Int_t etaindex = GetEtaIndex(eta); if(etaindex < 0 || etaindex >= GetNEtaSegments()) continue; //Get the correct histogrampointer: AliL3Histogram *hist = fParamSpace[etaindex]; if(!hist) { cerr<<"AliL3HoughTransformer::TransformCircle : Error getting histogram in index "<GetFirstYbin(); b<=hist->GetLastYbin(); b++) { Float_t phi0 = hist->GetBinCenterY(b); Float_t kappa = 2*sin(phi - phi0)/r; //hist->Fill(kappa,phi0,(int)rint(log((Float_t)charge))); hist->Fill(kappa,phi0,charge); //hist->Fill(kappa,phi0,1); #ifdef do_mc if(fDoMC) { Int_t bin = hist->FindBin(kappa,phi0); for(Int_t t=0; t<3; t++) { Int_t label = digPt[j].fTrackID[t]; if(label < 0) break; UInt_t c; for(c=0; c= AliL3Transform::GetLastRow(GetPatch())) minrow = AliL3Transform::GetFirstRow(GetPatch()); if(maxrow < AliL3Transform::GetFirstRow(GetPatch()) || maxrow >= AliL3Transform::GetLastRow(GetPatch())) maxrow = AliL3Transform::GetLastRow(GetPatch()); if(minrow > maxrow || maxrow==minrow) { cerr<<"AliL3HoughTransformer::TransformCircleC : Bad row range "<fNDigit; AliL3MemHandler::UpdateRowPointer(tempPt); } Int_t bound = (GetNEtaSegments()+1)*(AliL3Transform::GetNRows(GetPatch())+1); AliL3EtaContainer *etaPt = new AliL3EtaContainer[bound]; memset(etaPt,0,bound*sizeof(AliL3EtaContainer)); AliL3Digit *digits = new AliL3Digit[counter]; cout<<"Allocating "<fDigitData; for(UInt_t di=0; difNDigit; di++) { charge = digPt[di].fCharge; pad = digPt[di].fPad; time = digPt[di].fTime; AliL3Transform::Slice2Sector(GetSlice(),i,sector,row); AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time); eta = AliL3Transform::GetEta(xyz); digits[counter].fRow = i; digits[counter].fR = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]); digits[counter].fPhi = atan2(xyz[1],xyz[0]); digits[counter].fCharge = charge; if(!fEtaOverlap) { Int_t etaindex = GetEtaIndex(eta); Int_t index = (GetNEtaSegments()+1)*(i-AliL3Transform::GetFirstRow(GetPatch())) + etaindex; if(index > 0 && index < bound) { if(etaPt[index].fFirst == 0) etaPt[index].fFirst = &digits[counter]; else (etaPt[index].fLast)->fNext = &digits[counter]; etaPt[index].fLast = &digits[counter]; } } else { Int_t etaindex[2]; GetEtaIndexes(eta,etaindex); Int_t index[2]; index[0] = (GetNEtaSegments()+1)*(i-AliL3Transform::GetFirstRow(GetPatch())) + etaindex[0]; index[1] = (GetNEtaSegments()+1)*(i-AliL3Transform::GetFirstRow(GetPatch())) + etaindex[1]; if(index[0] == index[1]) { cerr<<"Same etaindexes "< 0 && ind < bound) { if(etaPt[ind].fFirst == 0) etaPt[ind].fFirst = &digits[counter]; else (etaPt[ind].fLast)->fNext = &digits[counter]; etaPt[ind].fLast = &digits[counter]; } ind = index[1]; if(ind > 0 && ind < bound) { if(etaPt[ind].fFirst == 0) etaPt[ind].fFirst = &digits[counter]; else (etaPt[ind].fLast)->fNext = &digits[counter]; etaPt[ind].fLast = &digits[counter]; } } counter++; } AliL3MemHandler::UpdateRowPointer(tempPt); } cout<<"Doing the combinatorics"<fNext) { for(Int_t j=i+every; j<=maxrow; j+=every) { Int_t index2 = (GetNEtaSegments()+1)*(j-AliL3Transform::GetFirstRow(GetPatch())) + e; for(dPt2 = (AliL3Digit*)etaPt[index2].fFirst; dPt2 != 0; dPt2 = (AliL3Digit*)dPt2->fNext) { if(dPt1->fRow == dPt2->fRow) { cerr<<"same row; indexes "<fR; phi1 = dPt1->fPhi; r2 = dPt2->fR; phi2 = dPt2->fPhi; phi0 = atan( (r2*sin(phi1)-r1*sin(phi2))/(r2*cos(phi1)-r1*cos(phi2)) ); kappa = 2*sin(phi2-phi0)/r2; totcharge = dPt1->fCharge + dPt2->fCharge; hist->Fill(kappa,phi0,totcharge); } } } } } cout<<"done"<= AliL3Transform::GetLastRow(GetPatch())) minrow = AliL3Transform::GetFirstRow(GetPatch()); if(maxrow < AliL3Transform::GetFirstRow(GetPatch()) || maxrow >= AliL3Transform::GetLastRow(GetPatch())) maxrow = AliL3Transform::GetLastRow(GetPatch()); if(minrow > maxrow || maxrow==minrow) { cerr<<"AliL3HoughTransformer::TransformCircleC : Bad row range "<fDigitData; if(i != (Int_t)tempPt->fRow) { printf("AliL3HoughTransform::TransformLine : Mismatching padrow numbering\n"); continue; } for(UInt_t j=0; jfNDigit; j++) { UShort_t charge = digPt[j].fCharge; UChar_t pad = digPt[j].fPad; UShort_t time = digPt[j].fTime; if(charge < GetLowerThreshold()) continue; Int_t sector,row; Float_t xyz[3]; AliL3Transform::Slice2Sector(GetSlice(),i,sector,row); AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time); if(phirange) { Float_t phi = AliL3Transform::GetPhi(xyz); if(phi < phirange[0] || phi > phirange[1]) continue; } Float_t eta = AliL3Transform::GetEta(xyz); Int_t etaindex = GetEtaIndex(eta);//(Int_t)(eta/etaslice); if(etaindex < 0 || etaindex >= GetNEtaSegments()) continue; xyz[0] = xyz[0] - AliL3Transform::Row2X(minrow); //Get the correct histogram: AliL3Histogram *hist = fParamSpace[etaindex]; if(!hist) { printf("AliL3HoughTransformer::TransformLine : Error getting histogram in index %d\n",etaindex); continue; } for(Int_t xbin=hist->GetFirstXbin(); xbinGetLastXbin(); xbin++) { Double_t theta = hist->GetBinCenterX(xbin); Double_t rho = xyz[0]*cos(theta) + xyz[1]*sin(theta); hist->Fill(theta,rho,charge); } } AliL3MemHandler::UpdateRowPointer(tempPt); } } struct AliL3LDigit { Int_t fRow; // Digit rowpad Int_t fCharge; // Digit charge Float_t fY; // Y position of the digit in the local coor system AliL3LDigit *fNext; // Next digit }; struct AliL3LEtaContainer { AliL3LDigit *fFirst; //First digit AliL3LDigit *fLast; //Last digit }; void AliL3HoughTransformer::TransformLineC(Int_t *rowrange,Float_t *phirange) { //Circle transform ?? AliL3DigitRowData *tempPt = GetDataPointer(); if(!tempPt) LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircleC","Data") <<"No input data "<fNDigit; AliL3MemHandler::UpdateRowPointer(tempPt); } Int_t bound = (GetNEtaSegments()+1)*(AliL3Transform::GetNRows(GetPatch())+1); AliL3LEtaContainer *etaPt = new AliL3LEtaContainer[bound]; memset(etaPt,0,bound*sizeof(AliL3LEtaContainer)); AliL3LDigit *digits = new AliL3LDigit[counter]; cout<<"Allocating "<fDigitData; for(UInt_t di=0; difNDigit; di++) { Int_t charge = digPt[di].fCharge; Int_t pad = digPt[di].fPad; Int_t time = digPt[di].fTime; AliL3Transform::Slice2Sector(GetSlice(),i,sector,row); AliL3Transform::Raw2Local(xyz,sector,row,(Int_t)pad,(Int_t)time); Double_t eta = AliL3Transform::GetEta(xyz); Float_t phi = atan2(xyz[1],xyz[0]); if(phi < phirange[0] || phi > phirange[1]) continue; digits[counter].fRow = i; digits[counter].fY = xyz[1]; digits[counter].fCharge = charge; Int_t etaindex = GetEtaIndex(eta); Int_t index = (GetNEtaSegments()+1)*(i-AliL3Transform::GetFirstRow(GetPatch())) + etaindex; if(index > 0 && index < bound) { if(etaPt[index].fFirst == 0) etaPt[index].fFirst = &digits[counter]; else (etaPt[index].fLast)->fNext = &digits[counter]; etaPt[index].fLast = &digits[counter]; } counter++; } AliL3MemHandler::UpdateRowPointer(tempPt); } cout<<"Doing the combinatorics"<fNext) { for(Int_t j=i+1; j<=rowrange[1]; j++) { Int_t index2 = (GetNEtaSegments()+1)*(j-AliL3Transform::GetFirstRow(GetPatch())) + e; for(dPt2 = (AliL3LDigit*)etaPt[index2].fFirst; dPt2 != 0; dPt2 = (AliL3LDigit*)dPt2->fNext) { if(dPt1->fRow == dPt2->fRow) { cerr<<"same row; indexes "<fRow) - AliL3Transform::Row2X(rowrange[0]); float x2 = AliL3Transform::Row2X(dPt2->fRow) - AliL3Transform::Row2X(rowrange[0]); float y1 = dPt1->fY; float y2 = dPt2->fY; float theta = atan2(x2-x1,y1-y2); float rho = x1*cos(theta)+y1*sin(theta); hist->Fill(theta,rho,1);//dPt1->charge+dPt2->charge); } } } } } cout<<"done"< GetNEtaSegments()) { cerr<<"AliL3HoughTransformer::GetTrackID : Wrong etaindex "<FindBin(kappa,psi); Int_t label=-1; Int_t max=0; for(UInt_t i=0; i max) { max = nhits; label = fTrackID[etaindex][bin].fLabel[i]; } } //nhits = max; return label; #else Int_t AliL3HoughTransformer::GetTrackID(Int_t /*etaindex*/,Double_t /*kappa*/,Double_t /*psi*/) const { // Returns the MC label for a given peak found in the Hough space if(!fDoMC) { cerr<<"AliL3HoughTransformer::GetTrackID : Flag switched off"<