From 94c27e4f47530d402298eb5bd27198e4392342ff Mon Sep 17 00:00:00 2001 From: alla Date: Thu, 3 May 2007 13:48:13 +0000 Subject: [PATCH] all time measurements perfomed as difference with case vertex=0 --- T0/AliT0CalibData.cxx | 33 ++++++--- T0/AliT0CalibData.h | 13 ++-- T0/AliT0Digitizer.cxx | 5 +- T0/AliT0Parameters.cxx | 31 ++++++--- T0/AliT0Parameters.h | 10 ++- T0/AliT0RawData.cxx | 2 +- T0/AliT0RawReader.cxx | 6 +- T0/AliT0Reconstructor.cxx | 92 +++++++++++++++----------- T0/Calib/TimeDelay/Run0_10_v0_s0.root | Bin 1661 -> 2898 bytes 9 files changed, 122 insertions(+), 70 deletions(-) diff --git a/T0/AliT0CalibData.cxx b/T0/AliT0CalibData.cxx index 815f417999e..5e03f2b60ef 100644 --- a/T0/AliT0CalibData.cxx +++ b/T0/AliT0CalibData.cxx @@ -48,7 +48,14 @@ ClassImp(AliT0CalibData) } //________________________________________________________________ -AliT0CalibData::AliT0CalibData(const char* name):TNamed(),fTimeDelayTVD(0),fWalk(),fSlewingLED(),fSlewingRec() +AliT0CalibData::AliT0CalibData(const char* name):TNamed(), + fTimeDelayTVD(0), + fMeanT0(0), + fWalk(0), + fSlewingLED(0), + fSlewingRec(0), + fLookup(0), + fNumberOfTRMs(0) { TString namst = "Calib_"; namst += name; @@ -59,7 +66,15 @@ AliT0CalibData::AliT0CalibData(const char* name):TNamed(),fTimeDelayTVD(0),fWalk //________________________________________________________________ AliT0CalibData::AliT0CalibData(const AliT0CalibData& calibda) : - TNamed(calibda),fTimeDelayTVD(0),fWalk(),fSlewingLED(),fSlewingRec() + TNamed(calibda), + fTimeDelayTVD(0), + fMeanT0(0), + fWalk(0), + fSlewingLED(0), + fSlewingRec(0), + fLookup(0), + fNumberOfTRMs(0) + { // copy constructor SetName(calibda.GetName()); @@ -87,7 +102,7 @@ AliT0CalibData::~AliT0CalibData() void AliT0CalibData::Reset() { memset(fTimeDelayCFD,1,24*sizeof(Float_t)); - memset(fTimeDelayLED,1,24*sizeof(Float_t)); + memset(fTimeDelayDA,1,24*sizeof(Float_t)); } @@ -96,8 +111,8 @@ void AliT0CalibData::Print(Option_t*) const { printf("\n ---- PM Arrays ----\n\n"); - printf(" Time delay CFD & LED\n"); - for (Int_t i=0; i<24; i++) printf(" CFD %f LED %f ",fTimeDelayCFD[i], fTimeDelayLED[i]); + printf(" Time delay CFD & DA\n"); + for (Int_t i=0; i<24; i++) printf(" CFD %f DA %f ",fTimeDelayCFD[i], fTimeDelayDA[i]); } //________________________________________________________________ @@ -117,7 +132,7 @@ void AliT0CalibData::PrintLookup(Option_t*, Int_t iTRM, Int_t iTDC, Int_t iChan printf(" AliT0CalibData::PrintLookup ::start GetValue %i %i %i \n",iTRM, iTDC, iChannel); lookkey = (AliT0LookUpKey*) fLookup.GetValue((TObject*)lookvalue); - cout<<" AliT0CalibData::PrintLookup :: lookkey "<< lookkey<GetKey()<<" VALUE "<GetTRM()<<" " @@ -135,9 +150,9 @@ void AliT0CalibData::SetTimeDelayCFD(Float_t* TimeDelay) if(TimeDelay) for(int t=0; t<24; t++) fTimeDelayCFD[t] = TimeDelay[t]; } //________________________________________________________________ - void AliT0CalibData::SetTimeDelayLED(Float_t* TimeDelay) + void AliT0CalibData::SetTimeDelayDA(Float_t* TimeDelay) { - if(TimeDelay) for(int t=0; t<24; t++) fTimeDelayLED[t] = TimeDelay[t]; + if(TimeDelay) for(int t=0; t<24; t++) fTimeDelayDA[t] = TimeDelay[t]; } @@ -175,7 +190,6 @@ void AliT0CalibData::SetWalk(Int_t ipmt) { sum +=x[ind]; iin++; - // cout<GetTimeDelayTVD(); for (Int_t i=0; i<24; i++){ timeDelayCFD[i] = param->GetTimeDelayCFD(i); - timeDelayLED[i] = param->GetTimeDelayLED(i); TGraph* gr = param ->GetSlew(i); slewingLED.AddAtAndExpand(gr,i); @@ -295,9 +294,9 @@ void AliT0Digitizer::Exec(Option_t* /*option*/) qt= 50.*al/ph2Mip; // 50mv/Mip amp in mV // fill TDC trCFD = Int_t (timeGaus[i]/channelWidth + (timeDelayCFD[i]-timeDelayCFD[0])); - trLED= Int_t (timeGaus[i] + timeDelayLED[i]); + // trLED= Int_t (timeGaus[i] + timeDelayLED[i]); sl = ((TGraph*)slewingLED.At(i))->Eval(qt); - trLED = Int_t(( trLED + 1000*sl )/channelWidth); + trLED = Int_t(( timeGaus[i] + 1000*sl )/channelWidth); qtCh=Int_t (1000.*TMath::Log(qt)) / channelWidth; fADC0->AddAt(0,i); fADC->AddAt(qtCh,i); diff --git a/T0/AliT0Parameters.cxx b/T0/AliT0Parameters.cxx index 78353dd58e4..082267f34ec 100644 --- a/T0/AliT0Parameters.cxx +++ b/T0/AliT0Parameters.cxx @@ -68,8 +68,10 @@ AliT0Parameters::AliT0Parameters() fQTmin(0),fQTmax(0), fSlewingLED(),fSlewingRec(), fPMTeff(), - fTimeDelayLED(0),fTimeDelayCFD(0),fTimeDelayTVD(0), - fCalibentry(), fLookUpentry(),fSlewCorr() + fTimeDelayDA(0),fTimeDelayCFD(0),fTimeDelayTVD(0),fMeanT0(0), + fCalibentry(), fLookUpentry(),fSlewCorr(), + fLookUp(0), fNumberOfTRMs(0) + { // Default constructor @@ -99,8 +101,8 @@ AliT0Parameters::Init() { // Initialize the parameters manager. We need to get stuff from the // CDB here. - // if (fIsInit) return; - + + if (fIsInit) return; AliCDBStorage *stor =AliCDBManager::Instance()->GetStorage("local://$ALICE_ROOT"); //time equalizing @@ -130,15 +132,15 @@ AliT0Parameters::Init() //__________________________________________________________________ Float_t -AliT0Parameters::GetTimeDelayLED(Int_t ipmt) +AliT0Parameters::GetTimeDelayDA(Int_t ipmt) { // return time delay for LED channel // if (!fCalibentry) { - fTimeDelayLED = 0; - return fTimeDelayLED; + fTimeDelayDA = 0; + return fTimeDelayDA; } - return fgCalibData ->GetTimeDelayLED(ipmt); + return fgCalibData ->GetTimeDelayDA(ipmt); } //__________________________________________________________________ Float_t @@ -155,6 +157,19 @@ AliT0Parameters::GetTimeDelayCFD(Int_t ipmt) return fgCalibData->GetTimeDelayCFD(ipmt); } +//__________________________________________________________________ +Int_t +AliT0Parameters::GetMeanT0() +{ + // return mean of T0 distrubution with vertex=0 + // + if (!fCalibentry) + { + return fMeanT0; + } + + return fgCalibData->GetMeanT0(); +} //__________________________________________________________________ void diff --git a/T0/AliT0Parameters.h b/T0/AliT0Parameters.h index 6c94bc8dc21..2d5bba775f9 100644 --- a/T0/AliT0Parameters.h +++ b/T0/AliT0Parameters.h @@ -76,7 +76,10 @@ public: void SetWalk(Int_t ipmt) ; Float_t GetTimeDelayCFD(Int_t ipmt); - Float_t GetTimeDelayLED(Int_t ipmt); + Float_t GetTimeDelayDA(Int_t ipmt); + + void SetMeanT0(Int_t mean=500) { fMeanT0 = mean; }; + Int_t GetMeanT0 (); //{return fMeanT0;}; // TMap *LookupTable; @@ -103,10 +106,11 @@ protected: TObjArray fPMTeff; //array PMT registration efficiency TObjArray fWalk; //array time-amplitude walk - Float_t fTimeDelayLED; // sum time delay for LED channel + Float_t fTimeDelayDA; // sum time delay for LED channel Float_t fTimeDelayCFD; // sum time delay for CFD channel Float_t fTimeDelayTVD; //time delay for TVD (vertex trigger channel) - + Int_t fMeanT0; //mean of T0distribution with vertex=0; + TMap fLookUp; //lookup table Int_t fNumberOfTRMs; // number of TRMs in setup diff --git a/T0/AliT0RawData.cxx b/T0/AliT0RawData.cxx index fb1604b0d7a..b33021d9c9e 100644 --- a/T0/AliT0RawData.cxx +++ b/T0/AliT0RawData.cxx @@ -540,7 +540,7 @@ Int_t AliT0RawData::RawDataT0(AliT0digit *fDigits) fIndex=-1; - AliRawDataHeaderSim header; + WriteDataHeader(kTRUE, kFALSE); GetDigits(fDigits); //write packing digits diff --git a/T0/AliT0RawReader.cxx b/T0/AliT0RawReader.cxx index 98c80505847..266018b8ab0 100644 --- a/T0/AliT0RawReader.cxx +++ b/T0/AliT0RawReader.cxx @@ -84,6 +84,8 @@ Bool_t AliT0RawReader::Next() Int_t TRM_CHAIN_0_TRAILER = 0x10000000; Int_t TRM_CHAIN_1_TRAILER = 0x30000000; Int_t TRM_GLOBAL_TRAILER = 0x5000000f; + + Int_t FILLER = 0x70000000; AliT0Parameters* param = AliT0Parameters::Instance(); @@ -189,8 +191,10 @@ Bool_t AliT0RawReader::Next() AliError(Form(" !!!! wrong TRM GLOBAL trailer %x!!!!", word)); break; } - } //TRM loop + } //TRM loop end + word = GetNextWord(); // + if (word == FILLER ) {cout<< "FIILER "<Init(); AliT0Calibrator *calib=new AliT0Calibrator(); - Int_t mV2Mip = param->GetmV2Mip(); + // Int_t mV2Mip = param->GetmV2Mip(); //mV2Mip = param->GetmV2Mip(); Int_t channelWidth = param->GetChannelWidth() ; + Int_t meanT0 = param->GetMeanT0(); for (Int_t i=0; i<24; i++){ TGraph* gr = param ->GetSlewRec(i); slewingLEDrec.AddAtAndExpand(gr,i) ; + time0vertex[i]= param->GetTimeDelayDA(i); } - zdetC = param->GetZPosition("C"); - zdetA = param->GetZPosition("A"); - + AliDebug(1,Form("Start DIGITS reconstruction ")); - + TBranch *brDigits=digitsTree->GetBranch("T0"); AliT0digit *fDigits = new AliT0digit() ; if (brDigits) { @@ -140,21 +139,22 @@ void AliT0Reconstructor::Reconstruct(TTree*digitsTree, TTree*clustersTree) const - AliT0RecPoint* frecpoints= new AliT0RecPoint (); - clustersTree->Branch( "T0", "AliT0RecPoint" ,&frecpoints, 405,1); - + AliT0RecPoint* frecpoints= new AliT0RecPoint (); + clustersTree->Branch( "T0", "AliT0RecPoint" ,&frecpoints, 405,1); + Float_t time[24], adc[24]; for (Int_t ipmt=0; ipmt<24; ipmt++) { if(timeCFD->At(ipmt)>0 ){ Int_t qt0= chargeQT0->At(ipmt); Int_t qt1= chargeQT1->At(ipmt); if((qt1-qt0)>0) adc[ipmt] = TMath::Exp( Double_t (channelWidth*(qt1-qt0)/1000)); - time[ipmt] = channelWidth * (calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ) ; + // time[ipmt] = channelWidth * (calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ) ; + time[ipmt] = calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ; //LED - Double_t sl = (timeLED->At(ipmt) - timeCFD->At(ipmt)- (1000.*timeDelayLED[ipmt]/channelWidth))*channelWidth; + Double_t sl = (timeLED->At(ipmt) - timeCFD->At(ipmt))*channelWidth; Double_t qt=((TGraph*)slewingLEDrec.At(ipmt))->Eval(sl/1000.); - frecpoints->SetTime(ipmt,time[ipmt]); + // frecpoints->SetTime(ipmt,time[ipmt]); frecpoints->SetAmp(ipmt,adc[ipmt]); frecpoints->SetAmpLED(ipmt,qt); } @@ -163,7 +163,7 @@ void AliT0Reconstructor::Reconstruct(TTree*digitsTree, TTree*clustersTree) const adc[ipmt] = 0; } } - + for (Int_t ipmt=0; ipmt<12; ipmt++){ if(time[ipmt] > 1 ) { if(time[ipmt]SetVertex(vertex); frecpoints->SetMeanTime(Int_t(meanTime)); } + //time in each channel as time[ipmt]-MeanTimeinThisChannel(with vertex=0) + for (Int_t ipmt=0; ipmt<24; ipmt++) { + if(time[ipmt]>1) { + time[ipmt] = (time[ipmt] - time0vertex[ipmt])*channelWidth; + frecpoints->SetTime(ipmt,time[ipmt]); + } + } clustersTree->Fill(); delete timeCFD; @@ -206,16 +213,15 @@ void AliT0Reconstructor::Reconstruct(TTree*digitsTree, TTree*clustersTree) const void AliT0Reconstructor::Reconstruct(AliRawReader* rawReader, TTree*recTree) const { -// T0 raw -> -// T0RecPoint writing - - //Q->T-> coefficients !!!! should be asked!!! - Float_t timeDelayLED[24]; - Float_t zdetA,zdetC; + // T0 raw -> + // T0RecPoint writing + + //Q->T-> coefficients !!!! should be measured!!! + Float_t time0vertex[24]; Int_t allData[110][5]; - TObjArray slewingLEDrec; + TObjArray slewingLEDrec; TObjArray walk; - + TArrayI * timeCFD = new TArrayI(24); TArrayI * timeLED = new TArrayI(24); TArrayI * chargeQT0 = new TArrayI(24); @@ -239,14 +245,14 @@ void AliT0Reconstructor::Reconstruct(AliRawReader* rawReader, TTree*recTree) con Int_t mV2Mip = param->GetmV2Mip(); //mV2Mip = param->GetmV2Mip(); Int_t channelWidth = param->GetChannelWidth() ; + Int_t meanT0 = param->GetMeanT0(); for (Int_t i=0; i<24; i++){ TGraph* gr = param ->GetSlewRec(i); slewingLEDrec.AddAtAndExpand(gr,i) ; + time0vertex[i]= param->GetTimeDelayDA(i); } - zdetC = param->GetZPosition("T0/C/PMT1"); - zdetA = param->GetZPosition("T0/A/PMT15"); for (Int_t in=0; in<24; in++) { @@ -275,8 +281,9 @@ void AliT0Reconstructor::Reconstruct(AliRawReader* rawReader, TTree*recTree) con Int_t qt0= chargeQT0->At(ipmt); Int_t qt1= chargeQT1->At(ipmt); if((qt1-qt0)>0) adc[ipmt] = TMath::Exp( Double_t (channelWidth*(qt1-qt0)/1000)); - time[ipmt] = channelWidth * (calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ) ; - Double_t sl = (timeLED->At(ipmt) - timeCFD->At(ipmt)- (1000.*timeDelayLED[ipmt]/channelWidth))*channelWidth; + // time[ipmt] = channelWidth * (calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ) ; + time[ipmt] = calib-> WalkCorrection( ipmt,qt1 , timeCFD->At(ipmt) ) ; + Double_t sl = (timeLED->At(ipmt) - timeCFD->At(ipmt))*channelWidth; Double_t qt=((TGraph*)slewingLEDrec.At(ipmt))->Eval(sl/1000.); frecpoints->SetTime(ipmt,time[ipmt]); frecpoints->SetAmp(ipmt,adc[ipmt]); @@ -309,16 +316,24 @@ void AliT0Reconstructor::Reconstruct(AliRawReader* rawReader, TTree*recTree) con Float_t c = 0.0299792; // cm/ps Float_t vertex = 0; if(besttimeA !=999999 && besttimeC != 999999 ){ - timeDiff = besttimeC - besttimeA; - meanTime = (besttimeA + besttimeC)/2.; + timeDiff = (besttimeC - besttimeA)*channelWidth; + // meanTime = (besttimeA + besttimeC)/2.; + meanTime = (meanT0 - (besttimeA + besttimeC)/2) * channelWidth; vertex = c*(timeDiff)/2.; //-(lenr-lenl))/2; AliDebug(1,Form(" timeDiff %f ps, meanTime %f ps, vertex %f cm",timeDiff, meanTime,vertex )); frecpoints->SetVertex(vertex); frecpoints->SetMeanTime(Int_t(meanTime)); } + //time in each channel as time[ipmt]-MeanTimeinThisChannel(with vertex=0) + for (Int_t ipmt=0; ipmt<24; ipmt++) { + if(time[ipmt]>1) { + time[ipmt] = (time[ipmt] - time0vertex[ipmt])*channelWidth; + frecpoints->SetTime(ipmt,time[ipmt]); + } + } recTree->Fill(); - + delete timeCFD; delete timeLED; @@ -367,12 +382,11 @@ void AliT0Reconstructor::FillESD(AliRunLoader* runLoader, AliESD *pESD) const brRec->GetEntry(0); Float_t timeStart, Zposition, amp[24], time[24]; - Int_t mean0 = 12450; Int_t i; Zposition = frecpoints -> GetVertex(); - timeStart = frecpoints -> GetMeanTime() - mean0; + timeStart = frecpoints -> GetMeanTime() ; for ( i=0; i<24; i++) { - time[i] = Float_t (frecpoints -> GetTime(i)) / 1000.; // ps to ns + time[i] = Float_t (frecpoints -> GetTime(i)); // ps to ns amp[i] = frecpoints -> GetAmp(i); } pESD->SetT0zVertex(Zposition); //vertex Z position diff --git a/T0/Calib/TimeDelay/Run0_10_v0_s0.root b/T0/Calib/TimeDelay/Run0_10_v0_s0.root index a57b3fa301cc74e7274e434dff13567dc9c5de82..7fe8e46321420c0e80c90f7945b516fb68af3eb8 100644 GIT binary patch literal 2898 zcmb_eX*8Sb7LFlihpL!LOHCCesG;VV5;Mn8iXbEvM+_xq5k<`+)vA)>&=PI6W;L{i z8fvUubm+Zoo&D-A* zF|x6|v@T&=W5(_(MD=c(S9%OJCO0NaM?zm*Uuw8FtIr0!bv^SaT`!z`A>8HBOP9{~ z14#38b|OGEgzc1S_zBe~{RzT=9V~rA2we7rU@Y1n8*CPE zBaqKHFw_elDUSCI@WWz&C4>O*Zp8{>g8;mDJA2?IyM>Qy$Y&3;=L~KMFgwx|f*9u9 z_(t{Mx2)E*aW_2=J}B4wUfo=sd>X2H%#|7}zBsII{g z`nu3^YC&9Lke=VKIO^>@bk5var<}`83x|x5Yxbu5wIjhUVY(S-?6+Y)AZBlGy0n96mMCCj|%D8B}R% zt|3C?;gVSJhokZ5QW-gxYG8%n5qBSs^DtZ9B|nV8+WZZ*S+a#PNETi(vXxk4>vS$f>HT+%|?sXu?6FEsfBVWitSvdYV>u)yHRasmUBE6W_41qQOcwK4T8HS zypgDj2O`i};e+V=PbQ>N!yp(ZdIx1$<^bF#-Ycnkp7(f<-Vnq2w&O*A zBC0LKcgrK3`U!k_1R5#GNl&B4)hX{fN5E#2ZR%fi8XWn!M%&e)v+~%o9U?AH*7jWP zesz8#k;74{NTNh*C9hk3j3;^NXiPe)NVINUh5ej5dx(MjT3=Get49a*J;Azn4652O zmj*dKj>SLa774}*F{|7bOC?W{F*1b$@5EJ2vWovSB=S3^yY1apAu5>b)IW18$>K5y z@9n_#GNWFy=j%$BS8v7WEZ1Y9*>J+{tE>0#TxFXmTsDIx8Aok3J#1IvJydbr+9>U= zmTUIDbRcX`=;cS%%GDT;&-m*2^qKf^+I#7-3PQPCP!vDhM9nCA#d5v@6N0<+`HJ+* zylg?ddD%z2`G4~brQsJpyO#GCDQ3aN#)9@=DVNyJA z8e3xPH!0xc;@%C;%=GVt21m-0Py}H;_1(RK0fCaMNf?qTRyI{)%>X$Ng@^vB;;^O! zakcDz=?^VS*pZ5i9x2LfJZs*PcPo(`cYWuT1 z|Ag4hw4Wa{I@5FU?r$Ts5GuFVTvuh1sFtkWhmrj%Zl98KKMwzJA_pxqUpsWpq-bu+ zT)vx7t8R;G4Bv14NQu1gHPEp!FsS&=5@9?R=w0p0t#7dQzYywTmD(CimL&y}3{qwb zap3xRts2W!JR3;SGS<{Fb6Z3cN6nDr2sUCit|(H2i+=az;u8IO#QADCq;cU2PQt3R`^b3m%)hNM=H)ATgTbr^j8C7f9Sz=XdV}gc5sseL9 z0|>+37bG~@;@d9+TM*a#P1vcJCmY5F!Npc?G?G^l6GV8lE*Sik3lyATO%R+qWg+L4bV zjz;e+-eBe7Aq9B6EY=d)^JgMTRxYx}6-+_ScU^%uok7IDwfND*w5_bjdxTr)L>IEZ zBCR9uL4-dikkpS2*9y;SR9W~iQ^P%UW=QL`(FcfYVJx;3N3}+QvOL4YHvVOvjT-3n8shPl~8UCF+cl`^tUKOFAUdh zKDoJJWgJrObA#Ky^1S}e#m*ud;I#y{og!|bICx#CW+j#@zaLkO8vW=|H|xKO-)9*P zd&cOR^Lyd9C{r4&-zX=lx>Zv+r<6ZbULTDDy9sWztmHar*S%!PemRenog(k&k}h+wi8+P{|YT2 YEZ`Ix$3LJg{bXnWFiyL0wR@m{0|rIiPyhe` literal 1661 zcmXTQ&o5zMIB|l3fgy!~fvpyZg@NoWAZ7&O1uPH-Qx^jR(j-g+*Fs;oWx4~pwc{pcteBuGK2VH1HB@U^C{KOzyfj?*li39(}B)f z0K{PT0bN)_$kU8oAiptrgY_GO{Kn`2($5X_gtLp2YhFoFB{G{K%7=rGk-?jZp@OkE zA)zQefyGH7fhmcd?bwh14i9EbmP~puXU622PbNi7;t=|lkWiM8Fris9jZNzrgLVhM zVS{nZDhY`gD`|B?Jv50eDmH3>>wm*3_{-gswr+cAp&){GYiUHI?Wyu7&o=#Ty%<`oz6kGU>y z5!(4 zUP@riA`!3mQLXKp;+}S0zOwzD`;yHo_N7-{c{O{f%0t`Q|7@xM@41M|UTpXNlE<*_ zjI~pGd5LtEB-KjSNYNS#-Xd)ARo8t-PzRKUwf#Y2wy|%~o<1n^adRJ=uFIrgWK5x55mw zGa{eXEZm=Pbmr?dip>rxN2}mUF7ik`=&Fzm5TX0tFBgw+1f9O_&C#J$_t~ZC(?pd&fI?x zsN(e3q_Tp~?#i0wH{~Sc!vwe&n!n<-vfuL?iG}yl0y&;NuE^ePD>duD zlzV?f(qsx(Jl(^3@7Nn7`Cl#(-_Jx}{hJoiP-g0HzcqDD6xLQXhzwRCtDES}ZzJIZmj8AHsP`1zmW1>`3-7hil}Af3+A z#ab%k+t?FwNzvei_@pRhZ(!P<4lWnX!6_bGE&|INaEhl!xd=1~R2q?5J^{65ft|$# abk-+GaSg5%fEkf0&H_4$t+w2B3IhO(0eGtb -- 2.39.3