]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
- Removing AliMpSegFactory -> using AliMpSegmentation instead
[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 "AliMUON.h"
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 "AliMUONTriggerCircuitNew.h"
65
66 #include "AliMpSegmentation.h"
67 #include "AliMpVSegmentation.h"
68 #include "AliMpPad.h"
69 #include "AliMpDEManager.h"
70 #include "AliMpBusPatch.h"
71
72 #include "AliRawReader.h"
73 #include "AliRawDataHeader.h"
74 #include "AliLog.h"
75 #include "AliRun.h"
76
77 #include <TClonesArray.h>
78 #include <TList.h>
79
80 #include <fstream>
81 #include <string>
82
83 /// \cond CLASSIMP
84 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
85 /// \endcond
86
87 //__________________________________________________________________________
88 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
89   : TObject(),
90     fMUONData(0x0),
91     fBusPatchManager(new AliMpBusPatch()),
92     fScalerEvent(kFALSE),
93     fDigitFlag(flag),
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   // bus patch 
112   fBusPatchManager->ReadBusPatchFile();
113
114  
115   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
116   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
117   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
118
119 }
120
121 //__________________________________________________________________________
122 AliMUONDigitMaker::~AliMUONDigitMaker()
123 {
124   /// clean up
125   /// and time processing measure
126
127   delete fRawStreamTracker;
128   delete fRawStreamTrigger;
129
130   delete fDigit;
131   delete fLocalTrigger;
132   delete fGlobalTrigger;
133
134   delete fBusPatchManager;
135
136   AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
137                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
138   AliDebug(1, Form("   Execution time for MUON tracker (mapping calls part) "
139                ": R:%.2fs C:%.2fs",
140                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
141   AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
142                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
143
144   return;
145 }
146
147 //____________________________________________________________________
148 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
149 {
150   /// Main method to creates digit
151   /// for tracker 
152   /// and trigger
153
154   // generate digits
155   ReadTrackerDDL(rawReader);
156
157   // generate trigger
158   ReadTriggerDDL(rawReader);
159
160   return kTRUE;
161
162 }
163
164 //____________________________________________________________________
165 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
166 {
167
168   /// reading tracker DDL
169   /// filling the TClonesArray in MUONData
170
171   fTrackerTimer.Start(kFALSE);
172
173   // elex info
174   Int_t    buspatchId;
175   UChar_t  channelId;
176   UShort_t manuId;
177   Char_t   parity;
178   UShort_t charge; 
179   Int_t    dataSize;
180
181   Int_t iChamber;
182
183   AliMUONDDLTracker*   ddlTracker = 0x0;
184   AliMUONBlockHeader*  blkHeader  = 0x0;
185   AliMUONDspHeader*    dspHeader  = 0x0;
186   AliMUONBusStruct*    busStruct  = 0x0;
187
188
189   fRawStreamTracker->SetReader(rawReader);
190
191   while(fRawStreamTracker->NextDDL()) {
192
193     ddlTracker =  fRawStreamTracker->GetDDLTracker();
194
195     Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
196     for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
197
198       blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
199  
200       Int_t nDsp = blkHeader->GetDspHeaderEntries();
201
202       for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){   //DSP loop
203
204         dspHeader =  blkHeader->GetDspHeaderEntry(iDsp);
205
206         Int_t nBusPatch = dspHeader->GetBusPatchEntries();
207
208         for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {  
209
210           busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
211
212           dataSize   = busStruct->GetLength();
213           buspatchId = busStruct->GetBusPatchId();
214
215           for (Int_t iData = 0; iData < dataSize; iData++) {
216
217             // digits info
218             parity    = busStruct->GetParity(iData); // test later for parity
219             manuId    = busStruct->GetManuId(iData);
220             channelId = busStruct->GetChannelId(iData);
221             charge    = busStruct->GetCharge(iData);
222             // set charge
223             fDigit->SetSignal(charge);
224             fDigit->SetPhysicsSignal(charge);
225             fDigit->SetADC(charge);
226
227             // Get Back the hits at pads
228             Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit); 
229             if (error) {
230               AliWarning("Mapping Error\n");
231               continue;
232             }
233             // debugging 
234             if (AliLog::GetGlobalDebugLevel() == 3) {
235               Int_t padX  = fDigit->PadX();
236               Int_t padY  = fDigit->PadY();
237               Int_t iCath = fDigit->Cathode();  
238               Int_t idDE  = fDigit->DetElemId();
239
240               AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
241                               idDE, buspatchId, padX, padY, iCath));
242                 
243               AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
244                               idDE, padX, padY, iCath, charge));
245             }
246
247             // fill digits
248             iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
249
250             if (fDigitFlag)
251               fMUONData->AddDigit(iChamber, *fDigit);
252             else
253               fMUONData->AddSDigit(iChamber, *fDigit);
254
255
256           } // iData
257         } // iBusPatch
258       } // iDsp
259     } // iBlock
260   } // NextDDL
261
262   fTrackerTimer.Stop();
263
264   return kTRUE;
265 }
266 //____________________________________________________________________
267 Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
268                                          UChar_t channelId, AliMUONDigit* digit )
269 {
270   /// mapping  for tracker
271
272   fMappingTimer.Start(kFALSE);
273   
274   // getting DE from buspatch
275   Int_t detElemId = fBusPatchManager->GetDEfromBus(busPatchId);
276   AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
277
278   const AliMpVSegmentation* seg 
279     = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);  
280   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
281
282   if (!pad.IsValid())
283   {
284     AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
285                   detElemId, busPatchId, manuId, channelId));
286     fMappingTimer.Stop();
287     return kTRUE;
288   } // return error
289
290   // Getting padX, padY and cathode number.
291   Int_t padX = pad.GetIndices().GetFirst();
292   Int_t padY = pad.GetIndices().GetSecond();
293   Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
294
295   // storing into digits
296   digit->SetPadX(padX);
297   digit->SetPadY(padY);
298   digit->SetCathode(iCath);
299   digit->SetDetElemId(detElemId);
300   digit->SetElectronics(manuId,channelId);
301   
302   AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
303                   detElemId, busPatchId, manuId, channelId, padX, padY));
304   StdoutToAliDebug(3,digit->Print(););
305   
306   fMappingTimer.Stop();
307   return kFALSE;
308 }
309
310 //____________________________________________________________________
311 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
312 {
313   /// reading tracker DDL
314   /// filling the TClonesArray in MUONData
315
316   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
317   AliMUONDarcHeader*       darcHeader      = 0x0;
318   AliMUONRegHeader*        regHeader       = 0x0;
319   AliMUONLocalStruct*      localStruct     = 0x0;
320
321   Int_t loCircuit;
322   TList digitList;
323
324
325   fTriggerTimer.Start(kFALSE);
326
327   fRawStreamTrigger->SetReader(rawReader);
328
329   while(fRawStreamTrigger->NextDDL()) {
330
331     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
332     darcHeader = ddlTrigger->GetDarcHeader();
333
334     // fill global trigger information in Digit Tree
335     if (fDigitFlag) {
336       if (darcHeader->GetGlobalFlag()) {
337         fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
338         fMUONData->AddGlobalTrigger(*fGlobalTrigger);
339       }
340     }
341
342     Int_t nReg = darcHeader->GetRegHeaderEntries();
343
344     for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
345
346       // crate info
347       if (!fCrateManager) AliFatal("Crate Store not defined");
348       AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
349   
350       if (!crate) 
351         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
352
353       TObjArray *boards  = crate->Boards();
354
355
356       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
357
358       Int_t nLocal = regHeader->GetLocalEntries();
359       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {  
360
361         localStruct = regHeader->GetLocalEntry(iLocal);
362
363         // if card has triggered
364         if (localStruct->GetTriggerY() == 0) {
365
366
367           AliMUONLocalTriggerBoard* localBoard = 
368             (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
369
370           loCircuit = localBoard->GetNumber();
371
372           if (fDigitFlag) {
373             // fill local trigger
374             fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
375
376             fMUONData->AddLocalTrigger(*fLocalTrigger);
377
378           } else {
379             // Make SDigit
380
381             digitList.Clear();
382             
383             if( TriggerDigits(localBoard, localStruct, digitList) ) {
384
385               for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
386
387                 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
388                 
389                 // filling S container
390                 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
391                 fMUONData->AddSDigit(iChamber, *digit);
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     AliMUONTriggerCircuitNew triggerCircuit;
480     detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
481     nBoard    = localBoard->GetNumber();
482
483     const AliMpVSegmentation* seg 
484       = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId, iCath);  
485
486     // loop over the 16 bits of pattern
487     for (Int_t ibitxy = 0; ibitxy < 16; ibitxy++) {
488     
489       if ((xyPattern >> ibitxy) & 0x1) {
490
491         // not quite sure about this
492         Int_t offset = 0;
493         if (iCath && localBoard->GetSwitch(6)) offset = -8;
494
495         AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
496
497         AliMUONDigit* digit = new  AliMUONDigit();
498         if (!pad.IsValid()) {
499           AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
500                           detElemId, nBoard, ibitxy));
501           continue;
502         } // 
503
504         Int_t padX = pad.GetIndices().GetFirst();
505         Int_t padY = pad.GetIndices().GetSecond();
506
507         // file digit
508         digit->SetPadX(padX);
509         digit->SetPadY(padY);
510         digit->SetCathode(iCath);
511         digit->SetDetElemId(detElemId);
512         digit->SetElectronics(nBoard, ibitxy);
513         digitList.Add(digit);
514         
515       }// xyPattern
516     }// ibitxy
517   }// case
518
519   return kTRUE;
520
521 //____________________________________________________________________
522 void  AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg)
523 {
524   /// set crate name from DDL & reg number
525   /// method same as in RawWriter, not so nice
526   /// should be put in AliMUONTriggerCrateStore
527
528       switch(iReg) {
529       case 0:
530       case 1:
531         sprintf(name,"%d", iReg+1);
532         break;
533       case 2:
534         strcpy(name, "2-3");
535         break;
536       case 3:
537       case 4:
538       case 5:
539       case 6:
540       case 7:
541         sprintf(name,"%d", iReg);
542         break;
543       }
544
545       // crate Right for first DDL
546       if (iDDL == 0)
547         strcat(name, "R");
548       else 
549         strcat(name, "L"); 
550 }