In trigger classes:
[u/mrichter/AliRoot.git] / MUON / AliMUONGlobalTriggerBoard.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONGlobalTriggerBoard
20 /// Global trigger implementation:
21 /// - inputs are regional responses
22 /// - output is a 12-bit word
23 /// - 4 bits per trigger level
24 ///
25 /// \author Rachid Guernane (LPCCFd), 
26 /// Corrected by Christian Finck (Subatech)
27 //-----------------------------------------------------------------------------
28
29 #include "AliMUONGlobalTriggerBoard.h"
30 #include "AliLog.h"
31 #include "TBits.h"
32
33 #include <Riostream.h>
34
35 /// \cond CLASSIMP
36 ClassImp(AliMUONGlobalTriggerBoard)
37 /// \endcond
38
39 //___________________________________________
40 AliMUONGlobalTriggerBoard::AliMUONGlobalTriggerBoard(): AliMUONTriggerBoard()
41 {
42 /// Default constructor
43
44    for (Int_t i=0;i<16;i++) fRegionalResponse[i] = 0;
45    for (Int_t i=0;i< 4;i++) fGlobalInput[i] = 0;
46    for (Int_t i=0;i< 4;i++) fMask[i] = 0xffffffff;
47 }
48
49 //___________________________________________
50 AliMUONGlobalTriggerBoard::AliMUONGlobalTriggerBoard(const char *name, Int_t a) : AliMUONTriggerBoard(name, a)
51 {
52 /// Standard constructor
53
54    for (Int_t i=0;i<16;i++) fRegionalResponse[i] = 0;
55    for (Int_t i=0;i< 4;i++) fGlobalInput[i] = 0;
56    for (Int_t i=0;i< 4;i++) fMask[i] = 0xffffffff;
57 }
58
59 //___________________________________________
60 AliMUONGlobalTriggerBoard::~AliMUONGlobalTriggerBoard()
61 {
62 /// Destructor
63 }
64
65 //___________________________________________
66 void AliMUONGlobalTriggerBoard::Mask(Int_t index, UInt_t mask)
67 {
68   /// mask global trigger board input index with value mask
69   if ( index >= 0 && index < 4 ) 
70   {
71     fMask[index]=mask;
72   }
73   else
74   {
75     AliError(Form("Index %d out of bounds (max %d)",index,3));
76   }  
77 }
78
79 //___________________________________________
80 void AliMUONGlobalTriggerBoard::Response()
81 {
82    /// compute the global trigger board
83    /// response according to the algo() method
84 // output from global trigger algorithm
85 // [+, -, US, LS] * [Hpt, Lpt]
86 // transformed to [usHpt, usLpt, lsHpt, lsLpt, sHpt, sLpt] according
87 // to Global Trigger Unit user manual
88
89    Int_t t[16];
90
91    BuildGlobalInput();
92    MaskGlobalInput();
93
94    for (Int_t i = 0; i < 16; ++i) 
95    {
96      t[i] = fRegionalResponse[i];
97    }
98    
99    
100    Int_t rank = 8;
101
102    for (Int_t i=0;i<4;i++)
103    {
104       Int_t ip = 0;
105       
106       for (Int_t j=0;j<rank;j++)
107       {
108          UShort_t lthres = Algo(t[2*j],t[2*j+1],"LPT");
109
110          UShort_t hthres = Algo(t[2*j],t[2*j+1],"HPT"); hthres <<= 4;
111
112          t[ip] = lthres | hthres;
113
114          ip++;
115       }
116       
117       rank /= 2; 
118    }
119    UChar_t sLpt, sHpt, lsLpt, lsHpt, usLpt, usHpt;
120    sLpt  = ((t[0] & 0xC)  != 0);
121    sHpt  = ((t[0] & 0xC0) != 0);
122    lsLpt = ((t[0] & 0x1)  != 0);
123    lsHpt = ((t[0] & 0x10) != 0);
124    usLpt = ((t[0] & 0x2 ) != 0);
125    usHpt = ((t[0] & 0x20) != 0);
126
127    // LSB is zero (trigger choice to send to CTP: sLpt or sHpt)
128
129    sLpt  <<= 1;
130    sHpt  <<= 2;
131    lsLpt <<= 3;
132    lsHpt <<= 4;
133    usLpt <<= 5;
134    usHpt <<= 6;
135
136    fResponse = sLpt | sHpt | lsLpt | lsHpt | usLpt |usHpt;
137    
138
139 }
140
141 //___________________________________________
142 UShort_t AliMUONGlobalTriggerBoard::Algo(UShort_t i, UShort_t j, const char *thres)
143 {
144 /// global trigger algorithm
145 ///   a ,b = reg  response  =  Hpt (+|-|us|ls) |  Lpt (+|-|us|ls)  
146                            
147    TBits a(8), b(8); a.Set(8,&i); b.Set(8,&j);
148
149    TBits trg1(2), trg2(2), trg(2);
150
151    if (!strcmp(thres,"LPT"))
152    {
153       trg1[0] = a[2]; trg1[1] = a[3]; 
154       trg2[0] = b[2]; trg2[1] = b[3];
155    }
156    else
157    {
158       trg1[0] = a[6]; trg1[1] = a[7]; 
159       trg2[0] = b[6]; trg2[1] = b[7];         
160    }
161        
162    TBits trgLS1(1), trgUS1(1), trgLS2(1), trgUS2(1), trgLS(1), trgUS(1);
163
164    if (!strcmp(thres,"LPT"))
165    {
166       trgLS1[0] = a[0]; trgUS1[0] = a[1]; 
167       trgLS2[0] = b[0]; trgUS2[0] = b[1];
168    }
169    else
170    {
171       trgLS1[0] = a[4]; trgUS1[0] = a[5]; 
172       trgLS2[0] = b[4]; trgUS2[0] = b[5];         
173    }
174
175    trgLS[0] = ( trg1[0] & trg2[0] ) | ( trg1[1] & trg2[1] ) | trgLS1[0] | trgLS2[0];
176    trgUS[0] = ( trg1[0] & trg2[1] ) | ( trg1[1] & trg2[0] ) | trgUS1[0] | trgUS2[0];
177    
178    trg[0] = trg1[0] | trg2[0];
179    trg[1] = trg1[1] | trg2[1];
180    
181    TBits v(4);
182    
183    v[0] = trgLS[0];
184    v[1] = trgUS[0];
185    v[2] = trg[0];
186    v[3] = trg[1];
187
188    UShort_t rv = 0;
189    v.Get(&rv);
190    
191    return rv;
192 }
193
194 //___________________________________________
195 void AliMUONGlobalTriggerBoard::BuildGlobalInput()
196 {
197   /// build the 4 words (32bits) global input from the regional responses
198   /// the order of regional responses is:
199   /// 1R, 2R, 2-3R, 3R, 4R, 5R, 6R, 7R, 1L, 2L, 2-3L, 3L, 4L, 5L, 6L, 7L
200
201   for (Int_t i=0;i< 4;i++) fGlobalInput[i] = 0;
202
203   UShort_t regRespInv;
204   TBits rs(8), rsi(8);
205   for (Int_t iReg = 0; iReg < 16; iReg++) {
206
207     // invert bits in regional response ?
208     rs.Set(8,&fRegionalResponse[iReg]);
209     for (Int_t i = 0; i < 4; i++) {
210       // ... YES
211       //rsi[2*i]   = rs[2*i+1];
212       //rsi[2*i+1] = rs[2*i];
213       // ... NO
214       rsi[2*i]   = rs[2*i];
215       rsi[2*i+1] = rs[2*i+1];
216     }
217     regRespInv = 0;
218     rsi.Get(&regRespInv);
219
220     if (iReg < 8) {    // right
221       // Lpt word
222       fGlobalInput[0] |=  (regRespInv & 0x0F)       << (4*iReg);
223       // Hpt word
224       fGlobalInput[2] |= ((regRespInv & 0xF0) >> 4) << (4*iReg);
225     } else {           // left
226       // Lpt word
227       fGlobalInput[1] |=  (regRespInv & 0x0F)       << (4*(iReg-8));
228       // Hpt word
229       fGlobalInput[3] |= ((regRespInv & 0xF0) >> 4) << (4*(iReg-8));
230     }
231
232   }
233
234 }
235
236 //___________________________________________
237 void AliMUONGlobalTriggerBoard::MaskGlobalInput()
238 {
239   /// Apply masks to global input and recalculate regional inputs before
240   /// applying the global response
241
242   UShort_t regRespInv;
243   TBits rs(8), rsi(8);
244
245   // global input with masks applied
246   UInt_t gitmp[4];
247
248   for (Int_t i = 0; i < 4; i++) {
249     gitmp[i] = fGlobalInput[i];
250     gitmp[i] &= fMask[i];
251   }
252
253   for (Int_t iReg = 0; iReg < 16; iReg++) {
254     fRegionalResponse[iReg] = 0;
255     if (iReg < 8) {    // right
256       // Lpt
257       fRegionalResponse[iReg] |=  (gitmp[0] >> (4*iReg))     & 0xF;
258       // Hpt
259       fRegionalResponse[iReg] |= ((gitmp[2] >> (4*iReg))     & 0xF) << 4;
260     } else {           // left
261       // Lpt
262       fRegionalResponse[iReg] |=  (gitmp[1] >> (4*(iReg-8))) & 0xF;
263       // Hpt
264       fRegionalResponse[iReg] |= ((gitmp[3] >> (4*(iReg-8))) & 0xF) << 4;
265     }
266     // invert bits in regional response ?
267     rs.Set(8,&fRegionalResponse[iReg]);
268     for (Int_t i = 0; i < 4; i++) {
269       rsi[2*i]   = rs[2*i+1];
270       rsi[2*i+1] = rs[2*i];
271     }
272     regRespInv = 0;
273     rsi.Get(&regRespInv);
274     // uncomment if ... YES
275     //fRegionalResponse[iReg] = regRespInv;
276   }
277
278 }
279
280 //___________________________________________
281 void AliMUONGlobalTriggerBoard::Scan(Option_t*) const
282 {
283   /// print global trigger output 
284   TBits w(7); w.Set(7,&fResponse);
285
286 // TRG[1:0]
287 // 00 noth
288 // 01 negative track
289 // 10 positive track
290 // 11 undef
291
292    Int_t iS[2] = {0,0};
293
294    iS[0] = (Int_t)w.TestBitNumber(1);
295    iS[1] = (Int_t)w.TestBitNumber(2);
296
297    Int_t iPU[2] = {w[5],w[6]};
298    Int_t iPL[2] = {w[3],w[4]};
299
300    printf("============================================\n");
301    printf(" Global Trigger output       Low pt  High pt\n");
302    printf(" number of Single           :\t");
303    for (Int_t i=0; i<2; i++) printf("%i\t",iS[i]);
304    printf("\n");
305    printf(" number of UnlikeSign pair  :\t"); 
306    for (Int_t i=0; i<2; i++) printf("%i\t",iPU[i]);
307    printf("\n");
308    printf(" number of LikeSign pair    :\t");  
309    for (Int_t i=0; i<2; i++) printf("%i\t",iPL[i]);
310    printf("\n");
311    printf("===================================================\n");
312    printf("\n");
313 }
314