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