]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPadStatusMaker.cxx
Copy constructor implemented.
[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 /// \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
64 ClassImp(AliMUONPadStatusMaker)
65
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)
73 {
74     // ctor
75 }
76
77 //_____________________________________________________________________________
78 AliMUONPadStatusMaker::~AliMUONPadStatusMaker()
79 {
80   // dtor.
81 }
82
83 //_____________________________________________________________________________
84 AliMUONV2DStore*
85 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
156 Bool_t 
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
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 //_____________________________________________________________________________
221 Bool_t 
222 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
335 AliMUONV2DStore* 
336 AliMUONPadStatusMaker::MakeGainStatus(const AliMUONV2DStore& /*gainValues*/) const
337 {
338   /// FIXME: to be implemented
339   AliWarning("Not implemented yet");
340   return 0x0;
341 }
342
343 //_____________________________________________________________________________
344 AliMUONV2DStore* 
345 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
430 AliMUONV2DStore* 
431 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
483 AliMUONV2DStore* 
484 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
520 void
521 AliMUONPadStatusMaker::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 //_____________________________________________________________________________
577 void
578 AliMUONPadStatusMaker::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