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"
27 ClassImp(AliDCSSensorArray)
29 const Double_t kSecInHour = 3600.; // seconds in one hour
30 const UInt_t kMinMapTime = 60; // don't fit maps shorter than one minute
32 //_____________________________________________________________________________
33 AliDCSSensorArray::AliDCSSensorArray():TNamed(),
41 fStartTime (2000,1,1,0,0,0),
42 fEndTime (2000,1,1,0,0,0),
46 // AliDCSSensorArray default constructor
50 //_____________________________________________________________________________
51 AliDCSSensorArray::AliDCSSensorArray(TClonesArray *arr):TNamed(),
59 fStartTime (2000,1,1,0,0,0),
60 fEndTime (2000,1,1,0,0,0),
64 // AliDCSSensorArray special constructor taking TClonesArray from ReadList
68 //_____________________________________________________________________________
69 AliDCSSensorArray::AliDCSSensorArray(Int_t run, const char* dbEntry) :
78 fStartTime (2000,1,1,0,0,0),
79 fEndTime (2000,1,1,0,0,0),
83 // Read configuration from OCDB
86 AliCDBEntry *entry = AliCDBManager::Instance()->Get(dbEntry,run);
87 TTree *tree = (TTree*) entry->GetObject();
88 fSensors = AliDCSSensor::ReadTree(tree);
90 //_____________________________________________________________________________
91 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
101 fStartTime (2000,1,1,0,0,0),
102 fEndTime (2000,1,1,0,0,0),
107 // AliDCSSensorArray constructor for Shuttle preprocessor
108 // (confTree read from OCDB)
110 fSensors = AliDCSSensor::ReadTree(confTree);
111 fSensors->BypassStreamer(kFALSE);
112 fStartTime = TTimeStamp((time_t)startTime,0);
113 fEndTime = TTimeStamp((time_t)endTime,0);
117 //_____________________________________________________________________________
118 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
119 TClonesArray *sensors) :
128 fStartTime (2000,1,1,0,0,0),
129 fEndTime (2000,1,1,0,0,0),
134 // AliDCSSensorArray constructor for Shuttle preprocessor
135 // (TClonesArray of AliDCSSensor objects)
137 fStartTime = TTimeStamp((time_t)startTime,0);
138 fEndTime = TTimeStamp((time_t)endTime,0);
141 //_____________________________________________________________________________
142 AliDCSSensorArray::AliDCSSensorArray(const AliDCSSensorArray &c):TNamed(c),
143 fMinGraph(c.fMinGraph),
144 fMinPoints(c.fMinPoints),
146 fMaxDelta(c.fMaxDelta),
149 fDiffCut(c.fDiffCut),
150 fStartTime (c.fStartTime),
151 fEndTime (c.fEndTime),
156 // AliDCSSensorArray copy constructor
159 fSensors = (TClonesArray*)c.fSensors->Clone();
162 ///_____________________________________________________________________________
163 AliDCSSensorArray::~AliDCSSensorArray()
166 // AliDCSSensorArray destructor
173 //_____________________________________________________________________________
174 AliDCSSensorArray &AliDCSSensorArray::operator=(const AliDCSSensorArray &c)
177 // Assignment operator
181 new (this) AliDCSSensorArray(c);
182 fSensors = (TClonesArray*)c.fSensors->Clone();
187 //____________________________________________________________________________
189 void AliDCSSensorArray::SetGraph(TMap *map)
192 // Read graphs from DCS maps
194 Int_t nsensors = fSensors->GetEntries();
195 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
196 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
197 TString stringID = entry->GetStringID();
198 TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
200 entry->SetGraph((TGraph*)gr->Clone());
206 //_____________________________________________________________________________
207 void AliDCSSensorArray::MakeSplineFit(TMap *map, Bool_t keepMap)
210 // Make spline fits from DCS maps
212 Int_t nsensors = fSensors->GetEntries();
213 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
214 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
215 TString stringID = entry->GetStringID();
216 TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
220 AliWarning(Form("sensor %s: no input graph",stringID.Data()));
223 UInt_t timeDiff = entry->GetEndTime() - entry->GetStartTime();
224 if ( timeDiff < kMinMapTime ) {
225 AliWarning(Form("sensor %s: map length < 60 s, DCS graph kept.",stringID.Data()));
226 entry->SetGraph((TGraph*)gr->Clone());
228 AliSplineFit *fit = new AliSplineFit();
229 fit->SetMinPoints(fMinGraph);
230 fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
231 fit->SplineFit(fFitReq);
236 AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
237 entry->SetGraph((TGraph*)gr->Clone());
240 if (keepMap) entry->SetGraph((TGraph*)gr->Clone());
243 //_____________________________________________________________________________
244 void AliDCSSensorArray::MakeSplineFitAddPoints(TMap *map)
247 // Make spline fits from DCS maps
249 Int_t nsensors = fSensors->GetEntries();
250 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
251 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
253 // fetch old points from existing graph
255 TGraph *gr = entry->GetGraph();
260 TString stringID = entry->GetStringID();
262 // fetch new points from DCS map
264 TGraph *grAdd = (TGraph*)map->GetValue(stringID.Data());
267 // add new points to end of graph
269 Int_t nPointsOld=gr->GetN();
270 Int_t nPointsAdd=grAdd->GetN();
271 gr->Expand(nPointsOld+nPointsAdd);
272 gr->Set(nPointsOld+nPointsAdd);
273 Double_t *addX=grAdd->GetX();
274 Double_t *addY=grAdd->GetY();
275 for (Int_t i=0;i<nPointsAdd;i++) {
276 gr->SetPoint(nPointsOld+i,addX[i],addY[i]);
279 // make fit to complete graph
281 AliSplineFit *fit = new AliSplineFit();
282 fit->SetMinPoints(fMinGraph);
283 fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
284 fit->SplineFit(fFitReq);
287 AliSplineFit *oldFit = entry->GetFit();
288 if (oldFit) delete oldFit;
291 AliWarning(Form("sensor %s: no new fit performed. If available, old fit kept.",stringID.Data()));
296 //_____________________________________________________________________________
297 Int_t AliDCSSensorArray::NumFits() const
300 // Return number of sensors where a succesful fit has been made
303 Int_t nsensors = fSensors->GetEntries();
304 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
305 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
306 if (entry->GetFit()) nfit++;
310 //_____________________________________________________________________________
311 Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor)
314 // Return sensor value at time timeSec (obtained from fitted function)
315 // timeSec = time in seconds from start of run
318 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(sensor);
319 return entry->GetValue(TTimeStamp((time_t)fStartTime.GetSec()+timeSec,0));
323 //_____________________________________________________________________________
324 TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap, Bool_t keepStart)
327 // Extract temperature graphs from DCS maps
329 TMap *values = new TMap;
330 TObjArray * valueSet;
332 // Keep global start/end times
333 // to avoid extrapolations, the fits will only be valid from first
334 // measured point to last measured point. This is consistent with hardware,
335 // as there would be a new measured point if the value changed.
337 TTimeStamp startTime=fStartTime;
338 TTimeStamp endTime=fEndTime;
340 Int_t nsensors = fSensors->GetEntries();
341 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
342 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
343 TString stringID = entry->GetStringID();
344 TPair *pair = (TPair*)dcsMap->FindObject(stringID.Data());
345 if ( pair ) { // only try to read values
346 // if DCS object available
347 valueSet = (TObjArray*)pair->Value();
348 TGraph *graph = MakeGraph(valueSet,keepStart); // MakeGraph sets start/end time
350 values->Add(new TObjString(stringID.Data()),graph);
351 entry->SetStartTime(fStartTime);
352 entry->SetEndTime(fEndTime);
355 // Reset global start/end time
356 // ..... yes, I know this won't get a prize for structured programming..:-)
358 fStartTime=startTime;
363 //_____________________________________________________________________________
364 TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet, Bool_t keepStart){
366 // Make graph of temperature values read from DCS map
367 // (spline fit parameters will subsequently be obtained from this graph)
369 Int_t nentries = valueSet->GetEntriesFast();
370 if ( nentries == 0 ) return 0;
372 Float_t *x = new Float_t[nentries];
373 Float_t *y = new Float_t[nentries];
374 Int_t time0=0, previousTime=0;
375 TTimeStamp firstTime(0);
376 TTimeStamp lastTime(0);
378 firstTime = fStartTime;
379 time0 = firstTime.GetSec();
383 AliDCSValue *val = (AliDCSValue *)valueSet->At(0);
384 AliDCSValue::Type type = val->GetType();
385 if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) return 0;
387 for (Int_t i=0; i<nentries; i++){
388 val = (AliDCSValue *)valueSet->At(i);
391 time0=val->GetTimeStamp();
392 firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
393 lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
397 case AliDCSValue::kFloat:
398 value = val->GetFloat();
400 case AliDCSValue::kChar:
401 value = static_cast<Float_t>(val->GetChar());
403 case AliDCSValue::kInt:
404 value = static_cast<Float_t>(val->GetInt());
406 case AliDCSValue::kUInt:
407 value = static_cast<Float_t>(val->GetUInt());
412 if (fValCut>0 && TMath::Abs(value)>fValCut) continue; // refuse values greater than cut
414 if ( out>0 && skipped<10 && TMath::Abs(value-y[out-1])>fDiffCut) {
415 skipped++; // refuse values changing
416 continue; // by > cut in one time step
420 if (val->GetTimeStamp()-time0>1000000) continue;
421 if (val->GetTimeStamp()-previousTime < 1 ) continue; // refuse duplicate recordings
422 previousTime=val->GetTimeStamp();
423 lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
424 x[out] = (val->GetTimeStamp()-time0)/kSecInHour; // give times in fractions of hours
425 y[out] = val->GetFloat();
428 if (!keepStart) fStartTime=firstTime;
430 TGraph * graph = new TGraph(out,x,y);
436 //_____________________________________________________________________________
437 AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS)
440 // Return sensor information for sensor specified by IdDCS
442 Int_t nsensors = fSensors->GetEntries();
443 for (Int_t isensor=0; isensor<nsensors; isensor++) {
444 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
445 if (entry->GetIdDCS() == IdDCS) return entry;
449 //_____________________________________________________________________________
450 AliDCSSensor* AliDCSSensorArray::GetSensor(const TString& stringID)
453 // Return sensor information for sensor specified by stringID
455 Int_t nsensors = fSensors->GetEntries();
456 for (Int_t isensor=0; isensor<nsensors; isensor++) {
457 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
458 if (entry->GetStringID() == stringID) return entry;
462 //_____________________________________________________________________________
463 AliDCSSensor* AliDCSSensorArray::GetSensor(Double_t x, Double_t y, Double_t z)
466 // Return sensor closest to given position
468 Int_t nsensors = fSensors->GetEntries();
469 Double_t dist2min=1e99;
470 Double_t xs,ys,zs,dist2;
472 for (Int_t isensor=0; isensor<nsensors; isensor++) {
473 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
477 dist2 = (x-xs)*(x-xs) + (y-ys)*(y-ys) + (z-zs)*(z-zs);
478 if (dist2 < dist2min) {
484 return (AliDCSSensor*)fSensors->At(ind);
489 //_____________________________________________________________________________
490 AliDCSSensor* AliDCSSensorArray::GetSensorNum(Int_t ind)
493 // Return sensor given by array index
495 return (AliDCSSensor*)fSensors->At(ind);
498 //_____________________________________________________________________________
499 Int_t AliDCSSensorArray::SetSensor(const TString& stringID,
500 const AliDCSSensor& sensor)
503 // Update sensor information for sensor specified by stringID
505 Int_t nsensors = fSensors->GetEntries();
506 for (Int_t isensor=0; isensor<nsensors; isensor++) {
507 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
508 if (entry->GetStringID() == stringID)
510 new ((*fSensors)[isensor])AliDCSSensor(sensor);
516 //_____________________________________________________________________________
517 void AliDCSSensorArray::SetSensorNum(const Int_t ind, const AliDCSSensor& sensor)
520 // Update sensor information for sensor at index ind
522 new ((*fSensors)[ind])AliDCSSensor(sensor);
525 //_____________________________________________________________________________
526 void AliDCSSensorArray::RemoveSensorNum(Int_t ind)
529 // Return sensor given by array index
532 delete fSensors->RemoveAt(ind);
533 fSensors->Compress();
535 //_____________________________________________________________________________
536 void AliDCSSensorArray::RemoveSensor(Int_t IdDCS)
539 // Deletes Sensor by given IdDCS
542 Int_t nsensors = fSensors->GetEntries();
543 for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
544 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
545 if (entry->GetIdDCS()==IdDCS) {
546 delete fSensors->RemoveAt(isensor);
550 fSensors->Compress();
552 //_____________________________________________________________________________
553 TArrayI AliDCSSensorArray::OutsideThreshold(Double_t threshold, UInt_t timeSec, Bool_t below) const
556 // Return sensors with values outside threshold at time defined by second
558 // By default sensors with values below threshold are listed, if third
559 // parameter is set to kFALSE sensors with values above threshold are listed
561 Int_t nsensors = fSensors->GetEntries();
562 TArrayI array(nsensors);
564 for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
565 AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
566 Double_t val=entry->GetValue(timeSec);
568 if (val<threshold) array[outside++] = entry->GetIdDCS();
570 if (val>threshold) array[outside++] = entry->GetIdDCS();
577 //_____________________________________________________________________________
578 Int_t AliDCSSensorArray::GetFirstIdDCS() const
581 // Return DCS Id of first sensor
583 if ( fSensors != 0 ) {
584 return ((AliDCSSensor*)fSensors->At(0))->GetIdDCS();
590 //_____________________________________________________________________________
591 Int_t AliDCSSensorArray::GetLastIdDCS() const
594 // Return DCS Id of last sensor
596 if ( fSensors != 0 ) {
597 Int_t last = fSensors->GetEntries();
598 return ((AliDCSSensor*)fSensors->At(last-1))->GetIdDCS();
603 //_____________________________________________________________________________
604 void AliDCSSensorArray::ClearGraph()
607 // Delete DCS graphs from all sensors in array
610 Int_t nsensors = fSensors->GetEntries();
611 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
612 AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
613 TGraph *gr = sensor->GetGraph();
621 //_____________________________________________________________________________
622 void AliDCSSensorArray::ClearFit()
625 // Delete spline fits from all sensors in array
628 Int_t nsensors = fSensors->GetEntries();
629 for ( Int_t isensor=0; isensor<nsensors; isensor++) {
630 AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
631 AliSplineFit *fit = sensor->GetFit();
639 //_____________________________________________________________________________
640 void AliDCSSensorArray::AddSensors(AliDCSSensorArray *newSensors)
643 // add sensors from two sensor arrays
646 Int_t numNew = newSensors->NumSensors();
647 Int_t numOld = fSensors->GetEntries();
648 fSensors->Expand(numOld+numNew);
649 for (Int_t i=0;i<numNew;i++) {
650 AliDCSSensor *sens = newSensors->GetSensorNum(i);
651 new ((*fSensors)[numOld+i]) AliDCSSensor(*sens);