]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RICH/AliRICHDigit.h
coding violation fixes
[u/mrichter/AliRoot.git] / RICH / AliRICHDigit.h
1 #ifndef AliRICHDigit_h
2 #define AliRICHDigit_h
3 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4  * See cxx source for full Copyright notice                               */
5
6 #include <AliDigit.h>      //base class  
7 #include <AliBitPacking.h> //ToRaw(), FromRaw()
8 #include <TVector.h>       //ctor
9 /*
10 Any given LDC collects data from all FEE connected to the LDC by DDL. This data is stored in name.ddl file.
11 Name of this file is composed by detector name plus some value for example RICH1793.ddl
12 That value is calculated as sequensial number of detector LDC plus some predifined offset, unique for a given detector.
13 The value is expected to be within a given range assigned to detector.
14 For RICH, the offset number is 0x700 hex or 1792 decimal (reffered in the code as kDdlOffset). 
15 The range assigned for RICH is 0x700-0x714 hex or 1792-1812 decimal. It is 20 ddl files or 20 LDCs.
16 RICH actually uses 14 LDCs hence DAQ writes for RICH 14 ddl files (reffered in the code as kNddls).
17 RICH FEE is connected to LDC in the following way:
18 Single LDC serves one half of a chamber i.e. 3 photocathodes aka sectors,  even LDC for left part( sectors 1-3-5) and odd LDC for right part(2-4-6) 
19 So the LDC -chamber-ddl file name map is:
20 LDC  0 -> ch 1L -> file name value 0x700 1792          LDC  1 -> ch 1R -> file name value 0x701 1793
21 LDC  2 -> ch 2L -> file name value 0x702 1794          LDC  3 -> ch 2R -> file name value 0x703 1795
22 LDC  4 -> ch 3L -> file name value 0x704 1796          LDC  5 -> ch 3R -> file name value 0x705 1797
23 LDC  6 -> ch 4L -> file name value 0x706 1798          LDC  7 -> ch 4R -> file name value 0x707 1799
24 LDC  8 -> ch 5L -> file name value 0x708 1800          LDC  9 -> ch 5R -> file name value 0x709 1801
25 LDC 10 -> ch 6L -> file name value 0x70a 1802          LDC 11 -> ch 6R -> file name value 0x70b 1803
26 LDC 12 -> ch 7L -> file name value 0x70c 1804          LDC 13 -> ch 7R -> file name value 0x70d 1805
27
28 Programmatically, operations with ddl files are interfaced by class AliRawReader. In order to select some ddl files for detector,
29 one needs to provide a reserved id number of detector. For RICH, this number is 7 (reffered in the code as kRichRawId).
30
31 DDL file starts with common header described in AliRawDataHeader, which can be followed by private header.
32 RICH has no any private header, just uses the common one.
33
34 RICH FEE as seen by single LDC is composed from a number of DILOGIC chips organized in vertical stack of rows. 
35 Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDiloX,kDiloY). Channels counted from 0 to 47.
36
37 ??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ???????  
38
39 10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdilo), so the row is 80x6 pads structure. 
40 DILOGIC chips in the row are counted from left to right as seen from MARS (0,0,0), from 1 to 10.
41 24 rows are piled up forming the whole FEE served by single LDC, so one LDC sees 80x144 pads separated in 3 photocathodes aka sectors.
42 Rows are counted from 1 to 24 from top    to bottom for left  half chamber (sectors 1-3-5) as seen from MARS (0,0,0), meaning even LDC number
43                           and from bottom to top    for right half chamber (sectors 2-4-6) as seen from MARS (0,0,0), meaning odd LDC number.
44
45 So RICH raw word is 32 bits with the structure:   
46    00000             rrrrr                      dddd                               aaaaaa                          qqqqqqqqqqqq 
47  5 bits zero  5 bits row number (1..24)  4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47)  12 bits QDC value (0..4095)
48 */
49
50 class AliRICHDigit :public AliDigit
51 {
52 public:
53   enum EAbsPad {kChamAbs=10000000,kSecAbs=1000000,kPadAbsX=1000,kPadAbsY=1};                //absolute pad number structure
54   enum ERawData{kDiloX=8,kDiloY=6,kNdilo=10};                                               //DILOGIC structure, see description above 
55   enum EPadData{kFirstPad=1,kPadsSecX=80,kPadsSecY=48,kPadsChamX=160,kPadsChamY=144,kSecX=2,kSecY=3};   //Segmentation structure 
56   enum EDdlData{kNddls=14,kDdlOffset=0x700,kRichRawId=7};                                   //Common DDL structure, see description above
57 //ctor&dtor    
58   AliRICHDigit()                                                :AliDigit(),fCFM(-1) ,fChamber(-1  )     ,fPadX(-1)      ,fPadY(-1)      ,fQdc(-1)  {}
59   AliRICHDigit(Int_t pad,Double_t qdc,Int_t cfm=-1,Int_t tid=-1):AliDigit(),fCFM(cfm),fChamber(P2C(pad)) ,fPadX(P2X(pad)),fPadY(P2Y(pad)),fQdc(qdc) {fTracks[0]=tid;}
60   AliRICHDigit(TVector pad,Double_t q                          ):AliDigit(),fCFM(-1) ,fChamber(-1)       ,fPadX((Int_t)pad[0])  ,fPadY((Int_t)pad[1])  ,fQdc(q)   {}
61   AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm),fChamber(c)  
62        {fPadX=(Int_t)pad[0];fPadY=(Int_t)pad[1];fQdc=q;fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;}
63   virtual ~AliRICHDigit() {;}
64 //framework part    
65                 Bool_t   IsSortable  (                               )const{return kTRUE;}                                                    //provision to use TObject::Sort()
66          inline Int_t    Compare     (const TObject *pObj            )const;                                                                  //provision to use TObject::Sort()
67                 void     Print       (Option_t *opt=""               )const;                                                                  //TObject Print() overload
68 //private part  
69                 void     AddTidOffset(Int_t offset                   )     {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging
70                 Int_t    Cfm         (                               )const{return fCFM;}                                                     //ckov-feed-mip mixture
71                 Int_t    Chamber     (                               )const{return fChamber;}                                                 //chamber number
72                 Int_t    C           (                               )const{return fChamber;}                                                 //chamber number 
73          inline Int_t    Dig2Raw     (        UInt_t &w              )const;                                                                  //returns DDL ID and fill raw word
74                 Int_t    PadX        (                               )const{return fPadX;}                                                    //x position of the pad
75                 Int_t    PadY        (                               )const{return fPadY;}                                                    //y postion of the pad     
76                 TVector  Pad         (                               )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);}
77                 Int_t    PadAbs      (                               )const{return fChamber*kChamAbs+fPadX*kPadAbsX+fPadY;}                   //absolute id of this pad
78   static inline Int_t    Pad2Sec     (Int_t x,Int_t y                );                                   
79   static        Int_t    P2A         (Int_t c,        Int_t x,Int_t y)     {Int_t s=Pad2Sec(x,y);return c*kChamAbs+s*kSecAbs+x*kPadAbsX+y;}   //(cham,padx,pady)-> abs pad
80   static        Int_t    P2A         (Int_t c,Int_t s,Int_t x,Int_t y)     {return Pad2Sec(x,y)==s?c*kChamAbs+s*kSecAbs+x*kPadAbsX+y:-1;}     //(cham,sec,padx,pady)-> abs pad
81   static        Int_t    P2C         (Int_t pad                      )     {return pad/kChamAbs;}                                             //abs pad -> chamber
82   static        Int_t    P2S         (Int_t pad                      )     {return pad%kChamAbs/kSecAbs;}                                     //abs pad -> sector 
83   static        Int_t    P2X         (Int_t pad                      )     {return pad%kSecAbs/kPadAbsX;}                                     //abs pad -> pad X 
84   static        Int_t    P2Y         (Int_t pad                      )     {return pad%kPadAbsX;}                                             //abs pad number-> pad Y 
85                 Double_t Qdc         (                               )const{return fQdc;}                                                     //charge, QDC
86          inline void     Raw2Dig     (Int_t ddl,UInt_t  w32          );                                                                       //(DDL,w32)->(ch,sec,x,y,QDC)
87                 Int_t    S           (                               )const{return -1;}                                                       //sector number  ?????
88   static        void     Test        (                               );                                                                       //test raw-digit manipulations
89 protected:
90   Int_t    fCFM;      //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips  
91   Int_t    fChamber;  //chamber
92   Int_t    fPadX;     //pad along X
93   Int_t    fPadY;     //pad along Y
94   Double_t fQdc;      //QDC value, fractions are permitted for summable procedure  
95   ClassDef(AliRICHDigit,3) //RICH digit class       
96 };//class AliRICHDigit
97 //__________________________________________________________________________________________________
98 Int_t AliRICHDigit::Compare(const TObject *pObj) const
99 {
100 //Used in Sort() method to compare to objects. Note that abs pad structure is first x then y, hence will be sorted on column basis.
101 //This feature is used in digitizer to facilitate finding of sdigits for the same pad since they all will come together after sorting.
102 //Arguments: pObj - pointer to object to compare with
103 //  Retunrs: -1 if AbsPad less then in pObj, 1 if more and 0 if they are the same      
104   if     (PadAbs()==((AliRICHDigit*)pObj)->PadAbs()) return  0;
105   else if(PadAbs() >((AliRICHDigit*)pObj)->PadAbs()) return  1;
106   else                                               return -1;
107 }
108 //__________________________________________________________________________________________________
109 void AliRICHDigit::Raw2Dig(Int_t ddl,UInt_t w32)
110 {
111 //Converts a given raw data word to a digit
112 //Arguments: w32 - 32 bits raw data word
113 //           ddl - DDL file number  0 1 2 3 4 ... 13
114 //  Returns: none
115       fQdc = AliBitPacking::UnpackWord(w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq         Qdc               bits (00..11) counts (0..4095)   
116   UInt_t a = AliBitPacking::UnpackWord(w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000         DILOGIC address   bits (12..17) counts (0..47)
117   UInt_t d = AliBitPacking::UnpackWord(w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210         DILOGIC number    bits (18..21) counts (1..10)
118   UInt_t r = AliBitPacking::UnpackWord(w32,22,26);  //                                                 Row number        bits (22..26) counts (1..24)    
119   
120   fPadY    = (r-1)*kDiloY+a/kDiloX+1;
121   fPadX    = (d-1)*kDiloX+a%kDiloX+1;      fPadX+=(ddl%2)*kDiloX*kNdilo;//if ddl is odd then right half of the chamber
122   fChamber = (ddl+2)/2;  // ddl 0..13 to chamber 1..7
123 }  
124 //__________________________________________________________________________________________________
125 Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const
126 {
127 //Convert digit structure to raw word format
128 //Arguments: 32 bits raw word to fill
129 //  Returns: DDL ID where to write this digit
130   Int_t ddl=2*C()-1;                                         //chamber 1..7 -> DDL 0..13, this idDdl is for right half (sectors 2 4 6), to be decremented if d < kNchips
131   UInt_t a =  (PadY()-1)%kDiloY*kDiloX+(PadX()-1)%kDiloX;    //invented to be horizontal zig-zag
132   UInt_t r =1+(PadY()-1)/kDiloY;                             //Row number depends only on y and we have (1..24) rows per (1..144) pads
133   UInt_t d =1+(PadX()-1)/kDiloX;                             //DILOGIC number depends only on x we have (1..10) chips per (1..80) pads
134   if(d>kNdilo)
135     d-=kNdilo;              //chip number more then kNdilo means right half of chamber, goes to this ddl
136   else
137     ddl--;                  //chip number less then kNdilo means left half of the chamber, goes to ddl-1 
138   
139   w32=0;
140   AliBitPacking::PackWord((UInt_t)fQdc,w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq        Qdc               bits (00..11) counts (0..4095)
141   AliBitPacking::PackWord(           a,w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000        DILOGIC address   bits (12..17) counts (0..47)
142   AliBitPacking::PackWord(           d,w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210        DILOGIC number    bits (18..21) counts (1..10)
143   AliBitPacking::PackWord(           r,w32,22,26);  //                                                Row number        bits (22..26) counts (1..24)  
144   return ddl; //ddl 0..13 where to write this digit 
145 }
146 //__________________________________________________________________________________________________
147 Int_t AliRICHDigit::Pad2Sec(Int_t padx,Int_t pady)
148 {
149 //Determines sector containing the given pad.
150 //Arguments: padx,pady - pad number
151 //  Returns: sector number    
152 //y ^  5 6         sectors map as seen from IP
153 //  |  3 4
154 //  |  1 2
155 //   -------> x  
156   Int_t sector;      
157   if     (padx >=     1      && padx <=   kPadsSecX )    sector=1;
158   else if(padx >  kPadsSecX  && padx <=   kPadsChamX)    sector=2; 
159   else                                                   return -1;//padx out of range     
160   if     (pady >=     1      && pady <=   kPadsSecY )    return sector;
161   else if(pady >   kPadsSecY && pady <= 2*kPadsSecY )    return sector+2;
162   else if(pady > 2*kPadsSecY && pady <=   kPadsChamY)    return sector+4;
163   else                                                   return -1; //pady out of range
164 }//Pad2Sec()
165 //__________________________________________________________________________________________________
166 #endif