for(Int_t iDig2=0;iDig2<Size();iDig2++) { //loop on all digits again
if(iDig1==iDig2) continue; //the same digit, no need to compare
AliHMPIDDigit *pDig2 = Dig(iDig2); //take second digit to compare with the first one
- Int_t dist = TMath::Sign(Int_t(pDig1->PadX()-pDig2->PadX()),1)+TMath::Sign(Int_t(pDig1->PadY()-pDig2->PadY()),1);//distance between pads
+ Int_t dist = TMath::Sign(Int_t(pDig1->PadChX()-pDig2->PadChX()),1)+TMath::Sign(Int_t(pDig1->PadChY()-pDig2->PadChY()),1);//distance between pads
if(dist==1) //means dig2 is a neighbour of dig1
if(pDig2->Q()>=pDig1->Q()) iHowManyMoreCnt++; //count number of pads with Q more then Q of current pad
}//second digits loop
ClassImp(AliHMPIDDigit)
/*
-Any given LDC collects data from a number of D-RORC cards connected to this same LDC by separate DDLs. This data is stored in corresponding number
-of DDL buffers.
+Preface: all geometrical information (like left-right sides) is reported as seen from electronic side.
-Each DDL buffer corresponds to a single D-RORC. The data this buffer contains are hardware generated by D-RORC. The buffer starts with common header
-which size and structure is standartized and mandatory for all detectors.
+
+The DDL file starts with common header which size and structure is standartized and mandatory for all detectors.
The header contains among other words, so called Equipment ID word. This unique value for each D-RORC is calculated as detector ID << 8 + DDL index.
For HMPID the detector ID is 6 (reffered in the code as kRichRawId) while DDL indexes are from 0 to 13.
Common header might be followed by the private one although HMPID has no any private header, just uses the common one.
-Single HMPID D-RORC serves one half of a chamber i.e. 3 photocathodes even LDC for left part( PCs 0-2-4) and odd LDC for right part(1-3-5)
-as it's seen from electronics side.
+Single HMPID D-RORC (with 2 channels) serves a single chamber so that channel 0 serves left half (PCs 0-2-4)
+ 1 serves right half(PCs 1-3-5)
So the LDC -chamber-ddl map is:
-DDL index 0 -> ch 1 left -> DDL ID 0x600 DDL index 1 -> ch 1 right -> DDL ID 0x601
-DDL index 2 -> ch 2 left -> DDL ID 0x602 DDL index 3 -> ch 2 right -> DDL ID 0x603
-DDL index 4 -> ch 3 left -> DDL ID 0x604 DDL index 5 -> ch 3 right -> DDL ID 0x605
-DDL index 6 -> ch 4 left -> DDL ID 0x606 DDL index 7 -> ch 4 right -> DDL ID 0x607
-DDL index 8 -> ch 5 left -> DDL ID 0x608 DDL index 9 -> ch 5 right -> DDL ID 0x609
-DDL index 10 -> ch 6 left -> DDL ID 0x60a DDL index 11 -> ch 6 right -> DDL ID 0x60b
-DDL index 12 -> ch 7 left -> DDL ID 0x60c DDL index 13 -> ch 7 right -> DDL ID 0x60d
+DDL index 0 -> ch 0 left -> DDL ID 0x600 DDL index 1 -> ch 1 right -> DDL ID 0x601
+DDL index 2 -> ch 1 left -> DDL ID 0x602 DDL index 3 -> ch 2 right -> DDL ID 0x603
+DDL index 4 -> ch 2 left -> DDL ID 0x604 DDL index 5 -> ch 3 right -> DDL ID 0x605
+DDL index 6 -> ch 3 left -> DDL ID 0x606 DDL index 7 -> ch 4 right -> DDL ID 0x607
+DDL index 8 -> ch 4 left -> DDL ID 0x608 DDL index 9 -> ch 5 right -> DDL ID 0x609
+DDL index 10 -> ch 5 left -> DDL ID 0x60a DDL index 11 -> ch 6 right -> DDL ID 0x60b
+DDL index 12 -> ch 6 left -> DDL ID 0x60c DDL index 13 -> ch 7 right -> DDL ID 0x60d
HMPID FEE as seen by single D-RORC is composed from a number of DILOGIC chips organized in vertical stack of rows.
-Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDilX,kDilY). Channels counted from 0 to 47.
+Each DILOGIC chip serves 48 channels for the 8x6 pads Channels counted from 0 to 47.
The mapping inside DILOGIC chip has the following structure (see from electronics side):
+pady
-5 04 10 16 22 28 34 40 46
-4 02 08 14 20 26 32 38 44
-3 00 06 12 18 24 30 36 42
-2 01 07 13 19 25 31 37 43
-1 03 09 15 21 27 33 39 45
-0 05 11 17 23 29 35 41 47
+5 04 10 16 22 28 34 40 46 due to repetition in column structure we may introduce per column map:
+4 02 08 14 20 26 32 38 44 pady= 0 1 2 3 4 5
+3 00 06 12 18 24 30 36 42 addr= 5 3 1 0 2 4
+2 01 07 13 19 25 31 37 43 or vice versa
+1 03 09 15 21 27 33 39 45 addr= 0 1 2 3 4 5
+0 05 11 17 23 29 35 41 47 pady= 3 2 4 1 5 0
0 1 2 3 4 5 6 7 padx
Int_t iSdiCnt=pSdiLst->GetEntries();
for(Int_t i=0;i<9;i++){ //affected pads loop
AliHMPIDDigit dig(pHit->Ch(),qdcTot,pHit->Tid(),pHit->LorsX(),y,i); //c,q,tid,x,y create tmp sdigit for pad i around hit position
- if(dig.PadX()==-1) continue;
+ if(dig.PadPcX()==-1) continue;
new((*pSdiLst)[iSdiCnt++]) AliHMPIDDigit(dig);
}
return qdcTot;
// Print current digit
// Arguments: option string not used
// Returns: none
- Printf("pad=(%2i,%2i,%3i,%3i),pos=(%7.2f,%7.2f) QDC=%8.3f, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i",
- Ch(),Pc(),PadX(),PadY(),LorsX(),LorsY(), Q(), fTracks[0],fTracks[1],fTracks[2], Row(), Dilogic(), Addr());
+ UInt_t w32; Raw(w32);
+ Printf("(ch=%1i,pc=%1i,x=%2i,y=%2i),pos=(%7.2f,%7.2f) Q=%8.3f TID=(%5i,%5i,%5i) ddl=%i raw=0x%x (r=%2i,d=%2i,a=%2i)",
+ A2C(fPad),A2P(fPad),A2X(fPad),A2Y(fPad),LorsX(),LorsY(), Q(), fTracks[0],fTracks[1],fTracks[2],DdlIdx(),w32,Row(),Dilogic(),Addr());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDDigit::PrintSize()
// Arguments: none
// Returns: none
Printf("-->pad =(%6.2f,%6.2f) cm dead zone %.2f cm\n"
- "-->PC =(%6.2f,%6.2f) cm\n"
- "-->all PCs=(%6.2f,%6.2f) cm",
- SizePadX(),SizePadY(),SizeDead(),SizePcX(),SizePcY(),SizeAllX(),SizeAllY());
+ "-->PC =(%6.2f,%6.2f) cm (%3i,%3i) pads\n"
+ "-->all PCs=(%6.2f,%6.2f) cm (%3i,%3i) pads",
+ SizePadX(),SizePadY(),SizeDead(),
+ SizePcX() ,SizePcY() ,kPadPcX ,kPadPcY,
+ SizeAllX(),SizeAllY(),kPadAllX,kPadAllY);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliHMPIDDigit::TestSeg()
+void AliHMPIDDigit::DrawSeg()
{
// Draws the picture of segmentation
// Arguments: none
// Returns: none
- TCanvas *pC=new TCanvas("pads","View from electronics side, IP is behind the picture.");pC->ToggleEventStatus();
- gPad->AddExec("test","AliHMPIDDigit::Zoom()");
+ TCanvas *pC=new TCanvas("pads","View from electronics side, IP is behind the picture.",1000,900);pC->ToggleEventStatus();
+ gPad->AddExec("test","AliHMPIDDigit::DrawZoom()");
DrawPc();
}//TestSeg()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliHMPIDDigit::Zoom()
+void AliHMPIDDigit::DrawZoom()
{
// Show info about current cursur position in status bar of the canvas
// Arguments: none
pBar->SetParts(5);
Float_t x=gPad->AbsPixeltoX(gPad->GetEventX());
Float_t y=gPad->AbsPixeltoY(gPad->GetEventY());
- AliHMPIDDigit dig(1,100,1,x,y);
+ AliHMPIDDigit dig(1,0,1,x,y); UInt_t w32=0;
if(IsInDead(x,y))
pBar->SetText("Out of sensitive area",4);
- else
- pBar->SetText(Form("p%i x%i y%i r%i d%i a%i (%.2f,%.2f)",dig.Pc(),dig.PadX(),dig.PadY(),dig.Row(),dig.Dilogic(),dig.Addr(),dig.LorsX(),dig.LorsY()),4);
+ else{
+ Int_t ddl=dig.Raw(w32);
+ pBar->SetText(Form("(p%i,x%i,y%i) ddl=%i 0x%x (r%i,d%i,a%i) (%.2f,%.2f)",
+ dig.Pc(),dig.PadPcX(),dig.PadPcY(),
+ ddl,w32,
+ dig.Row(),dig.Dilogic(),dig.Addr(),
+ dig.LorsX(),dig.LorsY() ),4);
+ }
if(gPad->GetEvent()==1){
new TCanvas("zoom",Form("Row %i DILOGIC %i",dig.Row(),dig.Dilogic()));
}
Float_t yC[5]={y3,y4,y4,y3,y3};
Float_t yU[5]={y5,y6,y6,y5,y5};
- TLatex t; t.SetTextSize(0.01); t.SetTextAlign(22);
+ TLatex txt; txt.SetTextSize(0.01);
Int_t iColLeft=29,iColRight=41;
- TPolyLine *pc=0; TLine *pL; Float_t x0=0,y0=0,wRow=kDilY*SizePadY(),wDil=kDilX*SizePadX();
+ TPolyLine *pc=0; TLine *pL;
+ AliHMPIDDigit dig;
for(Int_t iPc=0;iPc<kPcAll;iPc++){
- if(iPc==4) {pc=new TPolyLine(5,xL,yU);t.DrawText(x1-3.5,y6-20,"PC4");x0=x1;y0=y5;} if(iPc==5) {pc=new TPolyLine(5,xR,yU);t.DrawText(x4+3.5,y6-20,"PC5");x0=x3;y0=y5;}
- if(iPc==2) {pc=new TPolyLine(5,xL,yC);t.DrawText(x1-3.5,y4-20,"PC2");x0=x1;y0=y3;} if(iPc==3) {pc=new TPolyLine(5,xR,yC);t.DrawText(x4+3.5,y4-20,"PC3");x0=x3;y0=y3;}
- if(iPc==0) {pc=new TPolyLine(5,xL,yD);t.DrawText(x1-3.5,y2-20,"PC0");x0=x1;y0=y1;} if(iPc==1) {pc=new TPolyLine(5,xR,yD);t.DrawText(x4+3.5,y2-20,"PC1");x0=x3;y0=y1;}
+ if(iPc==4) pc=new TPolyLine(5,xL,yU); if(iPc==5) pc=new TPolyLine(5,xR,yU); //draw PCs
+ if(iPc==2) pc=new TPolyLine(5,xL,yC); if(iPc==3) pc=new TPolyLine(5,xR,yC);
+ if(iPc==0) pc=new TPolyLine(5,xL,yD); if(iPc==1) pc=new TPolyLine(5,xR,yD);
(iPc%2)? pc->SetFillColor(iColLeft): pc->SetFillColor(iColRight);
if(isFill) pc->Draw("f"); else pc->Draw();
- for(Int_t i=1;i<=8 ;i++){//draw row lines (horizontal)
- Float_t y=y0+i*wRow;
- Int_t row=i+iPc/2*8; if(iPc%2!=0) row=25-row; t.DrawText(x0-1,y -3,Form("r%i",row));
- if(i==8) break; //do not draw the last line of PC
- pL=new TLine(x0,y,x0+SizePcX(),y); pL->Draw();
- }
- for(Int_t iDil=1;iDil<=10;iDil++){Float_t x=x0+iDil*wDil;t.DrawText(x -3,y0-1,Form("d%i",11-iDil)); if(iDil==10) break; pL=new TLine(x,y0,x,y0+SizePcY()); pL->Draw();}
- }
+ if(iPc%2) {dig.Set(0,iPc,79,25); txt.DrawText(dig.LorsX()+2,dig.LorsY(),Form("PC%i",dig.Pc()));}//print PC#
+
+ txt.SetTextAlign(32);
+ for(Int_t iRow=0;iRow<8 ;iRow++){//draw row lines (horizontal)
+ dig.Set(0,iPc,0,iRow*6); //set digit to the left-down pad of this row
+ if(iPc%2) txt.DrawText(dig.LorsX()-1 ,dig.LorsY(),Form("%i",dig.PadPcY())); //print PadY#
+ txt.DrawText(dig.LorsX()-1+(iPc%2)*67,dig.LorsY()+2,Form("r%i",dig.Row())); //print Row#
+ pL=new TLine(dig.LorsX()-0.5*SizePadX(),dig.LorsY()-0.5*SizePadY(),dig.LorsX()+SizePcX()-0.5*SizePadX(),dig.LorsY()-0.5*SizePadY());
+ if(iRow!=0) pL->Draw();
+ }//row loop
+
+ txt.SetTextAlign(13);
+ for(Int_t iDil=0;iDil<10;iDil++){//draw dilogic lines (vertical)
+ dig.Set(0,iPc,iDil*8,0); //set this digit to the left-down pad of this dilogic
+ txt.DrawText(dig.LorsX() ,dig.LorsY()-1,Form("%i",dig.PadPcX())); //print PadX#
+ if(iPc==4 || iPc==5) txt.DrawText(dig.LorsX()+2,dig.LorsY()+42,Form("d%i",dig.Dilogic())); //print Dilogic#
+ pL=new TLine(dig.LorsX()-0.5*SizePadX(),dig.LorsY()-0.5*SizePadY(),dig.LorsX()-0.5*SizePadX(),dig.LorsY()+SizePcY()-0.5*SizePadY());
+ if(iDil!=0)pL->Draw();
+ }//dilogic loop
+ }//PC loop
}//DrawPc()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliHMPIDDigit::Test()
+{
+ AliHMPIDDigit d1,d2; Int_t ddl;UInt_t w32;
+ for(Int_t i=0;i<10000;i++){
+ Int_t ch=Int_t(gRandom->Rndm()*7);
+ Int_t pc=Int_t(gRandom->Rndm()*6);
+ Int_t px=Int_t(gRandom->Rndm()*80);
+ Int_t py=Int_t(gRandom->Rndm()*48);
+ d1.Set(ch,pc,px,py);
+ ddl=d1.Raw(w32); d2.Raw(ddl,w32);
+ if(d1.Compare(&d2)) Printf("Problem!!!");
+ }
+ Printf("OK");
+}//Test()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
{
public:
enum EAbsPad {kChAbs=100000000,kPcAbs=1000000,kPadAbsX=1000,kPadAbsY=1}; //absolute pad number structure
- enum ERawData{kDilX=8,kDilY=6,kNdil=10,kNrow=24,kNddls=14}; //RAW data structure
- enum EPadData{kPcX=2,kPcY=3,kPad1=0,kPadPcX=80,kPadPcY=48,kPadAllX=kPadPcX*kPcX,kPadAllY=kPadPcY*kPcY,kPcAll=kPcX*kPcY,kPadAll=kPadAllX*kPadAllY}; //Segmentation structure
- enum EPadShif{kC=0,kU=1,kUR=2,kR=3,kDR=4,kD=5,kDL=6,kL=7,kUL=8};
+ enum ERawData{kNddls=14}; //RAW data structure
+ enum EPadData{kPcX=2,kPcY=3,kPadPcX=80,kPadPcY=48,kPadAllX=kPadPcX*kPcX,kPadAllY=kPadPcY*kPcY,kPcAll=kPcX*kPcY,kPadAll=kPadAllX*kPadAllY}; //Segmentation structure
//ctor&dtor
AliHMPIDDigit( ):AliDigit( ),fPad(Abs(-1,-1,-1,-1)),fQ(-1) {} //default ctor
AliHMPIDDigit(Int_t pad,Int_t q,Int_t *t ):AliDigit(t),fPad(pad ),fQ(q ) {} //digit ctor
static Int_t A2P (Int_t pad ) {return pad%kChAbs/kPcAbs; } //abs pad -> pc
static Int_t A2X (Int_t pad ) {return pad%kPcAbs/kPadAbsX; } //abs pad -> pad X
static Int_t A2Y (Int_t pad ) {return pad%kPadAbsX; } //abs pad -> pad Y
- Int_t Addr ( )const{Int_t mapY2A[kDilY]={5,3,1,0,2,4}; return mapY2A[A2Y(fPad)%kDilY]+kDilY*(A2X(fPad)%kDilX);}//raw a=0..47
+ Int_t Addr ( )const{Int_t map[6]={5,3,1,0,2,4};return map[A2Y(fPad)%6]+6*(A2X(fPad)%8);}//ADDRESS 0..47
void AddTidOffset(Int_t offset ) {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging
Int_t Ch ( )const{return A2C(fPad); } //chamber number
- Int_t Dilogic ( )const{return 10-PadX()/kDilX; } //raw d=1..10
+ Int_t Dilogic ( )const{return 1+PadPcX()/8; } //DILOGIC# 1..10
static void DrawPc (Bool_t isFill=kTRUE ); //draw PCs
- Int_t Ddl ( )const{return (PadX()<kPadPcX) ? 2*Ch() : 2*Ch()+1; } //DDL number 0..13
- static Float_t Hit2Sdi (AliHMPIDHit *pHit,TClonesArray *); //hit -> 9 sdigits, returns total QDC
- static Bool_t IsOverTh (Float_t q ) {return q > 6; } //is digit over threshold????
- static Bool_t IsInside (Float_t x,Float_t y ) {return x>0&&y>0&&x<SizeAllX()&&y<SizeAllY(); } //is point inside pc boundary?
- inline static Bool_t IsInDead (Float_t x,Float_t y ); //is point in dead area?
- Float_t LorsX ( )const{return (PadX()+0.5)*SizePadX()+(Pc()%2)*(SizePcX()+SizeDead());} //center of the pad x, [cm]
- Float_t LorsY ( )const{return (PadY()+0.5)*SizePadY()+(Pc()/2)*(SizePcY()+SizeDead());} //center of the pad y, [cm]
+ static void DrawSeg ( ); //draw segmentation
+ void DrawZoom ( );
+ Int_t DdlIdx ( )const{return 2*Ch()+Pc()%2; } //DDL# 0..13
+ Int_t DdlId ( )const{return (6<<8)+DdlIdx(); } //DDL ID 0x600..0x60d
+ static Float_t Hit2Sdi (AliHMPIDHit *pHit,TClonesArray*); //hit -> 9 sdigits, returns total QDC
+ static Bool_t IsOverTh (Float_t q ) {return q > 6; } //is digit over threshold????
+ static Bool_t IsInside (Float_t x,Float_t y ) {return x>0&&y>0&&x<SizeAllX()&&y<SizeAllY(); } //is point inside pc boundary?
+ inline static Bool_t IsInDead (Float_t x,Float_t y ); //is point in dead area?
+ Float_t LorsX ( )const{return (PadPcX()+0.5)*SizePadX()+(Pc()%2)*(SizePcX()+SizeDead());} //center of the pad x, [cm]
+ Float_t LorsY ( )const{return (PadPcY()+0.5)*SizePadY()+(Pc()/2)*(SizePcY()+SizeDead());} //center of the pad y, [cm]
inline Float_t Mathieson (Float_t x,Float_t y )const; //Mathieson distribution
- Int_t PadX ( )const{return A2X(fPad);} //x position of the pad
- Int_t PadY ( )const{return A2Y(fPad);} //y postion of the pad
+ Int_t PadPcX ( )const{return A2X(fPad);} //pad x within PC 0..79
+ Int_t PadPcY ( )const{return A2Y(fPad);} //pad y within PC 0..47
+ Int_t PadChX ( )const{return A2X(fPad);} //pad x within chamber
+ Int_t PadChY ( )const{return A2Y(fPad);} //pad y within chamber
Int_t Pad ( )const{return fPad;} //absolute id of this pad
- Float_t Q ( )const{return fQ;} //charge, [QDC]
Int_t Pc ( )const{return A2P(fPad);} //PC position number
static void PrintSize ( ); //print all segmentation sizes
- inline Int_t Raw (UInt_t &w32 )const; //raw
- Int_t Row ( )const{Int_t r=1+Pc()/2*8+PadY()/kDilY; return (Pc()%2)?kNrow-r+1:r;} //row r=1..24
- void Set (Int_t c,Int_t s,Int_t x,Int_t y) {fPad=Abs(c,s,x,y);} //set new digit
- void ReadRaw (Int_t ddl,Int_t r,Int_t d,Int_t a){Int_t mapA2Y[kDilY]={3,2,4,1,5,0};fPad=Abs(ddl/2,ddl%7,d*kDilX+a/kDilY,r*kDilY+mapA2Y[a%kDilY]);} //from raw
- inline void ReadRaw (Int_t ddl,UInt_t w32 ); //read raw word
+ Float_t Q ( )const{return fQ;} //charge, [QDC]
+ inline Int_t Raw ( UInt_t &raw32 )const; //digit->(ddl,raw32)
+ inline void Raw (Int_t l,UInt_t raw32 ); //(ddl,raw32)->digit
+ static Int_t Raw2Ch (UInt_t l ) {return l/2;} //ch=f(ddl)
+ static Int_t Raw2Pc (UInt_t l,UInt_t r ) {r=(r-1)/8;return (l%2)?5-2*r:2*r;} //pc=f(ddl,r)
+ static Int_t Raw2X ( UInt_t d,UInt_t a ) { return (d-1)*8+a/6;} //padx=f(d,a)
+ static Int_t Raw2Y (UInt_t l,UInt_t r,UInt_t a ) {Int_t a2y[6]={3,2,4,1,5,0};r=(l%2)?(24-r):r-1;return 6*(r%8)+a2y[a%6];}//pady=f(ddl,r,a)
+ Int_t Row ( )const{Int_t r=1+Pc()/2*8+PadPcY()/6; return (Pc()%2)? 25-r:r;} //row r=1..24
+ void Set (Int_t c,Int_t s,Int_t x,Int_t y) {fPad=Abs(c,s,x,y);fQ=0xa3;} //set new digit
static Float_t SizeAllX ( ) {return SizePadX()*kPadAllX+SizeDead();} //all PCs size x, [cm]
static Float_t SizeAllY ( ) {return SizePadY()*kPadAllY+2*SizeDead();} //all PCs size y, [cm]
static Float_t SizePadY ( ) {return 0.84;} //pad size y, [cm]
static Float_t SizePcX ( ) {return SizePadX()*kPadPcX;} //PC size x, [cm]
static Float_t SizePcY ( ) {return SizePadY()*kPadPcY;} //PC size y, [cm]
- static Float_t SizeWin ( ) {return 0.5;}
- static Float_t SizeRad ( ) {return 1.5;}
- static void TestSeg ( ); //test segmentation
- void Zoom ( );
+ static Float_t SizeWin ( ) {return 0.5;} //Quartz window width
+ static Float_t SizeRad ( ) {return 1.5;} //Rad width
+ static void Test ( ); //Test conversions
protected: //AliDigit has fTracks[3]
Int_t fPad; //absolute pad number is chamber*kCham
- Float_t fQ; //QDC value, fractions are permitted for summable procedure
+ Float_t fQ; //QDC value, fractions are permitted for summable procedure
ClassDef(AliHMPIDDigit,4) //HMPID digit class
};//class AliHMPIDDigitN
// Arguments: c- chamber
// q- total QDC
// t -TID
-// x,y - hit position, LORS
+// x,y - hit position, LORS
+// flag- which pad to try
// Returns: none
Int_t pc,padx,pady;
if (x>= 0 && x<= SizePcX() ) {pc=0; padx=Int_t( x / SizePadX());}//PC 0 or 2 or 4
else return;
switch(flag){
- case kUL:padx--;pady++;break; case kU:pady++;break; case kUR:padx++; pady++;break;
+ case 8:padx--;pady++;break; case 1:pady++;break; case 2:padx++; pady++;break;
- case kL: padx--; break; case kC: break; case kR:padx++; break;
+ case 7: padx--; break; case 0: break; case 3:padx++; break;
- case kDL:padx--;pady--;break; case kD:pady--;break; case kDR:padx++; pady--;break;
+ case 6:padx--;pady--;break; case 5:pady--;break; case 4:padx++; pady--;break;
}
if(padx<0 || padx>=kPadPcX) return;
if(pady<0 || pady>=kPadPcY) return;
// Retunrs: -1 if AbsPad less then in pObj, 1 if more and 0 if they are the same
if (fPad==((AliHMPIDDigit*)pObj)->Pad()) return 0;
else if(fPad >((AliHMPIDDigit*)pObj)->Pad()) return 1;
- else return -1;
+ else return -1;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Bool_t AliHMPIDDigit::IsInDead(Float_t x,Float_t y)
AliBitPacking::PackWord( Addr() ,w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47)
AliBitPacking::PackWord( Dilogic(),w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10)
AliBitPacking::PackWord( Row() ,w32,22,26); // Row number bits (22..26) counts (1..24)
- return Ddl(); //ddl 0..13 where to write this digit
+ return DdlIdx(); //ddl 0..13 where to write this digit
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliHMPIDDigit::ReadRaw(Int_t ddl,UInt_t w32)
+void AliHMPIDDigit::Raw(Int_t ddl,UInt_t w32)
{
// Converts a given raw data word to a digit
// Arguments: w32 - 32 bits raw data word
UInt_t a = AliBitPacking::UnpackWord(w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47)
UInt_t d = AliBitPacking::UnpackWord(w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10)
UInt_t r = AliBitPacking::UnpackWord(w32,22,26); // Row number bits (22..26) counts (1..24)
- ReadRaw(ddl,r,d,a);
+ fPad=Abs(Raw2Ch(ddl),Raw2Pc(ddl,r),Raw2X(d,a),Raw2Y(ddl,r,a));
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#endif
// pCluLst - list of clusters, provided empty
// isTryUnfold - flag to choose between CoG and Mathieson fitting
// Returns: none
- TMatrixF digMap(AliHMPIDDigit::kPadAllX,AliHMPIDDigit::kPadAllY); digMap=(Float_t)-1; //digit map for single chamber reseted to -1
+ TMatrixF digMap(AliHMPIDDigit::kPadAllX,AliHMPIDDigit::kPadAllY); digMap=(Float_t)-1; //digit map for single chamber reseted to -1
for(Int_t iDig=0;iDig<pDigLst->GetEntriesFast();iDig++){ //digits loop to fill digits map
- AliHMPIDDigit *pDig= (AliHMPIDDigit*)pDigLst->At(iDig); //get current digit
- digMap( pDig->PadX(), pDig->PadY() )=iDig; //fill the map, (padx,pady) cell takes digit index
+ AliHMPIDDigit *pDig= (AliHMPIDDigit*)pDigLst->At(iDig); //get current digit
+ digMap( pDig->PadChX(), pDig->PadChY() )=iDig; //fill the map, (padx,pady) cell takes digit index
} //digits loop to fill digits map
AliHMPIDCluster clu; //tmp cluster to be used as current
for(Int_t iDig=0;iDig<pDigLst->GetEntriesFast();iDig++){ //digits loop to form clusters list
- AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigLst->At(iDig); //take current digit
- if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigLst,&digMap))) continue; //this digit is already taken in FormClu(), go after next digit
+ AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigLst->At(iDig); //take current digit
+ if(!(pDig=UseDig(pDig->PadChX(),pDig->PadChY(),pDigLst,&digMap))) continue; //this digit is already taken in FormClu(), go after next digit
FormClu(&clu,pDig,pDigLst,&digMap); //form cluster starting from this digit by recursion
clu.Solve(pCluLst,isTryUnfold); //solve this cluster and add all unfolded clusters to provided list
clu.Reset(); //empty current cluster
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDReconstructor::FormClu(AliHMPIDCluster *pClu,AliHMPIDDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap)
{
-// Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit
-// then calls itself recursevly for all neighbours.
+// Forms the initial cluster as a combination of all adjascent digits. Starts from the given digit
+// then calls itself recursevly for all possible neighbours.
// Arguments: pClu - pointer to cluster being formed
-// Returns: none
+// Returns: none ???????????????????
pClu->DigAdd(pDig);//take this digit in cluster
Int_t x[4],y[4];
+ Int_t cnt=0; Int_t iPadX=pDig->PadPcX(); Int_t iPadY=pDig->PadPcY();
+ if(iPadX != 0) {x[cnt]=iPadX-1; y[cnt]=iPadY; cnt++;} //left
+ if(iPadX != AliHMPIDDigit::kPadPcX-1) {x[cnt]=iPadX+1; y[cnt]=iPadY; cnt++;} //right
+ if(iPadY != 0) {x[cnt]=iPadX; y[cnt]=iPadY-1; cnt++;} //down
+ if(iPadY != AliHMPIDDigit::kPadPcY-1) {x[cnt]=iPadX; y[cnt]=iPadY+1; cnt++;} //up
- Int_t iPadCnt=0; Int_t iPadX=pDig->PadX(); Int_t iPadY=pDig->PadY();
- if(iPadX != AliHMPIDDigit::kPad1) {x[iPadCnt]=iPadX-1; y[iPadCnt]=iPadY; iPadCnt++;} //left
- if(iPadX != AliHMPIDDigit::kPadPcX) {x[iPadCnt]=iPadX+1; y[iPadCnt]=iPadY; iPadCnt++;} //right
- if(iPadY != AliHMPIDDigit::kPad1) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY-1; iPadCnt++;} //down
- if(iPadY != AliHMPIDDigit::kPadPcY) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY+1; iPadCnt++;} //up
+ for (Int_t i=0;i<cnt;i++)
+ if((pDig=UseDig(x[i],y[i],pDigLst,pDigMap))) FormClu(pClu,pDig,pDigLst,pDigMap); //check if this neighbour pad fired and mark it as taken
- for (Int_t i=0;i<iPadCnt;i++)
- if((pDig=UseDig(x[i],y[i],pDigLst,pDigMap))) FormClu(pClu,pDig,pDigLst,pDigMap); //check if this neighbour hit and mark it as taken
}//FormClu()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void AliHMPIDReconstructor::Reconstruct(AliRunLoader *pAL)const
UInt_t w32=0;
while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files)
UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13
- dig.ReadRaw(ddl,w32);
- AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iCh,ddl,w32,dig.Ch(),dig.Pc(),dig.PadX(),dig.PadY(),dig.Q()));
+ dig.Raw(ddl,w32);
+ AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iCh,ddl,w32,dig.Ch(),dig.Pc(),dig.PadPcX(),dig.PadPcY(),dig.Q()));
new((*pDigLst)[iDigCnt++]) AliHMPIDDigit(dig); //add this digit to the tmp list
}//raw records loop
if(iDigCnt) Dig2Clu(pDigLst,pRich->CluLst(iCh));//cluster finder for the current chamber if any digits present
#include <TCanvas.h> //Terminate()
#include <TChain.h>
#include <TBenchmark.h>
+#include <TFile.h> //docosmic()
#include <fstream> //caf()
#include <TProof.h> //caf()
#include <AliSelector.h> //base class
#include <AliESD.h>
-
+#include <AliBitPacking.h> //HmpidPayload()
+#include "AliHMPIDDigit.h"
+#include "AliHMPIDCluster.h"
+#include "AliHMPIDReconstructor.h" //docosmic()
class AliHMPIDSelector : public AliSelector {
public :
gBenchmark->Show("PRooF exec");
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t DateHeader(ifstream *pFile,Bool_t isPrint=0)
+{
+ Int_t iSize=-1;
+ pFile->read((char*)&iSize,4);
+ if(!isPrint)
+ pFile->seekg(16*4,ios::cur);
+ else{
+ Int_t w32=-1;
+ Printf("");
+ Printf("Event size %i bytes",iSize); //1 common DATE header 17 words
+ pFile->read((char*)&w32,4); Printf("Event magic 0x%x" ,w32); //2
+ pFile->read((char*)&w32,4); Printf("Event head size %i bytes",w32); //3
+ pFile->read((char*)&w32,4); Printf("Event version 0x%x" ,w32); //4
+ pFile->read((char*)&w32,4); Printf("Event type %i (%s)" ,w32,(w32==7)? "physics":"SOR"); //5
+ pFile->read((char*)&w32,4); Printf("Run number %i" ,w32); //6
+
+ pFile->read((char*)&w32,4); Printf("Event ID 1 %i" ,w32); //7
+ pFile->read((char*)&w32,4); Printf("Event ID 2 %i" ,w32); //8
+
+ pFile->read((char*)&w32,4); Printf("Trigger pattern 1 %i" ,w32); //9
+ pFile->read((char*)&w32,4); Printf("Trigger pattern 2 %i" ,w32); //10
+
+ pFile->read((char*)&w32,4); Printf("Detector pattern %i" ,w32); //11
+
+ pFile->read((char*)&w32,4); Printf("Type attribute 1 %i" ,w32); //12
+ pFile->read((char*)&w32,4); Printf("Type attribute 2 %i" ,w32); //13
+ pFile->read((char*)&w32,4); Printf("Type attribute 3 %i" ,w32); //14
+
+ pFile->read((char*)&w32,4); Printf("LDC ID %i" ,w32); //15
+ pFile->read((char*)&w32,4); Printf("GDC ID %i" ,w32); //16
+ pFile->read((char*)&w32,4); TDatime time(w32); time.Print(); //17
+
+ Printf("");
+ }
+ return iSize;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void HmpidHeader(ifstream *pFile,Bool_t isPrint=kFALSE)
+{
+// Prints hmpid trailer and returns number of words for this trailer
+ if(!isPrint) {pFile->seekg(15*4,ios::cur);return;}
+ Int_t w32=-1;
+ Printf("\nHMPID Header:");//private HEADER is 15 words
+ for(Int_t i=1;i<=11;i++) { pFile->read((char*)&w32,4); Printf("Word #%2i=%12i meaningless",i,w32);}
+ pFile->read((char*)&w32,4); Printf("Word #12=%12i event counter",w32);
+ for(Int_t i=13;i<=15;i++){ pFile->read((char*)&w32,4); Printf("Word #%2i=%12i empty",i,w32);}
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void HmpidPayload(ifstream *pFile,Int_t iDdl,TClonesArray *pDigLst)
+{
+// payload is 8 sequences with structure: WC36A8 then WC number of w32
+ UInt_t w32=0;
+ Int_t iDigCnt=pDigLst->GetEntriesFast();
+ for(Int_t row=1;row<=8;row++){
+ pFile->read((char*)&w32,4); Int_t wc=AliBitPacking::UnpackWord(w32,16,31); Int_t ma=AliBitPacking::UnpackWord(w32, 0,15);
+ if(ma!=0x36a8) Printf("ERROR ERROR ERROR WRONG Marker=0x%x ERROR ERROR ERROR",ma);
+ for(Int_t i=1;i<=wc;i++){//words loop
+ pFile->read((char*)&w32,4);
+ if(w32&0x08000000) continue; //it's DILOGIC CW
+ AliHMPIDDigit *pDig=new AliHMPIDDigit;
+ pDig->Raw(iDdl,w32);
+ new ((*pDigLst)[iDigCnt++]) AliHMPIDDigit(*pDig);
+ }//words loop
+ }//rows loop
+}//HmpidPayload()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void docosmic(const char* name)
+{
+ gBenchmark->Start("Cosmic converter");
+ ifstream in(name);
+
+
+ Bool_t isPrint=kFALSE;
+
+ TString rooName=name; rooName.Replace(1+rooName.First('.'),4,"root");
+ Int_t ddl=0;
+
+ TFile *pOut=new TFile(rooName,"recreate");
+ TTree *pTr=new TTree("cosmic","some for time being");
+
+ TClonesArray *pDigLst=new TClonesArray("AliHMPIDDigit"); pTr->Branch("Digs",&pDigLst);
+ TClonesArray *pCluLst=new TClonesArray("AliHMPIDCluster"); pTr->Branch("Clus",&pCluLst);
+
+ while(1){
+ Int_t iSize=DateHeader(&in, isPrint); if(iSize==68) continue; //DATE header
+ if(in.eof()) break;
+ HmpidHeader (&in, isPrint); //HMPID header
+ HmpidPayload(&in,ddl+1,pDigLst); //HMPID payload
+ HmpidHeader (&in, isPrint); //HMPID header
+ HmpidPayload(&in,ddl ,pDigLst); //HMPID payload
+
+ AliHMPIDReconstructor::Dig2Clu(pDigLst,pCluLst);
+ pTr->Fill();
+ pDigLst->Clear(); pCluLst->Clear();
+ }
+
+ pTr->Write();
+ pOut->Close();
+ delete pDigLst;
+ in.close();
+ gBenchmark->Show("Cosmic converter");
+}//docosmic()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void cosmic()
+{
+ TChain *pCh=new TChain("cosmic");
+ pCh->Add("test.root");
+
+
+ TH1F *pDigQ=new TH1F("digQ","Digits QDC",500,0,4100);
+ TH1F *pDigO=new TH1F("digO","Digits # per event",500,0,8000);
+ TH2F *pDigM=new TH2F("digM","Digits map",500,0,131,500,0,127);
+
+ TH1F *pCluQ=new TH1F("cluQ","Clusters QDC",500,0,12100);
+ TH1F *pCluO=new TH1F("cluO","Clusters # per event",500,0,5000);
+ TH2F *pCluM=new TH2F("cluM","Clusters map",500,0,131,500,0,127);
+
+ TClonesArray *pDigLst=new TClonesArray("AliHMPIDDigit"); pCh->SetBranchAddress("Digs",&pDigLst);
+ TClonesArray *pCluLst=new TClonesArray("AliHMPIDCluster"); pCh->SetBranchAddress("Clus",&pCluLst);
+
+ for(Int_t iEvt=0;iEvt<pCh->GetEntries();iEvt++){
+ pCh->GetEntry(iEvt);
+
+ pDigO->Fill(pDigLst->GetEntriesFast());
+ pCluO->Fill(pCluLst->GetEntriesFast());
+
+ for(Int_t iDig=0;iDig<pDigLst->GetEntriesFast();iDig++){//digits loop
+ AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigLst->UncheckedAt(iDig);
+ pDigQ->Fill(pDig->Q());
+ pDigM->Fill(pDig->LorsX(),pDig->LorsY());
+ }//digits loop
+
+ for(Int_t iClu=0;iClu<pCluLst->GetEntriesFast();iClu++){//clusters loop
+ AliHMPIDCluster *pClu=(AliHMPIDCluster*)pCluLst->UncheckedAt(iClu);
+ pCluQ->Fill(pClu->Q());
+ pCluM->Fill(pClu->X(),pClu->Y());
+ }//digits loop
+ }//entries loop
+
+ TCanvas *pC=new TCanvas("comic","cosmic"); pC->Divide(2,3);
+
+ pC->cd(1); pDigM->Draw(); pC->cd(2); pCluM->Draw();
+ pC->cd(3); pDigQ->Draw(); pC->cd(4); pCluQ->Draw();
+ pC->cd(5); pDigO->Draw(); pC->cd(6); pCluO->Draw();
+}//cosmic()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
UInt_t w32=0;
while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files)
UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13
- sdi.ReadRaw(ddl,w32);
+ sdi.Raw(ddl,w32);
new((*pSdiLst)[iSdiCnt++]) AliHMPIDDigit(sdi); //add this digit to the tmp list
}//raw records loop
GetLoader()->TreeS()->Fill(); GetLoader()->WriteSDigits("OVERWRITE");//write out sdigits
-0.942641 0.000000 0.333807 Tz = 163.565361
-Map of all HMPID PC planes, coordinates are in spherical system= distance from IP in cm, Theta and Phi in degrees:
-_______________________________ _______________________________
-| 506.21 506.21| | 506.21 506.21|
-| 63.26 78.07| | 82.59 97.41|
-| 58.02 57.32| | 57.22 57.22|
-| | | |
-| 498.00 | | 498.00 | Sensitive area (130.60,126.16)
-| 70.50 | | 90.00 | Lors Center ( 65.30, 63.08)
-| 50.00 | | 50.00 |
-| | | |
-| 506.21 506.21| | 506.21 506.21|
-| 63.26 78.07| | 82.59 97.41|
-| 41.98 6 42.68| | 42.78 5 42.78|
-------------------------------- -------------------------------
-
-_______________________________ _______________________________ _______________________________
-| 506.21 506.21| | 506.21 506.21| | 506.21 506.21|
-| 63.26 78.07| | 82.59 97.41| | 101.93 116.74|
-| 38.02 37.32| | 37.22 37.22| | 37.32 38.02|
-| | | | | |
-| 498.00 | | 498.00 | | 498.00 |
-| 70.50 | | 90.00 | | 109.50 |
-| 30.00 | | 30.00 | | 30.00 |
-| | | | | |
-| 506.21 506.21| | 506.21 506.21| | 506.21 506.21|
-| 63.26 78.07| | 82.59 97.41| | 101.93 116.74|
-| 21.98 4 22.68| | 22.78 3 22.78| | 37.32 2 38.02|
-------------------------------- ------------------------------- -------------------------------
-
- _______________________________ _______________________________
- | 506.21 506.21| | 506.21 506.21|
- | 82.59 97.41| | 101.93 116.74|
- | 17.22 17.22| | 17.32 18.02|
- | | | |
- | 498.00 | | 498.00 |
- | 90.00 | | 109.50 |
- | 10.00 | | 10.00 |
- | | | |
- | 506.21 506.21| | 506.21 506.21|
- | 82.59 97.41| | 101.93 116.74|
- | 2.78 1 2.78| | 2.68 0 1.98|
- ------------------------------- -------------------------------
+
+
+
+
+
+
+