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