Rewritten using new VDigitStore and VDigit interfaces (Laurent)
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
CommitLineData
a3283a4c 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
9265505b 16/// \class AliMUONDigitMaker
8c51a32f 17/// MUON Digit maker from rawdata.
a3283a4c 18///
19/// Raw2Digits:
20/// Using real mapping for tracker
21/// Indranil Das (Adapted for runloader: Ch. Finck) july 05
8c51a32f 22///
23/// Implemented non-constant buspatch numbers for tracking
24/// with correct DDL id.
25/// (Ch. Finck, dec 05)
26///
a3283a4c 27/// Add reader for scaler trigger events
28/// Use memcpy instead of assignment elt by elt
29/// (Ch. Finck, Jan 06)
8c51a32f 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.
78649106 38///
39/// \author Ch. Finck, oct 06
a3283a4c 40
a3283a4c 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
d53fb0de 59#include "AliMUONTriggerCrateStore.h"
60#include "AliMUONTriggerCrate.h"
61#include "AliMUONLocalTriggerBoard.h"
a3283a4c 62#include "AliMUONLocalTrigger.h"
63#include "AliMUONGlobalTrigger.h"
e1a10d41 64#include "AliMUONTriggerCircuit.h"
9265505b 65
66#include "AliMpSegmentation.h"
a3283a4c 67#include "AliMpVSegmentation.h"
68#include "AliMpPad.h"
69#include "AliMpDEManager.h"
e5ced899 70#include "AliMpDDLStore.h"
71#include "AliMpCathodType.h"
a3283a4c 72
9265505b 73#include "AliRawReader.h"
74#include "AliRawDataHeader.h"
75#include "AliLog.h"
76#include "AliRun.h"
77
9265505b 78#include <TList.h>
7771752e 79#include <TArrayS.h>
9265505b 80
9265505b 81
82/// \cond CLASSIMP
a3283a4c 83ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
9265505b 84/// \endcond
85
a3283a4c 86//__________________________________________________________________________
241560c2 87AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
a3283a4c 88 : TObject(),
aa6ecf89 89 fMUONData(0x0),
9f5dcca3 90 fScalerEvent(kFALSE),
241560c2 91 fDigitFlag(flag),
e604ac4c 92 fTriggerFlag(kTRUE),
8a91c35f 93 fDisplayFlag(kFALSE),
9f5dcca3 94 fRawStreamTracker(new AliMUONRawStreamTracker()),
95 fRawStreamTrigger(new AliMUONRawStreamTrigger()),
96 fDigit(new AliMUONDigit()),
97 fLocalTrigger(new AliMUONLocalTrigger()),
98 fGlobalTrigger(new AliMUONGlobalTrigger()),
fe5010dd 99 fCrateManager(0x0),
9f5dcca3 100 fTrackerTimer(),
101 fTriggerTimer(),
102 fMappingTimer()
a3283a4c 103{
9265505b 104 /// ctor with AliMUONData as argument
105 /// for reconstruction
a3283a4c 106
107 AliDebug(1,"");
108
109 // Standard Constructor
110
a3283a4c 111 fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
112 fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
113 fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
114
115}
116
117//__________________________________________________________________________
9f5dcca3 118AliMUONDigitMaker::~AliMUONDigitMaker()
a3283a4c 119{
9265505b 120 /// clean up
121 /// and time processing measure
122
a3283a4c 123 delete fRawStreamTracker;
124 delete fRawStreamTrigger;
125
126 delete fDigit;
127 delete fLocalTrigger;
128 delete fGlobalTrigger;
129
a7b01aa5 130 AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
a3283a4c 131 fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
a7b01aa5 132 AliDebug(1, Form(" Execution time for MUON tracker (mapping calls part) "
a3283a4c 133 ": R:%.2fs C:%.2fs",
134 fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
a7b01aa5 135 AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
a3283a4c 136 fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
137
138 return;
139}
140
141//____________________________________________________________________
142Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
143{
9265505b 144 /// Main method to creates digit
145 /// for tracker
146 /// and trigger
a3283a4c 147
148 // generate digits
149 ReadTrackerDDL(rawReader);
150
151 // generate trigger
e604ac4c 152 if( fTriggerFlag)
153 ReadTriggerDDL(rawReader);
154 else
155 AliInfo("Reading trigger rawdata disable");
a3283a4c 156
157 return kTRUE;
158
159}
160
161//____________________________________________________________________
162Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
163{
164
9265505b 165 /// reading tracker DDL
166 /// filling the TClonesArray in MUONData
167
a3283a4c 168 fTrackerTimer.Start(kFALSE);
169
170 // elex info
171 Int_t buspatchId;
172 UChar_t channelId;
173 UShort_t manuId;
a3283a4c 174 UShort_t charge;
a3283a4c 175
e6e1f642 176 Int_t iChamber;
177
a3283a4c 178 fRawStreamTracker->SetReader(rawReader);
1bc885f3 179 fRawStreamTracker->First();
180
181 while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
182 {
a3283a4c 183 fDigit->SetSignal(charge);
184 fDigit->SetPhysicsSignal(charge);
185 fDigit->SetADC(charge);
186
187 // Get Back the hits at pads
188 Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit);
1bc885f3 189 if (error)
190 {
e6e1f642 191 AliWarning("Mapping Error\n");
84ceeb06 192 continue;
193 }
1bc885f3 194
195 // debugging
196 if (AliLog::GetGlobalDebugLevel() == 3)
197 {
a3283a4c 198 Int_t padX = fDigit->PadX();
199 Int_t padY = fDigit->PadY();
200 Int_t iCath = fDigit->Cathode();
201 Int_t idDE = fDigit->DetElemId();
202
203 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
204 idDE, buspatchId, padX, padY, iCath));
205
206 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
207 idDE, padX, padY, iCath, charge));
208 }
209
210 // fill digits
66f4c572 211 iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
241560c2 212
d000f173 213 if (fDigitFlag || fDisplayFlag)
1bc885f3 214 {
215 fMUONData->AddDigit(iChamber, *fDigit);
216 }
d000f173 217 else
1bc885f3 218 {
219 fMUONData->AddSDigit(iChamber, *fDigit);
220 }
221 }
222
a3283a4c 223 fTrackerTimer.Stop();
224
225 return kTRUE;
226}
1bc885f3 227
a3283a4c 228//____________________________________________________________________
229Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId,
230 UChar_t channelId, AliMUONDigit* digit )
231{
9265505b 232 /// mapping for tracker
233
a3283a4c 234 fMappingTimer.Start(kFALSE);
235
236 // getting DE from buspatch
e5ced899 237 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
a3283a4c 238 AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
239
9265505b 240 const AliMpVSegmentation* seg
241 = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);
a3283a4c 242 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
243
244 if (!pad.IsValid())
245 {
246 AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
247 detElemId, busPatchId, manuId, channelId));
248 fMappingTimer.Stop();
249 return kTRUE;
250 } // return error
251
252 // Getting padX, padY and cathode number.
253 Int_t padX = pad.GetIndices().GetFirst();
254 Int_t padY = pad.GetIndices().GetSecond();
255 Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
256
257 // storing into digits
258 digit->SetPadX(padX);
259 digit->SetPadY(padY);
260 digit->SetCathode(iCath);
261 digit->SetDetElemId(detElemId);
262 digit->SetElectronics(manuId,channelId);
263
264 AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
265 detElemId, busPatchId, manuId, channelId, padX, padY));
6159fc91 266// StdoutToAliDebug(3,digit->Print(););
a3283a4c 267
268 fMappingTimer.Stop();
269 return kFALSE;
270}
271
272//____________________________________________________________________
273Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
274{
9265505b 275 /// reading tracker DDL
276 /// filling the TClonesArray in MUONData
a3283a4c 277
278 AliMUONDDLTrigger* ddlTrigger = 0x0;
279 AliMUONDarcHeader* darcHeader = 0x0;
280 AliMUONRegHeader* regHeader = 0x0;
281 AliMUONLocalStruct* localStruct = 0x0;
282
283 Int_t loCircuit;
d2d759cf 284 TList digitList;
285
a3283a4c 286 fTriggerTimer.Start(kFALSE);
287
288 fRawStreamTrigger->SetReader(rawReader);
289
290 while(fRawStreamTrigger->NextDDL()) {
8a91c35f 291
a3283a4c 292 ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
293 darcHeader = ddlTrigger->GetDarcHeader();
294
d2d759cf 295 // fill global trigger information in Digit Tree
296 if (fDigitFlag) {
297 if (darcHeader->GetGlobalFlag()) {
8a91c35f 298 if (!fDisplayFlag) {
299 fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
300 fMUONData->AddGlobalTrigger(*fGlobalTrigger);
301 }
d2d759cf 302 }
a3283a4c 303 }
304
305 Int_t nReg = darcHeader->GetRegHeaderEntries();
306
307 for(Int_t iReg = 0; iReg < nReg ;iReg++){ //reg loop
308
fe5010dd 309 // crate info
310 if (!fCrateManager) AliFatal("Crate Store not defined");
aa6ecf89 311 AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
d53fb0de 312
313 if (!crate)
314 AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
315
316 TObjArray *boards = crate->Boards();
317
a3283a4c 318 regHeader = darcHeader->GetRegHeaderEntry(iReg);
319
320 Int_t nLocal = regHeader->GetLocalEntries();
a3283a4c 321 for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {
8a91c35f 322
a3283a4c 323 localStruct = regHeader->GetLocalEntry(iLocal);
324
5a92f8e6 325 // if card exist
326 if (localStruct) {
d2d759cf 327
d53fb0de 328 AliMUONLocalTriggerBoard* localBoard =
329 (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
330
5a92f8e6 331 // skip copy cards
332 if( !(loCircuit = localBoard->GetNumber()) )
333 continue;
d2d759cf 334
335 if (fDigitFlag) {
336 // fill local trigger
8a91c35f 337 fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
338 fMUONData->AddLocalTrigger(*fLocalTrigger);
d000f173 339
d2d759cf 340 } else {
341 // Make SDigit
342
343 digitList.Clear();
7771752e 344 //FIXEME should find something better than a TArray
345 TArrayS xyPattern[2];
346 xyPattern[0].Set(4);
347 xyPattern[1].Set(4);
348
349 xyPattern[0].AddAt(localStruct->GetX1(),0);
350 xyPattern[0].AddAt(localStruct->GetX2(),1);
351 xyPattern[0].AddAt(localStruct->GetX3(),2);
352 xyPattern[0].AddAt(localStruct->GetX4(),3);
353
354 xyPattern[1].AddAt(localStruct->GetY1(),0);
355 xyPattern[1].AddAt(localStruct->GetY2(),1);
356 xyPattern[1].AddAt(localStruct->GetY3(),2);
357 xyPattern[1].AddAt(localStruct->GetY4(),3);
358
359 if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
d2d759cf 360
361 for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
362
363 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
364
365 // filling S container
66f4c572 366 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
8a91c35f 367 if (!fDisplayFlag) {
368 fMUONData->AddSDigit(iChamber, *digit);
369 } else {
d000f173 370 fMUONData->AddDigit(iChamber, *digit);
8a91c35f 371 }
d2d759cf 372
373 }
374
375 } // trigger digits
376 } // S flag
a3283a4c 377
a3283a4c 378 } // if triggerY
379 } // iLocal
380 } // iReg
381 } // NextDDL
382
383 fTriggerTimer.Stop();
384
385 return kTRUE;
386
387}
7771752e 388
d2d759cf 389//____________________________________________________________________
7771752e 390Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
391 TArrayS* xyPattern,
d2d759cf 392 TList& digitList)
393{
9265505b 394 /// make (S)Digit for trigger
d2d759cf 395
396 Int_t detElemId;
7771752e 397 Int_t previousDetElemId[4] = {0};
398 Int_t previousBoard[4] = {0};
d2d759cf 399
400 // loop over x1-4 and y1-4
7771752e 401 for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
402 for(Int_t iCath = 0; iCath < 2; ++iCath){
d2d759cf 403
7771752e 404 Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
405 if (!pattern) continue;
406
407 // get detElemId
408 AliMUONTriggerCircuit triggerCircuit;
409 AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
410 detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
411
d2d759cf 412
7771752e 413 if(iCath == 1){ // FIXME should find a more elegant way
414 // Don't save twice the same digit
415 // (since strips in non bending plane can cross several boards)
416 Int_t prevDetElemId = previousDetElemId[iChamber];
417 Int_t prevBoard = previousBoard[iChamber];
418 previousDetElemId[iChamber] = detElemId;
419 previousBoard[iChamber] = nBoard;
420
421 if(detElemId == prevDetElemId){
422 if(nBoard-prevBoard==1) continue;
423 }
424 }
d2d759cf 425
7771752e 426 const AliMpVSegmentation* seg
427 = AliMpSegmentation::Instance()
428 ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
d2d759cf 429
7771752e 430 // loop over the 16 bits of pattern
431 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
d2d759cf 432
7771752e 433 if ((pattern >> ibitxy) & 0x1) {
434
435 // not quite sure about this
436 Int_t offset = 0;
437 if (iCath && localBoard->GetSwitch(6)) offset = -8;
438
439 AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
440
441 AliMUONDigit* digit = new AliMUONDigit();
442 if (!pad.IsValid()) {
443 AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
444 detElemId, nBoard, ibitxy));
445 continue;
446 } //
447
448 Int_t padX = pad.GetIndices().GetFirst();
449 Int_t padY = pad.GetIndices().GetSecond();
450
451 // file digit
452 digit->SetPadX(padX);
453 digit->SetPadY(padY);
454 digit->SetSignal(1.);
455 digit->SetCathode(iCath);
456 digit->SetDetElemId(detElemId);
457 digit->SetElectronics(nBoard, ibitxy);
458 digitList.Add(digit);
d2d759cf 459
7771752e 460 }// xyPattern
461 }// ibitxy
462 }// cath
463 } // ichamber
d2d759cf 464
465 return kTRUE;
466}
d53fb0de 467//____________________________________________________________________
00e86732 468void AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
d53fb0de 469{
9265505b 470 /// set crate name from DDL & reg number
471 /// method same as in RawWriter, not so nice
472 /// should be put in AliMUONTriggerCrateStore
d53fb0de 473
474 switch(iReg) {
475 case 0:
476 case 1:
477 sprintf(name,"%d", iReg+1);
478 break;
479 case 2:
480 strcpy(name, "2-3");
481 break;
482 case 3:
483 case 4:
484 case 5:
485 case 6:
486 case 7:
487 sprintf(name,"%d", iReg);
488 break;
489 }
490
491 // crate Right for first DDL
492 if (iDDL == 0)
493 strcat(name, "R");
494 else
495 strcat(name, "L");
496}