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