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