1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /// \class AliMUONDigitMaker
17 /// MUON Digit maker from rawdata.
20 /// Using real mapping for tracker
21 /// Indranil Das (Adapted for runloader: Ch. Finck) july 05
23 /// Implemented non-constant buspatch numbers for tracking
24 /// with correct DDL id.
25 /// (Ch. Finck, dec 05)
27 /// Add reader for scaler trigger events
28 /// Use memcpy instead of assignment elt by elt
29 /// (Ch. Finck, Jan 06)
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)
36 /// Add (S)Digit maker tracker (for free)
37 /// and for trigger. Create trigger inverse mapping.
39 /// \author Ch. Finck, oct 06
41 #include "AliMUONDigitMaker.h"
42 #include "AliMUONDigit.h"
44 #include "AliMUONConstants.h"
45 #include "AliMUONData.h"
47 #include "AliMUONRawStreamTracker.h"
48 #include "AliMUONDDLTracker.h"
49 #include "AliMUONDspHeader.h"
50 #include "AliMUONBlockHeader.h"
51 #include "AliMUONBusStruct.h"
53 #include "AliMUONRawStreamTrigger.h"
54 #include "AliMUONDDLTrigger.h"
55 #include "AliMUONDarcHeader.h"
56 #include "AliMUONRegHeader.h"
57 #include "AliMUONLocalStruct.h"
59 #include "AliMUONTriggerCrateStore.h"
60 #include "AliMUONTriggerCrate.h"
61 #include "AliMUONLocalTriggerBoard.h"
62 #include "AliMUONLocalTrigger.h"
63 #include "AliMUONGlobalTrigger.h"
64 #include "AliMUONTriggerCircuit.h"
66 #include "AliMpSegmentation.h"
67 #include "AliMpVSegmentation.h"
69 #include "AliMpDEManager.h"
70 #include "AliMpDDLStore.h"
71 #include "AliMpCathodType.h"
73 #include "AliRawReader.h"
74 #include "AliRawDataHeader.h"
83 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
86 //__________________________________________________________________________
87 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t flag)
94 fRawStreamTracker(new AliMUONRawStreamTracker()),
95 fRawStreamTrigger(new AliMUONRawStreamTrigger()),
96 fDigit(new AliMUONDigit()),
97 fLocalTrigger(new AliMUONLocalTrigger()),
98 fGlobalTrigger(new AliMUONGlobalTrigger()),
104 /// ctor with AliMUONData as argument
105 /// for reconstruction
109 // Standard Constructor
111 fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
112 fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
113 fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
117 //__________________________________________________________________________
118 AliMUONDigitMaker::~AliMUONDigitMaker()
121 /// and time processing measure
123 delete fRawStreamTracker;
124 delete fRawStreamTrigger;
127 delete fLocalTrigger;
128 delete fGlobalTrigger;
130 AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
131 fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
132 AliDebug(1, Form(" Execution time for MUON tracker (mapping calls part) "
134 fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
135 AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
136 fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
141 //____________________________________________________________________
142 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader)
144 /// Main method to creates digit
149 ReadTrackerDDL(rawReader);
153 ReadTriggerDDL(rawReader);
155 AliInfo("Reading trigger rawdata disable");
161 //____________________________________________________________________
162 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
165 /// reading tracker DDL
166 /// filling the TClonesArray in MUONData
168 fTrackerTimer.Start(kFALSE);
178 fRawStreamTracker->SetReader(rawReader);
179 fRawStreamTracker->First();
181 while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
183 fDigit->SetSignal(charge);
184 fDigit->SetPhysicsSignal(charge);
185 fDigit->SetADC(charge);
187 // Get Back the hits at pads
188 Int_t error = GetMapping(buspatchId,manuId,channelId,fDigit);
191 AliWarning("Mapping Error\n");
196 if (AliLog::GetGlobalDebugLevel() == 3)
198 Int_t padX = fDigit->PadX();
199 Int_t padY = fDigit->PadY();
200 Int_t iCath = fDigit->Cathode();
201 Int_t idDE = fDigit->DetElemId();
203 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
204 idDE, buspatchId, padX, padY, iCath));
206 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",
207 idDE, padX, padY, iCath, charge));
211 iChamber = AliMpDEManager::GetChamberId(fDigit->DetElemId());
213 if (fDigitFlag || fDisplayFlag)
215 fMUONData->AddDigit(iChamber, *fDigit);
219 fMUONData->AddSDigit(iChamber, *fDigit);
223 fTrackerTimer.Stop();
228 //____________________________________________________________________
229 Int_t AliMUONDigitMaker::GetMapping(Int_t busPatchId, UShort_t manuId,
230 UChar_t channelId, AliMUONDigit* digit )
232 /// mapping for tracker
234 fMappingTimer.Start(kFALSE);
236 // getting DE from buspatch
237 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
238 AliDebug(3,Form("detElemId: %d busPatchId %d\n", detElemId, busPatchId));
240 const AliMpVSegmentation* seg
241 = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId);
242 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kTRUE);
246 AliWarning(Form("No pad for detElemId: %d, busPatchId %d, manuId: %d, channelId: %d\n",
247 detElemId, busPatchId, manuId, channelId));
248 fMappingTimer.Stop();
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());
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);
264 AliDebug(3,Form("detElemId: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
265 detElemId, busPatchId, manuId, channelId, padX, padY));
266 // StdoutToAliDebug(3,digit->Print(););
268 fMappingTimer.Stop();
272 //____________________________________________________________________
273 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
275 /// reading tracker DDL
276 /// filling the TClonesArray in MUONData
278 AliMUONDDLTrigger* ddlTrigger = 0x0;
279 AliMUONDarcHeader* darcHeader = 0x0;
280 AliMUONRegHeader* regHeader = 0x0;
281 AliMUONLocalStruct* localStruct = 0x0;
286 fTriggerTimer.Start(kFALSE);
288 fRawStreamTrigger->SetReader(rawReader);
290 while(fRawStreamTrigger->NextDDL()) {
292 ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
293 darcHeader = ddlTrigger->GetDarcHeader();
295 // fill global trigger information in Digit Tree
297 if (darcHeader->GetGlobalFlag()) {
299 fGlobalTrigger->SetFromGlobalResponse(darcHeader->GetGlobalOutput());
300 fMUONData->AddGlobalTrigger(*fGlobalTrigger);
305 Int_t nReg = darcHeader->GetRegHeaderEntries();
307 for(Int_t iReg = 0; iReg < nReg ;iReg++){ //reg loop
310 if (!fCrateManager) AliFatal("Crate Store not defined");
311 AliMUONTriggerCrate* crate = fCrateManager->Crate(fRawStreamTrigger->GetDDL(), iReg);
314 AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
316 TObjArray *boards = crate->Boards();
318 regHeader = darcHeader->GetRegHeaderEntry(iReg);
320 Int_t nLocal = regHeader->GetLocalEntries();
321 for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) {
323 localStruct = regHeader->GetLocalEntry(iLocal);
328 AliMUONLocalTriggerBoard* localBoard =
329 (AliMUONLocalTriggerBoard*)boards->At(localStruct->GetId()+1);
332 if( !(loCircuit = localBoard->GetNumber()) )
336 // fill local trigger
337 fLocalTrigger->SetLocalStruct(loCircuit, *localStruct);
338 fMUONData->AddLocalTrigger(*fLocalTrigger);
344 //FIXEME should find something better than a TArray
345 TArrayS xyPattern[2];
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);
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);
359 if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
361 for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
363 AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
365 // filling S container
366 Int_t iChamber = AliMpDEManager::GetChamberId(digit->DetElemId());
368 fMUONData->AddSDigit(iChamber, *digit);
370 fMUONData->AddDigit(iChamber, *digit);
383 fTriggerTimer.Stop();
389 //____________________________________________________________________
390 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
394 /// make (S)Digit for trigger
397 Int_t previousDetElemId[4] = {0};
398 Int_t previousBoard[4] = {0};
400 // loop over x1-4 and y1-4
401 for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
402 for(Int_t iCath = 0; iCath < 2; ++iCath){
404 Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
405 if (!pattern) continue;
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)
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;
421 if(detElemId == prevDetElemId){
422 if(nBoard-prevBoard==1) continue;
426 const AliMpVSegmentation* seg
427 = AliMpSegmentation::Instance()
428 ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
430 // loop over the 16 bits of pattern
431 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
433 if ((pattern >> ibitxy) & 0x1) {
435 // not quite sure about this
437 if (iCath && localBoard->GetSwitch(6)) offset = -8;
439 AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
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));
448 Int_t padX = pad.GetIndices().GetFirst();
449 Int_t padY = pad.GetIndices().GetSecond();
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);
467 //____________________________________________________________________
468 void AliMUONDigitMaker::GetCrateName(Char_t* name, Int_t iDDL, Int_t iReg) const
470 /// set crate name from DDL & reg number
471 /// method same as in RawWriter, not so nice
472 /// should be put in AliMUONTriggerCrateStore
477 sprintf(name,"%d", iReg+1);
487 sprintf(name,"%d", iReg);
491 // crate Right for first DDL