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