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 **************************************************************************/
17 /// \class AliMUONPadStatusMaker
19 /// Make a 2DStore of pad statuses, using different sources of information,
20 /// like pedestal values, gain values, and HV values.
23 // Author Laurent Aphecetche
25 #include "AliMUONPadStatusMaker.h"
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"
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"
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"
52 #include "AliCDBManager.h"
53 #include "AliCDBEntry.h"
54 #include "AliDCSValue.h"
57 #include "Riostream.h"
59 #include "TStopwatch.h"
64 ClassImp(AliMUONPadStatusMaker)
66 //_____________________________________________________________________________
67 AliMUONPadStatusMaker::AliMUONPadStatusMaker(const AliMUONCalibrationData& calibData)
68 : fCalibrationData(calibData),
69 fPedMeanLimits(0,4095),
70 fPedSigmaLimits(0,4095),
71 fHVSt12Limits(0,5000),
72 fHVSt345Limits(0,5000)
77 //_____________________________________________________________________________
78 AliMUONPadStatusMaker::~AliMUONPadStatusMaker()
83 //_____________________________________________________________________________
85 AliMUONPadStatusMaker::Combine(const AliMUONV2DStore& store1,
86 const AliMUONV2DStore& store2,
89 /// Combine two status containers into one, shifting store2 status bits
90 /// to the left by binShift before making an OR with store1.
95 AliMUONV2DStore* combined = static_cast<AliMUONV2DStore*>(store1.Clone());
97 AliMUONVDataIterator* it = store1.Iterator();
98 AliMUONObjectPair* pair;
100 while ( ( pair = static_cast<AliMUONObjectPair*>(it->Next()) ) )
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));
108 AliError(Form("Oups. Could not get statuses for store1 for DE %d ManuId %d !!!",
114 AliMUONVCalibParam* param2 = static_cast<AliMUONVCalibParam*>(store2.Get(detElemId,manuId));
117 AliError(Form("Oups. Could not get statuses for store2 for DE %d ManuId %d",
123 AliMUONVCalibParam* paramCombined = static_cast<AliMUONVCalibParam*>(combined->Get(detElemId,manuId));
126 AliError(Form("Oups. Could not get statuses for combined for DE %d ManuId %d",
133 for ( Int_t manuChannel = 0; manuChannel < param1->Size(); ++manuChannel )
135 if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) )
137 Int_t status1(param1->ValueAsInt(manuChannel));
138 Int_t status2(param2->ValueAsInt(manuChannel));
140 Int_t status = status1 | (status2 << binShift);
142 paramCombined->SetValueAsInt(manuChannel,0,status);
150 StdoutToAliInfo(timer.Print(););
155 //_____________________________________________________________________________
157 AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap,
158 Int_t detElemId, Int_t sector,
159 Bool_t& hvChannelTooLow,
160 Bool_t& hvChannelTooHigh,
161 Bool_t& hvChannelON) const
163 /// Get HV status for one HV sector of St12
165 /// For a given PCB in a given DE, get the HV status (both the channel
167 /// Returns false if hv switch changed during the run.
169 Bool_t error = kFALSE;
170 hvChannelTooLow = kFALSE;
171 hvChannelTooHigh = kFALSE;
174 AliMUONHVNamer hvNamer;
176 TString hvChannel(hvNamer.DCSHVChannelName(detElemId,sector));
178 TPair* hvPair = static_cast<TPair*>(hvMap.FindObject(hvChannel.Data()));
181 AliError(Form("Did not find expected alias (%s) for DE %d",
182 hvChannel.Data(),detElemId));
187 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
190 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
195 // find out min and max value, and makes a cut
201 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
203 Float_t hv = val->GetFloat();
204 hvMin = TMath::Min(hv,hvMin);
205 hvMax = TMath::Max(hv,hvMax);
208 float lowThreshold = fHVSt12Limits.X();
209 float highThreshold = fHVSt12Limits.Y();
211 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
212 if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
213 if ( hvMin < 1 ) hvChannelON = kFALSE;
220 //_____________________________________________________________________________
222 AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap,
223 Int_t detElemId, Int_t pcbIndex,
224 Bool_t& hvChannelTooLow,
225 Bool_t& hvChannelTooHigh,
227 Bool_t& hvSwitchON) const
229 /// For a given PCB in a given DE, get the HV status (both the channel
231 /// Returns false if something goes wrong (in particular if
232 /// hv switch changed during the run).
234 Bool_t error = kFALSE;
235 hvChannelTooLow = kFALSE;
236 hvChannelTooHigh = kFALSE;
240 AliMUONHVNamer hvNamer;
242 TString hvChannel(hvNamer.DCSHVChannelName(detElemId));
244 TPair* hvPair = static_cast<TPair*>(hvMap.FindObject(hvChannel.Data()));
247 AliError(Form("Did not find expected alias (%s) for DE %d",
248 hvChannel.Data(),detElemId));
253 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
256 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
261 // find out min and max value, and makes a cut
267 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
269 Float_t hv = val->GetFloat();
270 hvMin = TMath::Min(hv,hvMin);
271 hvMax = TMath::Max(hv,hvMax);
274 float lowThreshold = fHVSt345Limits.X();
275 float highThreshold = fHVSt345Limits.Y();
277 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
278 if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
279 if ( hvMin < 1 ) hvChannelON = kFALSE;
283 TString hvSwitch(hvNamer.DCSHVSwitchName(detElemId,pcbIndex));
284 TPair* switchPair = static_cast<TPair*>(hvMap.FindObject(hvSwitch.Data()));
287 AliError(Form("Did not find expected alias (%s) for DE %d PCB %d",
288 hvSwitch.Data(),detElemId,pcbIndex));
293 TObjArray* values = static_cast<TObjArray*>(switchPair->Value());
296 AliError(Form("Could not get values for alias %s",hvSwitch.Data()));
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)
309 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
311 if ( val->GetBool() )
321 if ( (nTrue>0 && nFalse>0) )
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));
328 if ( nFalse ) hvSwitchON = kFALSE;
334 //_____________________________________________________________________________
336 AliMUONPadStatusMaker::MakeGainStatus(const AliMUONV2DStore& /*gainValues*/) const
338 /// FIXME: to be implemented
339 AliWarning("Not implemented yet");
343 //_____________________________________________________________________________
345 AliMUONPadStatusMaker::MakeHVStatus(const TMap& hvValues) const
347 /// Scrutinize HV values and deduce an HV status for each pad
349 TStopwatch timerSt12;
350 TStopwatch timerSt345;
352 timerSt12.Start(kTRUE);
354 timerSt345.Start(kTRUE);
357 AliMUONHVNamer hvNamer;
359 AliMpDEIterator deIt;
363 AliMUONV2DStore* hv = new AliMUON2DMap(kTRUE);
365 while ( !deIt.IsDone() )
367 Int_t detElemId = deIt.CurrentDEId();
369 switch ( AliMpDEManager::GetStationType(detElemId) )
371 case AliMp::kStation1:
372 case AliMp::kStation2:
373 timerSt12.Start(kFALSE);
374 for ( int sector = 0; sector < 3; ++sector)
376 AliDebug(1,Form("detElemId %5d sector %d",detElemId,sector));
378 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON;
379 Bool_t error = GetSt12Status(hvValues,
381 hvChannelTooLow,hvChannelTooHigh,
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);
393 case AliMp::kStation345:
395 timerSt345.Start(kFALSE);
396 for ( Int_t pcbIndex = 0; pcbIndex < hvNamer.NumberOfPCBs(detElemId); ++pcbIndex)
398 AliDebug(1,Form("detElemId %5d pcbIndex %d",detElemId,pcbIndex));
399 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON;
400 Bool_t error = GetSt345Status(hvValues,
402 hvChannelTooLow,hvChannelTooHigh,
403 hvChannelON,hvSwitchON);
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);
421 AliInfo("St12 timer:");
422 StdoutToAliInfo(timerSt12.Print(););
423 AliInfo("St345 timer:");
424 StdoutToAliInfo(timerSt345.Print(););
429 //_____________________________________________________________________________
431 AliMUONPadStatusMaker::MakePedestalStatus(const AliMUONV2DStore& pedValues) const
433 /// Assign a pedestal status to each pad
439 AliMUONV2DStore* pedStatuses = new AliMUON2DMap(kTRUE);
441 AliMUONVDataIterator* it = pedValues.Iterator();
442 AliMUONObjectPair* pair;
445 while ( ( pair = static_cast<AliMUONObjectPair*>(it->Next() ) ) )
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());
452 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
455 if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) )
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;
465 AliMUONVCalibParam* vStatus =
466 static_cast<AliMUONVCalibParam*>(pedStatuses->Get(detElemId,manuId));
469 vStatus = new AliMUONCalibParam1I(64,0);
470 pedStatuses->Set(detElemId,manuId,vStatus,false);
472 vStatus->SetValueAsInt(manuChannel,0,status);
477 AliInfo(Form("%d manus checked in :",nofManus));
478 StdoutToAliInfo(timer.Print(););
482 //_____________________________________________________________________________
484 AliMUONPadStatusMaker::MakeStatus() const
486 /// Read ped, gains and hv values from CDB, apply some Q&A and produces
487 /// a combined status for each pad.
489 TMap* hvValues = fCalibrationData.HV();
493 AliError("Could not get HV values from CDB");
497 AliMUONV2DStore* pedValues = fCalibrationData.Pedestals();
501 AliError("Could not get pedestals values from CDB");
506 // AliMUONV2DStore* gainValues = fCalibrationData.Gains();
508 AliMUONV2DStore* hvStatus = MakeHVStatus(*hvValues);
509 AliMUONV2DStore* pedStatus = MakePedestalStatus(*pedValues);
511 AliMUONV2DStore* status = Combine(*hvStatus,*pedStatus,8);
519 //_____________________________________________________________________________
521 AliMUONPadStatusMaker::SetStatusSt12(AliMUONV2DStore& hvStatus,
526 /// Flag all pads of detElemId (for St12) as bad.
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...
532 const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 };
534 for ( Int_t icathode = 0; icathode < 2; ++icathode )
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();
542 mMap->GetAllMotifPositionsIDs(a);
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;
549 for ( Int_t i = 0; i < a.GetSize(); ++i )
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)
556 AliMUONVCalibParam* dead =
557 static_cast<AliMUONVCalibParam*>(hvStatus.Get(detElemId,manuId));
560 dead = new AliMUONCalibParam1I(64,status);
561 hvStatus.Set(detElemId,manuId,dead,false);
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.");
576 //_____________________________________________________________________________
578 AliMUONPadStatusMaker::SetStatusSt345(AliMUONV2DStore& hvStatus,
579 Int_t detElemId, Int_t pcbIndex,
582 /// Flag all pads of pcbIndex-th PCB of detElemId (for St345) as bad.
584 const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 };
586 for ( Int_t icathode = 0; icathode < 2; ++icathode )
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);
593 for ( Int_t i = 0; i < pcb->GetSize(); ++i )
595 AliMpMotifPosition* pos = pcb->GetMotifPosition(i);
596 Int_t manuId = pos->GetID();
597 AliMUONVCalibParam* dead =
598 static_cast<AliMUONVCalibParam*>(hvStatus.Get(detElemId,manuId));
601 AliError(Form("dead is not null as expected from DE %d manuId %d",
606 dead = new AliMUONCalibParam1I(64,status);
607 hvStatus.Set(detElemId,manuId,dead,false);