* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
+#include <TFile.h>
#include "AliITSOnlineSDDInjectors.h"
+#include "AliLog.h"
#include <TH2F.h>
+#include <TF1.h>
#include <TGraphErrors.h>
#include <TMath.h>
+#include <TString.h>
+
+/* $Id$ */
///////////////////////////////////////////////////////////////////
// //
ClassImp(AliITSOnlineSDDInjectors)
const Float_t AliITSOnlineSDDInjectors::fgkSaturation = 1008.;
-const Float_t AliITSOnlineSDDInjectors::fgkJitterTB = 8.;
+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.),fParam(),fPolOrder(0),fMinDriftVel(0.),fMaxDriftVel(0.),fThreshold(0.)
+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
- SetMinDriftVel();
- SetMaxDriftVel();
- SetRangeLine1();
- SetRangeLine2();
- SetRangeLine3();
SetPositions();
- SetPolOrder();
- SetThreshold();
+ SetDefaults();
+ SetTimeStep(fgkDefaultTimeStep);
+ for(Int_t i=0;i<kInjPads;i++){
+ fSumDriftSpeed[i]=0.;
+ fSumSqDriftSpeed[i]=0.;
+ fSumPadStatus[i]=0;
+ fSumPadStatusCut[i]=0;
+ fNEventsInPad[i]=0;
+ }
+ Reset();
}
//______________________________________________________________________
-AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors(Int_t mod, Int_t sid):AliITSOnlineSDD(mod,sid),fHisto(),fTbZero(0.),fParam(),fPolOrder(0),fMinDriftVel(0.),fMaxDriftVel(0.),fThreshold(0.)
+AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors(Int_t nddl, Int_t ncarlos, Int_t sid):
+ AliITSOnlineSDD(nddl,ncarlos,sid),
+ 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)
{
// standard constructor
- SetMinDriftVel();
- SetMaxDriftVel();
- SetRangeLine1();
- SetRangeLine2();
- SetRangeLine3();
SetPositions();
- SetPolOrder();
- SetThreshold();
+ SetDefaults();
+ SetTimeStep(fgkDefaultTimeStep);
+ for(Int_t i=0;i<kInjPads;i++){
+ fSumDriftSpeed[i]=0.;
+ fSumSqDriftSpeed[i]=0.;
+ fSumPadStatus[i]=0;
+ fSumPadStatusCut[i]=0;
+ fNEventsInPad[i]=0;
+ }
+ Reset();
}
//______________________________________________________________________
AliITSOnlineSDDInjectors::~AliITSOnlineSDDInjectors(){
// Destructor
- if(fHisto) delete fHisto;
+ // fHisto should not be deleted here because it points to an histo created
+ // by the external code which calls the method AnalyzeEvent
+ // if(fHisto) delete fHisto;
if(fParam) delete [] fParam;
}
//______________________________________________________________________
+void AliITSOnlineSDDInjectors::SetDefaults(){
+ // Sets default values for parameters
+ for(Int_t i=0;i<kInjLines;i++) {
+ SetInjLineRange(i,fgkDefaultTbMin[i],fgkDefaultTbMax[i]);
+ SetUseLine(i,kTRUE);
+ SetThresholds(i,fgkDefaultLThreshold,fgkDefaultHThreshold);
+ }
+ SetThresholds(0,fgkDefaultLThreshold1,fgkDefaultHThreshold1);
+ SetPolDegree(fgkDefaultPolDegree);
+ SetMinDriftSpeed(fgkDefaultMinSpeed);
+ SetMaxDriftSpeed(fgkDefaultMaxSpeed);
+ SetMaxDriftSpeedErr(fgkDefaultMaxErr);
+ SetFitLimits(1,kInjPads-2); // exclude first and last pad
+ SetPadStatusCutForFit();
+}
+//______________________________________________________________________
+void AliITSOnlineSDDInjectors::Set20MHzConfig(){
+ // Sets specific parameters for 20 MHz running
+ SetInjLineRange(0,10,20);
+ SetInjLineRange(1,50,70);
+ SetInjLineRange(2,100,120);
+ SetTimeStep(50.);
+ SetMaxNumberOfCellsPerAnode(40);
+}
+//______________________________________________________________________
+void AliITSOnlineSDDInjectors::Set40MHzConfig(){
+ // Sets specific parameters for 20 MHz running
+ SetInjLineRange(0,20,50);
+ SetInjLineRange(1,90,160);
+ SetInjLineRange(2,170,240);
+ SetTimeStep(25.);
+ SetMaxNumberOfCellsPerAnode(80);
+}
+//______________________________________________________________________
void AliITSOnlineSDDInjectors::SetPositions(){
- //
- Float_t kLinFromCenterUm[3]={31860.,17460.,660.};
- Float_t kAnodeFromCenterUm=35085;
- for(Int_t i=0;i<3;i++){
- fPosition[i]=kAnodeFromCenterUm-kLinFromCenterUm[i];
+ // Sets drift distances for the 3 injector lines
+ Double_t xLinFromCenterUm[kInjLines]={31860.,17460.,660.};
+ Double_t xAnodeFromCenterUm=35085;
+ for(Int_t i=0;i<kInjLines;i++){
+ fPosition[i]=xAnodeFromCenterUm-xLinFromCenterUm[i];
fPosition[i]/=10000.; // from microns to cm
}
}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::Reset(){
- //
- for(Int_t i=0;i<kNInjectors;i++){
- fDriftVel[i]=0.;
- fSigmaDriftVel[i]=0.;
+ // Resets all counters
+ for(Int_t i=0;i<kInjPads;i++){
+ fDriftSpeed[i]=0.;
+ fDriftSpeedErr[i]=0.;
}
- for(Int_t i=0;i<kNInjectors;i++){
- for(Int_t j=0;j<3;j++){
+ for(Int_t i=0;i<kInjPads;i++){
+ for(Int_t j=0;j<kInjLines;j++){
fGoodInj[i][j]=0;
fCentroid[i][j]=0.;
fRMSCentroid[i][j]=0.;
}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::AnalyzeEvent(TH2F* his){
- //
+ // Analyze the current event
+ AddEvent(his);
+ FitDriftSpeedVsAnode();
+}
+//______________________________________________________________________
+void AliITSOnlineSDDInjectors::AddEvent(TH2F* his){
+ // Add the drift speed from current event to the average value
+ if(fNEvents==0){
+ for(Int_t i=0;i<kInjPads;i++){
+ fSumDriftSpeed[i]=0.;
+ fSumSqDriftSpeed[i]=0.;
+ fSumPadStatus[i]=0;
+ fSumPadStatusCut[i]=0;
+ fNEventsInPad[i]=0;
+ }
+ }
Reset();
fHisto=his;
FindGoodInjectors();
FindCentroids();
CalcTimeBinZero();
- for(Int_t j=0;j<kNInjectors;j++) CalcDriftVelocity(j);
- FitDriftVelocityVsAnode();
+ for(Int_t j=0;j<kInjPads;j++){
+ CalcDriftSpeed(j);
+ Int_t padStatus=GetInjPadStatus(j);
+ fSumPadStatus[j]+=padStatus;
+ if(padStatus>fPadStatusCutForFit){
+ fSumDriftSpeed[j]+=fDriftSpeed[j];
+ fSumSqDriftSpeed[j]+=fDriftSpeed[j]*fDriftSpeed[j];
+ fSumPadStatusCut[j]+=padStatus;
+ fNEventsInPad[j]++;
+ }
+ }
+ ++fNEvents;
}
//______________________________________________________________________
-TGraphErrors* AliITSOnlineSDDInjectors::GetLineGraph(Int_t jlin){
- //
- Float_t x[4],y[4],ex[4],ey[4];
+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<kInjPads;i++){
+ fDriftSpeed[i]=GetMeanDriftSpeed(i);
+ Int_t padStatusCut=(Int_t)(GetMeanPadStatusCut(i)+0.5);
+ for(Int_t ilin=0; ilin<kInjLines ; ilin++) fGoodInj[i][ilin]=(padStatusCut&1<<ilin)>>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<kInjLines ; ilin++) fGoodInj[i][ilin]=0;
+ }
+ }
+ FitDriftSpeedVsAnode();
+ for(Int_t i=0;i<kInjPads;i++){
+ Int_t padStatus=(Int_t)(GetMeanPadStatusCut(i)+0.5);
+ for(Int_t ilin=0; ilin<kInjLines ; ilin++) fGoodInj[i][ilin]=(padStatus&1<<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;i<3;i++){
+ for(Int_t i=0;i<kInjLines;i++){
x[i+1]=fPosition[i];
ex[i+1]=0.;
- y[i+1]=fCentroid[jlin][i];
- ey[i+1]=fRMSCentroid[jlin][i];
+ y[i+1]=fCentroid[jpad][i];
+ ey[i+1]=fRMSCentroid[jpad][i];
}
TGraphErrors *g=new TGraphErrors(4,x,y,ex,ey);
return g;
}
+
//______________________________________________________________________
-Float_t AliITSOnlineSDDInjectors::GetDriftCoordinate(Float_t cAnode, Float_t cTimeBin){
- //
- Float_t vel=0;
- for(Int_t i=0;i<=fPolOrder;i++) vel+=fParam[i]*TMath::Power(cAnode,(Float_t)i);
- return vel*(cTimeBin-(fTbZero-fgkJitterTB))*25/1000.;
+TGraphErrors* AliITSOnlineSDDInjectors::GetDriftSpeedGraph() const{
+ // Builds the graph of drift speed vs. anode number
+ Int_t ipt=0;
+ TGraphErrors *g=new TGraphErrors(0);
+ for(Int_t i=0;i<kInjPads;i++){
+ if(fDriftSpeed[i]>0){
+ g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
+ g->SetPointError(ipt,0,fDriftSpeedErr[i]);
+ ipt++;
+ }
+ }
+ return g;
}
//______________________________________________________________________
-TGraphErrors* AliITSOnlineSDDInjectors::GetDriftVelocityGraph() const{
- //
+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;i<kNInjectors;i++){
- if(fDriftVel[i]>0){
- g->SetPoint(ipt,GetAnodeNumber(i),fDriftVel[i]);
- g->SetPointError(ipt,0,fSigmaDriftVel[i]);
+ for(Int_t i=0;i<kInjPads;i++){
+ Int_t padStatus = GetInjPadStatus(i);
+ if(fDriftSpeed[i]>0 && padStatus >= minAcceptStatus ){
+ g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
+ g->SetPointError(ipt,0,fDriftSpeedErr[i]);
ipt++;
}
}
}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::CalcTimeBinZero(){
- //
- Float_t tzero=0.,intCont=0.;
+ // 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;ian<fgkNAnodes;ian++){
for(Int_t itb=1;itb<fTbMin[0];itb++){
- Float_t cont=fHisto->GetBinContent(itb,ian+1);
- if(cont>fThreshold){
- tzero+=cont*float(itb);
- intCont+=cont;
+ Double_t cont=fHisto->GetBinContent(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;
+ if(intCont>0){
+ fTbZero=tzero/intCont;
+ fRMSTbZero=TMath::Sqrt(rmsPeak/intCont-fTbZero*fTbZero);
+ }
+ if(nTbUsed==1) fRMSTbZero=0.5;
}
+
//______________________________________________________________________
-void AliITSOnlineSDDInjectors::FitDriftVelocityVsAnode(){
- const Int_t nn=fPolOrder+1;
- Float_t **mat = new Float_t*[nn];
- for(Int_t i=0; i < nn; i++) mat[i] = new Float_t[nn];
- Float_t *vect = new Float_t[nn];
- for(Int_t k1=0;k1<nn;k1++){
+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] && zero1<rangeForMax[1]) oneZero=kTRUE;
+ if(zero2>rangeForMax[0] && zero2<rangeForMax[1]) oneZero=kTRUE;
+ if(!oneZero || twoZeroes){
+ PolyFit(2);
+ Double_t xmax=-999.;
+ if(fParam[2]<0.) xmax=-fParam[1]/2./fParam[2];
+ if(xmax>rangeForMax[0] && xmax<rangeForMax[1]){
+ fActualPolDegree=2;
+ }else{
+ Double_t averSpeed=0.;
+ Double_t sumWei=0.;
+ Int_t nUsedPts=0;
+ for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
+ if(fDriftSpeed[jpad]>0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){
+ Double_t wei=1./fDriftSpeedErr[jpad]/fDriftSpeedErr[jpad];
+ averSpeed+=wei*fDriftSpeed[jpad];
+ sumWei+=wei;
+ nUsedPts++;
+ }
+ }
+ if(sumWei>0.) averSpeed/=sumWei;
+ if(nUsedPts<fPolDegree+1) averSpeed=0;
+ fParam[0]=averSpeed;
+ for(Int_t i=1; i < fPolDegree+1; i++) fParam[i]=0.;
+ fActualPolDegree=0;
+ }
+ }
+ }
+}
+//______________________________________________________________________
+void AliITSOnlineSDDInjectors::PolyFit(Int_t degree){
+ // fits the anode dependence of drift speed with a polynomial function
+ const Int_t kNn=degree+1;
+ const Int_t kDimens=fPolDegree+1;
+
+ Double_t **mat = new Double_t*[kNn];
+ for(Int_t i=0; i < kNn; i++) mat[i] = new Double_t[kNn];
+ Double_t *vect = new Double_t[kNn];
+
+ for(Int_t k1=0;k1<kNn;k1++){
vect[k1]=0;
- for(Int_t k2=0;k2<nn;k2++){
+ for(Int_t k2=0;k2<kNn;k2++){
mat[k1][k2]=0;
- for(Int_t n=0; n<kNInjectors;n++){
- Float_t x=(Float_t)GetAnodeNumber(n);
- if(fDriftVel[n]>0) mat[k1][k2]+=TMath::Power(x,k1+k2)/TMath::Power(fSigmaDriftVel[n],2);
- }
}
}
- for(Int_t k1=0;k1<nn;k1++){
- for(Int_t n=0; n<kNInjectors;n++){
- Float_t x=(Float_t)GetAnodeNumber(n);
- if(fDriftVel[n]>0) vect[k1]+=fDriftVel[n]*TMath::Power(x,k1)/TMath::Power(fSigmaDriftVel[n],2);
+ Int_t npts = 0;
+ for(Int_t k1=0;k1<kNn;k1++){
+ for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
+ Double_t x=(Double_t)GetAnodeNumber(jpad);
+ if(fDriftSpeed[jpad]>0 && 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<kNn;k2++){
+ mat[k1][k2]+=TMath::Power(x,k1+k2)/TMath::Power(fDriftSpeedErr[jpad],2);
+ }
+ }
}
}
- Int_t *iPivot = new Int_t[nn];
- Int_t *indxR = new Int_t[nn];
- Int_t *indxC = new Int_t[nn];
- for(Int_t i=0;i<nn;i++) iPivot[i]=0;
- Int_t iCol=-1,iRow=-1;
- for(Int_t i=0;i<nn;i++){
- Float_t big=0.;
- for(Int_t j=0;j<nn;j++){
- if(iPivot[j]!=1){
- for(Int_t k=0;k<nn;k++){
- if(iPivot[k]==0){
- if(TMath::Abs(mat[j][k])>=big){
- big=TMath::Abs(mat[j][k]);
- iRow=j;
- iCol=k;
- }
+ if(npts<fPolDegree+1){
+ if(fParam) delete [] fParam;
+ fParam=new Double_t[kDimens];
+ for(Int_t i=0; i<kDimens;i++)fParam[i]=0;
+ }else{
+ Int_t *iPivot = new Int_t[kNn];
+ Int_t *indxR = new Int_t[kNn];
+ Int_t *indxC = new Int_t[kNn];
+ for(Int_t i=0;i<kNn;i++) iPivot[i]=0;
+ Int_t iCol=-1,iRow=-1;
+ for(Int_t i=0;i<kNn;i++){
+ Double_t big=0.;
+ for(Int_t j=0;j<kNn;j++){
+ if(iPivot[j]!=1){
+ for(Int_t k=0;k<kNn;k++){
+ if(iPivot[k]==0){
+ if(TMath::Abs(mat[j][k])>=big){
+ big=TMath::Abs(mat[j][k]);
+ iRow=j;
+ iCol=k;
+ }
+ }
}
}
}
- }
- iPivot[iCol]++;
- Float_t aux;
- if(iRow!=iCol){
- for(Int_t l=0;l<nn;l++){
- aux=mat[iRow][l];
- mat[iRow][l]=mat[iCol][l];
- mat[iCol][l]=aux;
+ iPivot[iCol]++;
+ Double_t aux;
+ if(iRow!=iCol){
+ for(Int_t l=0;l<kNn;l++){
+ aux=mat[iRow][l];
+ mat[iRow][l]=mat[iCol][l];
+ mat[iCol][l]=aux;
+ }
+ aux=vect[iRow];
+ vect[iRow]=vect[iCol];
+ vect[iCol]=aux;
}
- aux=vect[iRow];
- vect[iRow]=vect[iCol];
- vect[iCol]=aux;
+ indxR[i]=iRow;
+ indxC[i]=iCol;
+ if(mat[iCol][iCol]==0) break;
+ Double_t pivinv=1./mat[iCol][iCol];
+ mat[iCol][iCol]=1;
+ for(Int_t l=0;l<kNn;l++) mat[iCol][l]*=pivinv;
+ vect[iCol]*=pivinv;
+ for(Int_t m=0;m<kNn;m++){
+ if(m!=iCol){
+ aux=mat[m][iCol];
+ mat[m][iCol]=0;
+ for(Int_t n=0;n<kNn;n++) mat[m][n]-=mat[iCol][n]*aux;
+ vect[m]-=vect[iCol]*aux;
+ }
+ }
}
- indxR[i]=iRow;
- indxC[i]=iCol;
- if(mat[iCol][iCol]==0) break;
- Float_t pivinv=1./mat[iCol][iCol];
- mat[iCol][iCol]=1;
- for(Int_t l=0;l<nn;l++) mat[iCol][l]*=pivinv;
- vect[iCol]*=pivinv;
- for(Int_t m=0;m<nn;m++){
- if(m!=iCol){
- aux=mat[m][iCol];
- mat[m][iCol]=0;
- for(Int_t n=0;n<nn;n++) mat[m][n]-=mat[iCol][n]*aux;
- vect[m]-=vect[iCol]*aux;
- }
- }
+ delete [] iPivot;
+ delete [] indxR;
+ delete [] indxC;
+
+
+ if(fParam) delete [] fParam;
+ fParam=new Double_t[kDimens];
+ for(Int_t i=0; i<kNn;i++)fParam[i]=vect[i];
+ if(degree<fPolDegree) for(Int_t i=kNn; i<kDimens;i++)fParam[i]=0.;
}
- delete [] iPivot;
- delete [] indxR;
- delete [] indxC;
-
- if(fParam) delete [] fParam;
- fParam=new Float_t[nn];
- for(Int_t i=0; i<nn;i++)fParam[i]=vect[i];
- for(Int_t i=0; i < nn; i++) delete [] mat[i];
+ for(Int_t i=0; i < kNn; i++) delete [] mat[i];
delete [] mat;
delete [] vect;
}
//______________________________________________________________________
-void AliITSOnlineSDDInjectors::CalcDriftVelocity(Int_t jlin){
- //
- Float_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=0.;
+void AliITSOnlineSDDInjectors::CalcDriftSpeed(Int_t jpad){
+ // Computes the drift speed from the fit to the 3 injector lines for each anode
+ Double_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=0.;
Int_t npt=0;
- Float_t y[3],ey[3];
- Float_t tzero=0,erry=0;
- for(Int_t i=0;i<3;i++){
- y[i]=fCentroid[jlin][i];
- ey[i]=fRMSCentroid[jlin][i];
- }
- for(Int_t i=0;i<3;i++){
- if(fGoodInj[jlin][i]){
+ Double_t y[kInjLines],ey[kInjLines];
+ Double_t tzero=0,erry=0;
+ for(Int_t i=0;i<kInjLines;i++){
+ y[i]=fCentroid[jpad][i];
+ ey[i]=fRMSCentroid[jpad][i];
+ }
+ for(Int_t i=0;i<kInjLines;i++){
+ if(!fUseLine[i]) continue;
+ if(fGoodInj[jpad][i] && ey[i]!=0){
sumY+=y[i]/ey[i]/ey[i];
sumX+=fPosition[i]/ey[i]/ey[i];
sumXX+=fPosition[i]*fPosition[i]/ey[i]/ey[i];
sumXY+=fPosition[i]*y[i]/ey[i]/ey[i];
sumWEI+=1./ey[i]/ey[i];
tzero=fTbZero/ey[i]/ey[i];
- erry=ey[i];
+ erry=ey[i]/ey[i]/ey[i];
npt++;
}
}
- Float_t vel=0,evel=0;
+ Double_t slope=0.,eslope=0.;
+ if(npt==1){
+ slope=(sumY-tzero)/sumX;
+ eslope=erry/sumX;
+ }
if(npt>1){
- Float_t slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX);
- Float_t eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX));
- vel=1./slope*10000./25.;// micron/ns
- evel=eslope/slope/slope*10000./25.;// micron/ns
+ 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));
}
- if(npt==1){
- Float_t slope=(sumY-tzero)/sumX;
- Float_t eslope=erry/sumX;
- vel=1./slope*10000./25.;// micron/ns
- evel=eslope/slope/slope*10000./25.;// micron/ns
+
+ 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>fMaxDriftVel||vel<fMinDriftVel){
+ if(vel>fMaxDriftSpeed||vel<fMinDriftSpeed || evel>fMaxDriftSpeedErr){
vel=0.;
evel=0.;
}
- fDriftVel[jlin]=vel;
- fSigmaDriftVel[jlin]=evel;
+ fDriftSpeed[jpad]=vel;
+ fDriftSpeedErr[jpad]=evel;
}
//______________________________________________________________________
-Int_t AliITSOnlineSDDInjectors::GetAnodeNumber(Int_t iInjLine) const{
- //
+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(iInjLine>32) return ian;
- if(!fSide){
- ian=iInjLine*8;
- if(iInjLine==32) ian--;
- }else{
- ian=iInjLine*8-1;
- if(iInjLine==0) ian=0;
+ 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 && jpad<kInjPads){
+ for(Int_t jlin=0;jlin<kInjLines;jlin++) istatus+=fGoodInj[jpad][jlin]<<jlin;
+ }
+ return istatus;
+}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::FindGoodInjectors(){
- //
- for(Int_t iii=0;iii<kNInjectors;iii++){
- Int_t ian=GetAnodeNumber(iii);
- for(Int_t ninj=0;ninj<3;ninj++){
- for(Int_t jjj=fTbMin[ninj];jjj<fTbMax[ninj];jjj++){
- Float_t c1=fHisto->GetBinContent(jjj,ian+1);
- Float_t c2=fHisto->GetBinContent(jjj+1,ian+1);
- Float_t c3=fHisto->GetBinContent(jjj+2,ian+1);
- if(c1>fThreshold && c2>fThreshold && c3>fThreshold){
- fGoodInj[iii][ninj]=1;
- break;
+ // Mark good injector pads
+ // good = 1 cell above high threshold + 1 neighbour above low threshold
+ for(Int_t jpad=0;jpad<kInjPads;jpad++){
+ Int_t ian=GetAnodeNumber(jpad);
+ Int_t countAbove=0;
+ for(Int_t jjj=0; jjj<fHisto->GetNbinsX(); jjj++){
+ Float_t c=fHisto->GetBinContent(jjj+1,ian+1);
+ if(c>0.5) countAbove++;
+ }
+ if(countAbove>fMaxCellsAboveThreshold){
+ for(Int_t jlin=0;jlin<kInjLines;jlin++) fGoodInj[jpad][jlin]=0;
+ }else{
+ for(Int_t jlin=0;jlin<kInjLines;jlin++){
+ for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
+ Float_t c1=fHisto->GetBinContent(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;
+ }
+ }
}
}
- // for(Int_t jjj=fTbMin[ninj];jjj<fTbMax[ninj];jjj++){
- // Float_t c1=fHisto->GetBinContent(jjj,ian+1);
- // if(c1>=fgkSaturation){
- // fGoodInj[iii][ninj]=0;
- // break;
- // }
- // }
}
}
}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::FindCentroids(){
- //
- for(Int_t iii=0;iii<kNInjectors;iii++){
- Int_t ian=GetAnodeNumber(iii);
- for(Int_t ninj=0;ninj<3;ninj++){
- if(!fGoodInj[iii][ninj]) continue;
- Float_t maxcont=0;
+ // Computes the centroids (weighted mean) of teh injector pads
+ for(Int_t jpad=0;jpad<kInjPads;jpad++){
+ Int_t ian=GetAnodeNumber(jpad);
+ for(Int_t jlin=0;jlin<kInjLines;jlin++){
+ if(!fGoodInj[jpad][jlin]) continue;
+ Double_t maxcont=0;
Int_t ilmax=-1;
- for(Int_t jjj=fTbMin[ninj];jjj<fTbMax[ninj];jjj++){
- Float_t cont=fHisto->GetBinContent(jjj,ian+1);
+ for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
+ Double_t cont=fHisto->GetBinContent(jjj,ian+1);
if(cont>maxcont){
maxcont=cont;
ilmax=jjj;
}
}
- Float_t intCont=0;
+ Double_t intCont=0;
Int_t jjj=ilmax;
while(1){
- Float_t cont=fHisto->GetBinContent(jjj,ian+1);
- if(cont<fThreshold) break;
+ Double_t cont=fHisto->GetBinContent(jjj,ian+1);
+ if(cont<fLowThreshold[jlin]) break;
if(cont<fgkSaturation){
- fCentroid[iii][ninj]+=cont*(Float_t)jjj;
- fRMSCentroid[iii][ninj]+=cont*TMath::Power((Float_t)jjj,2);
+ fCentroid[jpad][jlin]+=cont*(Double_t)jjj;
+ fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
intCont+=cont;
}
jjj--;
}
jjj=ilmax+1;
while(1){
- Float_t cont=fHisto->GetBinContent(jjj,ian+1);
- if(cont<fThreshold) break;
+ Double_t cont=fHisto->GetBinContent(jjj,ian+1);
+ if(cont<fLowThreshold[jlin]) break;
if(cont<fgkSaturation){
- fCentroid[iii][ninj]+=cont*float(jjj);
- fRMSCentroid[iii][ninj]+=cont*TMath::Power((Float_t)jjj,2);
+ fCentroid[jpad][jlin]+=cont*float(jjj);
+ fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
intCont+=cont;
}
jjj++;
}
if(intCont>0){
- fCentroid[iii][ninj]/=intCont;
- fRMSCentroid[iii][ninj]=TMath::Sqrt(fRMSCentroid[iii][ninj]/intCont-fCentroid[iii][ninj]*fCentroid[iii][ninj]);
+ fCentroid[jpad][jlin]/=intCont;
+ fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin])/TMath::Sqrt(intCont);
}
else{
- fCentroid[iii][ninj]=0.;
- fRMSCentroid[iii][ninj]=0.;
- fGoodInj[iii][ninj]=0;
+ fCentroid[jpad][jlin]=0.;
+ fRMSCentroid[jpad][jlin]=0.;
+ fGoodInj[jpad][jlin]=0;
}
+ if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0;
}
}
}
//______________________________________________________________________
-void AliITSOnlineSDDInjectors::PrintInjMap(){
- //
- for(Int_t iii=0;iii<kNInjectors;iii++){
- printf("Line%d-Anode%d: %d %d %d\n",iii,GetAnodeNumber(iii),fGoodInj[iii][0],fGoodInj[iii][1],fGoodInj[iii][2]);
+void AliITSOnlineSDDInjectors::PrintInjectorStatus(){
+ // Dumps the status bit of injector pads
+ for(Int_t jpad=0;jpad<kInjPads;jpad++){
+ printf("Line%d-Anode%d: %d %d %d\n",jpad,GetAnodeNumber(jpad),fGoodInj[jpad][0],fGoodInj[jpad][1],fGoodInj[jpad][2]);
}
}
//______________________________________________________________________
void AliITSOnlineSDDInjectors::PrintCentroids(){
- //
- for(Int_t iii=0;iii<kNInjectors;iii++){
- printf("Line%d-Anode%d: %f+-%f %f+-%f %f+-%f\n",iii,GetAnodeNumber(iii),fCentroid[iii][0],fRMSCentroid[iii][0],fCentroid[iii][1],fRMSCentroid[iii][1],fCentroid[iii][2],fRMSCentroid[iii][2]);
+ // Dumps the drift time centroids of injector pads
+ for(Int_t jpad=0;jpad<kInjPads;jpad++){
+ printf("Line%d-Anode%d: %f+-%f %f+-%f %f+-%f\n",jpad,GetAnodeNumber(jpad),fCentroid[jpad][0],fRMSCentroid[jpad][0],fCentroid[jpad][1],fRMSCentroid[jpad][1],fCentroid[jpad][2],fRMSCentroid[jpad][2]);
}
}
//______________________________________________________________________
-void AliITSOnlineSDDInjectors::WriteToFXS(){
- //
- Char_t outfilnam[100];
- sprintf(outfilnam,"SDDinj_mod%03d_sid%d.data",fModuleId,fSide);
- FILE* outf=fopen(outfilnam,"w");
- for(Int_t ic=0;ic<fPolOrder+1;ic++){
+void AliITSOnlineSDDInjectors::WriteToASCII(Int_t evNumb, UInt_t timeStamp, Int_t optAppend){
+ // writes drift speed vs. anode fit parameters into an ASCII file
+ // to be sent to FXS by the DA and processed by the SHUTTLE
+
+ TString outfilnam;
+ outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);
+ FILE* outf;
+ if(optAppend==0){
+ outf=fopen(outfilnam.Data(),"w");
+ fprintf(outf,"%d\n",fActualPolDegree);
+ }
+ else outf=fopen(outfilnam.Data(),"a");
+ fprintf(outf,"%d %d ",evNumb,timeStamp);
+ for(Int_t ic=0;ic<fPolDegree+1;ic++){
fprintf(outf,"%G ",fParam[ic]);
}
fprintf(outf,"\n");
fclose(outf);
}
+//______________________________________________________________________
+TH1F* AliITSOnlineSDDInjectors::GetMeanDriftSpeedVsPadHisto() const{
+ // Builds histogram of average drift speed vs. pad number
+ TString hisnam;
+ hisnam.Form("hdrsp%02dc%02ds%d",fDDL,fCarlos,fSide);
+ TH1F* h=new TH1F(hisnam.Data(),"",kInjPads,-0.5,kInjPads-0.5);
+ if(fNEvents>0){
+ for(Int_t i=0;i<kInjPads;i++){
+ h->SetBinContent(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;i<kInjPads;i++){
+ hdsp.SetBinContent(i+1,GetMeanDriftSpeed(i));
+ Double_t rms=GetRMSDriftSpeed(i);
+ Double_t err=0.;
+ if(rms>0.) 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);
+
+}