]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliDCSSensorArray.cxx
Coverity 15850
[u/mrichter/AliRoot.git] / STEER / 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 //____________________________________________________________________________
193
194 void AliDCSSensorArray::SetGraph(TMap *map)
195 {
196   //
197   // Read graphs from DCS maps
198   //
199   Int_t nsensors = fSensors->GetEntries();
200   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
201     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
202     TString stringID = entry->GetStringID();
203     TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
204     if ( gr !=0 ) {
205        entry->SetGraph((TGraph*)gr->Clone());
206     } else {
207        entry->SetGraph(0);
208     }
209   }
210 }
211 //_____________________________________________________________________________
212 void AliDCSSensorArray::MakeSplineFit(TMap *map, Bool_t keepMap)
213 {
214   //
215   // Make spline fits from DCS maps
216   //
217   Int_t nsensors = fSensors->GetEntries();
218   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
219     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
220     TString stringID = entry->GetStringID();
221     TGraph *gr = (TGraph*)map->GetValue(stringID.Data());
222     if (!gr ) {
223       entry->SetFit(0);
224       entry->SetGraph(0);
225       AliWarning(Form("sensor %s: no input graph",stringID.Data()));
226       continue;
227     }
228     UInt_t timeDiff = entry->GetEndTime() - entry->GetStartTime();
229     if ( timeDiff < kMinMapTime ) {
230       AliWarning(Form("sensor %s: map length < 60 s, DCS graph kept.",stringID.Data()));
231       entry->SetGraph((TGraph*)gr->Clone());
232     } else {
233       AliSplineFit *fit = new AliSplineFit();
234       fit->SetMinPoints(fMinGraph);
235       fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
236       fit->SplineFit(fFitReq);
237       fit->Cleanup();
238       if (fit->GetKnots()>0) {
239         entry->SetFit(fit);
240       } else {
241         AliWarning(Form("sensor %s: no fit performed, DCS graph kept.",stringID.Data()));
242         entry->SetGraph((TGraph*)gr->Clone());
243       }
244     }
245     if (keepMap) entry->SetGraph((TGraph*)gr->Clone());
246   }
247 }
248 //_____________________________________________________________________________
249 void AliDCSSensorArray::MakeSplineFitAddPoints(TMap *map)
250 {
251   //
252   // Make spline fits from DCS maps
253   //
254   Int_t nsensors = fSensors->GetEntries();
255   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
256     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
257
258   // fetch old points from existing graph
259
260     TGraph *gr = entry->GetGraph();
261     if (!gr) {
262       gr = new TGraph();
263       entry->SetGraph(gr);
264     } 
265     TString stringID = entry->GetStringID();
266
267   // fetch new points from DCS map
268   
269     TGraph *grAdd = (TGraph*)map->GetValue(stringID.Data());
270     if (!grAdd ) return;
271
272   // add new points to end of graph
273   
274     Int_t nPointsOld=gr->GetN();
275     Int_t nPointsAdd=grAdd->GetN();
276     gr->Expand(nPointsOld+nPointsAdd);
277     gr->Set(nPointsOld+nPointsAdd);
278     Double_t *addX=grAdd->GetX();
279     Double_t *addY=grAdd->GetY();
280     for (Int_t i=0;i<nPointsAdd;i++) {
281       gr->SetPoint(nPointsOld+i,addX[i],addY[i]);
282     }
283  
284    // make fit to complete graph
285    
286     AliSplineFit *fit = new AliSplineFit();
287     fit->SetMinPoints(fMinGraph);
288     fit->InitKnots(gr,fMinPoints,fIter,fMaxDelta);
289     fit->SplineFit(fFitReq);
290     fit->Cleanup();
291     if (fit->GetKnots()>0) {
292       AliSplineFit *oldFit = entry->GetFit();
293       if (oldFit) delete oldFit;
294       entry->SetFit(fit);
295     } else {
296       AliWarning(Form("sensor %s: no new fit performed. If available, old fit kept.",stringID.Data()));
297     }
298   }
299 }
300
301 //_____________________________________________________________________________
302 Int_t AliDCSSensorArray::NumFits() const 
303 {
304  //
305  // Return number of sensors where a succesful fit has been made
306  //
307   Int_t nfit=0;
308   Int_t nsensors = fSensors->GetEntries();
309   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
310     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
311     if (entry->GetFit()) nfit++;
312   }    
313   return nfit;
314 }
315 //_____________________________________________________________________________
316 Double_t AliDCSSensorArray::GetValue(UInt_t timeSec, Int_t sensor) 
317 {
318   //
319   // Return sensor value at time timeSec (obtained from fitted function)
320   //  timeSec = time in seconds from start of run
321   //
322
323   AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(sensor);
324   return entry->GetValue(TTimeStamp((time_t)fStartTime.GetSec()+timeSec,0));
325 }
326
327
328 //_____________________________________________________________________________
329 TMap* AliDCSSensorArray::ExtractDCS(TMap *dcsMap, Bool_t keepStart)
330 {
331  //
332  // Extract temperature graphs from DCS maps
333  //
334  TMap *values = new TMap;
335  TObjArray * valueSet;
336  //
337  // Keep global start/end times
338  //    to avoid extrapolations, the fits will only be valid from first 
339  //    measured point to last measured point. This is consistent with hardware,
340  //    as there would be a new measured point if the value changed.
341  
342  TTimeStamp startTime=fStartTime;
343  TTimeStamp endTime=fEndTime;
344  
345  Int_t nsensors = fSensors->GetEntries();
346  for ( Int_t isensor=0; isensor<nsensors; isensor++) {
347    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
348    TString stringID = entry->GetStringID();
349    TPair *pair = (TPair*)dcsMap->FindObject(stringID.Data());
350    if ( pair ) {                            // only try to read values
351                                             // if DCS object available
352      valueSet = (TObjArray*)pair->Value();
353      TGraph *graph = MakeGraph(valueSet,keepStart);   // MakeGraph sets start/end time
354                                             // per sensor
355      values->Add(new TObjString(stringID.Data()),graph);
356      entry->SetStartTime(fStartTime);
357      entry->SetEndTime(fEndTime);
358    }
359  }
360  // Reset global start/end time 
361  //    ..... yes, I know this won't get a prize for structured programming..:-)
362
363  fStartTime=startTime;
364  fEndTime=endTime;
365  return values;
366 }
367
368
369 //_____________________________________________________________________________
370 TGraph* AliDCSSensorArray::MakeGraph(TObjArray* valueSet, Bool_t keepStart){
371   //
372   // Make graph of temperature values read from DCS map
373   //   (spline fit parameters will subsequently be obtained from this graph) 
374   //
375   Int_t nentries = valueSet->GetEntriesFast(); 
376   if ( nentries == 0 ) return 0;
377   
378   Float_t *x = new Float_t[nentries];
379   Float_t *y = new Float_t[nentries];
380   Int_t time0=0, previousTime=0;
381   TTimeStamp firstTime(0);
382   TTimeStamp lastTime(0);
383   if (keepStart) { 
384      firstTime = fStartTime;
385      time0 = firstTime.GetSec();
386   }
387   Int_t out=0;
388   Int_t skipped=0;
389   AliDCSValue *val = (AliDCSValue *)valueSet->At(0);
390   AliDCSValue::Type type = val->GetType();
391   if ( type == AliDCSValue::kInvalid || type == AliDCSValue::kBool ) {
392      delete [] x;
393      delete [] y;
394      return 0;
395   }
396   Float_t value;
397   for (Int_t i=0; i<nentries; i++){
398     val = (AliDCSValue *)valueSet->At(i);
399     if (!val) continue;
400     if (time0==0){
401       time0=val->GetTimeStamp();
402       firstTime= TTimeStamp((time_t)val->GetTimeStamp(),0);
403       lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
404      }
405     switch ( type )
406     { 
407       case AliDCSValue::kFloat:
408         value = val->GetFloat();
409         break;
410       case AliDCSValue::kChar:
411         value = static_cast<Float_t>(val->GetChar());
412         break;
413       case AliDCSValue::kInt:
414         value = static_cast<Float_t>(val->GetInt());
415         break;
416       case AliDCSValue::kUInt:
417         value = static_cast<Float_t>(val->GetUInt());
418         break;
419       default:
420         continue;
421     }
422     if (fValCut>0 && TMath::Abs(value)>fValCut) continue;   // refuse values greater than cut
423     if (fDiffCut>0 ) {
424       if ( out>0 && skipped<10 && TMath::Abs(value-y[out-1])>fDiffCut) {
425         skipped++;                               // refuse values changing 
426         continue;                                // by > cut  in one time step
427       }                                          
428       skipped=0;
429     }                                         
430     if (val->GetTimeStamp()-time0>1000000) continue;
431     if (val->GetTimeStamp()-previousTime < 1 ) continue;   // refuse duplicate recordings
432     previousTime=val->GetTimeStamp();
433     lastTime=TTimeStamp((time_t)val->GetTimeStamp(),0);
434     x[out] = (val->GetTimeStamp()-time0)/kSecInHour; // give times in fractions of hours 
435     y[out] = val->GetFloat();
436     out++;    
437   }
438   if (!keepStart) fStartTime=firstTime;
439   fEndTime=lastTime;
440   TGraph * graph = new TGraph(out,x,y);
441   delete [] x;
442   delete [] y;
443   return graph;
444 }
445
446 //_____________________________________________________________________________
447 void AliDCSSensorArray::RemoveGraphDuplicates(Double_t tolerance){
448 //
449 //   Remove points with same y value as the previous measured point
450 //   (to save space for non-fitted graphs -- i.e. last measured point used)
451 //
452   Int_t nsensors = fSensors->GetEntries();
453   for ( Int_t isensor=0; isensor<nsensors; isensor++) {
454     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
455     TGraph *graph = entry->GetGraph();
456     Double_t x=-999.,y=-999., x0=-999.,y0=-999.;
457     if (graph) {
458       Int_t npoints=graph->GetN();
459       if (npoints>1) {
460         for (Int_t i=npoints-1;i>0;i--) {
461            graph->GetPoint(i,x,y);
462            graph->GetPoint(i-1,x0,y0);
463            if ( TMath::Abs(y-y0) < TMath::Abs(tolerance*y0) ) graph->RemovePoint(i);
464          }
465       }
466     }
467    }
468 }    
469
470   
471 //_____________________________________________________________________________
472 AliDCSSensor* AliDCSSensorArray::GetSensor(Int_t IdDCS) 
473 {
474  //
475  //  Return sensor information for sensor specified by IdDCS
476  //
477  Int_t nsensors = fSensors->GetEntries();
478  for (Int_t isensor=0; isensor<nsensors; isensor++) {
479    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
480    if (entry->GetIdDCS() == IdDCS) return entry;
481  }
482  return 0;
483 }
484 //_____________________________________________________________________________
485 AliDCSSensor* AliDCSSensorArray::GetSensor(const TString& stringID)
486 {
487  //
488  //  Return sensor information for sensor specified by stringID
489  //
490  Int_t nsensors = fSensors->GetEntries();
491  for (Int_t isensor=0; isensor<nsensors; isensor++) {
492    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
493    if (entry->GetStringID() == stringID) return entry;
494  }
495  return 0;
496 }
497 //_____________________________________________________________________________
498 AliDCSSensor* AliDCSSensorArray::GetSensor(Double_t x, Double_t y, Double_t z)
499 {
500  //
501  //  Return sensor closest to given position
502  //
503  Int_t nsensors = fSensors->GetEntries();
504  Double_t dist2min=1e99;
505  Double_t xs,ys,zs,dist2;
506  Int_t ind=-1;
507  for (Int_t isensor=0; isensor<nsensors; isensor++) {
508    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
509    xs = entry->GetX();
510    ys = entry->GetY();
511    zs = entry->GetZ();
512    dist2 = (x-xs)*(x-xs) + (y-ys)*(y-ys) + (z-zs)*(z-zs);
513    if (dist2 < dist2min) {
514       ind=isensor;
515       dist2min = dist2;
516    }
517  }
518  if ( ind >= 0 ) {
519     return (AliDCSSensor*)fSensors->At(ind);
520  } else {
521     return 0;
522  }
523 }
524 //_____________________________________________________________________________
525 AliDCSSensor* AliDCSSensorArray::GetSensorNum(Int_t ind)
526 {
527  //
528  //  Return sensor given by array index
529  //
530  return (AliDCSSensor*)fSensors->At(ind);
531 }
532
533 //_____________________________________________________________________________
534 Int_t AliDCSSensorArray::SetSensor(const TString& stringID,
535                           const  AliDCSSensor& sensor)
536 {
537  //
538  //  Update sensor information for sensor specified by stringID
539  //
540  Int_t nsensors = fSensors->GetEntries();
541  for (Int_t isensor=0; isensor<nsensors; isensor++) {
542    AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
543    if (entry->GetStringID() == stringID) 
544      {
545       new ((*fSensors)[isensor])AliDCSSensor(sensor);
546       return isensor;
547      }
548  }
549  return -1;
550 }
551 //_____________________________________________________________________________
552 void AliDCSSensorArray::SetSensorNum(const Int_t ind, const AliDCSSensor& sensor)
553 {
554  //
555  //  Update sensor information for sensor at index ind
556  //
557    new ((*fSensors)[ind])AliDCSSensor(sensor);
558    return;
559 }
560 //_____________________________________________________________________________
561 void AliDCSSensorArray::RemoveSensorNum(Int_t ind)
562 {
563  //
564  //  Return sensor given by array index
565  //
566
567   delete fSensors->RemoveAt(ind);
568   fSensors->Compress();
569 }
570 //_____________________________________________________________________________
571 void AliDCSSensorArray::RemoveSensor(Int_t IdDCS)
572 {
573  //
574  //  Deletes Sensor by given IdDCS
575  //
576
577   Int_t nsensors = fSensors->GetEntries();
578   for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
579     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
580     if (entry->GetIdDCS()==IdDCS) {
581       delete fSensors->RemoveAt(isensor);
582       break;
583     }
584   }
585   fSensors->Compress();
586 }
587 //_____________________________________________________________________________
588 TArrayI AliDCSSensorArray::OutsideThreshold(Double_t threshold, UInt_t timeSec, Bool_t below) const
589 {
590  //
591  // Return sensors with values outside threshold at time defined by second
592  // parameter
593  // By default sensors with values below threshold are listed, if third
594  // parameter is set to kFALSE sensors with values above threshold are listed
595  //
596   Int_t nsensors = fSensors->GetEntries();
597   TArrayI array(nsensors);
598   Int_t outside=0;
599   for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over sensors
600     AliDCSSensor *entry = (AliDCSSensor*)fSensors->At(isensor);
601     Double_t val=entry->GetValue(timeSec);
602     if (below) {
603       if (val<threshold) array[outside++] = entry->GetIdDCS();
604     } else {
605       if (val>threshold) array[outside++] = entry->GetIdDCS();
606     }    
607   }
608   array.Set(outside);
609   return array;
610 }
611  
612 //_____________________________________________________________________________
613 Int_t AliDCSSensorArray::GetFirstIdDCS() const
614 {
615  //
616  //  Return DCS Id of first sensor
617  //
618  if ( fSensors != 0 ) {
619     return ((AliDCSSensor*)fSensors->At(0))->GetIdDCS();
620  } else {
621     return 0;
622  }
623 }
624
625 //_____________________________________________________________________________
626 Int_t AliDCSSensorArray::GetLastIdDCS() const 
627 {
628  //
629  //  Return DCS Id of last sensor
630  //
631  if ( fSensors != 0 ) {
632     Int_t last = fSensors->GetEntries();
633     return ((AliDCSSensor*)fSensors->At(last-1))->GetIdDCS();
634  } else {
635     return 0;
636  }
637 }
638 //_____________________________________________________________________________
639 void AliDCSSensorArray::ClearGraph()
640 {
641   //
642   // Delete DCS graphs from all sensors in array
643   //
644    
645    Int_t nsensors = fSensors->GetEntries();
646    for ( Int_t isensor=0; isensor<nsensors; isensor++) {
647      AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
648      TGraph *gr = sensor->GetGraph();
649      if ( gr != 0 ) {
650        delete gr;
651        gr = 0;
652      }
653      sensor->SetGraph(0);
654    }
655 }
656 //_____________________________________________________________________________
657 void AliDCSSensorArray::ClearFit()
658 {
659   //
660   // Delete spline fits from all sensors in array
661   //
662
663    Int_t nsensors = fSensors->GetEntries();
664    for ( Int_t isensor=0; isensor<nsensors; isensor++) {
665      AliDCSSensor *sensor = (AliDCSSensor*)fSensors->At(isensor);
666      AliSplineFit *fit = sensor->GetFit();
667      if ( fit != 0 ) {
668        delete fit;
669        fit = 0;
670      }
671      sensor->SetFit(0);
672    }
673 }
674 //_____________________________________________________________________________
675 void AliDCSSensorArray::AddSensors(AliDCSSensorArray *newSensors)
676 {
677   //
678   // add sensors from two sensor arrays
679   //
680   
681   Int_t numNew = newSensors->NumSensors();
682   Int_t numOld = fSensors->GetEntries();
683   fSensors->Expand(numOld+numNew);
684   for (Int_t i=0;i<numNew;i++) {
685     AliDCSSensor *sens = newSensors->GetSensorNum(i);
686     new ((*fSensors)[numOld+i]) AliDCSSensor(*sens);
687   }
688 }  
689