]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/CDB/AliDCSSensorArray.cxx
STEER/CDB: Missing delete in AliDCSSensor dtor
[u/mrichter/AliRoot.git] / STEER / CDB / AliDCSSensorArray.cxx
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
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 //  Calibration class for DCS sensors                                        //
20 //  Authors: Marian Ivanov and Haavard Helstrup                              //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include "AliDCSSensorArray.h"
25 #include "AliLog.h"
26 #include <TMath.h>
27
28 ClassImp(AliDCSSensorArray)
29
30 const Double_t kSecInHour = 3600.; // seconds in one hour
31 const UInt_t   kMinMapTime = 60;   // don't fit maps shorter than one minute
32
33 //_____________________________________________________________________________
34 AliDCSSensorArray::AliDCSSensorArray():TNamed(), 
35   fMinGraph(10),
36   fMinPoints(10),
37   fIter(10),
38   fMaxDelta(0.0),
39   fFitReq(2),
40   fValCut(-1),
41   fDiffCut(-1),
42   fStartTime (2000,1,1,0,0,0),
43   fEndTime   (2000,1,1,0,0,0),
44   fSensors(0)
45 {
46   //
47   // AliDCSSensorArray default constructor
48   //
49
50 }
51 //_____________________________________________________________________________
52 AliDCSSensorArray::AliDCSSensorArray(TClonesArray *arr):TNamed(),
53   fMinGraph(10),
54   fMinPoints(10),
55   fIter(10),
56   fMaxDelta(0.0),
57   fFitReq(2),
58   fValCut(-1),
59   fDiffCut(-1),
60   fStartTime (2000,1,1,0,0,0),
61   fEndTime   (2000,1,1,0,0,0),
62   fSensors(arr)
63 {
64   //
65   // AliDCSSensorArray special constructor taking TClonesArray from ReadList
66   //
67
68 }
69 //_____________________________________________________________________________
70 AliDCSSensorArray::AliDCSSensorArray(Int_t run, const char* dbEntry) :
71   TNamed(),
72   fMinGraph(10),
73   fMinPoints(10),
74   fIter(10),
75   fMaxDelta(0.0),
76   fFitReq(2),
77   fValCut(-1),
78   fDiffCut(-1),
79   fStartTime (2000,1,1,0,0,0),
80   fEndTime   (2000,1,1,0,0,0),
81   fSensors(0)
82 {
83   //
84   // Read configuration from OCDB
85   //
86
87   AliCDBEntry *entry = AliCDBManager::Instance()->Get(dbEntry,run);
88   if (entry) {
89     TTree *tree = (TTree*) entry->GetObject();
90     fSensors = AliDCSSensor::ReadTree(tree);
91   } else {
92     AliError("Unable to load configuration from CDB!");
93   }
94 }
95 //_____________________________________________________________________________
96 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
97                        TTree* confTree) :
98   TNamed(),
99   fMinGraph(10),
100   fMinPoints(10),
101   fIter(10),
102   fMaxDelta(0.0),
103   fFitReq(2),
104   fValCut(-1),
105   fDiffCut(-1),
106   fStartTime (2000,1,1,0,0,0),
107   fEndTime   (2000,1,1,0,0,0),
108   fSensors(0)
109
110 {
111   //
112   // AliDCSSensorArray constructor for Shuttle preprocessor
113   //  (confTree read from OCDB)
114   //
115   fSensors = AliDCSSensor::ReadTree(confTree);
116   fSensors->BypassStreamer(kFALSE);
117   fStartTime = TTimeStamp((time_t)startTime,0);
118   fEndTime   = TTimeStamp((time_t)endTime,0);
119 }
120
121
122 //_____________________________________________________________________________
123 AliDCSSensorArray::AliDCSSensorArray(UInt_t startTime, UInt_t endTime,
124                        TClonesArray *sensors) :
125   TNamed(),
126   fMinGraph(10),
127   fMinPoints(10),
128   fIter(10),
129   fMaxDelta(0.0),
130   fFitReq(2),
131   fValCut(-1),
132   fDiffCut(-1),
133   fStartTime (2000,1,1,0,0,0),
134   fEndTime   (2000,1,1,0,0,0),
135   fSensors(sensors)
136
137 {
138   //
139   // AliDCSSensorArray constructor for Shuttle preprocessor
140   //  (TClonesArray of AliDCSSensor objects)
141   //
142   fStartTime = TTimeStamp((time_t)startTime,0);
143   fEndTime   = TTimeStamp((time_t)endTime,0);
144 }
145
146 //_____________________________________________________________________________
147 AliDCSSensorArray::AliDCSSensorArray(const AliDCSSensorArray &c):TNamed(c),
148   fMinGraph(c.fMinGraph),
149   fMinPoints(c.fMinPoints),
150   fIter(c.fIter),
151   fMaxDelta(c.fMaxDelta),
152   fFitReq(c.fFitReq),
153   fValCut(c.fValCut),
154   fDiffCut(c.fDiffCut),
155   fStartTime (c.fStartTime),
156   fEndTime   (c.fEndTime),
157   fSensors(0)
158
159 {
160   //
161   // AliDCSSensorArray copy constructor
162   //
163
164   fSensors = (TClonesArray*)c.fSensors->Clone();
165 }
166
167 ///_____________________________________________________________________________
168 AliDCSSensorArray::~AliDCSSensorArray()
169 {
170   //
171   // AliDCSSensorArray destructor
172   //
173   fSensors->Delete();
174   delete fSensors;
175
176 }
177
178 //_____________________________________________________________________________
179 AliDCSSensorArray &AliDCSSensorArray::operator=(const AliDCSSensorArray &c)
180 {
181   //
182   // Assignment operator
183   //
184   if (this != &c) {
185      fSensors->Delete();
186      new (this) AliDCSSensorArray(c);
187      fSensors = (TClonesArray*)c.fSensors->Clone();
188   }
189   return *this;
190 }
191
192 void AliDCSSensorArray::Print(const Option_t* option) const{
193   //
194   // print function overwriten
195   //
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);
203   }
204 }
205
206 //____________________________________________________________________________
207
208 void AliDCSSensorArray::SetGraph(TMap *map)
209 {
210   //
211   // Read graphs from DCS maps
212   //
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());
218     if ( gr !=0 ) {
219        entry->SetGraph((TGraph*)gr->Clone());
220     } else {
221        entry->SetGraph(0);
222     }
223   }
224 }
225 //_____________________________________________________________________________
226 void AliDCSSensorArray::MakeSplineFit(TMap *map, Bool_t keepMap)
227 {
228   //
229   // Make spline fits from DCS maps
230   //
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());
236     if (!gr ) {
237       entry->SetFit(0);
238       entry->SetGraph(0);
239       AliWarning(Form("sensor %s: no input graph",stringID.Data()));
240       continue;
241     }
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());
246     } else {
247       AliSplineFit *fit = new AliSplineFit();
248       fit->SetMinPoints(fMinGraph);
249       fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
250       fit->SplineFit(fFitReq);
251       fit->Cleanup();
252       if (fit->GetKnots()>0) {
253         entry->SetFit(fit);
254       } else {
255         AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
256         entry->SetGraph((TGraph*)gr->Clone());
257       }
258     }
259     if (keepMap) entry->SetGraph((TGraph*)gr->Clone());
260   }
261 }
262 //_____________________________________________________________________________
263 void AliDCSSensorArray::MakeSplineFitAddPoints(TMap *map)
264 {
265   //
266   // Make spline fits from DCS maps
267   //
268   Int_t nsensors = fSensors->GetEntries();
269   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
270     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
271
272   // fetch old points from existing graph
273
274     TGraph *gr = entry->GetGraph();
275     if (!gr) {
276       gr = new TGraph();
277       entry->SetGraph(gr);
278     } 
279     TString stringID = entry->GetStringID();
280
281   // fetch new points from DCS map
282   
283     TGraph *grAdd = (TGraph*)map->GetValue(stringID.Data());
284     if (!grAdd ) return;
285
286   // add new points to end of graph
287   
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]);
296     }
297  
298    // make fit to complete graph
299    
300     AliSplineFit *fit = new AliSplineFit();
301     fit->SetMinPoints(fMinGraph);
302     fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
303     fit->SplineFit(fFitReq);
304     fit->Cleanup();
305     if (fit->GetKnots()>0) {
306       AliSplineFit *oldFit = entry->GetFit();
307       if (oldFit) delete oldFit;
308       entry->SetFit(fit);
309     } else {
310       AliWarning(Form("sensor %s: no new fit performed. If available, old fit kept.",stringID.Data()));
311     }
312   }
313 }
314
315 //_____________________________________________________________________________
316 Int_t AliDCSSensorArray::NumFits() const 
317 {
318  //
319  // Return number of sensors where a succesful fit has been made
320  //
321   Int_t nfit=0;
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++;
326   }    
327   return nfit;
328 }
329 //_____________________________________________________________________________
330 Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor) 
331 {
332   //
333   // Return sensor value at time timeSec (obtained from fitted function)
334   //  timeSec = time in seconds from start of run
335   //
336
337   AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(sensor);
338   return entry->GetValue(TTimeStamp((time_t)fStartTime.GetSec()+timeSec,0));
339 }
340
341
342 //_____________________________________________________________________________
343 TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap, Bool_t keepStart)
344 {
345  //
346  // Extract temperature graphs from DCS maps
347  //
348  TMap *values = new TMap;
349  TObjArray * valueSet;
350  //
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.
355  
356  TTimeStamp startTime=fStartTime;
357  TTimeStamp endTime=fEndTime;
358  
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
368                                             // per sensor
369      values->Add(new TObjString(stringID.Data()),graph);
370      entry->SetStartTime(fStartTime);
371      entry->SetEndTime(fEndTime);
372    }
373  }
374  // Reset global start/end time 
375  //    ..... yes, I know this won't get a prize for structured programming..:-)
376
377  fStartTime=startTime;
378  fEndTime=endTime;
379  return values;
380 }
381
382
383 //_____________________________________________________________________________
384 TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet, Bool_t keepStart){
385   //
386   // Make graph of temperature values read from DCS map
387   //   (spline fit parameters will subsequently be obtained from this graph) 
388   //
389   Int_t nentries = valueSet->GetEntriesFast(); 
390   if ( nentries == 0 ) return 0;
391   
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);
397   if (keepStart) { 
398      firstTime = fStartTime;
399      time0 = firstTime.GetSec();
400   }
401   Int_t out=0;
402   Int_t skipped=0;
403   AliDCSValue *val = (AliDCSValue *)valueSet->At(0);
404   AliDCSValue::Type type = val->GetType();
405   if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) {
406      delete [] x;
407      delete [] y;
408      return 0;
409   }
410   Float_t value;
411   for (Int_t i=0; i<nentries; i++){
412     val = (AliDCSValue *)valueSet->At(i);
413     if (!val) continue;
414     if (time0==0){
415       time0=val->GetTimeStamp();
416       firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
417       lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
418      }
419     switch ( type )
420     { 
421       case AliDCSValue::kFloat:
422         value = val->GetFloat();
423         break;
424       case AliDCSValue::kChar:
425         value = static_cast<Float_t>(val->GetChar());
426         break;
427       case AliDCSValue::kInt:
428         value = static_cast<Float_t>(val->GetInt());
429         break;
430       case AliDCSValue::kUInt:
431         value = static_cast<Float_t>(val->GetUInt());
432         break;
433       default:
434         continue;
435     }
436     if (fValCut>0 && TMath::Abs(value)>fValCut) continue;   // refuse values greater than cut
437     if (fDiffCut>0 ) {
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
441       }                                          
442       skipped=0;
443     }                                         
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 
449     y[out] = value;
450     out++;    
451   }
452   if (!keepStart) fStartTime=firstTime;
453   fEndTime=lastTime;
454   TGraph * graph = new TGraph(out,x,y);
455   delete [] x;
456   delete [] y;
457   return graph;
458 }
459
460 //_____________________________________________________________________________
461 void AliDCSSensorArray::RemoveGraphDuplicates(Double_t tolerance){
462 //
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)
465 //
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.;
471     if (graph) {
472       Int_t npoints=graph->GetN();
473       if (npoints>1) {
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);
478          }
479       }
480     }
481    }
482 }    
483
484   
485 //_____________________________________________________________________________
486 AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS) 
487 {
488  //
489  //  Return sensor information for sensor specified by IdDCS
490  //
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;
495  }
496  return 0;
497 }
498 //_____________________________________________________________________________
499 AliDCSSensor* AliDCSSensorArray::GetSensor(const TString& stringID)
500 {
501  //
502  //  Return sensor information for sensor specified by stringID
503  //
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;
508  }
509  return 0;
510 }
511 //_____________________________________________________________________________
512 AliDCSSensor* AliDCSSensorArray::GetSensor(Double_t x, Double_t y, Double_t z)
513 {
514  //
515  //  Return sensor closest to given position
516  //
517  Int_t nsensors = fSensors->GetEntries();
518  Double_t dist2min=1e99;
519  Double_t xs,ys,zs,dist2;
520  Int_t ind=-1;
521  for (Int_t isensor=0; isensor<nsensors; isensor++) {
522    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
523    xs = entry->GetX();
524    ys = entry->GetY();
525    zs = entry->GetZ();
526    dist2 = (x-xs)*(x-xs) + (y-ys)*(y-ys) + (z-zs)*(z-zs);
527    if (dist2 < dist2min) {
528       ind=isensor;
529       dist2min = dist2;
530    }
531  }
532  if ( ind >= 0 ) {
533     return (AliDCSSensor*)fSensors->At(ind);
534  } else {
535     return 0;
536  }
537 }
538 //_____________________________________________________________________________
539 AliDCSSensor* AliDCSSensorArray::GetSensorNum(Int_t ind)
540 {
541  //
542  //  Return sensor given by array index
543  //
544  return (AliDCSSensor*)fSensors->At(ind);
545 }
546
547 //_____________________________________________________________________________
548 Int_t AliDCSSensorArray::SetSensor(const TString& stringID,
549                           const  AliDCSSensor& sensor)
550 {
551  //
552  //  Update sensor information for sensor specified by stringID
553  //
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) 
558      {
559       new ((*fSensors)[isensor])AliDCSSensor(sensor);
560       return isensor;
561      }
562  }
563  return -1;
564 }
565 //_____________________________________________________________________________
566 void AliDCSSensorArray::SetSensorNum(const Int_t ind, const AliDCSSensor& sensor)
567 {
568  //
569  //  Update sensor information for sensor at index ind
570  //
571    new ((*fSensors)[ind])AliDCSSensor(sensor);
572    return;
573 }
574 //_____________________________________________________________________________
575 void AliDCSSensorArray::RemoveSensorNum(Int_t ind)
576 {
577  //
578  //  Return sensor given by array index
579  //
580
581   delete fSensors->RemoveAt(ind);
582   fSensors->Compress();
583 }
584 //_____________________________________________________________________________
585 void AliDCSSensorArray::RemoveSensor(Int_t IdDCS)
586 {
587  //
588  //  Deletes Sensor by given IdDCS
589  //
590
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);
596       break;
597     }
598   }
599   fSensors->Compress();
600 }
601 //_____________________________________________________________________________
602 TArrayI AliDCSSensorArray::OutsideThreshold(Double_t threshold, UInt_t timeSec, Bool_t below) const
603 {
604  //
605  // Return sensors with values outside threshold at time defined by second
606  // parameter
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
609  //
610   Int_t nsensors = fSensors->GetEntries();
611   TArrayI array(nsensors);
612   Int_t outside=0;
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);
616     if (below) {
617       if (val<threshold) array[outside++] = entry->GetIdDCS();
618     } else {
619       if (val>threshold) array[outside++] = entry->GetIdDCS();
620     }    
621   }
622   array.Set(outside);
623   return array;
624 }
625  
626 //_____________________________________________________________________________
627 Int_t AliDCSSensorArray::GetFirstIdDCS() const
628 {
629  //
630  //  Return DCS Id of first sensor
631  //
632  if ( fSensors != 0 ) {
633     return ((AliDCSSensor*)fSensors->At(0))->GetIdDCS();
634  } else {
635     return 0;
636  }
637 }
638
639 //_____________________________________________________________________________
640 Int_t AliDCSSensorArray::GetLastIdDCS() const 
641 {
642  //
643  //  Return DCS Id of last sensor
644  //
645  if ( fSensors != 0 ) {
646     Int_t last = fSensors->GetEntries();
647     return ((AliDCSSensor*)fSensors->At(last-1))->GetIdDCS();
648  } else {
649     return 0;
650  }
651 }
652 //_____________________________________________________________________________
653 void AliDCSSensorArray::ClearGraph()
654 {
655   //
656   // Delete DCS graphs from all sensors in array
657   //
658    
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();
663      if ( gr != 0 ) {
664        delete gr;
665        gr = 0;
666      }
667      sensor->SetGraph(0);
668    }
669 }
670 //_____________________________________________________________________________
671 void AliDCSSensorArray::ClearFit()
672 {
673   //
674   // Delete spline fits from all sensors in array
675   //
676
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();
681      if ( fit != 0 ) {
682        delete fit;
683        fit = 0;
684      }
685      sensor->SetFit(0);
686    }
687 }
688 //_____________________________________________________________________________
689 void AliDCSSensorArray::AddSensors(AliDCSSensorArray *newSensors)
690 {
691   //
692   // add sensors from two sensor arrays
693   //
694   
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);
701   }
702 }  
703