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