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