From b5241d619651063d77ca8ea96bf7ba72b756f67a Mon Sep 17 00:00:00 2001 From: schutz Date: Wed, 4 Apr 2001 13:08:03 +0000 Subject: [PATCH] new design:derived from AliPHOSEmcRecPoint. methods promoted to parent --- PHOS/AliPHOSCpvRecPoint.cxx | 483 +++++++++--------------------------- PHOS/AliPHOSCpvRecPoint.h | 48 ++-- 2 files changed, 136 insertions(+), 395 deletions(-) diff --git a/PHOS/AliPHOSCpvRecPoint.cxx b/PHOS/AliPHOSCpvRecPoint.cxx index 65c5e6b9ae6..7c10e0833c7 100644 --- a/PHOS/AliPHOSCpvRecPoint.cxx +++ b/PHOS/AliPHOSCpvRecPoint.cxx @@ -27,6 +27,7 @@ #include "TH2.h" #include "TMath.h" #include "TCanvas.h" +#include "TClonesArray.h" // --- Standard library --- @@ -34,28 +35,16 @@ // --- AliRoot header files --- -#include "AliPHOSGeometry.h" #include "AliPHOSCpvRecPoint.h" #include "AliPHOSPpsdRecPoint.h" -#include "AliRun.h" -#include "AliPHOSIndexToObject.h" ClassImp(AliPHOSCpvRecPoint) //____________________________________________________________________________ -AliPHOSCpvRecPoint::AliPHOSCpvRecPoint(Float_t W0, Float_t LocMaxCut) - : AliPHOSRecPoint() +AliPHOSCpvRecPoint::AliPHOSCpvRecPoint() : AliPHOSEmcRecPoint() { // ctor - fMulDigit = 0 ; - fAmp = 0. ; - fEnergyList = new Float_t[fMaxDigit]; - AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; - fDelta = phosgeom->GetCrystalSize(0) ; - fW0 = W0 ; - fLocMaxCut = LocMaxCut ; - fLocPos.SetX(1000000.) ; //Local position should be evaluated fLengX = -1; fLengZ = -1; } @@ -64,46 +53,8 @@ AliPHOSCpvRecPoint::AliPHOSCpvRecPoint(Float_t W0, Float_t LocMaxCut) AliPHOSCpvRecPoint::~AliPHOSCpvRecPoint() { // dtor - if ( fEnergyList ) delete[] fEnergyList ; } -//____________________________________________________________________________ -void AliPHOSCpvRecPoint::AddDigit(AliPHOSDigit & digit, Float_t Energy) -{ - // Adds a digit to the RecPoint - // and accumulates the total amplitude and the multiplicity - - if ( fMulDigit >= fMaxDigit ) { // increase the size of the lists - fMaxDigit*=2 ; - Int_t * tempo = new ( Int_t[fMaxDigit] ) ; - Float_t * tempoE = new ( Float_t[fMaxDigit] ) ; - - Int_t index ; - for ( index = 0 ; index < fMulDigit ; index++ ){ - tempo[index] = fDigitsList[index] ; - tempoE[index] = fEnergyList[index] ; - } - - delete [] fDigitsList ; - fDigitsList = new ( Int_t[fMaxDigit] ) ; - - delete [] fEnergyList ; - fEnergyList = new ( Float_t[fMaxDigit] ) ; - - for ( index = 0 ; index < fMulDigit ; index++ ){ - fDigitsList[index] = tempo[index] ; - fEnergyList[index] = tempoE[index] ; - } - - delete [] tempo ; - delete [] tempoE ; - } // if - - fDigitsList[fMulDigit] = digit.GetIndexInList() ; - fEnergyList[fMulDigit] = Energy ; - fMulDigit++ ; - fAmp += Energy ; -} //____________________________________________________________________________ Bool_t AliPHOSCpvRecPoint::AreNeighbours(AliPHOSDigit * digit1, AliPHOSDigit * digit2 ) const @@ -133,6 +84,10 @@ Int_t AliPHOSCpvRecPoint::Compare(const TObject * obj) const { // Compares two RecPoints according to their position in the PHOS modules + Float_t delta = 1 ; //Width of "Sorting row". If you changibg this + //value (what is senseless) change as vell delta in + //AliPHOSTrackSegmentMakerv* and other RecPoints... + Int_t rv ; if( (strcmp(obj->ClassName() , "AliPHOSPpsdRecPoint" )) == 0) // PPSD Rec Point @@ -148,20 +103,20 @@ Int_t AliPHOSCpvRecPoint::Compare(const TObject * obj) const { AliPHOSCpvRecPoint * clu = (AliPHOSCpvRecPoint *) obj ; - Int_t phosmod1 = this->GetPHOSMod() ; + Int_t phosmod1 = GetPHOSMod() ; Int_t phosmod2 = clu->GetPHOSMod() ; TVector3 locpos1; - this->GetLocalPosition(locpos1) ; + GetLocalPosition(locpos1) ; TVector3 locpos2; clu->GetLocalPosition(locpos2) ; if(phosmod1 == phosmod2 ) { - Int_t rowdif = (Int_t)TMath::Ceil(locpos1.X()/fDelta)-(Int_t)TMath::Ceil(locpos2.X()/fDelta) ; + Int_t rowdif = (Int_t)TMath::Ceil(locpos1.X()/delta)-(Int_t)TMath::Ceil(locpos2.X()/delta) ; if (rowdif> 0) - rv = -1 ; - else if(rowdif < 0) rv = 1 ; + else if(rowdif < 0) + rv = -1 ; else if(locpos1.Z()>locpos2.Z()) rv = -1 ; else @@ -182,123 +137,121 @@ Int_t AliPHOSCpvRecPoint::Compare(const TObject * obj) const //______________________________________________________________________________ void AliPHOSCpvRecPoint::ExecuteEvent(Int_t event, Int_t px, Int_t py) { - // Execute action corresponding to one event - // This member function is called when a AliPHOSRecPoint is clicked with the locator - // - // If Left button is clicked on AliPHOSRecPoint, the digits are switched on - // and switched off when the mouse button is released. - // +// // Execute action corresponding to one event +// // This member function is called when a AliPHOSRecPoint is clicked with the locator +// // +// // If Left button is clicked on AliPHOSRecPoint, the digits are switched on +// // and switched off when the mouse button is released. +// // - // static Int_t pxold, pyold; +// // static Int_t pxold, pyold; - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; +// AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - static TGraph * digitgraph = 0 ; +// static TGraph * digitgraph = 0 ; - if (!gPad->IsEditable()) return; +// if (!gPad->IsEditable()) return; - TH2F * histo = 0 ; - TCanvas * histocanvas ; +// TH2F * histo = 0 ; +// TCanvas * histocanvas ; - switch (event) { +// switch (event) { - case kButton1Down: { - AliPHOSDigit * digit ; - AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; - Int_t iDigit; - Int_t relid[4] ; +// case kButton1Down: { +// AliPHOSDigit * digit ; +// AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; +// Int_t iDigit; +// Int_t relid[4] ; - const Int_t kMulDigit = AliPHOSCpvRecPoint::GetDigitsMultiplicity() ; - Float_t * xi = new Float_t[kMulDigit] ; - Float_t * zi = new Float_t[kMulDigit] ; +// const Int_t kMulDigit = AliPHOSCpvRecPoint::GetDigitsMultiplicity() ; +// Float_t * xi = new Float_t[kMulDigit] ; +// Float_t * zi = new Float_t[kMulDigit] ; - // create the histogram for the single cluster - // 1. gets histogram boundaries - Float_t ximax = -999. ; - Float_t zimax = -999. ; - Float_t ximin = 999. ; - Float_t zimin = 999. ; +// // create the histogram for the single cluster +// // 1. gets histogram boundaries +// Float_t ximax = -999. ; +// Float_t zimax = -999. ; +// Float_t ximin = 999. ; +// Float_t zimin = 999. ; - for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ) ; - phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; - phosgeom->RelPosInModule(relid, xi[iDigit], zi[iDigit]); - if ( xi[iDigit] > ximax ) - ximax = xi[iDigit] ; - if ( xi[iDigit] < ximin ) - ximin = xi[iDigit] ; - if ( zi[iDigit] > zimax ) - zimax = zi[iDigit] ; - if ( zi[iDigit] < zimin ) - zimin = zi[iDigit] ; - } - ximax += phosgeom->GetCrystalSize(0) / 2. ; - zimax += phosgeom->GetCrystalSize(2) / 2. ; - ximin -= phosgeom->GetCrystalSize(0) / 2. ; - zimin -= phosgeom->GetCrystalSize(2) / 2. ; - Int_t xdim = (int)( (ximax - ximin ) / phosgeom->GetCrystalSize(0) + 0.5 ) ; - Int_t zdim = (int)( (zimax - zimin ) / phosgeom->GetCrystalSize(2) + 0.5 ) ; +// for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ) ; +// phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; +// phosgeom->RelPosInModule(relid, xi[iDigit], zi[iDigit]); +// if ( xi[iDigit] > ximax ) +// ximax = xi[iDigit] ; +// if ( xi[iDigit] < ximin ) +// ximin = xi[iDigit] ; +// if ( zi[iDigit] > zimax ) +// zimax = zi[iDigit] ; +// if ( zi[iDigit] < zimin ) +// zimin = zi[iDigit] ; +// } +// ximax += phosgeom->GetCrystalSize(0) / 2. ; +// zimax += phosgeom->GetCrystalSize(2) / 2. ; +// ximin -= phosgeom->GetCrystalSize(0) / 2. ; +// zimin -= phosgeom->GetCrystalSize(2) / 2. ; +// Int_t xdim = (int)( (ximax - ximin ) / phosgeom->GetCrystalSize(0) + 0.5 ) ; +// Int_t zdim = (int)( (zimax - zimin ) / phosgeom->GetCrystalSize(2) + 0.5 ) ; - // 2. gets the histogram title +// // 2. gets the histogram title - Text_t title[100] ; - sprintf(title,"Energy=%1.2f GeV ; Digits ; %d ", GetEnergy(), GetDigitsMultiplicity()) ; +// Text_t title[100] ; +// sprintf(title,"Energy=%1.2f GeV ; Digits ; %d ", GetEnergy(), GetDigitsMultiplicity()) ; - if (!histo) { - delete histo ; - histo = 0 ; - } - histo = new TH2F("cluster3D", title, xdim, ximin, ximax, zdim, zimin, zimax) ; +// if (!histo) { +// delete histo ; +// histo = 0 ; +// } +// histo = new TH2F("cluster3D", title, xdim, ximin, ximax, zdim, zimin, zimax) ; - Float_t x, z ; - for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ) ; - phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; - phosgeom->RelPosInModule(relid, x, z); - histo->Fill(x, z, fEnergyList[iDigit] ) ; - } +// Float_t x, z ; +// for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ) ; +// phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; +// phosgeom->RelPosInModule(relid, x, z); +// histo->Fill(x, z, fEnergyList[iDigit] ) ; +// } - if (!digitgraph) { - digitgraph = new TGraph(kMulDigit,xi,zi); - digitgraph-> SetMarkerStyle(5) ; - digitgraph-> SetMarkerSize(1.) ; - digitgraph-> SetMarkerColor(1) ; - digitgraph-> Paint("P") ; - } +// if (!digitgraph) { +// digitgraph = new TGraph(kMulDigit,xi,zi); +// digitgraph-> SetMarkerStyle(5) ; +// digitgraph-> SetMarkerSize(1.) ; +// digitgraph-> SetMarkerColor(1) ; +// digitgraph-> Paint("P") ; +// } - Print() ; - histocanvas = new TCanvas("cluser", "a single cluster", 600, 500) ; - histocanvas->Draw() ; - histo->Draw("lego1") ; +// Print() ; +// histocanvas = new TCanvas("cluser", "a single cluster", 600, 500) ; +// histocanvas->Draw() ; +// histo->Draw("lego1") ; - delete[] xi ; - delete[] zi ; +// delete[] xi ; +// delete[] zi ; - break; - } +// break; +// } - case kButton1Up: - if (digitgraph) { - delete digitgraph ; - digitgraph = 0 ; - } - break; +// case kButton1Up: +// if (digitgraph) { +// delete digitgraph ; +// digitgraph = 0 ; +// } +// break; - } +// } } //____________________________________________________________________________ -void AliPHOSCpvRecPoint::EvalAll(){ - AliPHOSRecPoint::EvalAll() ; - EvalLocalPosition() ; +void AliPHOSCpvRecPoint::EvalAll(Float_t logWeight,TClonesArray * digits){ + AliPHOSEmcRecPoint::EvalAll(logWeight,digits) ; + EvalClusterLengths(digits) ; } //____________________________________________________________________________ -void AliPHOSCpvRecPoint::EvalLocalPosition() +void AliPHOSCpvRecPoint::EvalLocalPosition(Float_t logWeight,TClonesArray * digits) { // Calculates the center of gravity in the local PHOS-module coordinates - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - Float_t wtot = 0. ; Int_t relid[4] ; @@ -313,13 +266,13 @@ void AliPHOSCpvRecPoint::EvalLocalPosition() Int_t iDigit; for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ); + digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]); Float_t xi ; Float_t zi ; phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; phosgeom->RelPosInModule(relid, xi, zi); - Float_t w = TMath::Max( 0., fW0 + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ; + Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ; x += xi * w ; z += zi * w ; wtot += w ; @@ -341,111 +294,15 @@ void AliPHOSCpvRecPoint::EvalLocalPosition() } //____________________________________________________________________________ -Float_t AliPHOSCpvRecPoint::GetDispersion() const +void AliPHOSCpvRecPoint::EvalClusterLengths(TClonesArray * digits) { - // Calculates the dispersion of the shower at the origine of the RecPoint - - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - - Float_t d = 0 ; - Float_t wtot = 0 ; - - TVector3 locpos; - GetLocalPosition(locpos); - Float_t x = locpos.X() ; - Float_t z = locpos.Z() ; - - AliPHOSDigit * digit ; - AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; + //Modified 15.03.2001 by Dmitri Peressounko - Int_t iDigit; - for(iDigit=0; iDigit < fMulDigit; iDigit++) { - digit = (AliPHOSDigit *) ( please->GimeDigit(fDigitsList[iDigit]) ) ; - Int_t relid[4] ; - Float_t xi ; - Float_t zi ; - phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; - phosgeom->RelPosInModule(relid, xi, zi); - Float_t w = TMath::Max(0.,fW0+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ; - d += w*((xi-x)*(xi-x) + (zi-z)*(zi-z) ) ; - wtot+=w ; - } - - d /= wtot ; - - return TMath::Sqrt(d) ; -} - -//____________________________________________________________________________ -void AliPHOSCpvRecPoint::GetElipsAxis(Float_t * lambda) const -{ - // Calculates the axis of the shower ellipsoid - - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - - Float_t wtot = 0. ; - Float_t x = 0.; - Float_t z = 0.; - Float_t dxx = 0.; - Float_t dzz = 0.; - Float_t dxz = 0.; - - AliPHOSDigit * digit ; - AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; - Int_t iDigit; - - for(iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ) ; - Int_t relid[4] ; - Float_t xi ; - Float_t zi ; - phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; - phosgeom->RelPosInModule(relid, xi, zi); - Float_t w = TMath::Max(0.,fW0+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ; - dxx += w * xi * xi ; - x += w * xi ; - dzz += w * zi * zi ; - z += w * zi ; - dxz += w * xi * zi ; - wtot += w ; - } - - dxx /= wtot ; - x /= wtot ; - dxx -= x * x ; - dzz /= wtot ; - z /= wtot ; - dzz -= z * z ; - dxz /= wtot ; - dxz -= x * z ; - - Float_t tmp0 = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ); - Float_t tmp1 = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ); - if (tmp0>=0) lambda[0] = TMath::Sqrt(tmp0); - else lambda[0] = -TMath::Sqrt(-tmp0); - if (tmp1>=0) lambda[1] = TMath::Sqrt(tmp1); - else lambda[1] = -TMath::Sqrt(-tmp1); -// lambda[0] = TMath::Sqrt( 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ) ; -// lambda[1] = TMath::Sqrt( 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ) ; -} - - -//____________________________________________________________________________ -void AliPHOSCpvRecPoint::GetClusterLengths(Int_t &lengX, Int_t &lengZ) -{ // Calculates the cluster lengths along X and Z axes // These characteristics are needed for CPV to tune // digitization+reconstruction to experimental data // Yuri Kharlov. 24 October 2000 - if( fLengX != -1 && fLengZ != -1 ) { // already evaluated - lengX = fLengX ; - lengZ = fLengZ ; - return ; - } - - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - Int_t relid[4] ; AliPHOSDigit * digit ; @@ -454,122 +311,34 @@ void AliPHOSCpvRecPoint::GetClusterLengths(Int_t &lengX, Int_t &lengZ) const Int_t kMaxLeng=20; Int_t idX[kMaxLeng], idZ[kMaxLeng]; - lengX = 0; - lengZ = 0; + fLengX = 0; + fLengZ = 0; Bool_t dejavu; for(Int_t iDigit=0; iDigitGimeDigit(fDigitsList[iDigit]) ); + digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ; Int_t absId = digit->GetId(); phosgeom->AbsToRelNumbering(absId, relid) ; Int_t i; dejavu=kFALSE; - for (i=0; i menergy) - menergy = fEnergyList[iDigit] ; - } - return menergy ; -} - -//____________________________________________________________________________ -Int_t AliPHOSCpvRecPoint::GetMultiplicityAtLevel(const Float_t H) const -{ - // Calculates the multiplicity of digits with energy larger than H*energy - - Int_t multipl = 0 ; - Int_t iDigit ; - for(iDigit=0; iDigit H * fAmp) - multipl++ ; - } - return multipl ; } -//____________________________________________________________________________ -Int_t AliPHOSCpvRecPoint::GetNumberOfLocalMax(Int_t * maxAt, Float_t * maxAtEnergy) const -{ - // Calculates the number of local maxima in the cluster using fLocalMaxCut as the minimum - // energy difference between two local maxima - - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; - - AliPHOSDigit * digit ; - AliPHOSDigit * digitN ; - - - Int_t iDigitN ; - Int_t iDigit ; - - for(iDigit = 0; iDigit < fMulDigit; iDigit++){ - maxAt[iDigit] = (Int_t) ( please->GimeDigit(fDigitsList[iDigit]) ) ; - } - - for(iDigit = 0 ; iDigit < fMulDigit; iDigit++) { - if(maxAt[iDigit] != -1) { - digit = (AliPHOSDigit *) maxAt[iDigit] ; - - for(iDigitN = 0; iDigitN < fMulDigit; iDigitN++) { - digitN = (AliPHOSDigit *) ( please->GimeDigit(fDigitsList[iDigitN]) ) ; - - if ( AreNeighbours(digit, digitN) ) { - if (fEnergyList[iDigit] > fEnergyList[iDigitN] ) { - maxAt[iDigitN] = -1 ; - // but may be digit too is not local max ? - if(fEnergyList[iDigit] < fEnergyList[iDigitN] + fLocMaxCut) - maxAt[iDigit] = -1 ; - } - else { - maxAt[iDigit] = -1 ; - // but may be digitN too is not local max ? - if(fEnergyList[iDigit] > fEnergyList[iDigitN] - fLocMaxCut) - maxAt[iDigitN] = -1 ; - } - } // if Areneighbours - } // while digitN - } // slot not empty - } // while digit - - iDigitN = 0 ; - for(iDigit = 0; iDigit < fMulDigit; iDigit++) { - if(maxAt[iDigit] != -1){ - maxAt[iDigitN] = maxAt[iDigit] ; - maxAtEnergy[iDigitN] = fEnergyList[iDigit] ; - iDigitN++ ; - } - } - return iDigitN ; -} //____________________________________________________________________________ @@ -579,26 +348,18 @@ void AliPHOSCpvRecPoint::Print(Option_t * option) cout << "AliPHOSCpvRecPoint: " << endl ; - AliPHOSDigit * digit ; Int_t iDigit; - AliPHOSGeometry * phosgeom = (AliPHOSGeometry *) fGeom ; - Float_t xi ; - Float_t zi ; - Int_t relid[4] ; - - AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ; + cout << "Digits # " ; + for(iDigit=0; iDigitGimeDigit( fDigitsList[iDigit] ) ; - phosgeom->AbsToRelNumbering(digit->GetId(), relid) ; - phosgeom->RelPosInModule(relid, xi, zi); - cout << " Id = " << digit->GetId() ; - cout << " module = " << relid[0] ; - cout << " x = " << xi ; - cout << " z = " << zi ; - cout << " Energy = " << fEnergyList[iDigit] << endl ; - } + cout << "Energies: " ; + for(iDigit=0; iDigitGetNCPVModules()) ; } + + void GetClusterLengths(Int_t &lengX, Int_t &lengZ){lengX = fLengX ;lengZ = fLengZ ;} + Bool_t IsEmc(void) const {return kFALSE ; } // tells that this is not a EMC + Bool_t IsCPV(void) const {return (fPHOSMod <= ((AliPHOSGeometry*) fGeom)->GetNCPVModules()) ; } // true if the recpoint is in CPV - Bool_t IsSortable() const { return kTRUE ; } // says that emcrecpoints are sortable objects + Bool_t IsSortable() const { return kTRUE ; } // tells that this is a sortable object void Print(Option_t * opt = "void") ; AliPHOSCpvRecPoint & operator = (const AliPHOSCpvRecPoint & rvalue) { @@ -72,14 +56,10 @@ public: return *this ; } - private: + protected: Bool_t AreNeighbours(AliPHOSDigit * digit1, AliPHOSDigit * digit2 ) const ; - Float_t fDelta ; // parameter used to sort the clusters - Float_t *fEnergyList ; //[fMulDigit] energy of digits - Float_t fLocMaxCut ; // minimum energy difference to distinguish two maxima - Float_t fW0 ; // logarithmic weight factor for center of gravity calculation Int_t fLengX ; // cluster length along x Int_t fLengZ ; // cluster length along z -- 2.43.0