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