]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPadStatusMaker.cxx
In AliMUONRawStreamTriggerHP:
[u/mrichter/AliRoot.git] / MUON / AliMUONPadStatusMaker.cxx
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 AliMUONPadStatusMaker
20 ///
21 /// Make a 2DStore of pad statuses, using different sources of information,
22 /// like pedestal values, gain values, and HV values.
23 ///
24 /// \author Laurent Aphecetche
25 //-----------------------------------------------------------------------------
26
27 #include "AliMUONPadStatusMaker.h"
28
29 #include "AliMUON2DMap.h"
30 #include "AliMUON2DStoreValidator.h"
31 #include "AliMUONCalibParamNI.h"
32 #include "AliMUONCalibrationData.h"
33 #include "AliMUONStringIntMap.h"
34 #include "AliMUONVCalibParam.h"
35
36 #include "AliMpArea.h"
37 #include "AliMpArrayI.h"
38 #include "AliMpConstants.h"
39 #include "AliMpDDLStore.h"
40 #include "AliMpDEManager.h"
41 #include "AliMpDetElement.h"
42 #include "AliMpHVNamer.h"
43 #include "AliMpManuUID.h"
44
45 #include "AliCDBEntry.h"
46 #include "AliCDBManager.h"
47 #include "AliCodeTimer.h"
48 #include "AliDCSValue.h"
49 #include "AliLog.h"
50
51 #include <Riostream.h>
52 #include <TArrayI.h>
53 #include <TExMap.h>
54 #include <TMap.h>
55 #include <TString.h>
56
57 /// \cond CLASSIMP
58 ClassImp(AliMUONPadStatusMaker)
59 /// \endcond
60
61 //_____________________________________________________________________________
62 AliMUONPadStatusMaker::AliMUONPadStatusMaker(const AliMUONCalibrationData& calibData)
63 : fCalibrationData(calibData),
64   fGainA0Limits(0,1E30),
65   fGainA1Limits(-1E-30,1E30),
66   fGainThresLimits(0,4095),
67   fHVSt12Limits(0,5000),
68   fHVSt345Limits(0,5000),
69   fPedMeanLimits(0,4095),
70   fPedSigmaLimits(0,4095),
71   fStatus(new AliMUON2DMap(true)),
72   fHV(new TExMap),
73   fPedestals(calibData.Pedestals()),
74   fGains(calibData.Gains())
75 {
76    /// ctor
77     AliInfo(Form("ped store %s gain store %s",
78                  fPedestals->ClassName(),
79                  fGains->ClassName()));
80 }
81
82 //_____________________________________________________________________________
83 AliMUONPadStatusMaker::~AliMUONPadStatusMaker()
84 {
85   /// dtor.
86   delete fStatus;
87   delete fHV;
88 }
89
90 //_____________________________________________________________________________
91 TString
92 AliMUONPadStatusMaker::AsString(Int_t status)
93 {
94   /// return a human readable version of the integer status
95   Int_t pedStatus;
96   Int_t gainStatus;
97   Int_t hvStatus;
98   
99   DecodeStatus(status,pedStatus,hvStatus,gainStatus);
100   
101 //  /// Gain status
102 //  enum EGainStatus
103 //  {
104 //    kGainOK = 0,
105 //    kGainA0TooLow = (1<<1),
106 //    kGainA0TooHigh = (1<<2),
107 //    kGainA1TooLow = (1<<3),
108 //    kGainA1TooHigh = (1<<4),
109 //    kGainThresTooLow = (1<<5),
110 //    kGainThresTooHigh = (1<<6),
111 //    
112 //    kGainMissing = kMissing // please always use last bit for meaning "missing"
113 //  };
114 //  
115 //  /// Pedestal status
116 //  enum EPedestalStatus
117 //  {
118 //    kPedOK = 0,
119 //    kPedMeanZero = (1<<1),
120 //    kPedMeanTooLow = (1<<2),
121 //    kPedMeanTooHigh = (1<<3),
122 //    kPedSigmaTooLow = (1<<4),
123 //    kPedSigmaTooHigh = (1<<5),
124 //    
125 //    kPedMissing = kMissing // please always use last bit for meaning "missing"
126 //  };
127 //  
128   TString s("PED ");
129   
130   if ( pedStatus == 0 ) s+= " OK";
131   if ( pedStatus & kPedMeanZero ) s += " Mean is Zero. ";
132   if ( pedStatus & kPedMeanTooLow ) s += " Mean Too Low. ";
133   if ( pedStatus & kPedMeanTooHigh ) s += " Mean Too High. ";
134   if ( pedStatus & kPedSigmaTooLow ) s += " Sigma Too Low. ";
135   if ( pedStatus & kPedSigmaTooHigh ) s += " Sigma Too High. ";
136   if ( pedStatus & kPedMissing ) s += " is missing.";
137   
138 //  /// HV Error
139 //  enum EHVError 
140 //  {
141 //    kHVOK = 0,
142 //    kHVError = (1<<0),
143 //    kHVTooLow = (1<<1),
144 //    kHVTooHigh = (1<<2),
145 //    kHVChannelOFF = (1<<3),
146 //    kHVSwitchOFF = (1<<4),
147 //    
148 //    kHVMissing = kMissing // please always use last bit for meaning "missing"
149 //  };
150
151   return s;
152 }
153
154 //_____________________________________________________________________________
155 Int_t
156 AliMUONPadStatusMaker::BuildStatus(Int_t pedStatus, 
157                                    Int_t hvStatus, 
158                                    Int_t gainStatus)
159 {
160   /// Build a complete status from specific parts (ped,hv,gain)
161   
162   return ( hvStatus & 0xFF ) | ( ( pedStatus & 0xFF ) << 8 ) | 
163   ( ( gainStatus & 0xFF ) << 16 );
164 }
165
166 //_____________________________________________________________________________
167 void
168 AliMUONPadStatusMaker::DecodeStatus(Int_t status, 
169                                     Int_t& pedStatus, 
170                                     Int_t& hvStatus, 
171                                     Int_t& gainStatus)
172 {
173   /// Decode complete status into specific parts (ped,hv,gain)
174   
175   gainStatus = ( status & 0xFF0000 ) >> 16;
176   pedStatus = ( status & 0xFF00 ) >> 8;
177   hvStatus = (status & 0xFF);
178 }
179
180 //_____________________________________________________________________________
181 Bool_t 
182 AliMUONPadStatusMaker::HVSt12Status(Int_t detElemId, Int_t sector,
183                                     Bool_t& hvChannelTooLow,
184                                     Bool_t& hvChannelTooHigh,
185                                     Bool_t& hvChannelON) const
186 {
187   /// Get HV status for one HV sector of St12
188   
189   /// For a given PCB in a given DE, get the HV status (both the channel
190   /// and the switch).
191   /// Returns false if hv switch changed during the run.
192   
193   AliCodeTimerAuto("")
194   
195   Bool_t error = kFALSE;
196   hvChannelTooLow = kFALSE;
197   hvChannelTooHigh = kFALSE;
198   hvChannelON = kTRUE;
199
200   AliMpHVNamer hvNamer;
201   
202   TString hvChannel(hvNamer.DCSHVChannelName(detElemId,sector));
203   
204   TMap* hvMap = fCalibrationData.HV();
205   TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(hvChannel.Data()));
206   if (!hvPair)
207   {
208     AliError(Form("Did not find expected alias (%s) for DE %d",
209                   hvChannel.Data(),detElemId));  
210     error = kTRUE;
211   }
212   else
213   {
214     TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
215     if (!values)
216     {
217       AliError(Form("Could not get values for alias %s",hvChannel.Data()));
218       error = kTRUE;
219     }
220     else
221     {
222       // find out min and max value, and makes a cut
223       Float_t hvMin(1E9);
224       Float_t hvMax(0);
225       TIter next(values);
226       AliDCSValue* val;
227       
228       while ( ( val = static_cast<AliDCSValue*>(next()) ) )
229       {
230         Float_t hv = val->GetFloat();
231         hvMin = TMath::Min(hv,hvMin);
232         hvMax = TMath::Max(hv,hvMax);
233       }
234       
235       float lowThreshold = fHVSt12Limits.X();
236       float highThreshold = fHVSt12Limits.Y();
237             
238       if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
239       if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
240       if ( hvMin < 1 ) hvChannelON = kFALSE;
241     }
242   }
243   
244   return error;
245 }
246
247 //_____________________________________________________________________________
248 Bool_t 
249 AliMUONPadStatusMaker::HVSt345Status(Int_t detElemId, Int_t pcbIndex,
250                                      Bool_t& hvChannelTooLow,
251                                      Bool_t& hvChannelTooHigh,
252                                      Bool_t& hvChannelON,
253                                      Bool_t& hvSwitchON) const
254 {
255   /// For a given PCB in a given DE, get the HV status (both the channel
256   /// and the switch).
257   /// Returns false if something goes wrong (in particular if 
258   /// hv switch changed during the run).
259   
260   AliCodeTimerAuto("")
261   
262   Bool_t error = kFALSE;
263   hvChannelTooLow = kFALSE;
264   hvChannelTooHigh = kFALSE;
265   hvSwitchON = kTRUE;
266   hvChannelON = kTRUE;
267   
268   AliMpHVNamer hvNamer;
269   
270   TString hvChannel(hvNamer.DCSHVChannelName(detElemId));
271   
272   TMap* hvMap = fCalibrationData.HV();
273   
274   TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(hvChannel.Data()));
275   if (!hvPair)
276   {
277     AliError(Form("Did not find expected alias (%s) for DE %d",
278                   hvChannel.Data(),detElemId));  
279     error = kTRUE;
280   }
281   else
282   {
283     TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
284     if (!values)
285     {
286       AliError(Form("Could not get values for alias %s",hvChannel.Data()));
287       error = kTRUE;
288     }
289     else
290     {
291       // find out min and max value, and makes a cut
292       Float_t hvMin(1E9);
293       Float_t hvMax(0);
294       TIter next(values);
295       AliDCSValue* val;
296       
297       while ( ( val = static_cast<AliDCSValue*>(next()) ) )
298       {
299         Float_t hv = val->GetFloat();
300         hvMin = TMath::Min(hv,hvMin);
301         hvMax = TMath::Max(hv,hvMax);
302       }
303
304       float lowThreshold = fHVSt345Limits.X();
305       float highThreshold = fHVSt345Limits.Y();
306
307       if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
308       else if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
309       if ( hvMin < 1 ) hvChannelON = kFALSE;
310     }
311   }
312   
313   TString hvSwitch(hvNamer.DCSHVSwitchName(detElemId,pcbIndex));
314   TPair* switchPair = static_cast<TPair*>(hvMap->FindObject(hvSwitch.Data()));
315   if (!switchPair)
316   {
317     AliError(Form("Did not find expected alias (%s) for DE %d PCB %d",
318                   hvSwitch.Data(),detElemId,pcbIndex));
319     error = kTRUE;
320   }
321   else
322   {
323     TObjArray* values = static_cast<TObjArray*>(switchPair->Value());
324     if (!values)
325     {    
326       AliError(Form("Could not get values for alias %s",hvSwitch.Data()));
327       error = kTRUE;
328     }
329     else
330     {
331       // we'll count the number of ON/OFF for this pad, to insure
332       // consistency (i.e. if status changed during the run, we should
333       // at least notify this fact ;-) and hope it's not the norm)
334       Int_t nTrue(0);
335       Int_t nFalse(0);
336       TIter next(values);
337       AliDCSValue* val;
338       
339       while ( ( val = static_cast<AliDCSValue*>(next()) ) )
340       {
341         if ( val->GetBool() )
342         {
343           ++nTrue;
344         }
345         else
346         {
347           ++nFalse;
348         }
349       }
350       
351       if ( (nTrue>0 && nFalse>0) )
352       {
353         AliWarning(Form("Status of HV Switch %s changed during this run nTrue=%d nFalse=%d! Will consider it OFF",
354                         hvSwitch.Data(),nTrue,nFalse));
355         error = kTRUE;
356       }
357       
358       if ( nFalse ) hvSwitchON = kFALSE;
359     }
360   }
361   return error;
362 }
363
364 //_____________________________________________________________________________
365 Int_t
366 AliMUONPadStatusMaker::HVStatus(Int_t detElemId, Int_t manuId) const
367 {
368   /// Get HV status of one manu
369   
370   AliCodeTimerAuto("")
371   
372   if ( !fCalibrationData.HV() ) return kMissing;
373
374   Long_t lint = fHV->GetValue(AliMpManuUID::BuildUniqueID(detElemId,manuId));
375   
376   if ( lint ) 
377   {
378     return (Int_t)(lint - 1);
379   }
380
381   Int_t status(0);
382   
383   AliMpHVNamer hvNamer;
384   
385   switch ( AliMpDEManager::GetStationType(detElemId) )
386   {
387     case AliMp::kStation1:
388     case AliMp::kStation2:
389     {
390       int sector = hvNamer.ManuId2Sector(detElemId,manuId);
391       if ( sector >= 0 ) 
392       {
393         Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON;
394         Bool_t error = HVSt12Status(detElemId,sector,
395                                     hvChannelTooLow,
396                                     hvChannelTooHigh,
397                                     hvChannelON);
398         if ( error ) status |= kHVError;
399         if ( hvChannelTooLow ) status |= kHVTooLow;
400         if ( hvChannelTooHigh ) status |= kHVTooHigh; 
401         if ( !hvChannelON ) status |= kHVChannelOFF;
402         // assign this status to all the other manus handled by the same HV channel
403         SetHVStatus(detElemId,sector,status);
404       }
405     }
406       break;
407     case AliMp::kStation345:
408     {
409       int pcbIndex = hvNamer.ManuId2PCBIndex(detElemId,manuId);
410       if ( pcbIndex >= 0 ) 
411       {
412         Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON;
413         Bool_t error = HVSt345Status(detElemId,pcbIndex,
414                                      hvChannelTooLow,hvChannelTooHigh,
415                                      hvChannelON,hvSwitchON);
416         if ( error ) status |= kHVError;
417         if ( hvChannelTooLow ) status |= kHVTooLow;
418         if ( hvChannelTooHigh ) status |= kHVTooHigh; 
419         if ( !hvSwitchON ) status |= kHVSwitchOFF; 
420         if ( !hvChannelON) status |= kHVChannelOFF;
421         // assign this status to all the other manus handled by the same HV channel
422         SetHVStatus(detElemId,pcbIndex,status);
423       }
424     }
425       break;
426     default:
427       break;
428   }
429   
430   return status;
431 }
432
433 //_____________________________________________________________________________
434 AliMUONVCalibParam* 
435 AliMUONPadStatusMaker::Neighbours(Int_t detElemId, Int_t manuId) const
436 {
437   /// Get the neighbours parameters for a given manu
438   AliMUONVStore* neighbourStore = fCalibrationData.Neighbours();
439   return static_cast<AliMUONVCalibParam*>(neighbourStore->FindObject(detElemId,manuId));
440 }
441
442 //_____________________________________________________________________________
443 AliMUONVStore* 
444 AliMUONPadStatusMaker::NeighboursStore() const
445 {
446   /// Return the store containing all the neighbours
447   return fCalibrationData.Neighbours();
448 }
449
450 //_____________________________________________________________________________
451 AliMUONVCalibParam*
452 AliMUONPadStatusMaker::ComputeStatus(Int_t detElemId, Int_t manuId) const
453 {
454   /// Compute the status of a given manu, using all available information,
455   /// i.e. pedestals, gains, and HV
456   
457 //  AliCodeTimerAuto("")
458   
459 //  AliCodeTimerStart("Param creation");
460   AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,-1);
461   fStatus->Add(param);
462 //  AliCodeTimerStop("Param creation");
463   
464 //  AliCodeTimerStart("FindObject");
465   AliMUONVCalibParam* pedestals = static_cast<AliMUONVCalibParam*>(fPedestals->FindObject(detElemId,manuId));
466
467   AliMUONVCalibParam* gains = static_cast<AliMUONVCalibParam*>(fGains->FindObject(detElemId,manuId));
468 //  AliCodeTimerStop("FindObject");
469   
470   Int_t hvStatus = HVStatus(detElemId,manuId);
471
472 //  AliCodeTimerStart("Loop");
473   
474   for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel )
475   {
476     Int_t pedStatus(0);
477     
478     if (pedestals) 
479     {
480       Float_t pedMean = pedestals->ValueAsFloatFast(manuChannel,0);
481       Float_t pedSigma = pedestals->ValueAsFloatFast(manuChannel,1);
482       if ( pedMean < fPedMeanLimits.X() ) pedStatus |= kPedMeanTooLow;
483       else if ( pedMean > fPedMeanLimits.Y() ) pedStatus |= kPedMeanTooHigh;
484       if ( pedSigma < fPedSigmaLimits.X() ) pedStatus |= kPedSigmaTooLow;
485       else if ( pedSigma > fPedSigmaLimits.Y() ) pedStatus |= kPedSigmaTooHigh;
486       if ( pedMean == 0 ) pedStatus |= kPedMeanZero;
487     }
488     else
489     {
490       pedStatus = kPedMissing;
491     }
492     
493     Int_t gainStatus(0);
494   
495     if ( gains ) 
496     {
497       Float_t a0 = gains->ValueAsFloatFast(manuChannel,0);
498       Float_t a1 = gains->ValueAsFloatFast(manuChannel,1);
499       Float_t thres = gains->ValueAsFloatFast(manuChannel,2);
500   
501       if ( a0 < fGainA0Limits.X() ) gainStatus |= kGainA0TooLow;
502       else if ( a0 > fGainA0Limits.Y() ) gainStatus |= kGainA0TooHigh;
503       if ( a1 < fGainA1Limits.X() ) gainStatus |= kGainA1TooLow;
504       else if ( a1 > fGainA1Limits.Y() ) gainStatus |= kGainA1TooHigh;
505       if ( thres < fGainThresLimits.X() ) gainStatus |= kGainThresTooLow;
506       else if ( thres > fGainThresLimits.Y() ) gainStatus |= kGainThresTooHigh;
507     }
508     else
509     {
510       gainStatus = kGainMissing;
511     }
512         
513     Int_t status = BuildStatus(pedStatus,hvStatus,gainStatus);
514       
515     param->SetValueAsIntFast(manuChannel,0,status);
516   }
517   
518 //  AliCodeTimerStop("Loop");
519   
520   return param;
521 }
522
523 //_____________________________________________________________________________
524 AliMUONVCalibParam* 
525 AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId) const
526 {
527   /// Get the status for a given channel
528   
529   AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->FindObject(detElemId,manuId));
530   if (!param)
531   {
532     // not already there, so compute it now
533     AliCodeTimerAuto("ComputeStatus");
534     param = ComputeStatus(detElemId,manuId);
535   }
536   return param;
537 }
538
539 //_____________________________________________________________________________
540 Int_t 
541 AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId, Int_t manuChannel) const
542 {
543   /// Get the status for a given channel
544   
545   AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->FindObject(detElemId,manuId));
546   if (!param)
547   {
548     // not already there, so compute it now
549     param = ComputeStatus(detElemId,manuId);
550   }
551   return param->ValueAsInt(manuChannel,0);
552 }
553
554 //_____________________________________________________________________________
555 void
556 AliMUONPadStatusMaker::SetHVStatus(Int_t detElemId, Int_t index, Int_t status) const
557 {
558   /// Assign status to all manus in a given HV "zone" (defined by index, meaning
559   /// is different thing from St12 and St345)
560   
561   AliCodeTimerAuto("")
562   
563   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
564   
565   const AliMpArrayI* manus = de->ManusForHV(index);
566   
567   for ( Int_t i = 0; i < manus->GetSize(); ++ i ) 
568   {
569     Int_t manuId = manus->GetValue(i);
570     fHV->Add(AliMpManuUID::BuildUniqueID(detElemId,manuId),status + 1);
571   }
572 }