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 ///////////////////////////////////////////////////////////////////////////////
19 // Calibration class for DCS sensors //
20 // Authors: Marian Ivanov and Haavard Helstrup //
22 ///////////////////////////////////////////////////////////////////////////////
24 #include "AliDCSSensorArray.h"
28 ClassImp(AliDCSSensorArray)
30 const Double_t kSecInHour = 3600.; // seconds in one hour
31 const UInt_t kMinMapTime = 60; // don't fit maps shorter than one minute
33 //_____________________________________________________________________________
34 AliDCSSensorArray::AliDCSSensorArray():TNamed(),
42 fStartTime (2000,1,1,0,0,0),
43 fEndTime (2000,1,1,0,0,0),
47 // AliDCSSensorArray default constructor
51 //_____________________________________________________________________________
52 AliDCSSensorArray::AliDCSSensorArray(TClonesArray *arr):TNamed(),
60 fStartTime (2000,1,1,0,0,0),
61 fEndTime (2000,1,1,0,0,0),
65 // AliDCSSensorArray special constructor taking TClonesArray from ReadList
69 //_____________________________________________________________________________
70 AliDCSSensorArray::AliDCSSensorArray(Int_t run, const char* dbEntry) :
79 fStartTime (2000,1,1,0,0,0),
80 fEndTime (2000,1,1,0,0,0),
84 // Read configuration from OCDB
87 AliCDBEntry *entry = AliCDBManager::Instance()->Get(dbEntry,run);
89 TTree *tree = (TTree*) entry->GetObject();
90 fSensors = AliDCSSensor::ReadTree(tree);
92 AliError("Unable to load configuration from CDB!");
95 //_____________________________________________________________________________
96 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
106 fStartTime (2000,1,1,0,0,0),
107 fEndTime (2000,1,1,0,0,0),
112 // AliDCSSensorArray constructor for Shuttle preprocessor
113 // (confTree read from OCDB)
115 fSensors = AliDCSSensor::ReadTree(confTree);
116 fSensors->BypassStreamer(kFALSE);
117 fStartTime = TTimeStamp((time_t)startTime,0);
118 fEndTime = TTimeStamp((time_t)endTime,0);
122 //_____________________________________________________________________________
123 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
124 TClonesArray *sensors) :
133 fStartTime (2000,1,1,0,0,0),
134 fEndTime (2000,1,1,0,0,0),
139 // AliDCSSensorArray constructor for Shuttle preprocessor
140 // (TClonesArray of AliDCSSensor objects)
142 fStartTime = TTimeStamp((time_t)startTime,0);
143 fEndTime = TTimeStamp((time_t)endTime,0);
146 //_____________________________________________________________________________
147 AliDCSSensorArray::AliDCSSensorArray(const AliDCSSensorArray &c):TNamed(c),
148 fMinGraph(c.fMinGraph),
149 fMinPoints(c.fMinPoints),
151 fMaxDelta(c.fMaxDelta),
154 fDiffCut(c.fDiffCut),
155 fStartTime (c.fStartTime),
156 fEndTime (c.fEndTime),
161 // AliDCSSensorArray copy constructor
164 fSensors = (TClonesArray*)c.fSensors->Clone();
167 ///_____________________________________________________________________________
168 AliDCSSensorArray::~AliDCSSensorArray()
171 // AliDCSSensorArray destructor
178 //_____________________________________________________________________________
179 AliDCSSensorArray &AliDCSSensorArray::operator=(const AliDCSSensorArray &c)
182 // Assignment operator
186 new (this) AliDCSSensorArray(c);
187 fSensors = (TClonesArray*)c.fSensors->Clone();
192 void AliDCSSensorArray::Print(const Option_t* option) const{
194 // print function overwriten
196 TString opt = option; opt.ToLower();
197 printf("%s:%s\n",GetTitle(), GetName());
198 if (!fSensors) return;
199 Int_t nsensors=fSensors->GetEntries();
200 for (Int_t i=0; i<nsensors; i++){
201 printf("Sensor Nr%d\n",i);
202 if (fSensors->At(i)) fSensors->At(i)->Print(option);
206 //____________________________________________________________________________
208 void AliDCSSensorArray::SetGraph(TMap *map)
211 // Read graphs from DCS maps
213 Int_t nsensors = fSensors->GetEntries();
214 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
215 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
216 TString stringID = entry->GetStringID();
217 TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
219 entry->SetGraph((TGraph*)gr->Clone());
225 //_____________________________________________________________________________
226 void AliDCSSensorArray::MakeSplineFit(TMap *map, Bool_t keepMap)
229 // Make spline fits from DCS maps
231 Int_t nsensors = fSensors->GetEntries();
232 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
233 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
234 TString stringID = entry->GetStringID();
235 TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
239 AliWarning(Form("sensor %s: no input graph",stringID.Data()));
242 UInt_t timeDiff = entry->GetEndTime() - entry->GetStartTime();
243 if ( timeDiff < kMinMapTime ) {
244 AliWarning(Form("sensor %s: map length < 60 s, DCS graph kept.",stringID.Data()));
245 entry->SetGraph((TGraph*)gr->Clone());
247 AliSplineFit *fit = new AliSplineFit();
248 fit->SetMinPoints(fMinGraph);
249 fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
250 fit->SplineFit(fFitReq);
252 if (fit->GetKnots()>0) {
255 AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
256 entry->SetGraph((TGraph*)gr->Clone());
259 if (keepMap) entry->SetGraph((TGraph*)gr->Clone());
262 //_____________________________________________________________________________
263 void AliDCSSensorArray::MakeSplineFitAddPoints(TMap *map)
266 // Make spline fits from DCS maps
268 Int_t nsensors = fSensors->GetEntries();
269 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
270 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
272 // fetch old points from existing graph
274 TGraph *gr = entry->GetGraph();
279 TString stringID = entry->GetStringID();
281 // fetch new points from DCS map
283 TGraph *grAdd = (TGraph*)map->GetValue(stringID.Data());
286 // add new points to end of graph
288 Int_t nPointsOld=gr->GetN();
289 Int_t nPointsAdd=grAdd->GetN();
290 gr->Expand(nPointsOld+nPointsAdd);
291 gr->Set(nPointsOld+nPointsAdd);
292 Double_t *addX=grAdd->GetX();
293 Double_t *addY=grAdd->GetY();
294 for (Int_t i=0;i<nPointsAdd;i++) {
295 gr->SetPoint(nPointsOld+i,addX[i],addY[i]);
298 // make fit to complete graph
300 AliSplineFit *fit = new AliSplineFit();
301 fit->SetMinPoints(fMinGraph);
302 fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
303 fit->SplineFit(fFitReq);
305 if (fit->GetKnots()>0) {
306 AliSplineFit *oldFit = entry->GetFit();
307 if (oldFit) delete oldFit;
310 AliWarning(Form("sensor %s: no new fit performed. If available, old fit kept.",stringID.Data()));
315 //_____________________________________________________________________________
316 Int_t AliDCSSensorArray::NumFits() const
319 // Return number of sensors where a succesful fit has been made
322 Int_t nsensors = fSensors->GetEntries();
323 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
324 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
325 if (entry->GetFit()) nfit++;
329 //_____________________________________________________________________________
330 Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor)
333 // Return sensor value at time timeSec (obtained from fitted function)
334 // timeSec = time in seconds from start of run
337 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(sensor);
338 return entry->GetValue(TTimeStamp((time_t)fStartTime.GetSec()+timeSec,0));
342 //_____________________________________________________________________________
343 TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap, Bool_t keepStart)
346 // Extract temperature graphs from DCS maps
348 TMap *values = new TMap;
349 TObjArray * valueSet;
351 // Keep global start/end times
352 // to avoid extrapolations, the fits will only be valid from first
353 // measured point to last measured point. This is consistent with hardware,
354 // as there would be a new measured point if the value changed.
356 TTimeStamp startTime=fStartTime;
357 TTimeStamp endTime=fEndTime;
359 Int_t nsensors = fSensors->GetEntries();
360 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
361 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
362 TString stringID = entry->GetStringID();
363 TPair *pair = (TPair*)dcsMap->FindObject(stringID.Data());
364 if ( pair ) { // only try to read values
365 // if DCS object available
366 valueSet = (TObjArray*)pair->Value();
367 TGraph *graph = MakeGraph(valueSet,keepStart); // MakeGraph sets start/end time
369 values->Add(new TObjString(stringID.Data()),graph);
370 entry->SetStartTime(fStartTime);
371 entry->SetEndTime(fEndTime);
374 // Reset global start/end time
375 // ..... yes, I know this won't get a prize for structured programming..:-)
377 fStartTime=startTime;
383 //_____________________________________________________________________________
384 TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet, Bool_t keepStart){
386 // Make graph of temperature values read from DCS map
387 // (spline fit parameters will subsequently be obtained from this graph)
389 Int_t nentries = valueSet->GetEntriesFast();
390 if ( nentries == 0 ) return 0;
392 Float_t *x = new Float_t[nentries];
393 Float_t *y = new Float_t[nentries];
394 Int_t time0=0, previousTime=0;
395 TTimeStamp firstTime(0);
396 TTimeStamp lastTime(0);
398 firstTime = fStartTime;
399 time0 = firstTime.GetSec();
403 AliDCSValue *val = (AliDCSValue *)valueSet->At(0);
404 AliDCSValue::Type type = val->GetType();
405 if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) {
411 for (Int_t i=0; i<nentries; i++){
412 val = (AliDCSValue *)valueSet->At(i);
415 time0=val->GetTimeStamp();
416 firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
417 lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
421 case AliDCSValue::kFloat:
422 value = val->GetFloat();
424 case AliDCSValue::kChar:
425 value = static_cast<Float_t>(val->GetChar());
427 case AliDCSValue::kInt:
428 value = static_cast<Float_t>(val->GetInt());
430 case AliDCSValue::kUInt:
431 value = static_cast<Float_t>(val->GetUInt());
436 if (fValCut>0 && TMath::Abs(value)>fValCut) continue; // refuse values greater than cut
438 if ( out>0 && skipped<10 && TMath::Abs(value-y[out-1])>fDiffCut) {
439 skipped++; // refuse values changing
440 continue; // by > cut in one time step
444 if (val->GetTimeStamp()-time0>1000000) continue;
445 if (val->GetTimeStamp()-previousTime < 1 ) continue; // refuse duplicate recordings
446 previousTime=val->GetTimeStamp();
447 lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
448 x[out] = (val->GetTimeStamp()-time0)/kSecInHour; // give times in fractions of hours
452 if (!keepStart) fStartTime=firstTime;
454 TGraph * graph = new TGraph(out,x,y);
460 //_____________________________________________________________________________
461 void AliDCSSensorArray::RemoveGraphDuplicates(Double_t tolerance){
463 // Remove points with same y value as the previous measured point
464 // (to save space for non-fitted graphs -- i.e. last measured point used)
466 Int_t nsensors = fSensors->GetEntries();
467 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
468 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
469 TGraph *graph = entry->GetGraph();
470 Double_t x=-999.,y=-999., x0=-999.,y0=-999.;
472 Int_t npoints=graph->GetN();
474 for (Int_t i=npoints-1;i>0;i--) {
475 graph->GetPoint(i,x,y);
476 graph->GetPoint(i-1,x0,y0);
477 if ( TMath::Abs(y-y0) < TMath::Abs(tolerance*y0) ) graph->RemovePoint(i);
485 //_____________________________________________________________________________
486 AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS)
489 // Return sensor information for sensor specified by IdDCS
491 Int_t nsensors = fSensors->GetEntries();
492 for (Int_t isensor=0; isensor<nsensors; isensor++) {
493 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
494 if (entry->GetIdDCS() == IdDCS) return entry;
498 //_____________________________________________________________________________
499 AliDCSSensor* AliDCSSensorArray::GetSensor(const TString& stringID)
502 // Return sensor information for sensor specified by stringID
504 Int_t nsensors = fSensors->GetEntries();
505 for (Int_t isensor=0; isensor<nsensors; isensor++) {
506 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
507 if (entry->GetStringID() == stringID) return entry;
511 //_____________________________________________________________________________
512 AliDCSSensor* AliDCSSensorArray::GetSensor(Double_t x, Double_t y, Double_t z)
515 // Return sensor closest to given position
517 Int_t nsensors = fSensors->GetEntries();
518 Double_t dist2min=1e99;
519 Double_t xs,ys,zs,dist2;
521 for (Int_t isensor=0; isensor<nsensors; isensor++) {
522 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
526 dist2 = (x-xs)*(x-xs) + (y-ys)*(y-ys) + (z-zs)*(z-zs);
527 if (dist2 < dist2min) {
533 return (AliDCSSensor*)fSensors->At(ind);
538 //_____________________________________________________________________________
539 AliDCSSensor* AliDCSSensorArray::GetSensorNum(Int_t ind)
542 // Return sensor given by array index
544 return (AliDCSSensor*)fSensors->At(ind);
547 //_____________________________________________________________________________
548 Int_t AliDCSSensorArray::SetSensor(const TString& stringID,
549 const AliDCSSensor& sensor)
552 // Update sensor information for sensor specified by stringID
554 Int_t nsensors = fSensors->GetEntries();
555 for (Int_t isensor=0; isensor<nsensors; isensor++) {
556 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
557 if (entry->GetStringID() == stringID)
559 new ((*fSensors)[isensor])AliDCSSensor(sensor);
565 //_____________________________________________________________________________
566 void AliDCSSensorArray::SetSensorNum(const Int_t ind, const AliDCSSensor& sensor)
569 // Update sensor information for sensor at index ind
571 new ((*fSensors)[ind])AliDCSSensor(sensor);
574 //_____________________________________________________________________________
575 void AliDCSSensorArray::RemoveSensorNum(Int_t ind)
578 // Return sensor given by array index
581 delete fSensors->RemoveAt(ind);
582 fSensors->Compress();
584 //_____________________________________________________________________________
585 void AliDCSSensorArray::RemoveSensor(Int_t IdDCS)
588 // Deletes Sensor by given IdDCS
591 Int_t nsensors = fSensors->GetEntries();
592 for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
593 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
594 if (entry->GetIdDCS()==IdDCS) {
595 delete fSensors->RemoveAt(isensor);
599 fSensors->Compress();
601 //_____________________________________________________________________________
602 TArrayI AliDCSSensorArray::OutsideThreshold(Double_t threshold, UInt_t timeSec, Bool_t below) const
605 // Return sensors with values outside threshold at time defined by second
607 // By default sensors with values below threshold are listed, if third
608 // parameter is set to kFALSE sensors with values above threshold are listed
610 Int_t nsensors = fSensors->GetEntries();
611 TArrayI array(nsensors);
613 for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
614 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
615 Double_t val=entry->GetValue(timeSec);
617 if (val<threshold) array[outside++] = entry->GetIdDCS();
619 if (val>threshold) array[outside++] = entry->GetIdDCS();
626 //_____________________________________________________________________________
627 Int_t AliDCSSensorArray::GetFirstIdDCS() const
630 // Return DCS Id of first sensor
632 if ( fSensors != 0 ) {
633 return ((AliDCSSensor*)fSensors->At(0))->GetIdDCS();
639 //_____________________________________________________________________________
640 Int_t AliDCSSensorArray::GetLastIdDCS() const
643 // Return DCS Id of last sensor
645 if ( fSensors != 0 ) {
646 Int_t last = fSensors->GetEntries();
647 return ((AliDCSSensor*)fSensors->At(last-1))->GetIdDCS();
652 //_____________________________________________________________________________
653 void AliDCSSensorArray::ClearGraph()
656 // Delete DCS graphs from all sensors in array
659 Int_t nsensors = fSensors->GetEntries();
660 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
661 AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
662 TGraph *gr = sensor->GetGraph();
670 //_____________________________________________________________________________
671 void AliDCSSensorArray::ClearFit()
674 // Delete spline fits from all sensors in array
677 Int_t nsensors = fSensors->GetEntries();
678 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
679 AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
680 AliSplineFit *fit = sensor->GetFit();
688 //_____________________________________________________________________________
689 void AliDCSSensorArray::AddSensors(AliDCSSensorArray *newSensors)
692 // add sensors from two sensor arrays
695 Int_t numNew = newSensors->NumSensors();
696 Int_t numOld = fSensors->GetEntries();
697 fSensors->Expand(numOld+numNew);
698 for (Int_t i=0;i<numNew;i++) {
699 AliDCSSensor *sens = newSensors->GetSensorNum(i);
700 new ((*fSensors)[numOld+i]) AliDCSSensor(*sens);