7277d409649255cec9b1a3a2ed4baf024c64c29b
[u/mrichter/AliRoot.git] / MUON / AliMUONLocalTriggerBoard.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 AliMUONLocalTriggerBoard
20 /// A local trigger board has as input a bit pattern and returns 
21 /// the local trigger response after comparison w/ a LUT
22 /// \todo Change member functions comments in capital letters to normal text
23 ///
24 /// \author Rachid Guernane (LPCCFd)
25 //-----------------------------------------------------------------------------
26
27 #include <cstdlib>
28 #include "AliMUONLocalTriggerBoard.h"
29 #include "AliMUONTriggerLut.h"
30
31 #include "AliLog.h"
32
33 #include <TBits.h>
34 #include <Riostream.h>
35
36 /// \cond CLASSIMP
37 ClassImp(AliMUONLocalTriggerBoard)
38 /// \endcond
39
40 const Int_t AliMUONLocalTriggerBoard::fgkCircuitId[234] = 
41 {
42   111,  121,  131,  141,  151,  161,  171,
43   211,  212,  221,  222,  231,  232,  241,  242,  251,  252,  261,  262,  271,
44   311,  312,  321,  322,  331,  332,  341,  342,  351,  352,  361,  362,  371,
45   411,  412,  413,  421,  422,  423,  424,  431,  432,  433,  434,  441,  442,  451,  452,  461,  462,  471,
46   521,  522,  523,  524,  531,  532,  533,  534,  541,  542,  551,  552,  561,  562,  571, 
47   611,  612,  613,  621,  622,  623,  624,  631,  632,  633,  634,  641,  642,  651,  652,  661,  662,  671,
48   711,  712,  721,  722,  731,  732,  741,  742,  751,  752,  761,  762,  771,
49   811,  812,  821,  822,  831,  832,  841,  842,  851,  852,  861,  862,  871,
50   911,  921,  931,  941,  951,  961,  971,
51   -111, -121, -131, -141, -151, -161, -171,
52   -211, -212, -221, -222, -231, -232, -241, -242, -251, -252, -261, -262, -271,
53   -311, -312, -321, -322, -331, -332, -341, -342, -351, -352, -361, -362, -371,
54   -411, -412, -413, -421, -422, -423, -424, -431, -432, -433, -434, -441, -442, -451, -452, -461, -462, -471,
55   -521, -522, -523, -524, -531, -532, -533, -534, -541, -542, -551, -552, -561, -562, -571, 
56   -611, -612, -613, -621, -622, -623, -624, -631, -632, -633, -634, -641, -642, -651, -652, -661, -662, -671,
57   -711, -712, -721, -722, -731, -732, -741, -742, -751, -752, -761, -762, -771,
58   -811, -812, -821, -822, -831, -832, -841, -842, -851, -852, -861, -862, -871,
59   -911, -921, -931, -941, -951, -961, -971 
60 };
61
62 //___________________________________________
63 AliMUONLocalTriggerBoard::AliMUONLocalTriggerBoard()
64     : AliMUONTriggerBoard(),
65       fMpLocalBoard(0x0),
66       fStripX11(0),
67       fStripY11(15),
68       fDev(0),
69       fTrigY(1),
70       fOutput(0),
71       fLUT(0x0),
72       fCoinc44(0)
73 {
74 /// default constructor
75 ///
76    
77    for (Int_t i=0; i<2; i++) 
78       for (Int_t j=0; j<4; j++) 
79       {
80          fXY[i][j] = fXYU[i][j] = fXYD[i][j] = 0;
81
82          fMask[i][j] = 0xFFFF;
83       }
84
85    for (Int_t i=0; i<5; i++) fMinDevStrip[i] = fMinDev[i] = fCoordY[i] = 0;
86
87    for (Int_t i=0; i<2; i++) fLutLpt[i] = fLutHpt[i] = 0;
88 }
89
90 //___________________________________________
91 AliMUONLocalTriggerBoard::AliMUONLocalTriggerBoard(AliMpLocalBoard* mpLocalBoard)
92     : AliMUONTriggerBoard(mpLocalBoard->GetName(), mpLocalBoard->GetSlot()),
93       fMpLocalBoard(mpLocalBoard),
94       fStripX11(0),
95       fStripY11(15),
96       fDev(0),
97       fTrigY(1),
98       fOutput(0),
99       fLUT(0x0),
100       fCoinc44(0)
101 {
102 /// Standard constructor
103 ///
104    
105    for (Int_t i=0; i<2; i++) 
106       for (Int_t j=0; j<4; j++) 
107       {
108          fXY[i][j] = fXYU[i][j] = fXYD[i][j] = 0;
109
110          fMask[i][j] = 0xFFFF;
111       }
112
113    for (Int_t i=0; i<5; i++) fMinDevStrip[i] = fMinDev[i] = fCoordY[i] = 0;
114
115    for (Int_t i=0; i<2; i++) fLutLpt[i] = fLutHpt[i] = 0;
116 }
117
118 //___________________________________________
119 AliMUONLocalTriggerBoard::AliMUONLocalTriggerBoard(const AliMUONLocalTriggerBoard& right) :
120   AliMUONTriggerBoard(right),
121   fMpLocalBoard(right.fMpLocalBoard),
122   fStripX11(right.fStripX11),
123   fStripY11(right.fStripY11),
124   fDev(right.fDev),
125   fTrigY(right.fTrigY),
126   fOutput(right.fOutput),
127   fLUT(right.fLUT),
128   fCoinc44(right.fCoinc44)
129 {
130   //
131   /// Copy constructor
132   //
133   for (Int_t i=0; i<2; i++) {
134     for (Int_t j=0; j<4; j++) {
135       fXY[i][j]  = right.fXY[i][j];
136       fXYU[i][j] = right.fXYU[i][j];
137       fXYD[i][j] = right.fXYD[i][j];
138
139       fMask[i][j] = right.fMask[i][j];
140     }
141   }
142
143   for (Int_t i=0; i<2; i++) {
144     fLutLpt[i] = right.fLutLpt[i];
145     fLutHpt[i] = right.fLutHpt[i];
146   }
147
148   for (Int_t i=0; i<5; i++) {
149     fMinDevStrip[i] = right.fMinDevStrip[i];
150     fMinDev[i] = right.fMinDev[i];
151     fCoordY[i] = right.fCoordY[i];
152   }
153 }
154
155 //___________________________________________
156 AliMUONLocalTriggerBoard& AliMUONLocalTriggerBoard::operator=(const AliMUONLocalTriggerBoard& right)
157 {
158 /// Assigment operator;
159 /// equal operator
160
161   if (this == &right)
162     return *this;
163
164   // base class assignement
165   AliMUONTriggerBoard::operator=(right);
166
167   fMpLocalBoard = right.fMpLocalBoard;
168   fStripX11 = right.fStripX11;
169   fStripY11 = right.fStripY11;
170   fDev      = right.fDev;
171   fTrigY    = right.fTrigY;
172   fOutput   = right.fOutput;
173   fLUT      = right.fLUT;
174   fCoinc44  = right.fCoinc44;
175
176   for (Int_t i=0; i<2; i++) {
177     for (Int_t j=0; j<4; j++) {
178       fXY[i][j]  = right.fXY[i][j];
179       fXYU[i][j] = right.fXYU[i][j];
180       fXYD[i][j] = right.fXYD[i][j];
181
182       fMask[i][j] = right.fMask[i][j];
183     }
184   }
185
186   for (Int_t i=0; i<2; i++) {
187     fLutLpt[i] = right.fLutLpt[i];
188     fLutHpt[i] = right.fLutHpt[i];
189   }
190
191   for (Int_t i=0; i<5; i++) {
192     fMinDevStrip[i] = right.fMinDevStrip[i];
193     fMinDev[i] = right.fMinDev[i];
194     fCoordY[i] = right.fCoordY[i];
195   }
196
197   return *this;  
198 }
199
200 //___________________________________________
201 AliMUONLocalTriggerBoard::~AliMUONLocalTriggerBoard()
202 {
203 /// Destructor
204 }
205
206
207 //___________________________________________
208 Int_t AliMUONLocalTriggerBoard::GetNumber() const 
209 {
210 /// return board number for notified boards
211
212     if (fMpLocalBoard->IsNotified())
213         return fMpLocalBoard->GetId();
214     else 
215         return 0;
216 }
217
218 //___________________________________________
219 void AliMUONLocalTriggerBoard::Reset()
220 {
221 /// reset board
222 ///
223    for (Int_t i=0; i<2; i++) 
224       for (Int_t j=0; j<4; j++) 
225          fXY[i][j] = fXYU[i][j] = fXYD[i][j] = 0;
226
227    ResetResponse();
228 }
229
230 //___________________________________________
231 void AliMUONLocalTriggerBoard::ResetResponse()
232 {
233 /// reset board response
234 //
235   fResponse = 0;
236
237   for (Int_t i=0; i<5; i++) fMinDevStrip[i] = fMinDev[i] = fCoordY[i] = 0;
238
239   fOutput = 0;
240    
241   fStripX11 = 0;
242   fStripY11 = 15;
243   fDev = 0;
244   fTrigY = 1;
245
246   for (Int_t i=0; i<2; i++) fLutLpt[i] = fLutHpt[i] = 0;
247 }
248
249
250 //___________________________________________
251 void AliMUONLocalTriggerBoard::Setbit(Int_t strip, Int_t cathode, Int_t chamber)
252 {
253 /// 0 .. LBS   :   N-1 .. MSB
254    TBits w, m;
255
256    UShort_t xy = fXY[cathode][chamber], mask = fMask[cathode][chamber];
257
258    w.Set(16,&xy);
259    m.Set(16,&mask);
260
261    Int_t s = strip - int(strip / 16) * 16;
262
263    w.SetBitNumber(s);
264    
265    w &= m;
266
267    UShort_t value;
268
269    w.Get(&value);
270
271    fXY[cathode][chamber] = value;
272 }
273
274 //___________________________________________
275 void AliMUONLocalTriggerBoard::SetbitM(Int_t strip, Int_t cathode, Int_t chamber)
276 {
277 /// 0 .. LBS   :   N-1 .. MSB
278    TBits w, m;
279
280    UShort_t xy = fXY[cathode][chamber], mask = fMask[cathode][chamber];
281
282    w.Set(16,&xy);
283    m.Set(16,&mask);
284
285    w.SetBitNumber(strip);
286    
287    w &= m;
288
289    UShort_t value;
290
291    w.Get(&value);
292
293    fXY[cathode][chamber] = value;
294 }
295
296
297 //___________________________________________
298 void AliMUONLocalTriggerBoard::Pattern(const Option_t *option) const
299 {
300 /// print bit pattern
301 ///
302    TString op = option;
303    
304    if (op.Contains("X")) BP("X");
305
306    if (op.Contains("Y")) BP("Y");
307 }
308
309
310 //___________________________________________
311 void AliMUONLocalTriggerBoard::BP(const Option_t *option) const
312 {
313 /// Respect the old printout format
314   
315   const Int_t kModuleId[126] = 
316   {11,12,13,14,15,16,17,         // right side of the chamber
317   21,22,23,24,25,26,27,
318   31,32,33,34,35,36,37,
319   41,42,43,44,45,46,47,
320   51,52,53,54,55,56,57,
321   61,62,63,64,65,66,67,
322   71,72,73,74,75,76,77,
323   81,82,83,84,85,86,87,
324   91,92,93,94,95,96,97,   
325   -11,-12,-13,-14,-15,-16,-17,  // right side of chamber
326   -21,-22,-23,-24,-25,-26,-27,
327   -31,-32,-33,-34,-35,-36,-37,
328   -41,-42,-43,-44,-45,-46,-47,
329   -51,-52,-53,-54,-55,-56,-57,
330   -61,-62,-63,-64,-65,-66,-67,
331   -71,-72,-73,-74,-75,-76,-77,
332   -81,-82,-83,-84,-85,-86,-87,
333   -91,-92,-93,-94,-95,-96,-97};
334
335   const Int_t kNstripY[126]=
336   { 8, 8, 8, 8, 8, 8,16,  // right side of the chamber
337   8, 8, 8, 8, 8, 8,16,
338   16,16,16,16,16, 8,16,
339   16,16,16,16,16, 8,16,
340   0, 8,16,16,16, 8,16,
341   16,16,16,16,16, 8,16,
342   16,16,16,16,16, 8,16,
343   8, 8, 8, 8, 8, 8,16,
344   8, 8, 8, 8, 8, 8,16,  
345   8, 8, 8, 8, 8, 8,16,  // left side of the chamber
346   8, 8, 8, 8, 8, 8,16,
347   16,16,16,16,16, 8,16,
348   16,16,16,16,16, 8,16,
349   0, 8,16,16,16, 8,16,
350   16,16,16,16,16, 8,16,
351   16,16,16,16,16, 8,16,
352   8, 8, 8, 8, 8, 8,16,
353   8, 8, 8, 8, 8, 8,16};
354
355    TString op = option;
356         
357    TString nn = GetName();
358
359    if (op.Contains("X"))
360    {
361       printf("-------- TRIGGER INPUT ---------\n");
362       printf("--- warning: switchs not activated at this level ---\n");
363       printf("===============================================================\n");
364       printf("                            5432109876543210");
365
366       const char *x[4] = {"XMC11","XMC12","XMC21","XMC22"};
367       const char *s[4] = {"                      ",
368                     "                      ",
369                     "              ",
370                     "              "};
371       
372       for (Int_t ch=0; ch<4; ch++)
373       { 
374          printf("\n %s%s", x[ch], s[ch]);
375
376          UShort_t xy = fXY[0][ch];
377
378          TBits w(16); w.Set(16,&xy);
379
380          if (ch<2) cout << w;
381          else
382          {
383             UShort_t xyd = fXYD[0][ch], xyu = fXYU[0][ch];
384             TBits dw(16), uw(16); dw.Set(16,&xyd); uw.Set(16,&xyu); 
385
386             TBits ew(32);
387          
388             for (Int_t i=0;i<16;i++) ew[i+8] = w[i];
389
390             for (Int_t i=0;i<8;i++) 
391             {
392                ew[i]    = dw[i+8]; // 8 MSB
393                ew[i+24] = uw[i];   // 
394             }
395
396             cout << ew;
397          }
398       }
399    
400       printf("\n                    ");
401       printf("10987654321098765432109876543210\n");
402    }
403
404    if (op.Contains("Y"))
405    {
406       printf("---------------------------------------------------------------\n");
407       printf("                            ");
408
409 /*    OLD NUMBERING STYLE    */
410 /**/
411       Int_t idCircuit = 0, absidModule = 0;
412
413       if (!(nn.Contains("Int"))) 
414       { 
415         idCircuit   = fgkCircuitId[GetI()];
416         absidModule = TMath::Abs(Int_t(idCircuit/10));
417       }
418                 
419       Int_t iModule=0;
420
421       for (Int_t i=0; i<63; i++) 
422       {
423         if (kModuleId[i]==absidModule) 
424          { 
425             iModule=i;
426             break;
427          }
428       }
429
430       Int_t nStrip = kNstripY[iModule];
431       for (Int_t istrip=nStrip-1; istrip>=0; istrip--) {
432          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
433          if (istrip<10) printf("%i",istrip);
434       }
435 /**/
436 /*                           */
437
438       UShort_t xyval = 0;
439
440       if (GetSwitch(1))
441       {
442          xyval = fXY[1][0];
443          TBits v11(8); v11.Set(8,&xyval);
444          printf("\n YMC11                      ");
445          cout << v11;         
446
447          xyval = fXY[1][1];
448          TBits v12(8); v12.Set(8,&xyval);
449          printf("\n YMC12                      ");
450          cout << v12;
451
452          xyval = fXY[1][2];
453          TBits v21(8); v21.Set(8,&xyval);
454          printf("\n YMC21                      ");         
455          cout << v21;
456
457          xyval = fXY[1][3];
458          TBits v22(8); v22.Set(8,&xyval);
459          printf("\n YMC22                      ");
460          cout << v22 << endl;
461       }
462       else
463       {
464          xyval = fXY[1][0];
465          TBits v11(16); v11.Set(16,&xyval);
466          printf("\n YMC11                      ");
467          cout << v11;         
468
469          xyval = fXY[1][1];
470          TBits v12(16); v12.Set(16,&xyval);
471          printf("\n YMC12                      ");
472          cout << v12;
473
474          xyval = fXY[1][2];
475          TBits v21(16); v21.Set(16,&xyval);
476          printf("\n YMC21                      ");         
477          cout << v21;
478
479          xyval = fXY[1][3];
480          TBits v22(16); v22.Set(16,&xyval);
481          printf("\n YMC22                      ");
482          cout << v22 << endl;
483       }
484
485 //    tmp
486       printf("---------------------------------------------------------------");
487       printf("\n upper part of circuit %i",idCircuit);
488       printf("\n UMC21                      ");
489       xyval = fXYU[1][2];
490       TBits wu21(16); wu21.Set(16,&xyval);
491       cout << wu21;
492       printf("\n UMC22                      ");
493       xyval = fXYU[1][3];
494       TBits wu22(16); wu22.Set(16,&xyval);
495       cout << wu22;
496       printf("\n lower part of circuit %i",idCircuit);
497       printf("\n LMC21                      ");
498       xyval = fXYD[1][2];
499       TBits wl21(16); wl21.Set(16,&xyval);
500       cout << wl21;
501       printf("\n LMC22                      ");
502       xyval = fXYD[1][3];
503       TBits wl22(16); wl22.Set(16,&xyval);
504       cout << wl22;
505       printf("\n");
506       printf("===============================================================\n");
507    }
508 }
509
510 //___________________________________________
511 void AliMUONLocalTriggerBoard::Module(char *mod)
512 {
513 /// get module from name
514 ///
515    const Int_t kMaxfields = 2; char **fields = new char*[kMaxfields];
516
517    char s[100]; strcpy(s, GetName());
518
519    Int_t numlines = 0;
520
521    for (char *token = strtok(s, "B");
522         token != NULL;
523         token = strtok(NULL, " "))
524    {
525       fields[numlines] = new char[strlen(token)+1];
526       strcpy(fields[numlines++],token);
527    }
528  
529    strcpy(mod,fields[0]);
530 }
531
532 //___________________________________________
533 void AliMUONLocalTriggerBoard::TrigX(Int_t ch1q[16], Int_t ch2q[16], Int_t ch3q[32], Int_t ch4q[32])
534 {
535 /// note : coinc44 = flag 0 or 1 (0 coincidence -> 3/4, 1 coincidence -> 4/4) \n
536 ///---------------------------------------------------------                  \n
537 /// step # 1 : declustering, reduction DS, calculate sgle & dble              \n 
538 ///---------------------------------------------------------
539    Int_t ch1e[19], ch2e[20], ch3e[35], ch4e[36]; 
540    Int_t sgleHit1[31], sgleHit2[63];
541    Int_t dbleHit1[31], dbleHit2[63];
542
543    Int_t i;
544    Int_t j;
545    Int_t istrip;
546
547    for (i=0; i<31; i++) {
548       sgleHit1[i]=0;
549       dbleHit1[i]=0;
550    }
551    for (i=0; i<63; i++) {
552       sgleHit2[i]=0;
553       dbleHit2[i]=0;
554    }
555
556 //--- inititialize che using chq 
557 //--- switch zero_down, zero_middle & zero_up added 30/05/07
558 //--- fSwitch[7/8/9] = zero_down/zero_middle/zero_up
559    for (i=0; i<19; i++) {
560       if (i<1||i>16)  ch1e[i]=0; 
561       else            ch1e[i]=ch1q[i-1]; 
562    }
563    for (i=0; i<20; i++) {
564       if (i<2||i>17) ch2e[i]=0; 
565       else           ch2e[i]=ch2q[i-2]; 
566    }
567    for (i=0; i<35; i++) {
568       if (i<1||i>32) ch3e[i]=0; 
569       else if (i>=1 && i<=8)   ch3e[i]=ch3q[i-1]&!GetSwitch(7);
570       else if (i>=9 && i<=24)  ch3e[i]=ch3q[i-1]&!GetSwitch(8);
571       else if (i>=25 && i<=32) ch3e[i]=ch3q[i-1]&!GetSwitch(9);
572    }
573    for (i=0; i<36; i++) {
574       if (i<2||i>33) ch4e[i]=0; 
575       else if (i>=2 && i<=9)   ch4e[i]=ch4q[i-2]&!GetSwitch(7);
576       else if (i>=10 && i<=25) ch4e[i]=ch4q[i-2]&!GetSwitch(8);
577       else if (i>=26 && i<=33) ch4e[i]=ch4q[i-2]&!GetSwitch(9);
578    }
579
580 //--- calculate dble & sgle first station
581    for (i=0; i<=15; i++) {                   
582       sgleHit1[2*i] = (!ch1e[i+1]|(ch1e[i]^ch1e[i+2])) & 
583          (!ch2e[i+2] | (ch2e[i+1]^ch2e[i+3]));
584
585       dbleHit1[2*i] = ch1e[i+1]&!(ch1e[i+2]^ch1e[i]) & 
586          (ch2e[i+2] | (!ch2e[i]&ch2e[i+1]) | (ch2e[i+3]&!ch2e[i+4]));
587    }
588
589    for (i=0; i<=14; i++) {               
590       sgleHit1[2*i+1] = (!ch1e[i+1]|!ch1e[i+2]|(ch1e[i]^ch1e[i+3])) & 
591          (!ch2e[i+2] | !ch2e[i+3] | (ch2e[i+1]^ch2e[i+4]));
592       dbleHit1[2*i+1] = ch1e[i+1]&ch1e[i+2]&!(ch1e[i]^ch1e[i+3]) & 
593         ((ch2e[i+2]&(!ch2e[i+1]|!ch2e[i])) | 
594           (ch2e[i+3]&(ch2e[i+2]|!ch2e[i+4]|!ch2e[i+5])));
595    }
596
597 //--- calculate dble & sgle second station
598    for (i=0; i<=31; i++) {               
599       sgleHit2[2*i] = (!ch3e[i+1]|(ch3e[i]^ch3e[i+2])) & 
600          (!ch4e[i+2] | (ch4e[i+1]^ch4e[i+3]));
601       dbleHit2[2*i] = ch3e[i+1]&!(ch3e[i+2]^ch3e[i]) & 
602          (ch4e[i+2] | (!ch4e[i]&ch4e[i+1]) | (ch4e[i+3]&!ch4e[i+4]));
603    }
604   
605    for (i=0; i<=30; i++) {               
606       sgleHit2[2*i+1] = (!ch3e[i+1]|!ch3e[i+2]|(ch3e[i]^ch3e[i+3])) & 
607          (!ch4e[i+2] | !ch4e[i+3] | (ch4e[i+1]^ch4e[i+4]));
608       dbleHit2[2*i+1] = ch3e[i+1]&ch3e[i+2]&!(ch3e[i]^ch3e[i+3]) & 
609         ((ch4e[i+2]&(!ch4e[i+1]|!ch4e[i])) | 
610           (ch4e[i+3]&((ch4e[i+2]|!ch4e[i+4])|!ch4e[i+5])));
611    }
612
613 //--- 
614    if(AliDebugLevel()==3||AliDebugLevel()==5) {
615       printf("===============================================================\n");
616       printf(" X plane after sgle and dble \n");
617       printf("                       0987654321098765432109876543210");
618       printf("\n SGLE1                 ");
619       for (istrip=30; istrip>=0; istrip--) printf("%i",(!sgleHit1[istrip]));
620       printf("\n DBLE1                 ");
621       for (istrip=30; istrip>=0; istrip--) printf("%i",dbleHit1[istrip]);
622       printf("\n SGLE2 ");
623       for (istrip=62; istrip>=0; istrip--) printf("%i",(!sgleHit2[istrip]));
624       printf("\n DBLE2 ");
625       for (istrip=62; istrip>=0; istrip--) printf("%i",dbleHit2[istrip]);
626       printf("\n       210987654321098765432109876543210987654321098765432109876543210\n");
627    }
628   
629 //---------------------------------------------------------
630 // step # 2 : coincidence 3/4
631 //---------------------------------------------------------
632    Int_t rearImage[31][31];
633    for (i=0; i<31; i++) {
634       for (j=0; j<31; j++) {
635          rearImage[i][j]=0;
636       }
637    }
638
639    Int_t notOr1=!dbleHit1[30] & !dbleHit1[29] & !dbleHit1[28] & !dbleHit1[27] & 
640       !dbleHit1[26] & !dbleHit1[25] & !dbleHit1[24] & !dbleHit1[23] &
641       !dbleHit1[22] & !dbleHit1[21] & !dbleHit1[20] & !dbleHit1[19] & 
642       !dbleHit1[18] & !dbleHit1[17] & !dbleHit1[16] & !dbleHit1[15] & 
643       !dbleHit1[14] & !dbleHit1[13] & !dbleHit1[12] & !dbleHit1[11] & 
644       !dbleHit1[10] & !dbleHit1[9]  & !dbleHit1[8]  & !dbleHit1[7]  & 
645       !dbleHit1[6]  & !dbleHit1[5]  & !dbleHit1[4]  & !dbleHit1[3]  & 
646       !dbleHit1[2]  & !dbleHit1[1]  & !dbleHit1[0]  & !fCoinc44;
647
648    Int_t notOr2= !dbleHit2[62] & !dbleHit2[61] & !dbleHit2[60] & !dbleHit2[59] & 
649       !dbleHit2[58] & !dbleHit2[57] & !dbleHit2[56] & !dbleHit2[55] & 
650       !dbleHit2[54] & !dbleHit2[53] & !dbleHit2[52] & !dbleHit2[51] & 
651       !dbleHit2[50] & !dbleHit2[49] & !dbleHit2[48] & !dbleHit2[47] & 
652       !dbleHit2[46] & !dbleHit2[45] & !dbleHit2[44] & !dbleHit2[43] & 
653       !dbleHit2[42] & !dbleHit2[41] & !dbleHit2[40] & !dbleHit2[39] & 
654       !dbleHit2[38] & !dbleHit2[37] & !dbleHit2[36] & !dbleHit2[35] & 
655       !dbleHit2[34] & !dbleHit2[33] & !dbleHit2[32] & !dbleHit2[31] &
656       !dbleHit2[30] & !dbleHit2[29] & !dbleHit2[28] & !dbleHit2[27] & 
657       !dbleHit2[26] & !dbleHit2[25] & !dbleHit2[24] & !dbleHit2[23] & 
658       !dbleHit2[22] & !dbleHit2[21] & !dbleHit2[20] & !dbleHit2[19] & 
659       !dbleHit2[18] & !dbleHit2[17] & !dbleHit2[16] & !dbleHit2[15] & 
660       !dbleHit2[14] & !dbleHit2[13] & !dbleHit2[12] & !dbleHit2[11] & 
661       !dbleHit2[10] & !dbleHit2[9]  & !dbleHit2[8]  & !dbleHit2[7]  & 
662       !dbleHit2[6]  & !dbleHit2[5]  & !dbleHit2[4]  & !dbleHit2[3]  & 
663       !dbleHit2[2]  & !dbleHit2[1]  & !dbleHit2[0]  & !fCoinc44;        
664
665 // DS reduction
666    for (i=0; i<31; i++) {
667       sgleHit1[i] = !sgleHit1[i]&notOr1;
668    }
669    for (i=0; i<63; i++) {
670       sgleHit2[i] = !sgleHit2[i]&notOr2;
671    }
672
673 // extract rearImage
674    for (i=0; i<31; i++){
675       Int_t tmpSgleHit2[31];
676       Int_t tmpDbleHit2[31];
677       for (j=0; j<31; j++){
678          tmpSgleHit2[j] = sgleHit2[i+j+1];
679          tmpDbleHit2[j] = dbleHit2[i+j+1];
680       }
681
682       for (Int_t k=0; k<31; k++) {
683          rearImage[i][k]=(sgleHit1[i]&tmpDbleHit2[k])|
684             (dbleHit1[i]&(tmpSgleHit2[k]|tmpDbleHit2[k]));
685       }
686    }
687
688    //-----------
689    if(AliDebugLevel()==3||AliDebugLevel()==5) {
690       printf("===============================================================\n");
691       for (i=30; i>=0; i--) {
692          printf("%i \t",i);
693          for (istrip=31; istrip>=0; istrip--) printf("%i",rearImage[i][istrip]);
694          printf("\n");   
695       }
696    }
697
698 //---------------------------------------------------------
699 // step # 3 : calculate deviation
700 //--------------------------------------------------------- 
701    Int_t dev[31][6];
702    for (i=0; i<31; i++) {
703       for (j=0; j<6; j++) {
704          dev[i][j]=0;
705       }
706    }
707
708    for (i=0; i<31; i++){
709       Int_t leftDev[5], rightDev[5]; 
710       Int_t orL1, andL1, andL2, orR1, orR2, andR1, andR2, andR3;
711
712 // calculate Left deviation
713       orL1=rearImage[i][16]|rearImage[i][18]|rearImage[i][20]|rearImage[i][22];
714       andL1=!rearImage[i][17]&!rearImage[i][19]&!rearImage[i][21] & !orL1; 
715       andL2=!rearImage[i][23]&!rearImage[i][24]&!rearImage[i][25]&!rearImage[i][26];
716  
717       leftDev[0] = (rearImage[i][16]|!rearImage[i][17]) & 
718          (rearImage[i][16]|rearImage[i][18]|(!rearImage[i][19]&
719          (rearImage[i][20]|!rearImage[i][21]))) &
720          (orL1|(!rearImage[i][23]&(rearImage[i][24]|!rearImage[i][25]))) & 
721          (orL1|rearImage[i][24]|rearImage[i][26]|(!rearImage[i][27]&
722          (rearImage[i][28]|!rearImage[i][29])));
723                                 
724       leftDev[1] = !rearImage[i][16] & 
725          !(!rearImage[i][17]&!rearImage[i][18]&!rearImage[i][21]&!rearImage[i][22] & 
726          (!rearImage[i][25]&!rearImage[i][26]&(rearImage[i][27]|rearImage[i][28]))) &
727          (rearImage[i][17]|rearImage[i][18] | (!rearImage[i][19]&!rearImage[i][20])) &
728          (rearImage[i][17]|rearImage[i][18]|rearImage[i][21]|rearImage[i][22] | 
729          (!rearImage[i][23]&!rearImage[i][24]));
730                                 
731       leftDev[2] = (!rearImage[i][16]&!rearImage[i][17]&!rearImage[i][18]) & 
732          (rearImage[i][19]|rearImage[i][20]|rearImage[i][21]|rearImage[i][22] | andL2);
733                 
734       leftDev[3] = andL1;
735                 
736       leftDev[4] = 
737          !rearImage[i][27]&!rearImage[i][28]&!rearImage[i][29]&!rearImage[i][30] & 
738          andL1 & andL2;
739
740       // calculate Right deviation
741       orR1=rearImage[i][8]|rearImage[i][10]|rearImage[i][12]|rearImage[i][14];
742       orR2=rearImage[i][8]|rearImage[i][9]|rearImage[i][10]|rearImage[i][11];
743       andR1=!rearImage[i][12]&!rearImage[i][13]&!rearImage[i][14]&!rearImage[i][15];
744       andR2=
745          !rearImage[i][8]&!rearImage[i][9]&!rearImage[i][10]&!rearImage[i][11] & andR1;
746       andR3=!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][6]&!rearImage[i][7]; 
747                 
748       rightDev[0] = !rearImage[i][15]&(rearImage[i][14]|!rearImage[i][13]) & 
749           ((rearImage[i][12]|rearImage[i][14]|(!rearImage[i][11]&
750           (rearImage[i][10]|!rearImage[i][9]))) &
751           ((orR1|(!rearImage[i][7]&(rearImage[i][6]|!rearImage[i][5]))) & 
752            (orR1|rearImage[i][4]|rearImage[i][6]|(!rearImage[i][3]&(rearImage[i][2]|
753                                                                    !rearImage[i][1])))));
754                                 
755       rightDev[1] = !rearImage[i][15]&!rearImage[i][14] & 
756          !(!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][8]&!rearImage[i][9] &
757            (!rearImage[i][12]&!rearImage[i][13]&(rearImage[i][2]|rearImage[i][3]))) &
758          (rearImage[i][12]|rearImage[i][13] | (!rearImage[i][10]&!rearImage[i][11])) & 
759          (rearImage[i][8]|rearImage[i][9]|rearImage[i][12]|rearImage[i][13] | 
760           (!rearImage[i][6]&!rearImage[i][7]));
761                 
762       rightDev[2] = andR1 & (orR2 | andR3); 
763       rightDev[3] = andR2;              
764       rightDev[4] = 
765          !rearImage[i][0]&!rearImage[i][1]&!rearImage[i][2]&!rearImage[i][3] & 
766          andR2 & andR3 ;
767
768       // compare Left & Right deviations
769       Int_t tmpLeftDev=0, tmpRightDev=0;
770       for (j=0; j<5; j++){
771          tmpLeftDev  = tmpLeftDev + Int_t(leftDev[j]<<j); 
772          tmpRightDev = tmpRightDev + Int_t(rightDev[j]<<j); 
773       }
774
775       // assign mimimum deviation do dev[][]
776       if (tmpLeftDev < tmpRightDev ){
777          for (j=0; j<5; j++){ dev[i][j]=leftDev[j];}
778          dev[i][5]=1;
779       } else {
780          for (j=0; j<5; j++){ dev[i][j]=rightDev[j];}
781          dev[i][5]=0;
782       }
783    }
784   
785 //---
786    if(AliDebugLevel()==3||AliDebugLevel()==5) {
787       printf("===============================================================\n");
788       for (i=30; i>=0; i--) {
789          printf("%i \t",i);
790          for (istrip=5; istrip>=0; istrip--) printf("%i",dev[i][istrip]);
791          printf(" \n");
792       }
793    }
794
795 //---------------------------------------------------------
796 // step # 4 : sort deviation
797 //--------------------------------------------------------- 
798    Int_t bga1[16], bga2[8], bga3[4], bga4[2], bga5;
799    Int_t tmpbga1[16][6], tmpbga2[8][6], tmpbga3[4][6], tmpbga4[2][6], tmpbga5[6];
800    Int_t tmpMax[6]={1,1,1,1,1,0};
801
802    for (i=0; i<15; i++) {
803       Sort2x5(dev[2*i],dev[2*i+1],tmpbga1[i],bga1[i]);
804    }  
805    Sort2x5(dev[30],tmpMax,tmpbga1[15],bga1[15]);
806
807 //--    
808    if(AliDebugLevel()==3||AliDebugLevel()==5) {
809       printf("===============================================================\n");
810       printf(" sorting : 1st level \n");
811       for (i=15; i>=0; i--) {
812          printf("\t %i \t",bga1[i]);    
813          for (j=5; j>=0; j--) printf("%i",tmpbga1[i][j]); 
814          printf(" \n");
815       }
816    }
817
818    for (i=0; i<8; i++) {  
819       Sort2x5(tmpbga1[2*i],tmpbga1[2*i+1],tmpbga2[i],bga2[i]);
820    }
821
822 //--    
823    if(AliDebugLevel()==3||AliDebugLevel()==5) {
824       printf("===============================================================\n");
825       printf(" sorting : 2nd level \n");
826       for (i=7; i>=0; i--) {
827          printf("\t %i \t",bga2[i]);    
828          for (j=5; j>=0; j--) printf("%i",tmpbga1[i][j]);       
829          printf(" \n");
830       }
831    }
832   
833    for (i=0; i<4; i++) {  
834       Sort2x5(tmpbga2[2*i],tmpbga2[2*i+1],tmpbga3[i],bga3[i]);
835    }
836
837 //--    
838    if(AliDebugLevel()==3||AliDebugLevel()==5) {
839       printf("===============================================================\n");
840       printf(" sorting : 3rd level \n");
841       for (i=3; i>=0; i--) {
842          printf("\t %i \t",bga3[i]);    
843          for (j=5; j>=0; j--) printf("%i",tmpbga3[i][j]); 
844          printf(" \n");
845       }
846    }
847
848    for (i=0; i<2; i++) {  
849       Sort2x5(tmpbga3[2*i],tmpbga3[2*i+1],tmpbga4[i],bga4[i]);
850    }
851
852 //--    
853    if(AliDebugLevel()==3||AliDebugLevel()==5) {
854       printf("===============================================================\n");
855       printf(" sorting : 4th level \n");
856       for (i=1; i>=0; i--) {
857          printf("\t %i \t",bga4[i]);    
858          for (j=5; j>=0; j--) printf("%i",tmpbga4[i][j]);
859          printf(" \n");
860       }
861    }
862   
863    Sort2x5(tmpbga4[0],tmpbga4[1],tmpbga5,bga5);
864
865    // coding from 6 to 5 bits 
866    fMinDev[4] = tmpbga5[5] | tmpbga5[4];
867    for (i=0; i<4; i++) { 
868       fMinDev[i]=tmpbga5[i] & !tmpbga5[4];
869    }
870
871    // find address of strip with minimum deviation 
872    fMinDevStrip[4]=bga5;
873    if (bga5<=1) fMinDevStrip[3]=bga4[bga5];
874
875    Int_t tmpAd=fMinDevStrip[3]+fMinDevStrip[4]*2;
876    if (tmpAd<=3) fMinDevStrip[2]=bga3[tmpAd];
877
878    tmpAd=fMinDevStrip[2]+fMinDevStrip[3]*2+fMinDevStrip[4]*4;
879    if (tmpAd<=7) fMinDevStrip[1]=bga2[tmpAd];
880
881    tmpAd=fMinDevStrip[1]+fMinDevStrip[2]*2+fMinDevStrip[3]*4+fMinDevStrip[4]*8;
882    if (tmpAd<=15) fMinDevStrip[0]=bga1[tmpAd];
883
884    if(AliDebugLevel()==3||AliDebugLevel()==5) {
885       printf("===============================================================\n");
886       printf("minDevStrip = ");
887       for  (i=4; i>=0; i--) printf("%i",fMinDevStrip[i]);
888       printf(" minDev = ");
889       for  (i=4; i>=0; i--) printf("%i",fMinDev[i]); 
890       printf(" \n");
891       printf("===============================================================\n");
892    }
893
894 }
895
896 //___________________________________________
897 void AliMUONLocalTriggerBoard::Sort2x5(Int_t dev1[6], Int_t dev2[6],
898                                        Int_t minDev[6], Int_t &dev1GTdev2)
899
900 /// returns minimun between dev1 and dev2
901    Int_t tmpDev1=0, tmpDev2=0;
902
903    for (Int_t j=0; j<5; j++)
904    {
905       tmpDev1 += Int_t(dev1[j]<<j); 
906       tmpDev2 += Int_t(dev2[j]<<j); 
907    }
908
909    if (tmpDev1<=tmpDev2)
910    {
911       for (Int_t j=0; j<=5; j++) minDev[j]=dev1[j];
912       dev1GTdev2=0;
913    } 
914    else 
915    {
916       for (Int_t j=0; j<=5; j++) minDev[j]=dev2[j];
917       dev1GTdev2=1;   
918    }
919 }
920
921 //___________________________________________
922 void AliMUONLocalTriggerBoard::TrigY(Int_t y1[16], Int_t y2[16], Int_t y3[16], Int_t y4[16],
923                                      Int_t y3u[16], Int_t y3d[16], Int_t y4u[16], Int_t y4d[16])
924 {
925 /// note : resMid = 1 -> cancel                             \n
926 ///---------------------------------------------------------\n
927 /// step # 1 : prehandling Y                                \n
928 ///--------------------------------------------------------- 
929    Int_t i;
930    Int_t istrip;
931
932    for (i=0; i<16; i++)
933    {
934      y3[i]=y3[i]&!GetSwitch(8);
935      y4[i]=y4[i]&!GetSwitch(8);
936    }
937
938 // 10/29/04 fZeroAllYLSB added
939 //    for (i=0; i<8; i++)
940 //    {
941 //       y1[i] = y1[i]&!fSwitch[6];     
942 //       y2[i] = y2[i]&!fSwitch[6];      
943 //       y3[i] = y3[i]&!fSwitch[6];      
944 //       y4[i] = y4[i]&!fSwitch[6];
945 //    }
946
947    Int_t ch1[16], ch2[16], ch3[16], ch4[16];
948
949    Int_t tmpy3to16[16], tmpy4to16[16];
950    Int_t tmpy3uto16[16], tmpy3dto16[16], tmpy4uto16[16], tmpy4dto16[16];
951    for (i=0; i<8; i++){
952       ch1[2*i]   = (y1[i]&GetSwitch(1)) | (y1[2*i]&!GetSwitch(1));              
953       ch1[2*i+1] = (y1[i]&GetSwitch(1)) | (y1[2*i+1]&!GetSwitch(1));
954
955       ch2[2*i]   = (y2[i]&GetSwitch(1)) | (y2[2*i]&!GetSwitch(1));              
956       ch2[2*i+1] = (y2[i]&GetSwitch(1)) | (y2[2*i+1]&!GetSwitch(1));
957
958       tmpy3to16[2*i  ] = (y3[i]&GetSwitch(1)) | (y3[2*i  ]&!GetSwitch(1));              
959       tmpy3to16[2*i+1] = (y3[i]&GetSwitch(1)) | (y3[2*i+1]&!GetSwitch(1));
960
961       tmpy4to16[2*i  ] = (y4[i]&GetSwitch(1)) | (y4[2*i  ]&!GetSwitch(1));
962       tmpy4to16[2*i+1] = (y4[i]&GetSwitch(1)) | (y4[2*i+1]&!GetSwitch(1));
963
964       tmpy3uto16[2*i  ] = (y3u[i]&GetSwitch(2)) | (y3u[2*i  ]&!GetSwitch(2)); 
965       tmpy3uto16[2*i+1] = (y3u[i]&GetSwitch(2)) | (y3u[2*i+1]&!GetSwitch(2));
966
967       tmpy4uto16[2*i  ] = (y4u[i]&GetSwitch(2)) | (y4u[2*i  ]&!GetSwitch(2)); 
968       tmpy4uto16[2*i+1] = (y4u[i]&GetSwitch(2)) | (y4u[2*i+1]&!GetSwitch(2));
969
970       tmpy3dto16[2*i  ] = (y3d[i]&GetSwitch(0)) | (y3d[2*i  ]&!GetSwitch(0)); 
971       tmpy3dto16[2*i+1] = (y3d[i]&GetSwitch(0)) | (y3d[2*i+1]&!GetSwitch(0));
972     
973       tmpy4dto16[2*i  ] = (y4d[i]&GetSwitch(0)) | (y4d[2*i  ]&!GetSwitch(0)); 
974       tmpy4dto16[2*i+1] = (y4d[i]&GetSwitch(0)) | (y4d[2*i+1]&!GetSwitch(0));
975    }
976   
977    if (GetSwitch(3)==0&&GetSwitch(4)==0){
978       for (i=0; i<16; i++){
979          ch3[i] = tmpy3to16[i];
980          ch4[i] = tmpy4to16[i];
981       }
982    }
983    if (GetSwitch(3)==0&&GetSwitch(4)==1){
984       for (i=0; i<16; i++){
985          ch3[i] = tmpy3dto16[i]|tmpy3to16[i];
986          ch4[i] = tmpy4dto16[i]|tmpy4to16[i];
987       }
988    }
989    if (GetSwitch(3)==1&&GetSwitch(4)==0){
990       for (i=0; i<16; i++){
991          ch3[i] = tmpy3uto16[i]|tmpy3to16[i];
992          ch4[i] = tmpy4uto16[i]|tmpy4to16[i];
993       }
994    }
995    if (GetSwitch(3)==1&&GetSwitch(4)==1){
996       for (i=0; i<16; i++){
997          ch3[i] = tmpy3dto16[i]|tmpy3to16[i]|tmpy3uto16[i];
998          ch4[i] = tmpy4dto16[i]|tmpy4to16[i]|tmpy4uto16[i];
999       }
1000    }
1001
1002 // debug
1003    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1004       printf("===============================================================\n");  
1005       printf(" Y plane after PreHandling x2m x2u x2d orMud %i %i %i %i %i \n",
1006              GetSwitch(1),GetSwitch(2), GetSwitch(0),GetSwitch(3),GetSwitch(4));
1007       printf("                            ");
1008       for (istrip=15; istrip>=0; istrip--) {
1009          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1010          if (istrip<10) printf("%i",istrip);
1011       }  
1012       printf("\n YMC11                      ");
1013       for (istrip=15; istrip>=0; istrip--) printf("%i",ch1[istrip]); 
1014       printf("\n YMC12                      ");
1015       for (istrip=15; istrip>=0; istrip--) printf("%i",ch2[istrip]); 
1016       printf("\n YMC21                      ");
1017       for (istrip=15; istrip>=0; istrip--) printf("%i",ch3[istrip]); 
1018       printf("\n YMC22                      ");
1019       for (istrip=15; istrip>=0; istrip--) printf("%i",ch4[istrip]); 
1020       printf(" \n"); 
1021    }
1022 //debug
1023   
1024 //---------------------------------------------------------
1025 // step # 2 : calculate sgle and dble, apply DS reduction
1026 //--------------------------------------------------------- 
1027    Int_t sgle1[16], dble1[16];
1028    Int_t sgle2[16], dble2[16];
1029
1030    // Calculate simple and double hits
1031    for (i=0; i<16; i++) {
1032       dble1[i] = ch1[i] & ch2[i];
1033       dble2[i] = ch3[i] & ch4[i];
1034     
1035       sgle1[i] = (ch1[i]|ch2[i]);
1036       sgle2[i] = (ch3[i]|ch4[i]);
1037    }
1038
1039    //debug
1040    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1041       printf("===============================================================\n");
1042       printf(" Y plane after sgle dble \n"); 
1043       printf("                            ");
1044       for (istrip=15; istrip>=0; istrip--) {
1045          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1046          if (istrip<10) printf("%i",istrip);
1047       }  
1048       printf("\n SGLE1                      ");
1049       for (istrip=15; istrip>=0; istrip--) printf("%i",sgle1[istrip]); 
1050       printf("\n DBLE1                      ");
1051       for (istrip=15; istrip>=0; istrip--) printf("%i",dble1[istrip]); 
1052       printf("\n SGLE2                      ");
1053       for (istrip=15; istrip>=0; istrip--) printf("%i",sgle2[istrip]); 
1054       printf("\n DBLE2                      ");
1055       for (istrip=15; istrip>=0; istrip--) printf("%i",dble2[istrip]); 
1056       printf(" \n"); 
1057    }
1058    //debug
1059
1060    // DS Reduction 
1061    Int_t notOr1, notOr2;
1062
1063    notOr1=!dble1[15] & !dble1[14] & !dble1[13] & !dble1[12] & 
1064       !dble1[11] & !dble1[10] & !dble1[9]  & !dble1[8]  & 
1065       !dble1[7]  & !dble1[6]  & !dble1[5]  & !dble1[4]  & 
1066       !dble1[3]  & !dble1[2]  & !dble1[1]  & !dble1[0];
1067
1068    notOr2=!dble2[15] & !dble2[14] & !dble2[13] & !dble2[12] & 
1069       !dble2[11] & !dble2[10] & !dble2[9]  & !dble2[8]  & 
1070       !dble2[7]  & !dble2[6]  & !dble2[5]  & !dble2[4]  & 
1071       !dble2[3]  & !dble2[2]  & !dble2[1]  & !dble2[0];
1072
1073    for (i=0; i<16; i++) {
1074       sgle1[i] = sgle1[i] & notOr1 & !fCoinc44;
1075       sgle2[i] = sgle2[i] & notOr2 & !fCoinc44;
1076    }
1077
1078 //---------------------------------------------------------
1079 // step # 3 : 3/4 coincidence 
1080 //--------------------------------------------------------- 
1081    Int_t frontImage[16];
1082
1083    for (i=1; i<15; i++) {
1084      frontImage[i] = ((dble1[i] | sgle1[i]) & 
1085                       (dble2[i+1] | dble2[i] | dble2[i-1])) |
1086         (dble1[i] & (sgle2[i+1] | sgle2[i] | sgle2[i-1]));
1087    }
1088    frontImage[0] = ((dble1[0] | sgle1[0]) & 
1089                     (dble2[1] | dble2[0])) | (dble1[0] & (sgle2[1] | sgle2[0]));
1090
1091    frontImage[15] = ((dble1[15] | sgle1[15]) & 
1092                      (dble2[15] | dble2[14])) | (dble1[15] & (sgle2[15] | sgle2[14]));
1093
1094
1095 //debug
1096    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1097       printf("===============================================================\n");
1098       printf(" Y plane frontImage\n");
1099       printf("                            ");
1100       for (istrip=15; istrip>=0; istrip--) {
1101          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1102          if (istrip<10) printf("%i",istrip);
1103       }
1104       printf("\n                            ");
1105       for (istrip=15; istrip>=0; istrip--) printf("%i",frontImage[istrip]); 
1106       printf("\n");
1107    }
1108 //debug
1109
1110 //---------------------------------------------------------
1111 // step # 4 : Y position 
1112 //--------------------------------------------------------- 
1113    Int_t or1, or2, and1, and2, and3;
1114
1115    or1  = frontImage[7]|frontImage[5]|frontImage[3]|frontImage[1];
1116    or2  = frontImage[7]|frontImage[6]|frontImage[5]|frontImage[4];
1117    and1 = !frontImage[3]&!frontImage[2]&!frontImage[1]&!frontImage[0];
1118    and2 = !frontImage[7]&!frontImage[6]&!frontImage[5]&!frontImage[4] & and1;
1119    and3 = !frontImage[11]&!frontImage[10]&!frontImage[9]&!frontImage[8]; 
1120  
1121    fCoordY[0] = !frontImage[0]&(frontImage[1]|!frontImage[2]) & 
1122      (frontImage[3]|frontImage[1]|(!frontImage[4]&(frontImage[5]|!frontImage[6]))) &
1123      (or1|(!frontImage[8]&(frontImage[9]|!frontImage[10]))) & 
1124      (or1|frontImage[11]|frontImage[9]|(!frontImage[12]&(frontImage[13]|!frontImage[14])));
1125  
1126    fCoordY[1] = !frontImage[0]&!frontImage[1] & 
1127       !(!frontImage[11]&!frontImage[10]&!frontImage[7]&!frontImage[6] & 
1128         !frontImage[3]&!frontImage[2]&(frontImage[13]|frontImage[12])) &
1129      (frontImage[3]|frontImage[2] | (!frontImage[5]&!frontImage[4])) & 
1130       (frontImage[7]|frontImage[6]|frontImage[3]|frontImage[2] | 
1131        (!frontImage[9]&!frontImage[8]));
1132                 
1133    fCoordY[2] = and1 & (or2 | and3);
1134                 
1135    fCoordY[3] = and2;
1136                 
1137    fCoordY[4] = !frontImage[15]&!frontImage[14]&!frontImage[13]&!frontImage[12] &
1138       and2 & and3 ;
1139 }
1140
1141 //___________________________________________
1142 void AliMUONLocalTriggerBoard::LocalTrigger()
1143 {
1144 /// L0 trigger after LUT
1145 ///
1146     Int_t deviation=0;
1147     Int_t iStripY=0;
1148     Int_t iStripX=0;
1149     Bool_t xOutput = IsTrigX();
1150     Bool_t yOutput = IsTrigY();
1151
1152    if (xOutput) {
1153       for (Int_t i=0; i<5; i++) iStripX += static_cast<int>( fMinDevStrip[i] << i );
1154       for (Int_t i=0; i<4; i++) deviation += static_cast<int>( fMinDev[i] << i );
1155       fDev      = deviation;
1156       fStripX11 = iStripX;
1157    }
1158    if (yOutput) {
1159      for (Int_t i=0; i<4; i++) iStripY   += static_cast<int>( fCoordY[i] << i );
1160       fStripY11 = iStripY;
1161       fTrigY    = fCoordY[4];
1162    }
1163   
1164 //   cout << " Local Trigger " << " " << fNumber << " " << 
1165 //       xOutput << " " << yOutput << " " << fDev << " " << fStripX11 << " " <<
1166 //       fTrigY << " " << fStripY11 << "\n";
1167
1168    if (xOutput && yOutput){ // trigger in X and Y
1169        fOutput =1;
1170
1171        Int_t sign = 0;
1172        if ( !fMinDev[4] &&  deviation ) sign=-1;
1173        if ( !fMinDev[4] && !deviation ) sign= 0;
1174        if (  fMinDev[4] == 1 )          sign=+1;    
1175        
1176        deviation *= sign; 
1177        
1178 //    calculate deviation in [0;+30]
1179        deviation += 15;
1180        
1181 //    GET LUT OUTPUT FOR icirc/istripX1/deviation/istripY
1182        fLUT->GetLutOutput(GetNumber(), fStripX11, deviation, fStripY11, fLutLpt, fLutHpt);
1183    }
1184
1185    fResponse = fLutLpt[0]              + 
1186        static_cast<int>(fLutLpt[1]<<1) + 
1187        static_cast<int>(fLutHpt[0]<<2) + 
1188        static_cast<int>(fLutHpt[1]<<3);  
1189
1190 }
1191
1192 //___________________________________________
1193 Int_t AliMUONLocalTriggerBoard::GetI() const
1194 {
1195 /// old numbering
1196 ///
1197    const Int_t kMaxfields = 2; char **fields = new char*[kMaxfields];
1198
1199    char s[100]; strcpy(s, GetName());
1200
1201    Int_t numlines = 0;
1202
1203    for (char *token = strtok(s, "B");
1204         token != NULL;
1205         token = strtok(NULL, " "))
1206    {
1207       fields[numlines] = new char[strlen(token)+1];
1208       strcpy(fields[numlines++], token);
1209    }
1210
1211    TString l(fields[0]);
1212
1213    char copy = l[0];
1214
1215    Int_t lL = atoi(&l[4]), cC = atoi(&l[2]), sS = (copy=='R') ? +1 : -1;
1216
1217    const char *b[4] = {"12", "34", "56", "78"};
1218
1219    Int_t ib = 0;
1220
1221    for (Int_t i=0; i<4; i++) if (!strcmp(fields[1],b[i])) {ib = i; break;} ib++;
1222
1223 // lL=1 ON TOP
1224    lL -= 9; lL = abs(lL); lL++;
1225
1226    Int_t code = 100 * lL + 10 * cC + ib;
1227
1228    code *= sS;
1229
1230    Int_t ic = 0;
1231
1232    for (Int_t i=0; i<234; i++) if (fgkCircuitId[i] == code) {ic = i; break;}
1233
1234    return ic;
1235 }
1236
1237 //___________________________________________
1238 void AliMUONLocalTriggerBoard::Mask(Int_t index, UShort_t mask)
1239 {
1240 /// set mask
1241 ///
1242   if ( index >= 0 && index < 2*4 )
1243   {
1244     Int_t i = index/4;
1245     Int_t j = index - i*4;
1246     fMask[i][j]=mask;
1247   }
1248   else
1249   {
1250     AliError(Form("Index %d out of bounds (max %d)",index,8));
1251   }
1252 }
1253
1254 //___________________________________________
1255 void AliMUONLocalTriggerBoard::Scan(Option_t *option) const
1256 {
1257 /// full dump
1258 ///
1259     TString op = option;
1260
1261    if (op.Contains("CONF")) Conf();
1262
1263    if (op.Contains("BITP")) Pattern();
1264
1265    if (op.Contains("RESPI")) Resp("I");
1266
1267    if (op.Contains("RESPF")) Resp("F"); 
1268
1269    if (op.Contains("RESPO")) Resp("O");
1270
1271    if (op.Contains("ALL"))
1272    {
1273       Conf();
1274       Pattern();
1275       Resp("I");
1276       Resp("F");
1277    }
1278 }
1279
1280 //___________________________________________
1281 void AliMUONLocalTriggerBoard::Conf() const
1282 {
1283 /// board switches
1284 ///
1285    cout << "Switch(" << GetName() << ")" 
1286         << " x2d = "           << GetSwitch(0) 
1287         << " x2m = "           << GetSwitch(1) 
1288         << " x2u = "           << GetSwitch(2) 
1289         << " OR[0] = "         << GetSwitch(3) 
1290         << " OR[1] = "         << GetSwitch(4) 
1291         << " EN-Y = "          << GetSwitch(5) 
1292         << " ZERO-ALLY-LSB = " << GetSwitch(6) 
1293         << " ZERO-down = "     << GetSwitch(7) 
1294         << " ZERO-middle = "   << GetSwitch(8) 
1295         << " ZERO-up = "       << GetSwitch(9) 
1296         << " trans. conn. "    << GetTC() 
1297         << " Slot = "          << fSlot 
1298         << endl;
1299 }
1300
1301 //___________________________________________
1302 void AliMUONLocalTriggerBoard::Resp(Option_t *option) const
1303 {
1304 /// board I/O
1305 ///
1306    TString op = option;
1307
1308    if (op.Contains("I"))
1309    {
1310 //    print Local trigger output before the LuT step
1311       printf("===============================================================\n");
1312       printf("-------- TRIGGER OUTPUT --------\n");
1313       printf("minDevStrip = ");
1314       for  (Int_t i=4; i>=0; i--) printf("%i",fMinDevStrip[i]);
1315       printf(" minDev = ");
1316       for  (Int_t i=4; i>=0; i--) printf("%i",fMinDev[i]);
1317       printf(" coordY = ");
1318       for  (Int_t i=4; i>=0; i--) printf("%i",fCoordY[i]); 
1319       printf(" \n");
1320    }
1321    if (op.Contains("O")){
1322      printf("-- Output --\n");
1323      printf("Coinc44 %i\n", fCoinc44);
1324      printf("StripX11 %i  StripY11 %i  Dev %i  TrigY %i\n", fStripX11, fStripY11, fDev, fTrigY);
1325      printf("LutLpt %i %i  LutHpt %i %i\n", fLutLpt[0], fLutLpt[1], fLutHpt[0], fLutHpt[1]);
1326      printf("Response %i\n", fOutput);
1327    }
1328
1329 }
1330
1331 //___________________________________________
1332 void AliMUONLocalTriggerBoard::Response()
1333 {
1334 /// algo
1335 ///
1336   if ( IsNull() ) {
1337     fMinDev[4] = 1;
1338     for  (Int_t i=4; i>=0; i--) fCoordY[i] = 1;
1339     return; // Do nothing if strip pattern is null
1340   }
1341
1342    Int_t xX1[16], xX2[16], xXX3[32], xXX4[32];
1343
1344    TBits x1(16), x2(16), x3(16), x4(16);
1345
1346    UShort_t xyv = 0;
1347
1348    xyv = fXY[0][0]; x1.Set(16,&xyv);
1349    xyv = fXY[0][1]; x2.Set(16,&xyv);
1350    xyv = fXY[0][2]; x3.Set(16,&xyv);
1351    xyv = fXY[0][3]; x4.Set(16,&xyv);
1352
1353    TBits x3u(16), x4u(16), x3d(16), x4d(16);
1354
1355    xyv = fXYU[0][2]; x3u.Set(16,&xyv);
1356    xyv = fXYU[0][3]; x4u.Set(16,&xyv);
1357
1358    xyv = fXYD[0][2]; x3d.Set(16,&xyv);
1359    xyv = fXYD[0][3]; x4d.Set(16,&xyv);
1360
1361    for (Int_t i=0;i<16;i++)
1362    {
1363       xX1[i] = x1[i];
1364       xX2[i] = x2[i];
1365       
1366       xXX3[i+8] = x3[i];
1367       xXX4[i+8] = x4[i];  
1368    }
1369
1370    for (Int_t i=0;i<8;i++)
1371    {
1372       xXX3[i] = x3d[i+8];
1373       xXX4[i] = x4d[i+8];
1374
1375       xXX3[i+24] = x3u[i];
1376       xXX4[i+24] = x4u[i];
1377    }
1378    
1379 //   Int_t coinc44 = 0;
1380    
1381    TrigX(xX1, xX2, xXX3, xXX4);   
1382
1383    Int_t yY1[16], yY2[16], yY3[16], yY4[16];
1384    
1385    Int_t yY3U[16], yY3D[16], yY4U[16], yY4D[16];
1386
1387    TBits y1(16), y2(16), y3(16), y4(16);
1388
1389    TBits y3u(16), y3d(16), y4u(16), y4d(16);
1390
1391    xyv = fXY[1][0]; y1.Set(16,&xyv);
1392    xyv = fXY[1][1]; y2.Set(16,&xyv);
1393    xyv = fXY[1][2]; y3.Set(16,&xyv);
1394    xyv = fXY[1][3]; y4.Set(16,&xyv);
1395
1396    xyv = fXYU[1][2]; y3u.Set(16,&xyv);
1397    xyv = fXYD[1][2]; y3d.Set(16,&xyv);
1398    xyv = fXYU[1][3]; y4u.Set(16,&xyv);
1399    xyv = fXYD[1][3]; y4d.Set(16,&xyv);
1400
1401    for (Int_t i=0;i<16;i++)
1402    {
1403       yY1[i] = y1[i];
1404       yY2[i] = y2[i];
1405       yY3[i] = y3[i];
1406       yY4[i] = y4[i];
1407       
1408       yY3U[i] = y3u[i];
1409       yY3D[i] = y3d[i];
1410       
1411       yY4U[i] = y4u[i];
1412       yY4D[i] = y4d[i];
1413    }
1414
1415    TrigY(yY1, yY2, yY3, yY4, yY3U, yY3D, yY4U, yY4D);
1416    
1417 // ASIGN fLutLpt, fLutHpt
1418    LocalTrigger();
1419 }
1420
1421 //___________________________________________
1422 Bool_t AliMUONLocalTriggerBoard::IsTrigY() const
1423 {
1424   /// Return the response of non-bending plane
1425   Int_t iStripY = 0;
1426   Bool_t output = kFALSE;
1427
1428   for (Int_t i=0; i<4; i++) iStripY   += static_cast<int>( fCoordY[i] << i );
1429
1430   if (fCoordY[4]==1 && iStripY==15) output=kFALSE; // no trigger in Y
1431   else output=kTRUE;                               // trigger in Y
1432    
1433   return output;
1434 }
1435
1436 //___________________________________________
1437 Bool_t AliMUONLocalTriggerBoard::IsTrigX() const
1438 {
1439   /// Return the response of bending plane
1440
1441   Int_t deviation = 0;
1442   Bool_t output = kFALSE;
1443
1444   for (Int_t i=0; i<4; i++) deviation += static_cast<int>( fMinDev[i] << i );
1445
1446   if (fMinDev[4]==1 && !deviation) output=kFALSE;  // no trigger in X
1447   else output=kTRUE;                               // trigger in X
1448
1449   return output;
1450 }
1451
1452 //___________________________________________
1453 Bool_t AliMUONLocalTriggerBoard::IsNull() const
1454 {
1455   /// Check if board has fired strips in the first station
1456   for (Int_t icath=0; icath<2; icath++){
1457     for(Int_t ich=0; ich<2; ich++){
1458       if ( fXY[icath][ich] ) return kFALSE;
1459     }
1460   }
1461   return kTRUE;
1462 }