correct access to digits in SetBit()
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerDecision.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 $Log$
17 Revision 1.8  2001/03/20 16:13:01  pcrochet
18 bug fixed in the rejection of soft background (thanks to FM)
19
20 Revision 1.7  2001/03/20 13:32:37  egangler
21 includes cleanup
22
23 Revision 1.6  2001/01/26 21:57:09  morsch
24 Use access functions to AliMUONDigit member data.
25
26 Revision 1.5  2000/10/02 16:58:29  egangler
27 Cleaning of the code :
28 -> coding conventions
29 -> void Streamers
30 -> some useless includes removed or replaced by "class" statement
31
32 Revision 1.4  2000/07/03 11:54:57  morsch
33 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
34 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
35
36 Revision 1.3  2000/06/25 17:02:19  pcrochet
37 scope problem on HP, i declared once, pow replaced by TMath::Power (PH)
38
39 Revision 1.2  2000/06/15 07:58:49  morsch
40 Code from MUON-dev joined
41
42 Revision 1.1.2.8  2000/06/14 14:54:34  morsch
43 Complete redesign, make use of TriggerCircuit and TriggerLut (PC)
44
45 Revision 1.1.2.5  2000/04/26 19:59:57  morsch
46 Constructor added.
47
48 Revision 1.1.2.4  2000/04/26 12:31:30  morsch
49 Modifications by P. Crochet:
50 - adapted to the new Trigger chamber geometry
51 - condition on soft background added
52 - contructor added in AliMUONTriggerDecision.h
53 - single-undefined taken into account in the output of GlobalTrigger()
54 - some bugs fixed
55
56 Revision 1.1.2.3  2000/03/21 09:29:58  morsch
57 Put back comments
58
59 Revision 1.1.2.2  2000/03/21 09:24:34  morsch
60 Author and responsible for the code: Philippe Crochet
61 */
62
63 #include "AliMUONTriggerCircuit.h"
64 #include "AliMUONTriggerDecision.h"
65 #include "AliMUONTriggerLut.h"
66 #include "AliMUONHitMapA1.h"
67 #include "AliRun.h"
68 #include "AliMUON.h"
69 #include "AliSegmentation.h"
70 #include "AliMUONResponse.h"
71 #include "AliMUONChamber.h"
72 #include "AliMUONDigit.h"
73
74
75 #include <TF1.h>
76 #include <TTree.h>
77 #include <TCanvas.h>
78 #include <TH1.h>
79 #include <TPad.h>
80 #include <TGraph.h> 
81 #include <TPostScript.h> 
82 #include <TMinuit.h> 
83 #include <iostream.h> 
84
85 //----------------------------------------------------------------------
86 ClassImp(AliMUONTriggerDecision)
87
88 //----------------------------------------------------------------------
89 AliMUONTriggerDecision::AliMUONTriggerDecision(Int_t iprint)
90 {
91 // Constructor 
92   fDebug = iprint;            // print option
93 // iprint = 0 : don't print anything
94 // iprint = 1 : print Global Trigger Output
95 // iprint = 2 : print Local and Global Trigger Outputs
96 // iprint = 3 : iprint = 2 + detailed info on X strips
97 // iprint = 4 : iprint = 2 + detailed info on Y strip
98 // iprint = 5 : iprint = 2 + detailed info on X and Y strips
99 // Note : with iprint>2, the strips detailed info is given for all circuits
100
101 // Global Trigger information
102   Int_t i;
103   Int_t icirc;
104   Int_t istrip;
105
106   for (i=0; i<3; i++) {   // [0] : Low pt, [1] : High pt, [2] : All pt 
107     fGlobalSinglePlus[i]=0;     // tot num of single plus 
108     fGlobalSingleMinus[i]=0;    // tot num of single minus
109     fGlobalSingleUndef[i]=0;    // tot num of single undefined
110     fGlobalPairUnlike[i]=0;     // tot num of unlike-sign pairs
111     fGlobalPairLike[i]=0;       // tot num of like-sign pairs
112   }
113   // Local Trigger information
114   for (icirc=0; icirc<234; icirc++){
115     fTrigger[icirc]=0;                   // trigger or not
116     fStripX11[icirc]=0;                   // X strip in MC11 which triggers 
117     fDev[icirc]=0;                        // deviation which triggers 
118     fStripY11[icirc]=0;                   // Y strip in MC11 which triggers 
119     for (i=0; i<2; i++) {           // pt information via LuT
120       fLutLpt[icirc][i]=fLutHpt[icirc][i]=fLutApt[icirc][i]=0;    
121     }
122   }
123   // bit pattern
124   for (icirc=0; icirc<234; icirc++) {
125     for (istrip=0; istrip<16; istrip++) {
126       fXbit11[icirc][istrip]=fXbit12[icirc][istrip]=0;
127       fYbit11[icirc][istrip]=fYbit12[icirc][istrip]=0;
128       fYbit21[icirc][istrip]=fYbit22[icirc][istrip]=0;
129       fYbit21U[icirc][istrip]=fYbit22U[icirc][istrip]=0;
130       fYbit21D[icirc][istrip]=fYbit22D[icirc][istrip]=0;
131     }
132     for (istrip=0; istrip<32; istrip++) {
133       fXbit21[icirc][istrip]=fXbit22[icirc][istrip]=0;
134     }
135   }
136 }
137
138 //----------------------------------------------------------------------
139 AliMUONTriggerDecision::~AliMUONTriggerDecision()
140 {
141 // Destructor
142 }
143
144 //----------------------------------------------------------------------
145 void AliMUONTriggerDecision::Trigger(){
146 // main method of the class which calls the overall Trigger procedure
147 //  cout << " In AliMUONTriggerDecision::Trigger " << "\n";
148
149   ResetBit();
150   SetBit();
151   SetBitUpDownY();
152
153   Int_t coinc44=0, resetMid=0; // initialize coincidence
154
155   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
156   AliMUONTriggerCircuit* triggerCircuit;
157
158   for (Int_t icirc=0; icirc<234; icirc++) {  // loop on circuits
159     triggerCircuit = &(pMUON->TriggerCircuit(icirc));     
160     //    Int_t idCircuit=triggerCircuit->GetIdCircuit(); 
161     
162     Int_t minDevStrip[5], minDev[5], coordY[5];
163     for (Int_t i=0; i<5; i++) {
164       minDevStrip[i]=minDev[i]=coordY[i]=0;
165     }
166     Int_t x2m=triggerCircuit->GetX2m();
167     Int_t x2ud=triggerCircuit->GetX2ud();
168     Int_t orMud[2]={0,0};
169     triggerCircuit->GetOrMud(orMud);
170         
171 // call triggerX
172     TrigX(fXbit11[icirc],fXbit12[icirc],fXbit21[icirc],fXbit22[icirc], 
173           coinc44, minDevStrip, minDev);
174 // call triggerY
175     TrigY(fYbit11[icirc],fYbit12[icirc],fYbit21[icirc],fYbit22[icirc],
176           fYbit21U[icirc],fYbit21D[icirc],fYbit22U[icirc],fYbit22D[icirc],
177           x2m,x2ud,orMud,resetMid,coinc44,coordY);
178 // call LocalTrigger     
179     Int_t iTrigger=0;
180     LocalTrigger(icirc, minDevStrip, minDev, coordY, iTrigger);
181
182     if (iTrigger==1&&fDebug>1) { 
183       PrintBitPatXInput(icirc);
184       PrintBitPatYInput(icirc);
185       PrintLocalOutput(minDevStrip, minDev, coordY);
186     }      
187   }  //  end loop on circuits
188
189 // call Global Trigger
190   GlobalTrigger();
191   //  cout << " Leaving AliMUONTriggerDecision::Trigger " << "\n";
192 }
193
194 //----------------------------------------------------------------------
195 void AliMUONTriggerDecision::ResetBit(){
196 // reset bit pattern, global and local trigger output tables to 0
197   
198     Int_t i;
199     Int_t icirc;
200     Int_t istrip;
201
202   for (icirc=0; icirc<234; icirc++) {
203     for (istrip=0; istrip<16; istrip++) {
204       fXbit11[icirc][istrip]=fXbit12[icirc][istrip]=0;
205       fYbit11[icirc][istrip]=fYbit12[icirc][istrip]=0;
206       fYbit21[icirc][istrip]=fYbit22[icirc][istrip]=0;
207       fYbit21U[icirc][istrip]=fYbit22U[icirc][istrip]=0;
208       fYbit21D[icirc][istrip]=fYbit22D[icirc][istrip]=0;
209     }
210     for (istrip=0; istrip<32; istrip++) {
211       fXbit21[icirc][istrip]=fXbit22[icirc][istrip]=0;
212     }
213   }
214   for (i=0; i<3; i++) { 
215     fGlobalSinglePlus[i]=0;
216     fGlobalSingleMinus[i]=0;
217     fGlobalSingleUndef[i]=0;
218     fGlobalPairLike[i]=0;
219     fGlobalPairLike[i]=0;
220   }
221   for (icirc=0; icirc<234; icirc++){
222     fTrigger[icirc]=0;
223     fStripX11[icirc]=0;
224     fDev[icirc]=0;                      
225     fStripY11[icirc]=0;                 
226     for (i=0; i<2; i++) {         
227       fLutLpt[icirc][i]=fLutHpt[icirc][i]=fLutApt[icirc][i]=0;    
228     }
229   }
230 }
231
232 //----------------------------------------------------------------------
233 void AliMUONTriggerDecision::SetBit(){
234 // 1) loop over chambers and cathodes
235 // 2) load digits 
236 // 3) remove soft background
237 // 4) set the bit patterns
238
239   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
240   AliMUONTriggerCircuit* triggerCircuit;
241
242   for (Int_t chamber=11; chamber<15; chamber++){
243     for (Int_t cathode=1; cathode<3; cathode++){
244       
245       AliMUONChamber*   iChamber;
246       AliSegmentation*  segmentation;
247       
248       TClonesArray *muonDigits  = pMUON->DigitsAddress(chamber-1);
249       if (muonDigits == 0) return;
250       
251       gAlice->ResetDigits();
252       Int_t nent = 0;
253       
254       if (gAlice->TreeD()) {
255         nent = (Int_t) gAlice->TreeD()->GetEntries();
256         //printf(" entries %d \n", nent);
257         //     gAlice->TreeD()->GetEvent(nent-2+cathode-1);
258         gAlice->TreeD()->GetEvent(cathode-1);
259       }
260       
261       Int_t ndigits = muonDigits->GetEntriesFast();
262       if (ndigits == 0) return;
263       
264       iChamber = &(pMUON->Chamber(chamber-1));
265       segmentation=iChamber->SegmentationModel(cathode);
266       AliMUONDigit  *mdig;
267       
268       for (Int_t digit=0; digit<ndigits; digit++) {
269         mdig    = (AliMUONDigit*)muonDigits->UncheckedAt(digit);
270 // get the center of the pad Id 
271         Int_t ix=mdig->PadX();
272         Int_t iy=mdig->PadY();
273 // get the sum of the coded charge 
274 // see coding convention in AliMUONChamberTrigger::DisIntegration       
275         Int_t sumCharge=0;
276         for (Int_t icharge=0; icharge<10; icharge++) {
277           sumCharge=sumCharge+mdig->TrackCharge(icharge);
278         }
279 // apply condition on soft background   
280         Int_t testCharge=sumCharge-(Int_t(sumCharge/10))*10;
281         if(sumCharge<=10||testCharge>0) {         
282 // code pad
283           Int_t code=TMath::Abs(ix)*100+iy;
284           if (ix<0) { code=-code; }
285           
286           Int_t icirc;
287           Int_t istrip;
288           Int_t nStrip;
289
290           if (cathode==1) {
291             switch (chamber)
292               {
293               case 11:
294                 for (icirc=0; icirc<234; icirc++) {               
295                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
296                   for (istrip=0; istrip<16; istrip++) {
297                     if (triggerCircuit->GetXcode(0,istrip)==code) 
298                       fXbit11[icirc][istrip]=1;
299                   }
300                 }
301                 break;
302               case 12:
303                 for (icirc=0; icirc<234; icirc++) {
304                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
305                   for (istrip=0; istrip<16; istrip++) {
306                     if (triggerCircuit->GetXcode(1,istrip)==code) 
307                       fXbit12[icirc][istrip]=1;
308                   }
309                 }
310                 break;
311               case 13:
312                 for (icirc=0; icirc<234; icirc++) {
313                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
314                   for (istrip=0; istrip<32; istrip++) {
315                     if (triggerCircuit->GetXcode(2,istrip)==code) 
316                       fXbit21[icirc][istrip]=1;
317                   }
318                 }
319                 break;
320               case 14:
321                 for (icirc=0; icirc<234; icirc++) {
322                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
323                   for (istrip=0; istrip<32; istrip++) {
324                     if (triggerCircuit->GetXcode(3,istrip)==code) 
325                       fXbit22[icirc][istrip]=1;             
326                   }
327                 }               
328                 break;
329               }
330             
331           } else {                // Y plane 
332             switch (chamber)
333               {
334               case 11:
335                 for (icirc=0; icirc<234; icirc++) {
336                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
337                   nStrip=triggerCircuit->GetNstripY();
338                   for (istrip=0; istrip<nStrip; istrip++) {
339                     if (triggerCircuit->GetYcode(0,istrip)==code) 
340                       fYbit11[icirc][istrip]=1;
341                   }
342                 }
343                 break;
344               case 12:
345                 for (icirc=0; icirc<234; icirc++) {
346                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
347                   nStrip=triggerCircuit->GetNstripY(); 
348                   for (istrip=0; istrip<nStrip; istrip++) {
349                     if (triggerCircuit->GetYcode(1,istrip)==code) 
350                       fYbit12[icirc][istrip]=1;
351                   }
352                 }
353                 break;
354               case 13:
355                 for (icirc=0; icirc<234; icirc++) {
356                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
357                   nStrip=triggerCircuit->GetNstripY();    
358                   for (istrip=0; istrip<nStrip; istrip++) {
359                     if (triggerCircuit->GetYcode(2,istrip)==code) 
360                       fYbit21[icirc][istrip]=1;
361                   }
362                 }
363                 break;
364               case 14:
365                 for (icirc=0; icirc<234; icirc++) {
366                   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
367                   nStrip=triggerCircuit->GetNstripY();    
368                   for (istrip=0; istrip<nStrip; istrip++) {
369                     if (triggerCircuit->GetYcode(3,istrip)==code) 
370                       fYbit22[icirc][istrip]=1;                          
371                   }
372                 }               
373                 break;
374               }
375           } // if cathode
376         }  // remove soft background
377       }   // end loop on digit
378     }    // end loop on cathode
379   }     // end loop on chamber
380 }  
381
382 //----------------------------------------------------------------------
383 void AliMUONTriggerDecision::SetBitUpDownY(){
384 // Set Y bit for up and down parts of circuits
385   Int_t idModule, nStripX, nStripY, iPosCircuit;
386
387   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
388   
389   for (Int_t icirc=0; icirc<234; icirc++) {
390
391     AliMUONTriggerCircuit* circuit;   // current circuit
392     AliMUONTriggerCircuit* circuitD;  // circuit Down
393     AliMUONTriggerCircuit* circuitU;  // circuit Up
394
395     circuit = &(pMUON->TriggerCircuit(icirc));  
396     idModule=circuit->GetIdModule();      // corresponding module Id.
397     nStripX=circuit->GetNstripX();        // number of X strips
398     nStripY=circuit->GetNstripY();        // number of Y strips
399     iPosCircuit=circuit->GetPosCircuit(); // position of circuit in module
400
401 // fill lower part
402     if (iPosCircuit==1) {               // need to scan lower module       
403       if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { 
404         Int_t icircD=circuit->GetICircuitD();
405         circuitD = &(pMUON->TriggerCircuit(icircD));  
406         Int_t nStripD=circuitD->GetNstripY();
407                 
408         if (TMath::Abs(idModule)==42) { // shift of +8 bits
409           for (Int_t istrip=0; istrip<nStripD; istrip++) {
410             fYbit21D[icirc][istrip+8]=fYbit21[icircD][istrip];
411             fYbit22D[icirc][istrip+8]=fYbit22[icircD][istrip];
412           }       
413         } else if (TMath::Abs(idModule)==52) { // shift of -8 bits
414           for (Int_t istrip=0; istrip<nStripD; istrip++) {
415             fYbit21D[icirc][istrip]=fYbit21[icircD][istrip+8];
416             fYbit22D[icirc][istrip]=fYbit22[icircD][istrip+8];
417           }
418         } else {
419           for (Int_t istrip=0; istrip<nStripD; istrip++) {
420             fYbit21D[icirc][istrip]=fYbit21[icircD][istrip];
421             fYbit22D[icirc][istrip]=fYbit22[icircD][istrip];
422           }
423         }
424       }      
425     } else {                         // lower strips within same module       
426       for (Int_t istrip=0; istrip<nStripY; istrip++) { 
427         fYbit21D[icirc][istrip]=fYbit21[icirc][istrip];
428         fYbit22D[icirc][istrip]=fYbit22[icirc][istrip];
429       }
430     }    
431     
432 // fill upper part
433     if ((iPosCircuit==1&&nStripX==16)||(iPosCircuit==2&&nStripX==32)|| 
434         (iPosCircuit==3&&nStripX==48)||(iPosCircuit==4&&nStripX==64)) {   
435       if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {  
436         Int_t icircU=circuit->GetICircuitU();
437         circuitU = &(pMUON->TriggerCircuit(icircU));  
438         Int_t nStripU=circuitU->GetNstripY();           
439         
440         if (TMath::Abs(idModule)==62) { // shift of +8 bits
441           for (Int_t istrip=0; istrip<nStripU; istrip++) {
442             fYbit21U[icirc][istrip+8]=fYbit21[icircU][istrip];
443             fYbit22U[icirc][istrip+8]=fYbit22[icircU][istrip];
444           }       
445         } else if (TMath::Abs(idModule)==52) { // shift of -8 bits
446           for (Int_t istrip=0; istrip<nStripU; istrip++) {
447             fYbit21U[icirc][istrip]=fYbit21[icircU][istrip+8];
448             fYbit22U[icirc][istrip]=fYbit22[icircU][istrip+8];
449           }
450         } else {
451           for (Int_t istrip=0; istrip<nStripU; istrip++) {
452             fYbit21U[icirc][istrip]=fYbit21[icircU][istrip];
453             fYbit22U[icirc][istrip]=fYbit22[icircU][istrip];
454           }
455         }
456       }      
457     } else {                       // upper strips within same module       
458       for (Int_t istrip=0; istrip<nStripY; istrip++) { 
459         fYbit21U[icirc][istrip]=fYbit21[icirc][istrip];
460         fYbit22U[icirc][istrip]=fYbit22[icirc][istrip];
461       }
462     } 
463   } // loop on circuit
464 }
465
466 //----------------------------------------------------------------------
467 // x part of trigger Algo
468 //----------------------------------------------------------------------
469 //----------------------------------------------------------------------
470 void AliMUONTriggerDecision::TrigX(Int_t ch1q[16], Int_t ch2q[16], 
471                                    Int_t ch3q[32], Int_t ch4q[32], 
472                                    Int_t coinc44, Int_t minDevStrip[5], 
473                                    Int_t minDev[5]){
474 // note : coinc44 = flag 0 or 1 (0 coincidence -> 3/4, 1 coincidence -> 4/4)
475 //---------------------------------------------------------
476 // step # 1 : declustering, reduction DS, calculate sgle & dble
477 //---------------------------------------------------------
478   Int_t ch1e[19], ch2e[20], ch3e[35], ch4e[36]; 
479   Int_t sgleHit1[31], sgleHit2[63];
480   Int_t dbleHit1[31], dbleHit2[63];
481
482   Int_t i;
483   Int_t j;
484   Int_t istrip;
485
486   for (i=0; i<31; i++) {
487     sgleHit1[i]=0;
488     dbleHit1[i]=0;
489   }
490   for (i=0; i<63; i++) {
491     sgleHit2[i]=0;
492     dbleHit2[i]=0;
493   }
494
495 //--- inititialize che using chq 
496   for (i=0; i<19; i++) {
497     if (i<1||i>16)  ch1e[i]=0; 
498     else            ch1e[i]=ch1q[i-1]; 
499   }
500   for (i=0; i<20; i++) {
501     if (i<2||i>17) ch2e[i]=0; 
502     else           ch2e[i]=ch2q[i-2]; 
503   }
504   for (i=0; i<35; i++) {
505     if (i<1||i>32) ch3e[i]=0; 
506     else           ch3e[i]=ch3q[i-1];
507   }
508   for (i=0; i<36; i++) {
509     if (i<2||i>33) ch4e[i]=0; 
510     else           ch4e[i]=ch4q[i-2];
511   }
512
513
514 //--- calculate dble & sgle first station
515   for (i=0; i<=15; i++) {                   
516     sgleHit1[2*i] = (!ch1e[i+1]|(ch1e[i]^ch1e[i+2])) & 
517       (!ch2e[i+2] | (ch2e[i+1]^ch2e[i+3]));
518
519     dbleHit1[2*i] = ch1e[i+1]&!(ch1e[i+2]^ch1e[i]) & 
520       (ch2e[i+2] | (!ch2e[i]&ch2e[i+1]) | (ch2e[i+3]&!ch2e[i+4]));
521   }
522
523   for (i=0; i<=14; i++) {               
524     sgleHit1[2*i+1] = (!ch1e[i+1]|!ch1e[i+2]|(ch1e[i]^ch1e[i+3])) & 
525       (!ch2e[i+2] | !ch2e[i+3] | (ch2e[i+1]^ch2e[i+4]));
526     dbleHit1[2*i+1] = ch1e[i+1]&ch1e[i+2]&!(ch1e[i]^ch1e[i+3]) & 
527       (ch2e[i+2]&(!ch2e[i+1]|!ch2e[i]) | 
528               ch2e[i+3]&(ch2e[i+2]|!ch2e[i+4]|!ch2e[i+5]));
529   }
530
531 //--- calculate dble & sgle second station
532   for (i=0; i<=31; i++) {               
533     sgleHit2[2*i] = (!ch3e[i+1]|(ch3e[i]^ch3e[i+2])) & 
534       (!ch4e[i+2] | (ch4e[i+1]^ch4e[i+3]));
535     dbleHit2[2*i] = ch3e[i+1]&!(ch3e[i+2]^ch3e[i]) & 
536       (ch4e[i+2] | (!ch4e[i]&ch4e[i+1]) | (ch4e[i+3]&!ch4e[i+4]));
537   }
538   
539   for (i=0; i<=30; i++) {               
540     sgleHit2[2*i+1] = (!ch3e[i+1]|!ch3e[i+2]|(ch3e[i]^ch3e[i+3])) & 
541       (!ch4e[i+2] | !ch4e[i+3] | (ch4e[i+1]^ch4e[i+4]));
542     dbleHit2[2*i+1] = ch3e[i+1]&ch3e[i+2]&!(ch3e[i]^ch3e[i+3]) & 
543       (ch4e[i+2]&(!ch4e[i+1]|!ch4e[i]) | 
544        ch4e[i+3]&(ch4e[i+2]|!ch4e[i+4]|!ch4e[i+5]));
545   }
546
547 //--- 
548   if(fDebug==3||fDebug==5) {
549     cout << "===============================================================" << "\n";
550     cout << " X plane after sgle and dble " << " \n";
551     cout << "                       0987654321098765432109876543210";
552     cout << "\n SGLE1                 ";
553     for (istrip=30; istrip>=0; istrip--) { cout << (!sgleHit1[istrip]); }
554     cout << "\n DBLE1                 ";
555     for (istrip=30; istrip>=0; istrip--) { cout << dbleHit1[istrip]; }
556     cout << "\n SGLE2 ";
557     for (istrip=62; istrip>=0; istrip--) { cout << (!sgleHit2[istrip]); }
558     cout << "\n DBLE2 ";
559     for (istrip=62; istrip>=0; istrip--) { cout << dbleHit2[istrip]; }
560     cout << "\n       210987654321098765432109876543210987654321098765432109876543210" << "\n";
561   }
562   
563 //---------------------------------------------------------
564 // step # 2 : coincidence 3/4
565 //---------------------------------------------------------
566   Int_t rearImage[31][31];
567   for (i=0; i<31; i++) {
568     for (j=0; j<31; j++) {
569       rearImage[i][j]=0;
570     }
571   }
572
573  Int_t notOr1=!dbleHit1[30] & !dbleHit1[29] & !dbleHit1[28] & !dbleHit1[27] & 
574  !dbleHit1[26] & !dbleHit1[25] & !dbleHit1[24] & !dbleHit1[23] &
575  !dbleHit1[22] & !dbleHit1[21] & !dbleHit1[20] & !dbleHit1[19] & 
576  !dbleHit1[18] & !dbleHit1[17] & !dbleHit1[16] & !dbleHit1[15] & 
577  !dbleHit1[14] & !dbleHit1[13] & !dbleHit1[12] & !dbleHit1[11] & 
578  !dbleHit1[10] & !dbleHit1[9]  & !dbleHit1[8]  & !dbleHit1[7]  & 
579  !dbleHit1[6]  & !dbleHit1[5]  & !dbleHit1[4]  & !dbleHit1[3]  & 
580  !dbleHit1[2]  & !dbleHit1[1]  & !dbleHit1[0]  & !coinc44;
581
582  Int_t notOr2= !dbleHit2[62] & !dbleHit2[61] & !dbleHit2[60] & !dbleHit2[59] & 
583  !dbleHit2[58] & !dbleHit2[57] & !dbleHit2[56] & !dbleHit2[55] & 
584  !dbleHit2[54] & !dbleHit2[53] & !dbleHit2[52] & !dbleHit2[51] & 
585  !dbleHit2[50] & !dbleHit2[49] & !dbleHit2[48] & !dbleHit2[47] & 
586  !dbleHit2[46] & !dbleHit2[45] & !dbleHit2[44] & !dbleHit2[43] & 
587  !dbleHit2[42] & !dbleHit2[41] & !dbleHit2[40] & !dbleHit2[39] & 
588  !dbleHit2[38] & !dbleHit2[37] & !dbleHit2[36] & !dbleHit2[35] & 
589  !dbleHit2[34] & !dbleHit2[33] & !dbleHit2[32] & !dbleHit2[31] &
590  !dbleHit2[30] & !dbleHit2[29] & !dbleHit2[28] & !dbleHit2[27] & 
591  !dbleHit2[26] & !dbleHit2[25] & !dbleHit2[24] & !dbleHit2[23] & 
592  !dbleHit2[22] & !dbleHit2[21] & !dbleHit2[20] & !dbleHit2[19] & 
593  !dbleHit2[18] & !dbleHit2[17] & !dbleHit2[16] & !dbleHit2[15] & 
594  !dbleHit2[14] & !dbleHit2[13] & !dbleHit2[12] & !dbleHit2[11] & 
595  !dbleHit2[10] & !dbleHit2[9]  & !dbleHit2[8]  & !dbleHit2[7]  & 
596  !dbleHit2[6]  & !dbleHit2[5]  & !dbleHit2[4]  & !dbleHit2[3]  & 
597  !dbleHit2[2]  & !dbleHit2[1]  & !dbleHit2[0]  & !coinc44;      
598
599 // DS reduction
600  for (i=0; i<31; i++) {
601    sgleHit1[i] = !sgleHit1[i]&notOr1;
602  }
603  for (i=0; i<63; i++) {
604    sgleHit2[i] = !sgleHit2[i]&notOr2;
605  }
606
607 // extract rearImage
608  for (i=0; i<31; i++){
609    Int_t tmpSgleHit2[31];
610    Int_t tmpDbleHit2[31];
611    for (j=0; j<31; j++){
612      tmpSgleHit2[j] = sgleHit2[i+j+1];
613      tmpDbleHit2[j] = dbleHit2[i+j+1];
614    }
615
616    for (Int_t k=0; k<31; k++) {
617      rearImage[i][k]=(sgleHit1[i]&tmpDbleHit2[k])|
618        (dbleHit1[i]&(tmpSgleHit2[k]|tmpDbleHit2[k]));
619    }
620  }
621
622   //-----------
623  if(fDebug==3||fDebug==5) {
624     cout << "===============================================================" << "\n";
625    for (i=30; i>=0; i--) {
626      cout << i << "\t ";
627      for (istrip=31; istrip>=0; istrip--) {
628        cout << rearImage[i][istrip];
629      }
630      cout << " " << "\n";
631    }
632  }
633   
634
635 //---------------------------------------------------------
636 // step # 3 : calculate deviation
637 //--------------------------------------------------------- 
638  Int_t dev[31][6];
639  for (i=0; i<31; i++) {
640    for (j=0; j<6; j++) {
641      dev[i][j]=0;
642    }
643  }
644
645  for (i=0; i<31; i++){
646    Int_t leftDev[5], rightDev[5]; 
647    Int_t orL1, andL1, andL2, orR1, orR2, andR1, andR2, andR3;
648
649 // calculate Left deviation
650  orL1=rearImage[i][16]|rearImage[i][18]|rearImage[i][20]|rearImage[i][22];
651  andL1=!rearImage[i][17]&!rearImage[i][19]&!rearImage[i][21] & !orL1; 
652  andL2=!rearImage[i][23]&!rearImage[i][24]&!rearImage[i][25]&!rearImage[i][26];
653  
654  leftDev[0] = (rearImage[i][16]|!rearImage[i][17]) & 
655  (rearImage[i][16]|rearImage[i][18]|!rearImage[i][19]&
656  (rearImage[i][20]|!rearImage[i][21])) &
657  (orL1|!rearImage[i][23]&(rearImage[i][24]|!rearImage[i][25])) & 
658  (orL1|rearImage[i][24]|rearImage[i][26]|!rearImage[i][27]&
659  (rearImage[i][28]|!rearImage[i][29]));
660                                 
661  leftDev[1] = !rearImage[i][16] & 
662  !(!rearImage[i][17]&!rearImage[i][18]&!rearImage[i][21]&!rearImage[i][22] & 
663  (!rearImage[i][25]&!rearImage[i][26]&(rearImage[i][27]|rearImage[i][28]))) &
664  (rearImage[i][17]|rearImage[i][18] | !rearImage[i][19]&!rearImage[i][20]) &
665  (rearImage[i][17]|rearImage[i][18]|rearImage[i][21]|rearImage[i][22] | 
666  !rearImage[i][23]&!rearImage[i][24]);
667                                 
668  leftDev[2] = (!rearImage[i][16]&!rearImage[i][17]&!rearImage[i][18]) & 
669  (rearImage[i][19]|rearImage[i][20]|rearImage[i][21]|rearImage[i][22] | andL2);
670                 
671  leftDev[3] = andL1;
672                 
673  leftDev[4] = 
674  !rearImage[i][27]&!rearImage[i][28]&!rearImage[i][29]&!rearImage[i][30] & 
675  andL1 & andL2;
676
677  // calculate Right deviation
678  orR1=rearImage[i][8]|rearImage[i][10]|rearImage[i][12]|rearImage[i][14];
679  orR2=rearImage[i][8]|rearImage[i][9]|rearImage[i][10]|rearImage[i][11];
680  andR1=!rearImage[i][12]&!rearImage[i][13]&!rearImage[i][14]&!rearImage[i][15];
681  andR2=
682  !rearImage[i][8]&!rearImage[i][9]&!rearImage[i][10]&!rearImage[i][11] & andR1;
683  andR3=!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][6]&!rearImage[i][7]; 
684                 
685  rightDev[0] = !rearImage[i][15]&(rearImage[i][14]|!rearImage[i][13]) & 
686  ((rearImage[i][12]|rearImage[i][14]|!rearImage[i][11]&
687  (rearImage[i][10]|!rearImage[i][9])) &
688  ((orR1|!rearImage[i][7]&(rearImage[i][6]|!rearImage[i][5])) & 
689  (orR1|rearImage[i][4]|rearImage[i][6]|!rearImage[i][3]&(rearImage[i][2]|
690  !rearImage[i][1]))));
691                                 
692  rightDev[1] = !rearImage[i][15]&!rearImage[i][14] & 
693  !(!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][8]&!rearImage[i][9] &
694  (!rearImage[i][12]&!rearImage[i][13]&(rearImage[i][2]|rearImage[i][3]))) &
695  (rearImage[i][12]|rearImage[i][13] | !rearImage[i][10]&!rearImage[i][11]) & 
696  (rearImage[i][8]|rearImage[i][9]|rearImage[i][12]|rearImage[i][13] | 
697  !rearImage[i][6]&!rearImage[i][7]);
698                 
699  rightDev[2] = andR1 & (orR2 | andR3); 
700  rightDev[3] = andR2;           
701  rightDev[4] = 
702  !rearImage[i][0]&!rearImage[i][1]&!rearImage[i][2]&!rearImage[i][3] & 
703  andR2 & andR3 ;
704
705  // compare Left & Right deviations
706  Int_t tmpLeftDev=0, tmpRightDev=0;
707  for (j=0; j<5; j++){
708    tmpLeftDev  = tmpLeftDev + Int_t(leftDev[j]*TMath::Power(2,j)); 
709    tmpRightDev = tmpRightDev + Int_t(rightDev[j]*TMath::Power(2,j)); 
710  }
711
712  // assign mimimum deviation do dev[][]
713  if (tmpLeftDev < tmpRightDev ){
714    for (j=0; j<5; j++){ dev[i][j]=leftDev[j];}
715    dev[i][5]=1;
716  } else {
717    for (j=0; j<5; j++){ dev[i][j]=rightDev[j];}
718    dev[i][5]=0;
719  }
720   }
721   
722 //---
723   if(fDebug==3||fDebug==5) {
724     cout << "===============================================================" << "\n";
725     for (i=30; i>=0; i--) {
726       cout << i << "\t ";
727       for (istrip=5; istrip>=0; istrip--) { cout << dev[i][istrip]; }
728       cout << " " << "\n";
729     }
730   }
731
732 //---------------------------------------------------------
733 // step # 4 : sort deviation
734 //--------------------------------------------------------- 
735  Int_t bga1[16], bga2[8], bga3[4], bga4[2], bga5;
736  Int_t tmpbga1[16][6], tmpbga2[8][6], tmpbga3[4][6], tmpbga4[2][6], tmpbga5[6];
737  Int_t tmpMax[6]={1,1,1,1,1,0};
738
739   for (i=0; i<15; i++) {
740     Sort2x5(dev[2*i],dev[2*i+1],tmpbga1[i],bga1[i]);
741   }  
742     Sort2x5(dev[30],tmpMax,tmpbga1[15],bga1[15]);
743
744 //--    
745   if(fDebug==3||fDebug==5) {
746     cout << "===============================================================" << "\n";
747     cout << " sorting : 1st level " << "\n";
748     for (i=15; i>=0; i--) {
749       cout << i << "\t " << bga1[i] << "\t";    
750       for (j=5; j>=0; j--) {
751         cout << tmpbga1[i][j]; 
752       }
753       cout << " " << "\n";
754     }
755   }
756
757   for (i=0; i<8; i++) {  
758     Sort2x5(tmpbga1[2*i],tmpbga1[2*i+1],tmpbga2[i],bga2[i]);
759   }
760
761 //--    
762   if(fDebug==3||fDebug==5) {
763     cout << "===============================================================" << "\n";
764     cout << " sorting : 2nd level " << "\n";
765     for (i=7; i>=0; i--) {
766       cout << i << "\t " << bga2[i] << "\t";    
767       for (j=5; j>=0; j--) {
768         cout << tmpbga2[i][j]; 
769       }
770       cout << " " << "\n";
771     }
772   }
773     
774   for (i=0; i<4; i++) {  
775     Sort2x5(tmpbga2[2*i],tmpbga2[2*i+1],tmpbga3[i],bga3[i]);
776   }
777
778 //--    
779   if(fDebug==3||fDebug==5) {
780     cout << "===============================================================" << "\n";
781     cout << " sorting : 3rd level " << "\n";
782     for (i=3; i>=0; i--) {
783       cout << i << "\t " << bga3[i] << "\t";    
784       for (j=5; j>=0; j--) {
785         cout << tmpbga3[i][j]; 
786       }
787       cout << " " << "\n";
788     }
789   }
790
791   for (i=0; i<2; i++) {  
792     Sort2x5(tmpbga3[2*i],tmpbga3[2*i+1],tmpbga4[i],bga4[i]);
793   }
794
795 //--    
796   if(fDebug==3||fDebug==5) {
797     cout << "===============================================================" << "\n";
798     cout << " sorting : 4th level " << "\n";
799     for (i=1; i>=0; i--) {
800       cout << i << "\t " << bga4[i] << "\t";    
801       for (j=5; j>=0; j--) {
802         cout << tmpbga4[i][j]; 
803       }
804       cout << " " << "\n";
805     }
806   }
807   
808     Sort2x5(tmpbga4[0],tmpbga4[1],tmpbga5,bga5);
809
810  // coding from 6 to 5 bits 
811     minDev[4] = tmpbga5[5] | tmpbga5[4];
812     for (i=0; i<4; i++) { 
813       minDev[i]=tmpbga5[i] & !tmpbga5[4];
814     }
815
816  // find address of strip with minimum deviation 
817     minDevStrip[4]=bga5;
818     if (bga5<=1) minDevStrip[3]=bga4[bga5];
819
820     Int_t tmpAd=minDevStrip[3]+minDevStrip[4]*2;
821     if (tmpAd<=3) minDevStrip[2]=bga3[tmpAd];
822
823     tmpAd=minDevStrip[2]+minDevStrip[3]*2+minDevStrip[4]*4;
824     if (tmpAd<=7) minDevStrip[1]=bga2[tmpAd];
825
826     tmpAd=minDevStrip[1]+minDevStrip[2]*2+minDevStrip[3]*4+minDevStrip[4]*8;
827     if (tmpAd<=15) minDevStrip[0]=bga1[tmpAd];
828
829   if(fDebug==3||fDebug==5) {
830     cout << "===============================================================" << "\n";
831     cout << "minDevStrip = ";
832     for  (i=4; i>=0; i--) {cout << minDevStrip[i];}
833     cout << " minDev = ";
834     for  (i=4; i>=0; i--) {cout << minDev[i];} 
835     cout << " " << "\n";
836     cout << "===============================================================" << "\n";
837   }
838
839 }
840
841 //---------------------------------------------
842 void AliMUONTriggerDecision::Sort2x5(Int_t dev1[6], Int_t dev2[6],
843                                      Int_t minDev[6], Int_t &dev1GTdev2){ 
844 // returns minimun between dev1 and dev2
845  Int_t tmpDev1=0, tmpDev2=0;
846  for (Int_t j=0; j<5; j++){
847    tmpDev1 = tmpDev1 + Int_t(dev1[j]*TMath::Power(2,j)); 
848    tmpDev2 = tmpDev2 + Int_t(dev2[j]*TMath::Power(2,j)); 
849  }
850  if (tmpDev1 <= tmpDev2 ){
851    for (Int_t j=0; j<=5; j++) { minDev[j]=dev1[j];}
852    dev1GTdev2=0;
853  } else {
854    for (Int_t j=0; j<=5; j++) { minDev[j]=dev2[j];}
855    dev1GTdev2=1;   
856  }
857 }
858
859 //----------------------------------------------------------------------
860 // y part of trigger Algo 
861 //----------------------------------------------------------------------
862 //----------------------------------------------------------------------
863 void AliMUONTriggerDecision::TrigY(Int_t y1[16], Int_t y2[16], 
864                                    Int_t y3[16], Int_t y4[16],
865                                    Int_t y3u[16], Int_t y3d[16], 
866                                    Int_t y4u[16], Int_t y4d[16],
867                                    Int_t x2m, Int_t x2ud, Int_t orMud[2], 
868                                    Int_t resetMid, Int_t coinc44, 
869                                    Int_t coordY[5]){
870 // note : resMid = 1 -> cancel 
871 //---------------------------------------------------------
872 // step # 1 : prehandling Y
873 //--------------------------------------------------------- 
874     Int_t i;
875     Int_t istrip;
876
877   for (i=0; i<16; i++){
878     y3[i]=y3[i]&!resetMid;
879     y4[i]=y4[i]&!resetMid;
880   }
881
882   Int_t ch1[16], ch2[16], ch3[16], ch4[16];
883
884   Int_t tmpy3to16[16], tmpy4to16[16];
885   Int_t tmpy3uto16[16], tmpy3dto16[16], tmpy4uto16[16], tmpy4dto16[16];
886   for (i=0; i<8; i++){
887     ch1[2*i]   = y1[i]&x2m | y1[2*i]&!x2m;              
888     ch1[2*i+1] = y1[i]&x2m | y1[2*i+1]&!x2m;
889
890     ch2[2*i]   = y2[i]&x2m | y2[2*i]&!x2m;              
891     ch2[2*i+1] = y2[i]&x2m | y2[2*i+1]&!x2m;
892
893     tmpy3to16[2*i]   = y3[i]&x2m | y3[2*i]&!x2m;                
894     tmpy3to16[2*i+1] = y3[i]&x2m | y3[2*i+1]&!x2m;
895
896     tmpy4to16[2*i]   = y4[i]&x2m | y4[2*i]&!x2m;
897     tmpy4to16[2*i+1] = y4[i]&x2m | y4[2*i+1]&!x2m;
898
899     tmpy3uto16[2*i]   = y3u[i]&x2ud | y3u[2*i]&!x2ud; 
900     tmpy3uto16[2*i+1] = y3u[i]&x2ud | y3u[2*i+1]&!x2ud;
901
902     tmpy4uto16[2*i]   = y4u[i]&x2ud | y4u[2*i]&!x2ud; 
903     tmpy4uto16[2*i+1] = y4u[i]&x2ud | y4u[2*i+1]&!x2ud;
904
905     tmpy3dto16[2*i]   = y3d[i]&x2ud | y3d[2*i]&!x2ud; 
906     tmpy3dto16[2*i+1] = y3d[i]&x2ud | y3d[2*i+1]&!x2ud;
907     
908     tmpy4dto16[2*i]   = y4d[i]&x2ud | y4d[2*i]&!x2ud; 
909     tmpy4dto16[2*i+1] = y4d[i]&x2ud | y4d[2*i+1]&!x2ud;
910   }
911   
912   if (orMud[0]==0&&orMud[1]==0){
913     for (i=0; i<16; i++){
914       ch3[i] = tmpy3to16[i];
915       ch4[i] = tmpy4to16[i];
916     }
917   }
918   if (orMud[0]==0&&orMud[1]==1){
919       for (i=0; i<16; i++){
920         ch3[i] = tmpy3uto16[i]|tmpy3to16[i];
921         ch4[i] = tmpy4uto16[i]|tmpy4to16[i];
922       }
923   }
924   if (orMud[0]==1&&orMud[1]==0){
925       for (i=0; i<16; i++){
926         ch3[i] = tmpy3dto16[i]|tmpy3to16[i];
927         ch4[i] = tmpy4dto16[i]|tmpy4to16[i];
928       }
929   }
930   if (orMud[0]==1&&orMud[1]==1){
931       for (i=0; i<16; i++){
932         ch3[i] = tmpy3dto16[i]|tmpy3to16[i]|tmpy3uto16[i];
933         ch4[i] = tmpy4dto16[i]|tmpy4to16[i]|tmpy4uto16[i];
934       }
935   }
936
937 // debug
938   if(fDebug==4||fDebug==5) {
939     cout << "===============================================================" << "\n";  
940     cout << " Y plane after PreHandling x2m x2ud orMud " 
941          << x2m << " , " << x2ud << " , " << orMud[0] << orMud[1] << "\n"; 
942     cout << "                            ";
943     for (istrip=15; istrip>=0; istrip--) {
944       if (istrip>9) cout << istrip-10*Int_t(istrip/10);
945       if (istrip<10) cout << istrip;
946     }  
947     cout << "\n YMC11                      ";
948     for (istrip=15; istrip>=0; istrip--) {
949       cout << ch1[istrip]; 
950     }
951     cout << "\n YMC12                      ";
952     for (istrip=15; istrip>=0; istrip--) {
953       cout << ch2[istrip]; 
954     }
955     cout << "\n YMC21                      ";
956     for (istrip=15; istrip>=0; istrip--) {
957       cout << ch3[istrip]; 
958     }
959     cout << "\n YMC22                      ";
960     for (istrip=15; istrip>=0; istrip--) {
961       cout << ch4[istrip]; 
962     }
963     cout << " \n"; 
964   }
965 //debug
966   
967 //---------------------------------------------------------
968 // step # 2 : calculate sgle and dble, apply DS reduction
969 //--------------------------------------------------------- 
970   Int_t sgle1[16], dble1[16];
971   Int_t sgle2[16], dble2[16];
972
973   // Calculate simple and double hits
974   for (i=0; i<16; i++) {
975     dble1[i] = ch1[i] & ch2[i];
976     dble2[i] = ch3[i] & ch4[i];
977     
978     sgle1[i] = (ch1[i]|ch2[i]);
979     sgle2[i] = (ch3[i]|ch4[i]);
980   }
981
982   //debug
983   if(fDebug==4||fDebug==5) {
984     cout << "===============================================================" << "\n";
985     cout << " Y plane after sgle dble " << "\n"; 
986     cout << "                            ";
987     for (istrip=15; istrip>=0; istrip--) {
988       if (istrip>9) { cout << istrip-10*Int_t(istrip/10);}
989       if (istrip<10) { cout << istrip;}
990     }  
991     cout << "\n SGLE1                      ";
992     for (istrip=15; istrip>=0; istrip--) {
993       cout << sgle1[istrip]; 
994     }
995     cout << "\n DBLE1                      ";
996     for (istrip=15; istrip>=0; istrip--) {
997       cout << dble1[istrip]; 
998     }
999     cout << "\n SGLE2                      ";
1000     for (istrip=15; istrip>=0; istrip--) {
1001       cout << sgle2[istrip]; 
1002     }
1003     cout << "\n DBLE2                      ";
1004     for (istrip=15; istrip>=0; istrip--) {
1005       cout << dble2[istrip]; 
1006     }
1007     cout << " \n"; 
1008   }
1009   //debug
1010
1011   // DS Reduction 
1012   Int_t notOr1, notOr2;
1013
1014   notOr1=!dble1[15] & !dble1[14] & !dble1[13] & !dble1[12] & 
1015          !dble1[11] & !dble1[10] & !dble1[9]  & !dble1[8]  & 
1016          !dble1[7]  & !dble1[6]  & !dble1[5]  & !dble1[4]  & 
1017          !dble1[3]  & !dble1[2]  & !dble1[1]  & !dble1[0];
1018
1019   notOr2=!dble2[15] & !dble2[14] & !dble2[13] & !dble2[12] & 
1020          !dble2[11] & !dble2[10] & !dble2[9]  & !dble2[8]  & 
1021          !dble2[7]  & !dble2[6]  & !dble2[5]  & !dble2[4]  & 
1022          !dble2[3]  & !dble2[2]  & !dble2[1]  & !dble2[0];
1023
1024   for (i=0; i<16; i++) {
1025     sgle1[i] = sgle1[i] & notOr1 & !coinc44;
1026     sgle2[i] = sgle2[i] & notOr2 & !coinc44;
1027   }
1028
1029 //---------------------------------------------------------
1030 // step # 3 : 3/4 coincidence 
1031 //--------------------------------------------------------- 
1032   Int_t frontImage[16];
1033
1034   for (i=1; i<15; i++) {
1035   frontImage[i] = (dble1[i] | sgle1[i]) & 
1036     (dble2[i+1] | dble2[i] | dble2[i-1]) |
1037      dble1[i] & (sgle2[i+1] | sgle2[i] | sgle2[i-1]);
1038   }
1039   frontImage[0] = (dble1[0] | sgle1[0]) & 
1040     (dble2[1] | dble2[0]) | dble1[0] & (sgle2[1] | sgle2[0]);
1041
1042   frontImage[15] = (dble1[15] | sgle1[15]) & 
1043     (dble2[15] | dble2[14]) | dble1[15] & (sgle2[15] | sgle2[14]);
1044
1045
1046 //debug
1047   if(fDebug==4||fDebug==5) {
1048     cout << "===============================================================" << "\n";
1049     cout << " Y plane frontImage\n";
1050     cout << "                            ";
1051   for (istrip=15; istrip>=0; istrip--) {
1052     if (istrip>9) cout << istrip-10*Int_t(istrip/10);
1053     if (istrip<10) cout << istrip;
1054   }
1055     cout << "\n                            ";
1056     for (istrip=15; istrip>=0; istrip--) {
1057       cout << frontImage[istrip]; 
1058     }
1059     cout << "\n";
1060   }
1061 //debug
1062
1063 //---------------------------------------------------------
1064 // step # 4 : Y position 
1065 //--------------------------------------------------------- 
1066   Int_t or1, or2, and1, and2, and3;
1067
1068  or1  = frontImage[7]|frontImage[5]|frontImage[3]|frontImage[1];
1069  or2  = frontImage[7]|frontImage[6]|frontImage[5]|frontImage[4];
1070  and1 = !frontImage[3]&!frontImage[2]&!frontImage[1]&!frontImage[0];
1071  and2 = !frontImage[7]&!frontImage[6]&!frontImage[5]&!frontImage[4] & and1;
1072  and3 = !frontImage[11]&!frontImage[10]&!frontImage[9]&!frontImage[8]; 
1073  
1074  coordY[0] = !frontImage[0]&(frontImage[1]|!frontImage[2]) & 
1075 (frontImage[3]|frontImage[1]|!frontImage[4]&(frontImage[5]|!frontImage[6])) &
1076 (or1|!frontImage[8]&(frontImage[9]|!frontImage[10])) & 
1077 (or1|frontImage[11]|frontImage[9]|!frontImage[12]&(frontImage[13]|!frontImage[14]));
1078  
1079  coordY[1] = !frontImage[0]&!frontImage[1] & 
1080 !(!frontImage[11]&!frontImage[10]&!frontImage[7]&!frontImage[6] & 
1081   !frontImage[3]&!frontImage[2]&(frontImage[13]|frontImage[12])) &
1082   (frontImage[3]|frontImage[2] | !frontImage[5]&!frontImage[4]) & 
1083   (frontImage[7]|frontImage[6]|frontImage[3]|frontImage[2] | 
1084 !frontImage[9]&!frontImage[8]);
1085                 
1086  coordY[2] = and1 & (or2 | and3);
1087                 
1088  coordY[3] = and2;
1089                 
1090  coordY[4] = !frontImage[15]&!frontImage[14]&!frontImage[13]&!frontImage[12] &
1091  and2 & and3 ;
1092
1093 }
1094 //----------------------------------------------------------------------
1095 // end of trigger Algo
1096 //----------------------------------------------------------------------
1097
1098 //----------------------------------------------------------------------
1099 void AliMUONTriggerDecision::LocalTrigger(Int_t icirc, 
1100                                           Int_t minDevStrip[5], 
1101                                           Int_t minDev[5], Int_t coordY[5], 
1102                                           Int_t &iTrigger){
1103 // returns local trigger answer for circuit icirc
1104   Int_t i;
1105
1106   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
1107   AliMUONTriggerCircuit* triggerCircuit;
1108   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
1109   Int_t idCircuit=triggerCircuit->GetIdCircuit();
1110   
1111   Int_t signDev=minDev[4];   
1112   Int_t deviation=0;
1113   for (i=0; i<4; i++) {          // extract deviation
1114     deviation = deviation+Int_t(minDev[i]*TMath::Power(2,i));   
1115   }
1116   
1117   Int_t istripX1Circ=0;
1118   for (i=0; i<5; i++) {          // extract X1 strip fired 
1119     istripX1Circ = istripX1Circ+Int_t(minDevStrip[i]*TMath::Power(2,i));   
1120   }
1121   
1122   Int_t iStripY=0;
1123   for (i=0; i<4; i++) {          // extract Y strip fired 
1124     iStripY = iStripY+Int_t(coordY[i]*TMath::Power(2,i));   
1125   }
1126
1127 // trigger or not 
1128   if (signDev==1&&deviation==0) {      // something in X ?
1129     iTrigger=0;    
1130   } else {
1131     if (coordY[4]==1&&iStripY==15) {   // something in Y ?
1132       iTrigger=0;
1133     } else {
1134       iTrigger=1;
1135     }
1136   }
1137   
1138   if (iTrigger==1) { 
1139 // fill fTrigger fStripX11 fStripY11 
1140     fTrigger[icirc] = 1;
1141     fStripX11[icirc] = istripX1Circ;
1142     fStripY11[icirc] = iStripY;
1143     
1144 // calculate deviation in [0+30]
1145     Int_t sign=0;
1146     if (signDev==0&&deviation!=0) sign=-1;
1147     if (signDev==0&&deviation==0) sign=0;
1148     if (signDev==1)               sign=1;    
1149     fDev[icirc] = sign * deviation + 15; // fill fDev 
1150
1151 // get Lut output for circuit/istripX/idev/istripY
1152     AliMUONTriggerLut* lut = new AliMUONTriggerLut;    
1153     //    lut->StartEvent();
1154     lut->GetLutOutput(icirc,fStripX11[icirc],fDev[icirc],fStripY11[icirc],
1155                       fLutLpt[icirc],fLutHpt[icirc],fLutApt[icirc]);
1156     //    lut->FinishEvent();
1157     delete lut;
1158     
1159     if (fDebug>1) {
1160       Float_t pt= // get ptCal corresponding to istripX1Circ/idev/iStripY
1161       triggerCircuit->PtCal(fStripX11[icirc],fDev[icirc],fStripY11[icirc]);
1162       cout << "-------------------------------------------" << "\n";
1163       cout << " Local Trigger info for circuit Id " << idCircuit 
1164            << " (number " << icirc << ")" << "\n";
1165       cout << " istripX1 signDev deviation istripY = " 
1166            << istripX1Circ << " , " << signDev 
1167            << " , " << deviation << " , " << iStripY << "\n";      
1168       cout << " pt = " << pt << " (GeV/c) " << "\n";
1169       cout << "-------------------------------------------" << "\n";
1170       cout << " Local Trigger Lut Output = Lpt : " ;
1171       for (i=1; i>=0; i--) { cout << fLutLpt[icirc][i] ; }
1172       cout << " Hpt : ";
1173       for (i=1; i>=0; i--) { cout << fLutHpt[icirc][i] ; }
1174       cout << " Apt : ";
1175       for (i=1; i>=0; i--) { cout << fLutApt[icirc][i] ; }        
1176       cout << "\n";
1177       cout << "-------------------------------------------" << "\n";
1178     } // fDebug > 1    
1179   }  // local trigger = 1
1180 }
1181
1182 //----------------------------------------------------------------------
1183 void AliMUONTriggerDecision::GlobalTrigger(){
1184 // loop on Lut[icirc] and give Global Trigger output
1185     Int_t i;
1186
1187   for (Int_t icirc=0; icirc<234; icirc++){
1188     if (fLutLpt[icirc][0]==1&&fLutLpt[icirc][1]==1) 
1189       fGlobalSingleUndef[0] = fGlobalSingleUndef[0] + 1;
1190     if (fLutHpt[icirc][0]==1&&fLutHpt[icirc][1]==1) 
1191       fGlobalSingleUndef[1] = fGlobalSingleUndef[1] + 1;
1192     if (fLutApt[icirc][0]==1&&fLutApt[icirc][1]==1) 
1193       fGlobalSingleUndef[2] = fGlobalSingleUndef[2] + 1;
1194     
1195     if (fLutLpt[icirc][0]==0&&fLutLpt[icirc][1]==1) 
1196       fGlobalSinglePlus[0] = fGlobalSinglePlus[0] + 1;
1197     if (fLutHpt[icirc][0]==0&&fLutHpt[icirc][1]==1) 
1198       fGlobalSinglePlus[1] = fGlobalSinglePlus[1] + 1;
1199     if (fLutApt[icirc][0]==0&&fLutApt[icirc][1]==1) 
1200       fGlobalSinglePlus[2] = fGlobalSinglePlus[2] + 1;
1201
1202     if (fLutLpt[icirc][0]==1&&fLutLpt[icirc][1]==0) 
1203       fGlobalSingleMinus[0] = fGlobalSingleMinus[0] + 1;
1204     if (fLutHpt[icirc][0]==1&&fLutHpt[icirc][1]==0) 
1205       fGlobalSingleMinus[1] = fGlobalSingleMinus[1] + 1;
1206     if (fLutApt[icirc][0]==1&&fLutApt[icirc][1]==0) 
1207       fGlobalSingleMinus[2] = fGlobalSingleMinus[2] + 1;
1208   }
1209
1210   // like sign low, high and all pt
1211   for (i=0; i<3; i++) {
1212     fGlobalPairLike[i]=fGlobalSingleMinus[i]*(fGlobalSingleMinus[i]-1)/2 + 
1213       fGlobalSinglePlus[i]*(fGlobalSinglePlus[i]-1)/2 + 
1214       fGlobalSingleUndef[i]*(fGlobalSingleUndef[i]-1)/2 + 
1215       fGlobalSingleUndef[i]*fGlobalSinglePlus[i] + 
1216       fGlobalSingleUndef[i]*fGlobalSingleMinus[i];
1217   }
1218
1219   // unlike sign low, high and all pt
1220   for (i=0; i<3; i++) {
1221     fGlobalPairUnlike[i]=fGlobalSingleMinus[i]*fGlobalSinglePlus[i] +
1222       fGlobalSingleUndef[i]*(fGlobalSingleUndef[i]-1)/2 + 
1223       fGlobalSingleUndef[i]*fGlobalSinglePlus[i] + 
1224       fGlobalSingleUndef[i]*fGlobalSingleMinus[i]; 
1225   }
1226   
1227   if (fDebug>=1) {
1228     cout << "\n";
1229     cout << "===================================================" << "\n";
1230     cout << " Global Trigger output       " << "Low pt  High pt   All"  << "\n";
1231     cout << " number of Single Plus      :\t";
1232     for (i=0; i<3; i++) { cout << fGlobalSinglePlus[i] <<"\t";}
1233     cout << "\n";
1234     cout << " number of Single Minus     :\t";
1235     for (i=0; i<3; i++) { cout << fGlobalSingleMinus[i] <<"\t";}
1236     cout << "\n";
1237     cout << " number of Single Undefined :\t"; 
1238     for (i=0; i<3; i++) { cout << fGlobalSingleUndef[i] <<"\t";}
1239     cout << "\n";
1240     cout << " number of UnlikeSign pair  :\t"; 
1241     for (i=0; i<3; i++) { cout << fGlobalPairUnlike[i] <<"\t";}
1242     cout << "\n";
1243     cout << " number of LikeSign pair    :\t";  
1244     for (i=0; i<3; i++) { cout << fGlobalPairLike[i] <<"\t";}
1245     cout << "\n";
1246     cout << "===================================================" << "\n";
1247   }
1248 }
1249
1250 //----------------------------------------------------------------------
1251 void AliMUONTriggerDecision::PrintBitPatXInput(Int_t icirc){
1252 // print bit pattern for X strips
1253
1254     Int_t istrip;
1255
1256   cout << "-------- TRIGGER INPUT ---------" << "\n";
1257   cout << "===============================================================" << "\n";
1258   cout << "                            5432109876543210";
1259   cout << "\n XMC11                      ";
1260   for (istrip=15; istrip>=0; istrip--) {
1261     cout << fXbit11[icirc][istrip]; 
1262   }
1263   cout << "\n XMC12                      ";
1264   for (istrip=15; istrip>=0; istrip--) {
1265     cout << fXbit12[icirc][istrip]; 
1266   }
1267   cout << "\n XMC21              ";
1268   for (istrip=31; istrip>=0; istrip--) {
1269     cout << fXbit21[icirc][istrip]; 
1270   }
1271   cout << "\n XMC22              ";
1272   for (istrip=31; istrip>=0; istrip--) {
1273     cout << fXbit22[icirc][istrip]; 
1274   }
1275   cout << "\n                    ";
1276   cout << "10987654321098765432109876543210" << "\n";
1277 }
1278
1279 //----------------------------------------------------------------------
1280 void AliMUONTriggerDecision::PrintBitPatYInput(Int_t icirc){
1281 // print bit pattern for Y strips
1282
1283     Int_t istrip;
1284
1285   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
1286   AliMUONTriggerCircuit* triggerCircuit;
1287   triggerCircuit = &(pMUON->TriggerCircuit(icirc));       
1288   Int_t idCircuit=triggerCircuit->GetIdCircuit();
1289   Int_t nStrip=triggerCircuit->GetNstripY();
1290
1291   cout << "---------------------------------------------------------------" << "\n";
1292   cout << "                            ";
1293   for (istrip=nStrip-1; istrip>=0; istrip--) {
1294     if (istrip>9) { cout << istrip-10*Int_t(istrip/10);}
1295     if (istrip<10) { cout << istrip;}
1296   }
1297   cout << "\n YMC11                      ";
1298   for (istrip=nStrip-1; istrip>=0; istrip--) {
1299     cout << fYbit11[icirc][istrip]; 
1300   }
1301   cout << "\n YMC12                      ";
1302   for (istrip=nStrip-1; istrip>=0; istrip--) {
1303     cout << fYbit12[icirc][istrip]; 
1304   }
1305   cout << "\n YMC21                      ";
1306   for (istrip=nStrip-1; istrip>=0; istrip--) {
1307     cout << fYbit21[icirc][istrip]; 
1308   }
1309   cout << "\n YMC22                      ";
1310   for (istrip=nStrip-1; istrip>=0; istrip--) {
1311     cout << fYbit22[icirc][istrip]; 
1312   }
1313   cout << "\n";
1314 // tmp
1315   cout << "---------------------------------------------------------------";
1316   cout << "\n upper part of circuit " << idCircuit ;
1317   cout << "\n UMC21                      ";
1318   for (istrip=15; istrip>=0; istrip--) {
1319     cout << fYbit21U[icirc][istrip]; 
1320   }
1321   cout << "\n UMC22                      ";
1322   for (istrip=15; istrip>=0; istrip--) {
1323     cout << fYbit22U[icirc][istrip]; 
1324   }
1325
1326   cout << "\n lower part of circuit " << idCircuit ;
1327   cout << "\n LMC21                      ";
1328   for (istrip=15; istrip>=0; istrip--) {
1329     cout << fYbit21D[icirc][istrip]; 
1330   }
1331   cout << "\n LMC22                      ";
1332   for (istrip=15; istrip>=0; istrip--) {
1333     cout << fYbit22D[icirc][istrip]; 
1334   }
1335   cout << "\n";
1336   cout << "===============================================================" << "\n";
1337 }
1338 //----------------------------------------------------------------------
1339 void AliMUONTriggerDecision::PrintLocalOutput(Int_t minDevStrip[5], 
1340                                               Int_t minDev[5], 
1341                                               Int_t coordY[5]){
1342 // print Local trigger output before the LuT step
1343
1344     Int_t i;
1345
1346   cout << "===============================================================" << "\n";
1347   cout << "-------- TRIGGER OUTPUT --------" << "\n";
1348   cout << "minDevStrip = ";
1349   for  (i=4; i>=0; i--) {cout << minDevStrip[i];}
1350   cout << " minDev = ";
1351   for  (i=4; i>=0; i--) {cout << minDev[i];} 
1352   cout << " coordY = ";
1353   for  (i=4; i>=0; i--) {cout << coordY[i];} 
1354   cout << " " << "\n";  
1355 }
1356
1357 //----------------------------------------------------------------------
1358 //--- methods which return member data related info
1359 //----------------------------------------------------------------------
1360 Int_t AliMUONTriggerDecision::GetITrigger(Int_t icirc){
1361 // returns Local Trigger Status
1362   return fTrigger[icirc];
1363 }
1364 //----------------------------------------------------------------------
1365 Int_t AliMUONTriggerDecision::GetStripX11(Int_t icirc){
1366 // returns fStripX11
1367   return fStripX11[icirc];
1368 }
1369 //----------------------------------------------------------------------
1370 Int_t AliMUONTriggerDecision::GetDev(Int_t icirc){
1371 // returns idev
1372   return fDev[icirc];
1373 }
1374 //----------------------------------------------------------------------
1375 Int_t AliMUONTriggerDecision::GetStripY11(Int_t icirc){
1376 // returns fStripY11;
1377    return fStripY11[icirc];
1378 }
1379 //----------------------------------------------------------------------
1380 void AliMUONTriggerDecision::GetLutOutput(Int_t icirc, Int_t lpt[2], 
1381                                           Int_t hpt[2], Int_t apt[2]){
1382 // returns Look up Table output
1383   for (Int_t i=0; i<2; i++) {
1384     lpt[i]=fLutLpt[icirc][i];
1385     hpt[i]=fLutHpt[icirc][i];
1386     apt[i]=fLutApt[icirc][i];
1387   }
1388 }
1389 //----------------------------------------------------------------------
1390 void AliMUONTriggerDecision::GetGlobalTrigger(Int_t singlePlus[3], 
1391                                               Int_t singleMinus[3], 
1392                                               Int_t singleUndef[3],
1393                                               Int_t pairUnlike[3], 
1394                                               Int_t pairLike[3]){
1395 // returns Global Trigger information (0,1,2 : Lpt,Hpt,Apt)
1396   for (Int_t i=0; i<3; i++) { 
1397     singlePlus[i]  = fGlobalSinglePlus[i];
1398     singleMinus[i] = fGlobalSingleMinus[i];
1399     singleUndef[i] = fGlobalSingleUndef[i];
1400     pairUnlike[i]  = fGlobalPairUnlike[i];
1401     pairLike[i]    = fGlobalPairLike[i];    
1402   }
1403 }
1404 //----------------------------------------------------------------------
1405 //--- end of methods which return member data related info
1406 //----------------------------------------------------------------------
1407 //----------------------------------------------------------------------
1408 /*
1409 void AliMUONTriggerDecision::AddLocalTrigger(const AliMUONLocalTrigger c){
1410 // Add a Local Trigger copy to the list
1411   AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON");
1412   MUON->AddLocalTrigger(c); 
1413   fNLocalTriggers++;
1414 }
1415 */