]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
Implemented Raw2SDigits for trigger (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 in ALICE-MUON
19 /// Using new interface with AliMUONRawStreamTracker(Trigger)
20 /// (New interface of AliMUONRawReader class)
21 /// Class version 1 (further details could be found in Alice-note)
22 ///
23 /// Implemented non-constant buspatch numbers for tracking
24 /// with correct DDL id (first guess)
25 /// (Ch. Finck, dec 2005)
26 ///
27 ///
28 /// Raw2Digits:
29 /// Using real mapping  for tracker
30 /// Indranil Das (Adapted for runloader: Ch. Finck) july 05
31 /// Add reader for scaler trigger events
32 /// Use memcpy instead of assignment elt by elt
33 /// (Ch. Finck, Jan 06)
34 /// 
35 ////////////////////////////////////
36
37 #include <fstream>
38 #include <string>
39
40 #include <TClonesArray.h>
41 #include <TList.h>
42
43 #include "AliRawReader.h"
44 #include "AliRawDataHeader.h"
45 #include "AliLog.h"
46 #include "AliRun.h"
47
48 #include "AliMpBusPatch.h"
49 #include "AliMUON.h"
50 #include "AliMUONDigitMaker.h"
51 #include "AliMUONDigit.h"
52
53 #include "AliMUONConstants.h"
54 #include "AliMUONData.h"
55
56 #include "AliMUONRawStreamTracker.h"
57 #include "AliMUONDDLTracker.h"
58 #include "AliMUONDspHeader.h"
59 #include "AliMUONBlockHeader.h"
60 #include "AliMUONBusStruct.h"
61
62 #include "AliMUONRawStreamTrigger.h"
63 #include "AliMUONDDLTrigger.h"
64 #include "AliMUONDarcHeader.h"
65 #include "AliMUONRegHeader.h"
66 #include "AliMUONLocalStruct.h"
67
68 #include "AliMUONTriggerCrateStore.h"
69 #include "AliMUONTriggerCrate.h"
70 #include "AliMUONLocalTriggerBoard.h"
71 #include "AliMUONLocalTrigger.h"
72 #include "AliMUONGlobalTrigger.h"
73 #include "AliMUONTriggerCircuitNew.h"
74 #include "AliMpSegFactory.h"
75 #include "AliMpVSegmentation.h"
76 #include "AliMpPad.h"
77 #include "AliMpDEManager.h"
78
79 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
80 //__________________________________________________________________________
81 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
82   : TObject(),
83     fMUONData(0x0),
84     fSegFactory(new AliMpSegFactory()),
85     fBusPatchManager(new AliMpBusPatch()),
86     fScalerEvent(kFALSE),
87     fDigitFlag(flag),
88     fRawStreamTracker(new AliMUONRawStreamTracker()),    
89     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
90     fDigit(new AliMUONDigit()),
91     fLocalTrigger(new AliMUONLocalTrigger()),
92     fGlobalTrigger(new AliMUONGlobalTrigger()),
93     fCrateManager(new AliMUONTriggerCrateStore()),
94     fTrackerTimer(),
95     fTriggerTimer(),
96     fMappingTimer()
97 {
98   //
99   // ctor with AliMUONData as argument
100   // for reconstruction
101   //
102
103   AliDebug(1,"");
104
105   // Standard Constructor
106
107   // bus patch 
108   fBusPatchManager->ReadBusPatchFile();
109
110   // Crate manager
111   fCrateManager->ReadFromFile();
112
113   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
114   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
115   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
116
117 }
118
119 //__________________________________________________________________________
120 AliMUONDigitMaker::~AliMUONDigitMaker()
121 {
122   //
123   // clean up
124   // and time processing measure
125   //
126   delete fSegFactory;  
127
128   delete fRawStreamTracker;
129   delete fRawStreamTrigger;
130
131   delete fDigit;
132   delete fLocalTrigger;
133   delete fGlobalTrigger;
134
135   delete fCrateManager;
136
137   delete fBusPatchManager;
138
139   AliInfo(Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
140                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
141   AliInfo(Form("   Execution time for MUON tracker (mapping calls part) "
142                ": R:%.2fs C:%.2fs",
143                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
144   AliInfo(Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
145                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
146
147   return;
148 }
149
150 //____________________________________________________________________
151 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
152 {
153   // Main method to creates digit
154   // for tracker 
155   // and trigger
156
157   // generate digits
158   ReadTrackerDDL(rawReader);
159
160   // generate trigger
161   ReadTriggerDDL(rawReader);
162
163   return kTRUE;
164
165 }
166
167 //____________________________________________________________________
168 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
169 {
170
171   // reading tracker DDL
172   // filling the TClonesArray in MUONData
173   //
174   fTrackerTimer.Start(kFALSE);
175
176   // elex info
177   Int_t    buspatchId;
178   UChar_t  channelId;
179   UShort_t manuId;
180   Char_t   parity;
181   UShort_t charge; 
182   Int_t    dataSize;
183
184   Int_t iChamber;
185
186   AliMUONDDLTracker*   ddlTracker = 0x0;
187   AliMUONBlockHeader*  blkHeader  = 0x0;
188   AliMUONDspHeader*    dspHeader  = 0x0;
189   AliMUONBusStruct*    busStruct  = 0x0;
190
191
192   fRawStreamTracker->SetReader(rawReader);
193
194   while(fRawStreamTracker->NextDDL()) {
195
196     ddlTracker =  fRawStreamTracker->GetDDLTracker();
197
198     Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
199     for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
200
201       blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
202  
203       Int_t nDsp = blkHeader->GetDspHeaderEntries();
204
205       for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){   //DSP loop
206
207         dspHeader =  blkHeader->GetDspHeaderEntry(iDsp);
208
209         Int_t nBusPatch = dspHeader->GetBusPatchEntries();
210
211         for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {  
212
213           busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
214
215           dataSize   = busStruct->GetLength();
216           buspatchId = busStruct->GetBusPatchId();
217
218           for (Int_t iData = 0; iData < dataSize; iData++) {
219
220             // digits info
221             parity    = busStruct->GetParity(iData); // test later for parity
222             manuId    = busStruct->GetManuId(iData);
223             channelId = busStruct->GetChannelId(iData);
224             charge    = busStruct->GetCharge(iData);
225             // set charge
226             fDigit->SetSignal(charge);
227             fDigit->SetPhysicsSignal(charge);
228             fDigit->SetADC(charge);
229
230             // Get Back the hits at pads
231             Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit); 
232             if (error) {
233               AliWarning("Mapping Error\n");
234               continue;
235             }
236             // debugging 
237             if (AliLog::GetGlobalDebugLevel() == 3) {
238               Int_t padX  = fDigit->PadX();
239               Int_t padY  = fDigit->PadY();
240               Int_t iCath = fDigit->Cathode();  
241               Int_t idDE  = fDigit->DetElemId();
242
243               AliDebug(1,Form("output  IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n", 
244                               idDE, buspatchId, padX, padY, iCath));
245                 
246               AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
247                               idDE, padX, padY, iCath, charge));
248             }
249
250             // fill digits
251             iChamber = fDigit->DetElemId()/100 - 1;
252
253             if (fDigitFlag)
254               fMUONData->AddDigit(iChamber, *fDigit);
255             else
256               fMUONData->AddSDigit(iChamber, *fDigit);
257
258
259           } // iData
260         } // iBusPatch
261       } // iDsp
262     } // iBlock
263   } // NextDDL
264
265   fTrackerTimer.Stop();
266
267   return kTRUE;
268 }
269 //____________________________________________________________________
270 Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId, 
271                                          UChar_t channelId, AliMUONDigit* digit )
272 {
273   //
274   // mapping  for tracker
275   //
276   fMappingTimer.Start(kFALSE);
277   
278   // getting DE from buspatch
279   Int_t detElemId = fBusPatchManager->GetDEfromBus(busPatchId);
280   AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
281
282   AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentationByElectronics(detElemId, manuId);  
283   AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
284
285   if (!pad.IsValid())
286   {
287     AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
288                   detElemId, busPatchId, manuId, channelId));
289     fMappingTimer.Stop();
290     return kTRUE;
291   } // return error
292
293   // Getting padX, padY and cathode number.
294   Int_t padX = pad.GetIndices().GetFirst();
295   Int_t padY = pad.GetIndices().GetSecond();
296   Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
297
298   // storing into digits
299   digit->SetPadX(padX);
300   digit->SetPadY(padY);
301   digit->SetCathode(iCath);
302   digit->SetDetElemId(detElemId);
303   digit->SetElectronics(manuId,channelId);
304   
305   AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
306                   detElemId, busPatchId, manuId, channelId, padX, padY));
307   StdoutToAliDebug(3,digit->Print(););
308   
309   fMappingTimer.Stop();
310   return kFALSE;
311 }
312
313 //____________________________________________________________________
314 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
315 {
316   // reading tracker DDL
317   // filling the TClonesArray in MUONData
318   //
319
320   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
321   AliMUONDarcHeader*       darcHeader      = 0x0;
322   AliMUONRegHeader*        regHeader       = 0x0;
323   AliMUONLocalStruct*      localStruct     = 0x0;
324
325   Int_t loCircuit;
326   TList digitList;
327
328
329   fTriggerTimer.Start(kFALSE);
330
331   fRawStreamTrigger->SetReader(rawReader);
332
333   while(fRawStreamTrigger->NextDDL()) {
334
335     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
336     darcHeader = ddlTrigger->GetDarcHeader();
337
338     // fill global trigger information in Digit Tree
339     if (fDigitFlag) {
340       if (darcHeader->GetGlobalFlag()) {
341         fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
342         fMUONData->AddGlobalTrigger(*fGlobalTrigger);
343       }
344     }
345
346     Int_t nReg = darcHeader->GetRegHeaderEntries();
347
348     for(Int_t iReg = 0; iReg < nReg ;iReg++){   //reg loop
349
350      // crate info
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 = digit->DetElemId()/100 - 1;
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
417     switch(icase) {
418     case 0: 
419       xyPattern =  localStruct->GetX1();
420       iCath = 0;
421       iChamber = 11;
422       break;
423     case 1: 
424       xyPattern =  localStruct->GetX2();
425       iCath = 0;
426       iChamber = 12;
427       break;
428     case 2: 
429       xyPattern =  localStruct->GetX3();
430       iCath = 0;
431       iChamber = 13;
432       break;
433     case 3: 
434       xyPattern =  localStruct->GetX4();
435       iCath = 0;
436       iChamber = 14;
437       break;
438     case 4: 
439       xyPattern =  localStruct->GetY1();
440       iCath = 1;
441       iChamber = 11;
442       break;
443     case 5: 
444       xyPattern =  localStruct->GetY2();
445       iCath = 1;
446       iChamber = 12;
447       break;
448     case 6: 
449       xyPattern =  localStruct->GetY3();
450       iCath = 1;
451       iChamber = 13;
452       break;
453     case 7: 
454       xyPattern =  localStruct->GetY4();
455       iCath = 1;
456       iChamber = 14;
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 }