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