]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONLocalTriggerBoard.cxx
Fixing RESOURCE_LEAK defect reported by Coverity
[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]; strncpy(s, GetName(), 100);
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    delete [] fields;
532 }
533
534 //___________________________________________
535 void AliMUONLocalTriggerBoard::TrigX(Int_t ch1q[16], Int_t ch2q[16], Int_t ch3q[32], Int_t ch4q[32])
536 {
537 /// note : coinc44 = flag 0 or 1 (0 coincidence -> 3/4, 1 coincidence -> 4/4) \n
538 ///---------------------------------------------------------                  \n
539 /// step # 1 : declustering, reduction DS, calculate sgle & dble              \n 
540 ///---------------------------------------------------------
541    Int_t ch1e[19], ch2e[20], ch3e[35], ch4e[36]; 
542    Int_t sgleHit1[31], sgleHit2[63];
543    Int_t dbleHit1[31], dbleHit2[63];
544
545    Int_t i;
546    Int_t j;
547    Int_t istrip;
548
549    for (i=0; i<31; i++) {
550       sgleHit1[i]=0;
551       dbleHit1[i]=0;
552    }
553    for (i=0; i<63; i++) {
554       sgleHit2[i]=0;
555       dbleHit2[i]=0;
556    }
557
558 //--- inititialize che using chq 
559 //--- switch zero_down, zero_middle & zero_up added 30/05/07
560 //--- fSwitch[7/8/9] = zero_down/zero_middle/zero_up
561    for (i=0; i<19; i++) {
562       if (i<1||i>16)  ch1e[i]=0; 
563       else            ch1e[i]=ch1q[i-1]; 
564    }
565    for (i=0; i<20; i++) {
566       if (i<2||i>17) ch2e[i]=0; 
567       else           ch2e[i]=ch2q[i-2]; 
568    }
569    for (i=0; i<35; i++) {
570       if (i<1||i>32) ch3e[i]=0; 
571       else if (i>=1 && i<=8)   ch3e[i]=ch3q[i-1]&!GetSwitch(7);
572       else if (i>=9 && i<=24)  ch3e[i]=ch3q[i-1]&!GetSwitch(8);
573       else if (i>=25 && i<=32) ch3e[i]=ch3q[i-1]&!GetSwitch(9);
574    }
575    for (i=0; i<36; i++) {
576       if (i<2||i>33) ch4e[i]=0; 
577       else if (i>=2 && i<=9)   ch4e[i]=ch4q[i-2]&!GetSwitch(7);
578       else if (i>=10 && i<=25) ch4e[i]=ch4q[i-2]&!GetSwitch(8);
579       else if (i>=26 && i<=33) ch4e[i]=ch4q[i-2]&!GetSwitch(9);
580    }
581
582 //--- calculate dble & sgle first station
583    for (i=0; i<=15; i++) {                   
584       sgleHit1[2*i] = (!ch1e[i+1]|(ch1e[i]^ch1e[i+2])) & 
585          (!ch2e[i+2] | (ch2e[i+1]^ch2e[i+3]));
586
587       dbleHit1[2*i] = ch1e[i+1]&!(ch1e[i+2]^ch1e[i]) & 
588          (ch2e[i+2] | (!ch2e[i]&ch2e[i+1]) | (ch2e[i+3]&!ch2e[i+4]));
589    }
590
591    for (i=0; i<=14; i++) {               
592       sgleHit1[2*i+1] = (!ch1e[i+1]|!ch1e[i+2]|(ch1e[i]^ch1e[i+3])) & 
593          (!ch2e[i+2] | !ch2e[i+3] | (ch2e[i+1]^ch2e[i+4]));
594       dbleHit1[2*i+1] = ch1e[i+1]&ch1e[i+2]&!(ch1e[i]^ch1e[i+3]) & 
595         ((ch2e[i+2]&(!ch2e[i+1]|!ch2e[i])) | 
596           (ch2e[i+3]&(ch2e[i+2]|!ch2e[i+4]|!ch2e[i+5])));
597    }
598
599 //--- calculate dble & sgle second station
600    for (i=0; i<=31; i++) {               
601       sgleHit2[2*i] = (!ch3e[i+1]|(ch3e[i]^ch3e[i+2])) & 
602          (!ch4e[i+2] | (ch4e[i+1]^ch4e[i+3]));
603       dbleHit2[2*i] = ch3e[i+1]&!(ch3e[i+2]^ch3e[i]) & 
604          (ch4e[i+2] | (!ch4e[i]&ch4e[i+1]) | (ch4e[i+3]&!ch4e[i+4]));
605    }
606   
607    for (i=0; i<=30; i++) {               
608       sgleHit2[2*i+1] = (!ch3e[i+1]|!ch3e[i+2]|(ch3e[i]^ch3e[i+3])) & 
609          (!ch4e[i+2] | !ch4e[i+3] | (ch4e[i+1]^ch4e[i+4]));
610       dbleHit2[2*i+1] = ch3e[i+1]&ch3e[i+2]&!(ch3e[i]^ch3e[i+3]) & 
611         ((ch4e[i+2]&(!ch4e[i+1]|!ch4e[i])) | 
612           (ch4e[i+3]&((ch4e[i+2]|!ch4e[i+4])|!ch4e[i+5])));
613    }
614
615 //--- 
616    if(AliDebugLevel()==3||AliDebugLevel()==5) {
617       printf("===============================================================\n");
618       printf(" X plane after sgle and dble \n");
619       printf("                       0987654321098765432109876543210");
620       printf("\n SGLE1                 ");
621       for (istrip=30; istrip>=0; istrip--) printf("%i",(!sgleHit1[istrip]));
622       printf("\n DBLE1                 ");
623       for (istrip=30; istrip>=0; istrip--) printf("%i",dbleHit1[istrip]);
624       printf("\n SGLE2 ");
625       for (istrip=62; istrip>=0; istrip--) printf("%i",(!sgleHit2[istrip]));
626       printf("\n DBLE2 ");
627       for (istrip=62; istrip>=0; istrip--) printf("%i",dbleHit2[istrip]);
628       printf("\n       210987654321098765432109876543210987654321098765432109876543210\n");
629    }
630   
631 //---------------------------------------------------------
632 // step # 2 : coincidence 3/4
633 //---------------------------------------------------------
634    Int_t rearImage[31][31];
635    for (i=0; i<31; i++) {
636       for (j=0; j<31; j++) {
637          rearImage[i][j]=0;
638       }
639    }
640
641    Int_t notOr1=!dbleHit1[30] & !dbleHit1[29] & !dbleHit1[28] & !dbleHit1[27] & 
642       !dbleHit1[26] & !dbleHit1[25] & !dbleHit1[24] & !dbleHit1[23] &
643       !dbleHit1[22] & !dbleHit1[21] & !dbleHit1[20] & !dbleHit1[19] & 
644       !dbleHit1[18] & !dbleHit1[17] & !dbleHit1[16] & !dbleHit1[15] & 
645       !dbleHit1[14] & !dbleHit1[13] & !dbleHit1[12] & !dbleHit1[11] & 
646       !dbleHit1[10] & !dbleHit1[9]  & !dbleHit1[8]  & !dbleHit1[7]  & 
647       !dbleHit1[6]  & !dbleHit1[5]  & !dbleHit1[4]  & !dbleHit1[3]  & 
648       !dbleHit1[2]  & !dbleHit1[1]  & !dbleHit1[0]  & !fCoinc44;
649
650    Int_t notOr2= !dbleHit2[62] & !dbleHit2[61] & !dbleHit2[60] & !dbleHit2[59] & 
651       !dbleHit2[58] & !dbleHit2[57] & !dbleHit2[56] & !dbleHit2[55] & 
652       !dbleHit2[54] & !dbleHit2[53] & !dbleHit2[52] & !dbleHit2[51] & 
653       !dbleHit2[50] & !dbleHit2[49] & !dbleHit2[48] & !dbleHit2[47] & 
654       !dbleHit2[46] & !dbleHit2[45] & !dbleHit2[44] & !dbleHit2[43] & 
655       !dbleHit2[42] & !dbleHit2[41] & !dbleHit2[40] & !dbleHit2[39] & 
656       !dbleHit2[38] & !dbleHit2[37] & !dbleHit2[36] & !dbleHit2[35] & 
657       !dbleHit2[34] & !dbleHit2[33] & !dbleHit2[32] & !dbleHit2[31] &
658       !dbleHit2[30] & !dbleHit2[29] & !dbleHit2[28] & !dbleHit2[27] & 
659       !dbleHit2[26] & !dbleHit2[25] & !dbleHit2[24] & !dbleHit2[23] & 
660       !dbleHit2[22] & !dbleHit2[21] & !dbleHit2[20] & !dbleHit2[19] & 
661       !dbleHit2[18] & !dbleHit2[17] & !dbleHit2[16] & !dbleHit2[15] & 
662       !dbleHit2[14] & !dbleHit2[13] & !dbleHit2[12] & !dbleHit2[11] & 
663       !dbleHit2[10] & !dbleHit2[9]  & !dbleHit2[8]  & !dbleHit2[7]  & 
664       !dbleHit2[6]  & !dbleHit2[5]  & !dbleHit2[4]  & !dbleHit2[3]  & 
665       !dbleHit2[2]  & !dbleHit2[1]  & !dbleHit2[0]  & !fCoinc44;        
666
667 // DS reduction
668    for (i=0; i<31; i++) {
669       sgleHit1[i] = !sgleHit1[i]&notOr1;
670    }
671    for (i=0; i<63; i++) {
672       sgleHit2[i] = !sgleHit2[i]&notOr2;
673    }
674
675 // extract rearImage
676    for (i=0; i<31; i++){
677       Int_t tmpSgleHit2[31];
678       Int_t tmpDbleHit2[31];
679       for (j=0; j<31; j++){
680          tmpSgleHit2[j] = sgleHit2[i+j+1];
681          tmpDbleHit2[j] = dbleHit2[i+j+1];
682       }
683
684       for (Int_t k=0; k<31; k++) {
685          rearImage[i][k]=(sgleHit1[i]&tmpDbleHit2[k])|
686             (dbleHit1[i]&(tmpSgleHit2[k]|tmpDbleHit2[k]));
687       }
688    }
689
690    //-----------
691    if(AliDebugLevel()==3||AliDebugLevel()==5) {
692       printf("===============================================================\n");
693       for (i=30; i>=0; i--) {
694          printf("%i \t",i);
695          for (istrip=31; istrip>=0; istrip--) printf("%i",rearImage[i][istrip]);
696          printf("\n");   
697       }
698    }
699
700 //---------------------------------------------------------
701 // step # 3 : calculate deviation
702 //--------------------------------------------------------- 
703    Int_t dev[31][6];
704    for (i=0; i<31; i++) {
705       for (j=0; j<6; j++) {
706          dev[i][j]=0;
707       }
708    }
709
710    for (i=0; i<31; i++){
711       Int_t leftDev[5], rightDev[5]; 
712       Int_t orL1, andL1, andL2, orR1, orR2, andR1, andR2, andR3;
713
714 // calculate Left deviation
715       orL1=rearImage[i][16]|rearImage[i][18]|rearImage[i][20]|rearImage[i][22];
716       andL1=!rearImage[i][17]&!rearImage[i][19]&!rearImage[i][21] & !orL1; 
717       andL2=!rearImage[i][23]&!rearImage[i][24]&!rearImage[i][25]&!rearImage[i][26];
718  
719       leftDev[0] = (rearImage[i][16]|!rearImage[i][17]) & 
720          (rearImage[i][16]|rearImage[i][18]|(!rearImage[i][19]&
721          (rearImage[i][20]|!rearImage[i][21]))) &
722          (orL1|(!rearImage[i][23]&(rearImage[i][24]|!rearImage[i][25]))) & 
723          (orL1|rearImage[i][24]|rearImage[i][26]|(!rearImage[i][27]&
724          (rearImage[i][28]|!rearImage[i][29])));
725                                 
726       leftDev[1] = !rearImage[i][16] & 
727          !(!rearImage[i][17]&!rearImage[i][18]&!rearImage[i][21]&!rearImage[i][22] & 
728          (!rearImage[i][25]&!rearImage[i][26]&(rearImage[i][27]|rearImage[i][28]))) &
729          (rearImage[i][17]|rearImage[i][18] | (!rearImage[i][19]&!rearImage[i][20])) &
730          (rearImage[i][17]|rearImage[i][18]|rearImage[i][21]|rearImage[i][22] | 
731          (!rearImage[i][23]&!rearImage[i][24]));
732                                 
733       leftDev[2] = (!rearImage[i][16]&!rearImage[i][17]&!rearImage[i][18]) & 
734          (rearImage[i][19]|rearImage[i][20]|rearImage[i][21]|rearImage[i][22] | andL2);
735                 
736       leftDev[3] = andL1;
737                 
738       leftDev[4] = 
739          !rearImage[i][27]&!rearImage[i][28]&!rearImage[i][29]&!rearImage[i][30] & 
740          andL1 & andL2;
741
742       // calculate Right deviation
743       orR1=rearImage[i][8]|rearImage[i][10]|rearImage[i][12]|rearImage[i][14];
744       orR2=rearImage[i][8]|rearImage[i][9]|rearImage[i][10]|rearImage[i][11];
745       andR1=!rearImage[i][12]&!rearImage[i][13]&!rearImage[i][14]&!rearImage[i][15];
746       andR2=
747          !rearImage[i][8]&!rearImage[i][9]&!rearImage[i][10]&!rearImage[i][11] & andR1;
748       andR3=!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][6]&!rearImage[i][7]; 
749                 
750       rightDev[0] = !rearImage[i][15]&(rearImage[i][14]|!rearImage[i][13]) & 
751           ((rearImage[i][12]|rearImage[i][14]|(!rearImage[i][11]&
752           (rearImage[i][10]|!rearImage[i][9]))) &
753           ((orR1|(!rearImage[i][7]&(rearImage[i][6]|!rearImage[i][5]))) & 
754            (orR1|rearImage[i][4]|rearImage[i][6]|(!rearImage[i][3]&(rearImage[i][2]|
755                                                                    !rearImage[i][1])))));
756                                 
757       rightDev[1] = !rearImage[i][15]&!rearImage[i][14] & 
758          !(!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][8]&!rearImage[i][9] &
759            (!rearImage[i][12]&!rearImage[i][13]&(rearImage[i][2]|rearImage[i][3]))) &
760          (rearImage[i][12]|rearImage[i][13] | (!rearImage[i][10]&!rearImage[i][11])) & 
761          (rearImage[i][8]|rearImage[i][9]|rearImage[i][12]|rearImage[i][13] | 
762           (!rearImage[i][6]&!rearImage[i][7]));
763                 
764       rightDev[2] = andR1 & (orR2 | andR3); 
765       rightDev[3] = andR2;              
766       rightDev[4] = 
767          !rearImage[i][0]&!rearImage[i][1]&!rearImage[i][2]&!rearImage[i][3] & 
768          andR2 & andR3 ;
769
770       // compare Left & Right deviations
771       Int_t tmpLeftDev=0, tmpRightDev=0;
772       for (j=0; j<5; j++){
773          tmpLeftDev  = tmpLeftDev + Int_t(leftDev[j]<<j); 
774          tmpRightDev = tmpRightDev + Int_t(rightDev[j]<<j); 
775       }
776
777       // assign mimimum deviation do dev[][]
778       if (tmpLeftDev < tmpRightDev ){
779          for (j=0; j<5; j++){ dev[i][j]=leftDev[j];}
780          dev[i][5]=1;
781       } else {
782          for (j=0; j<5; j++){ dev[i][j]=rightDev[j];}
783          dev[i][5]=0;
784       }
785    }
786   
787 //---
788    if(AliDebugLevel()==3||AliDebugLevel()==5) {
789       printf("===============================================================\n");
790       for (i=30; i>=0; i--) {
791          printf("%i \t",i);
792          for (istrip=5; istrip>=0; istrip--) printf("%i",dev[i][istrip]);
793          printf(" \n");
794       }
795    }
796
797 //---------------------------------------------------------
798 // step # 4 : sort deviation
799 //--------------------------------------------------------- 
800    Int_t bga1[16], bga2[8], bga3[4], bga4[2], bga5;
801    Int_t tmpbga1[16][6], tmpbga2[8][6], tmpbga3[4][6], tmpbga4[2][6], tmpbga5[6];
802    Int_t tmpMax[6]={1,1,1,1,1,0};
803
804    for (i=0; i<15; i++) {
805       Sort2x5(dev[2*i],dev[2*i+1],tmpbga1[i],bga1[i]);
806    }  
807    Sort2x5(dev[30],tmpMax,tmpbga1[15],bga1[15]);
808
809 //--    
810    if(AliDebugLevel()==3||AliDebugLevel()==5) {
811       printf("===============================================================\n");
812       printf(" sorting : 1st level \n");
813       for (i=15; i>=0; i--) {
814          printf("\t %i \t",bga1[i]);    
815          for (j=5; j>=0; j--) printf("%i",tmpbga1[i][j]); 
816          printf(" \n");
817       }
818    }
819
820    for (i=0; i<8; i++) {  
821       Sort2x5(tmpbga1[2*i],tmpbga1[2*i+1],tmpbga2[i],bga2[i]);
822    }
823
824 //--    
825    if(AliDebugLevel()==3||AliDebugLevel()==5) {
826       printf("===============================================================\n");
827       printf(" sorting : 2nd level \n");
828       for (i=7; i>=0; i--) {
829          printf("\t %i \t",bga2[i]);    
830          for (j=5; j>=0; j--) printf("%i",tmpbga1[i][j]);       
831          printf(" \n");
832       }
833    }
834   
835    for (i=0; i<4; i++) {  
836       Sort2x5(tmpbga2[2*i],tmpbga2[2*i+1],tmpbga3[i],bga3[i]);
837    }
838
839 //--    
840    if(AliDebugLevel()==3||AliDebugLevel()==5) {
841       printf("===============================================================\n");
842       printf(" sorting : 3rd level \n");
843       for (i=3; i>=0; i--) {
844          printf("\t %i \t",bga3[i]);    
845          for (j=5; j>=0; j--) printf("%i",tmpbga3[i][j]); 
846          printf(" \n");
847       }
848    }
849
850    for (i=0; i<2; i++) {  
851       Sort2x5(tmpbga3[2*i],tmpbga3[2*i+1],tmpbga4[i],bga4[i]);
852    }
853
854 //--    
855    if(AliDebugLevel()==3||AliDebugLevel()==5) {
856       printf("===============================================================\n");
857       printf(" sorting : 4th level \n");
858       for (i=1; i>=0; i--) {
859          printf("\t %i \t",bga4[i]);    
860          for (j=5; j>=0; j--) printf("%i",tmpbga4[i][j]);
861          printf(" \n");
862       }
863    }
864   
865    Sort2x5(tmpbga4[0],tmpbga4[1],tmpbga5,bga5);
866
867    // coding from 6 to 5 bits 
868    fMinDev[4] = tmpbga5[5] | tmpbga5[4];
869    for (i=0; i<4; i++) { 
870       fMinDev[i]=tmpbga5[i] & !tmpbga5[4];
871    }
872
873    // find address of strip with minimum deviation 
874    fMinDevStrip[4]=bga5;
875    if (bga5<=1) fMinDevStrip[3]=bga4[bga5];
876
877    Int_t tmpAd=fMinDevStrip[3]+fMinDevStrip[4]*2;
878    if (tmpAd<=3) fMinDevStrip[2]=bga3[tmpAd];
879
880    tmpAd=fMinDevStrip[2]+fMinDevStrip[3]*2+fMinDevStrip[4]*4;
881    if (tmpAd<=7) fMinDevStrip[1]=bga2[tmpAd];
882
883    tmpAd=fMinDevStrip[1]+fMinDevStrip[2]*2+fMinDevStrip[3]*4+fMinDevStrip[4]*8;
884    if (tmpAd<=15) fMinDevStrip[0]=bga1[tmpAd];
885
886    if(AliDebugLevel()==3||AliDebugLevel()==5) {
887       printf("===============================================================\n");
888       printf("minDevStrip = ");
889       for  (i=4; i>=0; i--) printf("%i",fMinDevStrip[i]);
890       printf(" minDev = ");
891       for  (i=4; i>=0; i--) printf("%i",fMinDev[i]); 
892       printf(" \n");
893       printf("===============================================================\n");
894    }
895
896 }
897
898 //___________________________________________
899 void AliMUONLocalTriggerBoard::Sort2x5(Int_t dev1[6], Int_t dev2[6],
900                                        Int_t minDev[6], Int_t &dev1GTdev2)
901
902 /// returns minimun between dev1 and dev2
903    Int_t tmpDev1=0, tmpDev2=0;
904
905    for (Int_t j=0; j<5; j++)
906    {
907       tmpDev1 += Int_t(dev1[j]<<j); 
908       tmpDev2 += Int_t(dev2[j]<<j); 
909    }
910
911    if (tmpDev1<=tmpDev2)
912    {
913       for (Int_t j=0; j<=5; j++) minDev[j]=dev1[j];
914       dev1GTdev2=0;
915    } 
916    else 
917    {
918       for (Int_t j=0; j<=5; j++) minDev[j]=dev2[j];
919       dev1GTdev2=1;   
920    }
921 }
922
923 //___________________________________________
924 void AliMUONLocalTriggerBoard::TrigY(Int_t y1[16], Int_t y2[16], Int_t y3[16], Int_t y4[16],
925                                      Int_t y3u[16], Int_t y3d[16], Int_t y4u[16], Int_t y4d[16])
926 {
927 /// note : resMid = 1 -> cancel                             \n
928 ///---------------------------------------------------------\n
929 /// step # 1 : prehandling Y                                \n
930 ///--------------------------------------------------------- 
931    Int_t i;
932    Int_t istrip;
933
934    for (i=0; i<16; i++)
935    {
936      y3[i]=y3[i]&!GetSwitch(8);
937      y4[i]=y4[i]&!GetSwitch(8);
938    }
939
940 // 10/29/04 fZeroAllYLSB added
941 //    for (i=0; i<8; i++)
942 //    {
943 //       y1[i] = y1[i]&!fSwitch[6];     
944 //       y2[i] = y2[i]&!fSwitch[6];      
945 //       y3[i] = y3[i]&!fSwitch[6];      
946 //       y4[i] = y4[i]&!fSwitch[6];
947 //    }
948
949    Int_t ch1[16], ch2[16], ch3[16], ch4[16];
950
951    Int_t tmpy3to16[16], tmpy4to16[16];
952    Int_t tmpy3uto16[16], tmpy3dto16[16], tmpy4uto16[16], tmpy4dto16[16];
953    for (i=0; i<8; i++){
954       ch1[2*i]   = (y1[i]&GetSwitch(1)) | (y1[2*i]&!GetSwitch(1));              
955       ch1[2*i+1] = (y1[i]&GetSwitch(1)) | (y1[2*i+1]&!GetSwitch(1));
956
957       ch2[2*i]   = (y2[i]&GetSwitch(1)) | (y2[2*i]&!GetSwitch(1));              
958       ch2[2*i+1] = (y2[i]&GetSwitch(1)) | (y2[2*i+1]&!GetSwitch(1));
959
960       tmpy3to16[2*i  ] = (y3[i]&GetSwitch(1)) | (y3[2*i  ]&!GetSwitch(1));              
961       tmpy3to16[2*i+1] = (y3[i]&GetSwitch(1)) | (y3[2*i+1]&!GetSwitch(1));
962
963       tmpy4to16[2*i  ] = (y4[i]&GetSwitch(1)) | (y4[2*i  ]&!GetSwitch(1));
964       tmpy4to16[2*i+1] = (y4[i]&GetSwitch(1)) | (y4[2*i+1]&!GetSwitch(1));
965
966       tmpy3uto16[2*i  ] = (y3u[i]&GetSwitch(2)) | (y3u[2*i  ]&!GetSwitch(2)); 
967       tmpy3uto16[2*i+1] = (y3u[i]&GetSwitch(2)) | (y3u[2*i+1]&!GetSwitch(2));
968
969       tmpy4uto16[2*i  ] = (y4u[i]&GetSwitch(2)) | (y4u[2*i  ]&!GetSwitch(2)); 
970       tmpy4uto16[2*i+1] = (y4u[i]&GetSwitch(2)) | (y4u[2*i+1]&!GetSwitch(2));
971
972       tmpy3dto16[2*i  ] = (y3d[i]&GetSwitch(0)) | (y3d[2*i  ]&!GetSwitch(0)); 
973       tmpy3dto16[2*i+1] = (y3d[i]&GetSwitch(0)) | (y3d[2*i+1]&!GetSwitch(0));
974     
975       tmpy4dto16[2*i  ] = (y4d[i]&GetSwitch(0)) | (y4d[2*i  ]&!GetSwitch(0)); 
976       tmpy4dto16[2*i+1] = (y4d[i]&GetSwitch(0)) | (y4d[2*i+1]&!GetSwitch(0));
977    }
978   
979    for (i=0; i<16; i++) ch3[i] = ch4[i] = 0;
980
981    if (GetSwitch(3)==0&&GetSwitch(4)==0){
982       for (i=0; i<16; i++){
983          ch3[i] = tmpy3to16[i];
984          ch4[i] = tmpy4to16[i];
985       }
986    }
987    if (GetSwitch(3)==0&&GetSwitch(4)==1){
988       for (i=0; i<16; i++){
989          ch3[i] = tmpy3dto16[i]|tmpy3to16[i];
990          ch4[i] = tmpy4dto16[i]|tmpy4to16[i];
991       }
992    }
993    if (GetSwitch(3)==1&&GetSwitch(4)==0){
994       for (i=0; i<16; i++){
995          ch3[i] = tmpy3uto16[i]|tmpy3to16[i];
996          ch4[i] = tmpy4uto16[i]|tmpy4to16[i];
997       }
998    }
999    if (GetSwitch(3)==1&&GetSwitch(4)==1){
1000       for (i=0; i<16; i++){
1001          ch3[i] = tmpy3dto16[i]|tmpy3to16[i]|tmpy3uto16[i];
1002          ch4[i] = tmpy4dto16[i]|tmpy4to16[i]|tmpy4uto16[i];
1003       }
1004    }
1005
1006 // debug
1007    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1008       printf("===============================================================\n");  
1009       printf(" Y plane after PreHandling x2m x2u x2d orMud %i %i %i %i %i \n",
1010              GetSwitch(1),GetSwitch(2), GetSwitch(0),GetSwitch(3),GetSwitch(4));
1011       printf("                            ");
1012       for (istrip=15; istrip>=0; istrip--) {
1013          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1014          if (istrip<10) printf("%i",istrip);
1015       }  
1016       printf("\n YMC11                      ");
1017       for (istrip=15; istrip>=0; istrip--) printf("%i",ch1[istrip]); 
1018       printf("\n YMC12                      ");
1019       for (istrip=15; istrip>=0; istrip--) printf("%i",ch2[istrip]); 
1020       printf("\n YMC21                      ");
1021       for (istrip=15; istrip>=0; istrip--) printf("%i",ch3[istrip]); 
1022       printf("\n YMC22                      ");
1023       for (istrip=15; istrip>=0; istrip--) printf("%i",ch4[istrip]); 
1024       printf(" \n"); 
1025    }
1026 //debug
1027   
1028 //---------------------------------------------------------
1029 // step # 2 : calculate sgle and dble, apply DS reduction
1030 //--------------------------------------------------------- 
1031    Int_t sgle1[16], dble1[16];
1032    Int_t sgle2[16], dble2[16];
1033
1034    // Calculate simple and double hits
1035    for (i=0; i<16; i++) {
1036       dble1[i] = ch1[i] & ch2[i];
1037       dble2[i] = ch3[i] & ch4[i];
1038     
1039       sgle1[i] = (ch1[i]|ch2[i]);
1040       sgle2[i] = (ch3[i]|ch4[i]);
1041    }
1042
1043    //debug
1044    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1045       printf("===============================================================\n");
1046       printf(" Y plane after sgle dble \n"); 
1047       printf("                            ");
1048       for (istrip=15; istrip>=0; istrip--) {
1049          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1050          if (istrip<10) printf("%i",istrip);
1051       }  
1052       printf("\n SGLE1                      ");
1053       for (istrip=15; istrip>=0; istrip--) printf("%i",sgle1[istrip]); 
1054       printf("\n DBLE1                      ");
1055       for (istrip=15; istrip>=0; istrip--) printf("%i",dble1[istrip]); 
1056       printf("\n SGLE2                      ");
1057       for (istrip=15; istrip>=0; istrip--) printf("%i",sgle2[istrip]); 
1058       printf("\n DBLE2                      ");
1059       for (istrip=15; istrip>=0; istrip--) printf("%i",dble2[istrip]); 
1060       printf(" \n"); 
1061    }
1062    //debug
1063
1064    // DS Reduction 
1065    Int_t notOr1, notOr2;
1066
1067    notOr1=!dble1[15] & !dble1[14] & !dble1[13] & !dble1[12] & 
1068       !dble1[11] & !dble1[10] & !dble1[9]  & !dble1[8]  & 
1069       !dble1[7]  & !dble1[6]  & !dble1[5]  & !dble1[4]  & 
1070       !dble1[3]  & !dble1[2]  & !dble1[1]  & !dble1[0];
1071
1072    notOr2=!dble2[15] & !dble2[14] & !dble2[13] & !dble2[12] & 
1073       !dble2[11] & !dble2[10] & !dble2[9]  & !dble2[8]  & 
1074       !dble2[7]  & !dble2[6]  & !dble2[5]  & !dble2[4]  & 
1075       !dble2[3]  & !dble2[2]  & !dble2[1]  & !dble2[0];
1076
1077    for (i=0; i<16; i++) {
1078       sgle1[i] = sgle1[i] & notOr1 & !fCoinc44;
1079       sgle2[i] = sgle2[i] & notOr2 & !fCoinc44;
1080    }
1081
1082 //---------------------------------------------------------
1083 // step # 3 : 3/4 coincidence 
1084 //--------------------------------------------------------- 
1085    Int_t frontImage[16];
1086
1087    for (i=1; i<15; i++) {
1088      frontImage[i] = ((dble1[i] | sgle1[i]) & 
1089                       (dble2[i+1] | dble2[i] | dble2[i-1])) |
1090         (dble1[i] & (sgle2[i+1] | sgle2[i] | sgle2[i-1]));
1091    }
1092    frontImage[0] = ((dble1[0] | sgle1[0]) & 
1093                     (dble2[1] | dble2[0])) | (dble1[0] & (sgle2[1] | sgle2[0]));
1094
1095    frontImage[15] = ((dble1[15] | sgle1[15]) & 
1096                      (dble2[15] | dble2[14])) | (dble1[15] & (sgle2[15] | sgle2[14]));
1097
1098
1099 //debug
1100    if(AliDebugLevel()==4||AliDebugLevel()==5) {
1101       printf("===============================================================\n");
1102       printf(" Y plane frontImage\n");
1103       printf("                            ");
1104       for (istrip=15; istrip>=0; istrip--) {
1105          if (istrip>9)  printf("%i",istrip-10*Int_t(istrip/10));
1106          if (istrip<10) printf("%i",istrip);
1107       }
1108       printf("\n                            ");
1109       for (istrip=15; istrip>=0; istrip--) printf("%i",frontImage[istrip]); 
1110       printf("\n");
1111    }
1112 //debug
1113
1114 //---------------------------------------------------------
1115 // step # 4 : Y position 
1116 //--------------------------------------------------------- 
1117    Int_t or1, or2, and1, and2, and3;
1118
1119    or1  = frontImage[7]|frontImage[5]|frontImage[3]|frontImage[1];
1120    or2  = frontImage[7]|frontImage[6]|frontImage[5]|frontImage[4];
1121    and1 = !frontImage[3]&!frontImage[2]&!frontImage[1]&!frontImage[0];
1122    and2 = !frontImage[7]&!frontImage[6]&!frontImage[5]&!frontImage[4] & and1;
1123    and3 = !frontImage[11]&!frontImage[10]&!frontImage[9]&!frontImage[8]; 
1124  
1125    fCoordY[0] = !frontImage[0]&(frontImage[1]|!frontImage[2]) & 
1126      (frontImage[3]|frontImage[1]|(!frontImage[4]&(frontImage[5]|!frontImage[6]))) &
1127      (or1|(!frontImage[8]&(frontImage[9]|!frontImage[10]))) & 
1128      (or1|frontImage[11]|frontImage[9]|(!frontImage[12]&(frontImage[13]|!frontImage[14])));
1129  
1130    fCoordY[1] = !frontImage[0]&!frontImage[1] & 
1131       !(!frontImage[11]&!frontImage[10]&!frontImage[7]&!frontImage[6] & 
1132         !frontImage[3]&!frontImage[2]&(frontImage[13]|frontImage[12])) &
1133      (frontImage[3]|frontImage[2] | (!frontImage[5]&!frontImage[4])) & 
1134       (frontImage[7]|frontImage[6]|frontImage[3]|frontImage[2] | 
1135        (!frontImage[9]&!frontImage[8]));
1136                 
1137    fCoordY[2] = and1 & (or2 | and3);
1138                 
1139    fCoordY[3] = and2;
1140                 
1141    fCoordY[4] = !frontImage[15]&!frontImage[14]&!frontImage[13]&!frontImage[12] &
1142       and2 & and3 ;
1143 }
1144
1145 //___________________________________________
1146 void AliMUONLocalTriggerBoard::LocalTrigger()
1147 {
1148 /// L0 trigger after LUT
1149 ///
1150     Int_t deviation=0;
1151     Int_t iStripY=0;
1152     Int_t iStripX=0;
1153     Bool_t xOutput = IsTrigX();
1154     Bool_t yOutput = IsTrigY();
1155
1156    if (xOutput) {
1157       for (Int_t i=0; i<5; i++) iStripX += static_cast<int>( fMinDevStrip[i] << i );
1158       for (Int_t i=0; i<4; i++) deviation += static_cast<int>( fMinDev[i] << i );
1159       fDev      = deviation;
1160       fStripX11 = iStripX;
1161    }
1162    if (yOutput) {
1163      for (Int_t i=0; i<4; i++) iStripY   += static_cast<int>( fCoordY[i] << i );
1164       fStripY11 = iStripY;
1165       fTrigY    = fCoordY[4];
1166    }
1167   
1168 //   cout << " Local Trigger " << " " << fNumber << " " << 
1169 //       xOutput << " " << yOutput << " " << fDev << " " << fStripX11 << " " <<
1170 //       fTrigY << " " << fStripY11 << "\n";
1171
1172    if (xOutput && yOutput){ // trigger in X and Y
1173        fOutput =1;
1174
1175        Int_t sign = 0;
1176        if ( !fMinDev[4] &&  deviation ) sign=-1;
1177        if ( !fMinDev[4] && !deviation ) sign= 0;
1178        if (  fMinDev[4] == 1 )          sign=+1;    
1179        
1180        deviation *= sign; 
1181        
1182 //    calculate deviation in [0;+30]
1183        deviation += 15;
1184        
1185 //    GET LUT OUTPUT FOR icirc/istripX1/deviation/istripY
1186        fLUT->GetLutOutput(GetNumber(), fStripX11, deviation, fStripY11, fLutLpt, fLutHpt);
1187    }
1188
1189    fResponse = fLutLpt[0]              + 
1190        static_cast<int>(fLutLpt[1]<<1) + 
1191        static_cast<int>(fLutHpt[0]<<2) + 
1192        static_cast<int>(fLutHpt[1]<<3);  
1193
1194 }
1195
1196 //___________________________________________
1197 Int_t AliMUONLocalTriggerBoard::GetI() const
1198 {
1199 /// old numbering
1200 ///
1201
1202    const Int_t kMaxfields = 2; char **fields = new char*[kMaxfields];
1203
1204    char s[100]; strncpy(s, GetName(), 100);
1205
1206    Int_t numlines = 0;
1207
1208    for (char *token = strtok(s, "B");
1209         token != NULL;
1210         token = strtok(NULL, " "))
1211    {
1212       fields[numlines] = new char[strlen(token)+1];
1213       strcpy(fields[numlines++], token);
1214    }
1215
1216    TString l(fields[0]);
1217
1218    char copy = l[0];
1219
1220    Int_t lL = atoi(&l[4]), cC = atoi(&l[2]), sS = (copy=='R') ? +1 : -1;
1221
1222    const char *b[4] = {"12", "34", "56", "78"};
1223
1224    Int_t ib = 0;
1225
1226    for (Int_t i=0; i<4; i++) if (!strcmp(fields[1],b[i])) {ib = i; break;} ib++;
1227
1228 // lL=1 ON TOP
1229    lL -= 9; lL = abs(lL); lL++;
1230
1231    Int_t code = 100 * lL + 10 * cC + ib;
1232
1233    code *= sS;
1234
1235    Int_t ic = 0;
1236
1237    for (Int_t i=0; i<234; i++) if (fgkCircuitId[i] == code) {ic = i; break;}
1238    
1239    delete [] fields;
1240
1241    return ic;
1242 }
1243
1244 //___________________________________________
1245 void AliMUONLocalTriggerBoard::Mask(Int_t index, UShort_t mask)
1246 {
1247 /// set mask
1248 ///
1249   if ( index >= 0 && index < 2*4 )
1250   {
1251     Int_t i = index/4;
1252     Int_t j = index%4;
1253     fMask[i][j]=mask;
1254   }
1255   else
1256   {
1257     AliError(Form("Index %d out of bounds (max %d)",index,8));
1258   }
1259 }
1260
1261 //___________________________________________
1262 void AliMUONLocalTriggerBoard::Scan(Option_t *option) const
1263 {
1264 /// full dump
1265 ///
1266     TString op = option;
1267
1268    if (op.Contains("CONF")) Conf();
1269
1270    if (op.Contains("BITP")) Pattern();
1271
1272    if (op.Contains("RESPI")) Resp("I");
1273
1274    if (op.Contains("RESPF")) Resp("F"); 
1275
1276    if (op.Contains("RESPO")) Resp("O");
1277
1278    if (op.Contains("ALL"))
1279    {
1280       Conf();
1281       Pattern();
1282       Resp("I");
1283       Resp("F");
1284    }
1285 }
1286
1287 //___________________________________________
1288 void AliMUONLocalTriggerBoard::Conf() const
1289 {
1290 /// board switches
1291 ///
1292    cout << "Switch(" << GetName() << ")" 
1293         << " x2d = "           << GetSwitch(0) 
1294         << " x2m = "           << GetSwitch(1) 
1295         << " x2u = "           << GetSwitch(2) 
1296         << " OR[0] = "         << GetSwitch(3) 
1297         << " OR[1] = "         << GetSwitch(4) 
1298         << " EN-Y = "          << GetSwitch(5) 
1299         << " ZERO-ALLY-LSB = " << GetSwitch(6) 
1300         << " ZERO-down = "     << GetSwitch(7) 
1301         << " ZERO-middle = "   << GetSwitch(8) 
1302         << " ZERO-up = "       << GetSwitch(9) 
1303         << " trans. conn. "    << GetTC() 
1304         << " Slot = "          << fSlot 
1305         << endl;
1306 }
1307
1308 //___________________________________________
1309 void AliMUONLocalTriggerBoard::Resp(Option_t *option) const
1310 {
1311 /// board I/O
1312 ///
1313    TString op = option;
1314
1315    if (op.Contains("I"))
1316    {
1317 //    print Local trigger output before the LuT step
1318       printf("===============================================================\n");
1319       printf("-------- TRIGGER OUTPUT --------\n");
1320       printf("minDevStrip = ");
1321       for  (Int_t i=4; i>=0; i--) printf("%i",fMinDevStrip[i]);
1322       printf(" minDev = ");
1323       for  (Int_t i=4; i>=0; i--) printf("%i",fMinDev[i]);
1324       printf(" coordY = ");
1325       for  (Int_t i=4; i>=0; i--) printf("%i",fCoordY[i]); 
1326       printf(" \n");
1327    }
1328    if (op.Contains("O")){
1329      printf("-- Output --\n");
1330      printf("Coinc44 %i\n", fCoinc44);
1331      printf("StripX11 %i  StripY11 %i  Dev %i  TrigY %i\n", fStripX11, fStripY11, fDev, fTrigY);
1332      printf("LutLpt %i %i  LutHpt %i %i\n", fLutLpt[0], fLutLpt[1], fLutHpt[0], fLutHpt[1]);
1333      printf("Response %i\n", fOutput);
1334    }
1335
1336 }
1337
1338 //___________________________________________
1339 void AliMUONLocalTriggerBoard::Response()
1340 {
1341 /// algo
1342 ///
1343   if ( IsNull() ) {
1344     fMinDev[4] = 1;
1345     for  (Int_t i=4; i>=0; i--) fCoordY[i] = 1;
1346     return; // Do nothing if strip pattern is null
1347   }
1348
1349    Int_t xX1[16], xX2[16], xXX3[32], xXX4[32];
1350
1351    TBits x1(16), x2(16), x3(16), x4(16);
1352
1353    UShort_t xyv = 0;
1354
1355    xyv = fXY[0][0]; x1.Set(16,&xyv);
1356    xyv = fXY[0][1]; x2.Set(16,&xyv);
1357    xyv = fXY[0][2]; x3.Set(16,&xyv);
1358    xyv = fXY[0][3]; x4.Set(16,&xyv);
1359
1360    TBits x3u(16), x4u(16), x3d(16), x4d(16);
1361
1362    xyv = fXYU[0][2]; x3u.Set(16,&xyv);
1363    xyv = fXYU[0][3]; x4u.Set(16,&xyv);
1364
1365    xyv = fXYD[0][2]; x3d.Set(16,&xyv);
1366    xyv = fXYD[0][3]; x4d.Set(16,&xyv);
1367
1368    for (Int_t i=0;i<16;i++)
1369    {
1370       xX1[i] = x1[i];
1371       xX2[i] = x2[i];
1372       
1373       xXX3[i+8] = x3[i];
1374       xXX4[i+8] = x4[i];  
1375    }
1376
1377    for (Int_t i=0;i<8;i++)
1378    {
1379       xXX3[i] = x3d[i+8];
1380       xXX4[i] = x4d[i+8];
1381
1382       xXX3[i+24] = x3u[i];
1383       xXX4[i+24] = x4u[i];
1384    }
1385    
1386 //   Int_t coinc44 = 0;
1387    
1388    TrigX(xX1, xX2, xXX3, xXX4);   
1389
1390    Int_t yY1[16], yY2[16], yY3[16], yY4[16];
1391    
1392    Int_t yY3U[16], yY3D[16], yY4U[16], yY4D[16];
1393
1394    TBits y1(16), y2(16), y3(16), y4(16);
1395
1396    TBits y3u(16), y3d(16), y4u(16), y4d(16);
1397
1398    xyv = fXY[1][0]; y1.Set(16,&xyv);
1399    xyv = fXY[1][1]; y2.Set(16,&xyv);
1400    xyv = fXY[1][2]; y3.Set(16,&xyv);
1401    xyv = fXY[1][3]; y4.Set(16,&xyv);
1402
1403    xyv = fXYU[1][2]; y3u.Set(16,&xyv);
1404    xyv = fXYD[1][2]; y3d.Set(16,&xyv);
1405    xyv = fXYU[1][3]; y4u.Set(16,&xyv);
1406    xyv = fXYD[1][3]; y4d.Set(16,&xyv);
1407
1408    for (Int_t i=0;i<16;i++)
1409    {
1410       yY1[i] = y1[i];
1411       yY2[i] = y2[i];
1412       yY3[i] = y3[i];
1413       yY4[i] = y4[i];
1414       
1415       yY3U[i] = y3u[i];
1416       yY3D[i] = y3d[i];
1417       
1418       yY4U[i] = y4u[i];
1419       yY4D[i] = y4d[i];
1420    }
1421
1422    TrigY(yY1, yY2, yY3, yY4, yY3U, yY3D, yY4U, yY4D);
1423    
1424 // ASIGN fLutLpt, fLutHpt
1425    LocalTrigger();
1426 }
1427
1428 //___________________________________________
1429 Bool_t AliMUONLocalTriggerBoard::IsTrigY() const
1430 {
1431   /// Return the response of non-bending plane
1432   Int_t iStripY = 0;
1433   Bool_t output = kFALSE;
1434
1435   for (Int_t i=0; i<4; i++) iStripY   += static_cast<int>( fCoordY[i] << i );
1436
1437   if (fCoordY[4]==1 && iStripY==15) output=kFALSE; // no trigger in Y
1438   else output=kTRUE;                               // trigger in Y
1439    
1440   return output;
1441 }
1442
1443 //___________________________________________
1444 Bool_t AliMUONLocalTriggerBoard::IsTrigX() const
1445 {
1446   /// Return the response of bending plane
1447
1448   Int_t deviation = 0;
1449   Bool_t output = kFALSE;
1450
1451   for (Int_t i=0; i<4; i++) deviation += static_cast<int>( fMinDev[i] << i );
1452
1453   if (fMinDev[4]==1 && !deviation) output=kFALSE;  // no trigger in X
1454   else output=kTRUE;                               // trigger in X
1455
1456   return output;
1457 }
1458
1459 //___________________________________________
1460 Bool_t AliMUONLocalTriggerBoard::IsNull() const
1461 {
1462   /// Check if board has fired strips in the first station
1463   for (Int_t icath=0; icath<2; icath++){
1464     for(Int_t ich=0; ich<2; ich++){
1465       if ( fXY[icath][ich] ) return kFALSE;
1466     }
1467   }
1468   return kTRUE;
1469 }