]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliDCSSensorArray.cxx
Corrected protection.
[u/mrichter/AliRoot.git] / STEER / AliDCSSensorArray.cxx
index 0bdf76eb9a34a589a5ef825524d503b90f1b2f4b..cf803214803ba395df4daee24e1b465904ac6967 100644 (file)
 
 #include "AliDCSSensorArray.h"
 #include "AliLog.h"
+#include <TMath.h>
 
 ClassImp(AliDCSSensorArray)
 
 const Double_t kSecInHour = 3600.; // seconds in one hour
+const UInt_t   kMinMapTime = 60;   // don't fit maps shorter than one minute
 
 //_____________________________________________________________________________
 AliDCSSensorArray::AliDCSSensorArray():TNamed(), 
@@ -108,8 +110,8 @@ AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
   //
   fSensors = AliDCSSensor::ReadTree(confTree);
   fSensors->BypassStreamer(kFALSE);
-  fStartTime = TTimeStamp((time_t)startTime);
-  fEndTime   = TTimeStamp((time_t)endTime);
+  fStartTime = TTimeStamp((time_t)startTime,0);
+  fEndTime   = TTimeStamp((time_t)endTime,0);
 }
 
 
@@ -133,8 +135,8 @@ AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
   // AliDCSSensorArray constructor for Shuttle preprocessor
   //  (TClonesArray of AliDCSSensor objects)
   //
-  fStartTime = TTimeStamp((time_t)startTime);
-  fEndTime   = TTimeStamp((time_t)endTime);
+  fStartTime = TTimeStamp((time_t)startTime,0);
+  fEndTime   = TTimeStamp((time_t)endTime,0);
 }
 
 //_____________________________________________________________________________
@@ -213,26 +215,82 @@ void AliDCSSensorArray::MakeSplineFit(TMap *map, Bool_t keepMap)
     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
     TString stringID = entry->GetStringID();
     TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
-    if (!gr || gr->GetN() == 0 ) {
+    if (!gr ) {
       entry->SetFit(0);
       entry->SetGraph(0);
       AliWarning(Form("sensor %s: no input graph",stringID.Data()));
       continue;
     }
+    UInt_t timeDiff = entry->GetEndTime() - entry->GetStartTime();
+    if ( timeDiff < kMinMapTime ) {
+      AliWarning(Form("sensor %s: map length < 60 s, DCS graph kept.",stringID.Data()));
+      entry->SetGraph((TGraph*)gr->Clone());
+    } else {
+      AliSplineFit *fit = new AliSplineFit();
+      fit->SetMinPoints(fMinGraph);
+      fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
+      fit->SplineFit(fFitReq);
+      fit->Cleanup();
+      if (fit) {
+        entry->SetFit(fit);
+      } else {
+        AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
+        entry->SetGraph((TGraph*)gr->Clone());
+      }
+    }
+    if (keepMap) entry->SetGraph((TGraph*)gr->Clone());
+  }
+}
+//_____________________________________________________________________________
+void AliDCSSensorArray::MakeSplineFitAddPoints(TMap *map)
+{
+  //
+  // Make spline fits from DCS maps
+  //
+  Int_t nsensors = fSensors->GetEntries();
+  for ( Int_t isensor=0; isensor<nsensors; isensor++) {
+    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
+
+  // fetch old points from existing graph
+
+    TGraph *gr = entry->GetGraph();
+    if (!gr) {
+      gr = new TGraph();
+      entry->SetGraph(gr);
+    } 
+    TString stringID = entry->GetStringID();
+
+  // fetch new points from DCS map
+  
+    TGraph *grAdd = (TGraph*)map->GetValue(stringID.Data());
+    if (!grAdd ) return;
+
+  // add new points to end of graph
+  
+    Int_t nPointsOld=gr->GetN();
+    Int_t nPointsAdd=grAdd->GetN();
+    gr->Expand(nPointsOld+nPointsAdd);
+    gr->Set(nPointsOld+nPointsAdd);
+    Double_t *addX=grAdd->GetX();
+    Double_t *addY=grAdd->GetY();
+    for (Int_t i=0;i<nPointsAdd;i++) {
+      gr->SetPoint(nPointsOld+i,addX[i],addY[i]);
+    }
+   // make fit to complete graph
+   
     AliSplineFit *fit = new AliSplineFit();
     fit->SetMinPoints(fMinGraph);
     fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
     fit->SplineFit(fFitReq);
-    entry->SetStartTime(fStartTime);
-    entry->SetEndTime(fEndTime);
     fit->Cleanup();
     if (fit) {
+      AliSplineFit *oldFit = entry->GetFit();
+      if (oldFit) delete oldFit;
       entry->SetFit(fit);
     } else {
-      AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
-      entry->SetGraph(gr);
+      AliWarning(Form("sensor %s: no new fit performed. If available, old fit kept.",stringID.Data()));
     }
-    if (keepMap) entry->SetGraph(gr);
   }
 }
 
@@ -251,25 +309,35 @@ Int_t AliDCSSensorArray::NumFits() const
   return nfit;
 }
 //_____________________________________________________________________________
-Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor)
+Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor) 
 {
   //
   // Return sensor value at time timeSec (obtained from fitted function)
   //  timeSec = time in seconds from start of run
   //
+
   AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(sensor);
-  return entry->GetValue(timeSec);
+  return entry->GetValue(TTimeStamp((time_t)fStartTime.GetSec()+timeSec,0));
 }
 
 
 //_____________________________________________________________________________
-TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap)
+TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap, Bool_t keepStart)
 {
  //
  // Extract temperature graphs from DCS maps
  //
  TMap *values = new TMap;
  TObjArray * valueSet;
+ //
+ // Keep global start/end times
+ //    to avoid extrapolations, the fits will only be valid from first 
+ //    measured point to last measured point. This is consistent with hardware,
+ //    as there would be a new measured point if the value changed.
+ TTimeStamp startTime=fStartTime;
+ TTimeStamp endTime=fEndTime;
  Int_t nsensors = fSensors->GetEntries();
  for ( Int_t isensor=0; isensor<nsensors; isensor++) {
    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
@@ -278,15 +346,24 @@ TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap)
    if ( pair ) {                            // only try to read values
                                             // if DCS object available
      valueSet = (TObjArray*)pair->Value();
-     TGraph *graph = MakeGraph(valueSet);
+     TGraph *graph = MakeGraph(valueSet,keepStart);   // MakeGraph sets start/end time
+                                            // per sensor
      values->Add(new TObjString(stringID.Data()),graph);
+     entry->SetStartTime(fStartTime);
+     entry->SetEndTime(fEndTime);
    }
  }
+ // Reset global start/end time 
+ //    ..... yes, I know this won't get a prize for structured programming..:-)
+
+ fStartTime=startTime;
+ fEndTime=endTime;
  return values;
 }
 
+
 //_____________________________________________________________________________
-TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet){
+TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet, Bool_t keepStart){
   //
   // Make graph of temperature values read from DCS map
   //   (spline fit parameters will subsequently be obtained from this graph) 
@@ -296,9 +373,13 @@ TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet){
   
   Float_t *x = new Float_t[nentries];
   Float_t *y = new Float_t[nentries];
-  Int_t time0=0;
+  Int_t time0=0, previousTime=0;
   TTimeStamp firstTime(0);
   TTimeStamp lastTime(0);
+  if (keepStart) { 
+     firstTime = fStartTime;
+     time0 = firstTime.GetSec();
+  }
   Int_t out=0;
   Int_t skipped=0;
   AliDCSValue *val = (AliDCSValue *)valueSet->At(0);
@@ -310,9 +391,9 @@ TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet){
     if (!val) continue;
     if (time0==0){
       time0=val->GetTimeStamp();
-      firstTime= val->GetTimeStamp();
-      lastTime=val->GetTimeStamp();
-    }
+      firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
+      lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
+     }
     switch ( type )
     { 
       case AliDCSValue::kFloat:
@@ -339,18 +420,45 @@ TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet){
       skipped=0;
     }                                        
     if (val->GetTimeStamp()-time0>1000000) continue;
-    lastTime=val->GetTimeStamp();
+    if (val->GetTimeStamp()-previousTime < 1 ) continue;   // refuse duplicate recordings
+    previousTime=val->GetTimeStamp();
+    lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
     x[out] = (val->GetTimeStamp()-time0)/kSecInHour; // give times in fractions of hours 
     y[out] = val->GetFloat();
     out++;    
   }
-  SetStartTime(firstTime);
-  SetEndTime(lastTime);
+  if (!keepStart) fStartTime=firstTime;
+  fEndTime=lastTime;
   TGraph * graph = new TGraph(out,x,y);
   delete [] x;
   delete [] y;
   return graph;
 }
+
+//_____________________________________________________________________________
+void AliDCSSensorArray::RemoveGraphDuplicates(Double_t tolerance){
+//
+//   Remove points with same y value as the previous measured point
+//   (to save space for non-fitted graphs -- i.e. last measured point used)
+//
+  Int_t nsensors = fSensors->GetEntries();
+  for ( Int_t isensor=0; isensor<nsensors; isensor++) {
+    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
+    TGraph *graph = entry->GetGraph();
+    Double_t x=-999.,y=-999., x0=-999.,y0=-999.;
+    if (graph) {
+      Int_t npoints=graph->GetN();
+      if (npoints>1) {
+        for (Int_t i=npoints-1;i>0;i--) {
+          graph->GetPoint(i,x,y);
+          graph->GetPoint(i-1,x0,y0);
+          if ( TMath::Abs(y-y0) < TMath::Abs(tolerance*y0) ) graph->RemovePoint(i);
+        }
+      }
+    }
+   }
+}    
+
   
 //_____________________________________________________________________________
 AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS) 
@@ -369,7 +477,7 @@ AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS)
 AliDCSSensor* AliDCSSensorArray::GetSensor(const TString& stringID)
 {
  //
- //  Return sensor information for sensor specified by IdDCS
+ //  Return sensor information for sensor specified by stringID
  //
  Int_t nsensors = fSensors->GetEntries();
  for (Int_t isensor=0; isensor<nsensors; isensor++) {
@@ -414,6 +522,33 @@ AliDCSSensor* AliDCSSensorArray::GetSensorNum(Int_t ind)
  return (AliDCSSensor*)fSensors->At(ind);
 }
 
+//_____________________________________________________________________________
+Int_t AliDCSSensorArray::SetSensor(const TString& stringID,
+                          const  AliDCSSensor& sensor)
+{
+ //
+ //  Update sensor information for sensor specified by stringID
+ //
+ Int_t nsensors = fSensors->GetEntries();
+ for (Int_t isensor=0; isensor<nsensors; isensor++) {
+   AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
+   if (entry->GetStringID() == stringID) 
+     {
+      new ((*fSensors)[isensor])AliDCSSensor(sensor);
+      return isensor;
+     }
+ }
+ return -1;
+}
+//_____________________________________________________________________________
+void AliDCSSensorArray::SetSensorNum(const Int_t ind, const AliDCSSensor& sensor)
+{
+ //
+ //  Update sensor information for sensor at index ind
+ //
+   new ((*fSensors)[ind])AliDCSSensor(sensor);
+   return;
+}
 //_____________________________________________________________________________
 void AliDCSSensorArray::RemoveSensorNum(Int_t ind)
 {
@@ -528,3 +663,19 @@ void AliDCSSensorArray::ClearFit()
      sensor->SetFit(0);
    }
 }
+//_____________________________________________________________________________
+void AliDCSSensorArray::AddSensors(AliDCSSensorArray *newSensors)
+{
+  //
+  // add sensors from two sensor arrays
+  //
+  
+  Int_t numNew = newSensors->NumSensors();
+  Int_t numOld = fSensors->GetEntries();
+  fSensors->Expand(numOld+numNew);
+  for (Int_t i=0;i<numNew;i++) {
+    AliDCSSensor *sens = newSensors->GetSensorNum(i);
+    new ((*fSensors)[numOld+i]) AliDCSSensor(*sens);
+  }
+}  
+