]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONPadStatusMaker.cxx
Many changes : \n-concerning trigger, fixing bugs in efficiency handling, partly...
[u/mrichter/AliRoot.git] / MUON / AliMUONPadStatusMaker.cxx
CommitLineData
2c780493 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/// \class AliMUONPadStatusMaker
18///
19/// Make a 2DStore of pad statuses, using different sources of information,
20/// like pedestal values, gain values, and HV values.
21///
22///
23// Author Laurent Aphecetche
24
25#include "AliMUONPadStatusMaker.h"
26
27#include "AliMUON2DMap.h"
28#include "AliMUONCalibParam1I.h"
29#include "AliMUONCalibrationData.h"
30#include "AliMUONHVNamer.h"
31#include "AliMUONObjectPair.h"
32#include "AliMUONVCalibParam.h"
33#include "AliMUONVDataIterator.h"
34
35#include "AliMpArea.h"
36#include "AliMpDEIterator.h"
37#include "AliMpDEManager.h"
38#include "AliMpIntPair.h"
39#include "AliMpManuList.h"
40#include "AliMpMotifMap.h"
41#include "AliMpMotifPosition.h"
42#include "AliMpPCB.h"
43#include "AliMpPad.h"
44#include "AliMpSector.h"
45#include "AliMpSectorSegmentation.h"
46#include "AliMpSegmentation.h"
47#include "AliMpSlat.h"
48#include "AliMpSlatSegmentation.h"
49#include "AliMpStationType.h"
50#include "AliMpVPadIterator.h"
51
52#include "AliCDBManager.h"
53#include "AliCDBEntry.h"
54#include "AliDCSValue.h"
55#include "AliLog.h"
56
57#include "Riostream.h"
58#include "TMap.h"
59#include "TStopwatch.h"
60#include "TString.h"
61
62#include <cassert>
63
64ClassImp(AliMUONPadStatusMaker)
65
66//_____________________________________________________________________________
67AliMUONPadStatusMaker::AliMUONPadStatusMaker(const AliMUONCalibrationData& calibData)
68: fCalibrationData(calibData),
69 fPedMeanLimits(0,4095),
70 fPedSigmaLimits(0,4095),
71 fHVSt12Limits(0,5000),
72 fHVSt345Limits(0,5000)
73{
74 // ctor
75}
76
77//_____________________________________________________________________________
78AliMUONPadStatusMaker::~AliMUONPadStatusMaker()
79{
80 // dtor.
81}
82
83//_____________________________________________________________________________
84AliMUONV2DStore*
85AliMUONPadStatusMaker::Combine(const AliMUONV2DStore& store1,
86 const AliMUONV2DStore& store2,
87 Int_t binShift) const
88{
89 /// Combine two status containers into one, shifting store2 status bits
90 /// to the left by binShift before making an OR with store1.
91
92 TStopwatch timer;
93 timer.Start(kTRUE);
94
95 AliMUONV2DStore* combined = static_cast<AliMUONV2DStore*>(store1.Clone());
96
97 AliMUONVDataIterator* it = store1.Iterator();
98 AliMUONObjectPair* pair;
99
100 while ( ( pair = static_cast<AliMUONObjectPair*>(it->Next()) ) )
101 {
102 AliMpIntPair* ip = static_cast<AliMpIntPair*>(pair->First());
103 Int_t detElemId = ip->GetFirst();
104 Int_t manuId = ip->GetSecond();
105 AliMUONVCalibParam* param1 = static_cast<AliMUONVCalibParam*>(store1.Get(detElemId,manuId));
106 if (!param1)
107 {
108 AliError(Form("Oups. Could not get statuses for store1 for DE %d ManuId %d !!!",
109 detElemId,manuId));
110 delete combined;
111 combined = 0x0;
112 break;
113 }
114 AliMUONVCalibParam* param2 = static_cast<AliMUONVCalibParam*>(store2.Get(detElemId,manuId));
115 if (!param2)
116 {
117 AliError(Form("Oups. Could not get statuses for store2 for DE %d ManuId %d",
118 detElemId,manuId));
119 delete combined;
120 combined = 0x0;
121 break;
122 }
123 AliMUONVCalibParam* paramCombined = static_cast<AliMUONVCalibParam*>(combined->Get(detElemId,manuId));
124 if (!paramCombined)
125 {
126 AliError(Form("Oups. Could not get statuses for combined for DE %d ManuId %d",
127 detElemId,manuId));
128 delete combined;
129 combined = 0x0;
130 break;
131 }
132
133 for ( Int_t manuChannel = 0; manuChannel < param1->Size(); ++manuChannel )
134 {
135 if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) )
136 {
137 Int_t status1(param1->ValueAsInt(manuChannel));
138 Int_t status2(param2->ValueAsInt(manuChannel));
139
140 Int_t status = status1 | (status2 << binShift);
141
142 paramCombined->SetValueAsInt(manuChannel,0,status);
143 }
144 }
145 }
146
147 delete it;
148
149 AliInfo("Timer:");
150 StdoutToAliInfo(timer.Print(););
151
152 return combined;
153}
154
155//_____________________________________________________________________________
156Bool_t
157AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap,
158 Int_t detElemId, Int_t sector,
159 Bool_t& hvChannelTooLow,
160 Bool_t& hvChannelTooHigh,
161 Bool_t& hvChannelON) const
162{
163 /// Get HV status for one HV sector of St12
164
165 /// For a given PCB in a given DE, get the HV status (both the channel
166 /// and the switch).
167 /// Returns false if hv switch changed during the run.
168
169 Bool_t error = kFALSE;
170 hvChannelTooLow = kFALSE;
171 hvChannelTooHigh = kFALSE;
172 hvChannelON = kTRUE;
173
174 AliMUONHVNamer hvNamer;
175
176 TString hvChannel(hvNamer.DCSHVChannelName(detElemId,sector));
177
178 TPair* hvPair = static_cast<TPair*>(hvMap.FindObject(hvChannel.Data()));
179 if (!hvPair)
180 {
181 AliError(Form("Did not find expected alias (%s) for DE %d",
182 hvChannel.Data(),detElemId));
183 error = kTRUE;
184 }
185 else
186 {
187 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
188 if (!values)
189 {
190 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
191 error = kTRUE;
192 }
193 else
194 {
195 // find out min and max value, and makes a cut
196 Float_t hvMin(1E9);
197 Float_t hvMax(0);
198 TIter next(values);
199 AliDCSValue* val;
200
201 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
202 {
203 Float_t hv = val->GetFloat();
204 hvMin = TMath::Min(hv,hvMin);
205 hvMax = TMath::Max(hv,hvMax);
206 }
207
208 float lowThreshold = fHVSt12Limits.X();
209 float highThreshold = fHVSt12Limits.Y();
210
211 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
212 if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
213 if ( hvMin < 1 ) hvChannelON = kFALSE;
214 }
215 }
216
217 return error;
218}
219
220//_____________________________________________________________________________
221Bool_t
222AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap,
223 Int_t detElemId, Int_t pcbIndex,
224 Bool_t& hvChannelTooLow,
225 Bool_t& hvChannelTooHigh,
226 Bool_t& hvChannelON,
227 Bool_t& hvSwitchON) const
228{
229 /// For a given PCB in a given DE, get the HV status (both the channel
230 /// and the switch).
231 /// Returns false if something goes wrong (in particular if
232 /// hv switch changed during the run).
233
234 Bool_t error = kFALSE;
235 hvChannelTooLow = kFALSE;
236 hvChannelTooHigh = kFALSE;
237 hvSwitchON = kTRUE;
238 hvChannelON = kTRUE;
239
240 AliMUONHVNamer hvNamer;
241
242 TString hvChannel(hvNamer.DCSHVChannelName(detElemId));
243
244 TPair* hvPair = static_cast<TPair*>(hvMap.FindObject(hvChannel.Data()));
245 if (!hvPair)
246 {
247 AliError(Form("Did not find expected alias (%s) for DE %d",
248 hvChannel.Data(),detElemId));
249 error = kTRUE;
250 }
251 else
252 {
253 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
254 if (!values)
255 {
256 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
257 error = kTRUE;
258 }
259 else
260 {
261 // find out min and max value, and makes a cut
262 Float_t hvMin(1E9);
263 Float_t hvMax(0);
264 TIter next(values);
265 AliDCSValue* val;
266
267 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
268 {
269 Float_t hv = val->GetFloat();
270 hvMin = TMath::Min(hv,hvMin);
271 hvMax = TMath::Max(hv,hvMax);
272 }
273
274 float lowThreshold = fHVSt345Limits.X();
275 float highThreshold = fHVSt345Limits.Y();
276
277 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
278 if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
279 if ( hvMin < 1 ) hvChannelON = kFALSE;
280 }
281 }
282
283 TString hvSwitch(hvNamer.DCSHVSwitchName(detElemId,pcbIndex));
284 TPair* switchPair = static_cast<TPair*>(hvMap.FindObject(hvSwitch.Data()));
285 if (!switchPair)
286 {
287 AliError(Form("Did not find expected alias (%s) for DE %d PCB %d",
288 hvSwitch.Data(),detElemId,pcbIndex));
289 error = kTRUE;
290 }
291 else
292 {
293 TObjArray* values = static_cast<TObjArray*>(switchPair->Value());
294 if (!values)
295 {
296 AliError(Form("Could not get values for alias %s",hvSwitch.Data()));
297 error = kTRUE;
298 }
299 else
300 {
301 // we'll count the number of ON/OFF for this pad, to insure
302 // consistency (i.e. if status changed during the run, we should
303 // at least notify this fact ;-) and hope it's not the norm)
304 Int_t nTrue(0);
305 Int_t nFalse(0);
306 TIter next(values);
307 AliDCSValue* val;
308
309 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
310 {
311 if ( val->GetBool() )
312 {
313 ++nTrue;
314 }
315 else
316 {
317 ++nFalse;
318 }
319 }
320
321 if ( (nTrue>0 && nFalse>0) )
322 {
323 AliWarning(Form("Status of HV Switch %s changed during this run nTrue=%d nFalse=%d! Will consider it OFF",
324 hvSwitch.Data(),nTrue,nFalse));
325 error = kTRUE;
326 }
327
328 if ( nFalse ) hvSwitchON = kFALSE;
329 }
330 }
331 return error;
332}
333
334//_____________________________________________________________________________
335AliMUONV2DStore*
336AliMUONPadStatusMaker::MakeGainStatus(const AliMUONV2DStore& /*gainValues*/) const
337{
338 /// FIXME: to be implemented
339 AliWarning("Not implemented yet");
340 return 0x0;
341}
342
343//_____________________________________________________________________________
344AliMUONV2DStore*
345AliMUONPadStatusMaker::MakeHVStatus(const TMap& hvValues) const
346{
347 /// Scrutinize HV values and deduce an HV status for each pad
348
349 TStopwatch timerSt12;
350 TStopwatch timerSt345;
351
352 timerSt12.Start(kTRUE);
353 timerSt12.Stop();
354 timerSt345.Start(kTRUE);
355 timerSt345.Stop();
356
357 AliMUONHVNamer hvNamer;
358
359 AliMpDEIterator deIt;
360
361 deIt.First();
362
363 AliMUONV2DStore* hv = new AliMUON2DMap(kTRUE);
364
365 while ( !deIt.IsDone() )
366 {
367 Int_t detElemId = deIt.CurrentDEId();
368
369 switch ( AliMpDEManager::GetStationType(detElemId) )
370 {
371 case AliMp::kStation1:
372 case AliMp::kStation2:
373 timerSt12.Start(kFALSE);
374 for ( int sector = 0; sector < 3; ++sector)
375 {
376 AliDebug(1,Form("detElemId %5d sector %d",detElemId,sector));
377
378 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON;
379 Bool_t error = GetSt12Status(hvValues,
380 detElemId,sector,
381 hvChannelTooLow,hvChannelTooHigh,
382 hvChannelON);
383 Int_t status = 0;
384 if ( error ) status |= kHVError;
385 if ( hvChannelTooLow ) status |= kHVTooLow;
386 if ( hvChannelTooHigh ) status |= kHVTooHigh;
387 if ( !hvChannelON ) status |= kHVChannelOFF;
388 SetStatusSt12(*hv,detElemId,sector,status);
389
390 }
391 timerSt12.Stop();
392 break;
393 case AliMp::kStation345:
394 {
395 timerSt345.Start(kFALSE);
396 for ( Int_t pcbIndex = 0; pcbIndex < hvNamer.NumberOfPCBs(detElemId); ++pcbIndex)
397 {
398 AliDebug(1,Form("detElemId %5d pcbIndex %d",detElemId,pcbIndex));
399 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON;
400 Bool_t error = GetSt345Status(hvValues,
401 detElemId,pcbIndex,
402 hvChannelTooLow,hvChannelTooHigh,
403 hvChannelON,hvSwitchON);
404 Int_t status = 0;
405 if ( error ) status |= kHVError;
406 if ( hvChannelTooLow ) status |= kHVTooLow;
407 if ( hvChannelTooHigh ) status |= kHVTooHigh;
408 if ( !hvSwitchON ) status |= kHVSwitchOFF;
409 if ( !hvChannelON) status |= kHVChannelOFF;
410 SetStatusSt345(*hv,detElemId,pcbIndex,status);
411 }
412 timerSt345.Stop();
413 }
414 break;
415 default:
416 break;
417 }
418 deIt.Next();
419 }
420
421 AliInfo("St12 timer:");
422 StdoutToAliInfo(timerSt12.Print(););
423 AliInfo("St345 timer:");
424 StdoutToAliInfo(timerSt345.Print(););
425
426 return hv;
427}
428
429//_____________________________________________________________________________
430AliMUONV2DStore*
431AliMUONPadStatusMaker::MakePedestalStatus(const AliMUONV2DStore& pedValues) const
432{
433 /// Assign a pedestal status to each pad
434
435 TStopwatch timer;
436
437 timer.Start(kTRUE);
438
439 AliMUONV2DStore* pedStatuses = new AliMUON2DMap(kTRUE);
440
441 AliMUONVDataIterator* it = pedValues.Iterator();
442 AliMUONObjectPair* pair;
443 Int_t nofManus(0);
444
445 while ( ( pair = static_cast<AliMUONObjectPair*>(it->Next() ) ) )
446 {
447 AliMpIntPair* ip = static_cast<AliMpIntPair*>(pair->First());
448 Int_t detElemId = ip->GetFirst();
449 Int_t manuId = ip->GetSecond();
450 AliMUONVCalibParam* pedestals = static_cast<AliMUONVCalibParam*>(pair->Second());
451 ++nofManus;
452 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
453 {
454 Int_t status(0);
455 if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) )
456 {
457 Float_t pedMean = pedestals->ValueAsFloat(manuChannel,0);
458 Float_t pedSigma = pedestals->ValueAsFloat(manuChannel,1);
459 if ( pedMean < fPedMeanLimits.X() ) status |= kPedMeanTooLow;
460 if ( pedMean > fPedMeanLimits.Y() ) status |= kPedMeanTooHigh;
461 if ( pedSigma < fPedSigmaLimits.X() ) status |= kPedSigmaTooLow;
462 if ( pedSigma > fPedSigmaLimits.Y() ) status |= kPedSigmaTooHigh;
463 if ( pedMean == 0 ) status |= kPedMeanZero;
464
465 AliMUONVCalibParam* vStatus =
466 static_cast<AliMUONVCalibParam*>(pedStatuses->Get(detElemId,manuId));
467 if ( !vStatus )
468 {
469 vStatus = new AliMUONCalibParam1I(64,0);
470 pedStatuses->Set(detElemId,manuId,vStatus,false);
471 }
472 vStatus->SetValueAsInt(manuChannel,0,status);
473 }
474 }
475 }
476
477 AliInfo(Form("%d manus checked in :",nofManus));
478 StdoutToAliInfo(timer.Print(););
479 return pedStatuses;
480}
481
482//_____________________________________________________________________________
483AliMUONV2DStore*
484AliMUONPadStatusMaker::MakeStatus() const
485{
486 /// Read ped, gains and hv values from CDB, apply some Q&A and produces
487 /// a combined status for each pad.
488
489 TMap* hvValues = fCalibrationData.HV();
490
491 if (!hvValues)
492 {
493 AliError("Could not get HV values from CDB");
494 return 0x0;
495 }
496
497 AliMUONV2DStore* pedValues = fCalibrationData.Pedestals();
498
499 if (!pedValues)
500 {
501 AliError("Could not get pedestals values from CDB");
502 return 0x0;
503
504 }
505
506// AliMUONV2DStore* gainValues = fCalibrationData.Gains();
507
508 AliMUONV2DStore* hvStatus = MakeHVStatus(*hvValues);
509 AliMUONV2DStore* pedStatus = MakePedestalStatus(*pedValues);
510
511 AliMUONV2DStore* status = Combine(*hvStatus,*pedStatus,8);
512
513 delete hvStatus;
514 delete pedStatus;
515
516 return status;
517}
518
519//_____________________________________________________________________________
520void
521AliMUONPadStatusMaker::SetStatusSt12(AliMUONV2DStore& hvStatus,
522 Int_t detElemId,
523 Int_t isector,
524 Int_t status) const
525{
526 /// Flag all pads of detElemId (for St12) as bad.
527
528 // FIXME: need a way to iterator on pads over a given HV sector for St12...
529 // we currently suppose that one sector is about a third of the chamber...
530 // FIXME !! This has to be checked very carefully...
531
532 const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 };
533
534 for ( Int_t icathode = 0; icathode < 2; ++icathode )
535 {
536 const AliMpSectorSegmentation* seg =
537 static_cast<const AliMpSectorSegmentation*>(AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,kCathodes[icathode]));
538 const AliMpSector* sector = seg->GetSector();
539 AliMpMotifMap* mMap = sector->GetMotifMap();
540 TArrayI a;
541
542 mMap->GetAllMotifPositionsIDs(a);
543
544 TVector2 dim = seg->Dimensions();
545 Double_t x = dim.X()*2;
546 Double_t xmin = isector*x/3.0;
547 Double_t xmax = xmin + x/3.0;
548
549 for ( Int_t i = 0; i < a.GetSize(); ++i )
550 {
551 AliMpMotifPosition* pos = mMap->FindMotifPosition(a[i]);
552 Int_t manuId = pos->GetID();
553 TVector2 position = pos->Position();
554 if ( position.X() >= xmin && position.X() <= xmax)
555 {
556 AliMUONVCalibParam* dead =
557 static_cast<AliMUONVCalibParam*>(hvStatus.Get(detElemId,manuId));
558 if (!dead)
559 {
560 dead = new AliMUONCalibParam1I(64,status);
561 hvStatus.Set(detElemId,manuId,dead,false);
562 }
563 else
564 {
565 // FIXME: this should really not happen, if we'd know really the
566 // relationship between manuId and HV sector...
567 // For the time being, let's leave it like that, for testing
568 // purposes only. For production, this will have to be fixed.
569 AliWarning("Please fixme.");
570 }
571 }
572 }
573 }
574}
575
576//_____________________________________________________________________________
577void
578AliMUONPadStatusMaker::SetStatusSt345(AliMUONV2DStore& hvStatus,
579 Int_t detElemId, Int_t pcbIndex,
580 Int_t status) const
581{
582 /// Flag all pads of pcbIndex-th PCB of detElemId (for St345) as bad.
583
584 const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 };
585
586 for ( Int_t icathode = 0; icathode < 2; ++icathode )
587 {
588 const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
589 (AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,kCathodes[icathode]));
590 const AliMpSlat* slat = seg->Slat();
591 const AliMpPCB* pcb = slat->GetPCB(pcbIndex);
592
593 for ( Int_t i = 0; i < pcb->GetSize(); ++i )
594 {
595 AliMpMotifPosition* pos = pcb->GetMotifPosition(i);
596 Int_t manuId = pos->GetID();
597 AliMUONVCalibParam* dead =
598 static_cast<AliMUONVCalibParam*>(hvStatus.Get(detElemId,manuId));
599 if (dead)
600 {
601 AliError(Form("dead is not null as expected from DE %d manuId %d",
602 detElemId,manuId));
603 }
604 if (!dead)
605 {
606 dead = new AliMUONCalibParam1I(64,status);
607 hvStatus.Set(detElemId,manuId,dead,false);
608 }
609 }
610 }
611}
612
613
614