Line data Source code
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 : // $Id$
17 :
18 : //-----------------------------------------------------------------------------
19 : /// \class AliMUONDigitMaker
20 : /// MUON Digit maker from rawdata.
21 : ///
22 : /// Raw2Digits:
23 : /// Using real mapping for tracker
24 : /// Indranil Das (Adapted for runloader: Ch. Finck) july 05
25 : ///
26 : /// Implemented non-constant buspatch numbers for tracking
27 : /// with correct DDL id.
28 : /// (Ch. Finck, dec 05)
29 : ///
30 : /// Add reader for scaler trigger events
31 : /// Use memcpy instead of assignment elt by elt
32 : /// (Ch. Finck, Jan 06)
33 : ///
34 : /// Using new interface with AliMUONRawStreamTracker(Trigger)
35 : /// (New interface of AliMUONRawReader class)
36 : /// (further details could be found in Alice-note)
37 : /// (Ch. Finck, March 06)
38 : ///
39 : /// Add (S)Digit maker tracker (for free)
40 : /// and for trigger. Create trigger inverse mapping.
41 : ///
42 : /// \author Ch. Finck, oct 06
43 : //-----------------------------------------------------------------------------
44 :
45 : #include "AliMUONDigitMaker.h"
46 :
47 : #include "AliMUONDDLTrigger.h"
48 : #include "AliMUONDarcHeader.h"
49 : #include "AliMUONVDigit.h"
50 : #include "AliMUONVDigitStore.h"
51 : #include "AliMUONGlobalTrigger.h"
52 : #include "AliMUONLocalStruct.h"
53 : #include "AliMUONLocalTrigger.h"
54 : #include "AliMUONLogger.h"
55 : #include "AliMUONRawStreamTrackerHP.h"
56 : #include "AliMUONRawStreamTriggerHP.h"
57 : #include "AliMUONRegHeader.h"
58 : #include "AliMUONVTriggerStore.h"
59 : #include "AliMpCDB.h"
60 : #include "AliMpDetElement.h"
61 : #include "AliMpTriggerCrate.h"
62 : #include "AliMpLocalBoard.h"
63 : #include "AliMpCathodType.h"
64 : #include "AliMpDDLStore.h"
65 : #include "AliMpDEManager.h"
66 : #include "AliMpPad.h"
67 : #include "AliMpSegmentation.h"
68 : #include "AliMpVSegmentation.h"
69 : #include "AliCodeTimer.h"
70 : #include "AliLog.h"
71 : #include "AliRawReader.h"
72 : #include <TArrayS.h>
73 : #include <iostream>
74 :
75 : using std::endl;
76 : using std::cout;
77 : /// \cond CLASSIMP
78 18 : ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
79 : /// \endcond
80 :
81 : //__________________________________________________________________________
82 : AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t a, Bool_t b) :
83 0 : TObject(),
84 0 : fScalerEvent(kFALSE),
85 0 : fMakeTriggerDigits(kFALSE),
86 0 : fMakeTrackerDigits(kFALSE),
87 0 : fRawStreamTracker(new AliMUONRawStreamTrackerHP),
88 0 : fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
89 0 : fDigitStore(0x0),
90 0 : fTriggerStore(0x0),
91 0 : fLogger(new AliMUONLogger(10000)){
92 : /// ctor
93 :
94 0 : if ( !a || !b ) AliFatal("no longer supported");
95 :
96 0 : AliDebug(1,"");
97 :
98 : // Standard Constructor
99 0 : if (enableErrorLogger)
100 : {
101 0 : fRawStreamTracker->EnabbleErrorLogger();
102 0 : fRawStreamTrigger->EnabbleErrorLogger();
103 : }
104 : else
105 : {
106 0 : fRawStreamTracker->DisableWarnings();
107 : }
108 :
109 0 : SetMakeTriggerDigits();
110 0 : SetMakeTrackerDigits();
111 :
112 : // Load mapping
113 0 : if ( ! AliMpCDB::LoadDDLStore() ) {
114 0 : AliFatal("Could not access mapping from OCDB !");
115 : }
116 0 : }
117 :
118 : //__________________________________________________________________________
119 : AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger) :
120 9 : TObject(),
121 9 : fScalerEvent(kFALSE),
122 9 : fMakeTriggerDigits(kFALSE),
123 9 : fMakeTrackerDigits(kFALSE),
124 27 : fRawStreamTracker(new AliMUONRawStreamTrackerHP),
125 27 : fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
126 9 : fDigitStore(0x0),
127 9 : fTriggerStore(0x0),
128 27 : fLogger(new AliMUONLogger(10000))
129 27 : {
130 : /// ctor
131 :
132 45 : AliDebug(1,"");
133 :
134 : // Standard Constructor
135 18 : if (enableErrorLogger)
136 : {
137 12 : fRawStreamTracker->EnabbleErrorLogger();
138 3 : fRawStreamTrigger->EnabbleErrorLogger();
139 : }
140 : else
141 : {
142 6 : fRawStreamTracker->DisableWarnings();
143 : }
144 :
145 9 : SetMakeTriggerDigits();
146 9 : SetMakeTrackerDigits();
147 :
148 : // Load mapping
149 18 : if ( ! AliMpCDB::LoadDDLStore() ) {
150 0 : AliFatal("Could not access mapping from OCDB !");
151 : }
152 18 : }
153 :
154 : //__________________________________________________________________________
155 : AliMUONDigitMaker::~AliMUONDigitMaker()
156 24 : {
157 : /// clean up
158 : /// and time processing measure
159 :
160 10 : delete fRawStreamTracker;
161 10 : delete fRawStreamTrigger;
162 10 : delete fLogger;
163 12 : }
164 :
165 : //____________________________________________________________________
166 : void
167 : AliMUONDigitMaker::Print(Option_t*) const
168 : {
169 : /// Printout
170 :
171 0 : cout << "RawStreamerTracker class=" << fRawStreamTracker->ClassName()
172 0 : << " MakeTriggerDigits=" << fMakeTriggerDigits
173 0 : << " ScalerEvent=" << fScalerEvent
174 0 : << " DigitStore=" << fDigitStore
175 0 : << " TriggerStore=" << fTriggerStore << endl;
176 :
177 0 : if ( fLogger ) fLogger->Print();
178 0 : }
179 :
180 : //____________________________________________________________________
181 : Int_t
182 : AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader,
183 : AliMUONVDigitStore* digitStore,
184 : AliMUONVTriggerStore* triggerStore)
185 : {
186 : /// Main method to creates digit
187 : /// for tracker
188 : /// and trigger
189 :
190 16 : AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
191 : rawReader,digitStore,triggerStore));
192 :
193 4 : fDigitStore = digitStore;
194 4 : fTriggerStore = triggerStore;
195 :
196 4 : if (!fDigitStore && !fTriggerStore)
197 : {
198 0 : fLogger->Log("No digit or trigger store given. Nothing to do...");
199 0 : return kTriggerBAD & kTrackerBAD;
200 : }
201 :
202 : Int_t tracker(kOK);
203 : Int_t trigger(kOK);
204 :
205 8 : if ( fDigitStore ) fDigitStore->Clear(); // insure we start with an empty container
206 :
207 4 : if ( fMakeTrackerDigits ) {
208 8 : if ( fDigitStore ) tracker = ReadTrackerDDL(rawReader);
209 0 : else fLogger->Log("Asking for tracker digits but digitStore is null");
210 : }
211 :
212 4 : if ( fTriggerStore || fMakeTriggerDigits )
213 : {
214 8 : if ( fTriggerStore ) fTriggerStore->Clear();
215 8 : if ( fMakeTriggerDigits && !fDigitStore )
216 : {
217 0 : fLogger->Log("Asking for trigger digits but digitStore is null");
218 0 : }
219 : else
220 : {
221 4 : trigger = ReadTriggerDDL(rawReader);
222 : }
223 : }
224 :
225 4 : return tracker | trigger;
226 4 : }
227 :
228 : //____________________________________________________________________
229 : Int_t
230 : AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
231 : {
232 : /// Reading tracker DDL
233 : /// filling the fDigitStore container, which must not be null
234 :
235 16 : AliDebug(1,"");
236 :
237 4 : AliCodeTimerAuto("",0);
238 :
239 : // elex info
240 4 : Int_t buspatchId;
241 4 : UChar_t channelId;
242 4 : UShort_t manuId;
243 4 : UShort_t charge;
244 :
245 4 : fRawStreamTracker->SetReader(rawReader);
246 4 : fRawStreamTracker->First();
247 :
248 1424 : while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge,kTRUE) )
249 : {
250 : // getting DE from buspatch
251 1416 : Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
252 :
253 1416 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
254 :
255 708 : if (!de)
256 : {
257 0 : fLogger->Log(Form("DE %04d does not exist !", detElemId));
258 0 : continue;
259 : }
260 :
261 1416 : if (!de->IsConnectedChannel(manuId,channelId))
262 : {
263 : // non connected pad, do nothing (this is not an error !)
264 0 : continue;
265 : }
266 :
267 : const AliMpVSegmentation* seg
268 1416 : = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,
269 708 : manuId);
270 :
271 708 : if (!seg)
272 : {
273 0 : fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
274 0 : continue;
275 : }
276 :
277 1416 : AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
278 :
279 708 : AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
280 :
281 708 : if (!pad.IsValid())
282 : {
283 0 : fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
284 0 : detElemId, manuId, channelId));
285 0 : continue;
286 : }
287 :
288 708 : AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
289 : AliMUONVDigitStore::kDeny);
290 :
291 708 : if (!digit)
292 : {
293 0 : fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
294 0 : detElemId, manuId, channelId));
295 0 : continue;
296 : }
297 :
298 2124 : digit->SetPadXY(pad.GetIx(),pad.GetIy());
299 :
300 708 : digit->SetADC(charge);
301 :
302 1416 : }
303 :
304 8 : if ( fRawStreamTracker->IsErrorMessage() )
305 : {
306 0 : return kTrackerBAD;
307 : }
308 :
309 4 : return kOK;
310 4 : }
311 :
312 : //____________________________________________________________________
313 : Int_t
314 : AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
315 : {
316 : /// reading tracker DDL like ReadTriggerDDL but with fast decoder interface.
317 : /// filling the fTriggerStore container, which must not be null
318 :
319 : const AliMUONRawStreamTriggerHP::AliHeader* darcHeader = 0x0;
320 : const AliMUONRawStreamTriggerHP::AliRegionalHeader* regHeader = 0x0;
321 : const AliMUONRawStreamTriggerHP::AliLocalStruct* localStruct = 0x0;
322 :
323 : Int_t loCircuit;
324 :
325 8 : fRawStreamTrigger->SetReader(rawReader);
326 :
327 24 : while (fRawStreamTrigger->NextDDL())
328 : {
329 8 : darcHeader = fRawStreamTrigger->GetHeaders();
330 :
331 : // fill global trigger information
332 8 : if (fTriggerStore)
333 : {
334 8 : if (darcHeader->GetGlobalFlag())
335 : {
336 4 : AliMUONGlobalTrigger globalTrigger;
337 8 : globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
338 4 : globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
339 4 : fTriggerStore->SetGlobal(globalTrigger);
340 4 : }
341 : }
342 :
343 8 : Int_t nReg = fRawStreamTrigger->GetRegionalHeaderCount();
344 :
345 144 : for(Int_t iReg = 0; iReg < nReg ;iReg++)
346 : { //reg loop
347 :
348 :
349 : // crate info
350 128 : AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
351 64 : GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
352 :
353 64 : if (!crate) {
354 0 : fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
355 0 : continue;
356 : }
357 :
358 64 : regHeader = fRawStreamTrigger->GetRegionalHeader(iReg);
359 :
360 64 : Int_t nLocal = regHeader->GetLocalStructCount();
361 2064 : for(Int_t iLocal = 0; iLocal < nLocal; iLocal++)
362 : {
363 :
364 968 : localStruct = regHeader->GetLocalStruct(iLocal);
365 :
366 : // if card exist
367 968 : if (localStruct) {
368 :
369 968 : loCircuit = crate->GetLocalBoardId(localStruct->GetId());
370 :
371 968 : if ( !loCircuit ) continue; // empty slot
372 :
373 :
374 968 : if (fTriggerStore)
375 : {
376 : // fill local trigger
377 968 : AliMUONLocalTrigger localTrigger;
378 968 : localTrigger.SetLocalStruct(loCircuit, *localStruct);
379 968 : fTriggerStore->Add(localTrigger);
380 968 : }
381 :
382 968 : if ( fMakeTriggerDigits )
383 : {
384 : //FIXEME should find something better than a TArray
385 4840 : TArrayS xyPattern[2];
386 :
387 968 : localStruct->GetXPattern(xyPattern[0]);
388 968 : localStruct->GetYPattern(xyPattern[1]);
389 :
390 968 : TriggerDigits(loCircuit, xyPattern, *fDigitStore);
391 3872 : }
392 : } // if triggerY
393 : } // iLocal
394 64 : } // iReg
395 : } // NextDDL
396 :
397 4 : return kOK;
398 0 : }
399 :
400 : //____________________________________________________________________
401 : Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
402 : const TArrayS* xyPattern,
403 : AliMUONVDigitStore& digitStore, Bool_t warn) const
404 : {
405 : /// make digits for trigger from pattern, and add them to digitStore
406 :
407 3098 : AliCodeTimerAuto("",0);
408 :
409 : Int_t detElemId;
410 :
411 6196 : AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
412 :
413 3098 : if ( ! localBoard->IsNotified() ) {
414 : // Copy board
415 : // The mapping is not correct for copy boards
416 : // Use the one of corresponding phyiscal board
417 56 : nBoard = localBoard->GetInputXfrom();
418 56 : }
419 :
420 : Int_t n,b;
421 :
422 : // loop over x1-4 and y1-4
423 30980 : for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
424 : {
425 74352 : for (Int_t iCath = 0; iCath < 2; ++iCath)
426 : {
427 49568 : Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
428 32499 : if (!pattern) continue;
429 :
430 : // get detElemId
431 34138 : detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
432 :
433 : const AliMpVSegmentation* seg
434 34138 : = AliMpSegmentation::Instance()
435 17069 : ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
436 :
437 : // loop over the 16 bits of pattern
438 580346 : for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy)
439 : {
440 273104 : if ((pattern >> ibitxy) & 0x1)
441 : {
442 : // not quite sure about this
443 : Int_t offset = 0;
444 516125 : if (iCath && localBoard->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) offset = -8;
445 :
446 261689 : AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,warn);
447 :
448 261689 : if (!pad.IsValid())
449 : {
450 38400 : fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
451 : detElemId, nBoard, ibitxy));
452 19200 : continue;
453 : }
454 :
455 242489 : n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
456 242489 : b = pad.GetLocalBoardChannel(0);
457 :
458 1212445 : AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
459 : n,b,nBoard,ibitxy));
460 :
461 242489 : AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
462 :
463 242489 : if (!digit)
464 : {
465 180845 : AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
466 : detElemId,nBoard,ibitxy,iCath));
467 36169 : continue;
468 : }
469 :
470 206320 : Int_t padX = pad.GetIx();
471 206320 : Int_t padY = pad.GetIy();
472 :
473 : // fill digit
474 206320 : digit->SetPadXY(padX,padY);
475 206320 : digit->SetCharge(1.);
476 468009 : }// xyPattern
477 : }// ibitxy
478 17069 : }// cath
479 : } // ichamber
480 :
481 : return kTRUE;
482 3098 : }
483 :
484 : //______________________________________________________________________________
485 : Bool_t
486 : AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
487 : AliMUONVDigitStore& digitStore) const
488 : {
489 : //
490 : /// make (S)Digit for trigger
491 : //
492 :
493 6 : digitStore.Clear();
494 :
495 : AliMUONLocalTrigger* locTrg;
496 3 : TIter next(triggerStore.CreateLocalIterator());
497 :
498 2187 : while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
499 : {
500 1452 : if (locTrg->IsNull()) continue;
501 :
502 3630 : TArrayS xyPattern[2];
503 726 : locTrg->GetXPattern(xyPattern[0]);
504 726 : locTrg->GetYPattern(xyPattern[1]);
505 :
506 726 : Int_t nBoard = locTrg->LoCircuit();
507 726 : TriggerDigits(nBoard, xyPattern, digitStore);
508 2904 : }
509 : return kTRUE;
510 3 : }
511 :
512 : //______________________________________________________________________________
513 : void
514 : AliMUONDigitMaker::SetTryRecover(Bool_t flag)
515 : {
516 : /// Instruct the decoder to try to recover corrupted raw data.
517 : /// Only use for specific cases for which you know it will work...
518 1 : fRawStreamTracker->TryRecover(flag);
519 1 : }
|