ChannelId() from Char to UChar
[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;
174 Char_t parity;
175 UShort_t charge;
176 Int_t dataSize;
177
e6e1f642 178 Int_t iChamber;
179
a3283a4c 180 AliMUONDDLTracker* ddlTracker = 0x0;
181 AliMUONBlockHeader* blkHeader = 0x0;
182 AliMUONDspHeader* dspHeader = 0x0;
183 AliMUONBusStruct* busStruct = 0x0;
184
a3283a4c 185 fRawStreamTracker->SetReader(rawReader);
186
187 while(fRawStreamTracker->NextDDL()) {
8a91c35f 188
a3283a4c 189 ddlTracker = fRawStreamTracker->GetDDLTracker();
190
191 Int_t nBlock = ddlTracker->GetBlkHeaderEntries();
192 for(Int_t iBlock = 0; iBlock < nBlock ;iBlock++){
193
194 blkHeader = ddlTracker->GetBlkHeaderEntry(iBlock);
195
196 Int_t nDsp = blkHeader->GetDspHeaderEntries();
197
198 for(Int_t iDsp = 0; iDsp < nDsp ;iDsp++){ //DSP loop
199
200 dspHeader = blkHeader->GetDspHeaderEntry(iDsp);
201
202 Int_t nBusPatch = dspHeader->GetBusPatchEntries();
203
204 for(Int_t iBusPatch = 0; iBusPatch < nBusPatch; iBusPatch++) {
205
206 busStruct = dspHeader->GetBusPatchEntry(iBusPatch);
207
208 dataSize = busStruct->GetLength();
209 buspatchId = busStruct->GetBusPatchId();
210
211 for (Int_t iData = 0; iData < dataSize; iData++) {
212
213 // digits info
214 parity = busStruct->GetParity(iData); // test later for parity
215 manuId = busStruct->GetManuId(iData);
216 channelId = busStruct->GetChannelId(iData);
217 charge = busStruct->GetCharge(iData);
218 // set charge
219 fDigit->SetSignal(charge);
220 fDigit->SetPhysicsSignal(charge);
221 fDigit->SetADC(charge);
222
223 // Get Back the hits at pads
224 Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit);
84ceeb06 225 if (error) {
e6e1f642 226 AliWarning("Mapping Error\n");
84ceeb06 227 continue;
228 }
a3283a4c 229 // debugging
230 if (AliLog::GetGlobalDebugLevel() == 3) {
231 Int_t padX = fDigit->PadX();
232 Int_t padY = fDigit->PadY();
233 Int_t iCath = fDigit->Cathode();
234 Int_t idDE = fDigit->DetElemId();
235
236 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
237 idDE, buspatchId, padX, padY, iCath));
238
239 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
240 idDE, padX, padY, iCath, charge));
241 }
242
243 // fill digits
66f4c572 244 iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
241560c2 245
d000f173 246
247 if (fDigitFlag || fDisplayFlag)
8a91c35f 248 fMUONData->AddDigit(iChamber, *fDigit);
d000f173 249 else
8a91c35f 250 fMUONData->AddSDigit(iChamber, *fDigit);
d000f173 251
a3283a4c 252
253 } // iData
254 } // iBusPatch
255 } // iDsp
256 } // iBlock
257 } // NextDDL
258
259 fTrackerTimer.Stop();
260
261 return kTRUE;
262}
263//____________________________________________________________________
264Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId,
265 UChar_t channelId, AliMUONDigit* digit )
266{
9265505b 267 /// mapping for tracker
268
a3283a4c 269 fMappingTimer.Start(kFALSE);
270
271 // getting DE from buspatch
e5ced899 272 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
a3283a4c 273 AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
274
9265505b 275 const AliMpVSegmentation* seg
276 = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);
a3283a4c 277 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
278
279 if (!pad.IsValid())
280 {
281 AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
282 detElemId, busPatchId, manuId, channelId));
283 fMappingTimer.Stop();
284 return kTRUE;
285 } // return error
286
287 // Getting padX, padY and cathode number.
288 Int_t padX = pad.GetIndices().GetFirst();
289 Int_t padY = pad.GetIndices().GetSecond();
290 Int_t iCath = AliMpDEManager::GetCathod(detElemId,seg->PlaneType());
291
292 // storing into digits
293 digit->SetPadX(padX);
294 digit->SetPadY(padY);
295 digit->SetCathode(iCath);
296 digit->SetDetElemId(detElemId);
297 digit->SetElectronics(manuId,channelId);
298
299 AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
300 detElemId, busPatchId, manuId, channelId, padX, padY));
6159fc91 301// StdoutToAliDebug(3,digit->Print(););
a3283a4c 302
303 fMappingTimer.Stop();
304 return kFALSE;
305}
306
307//____________________________________________________________________
308Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
309{
9265505b 310 /// reading tracker DDL
311 /// filling the TClonesArray in MUONData
a3283a4c 312
313 AliMUONDDLTrigger* ddlTrigger = 0x0;
314 AliMUONDarcHeader* darcHeader = 0x0;
315 AliMUONRegHeader* regHeader = 0x0;
316 AliMUONLocalStruct* localStruct = 0x0;
317
318 Int_t loCircuit;
d2d759cf 319 TList digitList;
320
a3283a4c 321 fTriggerTimer.Start(kFALSE);
322
323 fRawStreamTrigger->SetReader(rawReader);
324
325 while(fRawStreamTrigger->NextDDL()) {
8a91c35f 326
a3283a4c 327 ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
328 darcHeader = ddlTrigger->GetDarcHeader();
329
d2d759cf 330 // fill global trigger information in Digit Tree
331 if (fDigitFlag) {
332 if (darcHeader->GetGlobalFlag()) {
8a91c35f 333 if (!fDisplayFlag) {
334 fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
335 fMUONData->AddGlobalTrigger(*fGlobalTrigger);
336 }
d2d759cf 337 }
a3283a4c 338 }
339
340 Int_t nReg = darcHeader->GetRegHeaderEntries();
341
342 for(Int_t iReg = 0; iReg < nReg ;iReg++){ //reg loop
343
fe5010dd 344 // crate info
345 if (!fCrateManager) AliFatal("Crate Store not defined");
aa6ecf89 346 AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
d53fb0de 347
348 if (!crate)
349 AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
350
351 TObjArray *boards = crate->Boards();
352
a3283a4c 353 regHeader = darcHeader->GetRegHeaderEntry(iReg);
354
355 Int_t nLocal = regHeader->GetLocalEntries();
a3283a4c 356 for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {
8a91c35f 357
a3283a4c 358 localStruct = regHeader->GetLocalEntry(iLocal);
359
5a92f8e6 360 // if card exist
361 if (localStruct) {
d2d759cf 362
d53fb0de 363 AliMUONLocalTriggerBoard* localBoard =
364 (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
365
5a92f8e6 366 // skip copy cards
367 if( !(loCircuit = localBoard->GetNumber()) )
368 continue;
d2d759cf 369
370 if (fDigitFlag) {
371 // fill local trigger
8a91c35f 372 fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
373 fMUONData->AddLocalTrigger(*fLocalTrigger);
d000f173 374
d2d759cf 375 } else {
376 // Make SDigit
377
378 digitList.Clear();
7771752e 379 //FIXEME should find something better than a TArray
380 TArrayS xyPattern[2];
381 xyPattern[0].Set(4);
382 xyPattern[1].Set(4);
383
384 xyPattern[0].AddAt(localStruct->GetX1(),0);
385 xyPattern[0].AddAt(localStruct->GetX2(),1);
386 xyPattern[0].AddAt(localStruct->GetX3(),2);
387 xyPattern[0].AddAt(localStruct->GetX4(),3);
388
389 xyPattern[1].AddAt(localStruct->GetY1(),0);
390 xyPattern[1].AddAt(localStruct->GetY2(),1);
391 xyPattern[1].AddAt(localStruct->GetY3(),2);
392 xyPattern[1].AddAt(localStruct->GetY4(),3);
393
394 if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
d2d759cf 395
396 for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
397
398 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
399
400 // filling S container
66f4c572 401 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
8a91c35f 402 if (!fDisplayFlag) {
403 fMUONData->AddSDigit(iChamber, *digit);
404 } else {
d000f173 405 fMUONData->AddDigit(iChamber, *digit);
8a91c35f 406 }
d2d759cf 407
408 }
409
410 } // trigger digits
411 } // S flag
a3283a4c 412
a3283a4c 413 } // if triggerY
414 } // iLocal
415 } // iReg
416 } // NextDDL
417
418 fTriggerTimer.Stop();
419
420 return kTRUE;
421
422}
7771752e 423
d2d759cf 424//____________________________________________________________________
7771752e 425Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
426 TArrayS* xyPattern,
d2d759cf 427 TList& digitList)
428{
9265505b 429 /// make (S)Digit for trigger
d2d759cf 430
431 Int_t detElemId;
7771752e 432 Int_t previousDetElemId[4] = {0};
433 Int_t previousBoard[4] = {0};
d2d759cf 434
435 // loop over x1-4 and y1-4
7771752e 436 for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
437 for(Int_t iCath = 0; iCath < 2; ++iCath){
d2d759cf 438
7771752e 439 Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
440 if (!pattern) continue;
441
442 // get detElemId
443 AliMUONTriggerCircuit triggerCircuit;
444 AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
445 detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
446
d2d759cf 447
7771752e 448 if(iCath == 1){ // FIXME should find a more elegant way
449 // Don't save twice the same digit
450 // (since strips in non bending plane can cross several boards)
451 Int_t prevDetElemId = previousDetElemId[iChamber];
452 Int_t prevBoard = previousBoard[iChamber];
453 previousDetElemId[iChamber] = detElemId;
454 previousBoard[iChamber] = nBoard;
455
456 if(detElemId == prevDetElemId){
457 if(nBoard-prevBoard==1) continue;
458 }
459 }
d2d759cf 460
7771752e 461 const AliMpVSegmentation* seg
462 = AliMpSegmentation::Instance()
463 ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
d2d759cf 464
7771752e 465 // loop over the 16 bits of pattern
466 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
d2d759cf 467
7771752e 468 if ((pattern >> ibitxy) & 0x1) {
469
470 // not quite sure about this
471 Int_t offset = 0;
472 if (iCath && localBoard->GetSwitch(6)) offset = -8;
473
474 AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
475
476 AliMUONDigit* digit = new AliMUONDigit();
477 if (!pad.IsValid()) {
478 AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
479 detElemId, nBoard, ibitxy));
480 continue;
481 } //
482
483 Int_t padX = pad.GetIndices().GetFirst();
484 Int_t padY = pad.GetIndices().GetSecond();
485
486 // file digit
487 digit->SetPadX(padX);
488 digit->SetPadY(padY);
489 digit->SetSignal(1.);
490 digit->SetCathode(iCath);
491 digit->SetDetElemId(detElemId);
492 digit->SetElectronics(nBoard, ibitxy);
493 digitList.Add(digit);
d2d759cf 494
7771752e 495 }// xyPattern
496 }// ibitxy
497 }// cath
498 } // ichamber
d2d759cf 499
500 return kTRUE;
501}
d53fb0de 502//____________________________________________________________________
00e86732 503void AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
d53fb0de 504{
9265505b 505 /// set crate name from DDL & reg number
506 /// method same as in RawWriter, not so nice
507 /// should be put in AliMUONTriggerCrateStore
d53fb0de 508
509 switch(iReg) {
510 case 0:
511 case 1:
512 sprintf(name,"%d", iReg+1);
513 break;
514 case 2:
515 strcpy(name, "2-3");
516 break;
517 case 3:
518 case 4:
519 case 5:
520 case 6:
521 case 7:
522 sprintf(name,"%d", iReg);
523 break;
524 }
525
526 // crate Right for first DDL
527 if (iDDL == 0)
528 strcat(name, "R");
529 else
530 strcat(name, "L");
531}