]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawData.cxx
Updated for replacement of AliMpReader with AliMpSectorReader
[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 and reader in ALICE-MUON
19 // This class version 1 (further details could be found in Alice-note)
20 // Digits2Raw:
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 // Ch. Finck july 04
27 // Raw2Digits:
28 // Using still dummy mapping (inverse) for tracker
29 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
30 ////////////////////////////////////
31
32 #include <TClonesArray.h>
33 #include "AliMUONRawData.h"
34 #include "AliMUONDigit.h"
35
36 #include "AliMUON.h"
37 #include "AliMUONChamber.h"
38 #include "AliMUONConstants.h"
39 #include "AliMUONData.h"
40 #include "AliLoader.h"
41 #include "AliBitPacking.h" 
42 #include "AliRawReader.h"
43
44 #include "AliMUONSubEventTrigger.h"
45 #include "AliMUONDDLTracker.h"
46 #include "AliMUONDDLTrigger.h"
47
48 #include "AliMUONLocalTrigger.h"
49 #include "AliMUONGlobalTrigger.h"
50
51 #include "AliMUONGeometrySegmentation.h"
52 #include "AliLog.h"
53 #include "AliRun.h"
54
55
56
57 ClassImp(AliMUONRawData) // Class implementation in ROOT context
58 //__________________________________________________________________________
59   AliMUONRawData::AliMUONRawData(AliLoader* loader)
60   : TObject()
61 {
62   // Standard Constructor
63  
64   // initialize loader's
65   fLoader = loader;
66
67   // initialize container
68   fMUONData  = new AliMUONData(fLoader,"MUON","MUON");
69
70   // initialize array
71   fSubEventArray[0] = new TClonesArray("AliMUONSubEventTracker",1000);
72   fSubEventArray[1] = new TClonesArray("AliMUONSubEventTracker",1000);
73
74
75   // ddl pointer
76   fDDLTracker = new AliMUONDDLTracker();
77   fDDLTrigger = new AliMUONDDLTrigger();
78 }
79
80 //__________________________________________________________________________
81 AliMUONRawData::AliMUONRawData()
82   : TObject(),
83     fMUONData(0),
84     fLoader(0),
85     fFile1(0x0),
86     fFile2(0x0),
87     fDDLTracker(0),
88     fDDLTrigger(0)
89
90 {
91   // Default Constructor
92 }
93
94 //_______________________________________________________________________
95 AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
96   : TObject(rhs)
97 {
98 // Protected copy constructor
99
100   AliFatal("Not implemented.");
101 }
102
103 //_______________________________________________________________________
104 AliMUONRawData & 
105 AliMUONRawData::operator=(const AliMUONRawData& rhs)
106 {
107 // Protected assignement operator
108
109   if (this == &rhs) return *this;
110
111   AliFatal("Not implemented.");
112     
113   return *this;  
114 }
115
116 //__________________________________________________________________________
117 AliMUONRawData::~AliMUONRawData(void)
118 {
119   if (fMUONData)
120     delete fMUONData;
121   if (fSubEventArray[0])
122     fSubEventArray[0]->Delete(); //using delete cos allocating memory in copy ctor.
123   if (fSubEventArray[1])
124     fSubEventArray[1]->Delete();
125
126   if (fDDLTracker)
127     delete fDDLTracker;
128   if (fDDLTrigger)
129     delete fDDLTrigger;
130
131   return;
132 }
133 //____________________________________________________________________
134 Int_t AliMUONRawData::Digits2Raw()
135 {
136  // convert digits of the current event to raw data
137
138   Int_t idDDL;
139   Char_t name[20];
140
141   fLoader->LoadDigits("READ");
142
143   fMUONData->SetTreeAddress("D,GLT");
144
145
146   // tracking chambers
147
148   for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
149  
150     // open files
151     idDDL = ich * 2  + 0x900;
152     sprintf(name, "MUON_%d.ddl",idDDL);
153     fFile1 = fopen(name,"w");
154
155     idDDL = (ich * 2) + 1 + 0x900;
156     sprintf(name, "MUON_%d.ddl",idDDL);
157     fFile2 = fopen(name,"w");
158
159     WriteTrackerDDL(ich);
160   
161     // reset and close
162     fclose(fFile1);
163     fclose(fFile2);
164     fMUONData->ResetDigits();
165   }
166  
167   // trigger chambers
168  
169   // open files
170   idDDL = 0xA00;
171   sprintf(name, "MUTR_%d.ddl",idDDL);
172   fFile1 = fopen(name,"w");
173
174   idDDL = 0xA00 + 1;
175   sprintf(name, "MUTR_%d.ddl",idDDL);
176   fFile2 = fopen(name,"w");
177
178   WriteTriggerDDL();
179   
180   // reset and close
181   fclose(fFile1);
182   fclose(fFile2);
183   fMUONData->ResetTrigger();
184   
185   fLoader->UnloadDigits();
186
187   return kTRUE;
188 }
189 //____________________________________________________________________
190 Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
191 {
192   // resets
193   TClonesArray* muonDigits = 0;
194   fSubEventArray[0]->Clear();
195   fSubEventArray[1]->Clear();
196
197   //
198   TArrayI nbInBus[2];
199
200   nbInBus[0].Set(5000);
201   nbInBus[1].Set(5000);
202
203   nbInBus[0].Reset();
204   nbInBus[1].Reset();
205
206   // DDL header
207   AliRawDataHeader header = fDDLTracker->GetHeader();
208   Int_t headerSize = fDDLTracker->GetHeaderSize();
209
210   // DDL event one per half chamber
211   AliMUONSubEventTracker* subEvent;
212
213   // data format
214   Char_t parity = 0x4;
215   UShort_t manuId = 0;
216   UChar_t channelId = 0;
217   UShort_t charge = 0;
218   Int_t busPatchId = 0;
219
220   UInt_t word;
221   Int_t nEntries = 0;
222   Int_t* buffer = 0;
223   Int_t index;
224   Int_t indexDsp;
225   Int_t indexBlk;
226   Int_t padX;
227   Int_t padY;
228   Int_t cathode = 0;
229   Int_t detElemId;
230   Int_t nDigits;
231   const AliMUONDigit* digit;
232
233 //   AliMUON *pMUON;
234 //   AliMUONChamber* iChamber = 0x0;
235 //   AliMUONGeometrySegmentation* segmentation2[2];
236
237 //   pMUON = (AliMUON*) gAlice->GetModule("MUON");
238 //   iChamber =  &(pMUON->Chamber(iCh));
239
240 //   segmentation2[0]=iChamber->SegmentationModel2(1); // cathode 0
241 //   segmentation2[1]=iChamber->SegmentationModel2(2); // cathode 1
242
243    AliDebug(1, Form("WriteDDL chamber %d\n", iCh+1));
244
245    //  for (Int_t iCath = 0; iCath < 2; iCath++) {
246
247     fMUONData->ResetDigits();
248     fMUONData->GetDigits();
249     muonDigits = fMUONData->Digits(iCh);
250
251     nDigits = muonDigits->GetEntriesFast();
252     AliDebug(2,Form("ndigits = %d\n",nDigits));
253
254     // open DDL file, on per 1/2 chamber
255  
256     for (Int_t idig = 0; idig < nDigits; idig++) {
257
258       digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
259
260       padX = digit->PadX();
261       padY = digit->PadY();
262       charge = digit->Signal();
263       charge &= 0xFFF;
264       cathode = digit->Cathode();
265       detElemId = digit->DetElemId();
266
267       // mapping
268 //       if (detElemId == 0) {
269 //      AliWarning("\ndetElemId = 0, old segmentation !\n");
270         GetDummyMapping(iCh, cathode, digit, busPatchId, manuId, channelId);
271 //       } else {
272 //       // mapping (not far from real one)
273 //      AliMUONSegmentManuIndex* connect = segmentation2[iCath]->GetMpConnection(detElemId, padX, padY);
274 //      if (connect != 0x0) {
275 //        busPatchId = connect->GetBusPatchId(); 
276 //        manuId     = connect->GetManuId();
277 //        channelId  = connect->GetManuChannelId();
278 //        AliDebug(3,Form("busPatchId %d, manuId: %d, channelId: %d\n", busPatchId, manuId, channelId));
279 //      } else {
280 //        busPatchId = 0; 
281 //        manuId     = 0;
282 //        channelId  = 0;
283 //      }
284
285 //       }
286       //packing word
287       AliBitPacking::PackWord((UInt_t)parity,word,29,31);
288       AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
289       AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
290       AliBitPacking::PackWord((UInt_t)charge,word,0,11);
291
292       // set sub Event
293       subEvent = new AliMUONSubEventTracker();
294       subEvent->AddData(word);
295       subEvent->SetBusPatchId(busPatchId);
296       if (digit->PadX() > 0) {
297         nbInBus[0][busPatchId]++;
298         AddData1(subEvent);
299       } else {
300         nbInBus[1][busPatchId]++;
301         AddData2(subEvent);
302       }
303       delete subEvent;
304     }
305     //   }
306   fSubEventArray[0]->Sort();
307   fSubEventArray[1]->Sort();
308
309   // gather datas from same bus patch
310    for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
311     nEntries = fSubEventArray[iDDL]->GetEntriesFast();
312
313     for (Int_t i = 0; i < nEntries; i++) {
314       AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
315       busPatchId = temp->GetBusPatchId();
316
317       // add bus patch header, length and total length managed by subevent class
318       temp->SetTriggerWord(0xdeadbeef);
319       for (Int_t j = 0; j < nbInBus[iDDL][busPatchId]-1; j++) {
320         AliMUONSubEventTracker* temp1 =  (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(++i);
321         temp->AddData(temp1->GetData(0));
322         fSubEventArray[iDDL]->RemoveAt(i) ;
323       }
324     }
325     fSubEventArray[iDDL]->Compress();
326
327     if (AliLog::GetGlobalDebugLevel() == 3) {
328       nEntries = fSubEventArray[iDDL]->GetEntriesFast();
329       for (Int_t i = 0; i < nEntries; i++) {
330         AliMUONSubEventTracker* temp =  (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
331         printf("busPatchid back %d\n",temp->GetBusPatchId());
332         for (Int_t j = 0; j < temp->GetLength(); j++) {
333           printf("manuId back %d, ",temp->GetManuId(j));
334           printf("channelId back %d, ",temp->GetChannelId(j));
335           printf("charge back %d\n",temp->GetCharge(j));
336         }
337       }
338       printf("\n");
339     }
340   
341    }
342   
343   Int_t iBusPatch;
344   Int_t iEntries;
345   Int_t length;
346
347   for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
348  
349
350     // filling buffer
351     nEntries = fSubEventArray[iDDL]->GetEntriesFast();
352     buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
353
354     indexBlk = 0;
355     indexDsp = 0;
356     index = 0;
357     iBusPatch = 0;
358     iEntries = 0;
359
360     for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
361
362       // block header
363       //    fDDLTracker->SetTotalBlkLength(0xFFFFFFFF);
364       length = fDDLTracker->GetBlkHeaderLength();
365       memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
366       indexBlk = index;
367       index += length; 
368
369       for (Int_t iDsp = 0; iDsp < 5; iDsp++) {
370
371         // DSP header
372         //      fDDLTracker->SetTotalDspLength(0xEEEEEEEE);
373         length = fDDLTracker->GetDspHeaderLength();
374         memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
375         indexDsp = index;
376         index += length; 
377
378         for (Int_t i = 0; i < 5; i++) {
379
380           iBusPatch = i + iBlock*25 + iDsp*5 + 50*(2*iCh + iDDL);
381
382           AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(iEntries);
383           if (nEntries > 0) 
384             busPatchId = temp->GetBusPatchId();
385            else
386             busPatchId = -1;
387
388           if (busPatchId == iBusPatch) {
389             // add bus patch structure
390             length = temp->GetHeaderLength();
391             memcpy(&buffer[index],temp->GetAddress(),length*4);
392             index += length;
393             for (Int_t j = 0; j < temp->GetLength(); j++) 
394               buffer[index++] =  temp->GetData(j);
395             if (iEntries < nEntries-1)
396               iEntries++;
397           } else {
398             buffer[index++] = 4; // total length
399             buffer[index++] = 0; // raw data length
400             buffer[index++] = iBusPatch; // bus patch
401             buffer[index++] = 0xdeadbeef; // trigger word
402           }
403         } // bus patch
404         buffer[indexDsp] = index - indexDsp; // dsp length
405         buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
406         if ((index - indexDsp) % 2 == 0)
407           buffer[indexDsp+7] = 0;
408         else
409           buffer[indexDsp+7] = 1;
410       } // dsp
411       buffer[indexBlk] = index - indexBlk; // block length
412       buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
413     }
414     if (iDDL == 0) {
415       // write DDL 1
416       header.fSize = (index + headerSize) * 4;// total length in bytes
417       fwrite((char*)(&header),headerSize*4,1,fFile1);
418       fwrite(buffer,sizeof(int),index,fFile1);
419     } 
420     if (iDDL == 1) {
421       // write DDL 2
422       header.fSize = (index + headerSize) * 4;// total length in bytes
423       fwrite((char*)(&header),headerSize*4,1,fFile2);
424       fwrite(buffer,sizeof(int),index,fFile2);
425     }
426     delete[] buffer;
427   }
428
429   return kTRUE;
430 }
431 //____________________________________________________________________
432 Int_t AliMUONRawData::WriteTriggerDDL()
433 {
434
435  // DDL event one per half chamber
436   AliMUONSubEventTrigger* subEvent = 0x0;
437
438
439   // stored local id number 
440   TArrayI isFired(256);
441   isFired.Reset();
442
443
444  // DDL header
445   AliRawDataHeader header = fDDLTrigger->GetHeader();
446   Int_t headerSize = fDDLTrigger->GetHeaderSize();
447   Int_t length;
448   TClonesArray* localTrigger;
449   TClonesArray* globalTrigger;
450   AliMUONGlobalTrigger* gloTrg;
451   AliMUONLocalTrigger* locTrg = 0x0;
452
453   fMUONData->GetTriggerD();
454
455   // global trigger for trigger pattern
456   globalTrigger = fMUONData->GlobalTrigger(); 
457   gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
458   Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
459
460   // local trigger 
461   localTrigger = fMUONData->LocalTrigger();    
462
463   UInt_t word;
464   Int_t* buffer = 0;
465   Int_t index;
466   Int_t iEntries = 0;
467   Int_t iLocCard, locCard;
468   Char_t locDec, trigY, posY, devX, posX,regOut;
469   Int_t version = 1; // software version
470   Int_t eventType = 1; // trigger type: 1 for physics ?
471   Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
472   Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
473
474   Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
475   // stored the local card id that's fired
476   for (Int_t i = 0; i <  nEntries; i++) {
477     locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
478     isFired[locTrg->LoCircuit()] = 1;
479   }
480
481   if (!nEntries)
482     AliError("No Trigger information available");
483
484   buffer = new Int_t [672]; // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
485
486   for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
487     
488     index = 0; 
489
490     // DDL enhanced header
491     word = 0;
492     AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
493     AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
494     AliBitPacking::PackWord((UInt_t)version,word,16,23);
495     AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
496
497     if (iDDL == 0) // suppose global info in DDL one
498       globalFlag = 2;
499     else 
500       globalFlag = 1;
501     AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
502     fDDLTrigger->SetDDLWord(word);
503
504     if (iDDL == 0)
505       fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
506     else 
507       fDDLTrigger->SetGlobalOutput(0);
508     length = fDDLTrigger->GetHeaderLength(); 
509     memcpy(&buffer[index],fDDLTrigger->GetEnhancedHeader(),length*4);
510     index += length; 
511
512     for (Int_t iReg = 0; iReg < 8; iReg++) {
513
514       subEvent = new AliMUONSubEventTrigger();
515
516       // Regional card header
517       word = 0;
518       regOut  = 0;
519       AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see  AliMUONSubEventTrigger.h for details
520       AliBitPacking::PackWord((UInt_t)version,word,16,23);
521       AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
522       AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
523
524       subEvent->SetRegWord(word);
525       memcpy(&buffer[index++],subEvent->GetAddress(),4);
526
527       buffer[index++] = 0;// 2 words of regional input
528       buffer[index++] = 0;
529
530       for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
531
532         iLocCard = iLoc + iReg*16 + iDDL*128;
533
534         if (isFired[iLocCard]) {
535           locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
536           locCard = locTrg->LoCircuit();
537           locDec = locTrg->GetLoDecision();
538           trigY = 0;
539           posY = locTrg->LoStripY();
540           posX = locTrg->LoStripX();
541           devX = locTrg->LoDev();
542           AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", 
543                           locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
544         } else { //no trigger (see PRR chpt 3.4)
545           locCard = -1;
546           locDec = 0;
547           trigY = 1;
548           posY = 15;
549           posX = 0;
550           devX = 0x8000;
551         }
552
553         //packing word
554         word = 0;
555         AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
556         AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
557         AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
558         AliBitPacking::PackWord((UInt_t)posY,word,10,13);
559         AliBitPacking::PackWord((UInt_t)devX,word,5,9);
560         AliBitPacking::PackWord((UInt_t)posX,word,0,4);
561
562         if (locCard == iLocCard) {
563           // add local cards structure
564           buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
565           buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
566           buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
567           buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
568           buffer[index++] = (Int_t)word; // data word
569           if (iEntries < nEntries-1)
570             iEntries++;
571         } else {
572           buffer[index++] = 0; // 4 words for x1, x2, y1, y2
573           buffer[index++] = 0; 
574           buffer[index++] = 0; 
575           buffer[index++] = 0; 
576           buffer[index++] = (Int_t)word; // data word
577
578         }
579       } // local card 
580
581       delete subEvent;  
582
583     } // Regional card
584     
585     buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
586     buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
587
588     
589     if (iDDL == 0) {
590       // write DDL 1
591       header.fSize = (index + headerSize) * 4;// total length in bytes
592       fwrite((char*)(&header),headerSize*4,1,fFile1);
593       fwrite(buffer,sizeof(int),index,fFile1);
594     } 
595     if (iDDL == 1) {
596       // write DDL 2
597       header.fSize = (index + headerSize) * 4;// total length in bytes
598       fwrite((char*)(&header),headerSize*4,1,fFile2);
599       fwrite(buffer,sizeof(int),index,fFile2);
600     }
601   }
602   delete[] buffer;
603
604   return kTRUE;
605 }
606 //____________________________________________________________________
607 void AliMUONRawData::GetDummyMapping(Int_t iCh, Int_t iCath, const AliMUONDigit* digit,
608                                      Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId)
609 {
610 // Dummy mapping for tracker
611
612   Int_t offsetX = 0; // offet row
613   Int_t offsetY = 0; // offset columns
614   Int_t offsetCath = 0; //offset from one cathod to the other
615   Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
616   Int_t id;
617       switch (iCh+1) {
618       case 1:
619       case 2:
620       case 3:
621       case 4:
622         offsetX = 512;
623         offsetY = 256;
624         offsetCath = 65536;
625         maxChannel = (offsetY * offsetX + 2* offsetY + offsetCath);
626         break;
627       case 5:
628       case 6:
629       case 7:
630       case 8:
631       case 9:
632       case 10:
633         offsetX = 1024;
634         offsetY = 0;
635         offsetCath = 65536;
636         maxChannel = (256 * offsetX + offsetX + offsetCath);
637         break;
638       }
639       // dummy mapping
640       // manu Id directly from a matrix 8*8, same segmentation for B and NB
641       // 50 buspatches for 1/2 chamber
642
643       id =  (TMath::Abs(digit->PadX()) * offsetX + digit->PadY() + offsetY +
644              offsetCath * iCath);
645       Int_t chPerBus = maxChannel/50;
646       busPatchId = id/chPerBus; // start at zero 
647       if (digit->PadX() > 0)
648         busPatchId += 50*iCh*2;
649       else 
650         busPatchId += 50*(2*iCh+1);
651       // 64 manu cards for one buspatch
652       manuId = (id % chPerBus)/64; //start at zero 
653       manuId &= 0x7FF; // 11 bits 
654
655       // channel id
656       channelId = (id % chPerBus) % 64; //start at zero 
657       channelId &= 0x3F; // 6 bits
658
659      
660       AliDebug(2,Form("id: %d, busPatchId %d, manuId: %d, channelId: %d, maxchannel: %d, chPerBus %d\n",
661                       id, busPatchId, manuId, channelId, maxChannel, chPerBus));
662
663       AliDebug(2,Form("id: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d, charge %d\n",
664                       id, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal()));
665
666 }
667
668 //____________________________________________________________________
669 Int_t AliMUONRawData::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg)
670 {
671   // global trigger pattern calculation
672
673   Int_t gloTrigPat = 0;
674
675   if (gloTrg->SinglePlusLpt())  gloTrigPat|= 0x1;
676   if (gloTrg->SinglePlusHpt())  gloTrigPat|= 0x2;
677   if (gloTrg->SinglePlusApt())  gloTrigPat|= 0x4;
678  
679   if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
680   if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
681   if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
682  
683   if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
684   if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
685   if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
686  
687   if (gloTrg->PairUnlikeLpt())  gloTrigPat|= 0x200;
688   if (gloTrg->PairUnlikeHpt())  gloTrigPat|= 0x400;
689   if (gloTrg->PairUnlikeApt())  gloTrigPat|= 0x800;
690
691   if (gloTrg->PairLikeLpt())    gloTrigPat|= 0x1000;
692   if (gloTrg->PairLikeHpt())    gloTrigPat|= 0x2000;
693   if (gloTrg->PairLikeApt())    gloTrigPat|= 0x4000;
694
695   return gloTrigPat;
696 }
697
698 //____________________________________________________________________
699 Int_t AliMUONRawData::Raw2Digits(AliRawReader* rawReader)
700 {
701
702   // generate digits
703   ReadTrackerDDL(rawReader);
704
705   // generate trigger
706   ReadTriggerDDL(rawReader);
707
708   return kTRUE;
709
710 }
711
712 //____________________________________________________________________
713 Int_t AliMUONRawData::ReadTrackerDDL(AliRawReader* rawReader)
714 {
715
716   AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
717   AliMUONDigit* digit = new AliMUONDigit();
718
719
720   //Read Header Size of DDL,Block,DSP and BusPatch.
721
722   Int_t ddlHeaderSize      = fDDLTracker->GetHeaderSize();
723   Int_t blockHeaderSize    = fDDLTracker->GetBlkHeaderLength();
724   Int_t dspHeaderSize      = fDDLTracker->GetDspHeaderLength();
725   Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
726
727 //   Each DDL is made with 2 Blocks each of which consists of 5 DSP and each of DSP has at most 5 buspatches.
728 //   This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data. 
729
730   const Int_t blankDDLSize   = ddlHeaderSize + 2*blockHeaderSize + 2*5*dspHeaderSize + 2*5*5*buspatchHeaderSize;
731   const Int_t blankBlockSize = blockHeaderSize + 5*dspHeaderSize + 5*5*buspatchHeaderSize;
732   const Int_t blankDspSize   = dspHeaderSize + 5*buspatchHeaderSize;
733
734   Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize; 
735
736
737   for(Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++){                // loops over tracking chambers
738
739     UShort_t  charge; 
740     Int_t padX, padY,iCath;
741
742     for(Int_t iDDL = 0; iDDL < 2; iDDL++){                                         // DDL loop
743
744       //rawReader = new AliRawReaderFile(iEvent);
745       rawReader->Select(0X9,(2*iCh)+iDDL,(2*iCh)+iDDL);  //Select the DDL file to be read  
746
747       rawReader->ReadHeader();
748
749       totalDDLSize = (rawReader->GetDataSize()+sizeof(AliRawDataHeader))/4; // 4 is multipiled to convert byte 2 word
750
751       if(totalDDLSize>blankDDLSize){      // Compare the DDL header with an empty DDL header size to read the file
752
753
754         Int_t totalDataWord = rawReader->GetDataSize()/4 ;
755         UInt_t *buffer = new UInt_t[totalDataWord];
756         for(Int_t i=0;i<totalDataWord;i++){
757           UInt_t& temp = buffer[i]; 
758            rawReader->ReadNextInt(temp);      // takes the whole result into buffer variable for future analysis
759         }
760
761         Char_t parity;
762         Int_t buspatchId;
763         UChar_t channelId;
764         UShort_t  manuId;//,charge; 
765         Int_t id;//,padX, padY,iCath;
766         Int_t indexDsp, indexBusPatch, index = 0;
767
768
769         for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){  // loop over 2 blocks
770           totalBlockSize = buffer[index];
771           
772           if(totalBlockSize > blankBlockSize){        // compare block header
773             index += blockHeaderSize;
774
775             for(Int_t iDsp = 0; iDsp < 5 ;iDsp++){   //DSP loop
776               totalDspSize = buffer[index];
777               indexDsp = index;
778
779               if(totalDspSize > blankDspSize){       // Compare DSP Header
780                 index += dspHeaderSize;
781                 
782                 for(Int_t iBusPatch = 0; iBusPatch < 5 ; iBusPatch++){  
783                   totalBusPatchSize = buffer[index];
784                   indexBusPatch = index;
785                   buspatchId = buffer[index+2];
786
787                   if(totalBusPatchSize > buspatchHeaderSize){    //Check Buspatch header
788                     index += buspatchHeaderSize;
789                     dataSize = totalBusPatchSize - buspatchHeaderSize;
790
791                     if(dataSize>0) {
792
793                       for(Int_t iData = 0; iData < dataSize ;iData++) {
794
795                         subEventTracker->SetData(buffer[index++],iData);   //Set to extract data
796                         parity = subEventTracker->GetParity(iData);
797                         manuId = subEventTracker->GetManuId(iData);
798                         channelId = subEventTracker->GetChannelId(iData);
799                         charge = subEventTracker->GetCharge(iData);
800                         digit->AddSignal(charge); // set charge
801
802                         GetInvDummyMapping(iCh,buspatchId,manuId,channelId,digit); // Get Back the hits at pads
803                         padX = digit->PadX();
804                         padY = digit->PadY();
805                         iCath = digit->Cathode();  
806                         id = digit->DetElemId();
807
808                         // fill digits
809                         fMUONData->AddDigit(iCh, *digit);
810
811                       } // data loop
812                     } // dataSize test
813                   } // testing buspatch
814
815                   index = indexBusPatch + totalBusPatchSize;
816
817                 }  //buspatch loop
818                 
819                 
820               }  // dsp test
821
822               index = indexDsp + totalDspSize;
823               
824             }  // dsp loop
825
826           }   //block test
827
828           index = totalBlockSize;
829
830         }  //block loop
831
832         delete []buffer;
833       } //loop checking the header size of DDL
834
835       //delete rawReader;
836     } // DDL loop
837
838   } // Chamber loop
839
840   delete subEventTracker;
841   delete digit;
842
843   return kTRUE;
844 }
845
846 //____________________________________________________________________
847 void AliMUONRawData:: GetInvDummyMapping(Int_t iCh, Int_t buspatchId, UShort_t manuId, 
848                                          UChar_t channelId, AliMUONDigit* digit )
849 {
850   Int_t offsetX = 0; // offet row
851   Int_t offsetY = 0; // offset columns
852   Int_t offsetCath = 0; //offset from one cathod to the other
853   Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
854   //Int_t id;
855   Bool_t flag;
856   switch (iCh+1) {
857   case 1:
858   case 2:
859   case 3:
860   case 4:
861     offsetX = 512;
862     offsetY = 256;
863     offsetCath = 65536;
864     maxChannel = (offsetY * offsetX + 2* offsetY + offsetCath);
865     break;
866   case 5:
867   case 6:
868   case 7:
869   case 8:
870   case 9:
871   case 10:
872     offsetX = 1024;
873     offsetY = 0;
874     offsetCath = 65536;
875     maxChannel = (256 * offsetX + offsetX + offsetCath);
876     break;
877   }
878   // dummy mapping
879   // manu Id directly from a matrix 8*8, same segmentation for B and NB
880   // 50 buspatches for 1/2 chamber
881   
882   if(buspatchId >= 50*(2*iCh + 1)){          // condn to find the sign of padX
883     buspatchId = buspatchId - 50*(2*iCh + 1);
884     flag = kTRUE;
885   }
886   else{
887     buspatchId = buspatchId - 50*2*iCh;
888     flag = kFALSE;
889   }
890   
891   Int_t chPerBus = maxChannel/50;
892   
893   Int_t id = buspatchId*chPerBus + 64*manuId + channelId;
894   Int_t iCath, padX,padY;
895   if(id >= (offsetY + offsetCath))           // find cathode plane
896     iCath = 1;
897   else
898     iCath = 0;
899   
900   if(iCh<4)
901     padX = TMath::Nint((Float_t)(id - offsetY - offsetCath*iCath)/offsetX);
902   else
903     padX = (id - offsetY - offsetCath*iCath)/offsetX;
904   
905   padY = id - (padX*offsetX + offsetY + offsetCath*iCath);
906   
907   if(flag)                                 //Detect the sign of padX
908     padX = -padX;
909   else
910     padX = padX;
911   
912   digit->SetPadX(padX);
913   digit->SetPadY(padY);
914   digit->SetCathode(iCath);
915   digit->SetDetElemId(id);
916
917   return;
918 }
919
920 //____________________________________________________________________
921 Int_t AliMUONRawData::ReadTriggerDDL(AliRawReader* rawReader)
922 {
923   AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
924   AliMUONGlobalTrigger* globalTrigger = 0x0;
925   AliMUONLocalTrigger* localTrigger = new  AliMUONLocalTrigger();
926
927
928   //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize();    // we dont need this, as size of ddl data is same for triger and no trigger
929
930   Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength(); 
931   Int_t regHeaderLength      = subEventTrigger->GetRegHeaderLength() ;
932
933   Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
934   Char_t loDecision; 
935
936   UShort_t X1Pattern, X2Pattern, X3Pattern, X4Pattern;
937   UShort_t Y1Pattern, Y2Pattern, Y3Pattern, Y4Pattern;
938
939
940   for(Int_t iDDL = 0; iDDL < 2; iDDL++){                        //DDL loop
941
942     rawReader->Select(0XA,iDDL,iDDL);  //Select the DDL file to be read  
943
944     rawReader->ReadHeader();
945
946     Int_t totalDataWord = rawReader->GetDataSize()/4 ;
947     UInt_t *buffer = new UInt_t[totalDataWord];
948     for(Int_t i=0;i<totalDataWord;i++){
949       UInt_t& temp = buffer[i]; 
950       rawReader->ReadNextInt(temp);      // takes the whole result into buffer variable for future analysis
951     }
952
953     // rawReader->ReadNext((UChar_t*)buffer, totalDataWord);     // method is protected ????
954   
955     Int_t index = 0;
956
957     // fill DDL header informations
958     memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4); 
959
960     // fill global trigger information
961     globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
962     fMUONData->AddGlobalTrigger(*globalTrigger);
963
964     index += ddlEnhanceHeaderSize;
965
966     for (Int_t iReg = 0; iReg < 8; iReg++) {           //loop over regeonal card
967
968
969       subEventTrigger->SetRegWord(buffer[index]);      //read regional data 
970
971       index += regHeaderLength;
972
973       for (Int_t iLoc = 0; iLoc < 16; iLoc++) {         //loop over local card
974           
975         Int_t iLocIndex = index;
976
977         for(Int_t iData = 0; iData < 5 ;iData++ ){
978           subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData);   //read local data
979         }
980
981         if(buffer[iLocIndex] > 0) {
982
983           loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL; 
984           loStripX =  (Int_t)subEventTrigger->GetXPos(iLoc);
985           loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
986           loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
987             
988           // fill local trigger
989           localTrigger->SetLoCircuit(loCircuit);
990           localTrigger->SetLoStripX(loStripX );
991           localTrigger->SetLoStripY(loStripY);
992           localTrigger->SetLoDev(loDev);
993
994           loDecision = subEventTrigger->GetLocalDec(iLoc);
995           loLpt =  loDecision       & 0x3;
996           loHpt = (loDecision >> 2) & 0x3; 
997             
998           // fill local trigger
999           localTrigger->SetLoLpt(loLpt);
1000           localTrigger->SetLoHpt(loHpt);
1001
1002
1003           X1Pattern = subEventTrigger->GetX1(iLoc);
1004           X2Pattern = subEventTrigger->GetX2(iLoc);
1005           X3Pattern = subEventTrigger->GetX3(iLoc);
1006           X4Pattern = subEventTrigger->GetX4(iLoc);
1007             
1008           Y1Pattern = subEventTrigger->GetY1(iLoc);
1009           Y2Pattern = subEventTrigger->GetY2(iLoc);
1010           Y3Pattern = subEventTrigger->GetY3(iLoc);
1011           Y4Pattern = subEventTrigger->GetY4(iLoc);
1012
1013           // fill local trigger
1014           localTrigger->SetX1Pattern(X1Pattern);
1015           localTrigger->SetX2Pattern(X2Pattern);
1016           localTrigger->SetX3Pattern(X3Pattern);
1017           localTrigger->SetX4Pattern(X4Pattern);
1018
1019           localTrigger->SetY1Pattern(Y1Pattern);
1020           localTrigger->SetY2Pattern(Y2Pattern);
1021           localTrigger->SetY3Pattern(Y3Pattern);
1022           localTrigger->SetY4Pattern(Y4Pattern);
1023           fMUONData->AddLocalTrigger(*localTrigger);
1024
1025         }
1026           
1027       } // local card loop
1028         
1029     } // regeinal card loop
1030       
1031     delete [] buffer;
1032     //delete rawReader;
1033   } // DDL loop
1034
1035
1036   delete subEventTrigger;
1037   delete globalTrigger;
1038   delete localTrigger;
1039
1040   return kTRUE;
1041
1042 }
1043 //____________________________________________________________________
1044 AliMUONGlobalTrigger* AliMUONRawData::GetGlobalTriggerPattern(Int_t gloTrigPat)
1045 {
1046   // global trigger pattern calculation
1047
1048   Int_t globalSinglePlus[3];  // tot num of single plus
1049   Int_t globalSingleMinus[3]; // tot num of single minus
1050   Int_t globalSingleUndef[3]; // tot num of single undefined
1051   Int_t globalPairUnlike[3];  // tot num of unlike-sign pairs
1052   Int_t globalPairLike[3];    // tot num of like-sign pairs
1053
1054
1055   for (Int_t i = 0; i < 3; i++) {
1056     globalSinglePlus[i]  = gloTrigPat & (0x1 << i);
1057     globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
1058     globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
1059     globalPairUnlike[i]  = gloTrigPat & (0x1 << i+9);
1060     globalPairLike[i]    = gloTrigPat & (0x1 << i+12);
1061   }
1062
1063   return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
1064                                                        globalSingleUndef, globalPairUnlike, 
1065                                                         globalPairLike));  
1066
1067 }