/************************************************************************** * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ #include #include "AliITSOnlineSDDInjectors.h" #include "AliLog.h" #include #include #include #include #include /* $Id$ */ /////////////////////////////////////////////////////////////////// // // // Implementation of the class used for SDD injector analysis // // Origin: F.Prino, Torino, prino@to.infn.it // // // /////////////////////////////////////////////////////////////////// ClassImp(AliITSOnlineSDDInjectors) const Float_t AliITSOnlineSDDInjectors::fgkSaturation = 1008.; const Float_t AliITSOnlineSDDInjectors::fgkDefaultLThreshold1 = 8.; const Float_t AliITSOnlineSDDInjectors::fgkDefaultLThreshold = 15.; const Float_t AliITSOnlineSDDInjectors::fgkDefaultHThreshold1 =15.; const Float_t AliITSOnlineSDDInjectors::fgkDefaultHThreshold = 30.; const Float_t AliITSOnlineSDDInjectors::fgkDefaultMinSpeed = 5.5; const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxSpeed = 9.0; const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxErr = 1.5; const Int_t AliITSOnlineSDDInjectors::fgkDefaultPolDegree = 3; const Float_t AliITSOnlineSDDInjectors::fgkDefaultTimeStep = 50.; const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMin[kInjLines] = {10,50,100}; const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMax[kInjLines] = {20,70,120}; //______________________________________________________________________ AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors(): AliITSOnlineSDD(), fHisto(), fTbZero(0.), fRMSTbZero(0.), fNEvents(0), fParam(), fPolDegree(0), fActualPolDegree(0), fMinDriftSpeed(0.), fMaxDriftSpeed(0.), fMaxDriftSpeedErr(0.), fFirstPadForFit(0), fLastPadForFit(0), fPadStatusCutForFit(0), fTimeStep(0.), fUseTimeZeroSignal(kFALSE), fMaxCellsAboveThreshold(40) { // default constructor SetPositions(); SetDefaults(); SetTimeStep(fgkDefaultTimeStep); for(Int_t i=0;ifPadStatusCutForFit){ fSumDriftSpeed[j]+=fDriftSpeed[j]; fSumSqDriftSpeed[j]+=fDriftSpeed[j]*fDriftSpeed[j]; fSumPadStatusCut[j]+=padStatus; fNEventsInPad[j]++; } } ++fNEvents; } //______________________________________________________________________ Double_t AliITSOnlineSDDInjectors::GetRMSDriftSpeed(Int_t ipad) const { // Compute RMS of drift speed distribution on one anode if(fNEventsInPad[ipad]<=1) return 0.; Double_t mean=fSumDriftSpeed[ipad]/(Double_t)fNEventsInPad[ipad]; Double_t diff=fSumSqDriftSpeed[ipad]/(Double_t)fNEventsInPad[ipad]-mean*mean; if(diff<0.) diff=0.; return TMath::Sqrt(diff); } //______________________________________________________________________ void AliITSOnlineSDDInjectors::FitMeanDriftSpeedVsAnode(){ // Fits the average drift speed vs.anode number if(fNEvents==0) return; for(Int_t i=0;i>ilin; if(fNEventsInPad[i]>1){ Double_t rms=GetRMSDriftSpeed(i); if(rms>0.) fDriftSpeedErr[i]=rms/TMath::Sqrt(fNEventsInPad[i]); }else{ for(Int_t ilin=0; ilin>ilin; } } //______________________________________________________________________ TGraphErrors* AliITSOnlineSDDInjectors::GetTimeVsDistGraph(Int_t jpad) const{ // Builds the graph of drift time vs. drift distance const Int_t kPts=kInjLines+1; Float_t x[kPts],y[kPts],ex[kPts],ey[kPts]; x[0]=0.; ex[0]=0.; y[0]=fTbZero; ey[0]=0.; for(Int_t i=0;i0){ g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]); g->SetPointError(ipt,0,fDriftSpeedErr[i]); ipt++; } } return g; } //______________________________________________________________________ TGraphErrors* AliITSOnlineSDDInjectors::GetSelectedDriftSpeedGraph(Int_t minAcceptStatus) const{ // TGraphErrors with only pads with status of injector >= minAcceptStatus Int_t ipt=0; TGraphErrors *g=new TGraphErrors(0); for(Int_t i=0;i0 && padStatus >= minAcceptStatus ){ g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]); g->SetPointError(ipt,0,fDriftSpeedErr[i]); ipt++; } } return g; } //______________________________________________________________________ void AliITSOnlineSDDInjectors::CalcTimeBinZero(){ // Get time zero from trigger signal Double_t tzero=0.,intCont=0.,rmsPeak=0.; Bool_t isTbUsed[256]; Int_t nTbUsed=0; for(Int_t i=0;i<256;i++) isTbUsed[i]=0; for(Int_t ian=0;ianGetBinContent(itb,ian+1); Double_t contm1=fHisto->GetBinContent(itb+1,ian+1); Double_t contp1=fHisto->GetBinContent(itb-1,ian+1); if(cont>fLowThreshold[0]){ if(cont>fHighThreshold[0] &&(contm1>fLowThreshold[0] || contp1>fLowThreshold[0])){ tzero+=cont*float(itb); rmsPeak+=cont*float(itb)*float(itb); intCont+=cont; if(!isTbUsed[itb]){ isTbUsed[itb]=1; ++nTbUsed; } } } } } if(intCont>0){ fTbZero=tzero/intCont; fRMSTbZero=TMath::Sqrt(rmsPeak/intCont-fTbZero*fTbZero); } if(nTbUsed==1) fRMSTbZero=0.5; } //______________________________________________________________________ void AliITSOnlineSDDInjectors::FitDriftSpeedVsAnode(){ // fits the anode dependence of drift speed Float_t rangeForMax[2]={78.,178.}; PolyFit(fPolDegree); fActualPolDegree=fPolDegree; if(fPolDegree==3){ Double_t deltasq=fParam[2]*fParam[2]-3*fParam[1]*fParam[3]; Double_t zero1=-999.; Double_t zero2=-999.; if(deltasq>=0. && TMath::Abs(fParam[3])>0.){ Double_t delta=TMath::Sqrt(deltasq); zero1=(-fParam[2]+delta)/3./fParam[3]; zero2=(-fParam[2]-delta)/3./fParam[3]; } Bool_t twoZeroes=kFALSE; Bool_t oneZero=kFALSE; if(zero1>0. && zero1<256. && zero2>0. && zero2<256.) twoZeroes=kTRUE; if(zero1>rangeForMax[0] && zero1rangeForMax[0] && zero2rangeForMax[0] && xmax0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){ Double_t wei=1./fDriftSpeedErr[jpad]/fDriftSpeedErr[jpad]; averSpeed+=wei*fDriftSpeed[jpad]; sumWei+=wei; nUsedPts++; } } if(sumWei>0.) averSpeed/=sumWei; if(nUsedPts0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){ vect[k1]+=fDriftSpeed[jpad]*TMath::Power(x,k1)/TMath::Power(fDriftSpeedErr[jpad],2); if(k1==0) npts++; for(Int_t k2=0;k2=big){ big=TMath::Abs(mat[j][k]); iRow=j; iCol=k; } } } } } iPivot[iCol]++; Double_t aux; if(iRow!=iCol){ for(Int_t l=0;l1){ if(fUseTimeZeroSignal){ sumY+=fTbZero/fRMSTbZero/fRMSTbZero; sumX+=0.; sumXX+=0.; sumYY+=fTbZero*fTbZero/fRMSTbZero/fRMSTbZero; sumXY+=0.; sumWEI+=1./fRMSTbZero/fRMSTbZero; } slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX); eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX)); } Double_t vel=0,evel=0; if(slope!=0. && fTimeStep>0.){ vel=1./slope*10000./fTimeStep;// micron/ns evel=eslope/slope/slope*10000./fTimeStep;// micron/ns } if(vel>fMaxDriftSpeed||velfMaxDriftSpeedErr){ vel=0.; evel=0.; } fDriftSpeed[jpad]=vel; fDriftSpeedErr[jpad]=evel; } //______________________________________________________________________ Int_t AliITSOnlineSDDInjectors::GetAnodeNumber(Int_t iInjPad) const{ // Injectors location along anodes: // Side left (UP) - channel 0: injectors on anodes 0,7,15,...,247,255 // Side right (DOWN) - channel 1: injectors on anodes 0,8,16,...,248,255 Int_t ian=-1; if(iInjPad>=kInjPads) return ian; if(fSide==1){ // right side ian=iInjPad*8; if(iInjPad==32) ian--; }else{ // left side ian=iInjPad*8-1; if(iInjPad==0) ian=0; } return ian; } //______________________________________________________________________ Int_t AliITSOnlineSDDInjectors::GetInjPadNumberFromAnode(Int_t nAnode) const{ // Converts anode number into injector pad index Int_t iInjPad=-1; if(fSide==1){ // right side if(nAnode%8==0) iInjPad=nAnode/8; if(nAnode==255) iInjPad=32; }else{ // left side if(nAnode%8==7) iInjPad=1+nAnode/8; if(nAnode==0) iInjPad=0; } if(nAnode>=256) iInjPad=-1; return iInjPad; } //______________________________________________________________________ Int_t AliITSOnlineSDDInjectors::GetInjPadStatus(Int_t jpad) const{ // returns an integer value with status of injector lines for given pad/anode // status=7 --> 111 all injector are good // status=6 --> 110 1st line (close to anodes) is bad, other two are good // .... // status=1 --> 001 only 1st line (close to anodes) good // status=0 --> 000 all lines are bad Int_t istatus=0; if(jpad>=0 && jpadGetNbinsX(); jjj++){ Float_t c=fHisto->GetBinContent(jjj+1,ian+1); if(c>0.5) countAbove++; } if(countAbove>fMaxCellsAboveThreshold){ for(Int_t jlin=0;jlinGetBinContent(jjj,ian+1); Float_t c2=fHisto->GetBinContent(jjj+1,ian+1); // Float_t c3=fHisto->GetBinContent(jjj+2,ian+1); if(c1>fLowThreshold[jlin] && c2>fLowThreshold[jlin]){ if(c1>fHighThreshold[jlin] || c2>fHighThreshold[jlin]){ fGoodInj[jpad][jlin]=1; break; } } } } } } } //______________________________________________________________________ void AliITSOnlineSDDInjectors::FindCentroids(){ // Computes the centroids (weighted mean) of teh injector pads for(Int_t jpad=0;jpadGetBinContent(jjj,ian+1); if(cont>maxcont){ maxcont=cont; ilmax=jjj; } } Double_t intCont=0; Int_t jjj=ilmax; while(1){ Double_t cont=fHisto->GetBinContent(jjj,ian+1); if(contGetBinContent(jjj,ian+1); if(cont0){ fCentroid[jpad][jlin]/=intCont; fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin])/TMath::Sqrt(intCont); } else{ fCentroid[jpad][jlin]=0.; fRMSCentroid[jpad][jlin]=0.; fGoodInj[jpad][jlin]=0; } if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0; } } } //______________________________________________________________________ void AliITSOnlineSDDInjectors::PrintInjectorStatus(){ // Dumps the status bit of injector pads for(Int_t jpad=0;jpad0){ for(Int_t i=0;iSetBinContent(i+1,GetMeanDriftSpeed(i)); Double_t rms=GetRMSDriftSpeed(i); Double_t err=0.; if(rms>0.) err=rms/TMath::Sqrt(fNEventsInPad[i]); h->SetBinError(i+1,err); } } return h; } //______________________________________________________________________ Bool_t AliITSOnlineSDDInjectors::WriteToROOT(TFile *fil) const { // Writes the output histograms into a root file if(fil==0){ AliWarning("Invalid pointer to ROOT file"); return kFALSE; } TString hisnam; fil->cd(); hisnam.Form("hdrsp%02dc%02ds%d",fDDL,fCarlos,fSide); TH1F hdsp(hisnam.Data(),"",kInjPads,-0.5,kInjPads-0.5); if(fNEvents==0){ AliWarning("Zero analyzed events"); return kFALSE; } for(Int_t i=0;i0.) err=rms/TMath::Sqrt(fNEventsInPad[i]); hdsp.SetBinError(i+1,err); } hdsp.Write(); return kTRUE; } //______________________________________________________________________ void AliITSOnlineSDDInjectors::WriteInjectorStatusToASCII(){ // dump status of injectors encoded into UInt_t // 5 bits (value 0-31) to store number of pads with given status TString outfilnam; outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide); FILE* outf=fopen(outfilnam.Data(),"a"); Int_t n[8]={0,0,0,0,0,0,0,0}; for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){ Int_t statusPad=GetInjPadStatus(jpad); ++n[statusPad]; } UInt_t statusInj=0; statusInj+=(n[7]&0x1F)<<25; // bits 25-29: n. of pads with status 7 statusInj+=(n[6]&0x1F)<<20; // bits 20-24: n. of pads with status 6 statusInj+=(n[5]&0x1F)<<15; // bits 15-19: n. of pads with status 5 statusInj+=(n[4]&0x1F)<<10; // bits 10-14: n. of pads with status 4 statusInj+=(n[3]&0x1F)<<5; // bits 5- 9: n. of pads with status 3 statusInj+=(n[2]&0x1F); // bits 0- 4: n. of pads with status 2 fprintf(outf,"-99 %u\n",statusInj); // -99 used in preprocessor to find line // with injector status info fclose(outf); }