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