Separating writing and reading of raw data (Christian)
[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 generator and reader in ALICE-MUON
19 // This class version 3 (further details could be found in Alice-note)
20 //
21 // Implemented non-constant buspatch numbers for tracking
22 // with correct DDL id (first guess)
23 // (Ch. Finck, dec 2005)
24 //
25 // Digits2Raw:
26 // Generates raw data for MUON tracker and finally for trigger
27 // Using real mapping (inverse) for tracker
28 // For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
29 // Ch. Finck july 04
30 //
31 // Raw2Digits:
32 // Using real mapping  for tracker
33 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
34 // 
35 ////////////////////////////////////
36
37 #include <fstream>
38 #include <string>
39
40 #include <TClonesArray.h>
41
42 #include "AliLoader.h"
43 #include "AliBitPacking.h" 
44 #include "AliRawReader.h"
45 #include "AliLog.h"
46 #include "AliRun.h"
47
48 #include "AliMUON.h"
49 #include "AliMUONRawReader.h"
50 #include "AliMUONDigit.h"
51
52 #include "AliMUONConstants.h"
53 #include "AliMUONData.h"
54
55 #include "AliMUONSubEventTracker.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
72
73 ClassImp(AliMUONRawReader) // Class implementation in ROOT context
74 //__________________________________________________________________________
75 AliMUONRawReader::AliMUONRawReader(AliLoader* loader,  AliMUONData* data)
76   : TObject()
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 {
107   // Default Constructor
108   
109 }
110
111 //_______________________________________________________________________
112 AliMUONRawReader::AliMUONRawReader (const AliMUONRawReader& rhs)
113   : TObject(rhs)
114 {
115 // Protected copy constructor
116
117   AliFatal("Not implemented.");
118 }
119
120 //_______________________________________________________________________
121 AliMUONRawReader & 
122 AliMUONRawReader::operator=(const AliMUONRawReader& rhs)
123 {
124 // Protected assignement operator
125
126   if (this == &rhs) return *this;
127
128   AliFatal("Not implemented.");
129     
130   return *this;  
131 }
132
133 //__________________________________________________________________________
134 AliMUONRawReader::~AliMUONRawReader(void)
135 {
136   if (fSegFactory) 
137     fSegFactory->DeleteSegmentations();
138   delete fSegFactory;  
139
140   if (fDDLTracker)
141     delete fDDLTracker;
142   if (fDDLTrigger)
143     delete fDDLTrigger;
144
145   fBusPatchManager->Delete();
146
147   return;
148 }
149
150 //____________________________________________________________________
151 Int_t AliMUONRawReader::Raw2Digits(AliRawReader* rawReader)
152 {
153
154   // generate digits
155   ReadTrackerDDL(rawReader);
156
157   // generate trigger
158   ReadTriggerDDL(rawReader);
159
160   return kTRUE;
161
162 }
163
164 //____________________________________________________________________
165 Int_t AliMUONRawReader::ReadTrackerDDL(AliRawReader* rawReader)
166 {
167   // reading tracker DDL
168   // filling the TClonesArray in MUONData
169   //
170
171   AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
172   AliMUONDigit* digit = new AliMUONDigit();
173
174
175   //Read Header Size of DDL,Block,DSP and BusPatch.
176
177   Int_t ddlHeaderSize      = fDDLTracker->GetHeaderSize();
178   Int_t blockHeaderSize    = fDDLTracker->GetBlkHeaderLength();
179   Int_t dspHeaderSize      = fDDLTracker->GetDspHeaderLength();
180   Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
181
182   Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize; 
183
184
185   Int_t iBusPerDSP[5];//number of bus patches per DSP
186   Int_t iDspMax; //number max of DSP per block
187
188   // minimum data size (only header's)
189   Int_t blankDDLSize;
190   Int_t blankBlockSize;
191   Int_t blankDspSize;  
192
193   for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
194
195     AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
196
197     // getting DSP info
198     fBusPatchManager->GetDspInfo(iDDL/2, iDspMax, iBusPerDSP);
199
200     //   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.
201     //   This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
202     blankDDLSize   = ddlHeaderSize + 2*blockHeaderSize + 2*iDspMax*dspHeaderSize;
203     blankBlockSize = blockHeaderSize + iDspMax*dspHeaderSize;
204
205     for (Int_t i = 0; i < iDspMax; i++) {
206       blankDDLSize   += 2*iBusPerDSP[i]*buspatchHeaderSize;
207       blankBlockSize +=   iBusPerDSP[i]*buspatchHeaderSize;
208     }
209
210     rawReader->Select(0X9, iDDL, iDDL);  //Select the DDL file to be read  
211
212     rawReader->ReadHeader();
213
214     totalDDLSize = (rawReader->GetDataSize() + sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 words
215
216     if(totalDDLSize > blankDDLSize) {      // Compare the DDL header with an empty DDL header size to read the file
217
218       Int_t totalDataWord = rawReader->GetDataSize()/4 ;
219       UInt_t *buffer = new UInt_t[totalDataWord];
220       for(Int_t i = 0; i < totalDataWord; i++) { 
221         UInt_t& temp = buffer[i]; 
222         rawReader->ReadNextInt(temp);      // takes the whole result into buffer variable for future analysis
223       }
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 += blockHeaderSize;
242
243           for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){   //DSP loop
244
245             totalDspSize = buffer[index];
246             indexDsp = index;
247
248             blankDspSize =  dspHeaderSize + iBusPerDSP[iDsp]*buspatchHeaderSize; // no data just header
249
250             if(totalDspSize > blankDspSize) {       // Compare DSP Header
251               index += dspHeaderSize;
252                 
253               for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {  
254
255                 totalBusPatchSize = buffer[index];
256                 buspatchId        = buffer[index+2];
257                 indexBusPatch     = index;
258
259                 if(totalBusPatchSize > buspatchHeaderSize) {    //Check Buspatch header
260
261                   index   += buspatchHeaderSize;
262                   dataSize = totalBusPatchSize - buspatchHeaderSize;
263
264                   if(dataSize>0) { // check data present
265
266                     for(Int_t iData = 0; iData < dataSize; iData++) {
267
268                       subEventTracker->SetData(buffer[index++],iData);   //Set to extract data
269                       // digits info
270                       parity    = subEventTracker->GetParity(iData); // test later for parity
271                       manuId    = subEventTracker->GetManuId(iData);
272                       channelId = subEventTracker->GetChannelId(iData);
273                       charge    = subEventTracker->GetCharge(iData);
274                       // set charge
275                       digit->SetSignal(charge);
276
277                       Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
278                       if (error) continue;
279
280                       // debugging 
281                       if (AliLog::GetGlobalDebugLevel() == 3) {
282                         Int_t padX  = digit->PadX();
283                         Int_t padY  = digit->PadY();
284                         Int_t iCath = digit->Cathode();  
285                         Int_t idDE  = digit->DetElemId();
286
287                         AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
288                                       idDE, buspatchId, padX, padY, iCath));
289                 
290                         AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",idDE, padX, padY, iCath, charge));
291                       }
292
293                       // fill digits
294                       fMUONData->AddDigit(iDDL/2, *digit);
295
296                     } // data loop
297                   } // dataSize test
298                 } // testing buspatch
299
300                 index = indexBusPatch + totalBusPatchSize;
301
302               }  //buspatch loop
303                 
304             }  // dsp test
305
306             index = indexDsp + totalDspSize;
307               
308           }  // dsp loop
309
310         }   //block test
311
312         index = totalBlockSize;
313
314       }  //block loop
315
316       delete[] buffer;
317     } //loop checking the header size of DDL
318
319     //delete rawReader;
320   } // DDL loop
321
322
323   delete subEventTracker;
324   delete digit;
325
326   return kTRUE;
327 }
328
329 //____________________________________________________________________
330 Int_t AliMUONRawReader::GetMapping(Int_t busPatchId, UShort_t manuId, 
331                                          UChar_t channelId, AliMUONDigit* digit )
332 {
333
334  // mapping  for tracker
335
336   // getting DE from buspatch
337   Int_t  idDE = fBusPatchManager->GetDEfromBus(busPatchId);
338   AliDebug(3,Form("idDE: %d busPatchId %d\n", idDE, busPatchId));
339
340   // segmentation
341   Int_t iCath;
342   Int_t iCath1 = 0;
343   Int_t iCath2 = 1;
344
345 /*
346   AliMpPlaneType plane;
347
348   if (manuId > 1000) { // again tmp solution (ChF) (+1000 for Non-Bending plane
349     plane = kNonBendingPlane;
350   } else {
351     plane = kBendingPlane;
352   }
353 */
354
355   if (idDE < 500) { // should use GetDirection somehow (ChF)
356     if ( ((idDE % 100) % 2) != 0 ) {
357       iCath1 = 1;
358       iCath2 = 0;
359     }
360   }
361
362   iCath = (manuId > 1000) ? iCath2 : iCath1;
363
364   if (manuId > 1000) manuId -= 1000; // back to normal manuId
365
366   // Could the above logic be simplified ???
367   //AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
368   AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(idDE, iCath);  
369   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,(Int_t)channelId),kTRUE);
370
371   if(!pad.IsValid()){
372     AliWarning(Form("No pad for idDE: %d, busPatchId %d, manuId: %d, channelId: %d\n",
373                   idDE, busPatchId, manuId, channelId));
374     return kTRUE;
375   } // return error
376
377   // Getting padX
378   Int_t padX = pad.GetIndices().GetFirst();
379
380  // Getting padY
381   Int_t padY = pad.GetIndices().GetSecond();
382      
383   if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0) 
384     padX++;         // while in AliMUONSt345Seg. they begin at (1,1)
385     padY++;
386   }
387   // storing into digits
388   digit->SetPadX(padX);
389   digit->SetPadY(padY);
390   digit->SetCathode(iCath);
391   digit->SetDetElemId(idDE);
392
393   AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
394                   idDE, busPatchId, manuId, channelId, padX, padY));
395   return kFALSE;
396 }
397
398 //____________________________________________________________________
399 Int_t AliMUONRawReader::ReadTriggerDDL(AliRawReader* rawReader)
400 {
401
402   // reading DDL for trigger
403
404   AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
405   AliMUONGlobalTrigger* globalTrigger = 0x0;
406   AliMUONLocalTrigger* localTrigger = new  AliMUONLocalTrigger();
407
408
409   //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize();    
410   // we dont need this, as size of ddl data is same for triger and no trigger
411
412   Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength(); 
413   Int_t regHeaderLength      = subEventTrigger->GetRegHeaderLength() ;
414
415   Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
416   Char_t loDecision; 
417
418   UShort_t x1Pattern, x2Pattern, x3Pattern, x4Pattern;
419   UShort_t y1Pattern, y2Pattern, y3Pattern, y4Pattern;
420
421
422   // loop over the two ddl's
423   for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
424
425     rawReader->Select(0XA,iDDL,iDDL);  //Select the DDL file to be read  
426
427     rawReader->ReadHeader();
428
429     Int_t totalDataWord = rawReader->GetDataSize()/4 ;
430     UInt_t *buffer = new UInt_t[totalDataWord];
431     for(Int_t i=0;i<totalDataWord;i++){
432       UInt_t& temp = buffer[i]; 
433       rawReader->ReadNextInt(temp);      // takes the whole result into buffer variable for future analysis
434     }
435
436     // rawReader->ReadNext((UChar_t*)buffer, totalDataWord);     // method is protected ????
437   
438     Int_t index = 0;
439
440     // fill DDL header informations
441     memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4); 
442
443     // fill global trigger information
444     globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
445     fMUONData->AddGlobalTrigger(*globalTrigger);
446
447     index += ddlEnhanceHeaderSize;
448
449     // 8 regional boards
450     for (Int_t iReg = 0; iReg < 8; iReg++) {           //loop over regeonal card
451
452
453       subEventTrigger->SetRegWord(buffer[index]);      //read regional data 
454
455       index += regHeaderLength;
456
457       // 16 local cards per regional board
458       for (Int_t iLoc = 0; iLoc < 16; iLoc++) {         //loop over local card
459           
460         Int_t iLocIndex = index;
461
462         // 5 word trigger information
463         for(Int_t iData = 0; iData < 5 ;iData++ ){
464           subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData);   //read local data
465         }
466
467         if(buffer[iLocIndex] > 0) {
468
469           loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL; 
470           loStripX =  (Int_t)subEventTrigger->GetXPos(iLoc);
471           loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
472           loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
473             
474           // fill local trigger
475           localTrigger->SetLoCircuit(loCircuit);
476           localTrigger->SetLoStripX(loStripX );
477           localTrigger->SetLoStripY(loStripY);
478           localTrigger->SetLoDev(loDev);
479
480           loDecision = subEventTrigger->GetLocalDec(iLoc);
481           loLpt =  loDecision       & 0x3;
482           loHpt = (loDecision >> 2) & 0x3; 
483             
484           // fill local trigger
485           localTrigger->SetLoLpt(loLpt);
486           localTrigger->SetLoHpt(loHpt);
487
488           //getting pattern from subvent
489           x1Pattern = subEventTrigger->GetX1(iLoc);
490           x2Pattern = subEventTrigger->GetX2(iLoc);
491           x3Pattern = subEventTrigger->GetX3(iLoc);
492           x4Pattern = subEventTrigger->GetX4(iLoc);
493             
494           y1Pattern = subEventTrigger->GetY1(iLoc);
495           y2Pattern = subEventTrigger->GetY2(iLoc);
496           y3Pattern = subEventTrigger->GetY3(iLoc);
497           y4Pattern = subEventTrigger->GetY4(iLoc);
498
499           // fill local trigger
500           localTrigger->SetX1Pattern(x1Pattern);
501           localTrigger->SetX2Pattern(x2Pattern);
502           localTrigger->SetX3Pattern(x3Pattern);
503           localTrigger->SetX4Pattern(x4Pattern);
504
505           localTrigger->SetY1Pattern(y1Pattern);
506           localTrigger->SetY2Pattern(y2Pattern);
507           localTrigger->SetY3Pattern(y3Pattern);
508           localTrigger->SetY4Pattern(y4Pattern);
509           fMUONData->AddLocalTrigger(*localTrigger);
510
511         }
512           
513       } // local card loop
514         
515     } // regional card loop
516       
517     delete [] buffer;
518   } // DDL loop
519
520   delete subEventTrigger;
521   delete globalTrigger;
522   delete localTrigger;
523
524   return kTRUE;
525
526 }
527 //____________________________________________________________________
528 AliMUONGlobalTrigger* AliMUONRawReader::GetGlobalTriggerPattern(Int_t gloTrigPat) const
529 {
530   // global trigger pattern calculation
531
532   Int_t globalSinglePlus[3];  // tot num of single plus
533   Int_t globalSingleMinus[3]; // tot num of single minus
534   Int_t globalSingleUndef[3]; // tot num of single undefined
535   Int_t globalPairUnlike[3];  // tot num of unlike-sign pairs
536   Int_t globalPairLike[3];    // tot num of like-sign pairs
537
538
539   for (Int_t i = 0; i < 3; i++) {
540     globalSinglePlus[i]  = gloTrigPat & (0x1 << i);
541     globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
542     globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
543     globalPairUnlike[i]  = gloTrigPat & (0x1 << i+9);
544     globalPairLike[i]    = gloTrigPat & (0x1 << i+12);
545   }
546
547   return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
548                                    globalSingleUndef, globalPairUnlike, 
549                                    globalPairLike));  
550
551 }
552