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