#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(),
//
AliCDBEntry *entry = AliCDBManager::Instance()->Get(dbEntry,run);
- TTree *tree = (TTree*) entry->GetObject();
- fSensors = AliDCSSensor::ReadTree(tree);
+ if (entry) {
+ TTree *tree = (TTree*) entry->GetObject();
+ fSensors = AliDCSSensor::ReadTree(tree);
+ } else {
+ AliError("Unable to load configuration from CDB!");
+ }
}
//_____________________________________________________________________________
AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
//
fSensors = AliDCSSensor::ReadTree(confTree);
fSensors->BypassStreamer(kFALSE);
- fStartTime = TTimeStamp(startTime);
- fEndTime = TTimeStamp(endTime);
+ fStartTime = TTimeStamp((time_t)startTime,0);
+ fEndTime = TTimeStamp((time_t)endTime,0);
}
+//_____________________________________________________________________________
+AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
+ TClonesArray *sensors) :
+ TNamed(),
+ fMinGraph(10),
+ fMinPoints(10),
+ fIter(10),
+ fMaxDelta(0.0),
+ fFitReq(2),
+ fValCut(-1),
+ fDiffCut(-1),
+ fStartTime (2000,1,1,0,0,0),
+ fEndTime (2000,1,1,0,0,0),
+ fSensors(sensors)
+
+{
+ //
+ // AliDCSSensorArray constructor for Shuttle preprocessor
+ // (TClonesArray of AliDCSSensor objects)
+ //
+ fStartTime = TTimeStamp((time_t)startTime,0);
+ fEndTime = TTimeStamp((time_t)endTime,0);
+}
//_____________________________________________________________________________
AliDCSSensorArray::AliDCSSensorArray(const AliDCSSensorArray &c):TNamed(c),
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->GetKnots()>0) {
+ 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) {
+ if (fit->GetKnots()>0) {
+ 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);
}
}
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);
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)
Float_t *x = new Float_t[nentries];
Float_t *y = new Float_t[nentries];
- Int_t time0=fStartTime.GetSec();
+ 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);
AliDCSValue::Type type = val->GetType();
- if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) return 0;
+ if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) {
+ delete [] x;
+ delete [] y;
+ return 0;
+ }
Float_t value;
for (Int_t i=0; i<nentries; i++){
val = (AliDCSValue *)valueSet->At(i);
if (!val) continue;
if (time0==0){
time0=val->GetTimeStamp();
- }
+ firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
+ lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
+ }
switch ( type )
{
case AliDCSValue::kFloat:
skipped=0;
}
if (val->GetTimeStamp()-time0>1000000) continue;
+ 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++;
-
+ out++;
}
+ 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)
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++) {
return 0;
}
}
-
+//_____________________________________________________________________________
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)
{
//
delete fSensors->RemoveAt(ind);
fSensors->Compress();
}
+//_____________________________________________________________________________
void AliDCSSensorArray::RemoveSensor(Int_t IdDCS)
{
//
}
fSensors->Compress();
}
-
+//_____________________________________________________________________________
+TArrayI AliDCSSensorArray::OutsideThreshold(Double_t threshold, UInt_t timeSec, Bool_t below) const
+{
+ //
+ // Return sensors with values outside threshold at time defined by second
+ // parameter
+ // By default sensors with values below threshold are listed, if third
+ // parameter is set to kFALSE sensors with values above threshold are listed
+ //
+ Int_t nsensors = fSensors->GetEntries();
+ TArrayI array(nsensors);
+ Int_t outside=0;
+ for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
+ AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
+ Double_t val=entry->GetValue(timeSec);
+ if (below) {
+ if (val<threshold) array[outside++] = entry->GetIdDCS();
+ } else {
+ if (val>threshold) array[outside++] = entry->GetIdDCS();
+ }
+ }
+ array.Set(outside);
+ return array;
+}
+
+//_____________________________________________________________________________
Int_t AliDCSSensorArray::GetFirstIdDCS() const
{
//
}
}
+//_____________________________________________________________________________
Int_t AliDCSSensorArray::GetLastIdDCS() const
{
//
return 0;
}
}
+//_____________________________________________________________________________
void AliDCSSensorArray::ClearGraph()
{
//
sensor->SetGraph(0);
}
}
+//_____________________________________________________________________________
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);
+ }
+}
+