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