]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCTempMap.cxx
Fixing the problem that was causing the dip (savannah bug 48080):
[u/mrichter/AliRoot.git] / TPC / AliTPCTempMap.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 //  TPC calibration class for temperature maps and tendencies                //
20 //  (based on TPC Temperature Sensors and FiniteElement Simulation)          //
21 //                                                                           //
22 //  Authors: Stefan Rossegger, Haavard Helstrup                              //
23 //                                                                           //
24 ///////////////////////////////////////////////////////////////////////////////
25
26 #include "AliTPCSensorTempArray.h"
27 #include "TLinearFitter.h"
28 #include "TString.h"
29 #include "TGraph2D.h"
30 #include "TTimeStamp.h"
31
32 #include "AliTPCTempMap.h"
33
34
35 ClassImp(AliTPCTempMap)
36   
37   const char kStringFEsimulation[] = "FEsimulation.txt";
38
39 //_____________________________________________________________________________
40 AliTPCTempMap::AliTPCTempMap(AliTPCSensorTempArray *sensorDCS):
41   TNamed(),
42   fTempArray(0),
43   fStringFEsimulation(kStringFEsimulation)
44 {
45   //
46   // AliTPCTempMap default constructor
47   //
48
49   fTempArray = sensorDCS;
50
51 }
52
53 //_____________________________________________________________________________
54 AliTPCTempMap::AliTPCTempMap(const AliTPCTempMap &c):
55   TNamed(c),
56   fTempArray(c.fTempArray),
57   fStringFEsimulation(c.fStringFEsimulation)
58 {
59   //
60   // AliTPCTempMap copy constructor
61   //
62
63 }
64
65 //_____________________________________________________________________________
66 AliTPCTempMap::~AliTPCTempMap()
67 {
68   //
69   // AliTPCTempMap destructor
70   //
71   
72 }
73
74 //_____________________________________________________________________________
75 AliTPCTempMap &AliTPCTempMap::operator=(const AliTPCTempMap &c)
76 {
77   //
78   // Assignment operator
79   //
80
81   if (this != &c) ((AliTPCTempMap &) c).Copy(*this);
82   return *this;
83
84 }
85
86 //_____________________________________________________________________________
87 void AliTPCTempMap::Copy(TObject &c) const
88 {
89   //
90   // Copy function
91   //
92   
93   TObject::Copy(c);
94   
95 }
96
97 //_____________________________________________________________________________
98
99 Double_t AliTPCTempMap::GetTempGradientY(UInt_t timeSec, Int_t side){
100  //
101  // Extract Linear Vertical Temperature Gradient [K/cm] within the TPC on 
102  // Shaft Side(A): 0
103  // Muon  Side(C): 1
104  // Values based on TemperatureSensors within the TPC ( type: 3 (TPC) )
105  //
106  // FIXME: Also return residual-distribution, covariance Matrix
107  //        or simply chi2 for validity check? 
108  //        -> better use GetLinearFitter - function in this case!
109   
110  TLinearFitter *fitter = new TLinearFitter(3,"x0++x1++x2");
111  TVectorD param(3);
112  Int_t i = 0;
113
114  Int_t nsensors = fTempArray->NumSensors();
115  for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over all sensors
116    AliTPCSensorTemp *entry = (AliTPCSensorTemp*)fTempArray->GetSensorNum(isensor);
117    
118    if (entry->GetType()==3 && entry->GetSide()==side) { // take SensorType:TPC 
119      Double_t x[3];
120      x[0]=1;
121      x[1]=entry->GetX();
122      x[2]=entry->GetY();    
123      Double_t y = fTempArray->GetValue(timeSec,isensor); // get temperature value
124      fitter->AddPoint(x,y,1); // add values to LinearFitter
125      i++;
126    }
127
128  }  
129  fitter->Eval();
130  fitter->GetParameters(param);
131
132  fitter->~TLinearFitter();
133
134  return param[2]; // return vertical (Y) tempGradient in [K/cm]
135   
136 }
137
138 //_____________________________________________________________________________
139 TLinearFitter *AliTPCTempMap::GetLinearFitter(Int_t type, Int_t side, TTimeStamp &stamp)
140 {
141   //
142   // absolute time stamp used
143   // see AliTPCTempMap::GetLinearFitter(Int_t type, Int_t side, UInt_t timeSec) for details
144   //
145   Int_t timeSec = stamp.GetSec()-fTempArray->GetStartTime().GetSec();
146   return GetLinearFitter(type,side,timeSec);
147 }
148
149 //_____________________________________________________________________________
150 TLinearFitter *AliTPCTempMap::GetLinearFitter(Int_t type, Int_t side, UInt_t timeSec)
151 {
152   // 
153   // Creates a TlinearFitter object for the desired region of the TPC 
154   // (via choosen type and side of TPC temperature sensors) at a given 
155   // timeSec (in secounds) after start time
156   // type: 0 ... ReadOutChambers (ROC)
157   //       1 ... OuterContainmentVessel (OFC)
158   //       2 ... InnerContainmentVessel (IFC) + ThermalScreener (TS)
159   //       3 ... Within the TPC (DriftVolume) (TPC)
160   //       4 ... Only InnerContainmentVessel (IFC) 
161   // side: Can be choosen for type 0 and 3 (otherwise it will be ignored in 
162   //       in order to get all temperature sensors of interest)
163   //       0 ... Shaft Side (A)
164   //       1 ... Muon Side (C)
165   // 
166
167   TLinearFitter *fitter = new TLinearFitter(3);
168   Double_t *x = new Double_t[3];
169   Double_t y = 0;
170   const Float_t kMinT=10, kMaxT =30, kMaxDelta=0.5;
171   
172   if (type == 1 || type == 2 || type == 4) {
173     fitter->SetFormula("x0++x1++TMath::Sin(x2)"); // returns Z,Y gradient
174   } else {
175     fitter->SetFormula("x0++x1++x2"); // returns X,Y gradient
176   }
177
178   Int_t i = 0;
179   Int_t nsensors = fTempArray->NumSensors();
180
181   Float_t temps[1000];
182   for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over all sensors
183     AliTPCSensorTemp *entry = (AliTPCSensorTemp*)fTempArray->GetSensorNum(isensor);
184     if (entry->GetType()==type && entry->GetSide()==side){
185       Float_t temperature= fTempArray->GetValue(timeSec,isensor); // get temperature value
186       if (temperature>kMinT && temperature<kMaxT) {temps[i]=temperature; i++;}
187     }
188   }
189   Float_t medianTemp = TMath::Median(i, temps);
190   if (i<3) return 0;
191   Float_t rmsTemp = TMath::RMS(i, temps);
192   
193   i=0;
194   
195   for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over all sensors
196     AliTPCSensorTemp *entry = (AliTPCSensorTemp*)fTempArray->GetSensorNum(isensor);
197     
198     if (type==0 || type==3) { // 'side' information used
199       if (entry->GetType()==type && entry->GetSide()==side) {
200         x[0]=1;
201         x[1]=entry->GetX();
202         x[2]=entry->GetY();    
203         y = fTempArray->GetValue(timeSec,isensor); // get temperature value
204         if (TMath::Abs(y-medianTemp)>kMaxDelta+4.*rmsTemp) continue;
205         fitter->AddPoint(x,y,1); // add values to LinearFitter
206         i++;
207       }
208     } else if (type==2) { // in case of IFC also usage of TS values
209       if ((entry->GetType()==2) || (entry->GetType()==5)) {
210         x[0]=1;
211         x[1]=entry->GetZ();
212         x[2]=entry->GetPhi();    
213         y = fTempArray->GetValue(timeSec,isensor);
214         if (TMath::Abs(y-medianTemp)>kMaxDelta+4.*rmsTemp) continue;
215         fitter->AddPoint(x,y,1); 
216         i++;
217       }
218     } else if (type==1){
219       if (entry->GetType()==type) {
220         x[0]=1;
221         x[1]=entry->GetZ();
222         x[2]=entry->GetPhi();    
223         y = fTempArray->GetValue(timeSec,isensor);
224         if (TMath::Abs(y-medianTemp)>kMaxDelta+4.*rmsTemp) continue;
225         fitter->AddPoint(x,y,1);
226         i++;    
227       }
228     } else if (type==4) { // ONLY IFC
229       if (entry->GetType()==2) {
230         x[0]=1;
231         x[1]=entry->GetZ();
232         x[2]=entry->GetPhi();    
233         y = fTempArray->GetValue(timeSec,isensor);
234         if (TMath::Abs(y-medianTemp)>kMaxDelta+4.*rmsTemp) continue;
235         fitter->AddPoint(x,y,1); 
236         i++;
237       }
238     }
239   }  
240   fitter->Eval();
241   //fitter->EvalRobust(0.9); // Evaluates fitter
242   
243   delete [] x;
244
245   return fitter; 
246
247   // returns TLinearFitter object where Chi2, Fitparameters and residuals can 
248   // be extracted via usual memberfunctions
249   // example: fitter->GetParameters(param)
250   // In case of type IFC or OFC, the parameters are the gradients in 
251   // Z and Y direction (see fitformula)
252   // Caution: Parameters are [K/cm] except Y at IFC,OFC ([K/radius]) 
253 }
254
255 //_____________________________________________________________________________
256
257 TGraph2D *AliTPCTempMap::GetTempMapsViaSensors(Int_t type, Int_t side, UInt_t timeSec)
258 {
259   // 
260   // Creates a TGraph2D object for the desired region of the TPC 
261   // (via choosen type and side of TPC temperature sensors) at a given 
262   // timeSec (in secounds) after start time
263   // type: 0 ... ReadOutChambers (ROC)
264   //       1 ... OuterContainmentVessel (OFC)
265   //       2 ... InnerContainmentVessel (IFC) + ThermalScreener (TS)
266   //       3 ... Within the TPC (DriftVolume) (TPC)
267   // side: Can be choosen for type 0 and 3 (otherwise it will be ignored in 
268   //       in order to get all temperature sensors of interest)
269   //       0 ... A - side
270   //       1 ... C - side
271   // 
272
273   TGraph2D *graph2D = new TGraph2D();
274
275   Int_t i = 0;
276   
277   Int_t nsensors = fTempArray->NumSensors();
278   for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over all sensors
279     AliTPCSensorTemp *entry = (AliTPCSensorTemp*)fTempArray->GetSensorNum(isensor);
280
281     Double_t x, y, z, r, phi, tempValue;
282     x = entry->GetX();
283     y = entry->GetY();
284     z = entry->GetZ();
285     r = entry->GetR();
286     phi = entry->GetPhi();
287     tempValue = fTempArray->GetValue(timeSec,isensor);
288     //    printf("%d type %d: x=%lf y=%lf temp=%lf\n",isensor,entry->GetType(),x,y, tempValue);
289     if (type==0 || type==3) { // 'side' information used
290       if (entry->GetType()==type && entry->GetSide()==side) {
291         graph2D->SetPoint(i,x,y,tempValue);
292         i++;
293       }
294     } else if (type==2) { // in case of IFC also usage of TS values
295       if (entry->GetType()==2 || entry->GetType()==5) {
296         graph2D->SetPoint(i,z,phi,tempValue);
297         i++;
298       }
299     } else if (type==1){
300       if (entry->GetType()==type) {
301         graph2D->SetPoint(i,z,phi,tempValue);
302         i++;
303       }
304     }
305   }  
306   
307   if (type==0 || type==3) {
308     graph2D->GetXaxis()->SetTitle("X[cm]");
309     graph2D->GetYaxis()->SetTitle("Y[cm]");
310     if (type==0 && side==0) {
311       graph2D->SetTitle("ROC A side");
312     } else if (type==0 && side==1) {
313       graph2D->SetTitle("ROC C side");
314     } else if (type==3 && side==0) {
315       graph2D->SetTitle("TPC A side (Inside the TPC)");
316     } else if (type==3 && side==1) {
317       graph2D->SetTitle("TPC C side (Inside the TPC)");
318     }
319   } else if (type==1 || type==2) {
320     graph2D->GetXaxis()->SetTitle("Z[cm]");
321     graph2D->GetYaxis()->SetTitle("Phi[RAD]");
322     if (type==1) {
323       graph2D->SetTitle("Outer Containment Vessel");
324     } else if (type==2) {
325       graph2D->SetTitle("Inner Containment Vessel");
326     }
327   }
328
329   if (!graph2D->GetN()) {
330     printf("Returned TGraph2D is empty: check type and side values\n");
331   }
332
333   graph2D->GetXaxis()->SetLabelOffset(0.0);
334   graph2D->GetYaxis()->SetLabelOffset(0.005);
335   graph2D->GetZaxis()->SetLabelOffset(-0.04);
336   
337
338   return graph2D; // returns TGgraph2D object
339   
340 }
341
342
343 //_____________________________________________________________________________
344
345 TGraph *AliTPCTempMap::MakeGraphGradient(Int_t axis, Int_t side, Int_t nPoints)
346 {  
347   //
348   // Make graph from start time to end time of TempGradient in axis direction
349   // axis: 0 ... horizontal Temperature Gradient (X)
350   //       1 ... vertical Temperature Gradient (Y)
351   //       2 ... longitudenal Temperature Gradient (Z) (side is ignored) 
352   //             z gradient value based on OFC temperature sensors
353   //             Caution!: better z gradient values through difference between 
354   //             param[0] A- and param[0] C-side !
355   // side for X and Y gradient: 
356   //       0 ... Shaft Side (A)
357   //       1 ... Muon Side (C)
358   //
359   
360   TVectorD param(3);
361   TLinearFitter *fitter = new TLinearFitter(3);
362
363   UInt_t fStartTime = fTempArray->AliTPCSensorTempArray::GetStartTime();
364   UInt_t fEndTime = fTempArray->AliTPCSensorTempArray::GetEndTime();
365   
366   UInt_t stepTime = (fEndTime-fStartTime)/nPoints;
367
368   Double_t *x = new Double_t[nPoints];
369   Double_t *y = new Double_t[nPoints];
370   for (Int_t ip=0; ip<nPoints; ip++) {
371     x[ip] = fStartTime+ip*stepTime;
372     if (axis==2) {// Gradient in Z direction (based on OFC tempSensors)
373       fitter = GetLinearFitter(1, side, ip*stepTime);
374     } else {// Gradient in X or Y direction (based on TPC tempSensors)
375       fitter = GetLinearFitter(3, side, ip*stepTime);
376     }
377     fitter->GetParameters(param);
378     // multiplied by 500 since TempGradient is in [K/cm] 
379     // (TPC diameter and length ~500cm)
380     if (axis==1) { // Y axis
381       y[ip] = param[2]*500;
382     } else { // X axis
383       y[ip] = param[1]*500;
384     }
385   }
386
387   TGraph *graph = new TGraph(nPoints,x,y);
388
389   fitter->~TLinearFitter(); 
390   delete [] x;
391   delete [] y;
392
393   graph->GetXaxis()->SetTimeDisplay(1);
394   graph->GetXaxis()->SetLabelOffset(0.02);
395   graph->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}");
396
397   return graph;
398 }
399
400
401 //_____________________________________________________________________________
402 Double_t AliTPCTempMap::GetTemperature(Double_t x, Double_t y, Double_t z, TTimeStamp &stamp)
403 {
404   //
405   // absolute time stamp used
406   // see also Double_t AliTPCTempMap::GetTemperature(Double_t x, Double_t y, Double_t z, UInt_t timeSec) for details
407   //
408
409   Int_t timeSec = stamp.GetSec()-fTempArray->GetStartTime().GetSec();
410   return GetTemperature(x, y, z, timeSec);
411 }
412
413 //_____________________________________________________________________________
414
415 Double_t AliTPCTempMap::GetTemperature(Double_t x, Double_t y, Double_t z, UInt_t timeSec)
416 {  
417   //
418   // Returns estimated Temperature at given position (x,y,z[cm]) at given time 
419   // (timeSec) after starttime
420   // Method: so far just a linear interpolation between Linar fits of 
421   //         the TPC temperature sensors
422   //         FIXME: 'Educated Fit' through FiniteElement Simulation results!
423   // FIXXME: Return 0? if x,y,z out of range
424   //
425   
426   TVectorD paramA(3), paramC(3);
427   TLinearFitter *fitterA = new TLinearFitter(3);
428   TLinearFitter *fitterC = new TLinearFitter(3);
429
430   fitterA = GetLinearFitter(3, 0, timeSec);
431   fitterA->GetParameters(paramA);
432   fitterC = GetLinearFitter(3, 1, timeSec);
433   fitterC->GetParameters(paramC);
434
435   Double_t fvalA = paramA[0]+paramA[1]*x+paramA[2]*y;
436   Double_t fvalC = paramC[0]+paramC[1]*x+paramC[2]*y;
437
438   Double_t k = (fvalA-fvalC)/(2*247);
439   Double_t tempValue = fvalC+(fvalA-fvalC)/2+k*z;
440
441   fitterA->~TLinearFitter();
442   fitterC->~TLinearFitter();
443
444   return tempValue;
445
446 }
447