Marian
[u/mrichter/AliRoot.git] / TPC / AliTPCTempMap.cxx
CommitLineData
1209231c 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
34ClassImp(AliTPCTempMap)
35
36 const char kStringFEsimulation[] = "FEsimulation.txt";
37
38//_____________________________________________________________________________
39AliTPCTempMap::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//_____________________________________________________________________________
53AliTPCTempMap::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//_____________________________________________________________________________
65AliTPCTempMap::~AliTPCTempMap()
66{
67 //
68 // AliTPCTempMap destructor
69 //
70
71}
72
73//_____________________________________________________________________________
74AliTPCTempMap &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//_____________________________________________________________________________
86void AliTPCTempMap::Copy(TObject &c) const
87{
88 //
89 // Copy function
90 //
91
92 TObject::Copy(c);
93
94}
95
96//_____________________________________________________________________________
97
98Double_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
b479e253 109 TLinearFitter *fitter = new TLinearFitter(3,"x0++x1++x2");
1209231c 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();
55f06b51 122 Double_t y = ft->GetValue(timeSec,isensor); // get temperature value
b479e253 123 fitter->AddPoint(x,y,1); // add values to LinearFitter
1209231c 124 i++;
125 }
126
127 }
b479e253 128 fitter->Eval();
129 fitter->GetParameters(param);
130
131 fitter->~TLinearFitter();
1209231c 132
133 return param[2]; // return vertical (Y) tempGradient in [K/cm]
134
135}
136
137//_____________________________________________________________________________
138
139TLinearFitter *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)
d0bd4fcc 149 // 4 ... Only InnerContainmentVessel (IFC)
1209231c 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
d0bd4fcc 160 if (type == 1 || type == 2 || type == 4) {
1209231c 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();
55f06b51 176 y = ft->GetValue(timeSec,isensor); // get temperature value
1209231c 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();
55f06b51 185 y = ft->GetValue(timeSec,isensor);
1209231c 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();
55f06b51 194 y = ft->GetValue(timeSec,isensor);
1209231c 195 fitter->AddPoint(x,y,1);
196 i++;
197 }
d0bd4fcc 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();
55f06b51 203 y = ft->GetValue(timeSec,isensor);
d0bd4fcc 204 fitter->AddPoint(x,y,1);
205 i++;
206 }
1209231c 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
b479e253 217 // example: fitter->GetParameters(param)
1209231c 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
225TGraph2D *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)
55f06b51 237 // 0 ... A - side
238 // 1 ... C - side
1209231c 239 //
240
241 TGraph2D *graph2D = new TGraph2D();
242
243 Int_t i = 0;
244
1209231c 245 Int_t nsensors = ft->NumSensors();
1209231c 246 for (Int_t isensor=0; isensor<nsensors; isensor++) { // loop over all sensors
247 AliTPCSensorTemp *entry = (AliTPCSensorTemp*)ft->GetSensorNum(isensor);
248
249 Double_t x, y, z, r, phi, tempValue;
250 x = entry->GetX();
251 y = entry->GetY();
252 z = entry->GetZ();
253 r = entry->GetR();
254 phi = entry->GetPhi();
55f06b51 255 tempValue = ft->GetValue(timeSec,isensor);
256 // printf("%d type %d: x=%lf y=%lf temp=%lf\n",isensor,entry->GetType(),x,y, tempValue);
1209231c 257 if (type==0 || type==3) { // 'side' information used
258 if (entry->GetType()==type && entry->GetSide()==side) {
259 graph2D->SetPoint(i,x,y,tempValue);
260 i++;
261 }
262 } else if (type==2) { // in case of IFC also usage of TS values
263 if (entry->GetType()==2 || entry->GetType()==5) {
264 graph2D->SetPoint(i,z,phi,tempValue);
265 i++;
266 }
267 } else if (type==1){
268 if (entry->GetType()==type) {
269 graph2D->SetPoint(i,z,phi,tempValue);
270 i++;
271 }
272 }
273 }
274
275 if (type==0 || type==3) {
276 graph2D->GetXaxis()->SetTitle("X[cm]");
277 graph2D->GetYaxis()->SetTitle("Y[cm]");
278 if (type==0 && side==0) {
55f06b51 279 graph2D->SetTitle("ROC A side");
1209231c 280 } else if (type==0 && side==1) {
55f06b51 281 graph2D->SetTitle("ROC C side");
1209231c 282 } else if (type==3 && side==0) {
55f06b51 283 graph2D->SetTitle("TPC A side (Inside the TPC)");
1209231c 284 } else if (type==3 && side==1) {
55f06b51 285 graph2D->SetTitle("TPC C side (Inside the TPC)");
1209231c 286 }
287 } else if (type==1 || type==2) {
288 graph2D->GetXaxis()->SetTitle("Z[cm]");
289 graph2D->GetYaxis()->SetTitle("Phi[RAD]");
290 if (type==1) {
291 graph2D->SetTitle("Outer Containment Vessel");
292 } else if (type==2) {
55f06b51 293 graph2D->SetTitle("Inner Containment Vessel");
1209231c 294 }
295 }
296
297 if (!graph2D->GetN()) {
298 printf("Returned TGraph2D is empty: check type and side values\n");
299 }
300
301 graph2D->GetXaxis()->SetLabelOffset(0.0);
302 graph2D->GetYaxis()->SetLabelOffset(0.005);
303 graph2D->GetZaxis()->SetLabelOffset(-0.04);
304
305
306 return graph2D; // returns TGgraph2D object
307
308}
309
310
311//_____________________________________________________________________________
312
313TGraph *AliTPCTempMap::MakeGraphGradient(Int_t axis, Int_t side, Int_t nPoints)
314{
315 //
316 // Make graph from start time to end time of TempGradient in axis direction
317 // axis: 0 ... horizontal Temperature Gradient (X)
318 // 1 ... vertical Temperature Gradient (Y)
319 // 2 ... longitudenal Temperature Gradient (Z) (side is ignored)
320 // z gradient value based on OFC temperature sensors
321 // Caution!: better z gradient values through difference between
322 // param[0] A- and param[0] C-side !
323 // side for X and Y gradient:
324 // 0 ... Shaft Side (A)
325 // 1 ... Muon Side (C)
326 //
327
328 TVectorD param(3);
329 TLinearFitter *fitter = new TLinearFitter(3);
330
331 UInt_t fStartTime = ft->AliTPCSensorTempArray::GetStartTime();
332 UInt_t fEndTime = ft->AliTPCSensorTempArray::GetEndTime();
333
334 UInt_t stepTime = (fEndTime-fStartTime)/nPoints;
335
336 Double_t *x = new Double_t[nPoints];
337 Double_t *y = new Double_t[nPoints];
338 for (Int_t ip=0; ip<nPoints; ip++) {
339 x[ip] = fStartTime+ip*stepTime;
340 if (axis==2) {// Gradient in Z direction (based on OFC tempSensors)
341 fitter = GetLinearFitter(1, side, ip*stepTime);
342 } else {// Gradient in X or Y direction (based on TPC tempSensors)
343 fitter = GetLinearFitter(3, side, ip*stepTime);
344 }
345 fitter->GetParameters(param);
346 // multiplied by 500 since TempGradient is in [K/cm]
347 // (TPC diameter and length ~500cm)
348 if (axis==1) { // Y axis
349 y[ip] = param[2]*500;
350 } else { // X axis
351 y[ip] = param[1]*500;
352 }
353 }
354
355 TGraph *graph = new TGraph(nPoints,x,y);
356
357 fitter->~TLinearFitter();
358 delete [] x;
359 delete [] y;
360
361 graph->GetXaxis()->SetTimeDisplay(1);
362 graph->GetXaxis()->SetLabelOffset(0.02);
363 graph->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}");
364
365 return graph;
366}
367
368//_____________________________________________________________________________
369
370Double_t AliTPCTempMap::GetTemperature(Double_t x, Double_t y, Double_t z, UInt_t timeSec)
371{
372 //
373 // Returns estimated Temperature at given position (x,y,z) at given time
374 // (timeSec) after starttime
375 // Method: so far just a linear interpolation between Linar fits of
376 // the TPC temperature sensors
377 // FIXME: 'Educated Fit' through FiniteElement Simulation results!
378 // FIXXME: Return 0? if x,y,z out of range
379 //
380
381 TVectorD paramA(3), paramC(3);
382 TLinearFitter *fitterA = new TLinearFitter(3);
383 TLinearFitter *fitterC = new TLinearFitter(3);
384
385 fitterA = GetLinearFitter(3, 0, timeSec);
386 fitterA->GetParameters(paramA);
387 fitterC = GetLinearFitter(3, 1, timeSec);
388 fitterC->GetParameters(paramC);
389
390 Double_t fvalA = paramA[0]+paramA[1]*x+paramA[2]*y;
391 Double_t fvalC = paramC[0]+paramC[1]*x+paramC[2]*y;
392
393 Double_t k = (fvalA-fvalC)/(2*247);
394 Double_t tempValue = fvalC+(fvalA-fvalC)/2+k*z;
395
396 fitterA->~TLinearFitter();
397 fitterC->~TLinearFitter();
398
399 return tempValue;
400}
401