]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
Flag added to retrieve digits on fly from EVE display (Bogdan)
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.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 /// \class AliMUONDigitMaker
17 /// MUON Digit maker from rawdata.
18 ///
19 /// Raw2Digits:
20 /// Using real mapping  for tracker
21 /// Indranil Das (Adapted for runloader: Ch. Finck) july 05
22 ///
23 /// Implemented non-constant buspatch numbers for tracking
24 /// with correct DDL id.
25 /// (Ch. Finck, dec 05)
26 ///
27 /// Add reader for scaler trigger events
28 /// Use memcpy instead of assignment elt by elt
29 /// (Ch. Finck, Jan 06)
30 ///
31 /// Using new interface with AliMUONRawStreamTracker(Trigger)
32 /// (New interface of AliMUONRawReader class)
33 /// (further details could be found in Alice-note)
34 /// (Ch. Finck, March 06)
35 ///
36 /// Add (S)Digit maker tracker (for free)
37 /// and for trigger. Create trigger inverse mapping.
38 ///
39 /// \author Ch. Finck, oct 06 
40
41 #include "AliMUONDigitMaker.h"
42 #include "AliMUONDigit.h"
43
44 #include "AliMUONConstants.h"
45 #include "AliMUONData.h"
46
47 #include "AliMUONRawStreamTracker.h"
48 #include "AliMUONDDLTracker.h"
49 #include "AliMUONDspHeader.h"
50 #include "AliMUONBlockHeader.h"
51 #include "AliMUONBusStruct.h"
52
53 #include "AliMUONRawStreamTrigger.h"
54 #include "AliMUONDDLTrigger.h"
55 #include "AliMUONDarcHeader.h"
56 #include "AliMUONRegHeader.h"
57 #include "AliMUONLocalStruct.h"
58
59 #include "AliMUONTriggerCrateStore.h"
60 #include "AliMUONTriggerCrate.h"
61 #include "AliMUONLocalTriggerBoard.h"
62 #include "AliMUONLocalTrigger.h"
63 #include "AliMUONGlobalTrigger.h"
64 #include "AliMUONTriggerCircuit.h"
65
66 #include "AliMpSegmentation.h"
67 #include "AliMpVSegmentation.h"
68 #include "AliMpPad.h"
69 #include "AliMpDEManager.h"
70 #include "AliMpDDLStore.h"
71 #include "AliMpCathodType.h"
72
73 #include "AliRawReader.h"
74 #include "AliRawDataHeader.h"
75 #include "AliLog.h"
76 #include "AliRun.h"
77
78 #include <TList.h>
79
80
81 /// \cond CLASSIMP
82 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
83 /// \endcond
84
85 //__________________________________________________________________________
86 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
87   : TObject(),
88     fMUONData(0x0),
89     fScalerEvent(kFALSE),
90     fDigitFlag(flag),
91     fTriggerFlag(kTRUE),
92     fDisplayFlag(kFALSE),
93     fDigitsList(0),
94     fRawStreamTracker(new AliMUONRawStreamTracker()),    
95     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
96     fDigit(new AliMUONDigit()),
97     fLocalTrigger(new AliMUONLocalTrigger()),
98     fGlobalTrigger(new AliMUONGlobalTrigger()),
99     fCrateManager(0x0),
100     fTrackerTimer(),
101     fTriggerTimer(),
102     fMappingTimer()
103 {
104   /// ctor with AliMUONData as argument
105   /// for reconstruction
106
107   AliDebug(1,"");
108
109   // Standard Constructor
110
111   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
112   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
113   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
114
115 }
116
117 //__________________________________________________________________________
118 AliMUONDigitMaker::~AliMUONDigitMaker()
119 {
120   /// clean up
121   /// and time processing measure
122
123   delete fRawStreamTracker;
124   delete fRawStreamTrigger;
125
126   delete fDigit;
127   delete fLocalTrigger;
128   delete fGlobalTrigger;
129
130   delete fDigitsList;
131
132   AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
133                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
134   AliDebug(1, Form("   Execution time for MUON tracker (mapping calls part) "
135                ": R:%.2fs C:%.2fs",
136                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
137   AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
138                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
139
140   return;
141 }
142
143 //____________________________________________________________________
144 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
145 {
146   /// Main method to creates digit
147   /// for tracker 
148   /// and trigger
149
150   if (fDisplayFlag) {
151     fDigitsList = new TList();
152     fCrateManager = new AliMUONTriggerCrateStore();   
153     fCrateManager->ReadFromFile();
154   }
155
156   // generate digits
157   ReadTrackerDDL(rawReader);
158
159   // generate trigger
160   if( fTriggerFlag)
161       ReadTriggerDDL(rawReader);
162   else
163       AliInfo("Reading trigger rawdata disable");
164
165   return kTRUE;
166
167 }
168
169 //____________________________________________________________________
170 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
171 {
172
173   /// reading tracker DDL
174   /// filling the TClonesArray in MUONData
175
176   fTrackerTimer.Start(kFALSE);
177
178   // elex info
179   Int_t    buspatchId;
180   UChar_t  channelId;
181   UShort_t manuId;
182   Char_t   parity;
183   UShort_t charge; 
184   Int_t    dataSize;
185
186   Int_t iChamber;
187
188   AliMUONDDLTracker*   ddlTracker = 0x0;
189   AliMUONBlockHeader*  blkHeader  = 0x0;
190   AliMUONDspHeader*    dspHeader  = 0x0;
191   AliMUONBusStruct*    busStruct  = 0x0;
192
193   fRawStreamTracker->SetReader(rawReader);
194
195   while(fRawStreamTracker->NextDDL()) {
196     
197     ddlTracker =  fRawStreamTracker->GetDDLTracker();
198
199     Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
200     for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
201
202       blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
203  
204       Int_t nDsp = blkHeader->GetDspHeaderEntries();
205
206       for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){   //DSP loop
207
208         dspHeader =  blkHeader->GetDspHeaderEntry(iDsp);
209
210         Int_t nBusPatch = dspHeader->GetBusPatchEntries();
211
212         for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {  
213
214           busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
215
216           dataSize   = busStruct->GetLength();
217           buspatchId = busStruct->GetBusPatchId();
218
219           for (Int_t iData = 0; iData < dataSize; iData++) {
220
221             // digits info
222             parity    = busStruct->GetParity(iData); // test later for parity
223             manuId    = busStruct->GetManuId(iData);
224             channelId = busStruct->GetChannelId(iData);
225             charge    = busStruct->GetCharge(iData);
226             // set charge
227             fDigit->SetSignal(charge);
228             fDigit->SetPhysicsSignal(charge);
229             fDigit->SetADC(charge);
230
231             // Get Back the hits at pads
232             Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit); 
233             if (error) {
234               AliWarning("Mapping Error\n");
235               continue;
236             }
237             // debugging 
238             if (AliLog::GetGlobalDebugLevel() == 3) {
239               Int_t padX  = fDigit->PadX();
240               Int_t padY  = fDigit->PadY();
241               Int_t iCath = fDigit->Cathode();  
242               Int_t idDE  = fDigit->DetElemId();
243
244               AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
245                               idDE, buspatchId, padX, padY, iCath));
246                 
247               AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
248                               idDE, padX, padY, iCath, charge));
249             }
250
251             // fill digits
252             iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
253
254             if (!fDisplayFlag) {
255               if (fDigitFlag)
256                 fMUONData->AddDigit(iChamber, *fDigit);
257               else
258                 fMUONData->AddSDigit(iChamber, *fDigit);
259             } else {
260               AliMUONDigit *dig = new AliMUONDigit();
261               dig->SetPadX(fDigit->PadX());
262               dig->SetPadY(fDigit->PadY());
263               dig->SetDetElemId(fDigit->DetElemId());
264               dig->SetCathode(fDigit->Cathode());
265               dig->SetSignal(fDigit->Signal());
266               fDigitsList->Add(dig);
267             }
268
269           } // iData
270         } // iBusPatch
271       } // iDsp
272     } // iBlock
273   } // NextDDL
274
275   fTrackerTimer.Stop();
276
277   return kTRUE;
278 }
279 //____________________________________________________________________
280 Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
281                                          UChar_t channelId, AliMUONDigit* digit )
282 {
283   /// mapping  for tracker
284
285   fMappingTimer.Start(kFALSE);
286   
287   // getting DE from buspatch
288   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
289   AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
290
291   const AliMpVSegmentation* seg 
292     = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);  
293   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
294
295   if (!pad.IsValid())
296   {
297     AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
298                   detElemId, busPatchId, manuId, channelId));
299     fMappingTimer.Stop();
300     return kTRUE;
301   } // return error
302
303   // Getting padX, padY and cathode number.
304   Int_t padX = pad.GetIndices().GetFirst();
305   Int_t padY = pad.GetIndices().GetSecond();
306   Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
307
308   // storing into digits
309   digit->SetPadX(padX);
310   digit->SetPadY(padY);
311   digit->SetCathode(iCath);
312   digit->SetDetElemId(detElemId);
313   digit->SetElectronics(manuId,channelId);
314   
315   AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
316                   detElemId, busPatchId, manuId, channelId, padX, padY));
317 //  StdoutToAliDebug(3,digit->Print(););
318   
319   fMappingTimer.Stop();
320   return kFALSE;
321 }
322
323 //____________________________________________________________________
324 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
325 {
326   /// reading tracker DDL
327   /// filling the TClonesArray in MUONData
328
329   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
330   AliMUONDarcHeader*       darcHeader      = 0x0;
331   AliMUONRegHeader*        regHeader       = 0x0;
332   AliMUONLocalStruct*      localStruct     = 0x0;
333
334   Int_t loCircuit;
335   TList digitList;
336
337   fTriggerTimer.Start(kFALSE);
338
339   fRawStreamTrigger->SetReader(rawReader);
340
341   while(fRawStreamTrigger->NextDDL()) {
342     
343     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
344     darcHeader = ddlTrigger->GetDarcHeader();
345
346     // fill global trigger information in Digit Tree
347     if (fDigitFlag) {
348       if (darcHeader->GetGlobalFlag()) {
349         if (!fDisplayFlag) {
350           fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
351           fMUONData->AddGlobalTrigger(*fGlobalTrigger);
352         }
353       }
354     }
355
356     Int_t nReg = darcHeader->GetRegHeaderEntries();
357
358     for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
359
360       // crate info
361       if (!fCrateManager) AliFatal("Crate Store not defined");
362       AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
363   
364       if (!crate) 
365         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
366
367       TObjArray *boards  = crate->Boards();
368
369       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
370
371       Int_t nLocal = regHeader->GetLocalEntries();
372       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {  
373         
374         localStruct = regHeader->GetLocalEntry(iLocal);
375
376         // if card exist
377         if (localStruct) {
378
379           AliMUONLocalTriggerBoard* localBoard = 
380             (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
381
382           // skip copy cards
383           if( !(loCircuit = localBoard->GetNumber()) )
384              continue;
385
386           if (fDigitFlag) {
387             // fill local trigger
388             if (!fDisplayFlag) {
389               fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
390               fMUONData->AddLocalTrigger(*fLocalTrigger);
391             }
392
393           } else {
394             // Make SDigit
395
396             digitList.Clear();
397             
398             if( TriggerDigits(localBoard, localStruct, digitList) ) {
399
400               for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
401
402                 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
403                 
404                 // filling S container
405                 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
406                 if (!fDisplayFlag) {
407                   fMUONData->AddSDigit(iChamber, *digit);
408                 } else {
409                   AliMUONDigit *dig = new AliMUONDigit();
410                   dig->SetPadX(digit->PadX());
411                   dig->SetPadY(digit->PadY());
412                   dig->SetDetElemId(digit->DetElemId());
413                   dig->SetCathode(digit->Cathode());
414                   dig->SetSignal(1);
415                   fDigitsList->Add(dig);
416                 }
417
418               }
419
420             } // trigger digits
421           } // S flag
422
423         } // if triggerY
424       } // iLocal
425     } // iReg
426   } // NextDDL
427
428   fTriggerTimer.Stop();
429
430   return kTRUE;
431
432 }
433 //____________________________________________________________________
434 void AliMUONDigitMaker::GetTriggerChamber(AliMUONLocalStruct* localStruct, Int_t& xyPattern, 
435                                           Int_t& iChamber, Int_t& iCath, Int_t icase)
436 {
437   /// get chamber & cathode number, (chamber starts at 0 !)
438
439     switch(icase) {
440     case 0: 
441       xyPattern =  localStruct->GetX1();
442       iCath = 0;
443       iChamber = 10;
444       break;
445     case 1: 
446       xyPattern =  localStruct->GetX2();
447       iCath = 0;
448       iChamber = 11;
449       break;
450     case 2: 
451       xyPattern =  localStruct->GetX3();
452       iCath = 0;
453       iChamber = 12;
454       break;
455     case 3: 
456       xyPattern =  localStruct->GetX4();
457       iCath = 0;
458       iChamber = 13;
459       break;
460     case 4: 
461       xyPattern =  localStruct->GetY1();
462       iCath = 1;
463       iChamber = 10;
464       break;
465     case 5: 
466       xyPattern =  localStruct->GetY2();
467       iCath = 1;
468       iChamber = 11;
469       break;
470     case 6: 
471       xyPattern =  localStruct->GetY3();
472       iCath = 1;
473       iChamber = 12;
474       break;
475     case 7: 
476       xyPattern =  localStruct->GetY4();
477       iCath = 1;
478       iChamber = 13;
479       break;
480     }
481 }
482 //____________________________________________________________________
483 Int_t AliMUONDigitMaker::TriggerDigits(AliMUONLocalTriggerBoard* localBoard, 
484                                        AliMUONLocalStruct* localStruct,
485                                        TList& digitList)
486 {
487   /// make (S)Digit for trigger
488
489   Int_t detElemId;
490   Int_t nBoard;
491   Int_t iCath = -1;
492   Int_t iChamber = 0;
493   Int_t xyPattern = 0;
494
495   // loop over x1-4 and y1-4
496   for (Int_t icase = 0; icase < 8; icase++) {
497
498     // get chamber, cathode and associated trigger response pattern
499     GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
500   
501     if (!xyPattern) continue;
502
503     // get detElemId
504     AliMUONTriggerCircuit triggerCircuit;
505     detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
506     nBoard    = localBoard->GetNumber();
507
508     const AliMpVSegmentation* seg 
509       = AliMpSegmentation::Instance()
510         ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
511
512     // loop over the 16 bits of pattern
513     for (Int_t ibitxy = 0; ibitxy < 16; ibitxy++) {
514     
515       if ((xyPattern >> ibitxy) & 0x1) {
516
517         // not quite sure about this
518         Int_t offset = 0;
519         if (iCath && localBoard->GetSwitch(6)) offset = -8;
520
521         AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
522
523         AliMUONDigit* digit = new  AliMUONDigit();
524         if (!pad.IsValid()) {
525           AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
526                           detElemId, nBoard, ibitxy));
527           continue;
528         } // 
529
530         Int_t padX = pad.GetIndices().GetFirst();
531         Int_t padY = pad.GetIndices().GetSecond();
532
533         // file digit
534         digit->SetPadX(padX);
535         digit->SetPadY(padY);
536         digit->SetCathode(iCath);
537         digit->SetDetElemId(detElemId);
538         digit->SetElectronics(nBoard, ibitxy);
539         digitList.Add(digit);
540         
541       }// xyPattern
542     }// ibitxy
543   }// case
544
545   return kTRUE;
546
547 //____________________________________________________________________
548 void  AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
549 {
550   /// set crate name from DDL & reg number
551   /// method same as in RawWriter, not so nice
552   /// should be put in AliMUONTriggerCrateStore
553
554       switch(iReg) {
555       case 0:
556       case 1:
557         sprintf(name,"%d", iReg+1);
558         break;
559       case 2:
560         strcpy(name, "2-3");
561         break;
562       case 3:
563       case 4:
564       case 5:
565       case 6:
566       case 7:
567         sprintf(name,"%d", iReg);
568         break;
569       }
570
571       // crate Right for first DDL
572       if (iDDL == 0)
573         strcat(name, "R");
574       else 
575         strcat(name, "L"); 
576 }