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