fd701819242655a0b7899942e74e6f595e8c9b66
[u/mrichter/AliRoot.git] / MUON / AliMUONRawData.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 ////////////////////////////////////
17 //
18 // MUON Raw Data generator in ALICE-MUON
19 //
20 // This class version 1 (further details could be found in Alice-note coming soon right in our direction)
21 // Generates raw data for MUON tracker and finally for trigger
22 // * a simple mapping is used (see below)
23 // * the bus patch id is calculated with an absolute number 0 - 999
24 // * one DDL per 1/2 chamber is created for both cathode.
25 // For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
26 // don't need for digits2raw but needed in raw2Reco
27 // the position are given per local card
28 ////////////////////////////////////
29
30 #include <TClonesArray.h>
31 #include "AliMUONRawData.h"
32 #include "AliMUONDigit.h"
33
34 #include "AliMUONConstants.h"
35 #include "AliMUONData.h"
36 #include "AliLoader.h"
37 #include "AliBitPacking.h" 
38
39 #include "AliMUONSubEventTrigger.h"
40 #include "AliMUONDDLTracker.h"
41 #include "AliMUONDDLTrigger.h"
42
43 #include "AliMUONLocalTrigger.h"
44 #include "AliMUONGlobalTrigger.h"
45 #include "AliLog.h"
46
47 const Int_t AliMUONRawData::fgkDefaultPrintLevel = 0;
48
49 ClassImp(AliMUONRawData) // Class implementation in ROOT context
50
51 //__________________________________________________________________________
52 AliMUONRawData::AliMUONRawData(AliLoader* loader)
53   : TObject(),
54     fDebug(0)
55 {
56   // Standard Constructor
57  
58   fPrintLevel = fgkDefaultPrintLevel;
59
60   // initialize loader's
61   fLoader = loader;
62
63   // initialize container
64   fMUONData  = new AliMUONData(fLoader,"MUON","MUON");
65
66   // initialize array
67   fSubEventArray[0] = new TClonesArray("AliMUONSubEventTracker",1000);
68   fSubEventArray[1] = new TClonesArray("AliMUONSubEventTracker",1000);
69
70   // initialize array not used for the moment
71   fSubEventTrigArray[0] = new TClonesArray("AliMUONSubEventTrigger",1000);
72   fSubEventTrigArray[1] = new TClonesArray("AliMUONSubEventTrigger",1000);
73
74   // ddl pointer
75   fDDLTracker = new AliMUONDDLTracker();
76   fDDLTrigger = new  AliMUONDDLTrigger();
77 }
78
79 //__________________________________________________________________________
80 AliMUONRawData::AliMUONRawData()
81   : TObject(),
82     fMUONData(0),
83     fPrintLevel(fgkDefaultPrintLevel),
84     fDebug(0),
85     fLoader(0)
86 {
87   // Default Constructor
88 }
89
90 //_______________________________________________________________________
91 AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
92   : TObject(rhs)
93 {
94 // Protected copy constructor
95
96   AliFatal("Not implemented.");
97 }
98
99 //_______________________________________________________________________
100 AliMUONRawData & 
101 AliMUONRawData::operator=(const AliMUONRawData& rhs)
102 {
103 // Protected assignement operator
104
105   if (this == &rhs) return *this;
106
107   AliFatal("Not implemented.");
108     
109   return *this;  
110 }
111
112 //__________________________________________________________________________
113 AliMUONRawData::~AliMUONRawData(void)
114 {
115   if (fMUONData)
116     delete fMUONData;
117   if (fSubEventArray[0])
118     fSubEventArray[0]->Delete(); //using delete cos allocating memory in copy ctor.
119   if (fSubEventArray[1])
120     fSubEventArray[1]->Delete();
121
122   if (fSubEventTrigArray[0])
123     fSubEventTrigArray[0]->Delete();
124   if (fSubEventTrigArray[1])
125     fSubEventTrigArray[1]->Delete();
126
127   if (fDDLTracker)
128     delete fDDLTracker;
129   if (fDDLTrigger)
130     delete fDDLTrigger;
131
132   return;
133 }
134 //____________________________________________________________________
135 Int_t AliMUONRawData::WriteRawData()
136 {
137  // convert digits of the current event to raw data
138
139   Int_t idDDL;
140   Char_t name[20];
141
142   fLoader->LoadDigits("READ");
143
144   fMUONData->SetTreeAddress("D,GLT");
145
146
147   // tracking chambers
148
149   for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
150  
151     // open files
152     idDDL = ich * 2  + 0x900;
153     sprintf(name, "MUON_%d.ddl",idDDL);
154     fFile1 = fopen(name,"w");
155
156     idDDL = (ich * 2) + 1 + 0x900;
157     sprintf(name, "MUON_%d.ddl",idDDL);
158     fFile2 = fopen(name,"w");
159
160     WriteTrackerDDL(ich);
161   
162     // reset and close
163     fclose(fFile1);
164     fclose(fFile2);
165     fMUONData->ResetDigits();
166   }
167  
168   // trigger chambers
169  
170   // open files
171   idDDL = 0xA00;
172   sprintf(name, "MUTR_%d.ddl",idDDL);
173   fFile1 = fopen(name,"w");
174
175   idDDL = 0xA00 + 1;
176   sprintf(name, "MUTR_%d.ddl",idDDL);
177   fFile2 = fopen(name,"w");
178
179   WriteTriggerDDL();
180   
181   // reset and close
182   fclose(fFile1);
183   fclose(fFile2);
184   fMUONData->ResetTrigger();
185   
186   fLoader->UnloadDigits();
187
188   return kTRUE;
189 }
190 //____________________________________________________________________
191 Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
192 {
193   // resets
194   TClonesArray* muonDigits = 0;
195   fSubEventArray[0]->Clear();
196   fSubEventArray[1]->Clear();
197
198   //
199   TArrayI nbInBus[2];
200
201   nbInBus[0].Set(5000);
202   nbInBus[1].Set(5000);
203
204   nbInBus[0].Reset();
205   nbInBus[1].Reset();
206
207   // DDL header
208   AliRawDataHeader header = fDDLTracker->GetHeader();
209   Int_t headerSize = fDDLTracker->GetHeaderSize();
210
211   // DDL event one per half chamber
212   AliMUONSubEventTracker* subEvent;
213
214   // data format
215   Char_t parity = 0x4;
216   UShort_t manuId = 0;
217   UChar_t channelId = 0;
218   UShort_t charge = 0;
219   Int_t busPatchId = 0;
220
221   UInt_t word;
222   Int_t nEntries = 0;
223   Int_t* buffer = 0;
224   Int_t index;
225   Int_t indexDsp;
226   Int_t indexBlk;
227
228   Int_t nDigits;
229   const AliMUONDigit* digit;
230
231    if (fPrintLevel == 1)
232       printf("WriteDDL chamber %d\n", iCh+1);
233
234   for (Int_t iCath = 0; iCath < 2; iCath++) {
235
236     fMUONData->ResetDigits();
237     fMUONData->GetCathode(iCath);
238     muonDigits = fMUONData->Digits(iCh);
239
240     nDigits = muonDigits->GetEntriesFast();
241     if (fPrintLevel == 2)
242       printf("ndigits = %d\n",nDigits);
243
244     // open DDL file, on per 1/2 chamber
245  
246     for (Int_t idig = 0; idig < nDigits; idig++) {
247
248       digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
249
250       // mapping
251       GetDummyMapping(iCh, iCath, digit, busPatchId, manuId, channelId, charge);
252
253       //packing word
254       AliBitPacking::PackWord((UInt_t)parity,word,29,31);
255       AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
256       AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
257       AliBitPacking::PackWord((UInt_t)charge,word,0,11);
258
259       // set sub Event
260       subEvent = new AliMUONSubEventTracker();
261       subEvent->AddData(word);
262       subEvent->SetBusPatchId(busPatchId);
263       if (digit->PadX() > 0) {
264         nbInBus[0][busPatchId]++;
265         AddData1(subEvent);
266       } else {
267         nbInBus[1][busPatchId]++;
268         AddData2(subEvent);
269       }
270       delete subEvent;
271     }
272   }
273   fSubEventArray[0]->Sort();
274   fSubEventArray[1]->Sort();
275
276   // gather datas from same bus patch
277    for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
278     nEntries = fSubEventArray[iDDL]->GetEntriesFast();
279
280     for (Int_t i = 0; i < nEntries; i++) {
281       AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
282       busPatchId = temp->GetBusPatchId();
283
284       // add bus patch header, length and total length managed by subevent class
285       temp->SetTriggerWord(0xdeadbeef);
286       for (Int_t j = 0; j < nbInBus[iDDL][busPatchId]-1; j++) {
287         AliMUONSubEventTracker* temp1 =  (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(++i);
288         temp->AddData(temp1->GetData(0));
289         fSubEventArray[iDDL]->RemoveAt(i) ;
290       }
291     }
292     fSubEventArray[iDDL]->Compress();
293
294     if (fPrintLevel == 3) {
295       nEntries = fSubEventArray[iDDL]->GetEntriesFast();
296       for (Int_t i = 0; i < nEntries; i++) {
297         AliMUONSubEventTracker* temp =  (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
298         printf("busPatchid back %d\n",temp->GetBusPatchId());
299         for (Int_t j = 0; j < temp->GetLength(); j++) {
300           printf("manuId back %d, ",temp->GetManuId(j));
301           printf("channelId back %d, ",temp->GetChannelId(j));
302           printf("charge back %d\n",temp->GetCharge(j));
303         }
304       }
305       printf("\n");
306     }
307   
308   }
309   
310   Int_t iBusPatch;
311   Int_t iEntries;
312   Int_t length;
313
314   for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
315  
316
317     // filling buffer
318     nEntries = fSubEventArray[iDDL]->GetEntriesFast();
319     buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
320
321     indexBlk = 0;
322     indexDsp = 0;
323     index = 0;
324     iBusPatch = 0;
325     iEntries = 0;
326
327     for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
328
329       // block header
330       //    fDDLTracker->SetTotalBlkLength(0xFFFFFFFF);
331       length = fDDLTracker->GetBlkHeaderLength();
332       memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
333       indexBlk = index;
334       index += length; 
335
336       for (Int_t iDsp = 0; iDsp < 5; iDsp++) {
337
338         // DSP header
339         //      fDDLTracker->SetTotalDspLength(0xEEEEEEEE);
340         length = fDDLTracker->GetDspHeaderLength();
341         memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
342         indexDsp = index;
343         index += length; 
344
345         for (Int_t i = 0; i < 5; i++) {
346
347           iBusPatch = i + iBlock*25 + iDsp*5 + 50*(2*iCh + iDDL);
348
349           AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(iEntries);
350           if (nEntries > 0) 
351             busPatchId = temp->GetBusPatchId();
352            else
353             busPatchId = -1;
354
355           if (busPatchId == iBusPatch) {
356             // add bus patch structure
357             length = temp->GetHeaderLength();
358             memcpy(&buffer[index],temp->GetAddress(),length*4);
359             index += length;
360             for (Int_t j = 0; j < temp->GetLength(); j++) 
361               buffer[index++] =  temp->GetData(j);
362             if (iEntries < nEntries-1)
363               iEntries++;
364           } else {
365             buffer[index++] = 4; // total length
366             buffer[index++] = 0; // raw data length
367             buffer[index++] = iBusPatch; // bus patch
368             buffer[index++] = 0xdeadbeef; // trigger word
369           }
370         } // bus patch
371         buffer[indexDsp] = index - indexDsp; // dsp length
372         buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
373         if ((index - indexDsp) % 2 == 0)
374           buffer[indexDsp+7] = 0;
375         else
376           buffer[indexDsp+7] = 1;
377       } // dsp
378       buffer[indexBlk] = index - indexBlk; // block length
379       buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
380     }
381     if (iDDL == 0) {
382       // write DDL 1
383       header.fSize = index + headerSize;// total length in word
384       fwrite((char*)(&header),headerSize*4,1,fFile1);
385       fwrite(buffer,sizeof(int),index,fFile1);
386     } 
387     if (iDDL == 1) {
388       // write DDL 2
389       header.fSize = index + headerSize;// total length in word
390       fwrite((char*)(&header),headerSize*4,1,fFile2);
391       fwrite(buffer,sizeof(int),index,fFile2);
392     }
393     delete[] buffer;
394   }
395
396   return kTRUE;
397 }
398 //____________________________________________________________________
399 Int_t AliMUONRawData::WriteTriggerDDL()
400 {
401
402  // DDL event one per half chamber
403   AliMUONSubEventTrigger* subEvent = 0x0;
404
405
406   // stored local id number 
407   TArrayI isFired(256);
408   isFired.Reset();
409
410
411  // DDL header
412   AliRawDataHeader header = fDDLTrigger->GetHeader();
413   Int_t headerSize = fDDLTrigger->GetHeaderSize();
414   Int_t length;
415   TClonesArray* localTrigger;
416   TClonesArray* globalTrigger;
417   AliMUONGlobalTrigger* gloTrg;
418   AliMUONLocalTrigger* locTrg = 0x0;
419
420   fMUONData->GetTriggerD();
421
422   // global trigger for trigger pattern
423   globalTrigger = fMUONData->GlobalTrigger(); 
424   gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
425   Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
426
427   // local trigger 
428   localTrigger = fMUONData->LocalTrigger();    
429
430   UInt_t word;
431   Int_t* buffer = 0;
432   Int_t index;
433   Int_t iEntries = 0;
434   Int_t iLocCard, locCard;
435   Char_t locDec, trigY, posY, devX, posX,regOut;
436   Int_t version = 1; // software version
437   Int_t eventType = 1; // trigger type: 1 for physics ?
438   Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
439   Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
440
441   Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
442   // stored the local card id that's fired
443   for (Int_t i = 0; i <  nEntries; i++) {
444     locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
445     isFired[locTrg->LoCircuit()] = 1;
446   }
447
448   if (!nEntries)
449     AliError("No Trigger information available");
450
451   buffer = new Int_t [672]; // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
452
453   for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
454     
455     index = 0; 
456
457     // DDL enhanced header
458     word = 0;
459     AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
460     AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
461     AliBitPacking::PackWord((UInt_t)version,word,16,23);
462     AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
463
464     if (iDDL == 0) // suppose global info in DDL one
465       globalFlag = 2;
466     else 
467       globalFlag = 1;
468     AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
469     fDDLTrigger->SetDDLWord(word);
470
471     if (iDDL == 0)
472       fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
473     else 
474       fDDLTrigger->SetGlobalOutput(0);
475     length = fDDLTrigger->GetHeaderLength(); 
476     memcpy(&buffer[index],fDDLTrigger->GetEnhancedHeader(),length*4);
477     index += length; 
478
479     for (Int_t iReg = 0; iReg < 8; iReg++) {
480
481       subEvent = new AliMUONSubEventTrigger();
482
483       // Regional card header
484       word = 0;
485       regOut  = 0;
486       AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see  AliMUONSubEventTrigger.h for details
487       AliBitPacking::PackWord((UInt_t)version,word,16,23);
488       AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
489       AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
490
491       subEvent->SetRegWord(word);
492       memcpy(&buffer[index++],subEvent->GetAddress(),4);
493
494       buffer[index++] = 0;// 2 words of regional input
495       buffer[index++] = 0;
496
497       for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
498
499         iLocCard = iLoc + iReg*16 + iDDL*128;
500
501         if (isFired[iLocCard]) {
502           locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
503           locCard = locTrg->LoCircuit();
504           locDec = locTrg->GetLoDecision();
505           trigY = 0;
506           posY = locTrg->LoStripY();
507           posX = locTrg->LoStripX();
508           devX = locTrg->LoDev();
509           if (fPrintLevel == 4) 
510             printf("loctrg %d, posX %d, posY %d, devX %d\n", 
511                    locTrg-> LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev());
512         } else { //no trigger (see PRR chpt 3.4)
513           locCard = -1;
514           locDec = 0;
515           trigY = 1;
516           posY = 15;
517           posX = 0;
518           devX = 0x8000;
519         }
520
521         //packing word
522         word = 0;
523         AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
524         AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
525         AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
526         AliBitPacking::PackWord((UInt_t)posY,word,10,13);
527         AliBitPacking::PackWord((UInt_t)devX,word,5,9);
528         AliBitPacking::PackWord((UInt_t)posX,word,0,4);
529
530         if (locCard == iLocCard) {
531           // add local cards structure
532           buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
533           buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
534           buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
535           buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
536           buffer[index++] = (Int_t)word; // data word
537           if (iEntries < nEntries-1)
538             iEntries++;
539         } else {
540           buffer[index++] = 0; // 4 words for x1, x2, y1, y2
541           buffer[index++] = 0; 
542           buffer[index++] = 0; 
543           buffer[index++] = 0; 
544           buffer[index++] = (Int_t)word; // data word
545
546         }
547       } // local card 
548
549       delete subEvent;  
550
551     } // Regional card
552     
553     buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
554     buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
555
556     
557     if (iDDL == 0) {
558       // write DDL 1
559       header.fSize = index + headerSize;// total length in word
560       fwrite((char*)(&header),headerSize*4,1,fFile1);
561       fwrite(buffer,sizeof(int),index,fFile1);
562     } 
563     if (iDDL == 1) {
564       // write DDL 2
565       header.fSize = index + headerSize;// total length in word
566       fwrite((char*)(&header),headerSize*4,1,fFile2);
567       fwrite(buffer,sizeof(int),index,fFile2);
568     }
569   }
570   delete[] buffer;
571
572   return kTRUE;
573 }
574 //____________________________________________________________________
575 void AliMUONRawData::GetDummyMapping(Int_t iCh, Int_t iCath, const AliMUONDigit* digit,
576                                      Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId, UShort_t &charge)
577 {
578 // Dummy mapping for tracker
579
580   Int_t offsetX = 0; // offet row
581   Int_t offsetY = 0; // offset columns
582   Int_t offsetCath = 0; //offset from one cathod to the other
583   Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
584   Int_t id;
585       switch (iCh+1) {
586       case 1:
587       case 2:
588       case 3:
589       case 4:
590         offsetX = 512;
591         offsetY = 256;
592         offsetCath = 65536;
593         maxChannel = (offsetY * offsetX + 2* offsetY + offsetCath);
594         break;
595       case 5:
596       case 6:
597       case 7:
598       case 8:
599       case 9:
600       case 10:
601         offsetX = 1024;
602         offsetY = 0;
603         offsetCath = 65536;
604         maxChannel = (256 * offsetX + offsetX + offsetCath);
605         break;
606       }
607       // dummy mapping
608       // manu Id directly from a matrix 8*8, same segmentation for B and NB
609       // 50 buspatches for 1/2 chamber
610
611       id =  (TMath::Abs(digit->PadX()) * offsetX + digit->PadY() + offsetY +
612              offsetCath * iCath);
613       Int_t chPerBus = maxChannel/50;
614       busPatchId = id/chPerBus; // start at zero 
615       if (digit->PadX() > 0)
616         busPatchId += 50*iCh*2;
617       else 
618         busPatchId += 50*(2*iCh+1);
619       // 64 manu cards for one buspatch
620       manuId = (id % chPerBus)/64; //start at zero 
621       manuId &= 0x7FF; // 11 bits 
622
623       // channel id
624       channelId = (id % chPerBus) % 64; //start at zero 
625       channelId &= 0x3F; // 6 bits
626
627       if (fPrintLevel == 2)
628         printf("id: %d, busPatchId %d, manuId: %d, channelId: %d, maxchannel: %d, chPerBus %d\n",
629                id, busPatchId, manuId, channelId, maxChannel, chPerBus);
630       // charge
631       charge = digit->Signal();
632       charge &= 0xFFF;
633
634       if (fPrintLevel == 2)
635         printf("id: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d, charge %d\n",
636                id, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal());
637
638 }
639
640 //____________________________________________________________________
641 Int_t AliMUONRawData::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg)
642 {
643   // global trigger pattern calculation
644
645   Int_t gloTrigPat = 0;
646
647   if (gloTrg->SinglePlusLpt())  gloTrigPat|= 0x1;
648   if (gloTrg->SinglePlusHpt())  gloTrigPat|= 0x2;
649   if (gloTrg->SinglePlusApt())  gloTrigPat|= 0x4;
650  
651   if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
652   if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
653   if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
654  
655   if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
656   if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
657   if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
658  
659   if (gloTrg->PairUnlikeLpt())  gloTrigPat|= 0x200;
660   if (gloTrg->PairUnlikeHpt())  gloTrigPat|= 0x400;
661   if (gloTrg->PairUnlikeApt())  gloTrigPat|= 0x800;
662
663   if (gloTrg->PairLikeLpt())    gloTrigPat|= 0x1000;
664   if (gloTrg->PairLikeHpt())    gloTrigPat|= 0x2000;
665   if (gloTrg->PairLikeApt())    gloTrigPat|= 0x4000;
666
667   return gloTrigPat;
668 }