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