]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/trigger/AliHLTMuonSpectroTriggerComponent.cxx
Reverting the fix since another side effect bug in AliHLTLogging prevents it from...
[u/mrichter/AliRoot.git] / HLT / trigger / AliHLTMuonSpectroTriggerComponent.cxx
CommitLineData
c1550d2c 1// $Id: $
2/**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * All rights reserved. *
5 * *
6 * Primary Authors: *
7 * Artur Szostak <artursz@iafrica.com> *
8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18/// @file AliHLTMuonSpectroTriggerComponent.cxx
19/// @author Artur Szostak <artursz@iafrica.com>
20/// @date 9 Nov 2009
21/// @brief Implementation of the muon spectrometer trigger component.
22///
23/// The AliHLTMuonSpectroTriggerComponent component is used to generate the HLT
24/// trigger for the muon spectrometer.
25
26#include "AliHLTMuonSpectroTriggerComponent.h"
27#include "AliHLTTriggerDecision.h"
28#include "AliHLTMuonSpectroScalars.h"
29#include "AliHLTMUONDataBlockReader.h"
30#include "AliHLTMUONConstants.h"
31#include "AliHLTMUONUtils.h"
32#include "AliMUONTriggerDDLDecoderEventHandler.h"
33
34ClassImp(AliHLTMuonSpectroTriggerComponent);
35
36
37AliHLTMuonSpectroTriggerComponent::AliHLTMuonSpectroTriggerComponent() :
38 AliHLTTrigger(),
39 fBufferSizeConst(1024*16),
40 fBufferSizeMultiplier(1),
41 fMakeStats(false),
8fc88a5c 42 fTriggerDDLs(false),
c1550d2c 43 fTriggerHits(false),
44 fTriggerTrigRecs(false),
45 fTriggerTracks(true),
46 fTriggerDimuons(true)
47{
48 // Default constructor.
49}
50
51
52AliHLTMuonSpectroTriggerComponent::~AliHLTMuonSpectroTriggerComponent()
53{
54 // Default destructor.
55}
56
57
58void AliHLTMuonSpectroTriggerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) const
59{
60 // Returns the list of input types expected.
c057e1f9 61 list.push_back(AliHLTMUONConstants::DDLRawDataType());
c1550d2c 62 list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
63 list.push_back(AliHLTMUONConstants::RecHitsBlockDataType());
64 list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
d24a4636 65 list.push_back(AliHLTMUONConstants::TracksBlockDataType());
c1550d2c 66 list.push_back(AliHLTMUONConstants::SinglesDecisionBlockDataType());
67 list.push_back(AliHLTMUONConstants::PairsDecisionBlockDataType());
68}
69
70
71void AliHLTMuonSpectroTriggerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
72{
73 // Return the output data types generated.
74
75 list.push_back(kAliHLTDataTypeTriggerDecision);
76 list.push_back(kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT);
77}
78
79
80void AliHLTMuonSpectroTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
81{
82 // Returns the output data size estimate.
83
84 constBase = fBufferSizeConst;
85 inputMultiplier = fBufferSizeMultiplier;
86}
87
88
89AliHLTComponent* AliHLTMuonSpectroTriggerComponent::Spawn()
90{
91 // Creates and returns a new instance.
92
93 return new AliHLTMuonSpectroTriggerComponent;
94}
95
96
97Int_t AliHLTMuonSpectroTriggerComponent::DoInit(int argc, const char** argv)
98{
99 // Initialise the component.
100
101 fMakeStats = false;
c057e1f9 102 fTriggerDDLs = false;
c1550d2c 103 fTriggerHits = false;
104 fTriggerTrigRecs = false;
105 fTriggerTracks = false;
106 fTriggerDimuons = false;
c057e1f9 107
c1550d2c 108 for (int i = 0; i < argc; i++)
109 {
110 if (strcmp(argv[i], "-makestats") == 0)
111 {
112 fMakeStats = true;
113 continue;
114 }
c057e1f9 115 if (strcmp(argv[i], "-triggerddls") == 0)
116 {
117 fTriggerDDLs = true;
118 continue;
119 }
c1550d2c 120 if (strcmp(argv[i], "-triggerhits") == 0)
121 {
122 fTriggerHits = true;
123 continue;
124 }
125 if (strcmp(argv[i], "-triggertrigrecs") == 0)
126 {
127 fTriggerTrigRecs = true;
128 continue;
129 }
130 if (strcmp(argv[i], "-triggertracks") == 0)
131 {
132 fTriggerTracks = true;
133 continue;
134 }
135 if (strcmp(argv[i], "-triggerdimuons") == 0)
136 {
137 fTriggerDimuons = true;
138 continue;
139 }
140 if (strcmp(argv[i], "-triggerany") == 0)
141 {
142 fTriggerHits = true;
143 fTriggerTrigRecs = true;
144 fTriggerTracks = true;
145 fTriggerDimuons = true;
146 continue;
147 }
148
149 HLTError("Unknown option '%s'.", argv[i]);
150 return -EINVAL;
151 } // for loop
152
153 // If nothing was turned on to trigger then turn everything on by default.
154 if (fTriggerHits == false and fTriggerTrigRecs == false
155 and fTriggerTracks == false and fTriggerDimuons == false
156 )
157 {
158 fTriggerTracks = true;
159 fTriggerDimuons = true;
160 }
161
162 return 0;
163}
164
165
166Int_t AliHLTMuonSpectroTriggerComponent::DoDeinit()
167{
168 // Cleans up the component.
169
170 return 0;
171}
172
173
174int AliHLTMuonSpectroTriggerComponent::DoTrigger()
175{
176 // Applies the trigger for the HLT.
177
178 int result = 0;
c057e1f9 179
d24a4636 180 bool gotddls = false;
c1550d2c 181 bool gothits = false;
182 bool gottrigrecs = false;
183 bool gottracks = false;
184 bool gotsingles = false;
185 bool gotpairs = false;
c057e1f9 186 UInt_t nL0 = 0;
c1550d2c 187 UInt_t nhits = 0;
188 UInt_t nhitsMTR = 0;
189 UInt_t nhitsMCH = 0;
190 UInt_t nhitsCh[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
191 UInt_t ntrigrecs = 0;
192 UInt_t nL0plus = 0;
193 UInt_t nL0minus = 0;
d24a4636 194 UInt_t ntracksT = 0; // from track blocks.
c1550d2c 195 UInt_t ntracksSD = 0; // from singles decision blocks
196 UInt_t nplus = 0;
197 UInt_t nminus = 0;
198 UInt_t nlowpt = 0;
199 UInt_t nhighpt = 0;
200 Double_t minpt = -1;
201 Double_t maxpt = -1;
202 UInt_t nlikeany = 0;
203 UInt_t nlikelow = 0;
204 UInt_t nlikehigh = 0;
205 UInt_t nunlikeany = 0;
206 UInt_t nunlikelow = 0;
207 UInt_t nunlikehigh = 0;
208 UInt_t nlowmass = 0;
209 UInt_t nhighmass = 0;
210 Double_t minmass = -1;
211 Double_t maxmass = -1;
212
c057e1f9 213 AliHLTComponentDataType blockType = AliHLTMUONConstants::DDLRawDataType();
214 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
215 block != NULL;
216 block = GetNextInputBlock()
217 )
d24a4636 218 {
219 gotddls = true;
220 nL0 = 1;
c057e1f9 221 }
c1550d2c 222
c057e1f9 223 blockType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
c1550d2c 224 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
225 block != NULL;
226 block = GetNextInputBlock()
227 )
228 {
229 AliHLTMUONTriggerRecordsBlockReader trigRecsBlock(block->fPtr, block->fSize);
230 if (not IsBlockOk(trigRecsBlock, blockType))
231 {
232 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
233 continue;
234 }
235 gothits = true;
236
237 ntrigrecs += trigRecsBlock.Nentries();
238 for (AliHLTUInt32_t i = 0; i < trigRecsBlock.Nentries(); ++i)
239 {
240 AliHLTMUONParticleSign sign;
241 bool hitset[4];
242 AliHLTMUONUtils::UnpackTriggerRecordFlags(trigRecsBlock[i].fFlags, sign, hitset);
243 switch (sign)
244 {
245 case kSignPlus: ++nL0plus; break;
246 case kSignMinus: ++nL0minus; break;
247 default: break;
248 }
249 for (int j = 0; j < 4; ++j)
250 {
251 if (hitset[j])
252 {
253 ++nhitsCh[j+10];
254 ++nhits;
255 ++nhitsMTR;
256 }
257 }
258 }
259 }
260
261 blockType = AliHLTMUONConstants::RecHitsBlockDataType();
262 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
263 block != NULL;
264 block = GetNextInputBlock()
265 )
266 {
267 AliHLTMUONRecHitsBlockReader hitsBlock(block->fPtr, block->fSize);
268 if (not IsBlockOk(hitsBlock, blockType))
269 {
270 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
271 continue;
272 }
273 gottrigrecs = true;
274
275 nhits += hitsBlock.Nentries();
276 nhitsMCH += hitsBlock.Nentries();
277 for (AliHLTUInt32_t i = 0; i < hitsBlock.Nentries(); ++i)
278 {
279 AliHLTUInt8_t chamber;
280 AliHLTUInt16_t detElemId;
281 AliHLTMUONUtils::UnpackRecHitFlags(hitsBlock[i].fFlags, chamber, detElemId);
282 if (chamber < 10)
283 {
284 ++nhitsCh[chamber];
285 }
286 else
287 {
288 HLTWarning("Received a reconstructed hit which indicates"
289 " an invalid chamber number of %d. The expected"
61d8fa02 290 " range is [0..9]. The data block is probably corrupt.",
c1550d2c 291 int(chamber)
292 );
293 }
294 }
295 }
296
297 blockType = AliHLTMUONConstants::MansoTracksBlockDataType();
298 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
299 block != NULL;
300 block = GetNextInputBlock()
301 )
302 {
303 AliHLTMUONMansoTracksBlockReader tracksBlock(block->fPtr, block->fSize);
304 if (not IsBlockOk(tracksBlock, blockType))
305 {
306 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
307 continue;
308 }
309 gottracks = true;
310
d24a4636 311 ntracksT += tracksBlock.Nentries();
c1550d2c 312 for (AliHLTUInt32_t i = 0; i < tracksBlock.Nentries(); ++i)
313 {
314 AliHLTMUONParticleSign sign;
315 bool hitset[4];
316 AliHLTMUONUtils::UnpackMansoTrackFlags(tracksBlock[i].fFlags, sign, hitset);
317 switch (sign)
318 {
319 case kSignPlus: ++nplus; break;
320 case kSignMinus: ++nminus; break;
321 default: break;
322 }
323 }
324 }
325
d24a4636 326 blockType = AliHLTMUONConstants::TracksBlockDataType();
327 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
328 block != NULL;
329 block = GetNextInputBlock()
330 )
331 {
332 AliHLTMUONTracksBlockReader tracksBlock(block->fPtr, block->fSize);
333 if (not IsBlockOk(tracksBlock, blockType))
334 {
335 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
336 continue;
337 }
338 gottracks = true;
339
340 ntracksT += tracksBlock.Nentries();
341 for (AliHLTUInt32_t i = 0; i < tracksBlock.Nentries(); ++i)
342 {
343 AliHLTMUONParticleSign sign;
344 bool hitset[16];
345 AliHLTMUONUtils::UnpackTrackFlags(tracksBlock[i].fFlags, sign, hitset);
346 switch (sign)
347 {
348 case kSignPlus: ++nplus; break;
349 case kSignMinus: ++nminus; break;
350 default: break;
351 }
352 }
353 }
354
c1550d2c 355 blockType = AliHLTMUONConstants::SinglesDecisionBlockDataType();
356 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
357 block != NULL;
358 block = GetNextInputBlock()
359 )
360 {
361 AliHLTMUONSinglesDecisionBlockReader singlesBlock(block->fPtr, block->fSize);
362 if (not IsBlockOk(singlesBlock, blockType))
363 {
364 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
365 continue;
366 }
367 gotsingles = true;
368
369 ntracksSD += singlesBlock.Nentries();
370 nlowpt += singlesBlock.BlockHeader().fNlowPt;
371 nhighpt += singlesBlock.BlockHeader().fNhighPt;
372 for (AliHLTUInt32_t i = 0; i < singlesBlock.Nentries(); ++i)
373 {
374 if (singlesBlock[i].fPt < minpt or minpt == -1) minpt = singlesBlock[i].fPt;
375 if (singlesBlock[i].fPt > maxpt or maxpt == -1) maxpt = singlesBlock[i].fPt;
376 }
377 }
378
379 blockType = AliHLTMUONConstants::PairsDecisionBlockDataType();
380 for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
381 block != NULL;
382 block = GetNextInputBlock()
383 )
384 {
385 AliHLTMUONPairsDecisionBlockReader pairsBlock(block->fPtr, block->fSize);
386 if (not IsBlockOk(pairsBlock, blockType))
387 {
388 HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
389 continue;
390 }
391 gotpairs = true;
392
393 nunlikeany += pairsBlock.BlockHeader().fNunlikeAnyPt;
394 nlikeany += pairsBlock.BlockHeader().fNlikeAnyPt;
395 // Dont use the other scalars from the pair decisions block header because
396 // they are much more restrictive. They count pairs where both tracks pass
397 // the low or high pT cut. But we want to relax this to just one track needs
398 // to pass the pT cut.
399 for (AliHLTUInt32_t i = 0; i < pairsBlock.Nentries(); ++i)
400 {
401 if (pairsBlock[i].fInvMass < minmass or minmass == -1) minmass = pairsBlock[i].fInvMass;
402 if (pairsBlock[i].fInvMass > maxmass or maxmass == -1) maxmass = pairsBlock[i].fInvMass;
403 bool highMass, lowMass, unlike;
404 AliHLTUInt8_t highPtCount, lowPtCount;
405 AliHLTMUONUtils::UnpackPairDecisionBits(
406 pairsBlock[i].fTriggerBits, highMass, lowMass, unlike,
407 highPtCount, lowPtCount
408 );
409 if (unlike)
410 {
411 if (lowPtCount >= 1) ++nunlikelow;
412 if (highPtCount >= 1) ++nunlikehigh;
413 if (lowMass) ++nlowmass;
414 if (highMass) ++nhighmass;
415 }
416 else
417 {
418 if (lowPtCount >= 1) ++nlikelow;
419 if (highPtCount >= 1) ++nlikehigh;
420 }
421 }
422 }
423
424 // Select the largest value for nTracks since we might only get this information
425 // from singles decision blocks.
d24a4636 426 UInt_t ntracks = ntracksSD > ntracksT ? ntracksSD : ntracksT;
c1550d2c 427
c057e1f9 428 bool triggeredOnDDLs = fTriggerDDLs and nL0 > 0;
c1550d2c 429 bool triggeredOnHits = fTriggerHits and nhitsMCH > 0;
430 bool triggeredOnTrigRecs = fTriggerTrigRecs and ntrigrecs > 0;
431 bool triggeredOnTracks = fTriggerTracks and ntracks > 0;
432 bool triggeredOnDimuons = fTriggerDimuons and (nunlikeany > 0
433 or nunlikelow > 0 or nunlikehigh > 0 or nlowmass > 0 or nhighmass > 0);
434
435 if (triggeredOnDimuons)
436 {
437 SetDescription("Dimuon in muon spectrometer");
438 SetTriggerDomain(AliHLTTriggerDomain("*******:MUON"));
439 }
440 else if (triggeredOnTracks)
441 {
442 SetDescription("Tracks in muon spectrometer");
443 SetTriggerDomain(AliHLTTriggerDomain("*******:MUON"));
444 }
445 else if (triggeredOnTrigRecs)
446 {
447 SetDescription("Muon trigger chambers triggered");
448 if (triggeredOnHits)
449 {
450 SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRG | AliHLTReadoutList::kMUONTRK));
451 SetTriggerDomain(AliHLTTriggerDomain("TRIGRECS:MUON,RECHITS :MUON"));
452 }
453 else
454 {
455 SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRG));
456 SetTriggerDomain(AliHLTTriggerDomain("TRIGRECS:MUON"));
457 }
458 }
459 else if (triggeredOnHits)
460 {
461 SetDescription("Hits in muon tracking chambers");
462 SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRK));
463 SetTriggerDomain(AliHLTTriggerDomain("RECHITS :MUON"));
464 }
c057e1f9 465 else if (triggeredOnDDLs)
466 {
467 SetDescription("DDL in muon tracking chambers");
468 SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRG | AliHLTReadoutList::kMUONTRK));
469 SetTriggerDomain(AliHLTTriggerDomain("DDL_RAW :MUON"));
470 }
c1550d2c 471 else
472 {
473 SetDescription("Not triggered");
474 SetTriggerDomain(AliHLTTriggerDomain());
475 }
476
c057e1f9 477 if (triggeredOnDimuons or triggeredOnTracks or triggeredOnTrigRecs or triggeredOnHits or triggeredOnDDLs)
c1550d2c 478 {
479 result = TriggerEvent();
480 if (result == -ENOSPC) goto increaseBuffer;
481 if (result != 0) return result;
482 }
483
484 if (fMakeStats)
485 {
486 AliHLTMuonSpectroScalars scalars;
c057e1f9 487 if (gotddls) scalars.Add("NL0", "Number of L0 triggered event", nL0);
c1550d2c 488 if (gothits and gottrigrecs) scalars.Add("NHits", "Total number of hits", nhits);
489 if (gottrigrecs) scalars.Add("NHitsMTR", "Number of hits in trigger chambers", nhitsMTR);
490 if (gothits)
491 {
492 scalars.Add("NHitsMCH", "Number of hits in tracking chambers", nhitsMCH);
493 for (int i = 0; i < 10; i++)
494 {
495 scalars.Add(Form("NHitsCh%d", i+1), Form("Number of hits in chamber %d", i+1), nhitsCh[i]);
496 }
497 }
498 if (gottrigrecs)
499 {
500 for (int i = 10; i < 14; i++)
501 {
502 scalars.Add(Form("NHitsCh%d", i+1), Form("Number of hits in chamber %d", i+1), nhitsCh[i]);
503 }
504 scalars.Add("NTrigRecs", "Total number of trigger records", ntrigrecs);
505 scalars.Add("NL0+", "Number of positive sign tracks in L0", nL0plus);
506 scalars.Add("NL0-", "Number of negative sign tracks in L0", nL0minus);
507 }
508 if (gottracks or gotsingles) scalars.Add("NTracks", "Total number of tracks", ntracks);
509 if (gottracks)
510 {
511 scalars.Add("N+", "Number of positive sign tracks", nplus);
512 scalars.Add("N-", "Number of negative sign tracks", nminus);
513 }
514 if (gotsingles)
515 {
516 scalars.Add("NLowPt", "Number of low pT tracks", nlowpt);
517 scalars.Add("NHighPt", "Number of high pT tracks", nhighpt);
518 scalars.Add("MinPt", "Minimum pT found (GeV/c)", minpt);
519 scalars.Add("MaxPt", "Maximum pT found (GeV/c)", maxpt);
520 }
521 if (gotpairs)
522 {
523 scalars.Add("NLikeAny", "Number of like sign track pairs", nlikeany);
524 scalars.Add("NLikeLow", "Number of like sign pairs with at least 1 low pT track.", nlikelow);
525 scalars.Add("NLikeHigh", "Number of like sign pairs with at least 1 high pT track.", nlikehigh);
526 scalars.Add("NUnlikeAny", "Number of unlike sign track pairs", nunlikeany);
527 scalars.Add("NUnlikeLow", "Number of unlike sign pairs with at least 1 low pT track.", nunlikelow);
528 scalars.Add("NUnlikeHigh", "Number of unlike sign pairs with at least 1 high pT track.", nunlikehigh);
529 scalars.Add("NLowMass", "Number of low mass dimuons", nlowmass);
530 scalars.Add("NHighMass", "Number of high mass dimuons", nhighmass);
531 scalars.Add("MinMass", "Minimum invariant mass found for dimuon (GeV/c^2)", minmass);
532 scalars.Add("MaxMass", "Maximum invariant mass found for dimuon (GeV/c^2)", maxmass);
533 }
534
535 result = PushBack(&scalars, kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT);
536 if (result == -ENOSPC) goto increaseBuffer;
537 }
538 return result;
539
540increaseBuffer:
541 // Increase the estimated buffer space required since the PushBack
542 // or TriggerEvent methods indicate that they ran out of buffer space.
543 fBufferSizeConst += 1024*1024;
544 fBufferSizeMultiplier *= 2.;
545 return -ENOSPC;
546}
547
548
549template <typename BlockReader>
550bool AliHLTMuonSpectroTriggerComponent::IsBlockOk(
551 const BlockReader& reader, const AliHLTComponentDataType& type
552 ) const
553{
554 // Method for checking the block structure.
555
556 if (not reader.BufferSizeOk())
557 {
558 string name = DataType2Text(type).c_str();
559 size_t headerSize = sizeof(typename BlockReader::HeaderType);
560 if (reader.BufferSize() < headerSize)
561 {
562 HLTError("Received a '%s' data block with a size of %d bytes,"
563 " which is smaller than the minimum valid size of %d bytes."
564 " The block must be corrupt.",
565 name.c_str(), reader.BufferSize(), headerSize
566 );
567 }
568
569 size_t expectedWidth = sizeof(typename BlockReader::ElementType);
570 if (reader.CommonBlockHeader().fRecordWidth != expectedWidth)
571 {
572 HLTError("Received a '%s' data block with a record"
573 " width of %d bytes, but the expected value is %d bytes."
574 " The block might be corrupt.",
575 name.c_str(),
576 reader.CommonBlockHeader().fRecordWidth,
577 expectedWidth
578 );
579 }
580
581 HLTError("Received a '%s' data block with a size of %d bytes,"
582 " but the block header claims the block should be %d bytes."
583 " The block might be corrupt.",
584 name.c_str(), reader.BufferSize(), reader.BytesUsed()
585 );
586 return false;
587 }
588 return true;
589}