|
| 1 | +// Copyright CERN and copyright holders of ALICE O2. This software is |
| 2 | +// distributed under the terms of the GNU General Public License v3 (GPL |
| 3 | +// Version 3), copied verbatim in the file "COPYING". |
| 4 | +// |
| 5 | +// See http://alice-o2.web.cern.ch/license for full licensing information. |
| 6 | +// |
| 7 | +// In applying this license CERN does not waive the privileges and immunities |
| 8 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 9 | +// or submit itself to any jurisdiction. |
| 10 | + |
| 11 | +/// \file SpaceCharge.h |
| 12 | +/// \brief Definition of the handler for the ALICE TPC space-charge distortions calculations |
| 13 | +/// \author Ernst Hellbär, Goethe-Universität Frankfurt, ernst.hellbar@cern.ch |
| 14 | + |
| 15 | +/* |
| 16 | + * TODO: |
| 17 | + * - fix constants (more precise values, export into TPCBase/Constants) |
| 18 | + * - pad granularity in r, rphi? |
| 19 | + * - accumulate and add next slice |
| 20 | + * - event based: propagate charge(ievent-1), add charge(ievent) |
| 21 | + * - time based: mTime0, mEffectiveTime |
| 22 | + * addIons(eventtime, drifttime, r, phi) |
| 23 | + * time in us, 50 kHz = <one event / 20 us> |
| 24 | + * if (ev.time+dr.time-mTime0 < mLengthTimebin) => add2NextSlice |
| 25 | + * if (mLengthTimebin < ev.time+dr.time-mTime0 < mLengthTimebin+100us) add2NextToNextSlice |
| 26 | + * - apply updated distortions to ions in NextToNextSlice when space charge is propagated; need to store exact positions (e.g. std::vector<std::vector<float>>)! |
| 27 | + * - ion transport along the E field -> Jacobi matrices? |
| 28 | + * - what about primary ionization? |
| 29 | + * - irregular bin sizes in r and rphi |
| 30 | + * - timebins or z bins? |
| 31 | + */ |
| 32 | + |
| 33 | +#ifndef ALICEO2_TPC_SPACECHARGE_H |
| 34 | +#define ALICEO2_TPC_SPACECHARGE_H |
| 35 | + |
| 36 | +#include <TMatrixT.h> |
| 37 | + |
| 38 | +#include "AliTPCSpaceCharge3DCalc.h" |
| 39 | +#include "DataFormatsTPC/Defs.h" |
| 40 | + |
| 41 | +class TH3; |
| 42 | +class TMatrixDfwd; |
| 43 | + |
| 44 | +class AliTPCLookUpTable3DInterpolatorD; |
| 45 | + |
| 46 | +namespace o2 |
| 47 | +{ |
| 48 | +namespace TPC |
| 49 | +{ |
| 50 | + |
| 51 | +class SpaceCharge |
| 52 | +{ |
| 53 | + public: |
| 54 | + /// Enumerator for setting the space-charge distortion mode |
| 55 | + enum SCDistortionType { |
| 56 | + SCDistortionsConstant = 0, // space-charge distortions constant over time |
| 57 | + SCDistortionsRealistic = 1 // realistic evolution of space-charge distortions over time |
| 58 | + }; |
| 59 | + |
| 60 | + // Constructors |
| 61 | + /// Default constructor using a grid size of (129 z bins, 180 phi bins, 129 r bins) |
| 62 | + SpaceCharge(); |
| 63 | + /// Constructor with grid size specified by user |
| 64 | + /// \param nZSlices number of grid points in z, must be (2**N)+1 |
| 65 | + /// \param nPhiBins number of grid points in phi |
| 66 | + /// \param nRBins number of grid points in r, must be (2**N)+1 |
| 67 | + SpaceCharge(int nZSlices, int nPhiBins, int nRBins); |
| 68 | + /// Constructor with grid size and interpolation order specified by user |
| 69 | + /// \param nZSlices number of grid points in z, must be (2**N)+1 |
| 70 | + /// \param nPhiBins number of grid points in phi |
| 71 | + /// \param nRBins number of grid points in r, must be (2**N)+1 |
| 72 | + /// \param interpolationOrder order used for interpolation of lookup tables |
| 73 | + SpaceCharge(int nZSlices, int nPhiBins, int nRBins, int interpolationOrder); |
| 74 | + |
| 75 | + // Destructor |
| 76 | + ~SpaceCharge() = default; |
| 77 | + |
| 78 | + /// Allocate memory for data members |
| 79 | + void allocateMemory(); |
| 80 | + |
| 81 | + /// Calculate lookup tables if initial space-charge density is provided |
| 82 | + void init(); |
| 83 | + |
| 84 | + /// Calculate distortion and correction lookup tables using AliTPCSpaceChargeCalc class |
| 85 | + void calculateLookupTables(); |
| 86 | + /// Update distortion and correction lookup tables by current space-charge density |
| 87 | + /// \param eventTime time of current event |
| 88 | + void updateLookupTables(float eventTime); |
| 89 | + |
| 90 | + /// Set omega*tau and T1, T2 tensor terms in Langevin-equation solution |
| 91 | + /// \param omegaTau omega*tau |
| 92 | + /// \param t1 T1 tensor term |
| 93 | + /// \param t2 T2 tensor term |
| 94 | + void setOmegaTauT1T2(float omegaTau, float t1, float t2); |
| 95 | + /// Set an initial space-charge density |
| 96 | + /// \param hisSCDensity 3D space-charge density histogram, expected format (phi,r,z) |
| 97 | + void setInitialSpaceChargeDensity(TH3* hisSCDensity); |
| 98 | + /// Add ions to space-charge density |
| 99 | + /// \param zPos z position |
| 100 | + /// \param phiPos phi position |
| 101 | + /// \param rPos radial position |
| 102 | + /// \param nIons number of ions |
| 103 | + void fillSCDensity(float zPos, float phiPos, float rPos, int nIons); |
| 104 | + /// Propagate space-charge density along electric field by one time slice |
| 105 | + void propagateSpaceCharge(); |
| 106 | + /// Drift ion along electric field by one time slice |
| 107 | + /// \param point 3D coordinates of the ion |
| 108 | + /// \return GlobalPosition3D with coordinates of drifted ion |
| 109 | + GlobalPosition3D driftIon(GlobalPosition3D& point); |
| 110 | + |
| 111 | + /// Correct electron position using correction lookup tables |
| 112 | + /// \param point 3D coordinates of the electron |
| 113 | + void correctElectron(GlobalPosition3D& point); |
| 114 | + /// Distort electron position using distortion lookup tables |
| 115 | + /// \param point 3D coordinates of the electron |
| 116 | + void distortElectron(GlobalPosition3D& point); |
| 117 | + |
| 118 | + /// Set the space-charge distortions model |
| 119 | + /// \param distortionType distortion type (constant or realistic) |
| 120 | + void setSCDistortionType(SCDistortionType distortionType) { mSCDistortionType = distortionType; } |
| 121 | + /// Get the space-charge distortions model |
| 122 | + SCDistortionType getSCDistortionType() const { return mSCDistortionType; } |
| 123 | + |
| 124 | + private: |
| 125 | + /// Convert amount of ions into charge density C/m^3 |
| 126 | + /// \param nIons number of ions |
| 127 | + /// \return space-charge density (C/m^3) |
| 128 | + float ions2Charge(int nIons); |
| 129 | + |
| 130 | + static constexpr float DvDEoverv0 = 0.0025; //! v'(E) / v0 = K / (K*E0) for ions, used in dz calculation |
| 131 | + static const float sEzField; //! nominal drift field |
| 132 | + |
| 133 | + static constexpr int MaxZSlices = 200; //! default number of z slices (1 ms slices) |
| 134 | + static constexpr int MaxPhiBins = 360; //! default number of phi bins |
| 135 | + static constexpr float DriftLength = 250.; //! drift length of the TPC in (cm) |
| 136 | + // ion mobility K = 3.0769231 cm^2/(Vs) in Ne-CO2 90-10 published by A. Deisting |
| 137 | + // v_drift = K * E = 3.0769231 cm^2/(Vs) * 400 V/cm = 1230.7692 cm/s |
| 138 | + // t_drift = 250 cm / v_drift = 203 ms |
| 139 | + static constexpr float IonDriftTime = 2.03e5; //! drift time of ions for one full drift (us) |
| 140 | + static constexpr float RadiusInner = 85.; //! inner radius of the TPC active area |
| 141 | + static constexpr float RadiusOuter = 245.; //! outer radius of the TPC active area |
| 142 | + |
| 143 | + const int mInterpolationOrder; ///< order for interpolation of lookup tables: 2==quadratic, >2==cubic spline |
| 144 | + |
| 145 | + const int mNZSlices; ///< number of z slices used in lookup tables |
| 146 | + const int mNPhiBins; ///< number of phi bins used in lookup tables |
| 147 | + const int mNRBins; ///< number of r bins used in lookup tables |
| 148 | + const float mLengthZSlice; ///< length of one z bin (cm) |
| 149 | + const float mLengthTimeSlice; ///< ion drift time for one z slice (us) |
| 150 | + const float mWidthPhiBin; ///< width of one phi bin (radians) |
| 151 | + const float mLengthRBin; ///< length of one r bin (cm) |
| 152 | + |
| 153 | + std::vector<double> mCoordZ; ///< vector wiht coodinates of the z bins |
| 154 | + std::vector<double> mCoordPhi; ///< vector wiht coodinates of the phi bins |
| 155 | + std::vector<double> mCoordR; ///< vector wiht coodinates of the r bins |
| 156 | + |
| 157 | + bool mUseInitialSCDensity; ///< Flag for the use of an initial space-charge density at the beginning of the simulation |
| 158 | + bool mInitLookUpTables; ///< Flag to indicate if lookup tables have been calculated |
| 159 | + float mTimeInit; ///< time of last update of lookup tables |
| 160 | + SCDistortionType mSCDistortionType; ///< Type of space-charge distortions |
| 161 | + |
| 162 | + AliTPCSpaceCharge3DCalc mLookUpTableCalculator; ///< object to calculate and store correction and distortion lookup tables |
| 163 | + |
| 164 | + /// TODO: check fastest way to order std::vectors |
| 165 | + std::vector<std::vector<float>> mSpaceChargeDensityA; ///< space-charge density on the A side, stored in C/m^3 (z)(phi*r), ordering: z=[0,250], ir+iphi*nRBins |
| 166 | + std::vector<std::vector<float>> mSpaceChargeDensityC; ///< space-charge density on the C side, stored in C/m^3 (z)(phi*r), ordering: z=[0,-250], ir+iphi*nRBins |
| 167 | + |
| 168 | + /// TODO: Eliminate the need for these matrices as members, they will be owned by AliTPCLookUpTable3DInterpolatorD. AliTPCLookUpTable3DInterpolatorD needs getters for the matrices and the constructor has to be modified. |
| 169 | + TMatrixD** mMatrixLocalIonDriftDzA; ///< matrix to store local ion drift in z direction along E field on A side |
| 170 | + TMatrixD** mMatrixLocalIonDriftDzC; ///< matrix to store local ion drift in z direction along E field on A side |
| 171 | + TMatrixD** mMatrixLocalIonDriftDrphiA; ///< matrix to store local ion drift in rphi direction along E field on A side |
| 172 | + TMatrixD** mMatrixLocalIonDriftDrphiC; ///< matrix to store local ion drift in rphi direction along E field on A side |
| 173 | + TMatrixD** mMatrixLocalIonDriftDrA; ///< matrix to store local ion drift in radial direction along E field on A side |
| 174 | + TMatrixD** mMatrixLocalIonDriftDrC; ///< matrix to store local ion drift in radial direction along E field on C side |
| 175 | + std::unique_ptr<AliTPCLookUpTable3DInterpolatorD> mLookUpLocalIonDriftA; ///< lookup table for local ion drift along E field on A side |
| 176 | + std::unique_ptr<AliTPCLookUpTable3DInterpolatorD> mLookUpLocalIonDriftC; ///< lookup table for local ion drift along E field on C side |
| 177 | +}; |
| 178 | + |
| 179 | +} // namespace TPC |
| 180 | +} // namespace o2 |
| 181 | + |
| 182 | +#endif // ALICEO2_TPC_SPACECHARGE_H |
0 commit comments