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