- Adding hits pattern in trigger chambers in AliMUONTrack (Diego)
[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 #include <TArrayS.h>
80
81
82 /// \cond CLASSIMP
83 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
84 /// \endcond
85
86 //__________________________________________________________________________
87 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
88   : TObject(),
89     fMUONData(0x0),
90     fScalerEvent(kFALSE),
91     fDigitFlag(flag),
92     fTriggerFlag(kTRUE),
93     fDisplayFlag(kFALSE),
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   AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
131                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
132   AliDebug(1, Form("   Execution time for MUON tracker (mapping calls part) "
133                ": R:%.2fs C:%.2fs",
134                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
135   AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
136                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
137
138   return;
139 }
140
141 //____________________________________________________________________
142 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
143 {
144   /// Main method to creates digit
145   /// for tracker 
146   /// and trigger
147
148   // generate digits
149   ReadTrackerDDL(rawReader);
150
151   // generate trigger
152   if( fTriggerFlag)
153       ReadTriggerDDL(rawReader);
154   else
155       AliInfo("Reading trigger rawdata disable");
156
157   return kTRUE;
158
159 }
160
161 //____________________________________________________________________
162 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
163 {
164
165   /// reading tracker DDL
166   /// filling the TClonesArray in MUONData
167
168   fTrackerTimer.Start(kFALSE);
169
170   // elex info
171   Int_t    buspatchId;
172   UChar_t  channelId;
173   UShort_t manuId;
174   Char_t   parity;
175   UShort_t charge; 
176   Int_t    dataSize;
177
178   Int_t iChamber;
179
180   AliMUONDDLTracker*   ddlTracker = 0x0;
181   AliMUONBlockHeader*  blkHeader  = 0x0;
182   AliMUONDspHeader*    dspHeader  = 0x0;
183   AliMUONBusStruct*    busStruct  = 0x0;
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  
247             if (fDigitFlag || fDisplayFlag)
248                 fMUONData->AddDigit(iChamber, *fDigit);
249             else
250                 fMUONData->AddSDigit(iChamber, *fDigit);
251
252
253           } // iData
254         } // iBusPatch
255       } // iDsp
256     } // iBlock
257   } // NextDDL
258
259   fTrackerTimer.Stop();
260
261   return kTRUE;
262 }
263 //____________________________________________________________________
264 Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
265                                          UChar_t channelId, AliMUONDigit* digit )
266 {
267   /// mapping  for tracker
268
269   fMappingTimer.Start(kFALSE);
270   
271   // getting DE from buspatch
272   Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
273   AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
274
275   const AliMpVSegmentation* seg 
276     = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);  
277   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
278
279   if (!pad.IsValid())
280   {
281     AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
282                   detElemId, busPatchId, manuId, channelId));
283     fMappingTimer.Stop();
284     return kTRUE;
285   } // return error
286
287   // Getting padX, padY and cathode number.
288   Int_t padX = pad.GetIndices().GetFirst();
289   Int_t padY = pad.GetIndices().GetSecond();
290   Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
291
292   // storing into digits
293   digit->SetPadX(padX);
294   digit->SetPadY(padY);
295   digit->SetCathode(iCath);
296   digit->SetDetElemId(detElemId);
297   digit->SetElectronics(manuId,channelId);
298   
299   AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
300                   detElemId, busPatchId, manuId, channelId, padX, padY));
301 //  StdoutToAliDebug(3,digit->Print(););
302   
303   fMappingTimer.Stop();
304   return kFALSE;
305 }
306
307 //____________________________________________________________________
308 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
309 {
310   /// reading tracker DDL
311   /// filling the TClonesArray in MUONData
312
313   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
314   AliMUONDarcHeader*       darcHeader      = 0x0;
315   AliMUONRegHeader*        regHeader       = 0x0;
316   AliMUONLocalStruct*      localStruct     = 0x0;
317
318   Int_t loCircuit;
319   TList digitList;
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         if (!fDisplayFlag) {
334           fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
335           fMUONData->AddGlobalTrigger(*fGlobalTrigger);
336         }
337       }
338     }
339
340     Int_t nReg = darcHeader->GetRegHeaderEntries();
341
342     for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
343
344       // crate info
345       if (!fCrateManager) AliFatal("Crate Store not defined");
346       AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
347   
348       if (!crate) 
349         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
350
351       TObjArray *boards  = crate->Boards();
352
353       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
354
355       Int_t nLocal = regHeader->GetLocalEntries();
356       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {  
357         
358         localStruct = regHeader->GetLocalEntry(iLocal);
359
360         // if card exist
361         if (localStruct) {
362
363           AliMUONLocalTriggerBoard* localBoard = 
364             (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
365
366           // skip copy cards
367           if( !(loCircuit = localBoard->GetNumber()) )
368              continue;
369
370           if (fDigitFlag) {
371             // fill local trigger
372               fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
373               fMUONData->AddLocalTrigger(*fLocalTrigger);
374               
375           } else {
376             // Make SDigit
377
378             digitList.Clear();
379             //FIXEME should find something better than a TArray
380             TArrayS xyPattern[2];
381             xyPattern[0].Set(4);
382             xyPattern[1].Set(4);
383
384             xyPattern[0].AddAt(localStruct->GetX1(),0);
385             xyPattern[0].AddAt(localStruct->GetX2(),1);
386             xyPattern[0].AddAt(localStruct->GetX3(),2);
387             xyPattern[0].AddAt(localStruct->GetX4(),3);
388
389             xyPattern[1].AddAt(localStruct->GetY1(),0);
390             xyPattern[1].AddAt(localStruct->GetY2(),1);
391             xyPattern[1].AddAt(localStruct->GetY3(),2);
392             xyPattern[1].AddAt(localStruct->GetY4(),3);
393
394             if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
395
396               for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
397
398                 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
399                 
400                 // filling S container
401                 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
402                 if (!fDisplayFlag) {
403                   fMUONData->AddSDigit(iChamber, *digit);
404                 } else {
405                   fMUONData->AddDigit(iChamber, *digit);
406                 }
407
408               }
409
410             } // trigger digits
411           } // S flag
412
413         } // if triggerY
414       } // iLocal
415     } // iReg
416   } // NextDDL
417
418   fTriggerTimer.Stop();
419
420   return kTRUE;
421
422 }
423
424 //____________________________________________________________________
425 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
426                                        TArrayS* xyPattern,
427                                        TList& digitList)
428 {
429   /// make (S)Digit for trigger
430
431   Int_t detElemId;
432   Int_t previousDetElemId[4] = {0};
433   Int_t previousBoard[4] = {0};
434
435   // loop over x1-4 and y1-4
436   for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
437     for(Int_t iCath = 0; iCath < 2; ++iCath){
438   
439       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
440       if (!pattern) continue;
441
442       // get detElemId
443       AliMUONTriggerCircuit triggerCircuit;
444       AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
445       detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
446
447
448       if(iCath == 1){ // FIXME should find a more elegant way
449         // Don't save twice the same digit
450         // (since strips in non bending plane can cross several boards)
451         Int_t prevDetElemId = previousDetElemId[iChamber];
452         Int_t prevBoard = previousBoard[iChamber];
453         previousDetElemId[iChamber] = detElemId;
454         previousBoard[iChamber] = nBoard;
455
456         if(detElemId == prevDetElemId){
457           if(nBoard-prevBoard==1) continue;
458         }
459       }
460
461       const AliMpVSegmentation* seg 
462           = AliMpSegmentation::Instance()
463           ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
464
465       // loop over the 16 bits of pattern
466       for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
467     
468         if ((pattern >> ibitxy) & 0x1) {
469
470           // not quite sure about this
471           Int_t offset = 0;
472           if (iCath && localBoard->GetSwitch(6)) offset = -8;
473
474           AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
475
476           AliMUONDigit* digit = new  AliMUONDigit();
477           if (!pad.IsValid()) {
478             AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
479                             detElemId, nBoard, ibitxy));
480             continue;
481           } // 
482
483           Int_t padX = pad.GetIndices().GetFirst();
484           Int_t padY = pad.GetIndices().GetSecond();
485
486           // file digit
487           digit->SetPadX(padX);
488           digit->SetPadY(padY);
489           digit->SetSignal(1.);
490           digit->SetCathode(iCath);
491           digit->SetDetElemId(detElemId);
492           digit->SetElectronics(nBoard, ibitxy);
493           digitList.Add(digit);
494         
495         }// xyPattern
496       }// ibitxy
497     }// cath
498   } // ichamber
499
500   return kTRUE;
501
502 //____________________________________________________________________
503 void  AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
504 {
505   /// set crate name from DDL & reg number
506   /// method same as in RawWriter, not so nice
507   /// should be put in AliMUONTriggerCrateStore
508
509       switch(iReg) {
510       case 0:
511       case 1:
512         sprintf(name,"%d", iReg+1);
513         break;
514       case 2:
515         strcpy(name, "2-3");
516         break;
517       case 3:
518       case 4:
519       case 5:
520       case 6:
521       case 7:
522         sprintf(name,"%d", iReg);
523         break;
524       }
525
526       // crate Right for first DDL
527       if (iDDL == 0)
528         strcat(name, "R");
529       else 
530         strcat(name, "L"); 
531 }