// @(#) $Id$ // Author: Anders Vestbo , Constantin Loizides //*-- Copyright © ALICE HLT Group #include "AliL3StandardIncludes.h" #include "AliL3RootTypes.h" #include "AliL3Logging.h" #include "AliL3ClustFinderNew.h" #include "AliL3DigitData.h" #include "AliL3Transform.h" #include "AliL3SpacePointData.h" #include "AliL3MemHandler.h" #if __GNUC__ == 3 using namespace std; #endif /** \class AliL3ClustFinderNew
//_____________________________________________________________
// AliL3ClustFinderNew
//
// The current cluster finder for HLT
// (Based on STAR L3)
// 
// The cluster finder is initialized with the Init function, 
// providing the slice and patch information to work on. 
// The input is a AliL3DigitRowData structure using the 
// Read function. The resulting space points will be in the
// array given by the SetOutputArray function.
// 
// There are several setters which control the behaviour:
//
// - SetXYError(Float_t):   set fixed error in XY direction
// - SetZError(Float_t):    set fixed error in Z  direction
//                            (used if errors are not calculated) 
// - SetDeconv(Bool_t):     switch on/off deconvolution
// - SetThreshold(UInt_t):  set charge threshold for cluster
// - SetMatchWidth(UInt_t): set the match distance in 
//                            time for sequences to be merged 
// - SetSTDOutput(Bool_t):  switch on/off output about found clusters   
// - SetCalcErr(Bool_t):    switch on/off calculation of 
//                          space point errors (or widths in raw system)
// - SetRawSP(Bool_t):      switch on/off convertion to raw system
//
//
// Example Usage:
//
// AliL3FileHandler *file = new AliL3FileHandler();
// file->SetAliInput(digitfile); //give some input file
// for(int slice=0; slice<=35; slice++){
//   for(int patch=0; pat<6; pat++){
//     file->Init(slice,patch);
//     UInt_t ndigits=0;
//     UInt_t maxclusters=100000;
//     UInt_t pointsize = maxclusters*sizeof(AliL3SpacePointData);
//     AliL3SpacePointData *points = (AliL3SpacePointData*)memory->Allocate(pointsize);
//     AliL3DigitRowData *digits = (AliL3DigitRowData*)file->AliAltroDigits2Memory(ndigits,event);
//     AliL3ClustFinderNew *cf = new AliL3ClustFinderNew();
//     cf->SetMatchWidth(2);
//     cf->InitSlice(slice,patch,maxclusters);
//     cf->SetSTDOutput(kTRUE);    //Some output to standard IO
//     cf->SetRawSP(kFALSE);       //Convert space points to local system
//     cf->SetThreshold(5);        //Threshold of cluster charge
//     cf->SetDeconv(kTRUE);       //Deconv in pad and time direction
//     cf->SetCalcErr(kTRUE);      //Calculate the errors of the spacepoints
//     cf->SetOutputArray(points); //Move the spacepoints to the array
//     cf->Read(ndigits,digits);   //give the data to the cf
//     cf->ProcessDigits();        //process the rows given by init
//     Int_t npoints = cf->GetNumberOfClusters();
//     AliL3MemHandler *out= new AliL3MemHandler();
//     out->SetBinaryOutput(fname);
//     out->Memory2Binary(npoints,points); //store the spacepoints
//     out->CloseBinaryOutput();
//     delete out;
//     file->free();
//     delete cf;
//   }
// }
*/ ClassImp(AliL3ClustFinderNew) AliL3ClustFinderNew::AliL3ClustFinderNew() { //constructor fMatch = 1; fThreshold = 10; fXYErr = 0.2; fZErr = 0.3; fDeconvPad = kTRUE; fDeconvTime = kTRUE; fStdout = kFALSE; fCalcerr = kTRUE; fRawSP = kFALSE; fFirstRow=0; fLastRow=0; } AliL3ClustFinderNew::~AliL3ClustFinderNew() { //destructor ; } void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints) { //init slice fNClusters = 0; fMaxNClusters = nmaxpoints; fCurrentSlice = slice; fCurrentPatch = patch; fFirstRow = firstrow; fLastRow = lastrow; } void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints) { //init slice fNClusters = 0; fMaxNClusters = nmaxpoints; fCurrentSlice = slice; fCurrentPatch = patch; fFirstRow=AliL3Transform::GetFirstRow(patch); fLastRow=AliL3Transform::GetLastRow(patch); } void AliL3ClustFinderNew::SetOutputArray(AliL3SpacePointData *pt) { //set pointer to output fSpacePointData = pt; } void AliL3ClustFinderNew::Read(UInt_t ndigits,AliL3DigitRowData *ptr) { //set input pointer fNDigitRowData = ndigits; fDigitRowData = ptr; } void AliL3ClustFinderNew::ProcessDigits() { //Loop over rows, and call processrow AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fDigitRowData; fNClusters = 0; for(Int_t i=fFirstRow; i<=fLastRow; i++) { fCurrentRow = i; if((Int_t)tempPt->fRow!=fCurrentRow){ LOG(AliL3Log::kWarning,"AliL3ClustFinderNew::ProcessDigits","Digits") <<"Row number should match! "<fRow<<" "<fNDigit*sizeof(AliL3DigitData); tmp += size; tempPt = (AliL3DigitRowData*)tmp; } LOG(AliL3Log::kInformational,"AliL3ClustFinderNew::ProcessDigits","Space points") <<"Cluster finder found "<fNDigit; bin++) { AliL3DigitData *data = tempPt->fDigitData; if(data[bin].fPad != lastpad) { //This is a new pad //Switch the lists: if(currentPt == pad2) { currentPt = pad1; previousPt = pad2; } else { currentPt = pad2; previousPt = pad1; } nprevious = ncurrent; ncurrent = 0; if(bin[data].fPad != lastpad+1) { //this happens if there is a pad with no signal. nprevious = ncurrent = 0; } lastpad = data[bin].fPad; } Bool_t newcluster = kTRUE; UInt_t seqcharge=0,seqaverage=0,seqerror=0; UInt_t lastcharge=0,lastwas_falling=0; Int_t newbin=-1; if(fDeconvTime) { redo: //This is a goto. if(newbin > -1) { bin = newbin; newbin = -1; } lastcharge=0; lastwas_falling = 0; } while(1) //Loop over current sequence { if(data[bin].fTime >= AliL3Transform::GetNTimeBins()) { LOG(AliL3Log::kFatal,"AliL3ClustFinderNew::ProcessRow","Digits") <<"Timebin out of range "<<(Int_t)data[bin].fTime< lastcharge) { if(lastwas_falling) { newbin = bin; break; } } else lastwas_falling = 1; //last pixel was larger than this lastcharge = charge; } //Sum the total charge of this sequence seqcharge += charge; seqaverage += data[bin].fTime*charge; seqerror += data[bin].fTime*data[bin].fTime*charge; //Check where to stop: if(bin >= tempPt->fNDigit - 1) //out of range break; if(data[bin+1].fPad != data[bin].fPad) //new pad break; if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence break; bin++; }//end loop over sequence //Calculate mean of sequence: Int_t seqmean=0; if(seqcharge) seqmean = seqaverage/seqcharge; else { LOG(AliL3Log::kFatal,"AliL3ClustFinderNew::ProcessRow","Data") <<"Error in data given to the cluster finder"<fLastMergedPad==data[bin].fPad) continue; Int_t difference = seqmean - previousPt[p]->fMean; if(difference < -fMatch) break; if(difference <= fMatch) //There is a match here!! { AliClusterData *local = previousPt[p]; if(fDeconvPad) { if(seqcharge > local->fLastCharge) { if(local->fChargeFalling) //The previous pad was falling { break; //create a new cluster } } else local->fChargeFalling = 1; local->fLastCharge = seqcharge; } //Don't create a new cluster, because we found a match newcluster = kFALSE; //Update cluster on current pad with the matching one: local->fTotalCharge += seqcharge; local->fPad += padmean; local->fPad2 += paderror; local->fTime += seqaverage; local->fTime2 += seqerror; local->fMean = seqmean; local->fFlags++; //means we have more than one pad local->fLastMergedPad = data[bin].fPad; currentPt[ncurrent] = local; ncurrent++; break; } //Checking for match at previous pad } //Loop over results on previous pad. if(newcluster) { //Start a new cluster. Add it to the clusterlist, and update //the list of pointers to clusters in current pad. //current pad will be previous pad on next pad. //Add to the clusterlist: AliClusterData *tmp = &clusterlist[ntotal]; tmp->fTotalCharge = seqcharge; tmp->fPad = padmean; tmp->fPad2 = paderror; tmp->fTime = seqaverage; tmp->fTime2 = seqerror; tmp->fMean = seqmean; tmp->fFlags = 0; //flags for single pad clusters tmp->fLastMergedPad = data[bin].fPad; if(fDeconvPad) { tmp->fChargeFalling = 0; tmp->fLastCharge = seqcharge; } //Update list of pointers to previous pad: currentPt[ncurrent] = &clusterlist[ntotal]; ntotal++; ncurrent++; } if(fDeconvTime) if(newbin >= 0) goto redo; }//Loop over digits on this padrow WriteClusters(ntotal,clusterlist); } void AliL3ClustFinderNew::WriteClusters(Int_t nclusters,AliClusterData *list) { //write cluster to output pointer Int_t thisrow,thissector; UInt_t counter = fNClusters; for(int j=0; j= fMaxNClusters) { LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder") <fRow < (UInt_t)fCurrentRow){ AliL3MemHandler::UpdateRowPointer(rowPt); continue; } AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData; for(UInt_t j=0; jfNDigit; j++){ Int_t cpad = digPt[j].fPad; Int_t ctime = digPt[j].fTime; if(cpad != pad) continue; if(ctime != time) continue; trackID[0] = digPt[j].fTrackID[0]; trackID[1] = digPt[j].fTrackID[1]; trackID[2] = digPt[j].fTrackID[2]; //cout<<"Reading row "<