LCOV - code coverage report
Current view: top level - TPC/TPCbase - AliTPCTempMap.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 195 0.5 %
Date: 2016-06-14 17:26:59 Functions: 1 18 5.6 %

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

Generated by: LCOV version 1.11