- Class description on 5 lines (Coding conventions)
[u/mrichter/AliRoot.git] / MUON / AliMUONRawReader.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 reader in ALICE-MUON
19 // 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 //
26 // Raw2Digits:
27 // Using real mapping  for tracker
28 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
29 // Add reader for scaler trigger events
30 // Use memcpy instead of assignment elt by elt
31 // (Ch. Finck, Jan 06)
32 // 
33 ////////////////////////////////////
34
35 #include <fstream>
36 #include <string>
37
38 #include <TClonesArray.h>
39
40 #include "AliBitPacking.h" 
41 #include "AliRawReader.h"
42 #include "AliLog.h"
43 #include "AliRun.h"
44
45 #include "AliMpBusPatch.h"
46
47 #include "AliMUON.h"
48 #include "AliMUONRawReader.h"
49 #include "AliMUONDigit.h"
50
51 #include "AliMUONConstants.h"
52 #include "AliMUONData.h"
53
54 #include "AliMUONSubEventTracker.h"
55 #include "AliMUONScalerEventTrigger.h"
56 #include "AliMUONSubEventTrigger.h"
57 #include "AliMUONDDLTracker.h"
58 #include "AliMUONDDLTrigger.h"
59
60 #include "AliMUONLocalTrigger.h"
61 #include "AliMUONGlobalTrigger.h"
62
63 #include "AliMUONGeometrySegmentation.h"
64 #include "AliMUONGeometryModule.h"
65 #include "AliMUONGeometryStore.h"
66 #include "AliMpSegFactory.h"
67 #include "AliMpPlaneType.h"
68 #include "AliMpVSegmentation.h"
69 #include "AliMpHelper.h"
70 #include "AliMpPad.h"
71 #include "AliMpDEManager.h"
72
73 ClassImp(AliMUONRawReader) // Class implementation in ROOT context
74 //__________________________________________________________________________
75 AliMUONRawReader::AliMUONRawReader(AliMUONData* data)
76 : TObject(),
77   fScalerEvent(kFALSE)
78 {
79 // Standard Constructor
80  
81   AliDebug(1,"");
82       
83   // initialize segmentation factory
84   fSegFactory = new AliMpSegFactory();
85
86   // initialize container
87   fMUONData  = data;
88
89   // ddl pointer
90   fDDLTracker = new AliMUONDDLTracker();
91   fDDLTrigger = new AliMUONDDLTrigger();
92
93   fBusPatchManager = new AliMpBusPatch();
94   fBusPatchManager->ReadBusPatchFile();
95
96   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
97   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
98   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
99 }
100
101 //__________________________________________________________________________
102 AliMUONRawReader::AliMUONRawReader()
103   : TObject(),
104     fMUONData(0),
105     fSegFactory(0),
106     fDDLTracker(0),
107     fDDLTrigger(0),
108     fBusPatchManager(0),
109     fScalerEvent(kFALSE)
110 {
111   // Default Constructor
112       AliDebug(1,""); 
113       fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
114       fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
115       fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
116 }
117
118 //_______________________________________________________________________
119 AliMUONRawReader::AliMUONRawReader (const AliMUONRawReader& rhs)
120   : TObject(rhs)
121 {
122 // Protected copy constructor
123
124   AliFatal("Not implemented.");
125 }
126
127 //_______________________________________________________________________
128 AliMUONRawReader & 
129 AliMUONRawReader::operator=(const AliMUONRawReader& rhs)
130 {
131 // Protected assignement operator
132
133   if (this == &rhs) return *this;
134
135   AliFatal("Not implemented.");
136     
137   return *this;  
138 }
139
140 //__________________________________________________________________________
141 AliMUONRawReader::~AliMUONRawReader()
142 {
143 // Destructor
144
145   delete fSegFactory;  
146
147   delete fDDLTracker;
148   delete fDDLTrigger;
149
150   delete fBusPatchManager;
151   
152   AliInfo(Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
153                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
154   AliInfo(Form("   Execution time for MUON tracker (mapping calls part) "
155                ": R:%.2fs C:%.2fs",
156                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
157   AliInfo(Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
158                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
159
160 }
161
162 //____________________________________________________________________
163 Int_t AliMUONRawReader::Raw2Digits(AliRawReader* rawReader)
164 {
165
166   // generate digits
167   ReadTrackerDDL(rawReader);
168
169   // generate trigger
170   ReadTriggerDDL(rawReader);
171
172   return kTRUE;
173
174 }
175
176 //____________________________________________________________________
177 Int_t AliMUONRawReader::ReadTrackerDDL(AliRawReader* rawReader)
178 {
179   // reading tracker DDL
180   // filling the TClonesArray in MUONData
181   //
182   fTrackerTimer.Start(kFALSE);
183   
184   AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
185   AliMUONDigit* digit = new AliMUONDigit();
186
187
188   //Read Header Size of DDL,Block,DSP and BusPatch (put k before constant imb'cile)
189
190   Int_t kDDLHeaderSize      = fDDLTracker->GetHeaderSize();
191   Int_t kBlockHeaderSize    = fDDLTracker->GetBlkHeaderLength();
192   Int_t kDspHeaderSize      = fDDLTracker->GetDspHeaderLength();
193   Int_t kBusPatchHeaderSize = subEventTracker->GetHeaderLength();
194
195   Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize; 
196
197
198   Int_t iBusPerDSP[5];//number of bus patches per DSP
199   Int_t iDspMax; //number max of DSP per block
200
201   // minimum data size (only header's)
202   Int_t blankDDLSize;
203   Int_t blankBlockSize;
204   Int_t blankDspSize;  
205
206   for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
207
208     AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
209
210     // getting DSP info
211     fBusPatchManager->GetDspInfo(iDDL/2, iDspMax, iBusPerDSP);
212
213     //   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.
214     //   This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
215     blankDDLSize   = kDDLHeaderSize + 2*kBlockHeaderSize + 2*iDspMax*kDspHeaderSize;
216     blankBlockSize = kBlockHeaderSize + iDspMax*kDspHeaderSize;
217
218     for (Int_t i = 0; i < iDspMax; i++) {
219       blankDDLSize   += 2*iBusPerDSP[i]*kBusPatchHeaderSize;
220       blankBlockSize +=   iBusPerDSP[i]*kBusPatchHeaderSize;
221     }
222     rawReader->Reset();
223     rawReader->Select(0X9, iDDL, iDDL);  //Select the DDL file to be read  
224
225     rawReader->ReadHeader();
226
227     totalDDLSize = (rawReader->GetDataSize() + sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 words
228
229     if(totalDDLSize > blankDDLSize) {      // Compare the DDL header with an empty DDL header size to read the file
230
231       Int_t totalDataWord = rawReader->GetDataSize(); // in bytes
232       UInt_t *buffer = new UInt_t[totalDataWord/4];
233
234       rawReader->ReadNext((UChar_t*)buffer, totalDataWord); 
235
236       // elex info
237       Int_t    buspatchId;
238       UChar_t  channelId;
239       UShort_t manuId;
240       Char_t   parity;
241       UShort_t charge; 
242
243       // indexes
244       Int_t indexDsp;
245       Int_t indexBusPatch;
246       Int_t index = 0;
247
248       for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){  // loop over 2 blocks
249         totalBlockSize = buffer[index];
250           
251         if(totalBlockSize > blankBlockSize) {        // compare block header
252           index += kBlockHeaderSize;
253
254           for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){   //DSP loop
255
256             totalDspSize = buffer[index];
257             indexDsp = index;
258
259             blankDspSize =  kDspHeaderSize + iBusPerDSP[iDsp]*kBusPatchHeaderSize; // no data just header
260
261             if(totalDspSize > blankDspSize) {       // Compare DSP Header
262               index += kDspHeaderSize;
263                 
264               for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {  
265
266                 //copy buffer into header structure
267                 memcpy(subEventTracker->GetBusPatchHeader(), &buffer[index], kBusPatchHeaderSize*4);
268
269                 totalBusPatchSize = subEventTracker->GetTotalLength();
270                 buspatchId        = subEventTracker->GetBusPatchId();
271                 indexBusPatch     = index;
272                 
273
274                 if(totalBusPatchSize > kBusPatchHeaderSize) {    //Check Buspatch header, not empty events
275
276                   index   += kBusPatchHeaderSize;
277                   dataSize = subEventTracker->GetLength();
278                   Int_t bufSize = subEventTracker->GetBufSize();
279
280                   if(dataSize>0) { // check data present
281                     if (dataSize > bufSize) subEventTracker->SetAlloc(dataSize);
282
283                     //copy buffer into data structure
284                     memcpy(subEventTracker->GetData(), &buffer[index], dataSize*4); 
285                     index += dataSize;
286
287                     for(Int_t iData = 0; iData < dataSize; iData++) {
288
289                       // digits info
290                       parity    = subEventTracker->GetParity(iData); // test later for parity
291                       manuId    = subEventTracker->GetManuId(iData);
292                       channelId = subEventTracker->GetChannelId(iData);
293                       charge    = subEventTracker->GetCharge(iData);
294                       
295                       // set charge
296                       digit->SetSignal(charge);
297           digit->SetPhysicsSignal(charge);
298           digit->SetADC(charge);
299                       Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
300                       if (error) continue;
301
302                       // debugging 
303                       if (AliLog::GetGlobalDebugLevel() == 3) {
304                         Int_t padX  = digit->PadX();
305                         Int_t padY  = digit->PadY();
306                         Int_t iCath = digit->Cathode();  
307                         Int_t detElemId  = digit->DetElemId();
308
309                         AliDebug(1,Form("output  detElemId %d busPatchid %d PadX %d PadY %d iCath %d \n", 
310                                       detElemId, buspatchId, padX, padY, iCath));
311                 
312                         AliDebug(3,Form("detElemId %d Padx %d Pady %d, Cath %d, charge %d",detElemId, padX, padY, iCath, charge));
313                       }
314
315                       // fill digits
316                       fMUONData->AddDigit(iDDL/2, *digit);
317
318                     } // data loop
319                   } // dataSize test
320                 } // testing buspatch
321
322                 index = indexBusPatch + totalBusPatchSize;
323
324               }  //buspatch loop
325                 
326             }  // dsp test
327
328             index = indexDsp + totalDspSize;
329               
330           }  // dsp loop
331
332         }   //block test
333
334         index = totalBlockSize;
335
336       }  //block loop
337
338       delete[] buffer;
339     } //loop checking the header size of DDL
340
341     //delete rawReader;
342   } // DDL loop
343
344
345   delete subEventTracker;
346   delete digit;
347
348   fTrackerTimer.Stop();
349   
350   return kTRUE;
351 }
352
353 //____________________________________________________________________
354 Int_t AliMUONRawReader::GetMapping(Int_t busPatchId, UShort_t manuId, 
355                                          UChar_t channelId, AliMUONDigit* digit )
356 {
357
358  // mapping  for tracker
359
360   fMappingTimer.Start(kFALSE);
361   
362   // getting DE from buspatch
363   Int_t  detElemId = fBusPatchManager->GetDEfromBus(busPatchId);
364   AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
365
366   AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentationByElectronics(detElemId, manuId);  
367   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
368
369   if (!pad.IsValid())
370   {
371     AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
372                   detElemId, busPatchId, manuId, channelId));
373     fMappingTimer.Stop();
374     return kTRUE;
375   } // return error
376
377   // Getting padX, padY and cathode number.
378   Int_t padX = pad.GetIndices().GetFirst();
379   Int_t padY = pad.GetIndices().GetSecond();
380   Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
381
382   // storing into digits
383   digit->SetPadX(padX);
384   digit->SetPadY(padY);
385   digit->SetCathode(iCath);
386   digit->SetDetElemId(detElemId);
387   digit->SetElectronics(manuId,channelId);
388   
389   AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
390                   detElemId, busPatchId, manuId, channelId, padX, padY));
391   StdoutToAliDebug(3,digit->Print(););
392   
393   fMappingTimer.Stop();
394   return kFALSE;
395 }
396
397 //____________________________________________________________________
398 Int_t AliMUONRawReader::ReadTriggerDDL(AliRawReader* rawReader)
399 {
400
401   // reading DDL for trigger
402
403   fTriggerTimer.Start(kFALSE);
404   
405   AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
406   AliMUONScalerEventTrigger* scalerEvent = 0x0;
407
408   AliMUONGlobalTrigger* globalTrigger = 0x0;
409   AliMUONLocalTrigger* localTrigger = new  AliMUONLocalTrigger();
410
411
412   //Int_t kDDLHeaderSize = fDDLTrigger->GetHeaderSize();    
413   // we dont need this, as size of ddl data is same for triger and no trigger
414
415   Int_t kDDLEnhanceHeaderSize = fDDLTrigger->GetHeaderLength(); 
416   Int_t kRegHeaderSize        = subEventTrigger->GetRegHeaderLength() ;
417
418   Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
419   Char_t loDecision; 
420
421   UShort_t x1Pattern, x2Pattern, x3Pattern, x4Pattern;
422   UShort_t y1Pattern, y2Pattern, y3Pattern, y4Pattern;
423
424   // loop over the two ddl's
425   for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
426
427     rawReader->Reset();
428     rawReader->Select(0XA,iDDL,iDDL);  //Select the DDL file to be read  
429
430     rawReader->ReadHeader();
431
432     Int_t totalDataWord = rawReader->GetDataSize(); // in bytes
433     UInt_t *buffer = new UInt_t[totalDataWord/4];
434
435     rawReader->ReadNext((UChar_t*)buffer, totalDataWord); 
436   
437     Int_t index = 0;
438     fDDLTrigger->SetDDLWord(buffer[index++]);
439
440     if(fDDLTrigger->GetEventType() == 2) {
441       fScalerEvent = kTRUE;
442       scalerEvent = new  AliMUONScalerEventTrigger();
443     } else
444       fScalerEvent = kFALSE;
445
446     if(fScalerEvent) {
447       // 6 DARC scaler words
448       memcpy(scalerEvent->GetDarcScalers(), &buffer[index], scalerEvent->GetDarcScalerLength()*4);
449       index += scalerEvent->GetDarcScalerLength();
450     }
451
452     // 4 words of global board input + Global board output
453     memcpy(fDDLTrigger->GetGlobalInput(), &buffer[index], (kDDLEnhanceHeaderSize-1)*4); 
454     index += kDDLEnhanceHeaderSize - 1; // kind tricky cos scaler info in-between Darc header
455
456     if(fScalerEvent) {
457       // 10 Global scaler words
458       memcpy(scalerEvent->GetGlobalScalers(), &buffer[index], scalerEvent->GetGlobalScalerLength()*4);
459       index += scalerEvent->GetGlobalScalerLength();
460     }
461
462     // fill global trigger information
463     globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
464     fMUONData->AddGlobalTrigger(*globalTrigger);
465     
466     // 8 regional boards
467     for (Int_t iReg = 0; iReg < 8; iReg++) {           //loop over regeonal card
468
469       memcpy(subEventTrigger->GetRegHeader(), &buffer[index], kRegHeaderSize*4);
470       index += kRegHeaderSize;
471
472      // 11 regional scaler word
473       if(fScalerEvent) {
474         memcpy(scalerEvent->GetRegScalers(), &buffer[index], scalerEvent->GetRegScalerLength()*4);
475         index += scalerEvent->GetRegScalerLength();
476       }
477
478       // 16 local cards per regional board
479       for (Int_t iLoc = 0; iLoc < 16; iLoc++) {         //loop over local card
480           
481         Int_t iLocIndex = index;
482
483         // 5 word trigger information
484         for(Int_t iData = 0; iData < 5 ;iData++ ){
485           subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData);   //read local data
486         }
487
488         if(buffer[iLocIndex] > 0) {
489
490           loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL; 
491           loStripX  = (Int_t)subEventTrigger->GetXPos(iLoc);
492           loStripY  = (Int_t)subEventTrigger->GetYPos(iLoc);
493           loDev     = (Int_t)subEventTrigger->GetXDev(iLoc);
494             
495           // fill local trigger
496           localTrigger->SetLoCircuit(loCircuit);
497           localTrigger->SetLoStripX(loStripX );
498           localTrigger->SetLoStripY(loStripY);
499           localTrigger->SetLoDev(loDev);
500
501           loDecision = subEventTrigger->GetLocalDec(iLoc);
502           loLpt =  loDecision       & 0x3;
503           loHpt = (loDecision >> 2) & 0x3; 
504             
505           // fill local trigger
506           localTrigger->SetLoLpt(loLpt);
507           localTrigger->SetLoHpt(loHpt);
508
509           //getting pattern from subvent
510           x1Pattern = subEventTrigger->GetX1(iLoc);
511           x2Pattern = subEventTrigger->GetX2(iLoc);
512           x3Pattern = subEventTrigger->GetX3(iLoc);
513           x4Pattern = subEventTrigger->GetX4(iLoc);
514             
515           y1Pattern = subEventTrigger->GetY1(iLoc);
516           y2Pattern = subEventTrigger->GetY2(iLoc);
517           y3Pattern = subEventTrigger->GetY3(iLoc);
518           y4Pattern = subEventTrigger->GetY4(iLoc);
519
520           // fill local trigger
521           localTrigger->SetX1Pattern(x1Pattern);
522           localTrigger->SetX2Pattern(x2Pattern);
523           localTrigger->SetX3Pattern(x3Pattern);
524           localTrigger->SetX4Pattern(x4Pattern);
525
526           localTrigger->SetY1Pattern(y1Pattern);
527           localTrigger->SetY2Pattern(y2Pattern);
528           localTrigger->SetY3Pattern(y3Pattern);
529           localTrigger->SetY4Pattern(y4Pattern);
530           fMUONData->AddLocalTrigger(*localTrigger);
531
532         } // if buffer[] > 0
533
534         // 45 regional scaler word
535         if(fScalerEvent) {
536           memcpy(scalerEvent->GetLocalScalers(), &buffer[index], scalerEvent->GetLocalScalerLength()*4);
537           index += scalerEvent->GetLocalScalerLength();
538         }
539           
540       } // local card loop
541         
542     } // regional card loop
543       
544     delete [] buffer;
545   } // DDL loop
546
547   delete subEventTrigger;
548   delete globalTrigger;
549   delete localTrigger;
550
551   delete scalerEvent;
552
553   fTriggerTimer.Stop();
554   return kTRUE;
555
556 }
557 //____________________________________________________________________
558 AliMUONGlobalTrigger* AliMUONRawReader::GetGlobalTriggerPattern(Int_t gloTrigPat) const
559 {
560   // global trigger pattern calculation
561
562   Int_t globalSinglePlus[3];  // tot num of single plus
563   Int_t globalSingleMinus[3]; // tot num of single minus
564   Int_t globalSingleUndef[3]; // tot num of single undefined
565   Int_t globalPairUnlike[3];  // tot num of unlike-sign pairs
566   Int_t globalPairLike[3];    // tot num of like-sign pairs
567
568
569   for (Int_t i = 0; i < 3; i++) {
570
571     globalSinglePlus[i]  = (gloTrigPat >> i) & 0x1;
572     globalSingleMinus[i] = (gloTrigPat >> (i+3)) & 0x1;
573     globalSingleUndef[i] = (gloTrigPat >> (i+6)) & 0x1;
574     globalPairUnlike[i]  = (gloTrigPat >> (i+9)) & 0x1;
575     globalPairLike[i]    = (gloTrigPat >> (i+12)) & 0x1;
576   }
577
578   return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
579                                    globalSingleUndef, globalPairUnlike, 
580                                    globalPairLike));  
581
582 }
583