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