replacing AliMUONTriggerCircuitNew by AliMUONTriggerCircuitNew
[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 "AliMpBusPatch.h"
70
71 #include "AliRawReader.h"
72 #include "AliRawDataHeader.h"
73 #include "AliLog.h"
74 #include "AliRun.h"
75
76 #include <TList.h>
77
78
79 /// \cond CLASSIMP
80 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
81 /// \endcond
82
83 //__________________________________________________________________________
84 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
85   : TObject(),
86     fMUONData(0x0),
87     fBusPatchManager(new AliMpBusPatch()),
88     fScalerEvent(kFALSE),
89     fDigitFlag(flag),
90     fRawStreamTracker(new AliMUONRawStreamTracker()),    
91     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
92     fDigit(new AliMUONDigit()),
93     fLocalTrigger(new AliMUONLocalTrigger()),
94     fGlobalTrigger(new AliMUONGlobalTrigger()),
95     fCrateManager(0x0),
96     fTrackerTimer(),
97     fTriggerTimer(),
98     fMappingTimer()
99 {
100   /// ctor with AliMUONData as argument
101   /// for reconstruction
102
103   AliDebug(1,"");
104
105   // Standard Constructor
106
107   // bus patch 
108   fBusPatchManager->ReadBusPatchFile();
109
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 fBusPatchManager;
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   // generate digits
151   ReadTrackerDDL(rawReader);
152
153   // generate trigger
154   ReadTriggerDDL(rawReader);
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
185   fRawStreamTracker->SetReader(rawReader);
186
187   while(fRawStreamTracker->NextDDL()) {
188
189     ddlTracker =  fRawStreamTracker->GetDDLTracker();
190
191     Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
192     for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
193
194       blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
195  
196       Int_t nDsp = blkHeader->GetDspHeaderEntries();
197
198       for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){   //DSP loop
199
200         dspHeader =  blkHeader->GetDspHeaderEntry(iDsp);
201
202         Int_t nBusPatch = dspHeader->GetBusPatchEntries();
203
204         for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {  
205
206           busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
207
208           dataSize   = busStruct->GetLength();
209           buspatchId = busStruct->GetBusPatchId();
210
211           for (Int_t iData = 0; iData < dataSize; iData++) {
212
213             // digits info
214             parity    = busStruct->GetParity(iData); // test later for parity
215             manuId    = busStruct->GetManuId(iData);
216             channelId = busStruct->GetChannelId(iData);
217             charge    = busStruct->GetCharge(iData);
218             // set charge
219             fDigit->SetSignal(charge);
220             fDigit->SetPhysicsSignal(charge);
221             fDigit->SetADC(charge);
222
223             // Get Back the hits at pads
224             Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit); 
225             if (error) {
226               AliWarning("Mapping Error\n");
227               continue;
228             }
229             // debugging 
230             if (AliLog::GetGlobalDebugLevel() == 3) {
231               Int_t padX  = fDigit->PadX();
232               Int_t padY  = fDigit->PadY();
233               Int_t iCath = fDigit->Cathode();  
234               Int_t idDE  = fDigit->DetElemId();
235
236               AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
237                               idDE, buspatchId, padX, padY, iCath));
238                 
239               AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
240                               idDE, padX, padY, iCath, charge));
241             }
242
243             // fill digits
244             iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
245
246             if (fDigitFlag)
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 = fBusPatchManager->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
321   fTriggerTimer.Start(kFALSE);
322
323   fRawStreamTrigger->SetReader(rawReader);
324
325   while(fRawStreamTrigger->NextDDL()) {
326
327     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
328     darcHeader = ddlTrigger->GetDarcHeader();
329
330     // fill global trigger information in Digit Tree
331     if (fDigitFlag) {
332       if (darcHeader->GetGlobalFlag()) {
333         fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
334         fMUONData->AddGlobalTrigger(*fGlobalTrigger);
335       }
336     }
337
338     Int_t nReg = darcHeader->GetRegHeaderEntries();
339
340     for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
341
342       // crate info
343       if (!fCrateManager) AliFatal("Crate Store not defined");
344       AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
345   
346       if (!crate) 
347         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
348
349       TObjArray *boards  = crate->Boards();
350
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 has triggered
360         if (localStruct->GetTriggerY() == 0) {
361
362
363           AliMUONLocalTriggerBoard* localBoard = 
364             (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
365
366           loCircuit = localBoard->GetNumber();
367
368           if (fDigitFlag) {
369             // fill local trigger
370             fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
371
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                 fMUONData->AddSDigit(iChamber, *digit);
388
389               }
390
391             } // trigger digits
392           } // S flag
393
394         } // if triggerY
395       } // iLocal
396     } // iReg
397   } // NextDDL
398
399   fTriggerTimer.Stop();
400
401   return kTRUE;
402
403 }
404 //____________________________________________________________________
405 void AliMUONDigitMaker::GetTriggerChamber(AliMUONLocalStruct* localStruct, Int_t& xyPattern, 
406                                           Int_t& iChamber, Int_t& iCath, Int_t icase)
407 {
408   /// get chamber & cathode number, (chamber starts at 0 !)
409
410     switch(icase) {
411     case 0: 
412       xyPattern =  localStruct->GetX1();
413       iCath = 0;
414       iChamber = 10;
415       break;
416     case 1: 
417       xyPattern =  localStruct->GetX2();
418       iCath = 0;
419       iChamber = 11;
420       break;
421     case 2: 
422       xyPattern =  localStruct->GetX3();
423       iCath = 0;
424       iChamber = 12;
425       break;
426     case 3: 
427       xyPattern =  localStruct->GetX4();
428       iCath = 0;
429       iChamber = 13;
430       break;
431     case 4: 
432       xyPattern =  localStruct->GetY1();
433       iCath = 1;
434       iChamber = 10;
435       break;
436     case 5: 
437       xyPattern =  localStruct->GetY2();
438       iCath = 1;
439       iChamber = 11;
440       break;
441     case 6: 
442       xyPattern =  localStruct->GetY3();
443       iCath = 1;
444       iChamber = 12;
445       break;
446     case 7: 
447       xyPattern =  localStruct->GetY4();
448       iCath = 1;
449       iChamber = 13;
450       break;
451     }
452 }
453 //____________________________________________________________________
454 Int_t AliMUONDigitMaker::TriggerDigits(AliMUONLocalTriggerBoard* localBoard, 
455                                        AliMUONLocalStruct* localStruct,
456                                        TList& digitList)
457 {
458   /// make (S)Digit for trigger
459
460   Int_t detElemId;
461   Int_t nBoard;
462   Int_t iCath = -1;
463   Int_t iChamber = 0;
464   Int_t xyPattern = 0;
465
466   // loop over x1-4 and y1-4
467   for (Int_t icase = 0; icase < 8; icase++) {
468
469     // get chamber, cathode and associated trigger response pattern
470     GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
471   
472     if (!xyPattern) continue;
473
474     // get detElemId
475     AliMUONTriggerCircuit triggerCircuit;
476     detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
477     nBoard    = localBoard->GetNumber();
478
479     const AliMpVSegmentation* seg 
480       = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId, 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 }