diff --git a/DataModel/FoMCalculator.cpp b/DataModel/FoMCalculator.cpp index d2f859a64..add5e32ff 100644 --- a/DataModel/FoMCalculator.cpp +++ b/DataModel/FoMCalculator.cpp @@ -1,529 +1,652 @@ -#include "FoMCalculator.h" - -//Constructor -FoMCalculator::FoMCalculator() { - fVtxGeo = 0; - fBaseFOM = 100.0; - - // fitting parameters ported from vertexFinder (FIXME) - fTimeFitWeight = 0.50; // nominal time weight - fConeFitWeight = 0.50; // nominal cone weight - - // default Mean time calculator type - fMeanTimeCalculatorType = 0; -} - -//Destructor -FoMCalculator::~FoMCalculator() { - fVtxGeo = 0; -} - - -void FoMCalculator::LoadVertexGeometry(VertexGeometry* vtxgeo) { - this->fVtxGeo = vtxgeo; -} - - -void FoMCalculator::TimePropertiesLnL(double vtxTime, double& vtxFOM) -{ - // internal variables - // ================== - double weight = 0.0; - double delta = 0.0; // time residual of each hit - double sigma = 0.0; // time resolution of each hit - double A = 0.0; // normalisation of first Gaussian - int type; // Digit type (LAPPD or PMT) - - double Preal = 0.0; // probability of real hit - double P = 0.0; // probability of hit - - double chi2 = 0.0; // log-likelihood: chi2 = -2.0*log(L) - double ndof = 0.0; // total number of hits - double fom = -9999.; // figure of merit - - // add noise to model - // ================== - double Pnoise; - - //FIXME: We need an implementation of noise models for PMTs and LAPPDs - //double nFilterDigits = this->fVtxGeo->GetNFilterDigits(); - //double fTimeFitNoiseRate = 0.02; // hits/ns [0.40 for electrons, 0.02 for muons] - //Pnoise = fTimeFitNoiseRate/nFilterDigits; - - // loop over digits - // ================ - for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ - int detType = this->fVtxGeo->GetDigitType(idigit); - delta = this->fVtxGeo->GetDelta(idigit) - vtxTime; - sigma = this->fVtxGeo->GetDeltaSigma(idigit); - type = this->fVtxGeo->GetDigitType(idigit); - if (type == RecoDigit::PMT8inch){ //PMT8Inch - sigma = 1.5*sigma; - Pnoise = 1e-8; //FIXME; Need implementation of noise model - } - if (type == RecoDigit::lappd_v0){ //lappd - sigma = 1.2*sigma; - Pnoise = 1e-8; //FIXME; Need implementation of noise model - } - A = 1.0 / ( 2.0*sigma*sqrt(0.5*TMath::Pi()) ); //normalisation constant - Preal = A*exp(-(delta*delta)/(2.0*sigma*sigma)); - P = (1.0-Pnoise)*Preal + Pnoise; - chi2 += -2.0*log(P); - ndof += 1.0; - } - - // calculate figure of merit - if( ndof>0.0 ){ - fom = fBaseFOM - 5.0*chi2/ndof; - } - - // return figure of merit - // ====================== - vtxFOM = fom; - return; -} - - - - -void FoMCalculator::ConePropertiesFoM(double coneEdge, double& coneFOM) -{ - // calculate figure of merit - // ========================= - double coneEdgeLow = 21.0; // cone edge (low side) - double coneEdgeHigh = 3.0; // cone edge (high side) [muons: 3.0, electrons: 7.0] - double deltaAngle = 0.0; - double digitCharge = 0.0; - double coneCharge = 0.0; - double allCharge = 0.0; - - double fom = -9999.; - - for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ - if( this->fVtxGeo->IsFiltered(idigit) && this->fVtxGeo->GetDigitType(idigit) == RecoDigit::PMT8inch){ - deltaAngle = this->fVtxGeo->GetAngle(idigit) - coneEdge; - digitCharge = this->fVtxGeo->GetDigitQ(idigit); - - if( deltaAngle<=0.0 ){ - coneCharge += digitCharge*( 0.75 + 0.25/( 1.0 + (deltaAngle*deltaAngle)/(coneEdgeLow*coneEdgeLow) ) ); - } - else{ - coneCharge += digitCharge*( 0.00 + 1.00/( 1.0 + (deltaAngle*deltaAngle)/(coneEdgeHigh*coneEdgeHigh) ) ); - } - - allCharge += digitCharge; - } - } - - if( allCharge>0.0 ){ - fom = fBaseFOM*coneCharge/allCharge; - } - - // return figure of merit - // ====================== - coneFOM = fom; - return; -} - - - - -//Given the position of the point vertex (x, y, z) and n digits, calculate the mean expected vertex time -double FoMCalculator::FindSimpleTimeProperties(double myConeEdge) { - double meanTime = 0.0; - // weighted average - if(fMeanTimeCalculatorType == 0) { - // calculate mean and rms of hits inside cone - // ========================================== - double Swx = 0.0; - double Sw = 0.0; - - double delta = 0.0; - double sigma = 0.0; - double weight = 0.0; - double deweight = 0.0; - double deltaAngle = 0.0; - - double myConeEdgeSigma = 7.0; // [degrees] - - for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ - int detType = this->fVtxGeo->GetDigitType(idigit); - if( this->fVtxGeo->IsFiltered(idigit) ){ - delta = this->fVtxGeo->GetDelta(idigit); - sigma = this->fVtxGeo->GetDeltaSigma(idigit); - weight = 1.0/(sigma*sigma); - // profile in angle - deltaAngle = this->fVtxGeo->GetAngle(idigit) - myConeEdge; - // deweight hits outside cone - if( deltaAngle<=0.0 ){ - deweight = 1.0; - } - else{ - deweight = 1.0/(1.0+(deltaAngle*deltaAngle)/(myConeEdgeSigma*myConeEdgeSigma)); - } - Swx += deweight*weight*delta; //delta is expected vertex time - Sw += deweight*weight; - } - } - if( Sw>0.0 ){ - meanTime = Swx*1.0/Sw; - } - } - - // most probable time - else if(fMeanTimeCalculatorType == 1) { - double sigma = 0.0; - double deltaAngle = 0.0; - double weight = 0.0; - double deweight = 0.0; - double myConeEdgeSigma = 7.0; // [degrees] - vector deltaTime1; - vector deltaTime2; - vector TimeWeight; - - for( int idigit=0; idigitGetNDigits(); idigit++ ){ - if(fVtxGeo->IsFiltered(idigit)){ - deltaTime1.push_back(fVtxGeo->GetDelta(idigit)); - deltaTime2.push_back(fVtxGeo->GetDelta(idigit)); - sigma = fVtxGeo->GetDeltaSigma(idigit); - weight = 1.0/(sigma*sigma); - deltaAngle = fVtxGeo->GetAngle(idigit) - myConeEdge; - if( deltaAngle<=0.0 ){ - deweight = 1.0; - } - else{ - deweight = 1.0/(1.0+(deltaAngle*deltaAngle)/(myConeEdgeSigma*myConeEdgeSigma)); - } - TimeWeight.push_back(deweight*weight); - } - } - int n = deltaTime1.size(); - std::sort(deltaTime1.begin(),deltaTime1.end()); - double timeMin = deltaTime1.at(int((n-1)*0.05)); // 5% of the total entries - double timeMax = deltaTime1.at(int((n-1)*0.90)); // 90% of the total entries - int nbins = int(n/5); - TH1D *hDeltaTime = new TH1D("hDeltaTime", "hDeltaTime", nbins, timeMin, timeMax); - for(int i=0; iFill(deltaTime2.at(i), TimeWeight.at(i)); - hDeltaTime->Fill(deltaTime2.at(i)); - } - meanTime = hDeltaTime->GetBinCenter(hDeltaTime->GetMaximumBin()); - delete hDeltaTime; hDeltaTime = 0; - } - - else std::cout<<"FoMCalculator Error: Wrong type of Mean time calculator! "<fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, 0.0, 0.0, 0.0); //calculate expected point vertex time for each digit - - // calculate figure of merit - // ========================= - this->TimePropertiesLnL(vtxTime, vtxFOM); - - // calculate overall figure of merit - // ================================= - fom = vtxFOM; - // truncate - if( fom<-9999. ) fom = -9999.; - - return; -} - - - - - -void FoMCalculator::PointDirectionChi2(double vtxX, double vtxY, - double vtxZ, double dirX, double dirY, double dirZ, - double coneAngle, double& fom) -{ - // figure of merit - // =============== - double coneFOM = -9999.; - - // calculate residuals - // =================== - this->fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, - dirX, dirY, dirZ); //load expected vertex time for each digit - - // calculate figure of merit - // ========================= - this->ConePropertiesFoM(coneAngle, coneFOM); - - // calculate overall figure of merit - // ================================= - fom = coneFOM; - - // truncate - if( fom<-9999. ) fom = -9999.; - - return; -} - -void FoMCalculator::PointVertexChi2(double vtxX, double vtxY, double vtxZ, - double dirX, double dirY, double dirZ, - double coneAngle, double vtxTime, double& fom) -{ - // figure of merit - // =============== - double vtxFOM = -9999.; - - // calculate residuals - // =================== - this->fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, - dirX, dirY, dirZ); //calculate expected vertex time for each digit - // calculate figure of merit - // ========================= - double timeFOM = -9999.; - double coneFOM = -9999.; - - this->ConePropertiesFoM(coneAngle,coneFOM); - this->TimePropertiesLnL(vtxTime, timeFOM); - - double fTimeFitWeight = this->fTimeFitWeight; - double fConeFitWeight = this->fConeFitWeight; - vtxFOM = (fTimeFitWeight*timeFOM+fConeFitWeight*coneFOM)/(fTimeFitWeight+fConeFitWeight); - - // calculate overall figure of merit - // ================================= - fom = vtxFOM; - // truncate - if( fom<-9999. ) fom = -9999.; - - return; -} - -void FoMCalculator::ExtendedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneAngle, double vtxTime, double& fom) -{ - // figure of merit - // =============== - double vtxFOM = -9999.; - double timeFOM = -9999.; - double coneFOM = -9999.; - - // calculate residuals - // =================== - this->fVtxGeo->CalcExtendedResiduals(vtxX,vtxY,vtxZ,0.0,dirX,dirY,dirZ); - - // calculate figure of merit - // ========================= - - this->ConePropertiesFoM(coneAngle,coneFOM); - this->TimePropertiesLnL(vtxTime, timeFOM); - - double fTimeFitWeight = this->fTimeFitWeight; - double fConeFitWeight = this->fConeFitWeight; - vtxFOM = (fTimeFitWeight*timeFOM+fConeFitWeight*coneFOM)/(fTimeFitWeight+fConeFitWeight); - - // calculate overall figure of merit - // ================================= - fom = vtxFOM; - - // truncate - if( fom<-9999. ) fom = -9999.; - - return; -} - -//KEPT FOR HISTORY, BUT FITTER IS CURRENTLY NOT WORKING -//void FoMCalculator::CorrectedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double& vtxAngle, double& vtxTime, double& fom) -//{ -// // figure of merit -// // =============== -// double vtxFOM = 0.0; -// double timeFOM = 0.0; -// double coneFOM = 0.0; -// double penaltyFOM = 0.0; -// double fixPositionFOM = 0.0; -// double fixDirectionFOM = 0.0; -// -// // calculate residuals -// // =================== -// this->fVtxGeo->CalcExtendedResiduals(vtxX,vtxY,vtxZ,0.0,dirX,dirY,dirZ); -// -// // calculate figure of merit -// // ========================= -// -// this->ConePropertiesFoM(vtxAngle,coneFOM); -// fom = coneFOM; -// -// // truncate -// if( fom<-999.999*fBaseFOM ) fom = -999.999*fBaseFOM; -// -// return; -//} -// -//void FoMCalculator::ConePropertiesLnL(double coneParam0, double coneParam1, double coneParam2, double& coneAngle, double& coneFOM) -//{ -// -// // nuisance parameters -// // =================== -// double alpha = coneParam0; // track length parameter = 0.25 -// double alpha0 = coneParam1; // track length parameter = 0.5 -// double beta = coneParam2; // particle ID: 0.0[electron]->1.0[muon] = 0.75 -// -// // internal variables -// // ================== -// double deltaAngle = 0.0; // -// double sigmaAngle = 7.0; //Cherenkov Angle resolution -// double Angle0 = Parameters::CherenkovAngle(); //Cherenkov Angle: 42 degree -// double deltaAngle0 = Angle0*alpha0; //? -// -// double digitQ = 0.0; -// double sigmaQmin = 1.0; -// double sigmaQmax = 10.0; -// double sigmaQ = 0.0; -// -// double A = 0.0; -// -// double PconeA = 0.0; -// double PconeB = 0.0; -// double Pmu = 0.0; -// double Pel = 0.0; -// -// double Pcharge = 0.0; -// double Pangle = 0.0; -// double P = 0.0; -// -// double chi2 = 0.0; -// double ndof = 0.0; -// -// double angle = 46.0; -// double fom = 0.0; -// -// // hard-coded parameters: 200 kton (100 kton) -// // ========================================== -// double lambdaMuShort = 0.5; // 0.5; -// double lambdaMuLong = 5.0; // 15.0; -// double alphaMu = 1.0; // 4.5; -// -// double lambdaElShort = 1.0; // 2.5; -// double lambdaElLong = 7.5; // 15.0; -// double alphaEl = 6.0; // 3.5; -// -// // numerical integrals -// // =================== -// fSconeA = 21.9938; -// fSconeB = 0.0000; -// -// // Number of P.E. angular distribution -// // inside cone -// int nbinsInside = 420; //divide the angle range by 420 bins -// for( int n=0; nfVtxGeo->GetNDigits(); idigit++ ){ -// -// if( this->fVtxGeo->IsFiltered(idigit) ){ -// digitQ = this->fVtxGeo->GetDigitQ(idigit); -// deltaAngle = this->fVtxGeo->GetAngle(idigit) - Angle0; -// -// // pulse height distribution -// // ========================= -// if( deltaAngle<=0 ){ //inside Cone -// sigmaQ = sigmaQmax; -// } -// else{ //outside Cone -// sigmaQ = sigmaQmin + (sigmaQmax-sigmaQmin)/(1.0+(deltaAngle*deltaAngle)/(sigmaAngle*sigmaAngle)); -// } -// -// A = 1.0/(log(2.0)+0.5*TMath::Pi()*sigmaQ); -// -// if( digitQ<1.0 ){ -// Pcharge = 2.0*A*digitQ/(1.0+digitQ*digitQ); -// } -// else{ -// Pcharge = A/(1.0+(digitQ-1.0)*(digitQ-1.0)/(sigmaQ*sigmaQ)); -// } -// -// // angular distribution -// // ==================== -// A = 1.0/( alpha*fSconeA + (1.0-alpha)*fSconeB -// + beta*fSmu + (1.0-beta)*fSel ); // numerical integrals -// -// if( deltaAngle<=0 ){ -// -// // pdfs inside cone: -// PconeA = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ); -// PconeB = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) -// *( 1.0/(1.0+(deltaAngle*deltaAngle)/(deltaAngle0*deltaAngle0)) ); -// -// Pangle = A*( alpha*PconeA+(1.0-alpha)*PconeB ); -// } -// else{ -// -// // pdfs outside cone -// Pmu = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) -// *( 1.0/(1.0+alphaMu*(lambdaMuShort/lambdaMuLong)) )*( 1.0/(1.0+(deltaAngle*deltaAngle)/(lambdaMuShort*lambdaMuShort)) -// + alphaMu*(lambdaMuShort/lambdaMuLong)/(1.0+(deltaAngle*deltaAngle)/(lambdaMuLong*lambdaMuLong)) ); -// -// Pel = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) -// *( 1.0/(1.0+alphaEl*(lambdaElShort/lambdaElLong)) )*( 1.0/(1.0+(deltaAngle*deltaAngle)/(lambdaElShort*lambdaElShort)) -// + alphaEl*(lambdaElShort/lambdaElLong)/(1.0+(deltaAngle*deltaAngle)/(lambdaElLong*lambdaElLong)) ); -// -// Pangle = A*( beta*Pmu+(1.0-beta)*Pel ); -// } -// -// // overall probability -// // =================== -// P = Pcharge*Pangle; -// -// chi2 += -2.0*log(P); -// ndof += 1.0; -// } -// } -// -// // calculate figure of merit -// // ========================= -// if( ndof>0.0 ){ -// fom = fBaseFOM - 5.0*chi2/ndof; -// angle = beta*43.0 + (1.0-beta)*49.0; -// } -// -// // return figure of merit -// // ====================== -// coneAngle = angle; -// coneFOM = fom; -// -// return; -//} - +#include "FoMCalculator.h" + +//Constructor +FoMCalculator::FoMCalculator() { + fVtxGeo = 0; + fBaseFOM = 100.0; + + // fitting parameters ported from vertexFinder (FIXME) + fTimeFitWeight = 0.50; // nominal time weight + fConeFitWeight = 0.50; // nominal cone weight + + // default Mean time calculator type + fMeanTimeCalculatorType = 0; +} + +//Destructor +FoMCalculator::~FoMCalculator() { + fVtxGeo = 0; +} + + +void FoMCalculator::LoadVertexGeometry(VertexGeometry* vtxgeo) { + this->fVtxGeo = vtxgeo; +} + + +void FoMCalculator::TimePropertiesLnL(double vtxTime, double& vtxFOM) +{ + // internal variables + // ================== + double weight = 0.0; + double delta = 0.0; // time residual of each hit + double sigma = 0.0; // time resolution of each hit + double A = 0.0; // normalisation of first Gaussian + int type; // Digit type (LAPPD or PMT) + + double Preal = 0.0; // probability of real hit + double P = 0.0; // probability of hit + + double chi2 = 0.0; // log-likelihood: chi2 = -2.0*log(L) + double ndof = 0.0; // total number of hits + double fom = -9999.; // figure of merit + + // add noise to model + // ================== + double Pnoise; + + //FIXME: We need an implementation of noise models for PMTs and LAPPDs + //double nFilterDigits = this->fVtxGeo->GetNFilterDigits(); + //double fTimeFitNoiseRate = 0.02; // hits/ns [0.40 for electrons, 0.02 for muons] + //Pnoise = fTimeFitNoiseRate/nFilterDigits; + + // loop over digits + // ================ + for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ + int detType = this->fVtxGeo->GetDigitType(idigit); + delta = this->fVtxGeo->GetDelta(idigit) - vtxTime; + sigma = this->fVtxGeo->GetDeltaSigma(idigit); + type = this->fVtxGeo->GetDigitType(idigit); + if (type == RecoDigit::PMT8inch){ //PMT8Inch + sigma = 1.5*sigma; + Pnoise = 1e-8; //FIXME; Need implementation of noise model + } + if (type == RecoDigit::lappd_v0){ //lappd + sigma = 1.2*sigma; + Pnoise = 1e-8; //FIXME; Need implementation of noise model + } + A = 1.0 / ( 2.0*sigma*sqrt(0.5*TMath::Pi()) ); //normalisation constant + Preal = A*exp(-(delta*delta)/(2.0*sigma*sigma)); + P = (1.0-Pnoise)*Preal + Pnoise; + chi2 += -2.0*log(P); + ndof += 1.0; + } + + // calculate figure of merit + if( ndof>0.0 ){ + fom = fBaseFOM - 5.0*chi2/ndof; + } + + // return figure of merit + // ====================== + vtxFOM = fom; + return; +} + + + + +void FoMCalculator::ConePropertiesFoM(double coneEdge, double& coneFOM) +{ + // calculate figure of merit + // ========================= + double coneEdgeLow = 21.0; // cone edge (low side) + double coneEdgeHigh = 3.0; // cone edge (high side) [muons: 3.0, electrons: 7.0] + double deltaAngle = 0.0; + double digitCharge = 0.0; + double coneCharge = 0.0; + double allCharge = 0.0; + double outerCone = -99.9; + int outhits = 0; + int inhits = 0; + + double fom = -9999.; + + for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ + if( this->fVtxGeo->IsFiltered(idigit) /* && this->fVtxGeo->GetDigitType(idigit) == RecoDigit::PMT8inch*/) { + deltaAngle = this->fVtxGeo->GetAngle(idigit) - coneEdge; + digitCharge = this->fVtxGeo->GetDigitQ(idigit); + + if( deltaAngle<=0.0 ){ + coneCharge += digitCharge*( 0.75 + 0.25/( 1.0 + (deltaAngle*deltaAngle)/(coneEdgeLow*coneEdgeLow) ) ); + inhits++; + //if (deltaAngle > outerCone) outerCone = deltaAngle; + } + else{ + coneCharge += digitCharge*( 0.00 + 1.00/( 1.0 + (deltaAngle*deltaAngle)/(coneEdgeHigh*coneEdgeHigh) ) ); + outhits++; + //outerCone = 0; + } + + allCharge += digitCharge; + //outerCone = -outhits/inhits; + } + } + + if( allCharge>0.0 ){ + if( outerCone>-42 ){ + fom = fBaseFOM*coneCharge/allCharge/*exp(outerCone)*/; + }else{ + fom = fBaseFOM*coneCharge/allCharge; + } + } + + // return figure of merit + // ====================== + coneFOM = fom; + return; +} + +void FoMCalculator::ConePropertiesLnL(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneEdge, double& chi2, TH1D angularDist, double& phimax, double& phimin) { + double coneEdgeLow = 21.0; // cone edge (low side) + double coneEdgeHigh = 3.0; // cone edge (high side) [muons: 3.0, electrons: 7.0] + double deltaAngle = 0.0; + double digitCharge = 0.0; + double digitPE = 0.0; + double coneCharge = 0.0; + double allCharge = 0.0; + double outerCone = -99.9; + double coef = angularDist.Integral(); //1000; + chi2 = 0; + cout << "ConePropertiesLnL Position: (" << vtxX << ", " << vtxY << ", " << vtxZ << ")" << endl; + cout << "And Direction: (" << dirX << ", " << dirY << ", " << dirZ << ")" << endl; + + double digitX, digitY, digitZ; + double dx, dy, dz, ds; + double px, py, pz; + double cosphi, phi, phideg; + phimax = 0; + phimin = 10; + double allPE = 0; + int refbin; + double weight; + double P; + + for (int idigit = 0; idigit < this->fVtxGeo->GetNDigits(); idigit++) { + if (this->fVtxGeo->IsFiltered(idigit) && this->fVtxGeo->GetDigitType(idigit) == RecoDigit::PMT8inch) { + digitCharge = this->fVtxGeo->GetDigitQ(idigit); + allCharge += digitCharge; + } + } + + for (int idigit = 0; idigit < this->fVtxGeo->GetNDigits(); idigit++) { + if (this->fVtxGeo->IsFiltered(idigit) && this->fVtxGeo->GetDigitType(idigit) == RecoDigit::PMT8inch) { + deltaAngle = this->fVtxGeo->GetAngle(idigit) - coneEdge; + digitCharge = this->fVtxGeo->GetDigitQ(idigit); + //digitPE = this->fVtxGeo->GetDigitPE(idigit); + digitX = fVtxGeo->GetDigitX(idigit); + digitY = fVtxGeo->GetDigitY(idigit); + digitZ = fVtxGeo->GetDigitZ(idigit); + dx = digitX - vtxX; + dy = digitY - vtxY; + dz = digitZ - vtxZ; + std::cout << "dx, dy, dz: " << dx << ", " << dy << ", " << dz << endl; + ds = pow(dx * dx + dy * dy + dz * dz, 0.5); + std::cout << "ds: " << ds << endl; + px = dx / ds; + py = dy / ds; + pz = dz / ds; + std::cout << "px, py, pz: " << px << ", " << py << ", " << pz << endl; + std::cout << "dirX, dirY, DirZ: " << dirX << ", " << dirY << ", " << dirZ << endl; + + cosphi = 1.0; + phi = 0.0; + //cout << "angle direction: " << dx << " " << dy << " " << dz << " = " << ds << endl; + cosphi = px * dirX + py * dirY + pz * dirZ; + //cout << "cosphi: " << cosphi << endl; + phi = acos(cosphi); + + if (phi > phimax) phimax = phi; + if (phi < phimin) phimin = phi; + + phideg = phi / (TMath::Pi() / 180); + std::cout << "phi, phideg: " << phi << ", " << phideg << endl; + std::cout << "vs. Zenith: " << fVtxGeo->GetZenith(idigit) << endl; + refbin = angularDist.FindBin(phideg); + weight = angularDist.GetBinContent(refbin)/coef; + P = digitCharge / allCharge; + //cout << "conefomlnl P: " << P << ", weight: " << weight << endl; + chi2 += pow(P - weight, 2)/weight; + + //outerCone = -outhits/inhits; + } + } + //chi2 = (100 - chi2) * exp(-pow(pow(0.7330382, 2) - pow(phimax - phimin, 2), 2) / pow(0.7330382, 2)); +} + + + + +//Given the position of the point vertex (x, y, z) and n digits, calculate the mean expected vertex time +double FoMCalculator::FindSimpleTimeProperties(double myConeEdge) { + double meanTime = 0.0; + // weighted average + if(fMeanTimeCalculatorType == 0) { + // calculate mean and rms of hits inside cone + // ========================================== + double Swx = 0.0; + double Sw = 0.0; + + double delta = 0.0; + double sigma = 0.0; + double weight = 0.0; + double deweight = 0.0; + double deltaAngle = 0.0; + + double myConeEdgeSigma = 7.0; // [degrees] + + for( int idigit=0; idigitfVtxGeo->GetNDigits(); idigit++ ){ + int detType = this->fVtxGeo->GetDigitType(idigit); + if( this->fVtxGeo->IsFiltered(idigit) ){ + delta = this->fVtxGeo->GetDelta(idigit); + sigma = this->fVtxGeo->GetDeltaSigma(idigit); + weight = 1.0/(sigma*sigma); + // profile in angle + deltaAngle = this->fVtxGeo->GetAngle(idigit) - myConeEdge; + // deweight hits outside cone + if( deltaAngle<=0.0 ){ + deweight = 1.0; + } + else{ + deweight = 1.0/(1.0+(deltaAngle*deltaAngle)/(myConeEdgeSigma*myConeEdgeSigma)); + } + Swx += deweight*weight*delta; //delta is expected vertex time + Sw += deweight*weight; + } + } + if( Sw>0.0 ){ + meanTime = Swx*1.0/Sw; + } + } + + // most probable time + else if(fMeanTimeCalculatorType == 1) { + double sigma = 0.0; + double deltaAngle = 0.0; + double weight = 0.0; + double deweight = 0.0; + double myConeEdgeSigma = 7.0; // [degrees] + vector deltaTime1; + vector deltaTime2; + vector TimeWeight; + + for( int idigit=0; idigitGetNDigits(); idigit++ ){ + if(fVtxGeo->IsFiltered(idigit)){ + deltaTime1.push_back(fVtxGeo->GetDelta(idigit)); + deltaTime2.push_back(fVtxGeo->GetDelta(idigit)); + sigma = fVtxGeo->GetDeltaSigma(idigit); + weight = 1.0/(sigma*sigma); + deltaAngle = fVtxGeo->GetAngle(idigit) - myConeEdge; + if( deltaAngle<=0.0 ){ + deweight = 1.0; + } + else{ + deweight = 1.0/(1.0+(deltaAngle*deltaAngle)/(myConeEdgeSigma*myConeEdgeSigma)); + } + TimeWeight.push_back(deweight*weight); + } + } + int n = deltaTime1.size(); + std::sort(deltaTime1.begin(),deltaTime1.end()); + double timeMin = deltaTime1.at(int((n-1)*0.05)); // 5% of the total entries + double timeMax = deltaTime1.at(int((n-1)*0.90)); // 90% of the total entries + int nbins = int(n/5); + TH1D *hDeltaTime = new TH1D("hDeltaTime", "hDeltaTime", nbins, timeMin, timeMax); + for(int i=0; iFill(deltaTime2.at(i), TimeWeight.at(i)); + hDeltaTime->Fill(deltaTime2.at(i)); + } + meanTime = hDeltaTime->GetBinCenter(hDeltaTime->GetMaximumBin()); + delete hDeltaTime; hDeltaTime = 0; + } + + else std::cout<<"FoMCalculator Error: Wrong type of Mean time calculator! "<fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, 0.0, 0.0, 0.0); //calculate expected point vertex time for each digit + + // calculate figure of merit + // ========================= + this->TimePropertiesLnL(vtxTime, vtxFOM); + + // calculate overall figure of merit + // ================================= + fom = vtxFOM; + // truncate + if( fom<-9999. ) fom = -9999.; + + return; +} + + + + + +void FoMCalculator::PointDirectionChi2(double vtxX, double vtxY, + double vtxZ, double dirX, double dirY, double dirZ, + double coneAngle, double& fom) +{ + // figure of merit + // =============== + double coneFOM = -9999.; + + // calculate residuals + // =================== + this->fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, + dirX, dirY, dirZ); //load expected vertex time for each digit + + // calculate figure of merit + // ========================= + this->ConePropertiesFoM(coneAngle, coneFOM); + + // calculate overall figure of merit + // ================================= + fom = coneFOM; + + // truncate + if( fom<-9999. ) fom = -9999.; + + return; +} + +void FoMCalculator::PointVertexChi2(double vtxX, double vtxY, double vtxZ, + double dirX, double dirY, double dirZ, + double coneAngle, double vtxTime, double& fom) +{ + // figure of merit + // =============== + double vtxFOM = -9999.; + + // calculate residuals + // =================== + this->fVtxGeo->CalcPointResiduals(vtxX, vtxY, vtxZ, 0.0, + dirX, dirY, dirZ); //calculate expected vertex time for each digit + // calculate figure of merit + // ========================= + double timeFOM = -9999.; + double coneFOM = -9999.; + + this->ConePropertiesFoM(coneAngle,coneFOM); + this->TimePropertiesLnL(vtxTime, timeFOM); + + double fTimeFitWeight = this->fTimeFitWeight; + double fConeFitWeight = this->fConeFitWeight; + vtxFOM = (fTimeFitWeight*timeFOM+fConeFitWeight*coneFOM)/(fTimeFitWeight+fConeFitWeight); + + // calculate overall figure of merit + // ================================= + fom = vtxFOM; + // truncate + if( fom<-9999. ) fom = -9999.; + + return; +} + +void FoMCalculator::ExtendedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneAngle, double vtxTime, double& fom) +{ + // figure of merit + // =============== + double vtxFOM = -9999.; + double timeFOM = -9999.; + double coneFOM = -9999.; + + // calculate residuals + // =================== + this->fVtxGeo->CalcExtendedResiduals(vtxX,vtxY,vtxZ,0.0,dirX,dirY,dirZ); + + // calculate figure of merit + // ========================= + + this->ConePropertiesFoM(coneAngle,coneFOM); + this->TimePropertiesLnL(vtxTime, timeFOM); + + double fTimeFitWeight = this->fTimeFitWeight; + double fConeFitWeight = this->fConeFitWeight; + vtxFOM = (fTimeFitWeight*timeFOM+fConeFitWeight*coneFOM)/(fTimeFitWeight+fConeFitWeight); + + // calculate overall figure of merit + // ================================= + fom = vtxFOM; + + // truncate + if( fom<-9999. ) fom = -9999.; + + return; +} + +void FoMCalculator::ExtendedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneAngle, double vtxTime, double& fom, TH1D pdf) +{ + // figure of merit + // =============== + double vtxFOM = -9999.; + double timeFOM = -9999.; + double coneFOM = -9999.; + double phimax, phimin; + + // calculate residuals + // =================== + this->fVtxGeo->CalcExtendedResiduals(vtxX, vtxY, vtxZ, 0.0, dirX, dirY, dirZ); + + // calculate figure of merit + // ========================= + + this->ConePropertiesLnL(vtxX, vtxY, vtxZ, dirX, dirY, dirZ, coneAngle, coneFOM, pdf, phimax, phimin); + this->TimePropertiesLnL(vtxTime, timeFOM); + + double fTimeFitWeight = this->fTimeFitWeight; + double fConeFitWeight = this->fConeFitWeight; + vtxFOM = (fTimeFitWeight * timeFOM + fConeFitWeight * coneFOM) / (fTimeFitWeight + fConeFitWeight); + + // calculate overall figure of merit + // ================================= + fom = vtxFOM; + + // truncate + if (fom < -9999.) fom = -9999.; + + return; +} + + + +//KEPT FOR HISTORY, BUT FITTER IS CURRENTLY NOT WORKING +//void FoMCalculator::CorrectedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double& vtxAngle, double& vtxTime, double& fom) +//{ +// // figure of merit +// // =============== +// double vtxFOM = 0.0; +// double timeFOM = 0.0; +// double coneFOM = 0.0; +// double penaltyFOM = 0.0; +// double fixPositionFOM = 0.0; +// double fixDirectionFOM = 0.0; +// +// // calculate residuals +// // =================== +// this->fVtxGeo->CalcExtendedResiduals(vtxX,vtxY,vtxZ,0.0,dirX,dirY,dirZ); +// +// // calculate figure of merit +// // ========================= +// +// this->ConePropertiesFoM(vtxAngle,coneFOM); +// fom = coneFOM; +// +// // truncate +// if( fom<-999.999*fBaseFOM ) fom = -999.999*fBaseFOM; +// +// return; +//} +// +//void FoMCalculator::ConePropertiesLnL(double coneParam0, double coneParam1, double coneParam2, double& coneAngle, double& coneFOM) +//{ +// +// // nuisance parameters +// // =================== +// double alpha = coneParam0; // track length parameter = 0.25 +// double alpha0 = coneParam1; // track length parameter = 0.5 +// double beta = coneParam2; // particle ID: 0.0[electron]->1.0[muon] = 0.75 +// +// // internal variables +// // ================== +// double deltaAngle = 0.0; // +// double sigmaAngle = 7.0; //Cherenkov Angle resolution +// double Angle0 = Parameters::CherenkovAngle(); //Cherenkov Angle: 42 degree +// double deltaAngle0 = Angle0*alpha0; //? +// +// double digitQ = 0.0; +// double sigmaQmin = 1.0; +// double sigmaQmax = 10.0; +// double sigmaQ = 0.0; +// +// double A = 0.0; +// +// double PconeA = 0.0; +// double PconeB = 0.0; +// double Pmu = 0.0; +// double Pel = 0.0; +// +// double Pcharge = 0.0; +// double Pangle = 0.0; +// double P = 0.0; +// +// double chi2 = 0.0; +// double ndof = 0.0; +// +// double angle = 46.0; +// double fom = 0.0; +// +// // hard-coded parameters: 200 kton (100 kton) +// // ========================================== +// double lambdaMuShort = 0.5; // 0.5; +// double lambdaMuLong = 5.0; // 15.0; +// double alphaMu = 1.0; // 4.5; +// +// double lambdaElShort = 1.0; // 2.5; +// double lambdaElLong = 7.5; // 15.0; +// double alphaEl = 6.0; // 3.5; +// +// // numerical integrals +// // =================== +// fSconeA = 21.9938; +// fSconeB = 0.0000; +// +// // Number of P.E. angular distribution +// // inside cone +// int nbinsInside = 420; //divide the angle range by 420 bins +// for( int n=0; nfVtxGeo->GetNDigits(); idigit++ ){ +// +// if( this->fVtxGeo->IsFiltered(idigit) ){ +// digitQ = this->fVtxGeo->GetDigitQ(idigit); +// deltaAngle = this->fVtxGeo->GetAngle(idigit) - Angle0; +// +// // pulse height distribution +// // ========================= +// if( deltaAngle<=0 ){ //inside Cone +// sigmaQ = sigmaQmax; +// } +// else{ //outside Cone +// sigmaQ = sigmaQmin + (sigmaQmax-sigmaQmin)/(1.0+(deltaAngle*deltaAngle)/(sigmaAngle*sigmaAngle)); +// } +// +// A = 1.0/(log(2.0)+0.5*TMath::Pi()*sigmaQ); +// +// if( digitQ<1.0 ){ +// Pcharge = 2.0*A*digitQ/(1.0+digitQ*digitQ); +// } +// else{ +// Pcharge = A/(1.0+(digitQ-1.0)*(digitQ-1.0)/(sigmaQ*sigmaQ)); +// } +// +// // angular distribution +// // ==================== +// A = 1.0/( alpha*fSconeA + (1.0-alpha)*fSconeB +// + beta*fSmu + (1.0-beta)*fSel ); // numerical integrals +// +// if( deltaAngle<=0 ){ +// +// // pdfs inside cone: +// PconeA = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ); +// PconeB = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) +// *( 1.0/(1.0+(deltaAngle*deltaAngle)/(deltaAngle0*deltaAngle0)) ); +// +// Pangle = A*( alpha*PconeA+(1.0-alpha)*PconeB ); +// } +// else{ +// +// // pdfs outside cone +// Pmu = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) +// *( 1.0/(1.0+alphaMu*(lambdaMuShort/lambdaMuLong)) )*( 1.0/(1.0+(deltaAngle*deltaAngle)/(lambdaMuShort*lambdaMuShort)) +// + alphaMu*(lambdaMuShort/lambdaMuLong)/(1.0+(deltaAngle*deltaAngle)/(lambdaMuLong*lambdaMuLong)) ); +// +// Pel = 1.4944765*sin( (Angle0+deltaAngle)*(TMath::Pi()/180.0) ) +// *( 1.0/(1.0+alphaEl*(lambdaElShort/lambdaElLong)) )*( 1.0/(1.0+(deltaAngle*deltaAngle)/(lambdaElShort*lambdaElShort)) +// + alphaEl*(lambdaElShort/lambdaElLong)/(1.0+(deltaAngle*deltaAngle)/(lambdaElLong*lambdaElLong)) ); +// +// Pangle = A*( beta*Pmu+(1.0-beta)*Pel ); +// } +// +// // overall probability +// // =================== +// P = Pcharge*Pangle; +// +// chi2 += -2.0*log(P); +// ndof += 1.0; +// } +// } +// +// // calculate figure of merit +// // ========================= +// if( ndof>0.0 ){ +// fom = fBaseFOM - 5.0*chi2/ndof; +// angle = beta*43.0 + (1.0-beta)*49.0; +// } +// +// // return figure of merit +// // ====================== +// coneAngle = angle; +// coneFOM = fom; +// +// return; +//} diff --git a/DataModel/FoMCalculator.h b/DataModel/FoMCalculator.h index a9172ded3..fdd51bdc2 100644 --- a/DataModel/FoMCalculator.h +++ b/DataModel/FoMCalculator.h @@ -1,5 +1,5 @@ /************************************************************************* - > File Name: MinuitOptimizer.hh + > File Name: FoMCalculator.hh > Author: Jingbo Wang, Teal Pershing > mail: jiowang@ucdavis.edu, tjpershing@ucdavis.edu > Created Time: MAY 07, 2019 @@ -50,6 +50,7 @@ class FoMCalculator { double FindSimpleTimeProperties(double myConeEdge); void TimePropertiesLnL(double vtxTime, double& vtxFom); void ConePropertiesFoM(double coneEdge, double& chi2); + void ConePropertiesLnL(double vtxX, double vtxY, double VtxZ, double dirX, double dirY, double dirZ, double coneEdge, double& chi2, TH1D angularDist, double& phimax, double& phimin); void PointPositionChi2(double vtxX, double vtxY, double vtxZ, double vtxTime, double& fom); void PointDirectionChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneAngle, double& fom); void PointVertexChi2(double vtxX, double vtxY, double vtxZ, @@ -58,6 +59,9 @@ class FoMCalculator { void ExtendedVertexChi2(double vtxX, double vtxY, double vtxZ, double dirX, double dirY, double dirZ, double coneAngle, double vtxTime, double& fom); + void ExtendedVertexChi2(double vtxX, double vtxY, double vtxZ, + double dirX, double dirY, double dirZ, + double coneAngle, double vtxTime, double& fom, TH1D pdf); // void ConePropertiesLnL(double coneParam0, double coneParam1, double coneParam2, double& coneAngle, double& coneFOM); // void CorrectedVertexChi2(double vtxX, double vtxY, double vtxZ, // double dirX, double dirY, double dirZ, diff --git a/DataModel/MinuitOptimizer.cpp b/DataModel/MinuitOptimizer.cpp old mode 100644 new mode 100755 diff --git a/DataModel/MinuitOptimizer.h b/DataModel/MinuitOptimizer.h old mode 100644 new mode 100755 diff --git a/UserTools/DigitBuilder/DigitBuilder.cpp b/UserTools/DigitBuilder/DigitBuilder.cpp index b3a5a3e4e..f3c2c0043 100644 --- a/UserTools/DigitBuilder/DigitBuilder.cpp +++ b/UserTools/DigitBuilder/DigitBuilder.cpp @@ -29,7 +29,7 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ fParametricModel = 0; fIsMC = 1; fDigitChargeThr = 10; - + /// Get the Tool configuration variables m_variables.Get("verbosity",verbosity); @@ -43,9 +43,11 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ m_variables.Get("DigitChargeThr",fDigitChargeThr); m_variables.Get("ChankeyToPMTIDMap",path_chankeymap); m_variables.Get("SinglePEGains",singlePEgains); + m_variables.Get("StripHit", striphit); /// Construct the other objects we'll be setting at event level, fDigitList = new std::vector; + fHitLAPPDs = new std::vector; // Make the RecoDigit Store if it doesn't exist int recoeventexists = m_data->Stores.count("RecoEvent"); @@ -57,6 +59,7 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ Log("DigitBuilder Tool: Error retrieving Geometry from ANNIEEvent!",v_error,verbosity); return false; } + std::cout << "Strip Hit Mode:" << striphit << endl; // Some hard-coded values of old WCSim LAPPDIDs are in this Tool // I would recommend moving away from the use of WCSim IDs if possible as they are liable to change @@ -267,6 +270,7 @@ bool DigitBuilder::BuildMCPMTRecoDigit() { } else { calT = hitTimes.at(timesize/2); } + //calT = frand.Gaus(calT, 1.0); calQ = 0.; for(std::vector::iterator it = hitCharges.begin(); it != hitCharges.end(); ++it){ calQ += *it; @@ -296,6 +300,7 @@ bool DigitBuilder::BuildMCPMTRecoDigit() { std::cout << "PMT Charge,Time: " << to_string(calQ) << "," << to_string(calT) << std::endl; } + calT = frand.Gaus(calT, 1.0); digitType = RecoDigit::PMT8inch; RecoDigit recoDigit(region, pos_reco, calT, calQ, digitType, PMTId); //recoDigit.Print(); @@ -320,9 +325,14 @@ bool DigitBuilder::BuildMCLAPPDRecoDigit() { int digitType = -999; Detector* det=nullptr; Position pos_sim, pos_reco; + int currentLAPPD = 0; + if (fHitLAPPDs->size() > 0) { + fHitLAPPDs->clear(); + } + // repeat for LAPPD hits // MCLAPPDHits is a std::map> - if(fMCLAPPDHits){ + if(fMCLAPPDHits && fMCLAPPDHits->size() > 0){ Log("DigitBuilder Tool: Num LAPPD Digits = "+to_string(fMCLAPPDHits->size()),v_message,verbosity); // iterate over the map of sensors with a measurement for(std::pair>&& apair : *fMCLAPPDHits){ @@ -342,45 +352,126 @@ bool DigitBuilder::BuildMCLAPPDRecoDigit() { if(!isSelectedLAPPD && fLAPPDId.size()>0) continue; if(verbosity>2){ std::cout << "Loading in digits for LAPPDID " << LAPPDId << std::endl; + std::cout << "located: "; + det->GetPositionInTank().Print(); + std::cout << "directed: "; + det->GetDetectorDirection().Print(); } - if(det->GetDetectorElement()=="LAPPD"){ // redundant, MCLAPPDHits are LAPPD hitss - std::vector& hits = apair.second; - for(MCLAPPDHit& ahit : hits){ - //if(v_message4) { - std::cout << "LAPPD position (XGetDetectorElement() == "LAPPD") { // redundant, MCLAPPDHits are LAPPD hitss + std::vector& hits = apair.second; + + std::vector sumposX; + std::vector sumposY; + std::vector sumposZ; + std::vector sumT; + double posX; + std::vector nHitsOnStrip; + int a; + for (int i = 0; i < 28; i++) { + sumposX.push_back(0); + sumposY.push_back(0); + sumposZ.push_back(0); + sumT.push_back(0); + nHitsOnStrip.push_back(0); } - // I found the charge is 0 for all the hits. In order to test the code, - // here I just set the charge to 1. We should come back to this later. (Jingbo Wang) - calQ = 1.; - digitType = RecoDigit::lappd_v0; - RecoDigit recoDigit(region, pos_reco, calT, calQ, digitType,LAPPDId); - //if(v_message40 || calT<-10) continue; // cut off delayed hits - fDigitList->push_back(recoDigit); + for(MCLAPPDHit& ahit : hits){ + if (LAPPDId != currentLAPPD && hits.size() > 3) { + std::cout << "THERE ARE HITS ON LAPPD " << LAPPDId << endl; + currentLAPPD = LAPPDId; + fHitLAPPDs->push_back(currentLAPPD); + std::cout << "fHitLAPPDs size: " << fHitLAPPDs->size() << endl; + } + if (striphit == 0) { + //if(v_message 4) { + std::cout << "LAPPD position (X 40 || calT < -10) continue; // cut off delayed hits + fDigitList->push_back(recoDigit); + + } + else { + posX = (ahit.GetPosition().at(0) * 100 + xshift) - (det->GetPositionInTank().X() * 100 + xshift); + double dirX = det->GetDetectorDirection().X(); + double AngX = std::asin(dirX); + int strip = (int)((posX / (20.* std::sin(AngX) / 28.)) + 14 - 1); + if (strip > 27 || strip < 0) { + Log("warning: LAPPD hit found off LAPPD: ", v_debug, verbosity); + std::cout << "hit found on strip " << strip << endl; + std::cout << "LAPPD truehit X,Y,Z: " << ahit.GetPosition().at(0) << ", "; + std::cout << ahit.GetPosition().at(1) << ", "; + std::cout << ahit.GetPosition().at(2) << endl; + std::cout << "continuing loop without this hit." << endl; + continue; + } + std::cout << "hit found on strip " << strip << endl; + sumposX.at(strip) += ahit.GetPosition().at(0) * 100 + xshift; + std::cout << "LAPPD truehit X,Y,Z: " << ahit.GetPosition().at(0) << ", "; + sumposY.at(strip) += ahit.GetPosition().at(1) * 100 + yshift; + std::cout << ahit.GetPosition().at(1) << ", "; + sumposZ.at(strip) += ahit.GetPosition().at(2) * 100 + zshift; + std::cout << ahit.GetPosition().at(2) << endl; + + if ((striphit == 3 && nHitsOnStrip.at(strip) < 3) || (striphit==2 && nHitsOnStrip.at(strip) == 0) || striphit == 1) + sumT.at(strip) += frand.Gaus(calT, 0.1); // time is smeared with 100 ps time resolution. Harded-coded for now. + nHitsOnStrip.at(strip) += 1; + + } } + if (striphit != 0) { + for (int strip = 0; strip < 28; strip++) { + if (nHitsOnStrip.at(strip) != 0) { + pos_reco.SetX(sumposX.at(strip) / nHitsOnStrip.at(strip)); + pos_reco.SetY(sumposY.at(strip) / nHitsOnStrip.at(strip)); + pos_reco.SetZ(sumposZ.at(strip) / nHitsOnStrip.at(strip)); + if(striphit == 1) calT = sumT.at(strip) / nHitsOnStrip.at(strip); + if (striphit == 3) calT = sumT.at(strip) / 3; + calQ = nHitsOnStrip.at(strip); //set to the number of hits for now. + digitType = RecoDigit::lappd_v0; + + std::cout << "LAPPD ID: " << to_string(LAPPDId) << endl; + std::cout << "LAPPD strip-hit position (Xpush_back(recoDigit); + } + } + } + sumposX.clear(); + sumposY.clear(); + sumposZ.clear(); + sumT.clear(); + nHitsOnStrip.clear(); } } // end loop over MCLAPPDHits } else { cout<<"No MCLAPPDHits"<Stores.at("RecoEvent")->Set("RecoDigit", fDigitList, savetodisk); ///> Add digits to RecoEvent + m_data->Stores.at("RecoEvent")->Set("HitLAPPDs", fHitLAPPDs, savetodisk); } void DigitBuilder::Reset() { diff --git a/UserTools/DigitBuilder/DigitBuilder.h b/UserTools/DigitBuilder/DigitBuilder.h index ed3986175..d774be9f5 100644 --- a/UserTools/DigitBuilder/DigitBuilder.h +++ b/UserTools/DigitBuilder/DigitBuilder.h @@ -72,7 +72,7 @@ class DigitBuilder: public Tool { int verbosity=1; std::string fInputfile; unsigned long fNumEvents; - + std::vector* fHitLAPPDs; std::vector fLAPPDId; ///< selected LAPPDs std::string fPhotodetectorConfiguration; ///< "PMTs_Only", "LAPPDs_Only", "All_Detectors" bool fParametricModel; ///< configures if PMTs hits for each event are accumulated into one hit per PMT @@ -81,6 +81,7 @@ class DigitBuilder: public Tool { double fDigitChargeThr; std::string path_chankeymap; std::string singlePEgains; + int striphit; //0 all LAPPD Hits as true; 1 average all times per strip; 2 use first time for each strip Geometry* fGeometry=nullptr; ///< ANNIE Geometry TRandom3 frand; ///< Random number generator diff --git a/UserTools/DirectionGridCheck/DirectionGridCheck.cpp b/UserTools/DirectionGridCheck/DirectionGridCheck.cpp new file mode 100644 index 000000000..022a0bdff --- /dev/null +++ b/UserTools/DirectionGridCheck/DirectionGridCheck.cpp @@ -0,0 +1,245 @@ +#include "DirectionGridCheck.h" + +DirectionGridCheck::DirectionGridCheck():Tool(){} + + +bool DirectionGridCheck::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + + m_variables.Get("OutputFile", OutputFile); + m_variables.Get("ShowEvent", showEvent); + m_variables.Get("verbosity", verbosity); + + fOutput_tfile = new TFile("DGCheck.root", "recreate"); + AngularPlot = new TGraph(); + AngularPlot->SetTitle("Seed Directions in Angular Space"); + AngularPlot->GetXaxis()->SetTitle("Polar Angle"); + AngularPlot->GetYaxis()->SetTitle("ZenithAngle"); + AngularPlot->SetMarkerStyle(3); + AngularPlot->SetMarkerColor(1); + AngularPlot->SetLineColor(0); + TrueDirPlot = new TGraph(); + TrueDirPlot->SetTitle("TrueDirection"); + TrueDirPlot->SetMarkerColor(3); + TrueDirPlot->SetMarkerStyle(25); + TrueDirPlot->SetLineColor(0); + MRDDirPlot = new TGraph(); + MRDDirPlot->SetTitle("MRDDirection"); + MRDDirPlot->SetMarkerColor(2); + MRDDirPlot->SetMarkerStyle(26); + MRDDirPlot->SetLineColor(0); + SimpDirPlot = new TGraph(); + SimpDirPlot->SetTitle("SimpleDirection"); + SimpDirPlot->SetMarkerColor(4); + SimpDirPlot->SetMarkerStyle(27); + SimpDirPlot->SetLineColor(0); + RecoDirPlot = new TGraph(); + RecoDirPlot->SetMarkerColor(5); + RecoDirPlot->SetMarkerStyle(28); + RecoDirPlot->SetLineColor(0); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + return true; +} + + +bool DirectionGridCheck::Execute(){ + + auto* annie_event = m_data->Stores["RecoEvent"]; + if (!annie_event) { + Log("Error: The PhaseITreeMaker tool could not find the ANNIEEvent Store", + 0, verbosity); + return false; + } + + // MC entry number + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum", fMCEventNum); + + // MC trigger number + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum", fMCTriggerNum); + + // ANNIE Event number + m_data->Stores.at("ANNIEEvent")->Get("EventNumber", fEventNumber); + + auto get_flags = m_data->Stores.at("RecoEvent")->Get("EventFlagged", fEventStatusFlagged); + + if ((fEventStatusFlagged) != 0) { + // if (!fEventCutStatus){ + Log("PhaseIITreeMaker Tool: Event was flagged with one of the active cuts.", v_debug, verbosity); + return true; + } + + // Only check this event + //if (showEvent > 0 && (int)fEventNumber != showEvent) return true; + if (eventCount > 9)return true; + + VertexGeometry* myvtxgeo = VertexGeometry::Instance(); + Direction tempdir; + + + if (eventCount == 0) { + for (int l = 0; l < 100; l++) { + double phi = (6 * TMath::Pi() / 50) * l; + double theta = (TMath::Pi() / 200) * l; + + while (phi > 2 * TMath::Pi()) { + std::cout << "correcting theta" << endl; + phi -= 2 * TMath::Pi(); + } + + tempdir.SetTheta(theta); + tempdir.SetPhi(phi); + AngularPlot->SetPoint(l, phi, theta); + std::cout << "Angular Plot set:" << l << ", " << phi << ", " << theta << endl; + } + } + RecoVertex* truevtx = 0; + RecoVertex* recovtx = 0; + auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex", truevtx); + auto get_muonReco = m_data->Stores.at("RecoEvent")->Get("ExtendedVertex", recovtx); + double truePhi = truevtx->GetDirection().GetPhi(); + double trueTheta = truevtx->GetDirection().GetTheta(); + double RecoDirX = recovtx->GetDirection().X(); + double RecoDirY = recovtx->GetDirection().Y(); + double RecoDirZ = recovtx->GetDirection().Z(); + double recoPhi = atan(RecoDirY/RecoDirX); + double recoTheta = asin(RecoDirX * RecoDirX + RecoDirY * RecoDirY); + if (trueTheta < 0) trueTheta += 2*TMath::Pi(); + if (trueTheta > 2 * TMath::Pi()) trueTheta -= 2 * TMath::Pi(); + TrueDirPlot->SetPoint(eventCount, truePhi, trueTheta); + std::cout << "True Plot set: " << eventCount << ", " << truePhi << ", " << trueTheta << endl; + Direction MRDDirection = this->findDirectionMRD(); + MRDDirPlot->SetPoint(eventCount, MRDDirection.GetPhi(), MRDDirection.GetTheta()); + std::cout << "MRD Plot set: " << eventCount << ", " << MRDDirection.GetPhi() << ", " << MRDDirection.GetTheta() << endl; + RecoDirPlot->SetPoint(eventCount, recoPhi, recoTheta); + std::cout << "recoPlot set: " << eventCount << ", " << recoPhi << ", " << recoTheta << endl; + + eventCount++; + return true; +} + + +bool DirectionGridCheck::Finalise(){ + fOutput_tfile->cd(); + AngularPlot->Write("Angular Grid"); + TrueDirPlot->Write("trueDirection"); + MRDDirPlot->Write("MRDDirection"); + RecoDirPlot->Write("recoDirection"); + fOutput_tfile->Write(); + fOutput_tfile->Close(); + return true; +} + +Direction DirectionGridCheck::findDirectionMRD() { + std::vector* Tracks; + int numtracksinev; + m_data->Stores["MRDTracks"]->Get("MRDTracks", Tracks); + m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numtracksinev); + + if (numtracksinev > 1) Log("Multiple tracks need work; just using first for now", v_debug, verbosity); + double gradx, grady, theta, phi; + Direction startVertex, endVertex, result; + BoostStore* thisTrack = &(Tracks->at(0)); + + thisTrack->Get("VTrackGradient", gradx); + thisTrack->Get("HTrackGradient", grady); + phi = atan(grady / gradx); + theta = asin(pow((gradx * gradx + grady * grady), 0.5)); + /*TRandom3 smear; + Direction vtxDir = fTrueVertex->GetDirection(); + Direction result; + result.SetTheta(smear.Gaus(vtxDir.GetTheta(), 0.4)); + result.SetPhi(smear.Gaus(vtxDir.GetPhi(), 0.4));*/ + result.SetTheta(theta); + result.SetPhi(phi); + + return result; +} + +RecoVertex* DirectionGridCheck::FindSimpleDirection(RecoVertex* myVertex) { + + /// get vertex position + double vtxX = myVertex->GetPosition().X(); + double vtxY = myVertex->GetPosition().Y(); + double vtxZ = myVertex->GetPosition().Z(); + double vtxTime = myVertex->GetTime(); + + std::cout << "Simple Direction Input Position: (" << vtxX << "," << vtxY << "," << vtxZ << ")\n"; + // current status + // ============== + int status = myVertex->GetStatus(); + + /// loop over digits + /// ================ + double Swx = 0.0; + double Swy = 0.0; + double Swz = 0.0; + double Sw = 0.0; + double digitq = 0.; + double dx, dy, dz, ds, px, py, pz, q; + + RecoDigit digit; + for (int idigit = 0; idigit < fDigitList->size(); idigit++) { + digit = fDigitList->at(idigit); + if (digit.GetFilterStatus()) { + q = digit.GetCalCharge(); + dx = digit.GetPosition().X() - vtxX; + dy = digit.GetPosition().Y() - vtxY; + dz = digit.GetPosition().Z() - vtxZ; + ds = sqrt(dx * dx + dy * dy + dz * dz); + px = dx / ds; + py = dx / ds; + pz = dz / ds; + Swx += q * px; + Swy += q * py; + Swz += q * pz; + Sw += q; + } + } + + /// average direction + /// ================= + double dirX = 0.0; + double dirY = 0.0; + double dirZ = 0.0; + + int itr = 0; + bool pass = 0; + double fom = 0.0; + + if (Sw > 0.0) { + double qx = Swx / Sw; + double qy = Swy / Sw; + double qz = Swz / Sw; + double qs = sqrt(qx * qx + qy * qy + qz * qz); + + dirX = qx / qs; + dirY = qy / qs; + pass = 1; + } + + // set vertex and direction + // ======================== + RecoVertex* newVertex = new RecoVertex(); // Note: pointer must be deleted by the invoker + + if (pass) { + newVertex->SetVertex(vtxX, vtxY, vtxZ, vtxTime); + newVertex->SetDirection(dirX, dirY, dirZ); + newVertex->SetFOM(fom, itr, pass); + } + + // set status + // ========== + if (!pass) status |= RecoVertex::kFailSimpleDirection; + newVertex->SetStatus(status); + cout << "simple direction: " << dirX << ", " << dirY << ", " << dirZ << endl; + + // return vertex + // ============= + return newVertex; +} \ No newline at end of file diff --git a/UserTools/DirectionGridCheck/DirectionGridCheck.h b/UserTools/DirectionGridCheck/DirectionGridCheck.h new file mode 100644 index 000000000..ef6c6f7df --- /dev/null +++ b/UserTools/DirectionGridCheck/DirectionGridCheck.h @@ -0,0 +1,80 @@ +#ifndef DirectionGridCheck_H +#define DirectionGridCheck_H + +#include +#include + +#include "Tool.h" +#include "TH1.h" +#include "TH2D.h" +#include "TFile.h" + +#include "VertexGeometry.h" +#include "Parameters.h" +#include "TTree.h" + + +/** + * \class DirectionGridCheck + * + * This is a debug tool to look at the differences between the various directions associated with a muontrack event. +* +* $Author: F. A. Lemmons $ +* $Date: 2024/02/22 01:38:00 $ +* Contact: franklin.lemmons@mines.sdsmt.edu +*/ +class DirectionGridCheck: public Tool { + + + public: + + DirectionGridCheck(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + RecoVertex* FindSimpleDirection(RecoVertex* myVertex); + Direction findDirectionMRD(); + + + private: + std::string OutputFile; + int showEvent; + TFile* fOutput_tfile = nullptr; + TTree* fVertexGeometry = nullptr; + /// \brief MC entry number + uint64_t fMCEventNum; + + /// \brief trigger number + uint16_t fMCTriggerNum; + + /// \brief ANNIE event number + uint32_t fEventNumber; + + std::vector* fDigitList = 0; + RecoVertex* fTrueVertex = 0; + RecoVertex* fSDVertex = 0; + int verbosity = -1; + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + + int eventCount = 0; + + // \brief Event Status flag masks + int fEventStatusApplied; + int fEventStatusFlagged; + std::vector* theMRDTracks; + + std::vector* theMrdTracks; // the MRD tracks + TGraph* AngularPlot = 0; + TGraph* MRDDirPlot = 0; + TGraph* TrueDirPlot = 0; + TGraph* SimpDirPlot = 0; + TGraph* RecoDirPlot = 0; + TTree* DirectionTree = 0; + +}; + + +#endif diff --git a/UserTools/DirectionGridCheck/README.md b/UserTools/DirectionGridCheck/README.md new file mode 100644 index 000000000..f7c9b7772 --- /dev/null +++ b/UserTools/DirectionGridCheck/README.md @@ -0,0 +1,20 @@ +# DirectionGridCheck + +DirectionGridCheck + +## Data + +Describe any data formats DirectionGridCheck creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for DirectionGridCheck. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/EventSelector/EventSelector.cpp b/UserTools/EventSelector/EventSelector.cpp index 2f353fee5..29cae2a6d 100644 --- a/UserTools/EventSelector/EventSelector.cpp +++ b/UserTools/EventSelector/EventSelector.cpp @@ -34,6 +34,7 @@ bool EventSelector::Initialise(std::string configfile, DataModel &data){ m_variables.Get("Emax",Emax); m_variables.Get("NHitCut", fNHitCut); m_variables.Get("NHitmin", fNHitmin); + m_variables.Get("LAPPDMult", fLAPPDMultMin); m_variables.Get("PromptTrigOnly", fPromptTrigOnly); m_variables.Get("RecoFVCut", fRecoFVCut); m_variables.Get("RecoPMTVolCut", fRecoPMTVolCut); @@ -46,6 +47,8 @@ bool EventSelector::Initialise(std::string configfile, DataModel &data){ m_variables.Get("SaveStatusToStore", fSaveStatusToStore); m_variables.Get("IsMC",fIsMC); m_variables.Get("RecoPDG",fRecoPDG); + m_variables.Get("TriggerExtendedWindow",fTriggerExtended); + m_variables.Get("BeamOK",fBeamOK); m_variables.Get("CutConfiguration",fCutConfigurationName); if (!fIsMC){fMCFVCut = false; fMCPMTVolCut = false; fMCMRDCut = false; fMCPiKCut = false; fMCIsMuonCut = false; fMCIsElectronCut = false; fMCIsSingleRingCut = false; fMCIsMultiRingCut = false; fMCProjectedMRDHit = false; fMCEnergyCut = false; fPromptTrigOnly = false;} @@ -109,6 +112,15 @@ bool EventSelector::Execute(){ Log("EventSelector Tool: Error retrieving RecoDigits,no digit from the RecoEvent!",v_warning,verbosity); /*return false;*/ } + auto has_LAPPDMult = m_data->Stores.at("RecoEvent")->Get("HitLAPPDs", fHitLAPPDs); + if (not has_LAPPDMult) { + Log("EventSelector Tool: No count of hit LAPPDs; proceeding without LAPPD multiplicity cut.", v_warning, verbosity); + fLAPPDMultMin = 0; + fHitLAPPDs = new std::vector; + } + else { + Log("EventSelector Tool: # of LAPPDs hit in this event: " + std::to_string(fHitLAPPDs->size()), v_debug, verbosity); + } // BEGIN CUTS USING TRUTH INFORMATION // @@ -206,10 +218,20 @@ bool EventSelector::Execute(){ bool passThroughGoingCut = true; m_data->Stores.at("RecoEvent")->Set("ThroughGoing",passThroughGoingCut); - std::vector cluster_reco_pdg; - bool passRecoPDGCut = this->EventSelectionByRecoPDG(fRecoPDG, cluster_reco_pdg); - m_data->Stores.at("RecoEvent")->Set("RecoPDGVector",cluster_reco_pdg); - m_data->Stores.at("RecoEvent")->Set("PDG",fRecoPDG); + bool passRecoPDGCut = 0; + std::cout << "fRecoPDG: " << fRecoPDG << endl; + if (fRecoPDG != -1) { + std::vector cluster_reco_pdg; + passRecoPDGCut = this->EventSelectionByRecoPDG(fRecoPDG, cluster_reco_pdg); + m_data->Stores.at("RecoEvent")->Set("RecoPDGVector", cluster_reco_pdg); + m_data->Stores.at("RecoEvent")->Set("PDG", fRecoPDG); + } + + bool passExtendedCut = this->EventSelectionByTriggerExtended(); + m_data->Stores.at("RecoEvent")->Set("TriggerExtended",passExtendedCut); + + bool passBeamOKCut = this->EventSelectionByBeamOK(); + m_data->Stores.at("RecoEvent")->Set("BeamOK",passBeamOKCut); // Fill the EventSelection mask for the cuts that are supposed to be applied if (fMCPiKCut){ @@ -240,7 +262,7 @@ bool EventSelector::Execute(){ if(fNHitCut){ fEventApplied |= EventSelector::kFlagNHit; - if(!HasEnoughHits) fEventFlagged |= EventSelector::kFlagNHit; + if(!HasEnoughHits || (fLAPPDMultMin > 0 && fHitLAPPDs->size() < fLAPPDMultMin)) fEventFlagged |= EventSelector::kFlagNHit; } if (fMCEnergyCut){ @@ -329,6 +351,16 @@ bool EventSelector::Execute(){ if (!passTriggerCut) fEventFlagged |= EventSelector::kFlagTrigger; } + if (fTriggerExtended){ + fEventApplied |= EventSelector::kFlagExtended; + if (!passExtendedCut) fEventFlagged |= EventSelector::kFlagExtended; + } + + if (fBeamOK){ + fEventApplied |= EventSelector::kFlagBeamOK; + if (!passBeamOKCut) fEventFlagged |= EventSelector::kFlagBeamOK; + } + if (fRecoPDG != -1){ fEventApplied |= EventSelector::kFlagRecoPDG; if (!passRecoPDGCut) fEventFlagged |= EventSelector::kFlagRecoPDG; @@ -338,7 +370,10 @@ bool EventSelector::Execute(){ if(fEventCutStatus){ Log("EventSelector Tool: Event is clean according to current event selection.",v_message,verbosity); } - if(fSaveStatusToStore) m_data->Stores.at("RecoEvent")->Set("EventCutStatus", fEventCutStatus); + if(fSaveStatusToStore) { + m_data->Stores.at("RecoEvent")->Set("EventCutStatus", fEventCutStatus); + m_data->Stores.at("ANNIEEvent")->Set("EventCutStatus", fEventCutStatus); + } m_data->Stores.at("RecoEvent")->Set("EventFlagApplied", fEventApplied); m_data->Stores.at("RecoEvent")->Set("EventFlagged", fEventFlagged); @@ -349,6 +384,9 @@ bool EventSelector::Execute(){ if (verbosity > 1) std::cout <<"EventCutStatus: "<(fEventApplied) << ", fEventFlagged: " << std::bitset<32>(fEventFlagged) << std::endl; + //std::cout <<"EventCutStatus: "<GetMrdEnd()*100-168.1; double mrdHeightY = fGeometry->GetMrdHeight()*100; double mrdWidthX = fGeometry->GetMrdWidth()*100; - std::cout <<"mrdStartZ: "<mrdEndZ || muonStopX<-1.0*mrdWidthX || muonStopX>mrdWidthX || muonStopY<-1.0*mrdHeightY || muonStopY>mrdHeightY) { @@ -626,10 +663,10 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { m_data->Stores["RecoEvent"]->Set("NumPMTClusters",pmt_cluster_size); vec_pmtclusters_charge->clear(); vec_pmtclusters_time->clear(); - m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,false); - m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,false); + m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,true); + m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,true); vec_mrdclusters_time->clear(); - m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time); + m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time,true); if (verbosity > 1) std::cout <<"pmt_cluster_size: "<Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,false); - m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,false); + m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,true); + m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,true); std::vector mrd_meantimes; if (verbosity > 1) std::cout <<"MrdTimeClusters.size(): "<push_back(mrd_meantimes.at(i)); } - m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time); + m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time, true); if (fIsMC){ if (MrdTimeClusters.size() == 0 || m_all_clusters_MC->size() == 0) return false; @@ -736,16 +773,24 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { pmtmrd_coinc_min = fPMTMRDOffset - 50; pmtmrd_coinc_max = fPMTMRDOffset + 50; + std::vector vector_mrd_coincidence; + bool coincidence = false; for (int i_mrd = 0; i_mrd < int(mrd_meantimes.size()); i_mrd++){ double time_diff = mrd_meantimes.at(i_mrd) - pmt_time; if (verbosity > 0) std::cout <<"MRD time: "< 1) std::cout <<"max_charge: "< pmtmrd_coinc_min && time_diff < pmtmrd_coinc_max && max_charge > 200 && n_hits >= 20){ + Log("EventSelector tool: Adding MRD coincidence to Vector.", v_debug, verbosity); coincidence = true; + vector_mrd_coincidence.push_back(i_mrd); } } + + m_data->Stores["RecoEvent"]->Set("MRDCoincidenceCluster",vector_mrd_coincidence); return coincidence; @@ -1054,4 +1099,20 @@ bool EventSelector::EventSelectionByRecoPDG(int recoPDG, std::vector & c return found_pdg; } +bool EventSelector::EventSelectionByTriggerExtended(){ + + int fExtended = 0; + m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); + if (fExtended == 1) return true; + else return false; + +} + +bool EventSelector::EventSelectionByBeamOK(){ + BeamStatus beamstat; + m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + if (beamstat.ok()) return true; + else return false; + +} diff --git a/UserTools/EventSelector/EventSelector.h b/UserTools/EventSelector/EventSelector.h old mode 100644 new mode 100755 index 3e65cd47f..a35c0a36d --- a/UserTools/EventSelector/EventSelector.h +++ b/UserTools/EventSelector/EventSelector.h @@ -19,6 +19,8 @@ #include "ANNIEGeometry.h" #include "TMath.h" +#include "BeamStatus.h" + class EventSelector: public Tool { @@ -51,7 +53,9 @@ class EventSelector: public Tool { kFlagVeto = 0x20000, //131072 kFlagTrigger = 0x40000, kFlagThroughGoing = 0x80000, - kFlagRecoPDG = 0x1000000, + kFlagRecoPDG = 0x100000, + kFlagExtended = 0x200000, + kFlagBeamOK = 0x400000, } EventFlags_t; private: @@ -176,6 +180,16 @@ class EventSelector: public Tool { // bool EventSelectionByRecoPDG(int recoPDG, std::vector & vector_reco_pdg); + /// \brief Event selection for extended acquisition windows + // + /// This event selection criterion flags events with an extended trigger window (70us) + bool EventSelectionByTriggerExtended(); + + /// \brief Event selection for beam status + /// + /// This event selection criterion flags events for which beam status was ok + bool EventSelectionByBeamOK(); + /// \brief MC entry number uint64_t fMCEventNum; @@ -193,6 +207,7 @@ class EventSelector: public Tool { RecoVertex* fMuonStartVertex = nullptr; ///< true muon start vertex RecoVertex* fMuonStopVertex = nullptr; ///< true muon stop vertex std::vector* fDigitList; ///< Reconstructed Hits including both LAPPD hits and PMT hits + std::vector* fHitLAPPDs; RecoVertex* fRecoVertex = nullptr; ///< Reconstructed Vertex std::map>* m_all_clusters; ///< clustered PMT hits std::map>* m_all_clusters_MC; ///< clustered PMT hits @@ -237,6 +252,9 @@ class EventSelector: public Tool { bool fIsMC; int fTriggerWord; int fRecoPDG; + bool fTriggerExtended = false; + bool fBeamOK = false; + int fLAPPDMultMin = 0; std::string fCutConfigurationName; bool get_mrd = false; diff --git a/UserTools/EventSelectorDoE/EventSelectorDoE.cpp b/UserTools/EventSelectorDoE/EventSelectorDoE.cpp index 787f6e605..b4ea7e757 100644 --- a/UserTools/EventSelectorDoE/EventSelectorDoE.cpp +++ b/UserTools/EventSelectorDoE/EventSelectorDoE.cpp @@ -16,9 +16,6 @@ bool EventSelectorDoE::Initialise(std::string configfile, DataModel &data){ m_variables.Get("verbosity",verbosity); m_variables.Get("MCTruthCut", fMCTruthCut); m_variables.Get("PromptTrigOnly", fPromptTrigOnly); - - /// Construct the other objects we'll be setting at event level, - fMuonVertex = new RecoVertex(); // Make the RecoDigit Store if it doesn't exist int recoeventexists = m_data->Stores.count("RecoEvent"); @@ -89,7 +86,6 @@ bool EventSelectorDoE::Execute(){ bool EventSelectorDoE::Finalise(){ if(verbosity>0) cout<<"EventSelectorDoE exitting"<at(i)); digits->push_back((RecoDigit*)recodigitptr); } + // Reset Filter // ============ for(int n=0; nsize()); n++ ) { digits->at(n)->ResetFilter(); } - + // Run Hit Cleaner // ================ std::vector* FilterDigitList = Run(digits); @@ -290,7 +291,7 @@ std::vector* HitCleaner::Run(std::vector* myDigitList) // filter all digits // ================= - myInputList = ResetDigits(myOutputList); + myInputList = ResetDigits(myOutputList); myOutputList = (std::vector*)(this->FilterAll(myInputList)); myOutputList = FilterDigits(myOutputList); if( fConfig==HitCleaner::kNone ) return myOutputList; @@ -330,6 +331,7 @@ std::vector* HitCleaner::Run(std::vector* myDigitList) return myOutputList; } +// Set all filter status to 0 (default is 1) std::vector* HitCleaner::ResetDigits(std::vector* myDigitList) { for(int idigit=0; idigitsize()); idigit++ ){ @@ -691,7 +693,7 @@ std::vector* HitCleaner::RecoClusters(std::vector* myD } } - //std::cout <<"fClusterList->size() = "<size()<SetTitle("Figure of merit parallel to the track direction"); gr_transverse = new TGraph(); gr_transverse->SetTitle("Figure of merit transverse to the track direction"); + pdf_parallel = new TGraph(); + pdf_parallel->SetTitle("PDF-based Figure of merit parallel to track direction"); + pdf_transverse = new TGraph(); + pdf_transverse->SetTitle("PDF-based figure of merit transverse to track direction"); m_data= &data; //assigning transient data pointer ///////////////////////////////////////////////////////////////// @@ -30,6 +39,7 @@ bool LikelihoodFitterCheck::Initialise(std::string configfile, DataModel &data){ bool LikelihoodFitterCheck::Execute(){ + Log("===========================================================================================",v_debug,verbosity); Log("LikelihoodFitterCheck Tool: Executing",v_debug,verbosity); @@ -51,8 +61,24 @@ bool LikelihoodFitterCheck::Execute(){ // ANNIE Event number m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); - // Only check this event - if(fShowEvent>0 && (int)fEventNumber!=fShowEvent) return true; + // check if event passes the cut + bool EventCutstatus = false; + if (ifCleanEventsOnly) { + auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus", EventCutstatus); + if (!get_evtstatus) { + Log("Error: The LikelihoodFitterCheck tool could not find the Event selection status", v_error, verbosity); + return false; + } + if (!EventCutstatus) { + Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); + return true; + } + } + + // Only check this event, or this range of events + if ((fShowEvent > 0 && (int)fEventNumber <= fShowEvent) || fEventsShown > fEventRange) return true; + fEventsShown++; + std::cout << "LFCheck event " << fEventsShown << " out of " << fEventRange << endl; logmessage = "Likelihood check for MC Entry Number " + to_string(fMCEventNum) + " , MC Trigger Number" + to_string(fMCTriggerNum) @@ -73,6 +99,15 @@ bool LikelihoodFitterCheck::Execute(){ Log("LikelihoodFitterCheck Tool: Error retrieving RecoDigits,no digit from the RecoEvent!",v_error,verbosity); return false; } + + if (fUsePDFFile) { + bool pdftest = this->GetPDF(pdf); + if (!pdftest) { + Log("LikelihoodFitterCheck Tool: Error retrieving pdffile; running without!", v_error, verbosity); + fUsePDFFile = 0; + return false; + } + } double recoVtxX, recoVtxY, recoVtxZ, recoVtxT, recoDirX, recoDirY, recoDirZ; double trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ; @@ -89,6 +124,7 @@ bool LikelihoodFitterCheck::Execute(){ trueDirX = vtxDir.X(); trueDirY = vtxDir.Y(); trueDirZ = vtxDir.Z(); + std::string plotname; if(verbosity>0) cout<<"True vertex = ("<TimePropertiesLnL(meantime,timefom); myFoMCalculator->ConePropertiesFoM(ConeAngle,conefom); fom = timefom*0.5+conefom*0.5; cout<<"timeFOM, coneFOM, fom = "<SetPoint(j, dlpara[j], dlfom[j]); + + if (fUsePDFFile) { + myFoMCalculator->ConePropertiesLnL(seedX, seedY, seedZ, seedDirX, seedDirY, seedDirZ, ConeAngle, conefomlnl, pdf, maxphi, minphi); + cout << "conefomlnl: " << conefomlnl << endl; + fompdf = 0.5 * timefom + 0.5 * conefomlnl; + pdf_parallel->SetPoint(j, dlpara[j], fompdf); + } } //transverse direction @@ -148,8 +194,10 @@ bool LikelihoodFitterCheck::Execute(){ int nhits = myvtxgeo->GetNDigits(); double meantime = myFoMCalculator->FindSimpleTimeProperties(ConeAngle); Double_t fom = -999.999*100; + Double_t fompdf = -999.999 * 100; double timefom = -999.999*100; double conefom = -999.999*100; + double conefomlnl = -999.999 * 100; double coneAngle = 42.0; myFoMCalculator->TimePropertiesLnL(meantime,timefom); myFoMCalculator->ConePropertiesFoM(ConeAngle,conefom); @@ -158,11 +206,18 @@ bool LikelihoodFitterCheck::Execute(){ cout<<"timeFOM, coneFOM, fom = "<SetPoint(j, dlpara[j], dlfom[j]); + gr_transverse->SetPoint(j, dltrans[j], dlfom[j]); + if (fUsePDFFile) { + cout << "pdf fom coming\n"; + // myFoMCalculator->ConePropertiesLnL(seedX, seedY, seedZ, trueDirX, trueDirY, trueDirZ, coneAngle, conefomlnl, pdf); + fompdf = timefom * conefomlnl; + pdf_transverse->SetPoint(j, dltrans[j], conefomlnl); + } } if(ifPlot2DFOM) { //2D scan around the true vertex position + cout << "2DPlot starting now" << endl; double dl_para = 1.0, dl_trans = 1.0; double dx_para = dl_para * trueDirX; double dy_para = dl_para * trueDirY; @@ -170,42 +225,92 @@ bool LikelihoodFitterCheck::Execute(){ double dx_trans = dl_trans * v.X(); double dy_trans = dl_trans * v.Y(); double dz_trans = dl_trans * v.Z(); + double phimax, phimin; for(int k=0; k<100; k++) { for(int m=0; m<200; m++) { seedX = trueVtxX - 50*dx_trans + k*dx_trans - 50*dx_para + m*dx_para; seedY = trueVtxY - 50*dy_trans + k*dy_trans - 50*dy_para + m*dy_para; seedZ = trueVtxZ - 50*dz_trans + k*dz_trans - 50*dz_para + m*dz_para; seedT = trueVtxT; - seedDirX = trueDirX; - seedDirY = trueDirY; - seedDirZ = trueDirZ; - myvtxgeo->CalcExtendedResiduals(seedX, seedY, seedZ, seedT, seedDirX, seedDirY, seedDirZ); + seedDirX = cos(m * TMath::Pi() / 100) * sin(k * TMath::Pi() / 100); + seedDirY = sin(m * TMath::Pi() / 100) * sin(k * TMath::Pi() / 100); + seedDirZ = cos(k * TMath::Pi() / 100); + myvtxgeo->CalcExtendedResiduals(seedX, seedY, seedZ, seedT, trueDirX, trueDirY, trueDirZ); int nhits = myvtxgeo->GetNDigits(); double meantime = myFoMCalculator->FindSimpleTimeProperties(ConeAngle); Double_t fom = -999.999*100; + Double_t fompdf = -999.999 * 100; double timefom = -999.999*100; double conefom = -999.999*100; + double conefomlnl = -999.999 * 100; double coneAngle = 42.0; myFoMCalculator->TimePropertiesLnL(meantime,timefom); myFoMCalculator->ConePropertiesFoM(coneAngle,conefom); - fom = timefom*0.5+conefom*0.5; + fom = timefom * 0.5 + conefom * 0.5; //fom = timefom; cout<<"k,m, timeFOM, coneFOM, fom = "<SetBinContent(m, k, fom); + if (fUsePDFFile) { + myFoMCalculator->ConePropertiesLnL(seedX, seedY, seedZ, trueDirX, trueDirY, trueDirZ, coneAngle, conefomlnl, pdf, phimax, phimin); + fompdf = 0.5 * timefom + 0.5 * (conefomlnl); + cout << "coneFOMlnl: " << conefomlnl << endl; + if (k == 50 && m == 50) { + std::cout << "!!!OUTPUT!!! at true:\n"; + } + std::cout<<"conefomlnl, timefom, fompdf: " << conefomlnl << ", " << timefom << ", " << fompdf << endl; + std::cout << "phimax, phimin: " << phimax << ", " << phimin << endl; + Likelihood2D_pdf->SetBinContent(m, k, fompdf); + } } } } + + fOutput_tfile->cd(); + plotname = "FoM_parallel" + std::to_string(fEventNumber); + gr_parallel->Write(plotname.c_str()); + plotname = "FoM_transvers" + std::to_string(fEventNumber); + gr_transverse->Write(plotname.c_str()); + plotname = "FoM_2D" + to_string(fEventNumber); + if(ifPlot2DFOM) Likelihood2D->Write(plotname.c_str()); + + if (fUsePDFFile) { + plotname = "pdfFoM_parallel" + std::to_string(fEventNumber); + pdf_parallel->Write(plotname.c_str()); + plotname = "pdfFoM_transverse" + std::to_string(fEventNumber); + pdf_transverse->Write(plotname.c_str()); + plotname = "pdfFoM_2D" + std::to_string(fEventNumber); + if (ifPlot2DFOM) Likelihood2D_pdf->Write(plotname.c_str()); + } + + Likelihood2D->Reset(); + + if (fUsePDFFile) { + Likelihood2D_pdf->Reset(); + } + delete myFoMCalculator; return true; } -bool LikelihoodFitterCheck::Finalise(){ - fOutput_tfile->cd(); - gr_parallel->Write(); - gr_transverse->Write(); - fOutput_tfile->Write(); - fOutput_tfile->Close(); - Log("LikelihoodFitterCheck exitting", v_debug,verbosity); - return true; +bool LikelihoodFitterCheck::Finalise() { + + + fOutput_tfile->Write(); + fOutput_tfile->Close(); + + Log("LikelihoodFitterCheck exitting", v_debug, verbosity); + return true; } + + + bool LikelihoodFitterCheck::GetPDF(TH1D & pdf) { + TFile f1(pdffile.c_str(), "READ"); + if (!f1.IsOpen()) { + Log("VtxExtendedVertexFinder: pdffile does not exist", v_error, verbosity); + return false; + } + pdf = *(TH1D*)f1.Get("zenith"); + cout << "pdf entries: " << pdf.GetEntries() << endl; + return true; + } diff --git a/UserTools/LikelihoodFitterCheck/LikelihoodFitterCheck.h b/UserTools/LikelihoodFitterCheck/LikelihoodFitterCheck.h old mode 100644 new mode 100755 index 22ed724aa..3cdebfee0 --- a/UserTools/LikelihoodFitterCheck/LikelihoodFitterCheck.h +++ b/UserTools/LikelihoodFitterCheck/LikelihoodFitterCheck.h @@ -7,6 +7,7 @@ #include "Tool.h" #include "TH1.h" #include "TH2D.h" +#include "TFile.h" #include "FoMCalculator.h" #include "VertexGeometry.h" @@ -22,6 +23,7 @@ class LikelihoodFitterCheck: public Tool { bool Initialise(std::string configfile,DataModel &data); bool Execute(); bool Finalise(); + bool GetPDF(TH1D & pdf); private: @@ -42,7 +44,13 @@ class LikelihoodFitterCheck: public Tool { /// \brief Selecte a particular event to show int fShowEvent = 0; + /// \brief Give a maximum number of events to show after the selected event (set to 0 to show only the selected) + int fEventRange = 0; + int fEventsShown; + /// \brief Determine whether or not to show events that failed to pass selection cuts + bool ifCleanEventsOnly; + std::vector* fDigitList = 0; RecoVertex* fTrueVertex = 0; @@ -50,6 +58,11 @@ class LikelihoodFitterCheck: public Tool { TH2D* Likelihood2D = 0; TGraph *gr_parallel = 0; TGraph *gr_transverse = 0; + + /// \comparison histograms + TH2D* Likelihood2D_pdf = 0; + TGraph* pdf_parallel = 0; + TGraph* pdf_transverse = 0; /// verbosity levels: if 'verbosity' < this level, the message type will be logged. int verbosity=-1; @@ -60,6 +73,9 @@ class LikelihoodFitterCheck: public Tool { std::string logmessage; int get_ok; bool ifPlot2DFOM = false; + std::string pdffile; + bool fUsePDFFile = 0; + TH1D pdf; diff --git a/UserTools/LikelihoodFitterCheck/README.md b/UserTools/LikelihoodFitterCheck/README.md old mode 100644 new mode 100755 diff --git a/UserTools/LoadWCSim/LoadWCSim.cpp b/UserTools/LoadWCSim/LoadWCSim.cpp index 8935e3b47..9a26e1944 100644 --- a/UserTools/LoadWCSim/LoadWCSim.cpp +++ b/UserTools/LoadWCSim/LoadWCSim.cpp @@ -38,6 +38,13 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ Log("LoadWCSim Tool: Assuming to use smeared digit times",v_warning,verbosity); use_smeared_digit_time=1; } + if (use_smeared_digit_time == 0) { + get_ok = m_variables.Get("FirstHit", firstHit); + if (not get_ok) { + Log("LoadWCSim Tool: No firstHit setting applied; setting to 1", v_warning, verbosity); + firstHit = 1; + } + } get_ok = m_variables.Get("LappdNumStrips", LappdNumStrips); if(not get_ok){ Log("LoadWCSim Tool: Assuming to use 56 LAPPD striplines",v_warning,verbosity); @@ -69,7 +76,7 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ Log("LoadWCSim Tool: No Triggertype specified. Assuming TriggerType = Beam",v_warning,verbosity); Triggertype = "Beam"; //other options: Cosmic / No Loopback } - + get_ok = m_variables.Get("TriggerWord",TriggerWord); if (not get_ok){ Log("LoadWCSim Tool: No Triggerword specified. Assuming TriggerWord = 5 (Beam)",v_warning,verbosity); @@ -90,7 +97,7 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ channelkey_to_pmtid.emplace(chankey,pmtid); pmtid_to_channelkey.emplace(pmtid,chankey); } - + file_pmtid.close(); m_data->CStore.Set("pmt_tubeid_to_channelkey_data",pmtid_to_channelkey); m_data->CStore.Set("channelkey_to_pmtid_data",channelkey_to_pmtid); @@ -99,50 +106,50 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ return false; } path_mrd_chankeymap = "./configfiles/LoadWCSim/MRD_Chankey_WCSimID.dat"; - get_ok = m_variables.Get("ChankeyToMRDIDMap",path_mrd_chankeymap); - ifstream file_mrdid(path_mrd_chankeymap.c_str()); - if (file_mrdid.is_open()){ - // watch out: comment or empty lines not supported here - while (!file_mrdid.eof()){ - unsigned long chankey; - int mrdid; - file_mrdid >> chankey >> mrdid; - mrdid_to_channelkey.emplace(mrdid,chankey); - } - file_mrdid.close(); - } else { - Log("LoadWCSim Tool: MRD ID Configuration file "+path_mrd_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); - return false; - } + get_ok = m_variables.Get("ChankeyToMRDIDMap",path_mrd_chankeymap); + ifstream file_mrdid(path_mrd_chankeymap.c_str()); + if (file_mrdid.is_open()){ + // watch out: comment or empty lines not supported here + while (!file_mrdid.eof()){ + unsigned long chankey; + int mrdid; + file_mrdid >> chankey >> mrdid; + mrdid_to_channelkey.emplace(mrdid,chankey); + } + file_mrdid.close(); + } else { + Log("LoadWCSim Tool: MRD ID Configuration file "+path_mrd_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); + return false; + } path_fmv_chankeymap = "./configfiles/LoadWCSim/FMV_Chankey_WCSimID.dat"; - get_ok = m_variables.Get("ChankeyToFMVIDMap",path_fmv_chankeymap); - ifstream file_fmvid(path_fmv_chankeymap.c_str()); - if (file_fmvid.is_open()){ - // watch out: comment or empty lines not supported here - while (!file_fmvid.eof()){ - unsigned long chankey; - int fmvid; - file_fmvid >> chankey >> fmvid; - fmvid_to_channelkey.emplace(fmvid,chankey); - } - file_fmvid.close(); - } else { - Log("LoadWCSim Tool: FMV ID Configuration file "+path_fmv_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); - return false; - } - get_ok = m_variables.Get("RunType",RunType); - if (not get_ok){ - Log("LoadWCSim Tool: No RunType specified. Assuming RunType = 3 (Beam)",v_warning,verbosity); - RunType = 3; - } - + get_ok = m_variables.Get("ChankeyToFMVIDMap",path_fmv_chankeymap); + ifstream file_fmvid(path_fmv_chankeymap.c_str()); + if (file_fmvid.is_open()){ + // watch out: comment or empty lines not supported here + while (!file_fmvid.eof()){ + unsigned long chankey; + int fmvid; + file_fmvid >> chankey >> fmvid; + fmvid_to_channelkey.emplace(fmvid,chankey); + } + file_fmvid.close(); + } else { + Log("LoadWCSim Tool: FMV ID Configuration file "+path_fmv_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); + return false; + } + get_ok = m_variables.Get("RunType",RunType); + if (not get_ok){ + Log("LoadWCSim Tool: No RunType specified. Assuming RunType = 3 (Beam)",v_warning,verbosity); + RunType = 3; + } + get_ok = m_variables.Get("PMTMask",PMTMask); if (not get_ok){ Log("LoadWCSim Tool: Assuming to use no PMTMask",v_warning,verbosity); PMTMask = "None"; } - - MCEventNum=0; + + MCEventNum=0; get_ok = m_variables.Get("FileStartOffset",MCEventNum); // put version in the CStore for downstream tools @@ -269,7 +276,7 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ if (PMTMask != "None"){ masked_ids = this->LoadPMTMask(PMTMask); } - + // use nominal beam values TODO double beaminten=4.777e+12; double beampow=3.2545e+16; @@ -279,7 +286,7 @@ bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ beamstat.set_pot(beampow); BeamCondition bc = BeamCondition::Ok; beamstat.set_condition(bc); - + // Construct the other objects we'll be setting at event level, // pass managed pointers to the ANNIEEvent Store MCParticles = new std::vector; @@ -363,23 +370,21 @@ bool LoadWCSim::Execute(){ } MCFile = WCSimEntry->GetCurrentFile()->GetName(); + MCHits->clear(); TDCData->clear(); MCNeutCap.clear(); MCNeutCapGammas.clear(); mrd_firstlayer=false; - mrd_lastlayer=false; - + mrd_lastlayer=false; + triggers_event = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); - int MaxEventNr = MCTriggernum+1; - if (!splitSubtriggers){ - // we'll merge all subtriggers, so loop from 0 to triggers_event; - MCTriggernum = 0; - MaxEventNr = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); - } // else if we're splitting subtriggers, loop from [current MCTriggernum] to [current MCTriggernum+1] - + if (!splitSubtriggers) MCTriggernum = 0; + int MaxEventNr = (splitSubtriggers)? (MCTriggernum + 1) : (WCSimEntry->wcsimrootevent->GetNumberOfEvents()); + while (MCTriggernum < MaxEventNr){ + //for(MCTriggernum=0; MCTriggernumwcsimrootevent->GetNumberOfEvents(); MCTriggernum++){ if(verbosity>1) cout<<"getting triggers"<wcsimrootevent->GetTrigger(0); @@ -414,7 +419,7 @@ bool LoadWCSim::Execute(){ int genieentry = firsttrigt->GetHeader()->GetGenieEntryNum(); /*if(verbosity>3)*/ cout<<"Genie file is "<CStore.Set("GenieFile",geniefilename); - m_data->CStore.Set("GenieEntry",std::to_string(genieentry)); + m_data->CStore.Set("GenieEntry",genieentry); for(int trigi=0; trigiwcsimrootevent->GetNumberOfEvents(); trigi++){ @@ -452,10 +457,10 @@ bool LoadWCSim::Execute(){ if (splitSubtriggers){ //MC particle times now stored relative to the trigger time starttime = (static_cast(nextrack->GetTime()-EventTimeNs)); - stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); + stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); } else { starttime = (static_cast(nextrack->GetTime())); - stoptime = (static_cast(nextrack->GetStopTime())); + stoptime = (static_cast(nextrack->GetStopTime())); } MCParticle neutrino( nextrack->GetIpnu(), nextrack->GetE(), nextrack->GetEndE(), @@ -476,7 +481,7 @@ bool LoadWCSim::Execute(){ nextrack->GetParenttype(), nextrack->GetFlag(), trigi); - + //Set the neutrino as its own particle m_data->Stores["ANNIEEvent"]->Set("NeutrinoParticle",neutrino); @@ -487,10 +492,10 @@ bool LoadWCSim::Execute(){ if (splitSubtriggers){ //MC particle times now stored relative to the trigger time starttime = (static_cast(nextrack->GetTime()-EventTimeNs)); - stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); + stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); } else { starttime = (static_cast(nextrack->GetTime())); - stoptime = (static_cast(nextrack->GetStopTime())); + stoptime = (static_cast(nextrack->GetStopTime())); } MCParticle thisparticle( nextrack->GetIpnu(), nextrack->GetE(), nextrack->GetEndE(), @@ -514,8 +519,8 @@ bool LoadWCSim::Execute(){ // not currently in constructor call, but we now have it in latest WCSim files // XXX this will fall over with older WCSim files, whose WCSimLib doesn't have this method! thisparticle.SetTankExitPoint(Position(nextrack->GetTankExitPoint(0)/ 100., - nextrack->GetTankExitPoint(1)/ 100., - nextrack->GetTankExitPoint(2)/ 100.)); + nextrack->GetTankExitPoint(1)/ 100., + nextrack->GetTankExitPoint(2)/ 100.)); if( (nextrack->GetIpnu()==13) && (nextrack->GetParenttype()==0) && (nextrack->GetFlag()==0) && @@ -631,18 +636,24 @@ bool LoadWCSim::Execute(){ } else { // instead take the true time of the first photon std::vector photonids = digihit->GetPhotonIds(); // indices of the digit's photons + std::cout << "LoadWCSim Tool: number of photons in this hit: " << photonids.size() << endl; double earliestphotontruetime=999999999999; - for(int& aphotonindex : photonids){ - WCSimRootCherenkovHitTime* thehittimeobject = - (WCSimRootCherenkovHitTime*)firsttrigt->GetCherenkovHitTimes()->At(aphotonindex); - if(thehittimeobject==nullptr){ - cerr<<"LoadWCSim Tool: ERROR! Retrieval of photon from digit returned nullptr!"<GetCherenkovHitTimes()->At(aphotonindex); + if (thehittimeobject == nullptr) { + cerr << "LoadWCSim Tool: ERROR! Retrieval of photon from digit returned nullptr!" << endl; + continue; + } + double aphotontime = static_cast(thehittimeobject->GetTruetime()); + if (aphotontime < earliestphotontruetime) { earliestphotontruetime = aphotontime; } } - double aphotontime = static_cast(thehittimeobject->GetTruetime()); - if(aphotontime2){ cout<<"digittime is "<GetQ(); @@ -653,7 +664,7 @@ bool LoadWCSim::Execute(){ if (!splitSubtriggers) digittime += EventTimeNs; //std::cout <<"digittime after adding event time: "<count(key)==0) MCHits->emplace(key, std::vector{nexthit}); else MCHits->at(key).push_back(nexthit); @@ -700,8 +711,8 @@ bool LoadWCSim::Execute(){ if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigm); - if (!splitSubtriggers) digittime += EventTimeNs; - + if (!splitSubtriggers) digittime += EventTimeNs; + MCHit nexthit(key, digittime, digiq, parents); if(TDCData->count(key)==0) {TDCData->emplace(key, std::vector{nexthit}); if (Mrd_Chankey_Layer.at(key)==0) mrd_firstlayer=true; if (Mrd_Chankey_Layer.at(key)==10) mrd_lastlayer=true;} else TDCData->at(key).push_back(nexthit); @@ -748,8 +759,8 @@ bool LoadWCSim::Execute(){ if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigv); - digittime += EventTimeNs; - + digittime += EventTimeNs; + MCHit nexthit(key, digittime, digiq, parents); if(TDCData->count(key)==0) TDCData->emplace(key, std::vector{nexthit}); else TDCData->at(key).push_back(nexthit); @@ -762,11 +773,12 @@ bool LoadWCSim::Execute(){ //Load neutron capture information int numcaptures = atrigt ? atrigt->GetNcaptures() : 0; - if(verbosity>1) cout<<"LoadWCSim tool: looping over "<2) cout<<"getting capture # "<GetCaptures()->At(capi); - + if(verbosity>1) cout<<"LoadWCSim tool: looping over "<2) cout<<"getting capture # "<GetCaptures()->At(capi); + int capt_parent = capt->GetCaptureParent(); double capt_vtxx = capt->GetCaptureVtx(0); double capt_vtxy = capt->GetCaptureVtx(1); @@ -805,7 +817,9 @@ bool LoadWCSim::Execute(){ MCNeutCapGammas.at("CaptGammas").push_back(gamma_energies); } } - + + + // update the information about tracks and which tank/mrd/veto PMTs they hit // this needs updating with each MC trigger, as digits are grouped into MC trigger // so these maps will then only contain the digits respective particles create @@ -840,13 +854,14 @@ bool LoadWCSim::Execute(){ if(verbosity>1) cout<<"setting the store variables"<Stores.at("ANNIEEvent")->Set("RunNumber",RunNumber); m_data->Stores.at("ANNIEEvent")->Set("SubrunNumber",SubrunNumber); - m_data->Stores.at("ANNIEEvent")->Set("RunType",RunType); + m_data->Stores.at("ANNIEEvent")->Set("RunType",RunType); m_data->Stores.at("ANNIEEvent")->Set("EventNumber",EventNumber); if(verbosity>2) cout<<"particles"<Stores.at("ANNIEEvent")->Set("MCParticles",MCParticles,true); if(verbosity>2) cout<<"hits"<Stores.at("ANNIEEvent")->Set("MCHits",MCHits,true); - if(verbosity>2) cout<<"tdcdata"< 2) cout << "tdcdata: size = " << TDCData->size() << endl; + m_data->Stores.at("ANNIEEvent")->Set("TDCData",TDCData,true); // TODO? // right now we have three Time variables: @@ -868,12 +883,9 @@ bool LoadWCSim::Execute(){ m_data->Stores.at("ANNIEEvent")->Set("EventTimeMRD",RunStartTime); m_data->Stores.at("ANNIEEvent")->Set("EventTime",EventTime,true); m_data->Stores.at("ANNIEEvent")->Set("MCEventNum",MCEventNum); - // if we merged the subtriggers, report an MCTriggernum of 0 - // so downstream tools know it's a new event - int reported_triggernum = splitSubtriggers ? MCTriggernum-1 : 0; - m_data->Stores.at("ANNIEEvent")->Set("MCTriggernum",reported_triggernum); + m_data->Stores.at("ANNIEEvent")->Set("MCTriggernum",MCTriggernum-1); m_data->Stores.at("ANNIEEvent")->Set("MCFile",MCFile); - m_data->Stores.at("ANNIEEvent")->Set("MCFlag",true); + m_data->Stores.at("ANNIEEvent")->Set("MCFlag",true); // constant //m_data->Stores.at("ANNIEEvent")->Set("BeamStatus",BeamStatus,true); m_data->Stores.at("ANNIEEvent")->Set("BeamStatus",beamstat); m_data->Stores.at("ANNIEEvent")->Set("MCNeutCap",MCNeutCap); @@ -892,17 +904,17 @@ bool LoadWCSim::Execute(){ m_data->Stores.at("ANNIEEvent")->Set("MRDTriggerType",Triggertype); m_data->Stores.at("ANNIEEvent")->Set("PrimaryMuonIndex",primarymuonindex); m_data->Stores.at("ANNIEEvent")->Set("TriggerWord",TriggerWord); - + std::map DataStreams; DataStreams.emplace(std::make_pair("Tank",true)); DataStreams.emplace(std::make_pair("MRD",true)); DataStreams.emplace(std::make_pair("Trigger",true)); DataStreams.emplace(std::make_pair("LAPPD",true)); m_data->Stores.at("ANNIEEvent")->Set("DataStreams",DataStreams); - + int TriggerExtended = 1; //1: We have an extended readout for all MC events m_data->Stores.at("ANNIEEvent")->Set("TriggerExtended",TriggerExtended); - + //Things that need to be set by later tools: //RawADCData //CalibratedADCData @@ -916,7 +928,7 @@ bool LoadWCSim::Execute(){ bool newentry=false; if(MCTriggernum==WCSimEntry->wcsimrootevent->GetNumberOfEvents()){ MCTriggernum=0; - MCEventNum++; + MCEventNum++; newentry=true; if(verbosity>2) cout<<"this is the last trigger in the event: next loop will process a new event"<GetWCOffset(1)) / 100.; double tank_zcentre = (wcsimrootgeom->GetWCOffset(2)) / 100.; Position tank_centre(tank_xcentre, tank_ycentre, tank_zcentre); - double tank_radius = (wcsimrootgeom->GetWCCylRadius()) / 100.; //GetWCCylRadius() returns the black sheet radius not the tank radius - double tank_halfheight = (wcsimrootgeom->GetWCCylLength()) / 200.; //GetWCCylLength() returns the main annulus height not the tank height + double tank_radius = (wcsimrootgeom->GetWCCylRadius()) / 100.; + double tank_halfheight = (wcsimrootgeom->GetWCCylLength()) / 100.; //Currently hard-coded; estimated with a tape measure on the ANNIE frame :) double pmt_enclosed_radius = 1.0; double pmt_enclosed_halfheight = 1.45; @@ -994,20 +1006,20 @@ Geometry* LoadWCSim::ConstructToolChainGeometry(){ // construct the ToolChain Goemetry // ================================ Geometry* anniegeom = new Geometry(WCSimGeometryVer, - tank_centre, - tank_radius, - tank_halfheight, - pmt_enclosed_radius, - pmt_enclosed_halfheight, - mrd_width, - mrd_height, - mrd_depth, - mrd_start, - numtankpmts, - nummrdpmts, - numvetopmts, - numlappds, - geostatus::FULLY_OPERATIONAL); + tank_centre, + tank_radius, + tank_halfheight, + pmt_enclosed_radius, + pmt_enclosed_halfheight, + mrd_width, + mrd_height, + mrd_depth, + mrd_start, + numtankpmts, + nummrdpmts, + numvetopmts, + numlappds, + geostatus::FULLY_OPERATIONAL); if(verbosity>1){ cout<<"constructed anniegeom at "<=CAEN_HV_CARDS_PER_CRATE) { CAEN_HV_Card_Num=0; CAEN_HV_Crate_Num++; } Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - ADC_Crate_Num, - ADC_Card_Num, - ADC_Chan_Num, - MT_Crate_Num, - MT_Card_Num, - MT_Chan_Num, - CAEN_HV_Crate_Num, - CAEN_HV_Card_Num, - CAEN_HV_Chan_Num, - channelstatus::ON); + Position(0,0,0.), + 0, // stripside + 0, // stripnum + ADC_Crate_Num, + ADC_Card_Num, + ADC_Chan_Num, + MT_Crate_Num, + MT_Card_Num, + MT_Chan_Num, + CAEN_HV_Crate_Num, + CAEN_HV_Card_Num, + CAEN_HV_Chan_Num, + channelstatus::ON); // Add this channel to the geometry if(verbosity>4) cout<<"Adding channel "<ConsumeNextFreeChannelKey(); @@ -1166,19 +1178,19 @@ Geometry* LoadWCSim::ConstructToolChainGeometry(){ if(LeCroy_HV_Card_Num>=LECROY_HV_CARDS_PER_CRATE) { LeCroy_HV_Card_Num=0; LeCroy_HV_Crate_Num++; } Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - TDC_Crate_Num, - TDC_Card_Num, - TDC_Chan_Num, - -1, // TDC has no level 2 signal handling - -1, - -1, - LeCroy_HV_Crate_Num, - LeCroy_HV_Card_Num, - LeCroy_HV_Chan_Num, - channelstatus::ON); + Position(0,0,0.), + 0, // stripside + 0, // stripnum + TDC_Crate_Num, + TDC_Card_Num, + TDC_Chan_Num, + -1, // TDC has no level 2 signal handling + -1, + -1, + LeCroy_HV_Crate_Num, + LeCroy_HV_Card_Num, + LeCroy_HV_Chan_Num, + channelstatus::ON); // Add this channel to the geometry if(verbosity>4) cout<<"Adding channel "<{MRDSpecs::paddle_extentsx.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsx.at(mrdpmti).second/1000.}, - std::pair{MRDSpecs::paddle_extentsy.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsy.at(mrdpmti).second/1000.}, - std::pair{MRDSpecs::paddle_extentsz.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsz.at(mrdpmti).second/1000.}); + MRD_x, + MRD_y, + MRD_z, + orientation, + Position( MRDSpecs::paddle_originx.at(mrdpmti)/1000., + MRDSpecs::paddle_originy.at(mrdpmti)/1000., + MRDSpecs::paddle_originz.at(mrdpmti)/1000.), + std::pair{MRDSpecs::paddle_extentsx.at(mrdpmti).first/1000., + MRDSpecs::paddle_extentsx.at(mrdpmti).second/1000.}, + std::pair{MRDSpecs::paddle_extentsy.at(mrdpmti).first/1000., + MRDSpecs::paddle_extentsy.at(mrdpmti).second/1000.}, + std::pair{MRDSpecs::paddle_extentsz.at(mrdpmti).first/1000., + MRDSpecs::paddle_extentsz.at(mrdpmti).second/1000.}); if(verbosity>4) cout<<"Setting paddle for detector "<SetDetectorPaddle(uniquedetectorkey,apaddle); @@ -1245,18 +1257,18 @@ Geometry* LoadWCSim::ConstructToolChainGeometry(){ case 5: CylLocString = "Veto"; break; // TODO set layer? default: CylLocString = "NA"; break; // unknown } - Detector adet( uniquedetectorkey, - "Veto", - CylLocString, - Position( apmt.GetPosition(0)/100., - apmt.GetPosition(1)/100., - apmt.GetPosition(2)/100.), - Direction(apmt.GetOrientation(0), - apmt.GetOrientation(1), - apmt.GetOrientation(2)), - apmt.GetName(), - detectorstatus::ON, - 0.); + Detector adet(uniquedetectorkey, + "Veto", + CylLocString, + Position( apmt.GetPosition(0)/100., + apmt.GetPosition(1)/100., + apmt.GetPosition(2)/100.), + Direction(apmt.GetOrientation(0), + apmt.GetOrientation(1), + apmt.GetOrientation(2)), + apmt.GetName(), + detectorstatus::ON, + 0.); if (verbosity > 3) std::cout <<"LoadWCSim tool: FACC tube channelkey: "<ConsumeNextFreeChannelKey(); @@ -1274,19 +1286,19 @@ Geometry* LoadWCSim::ConstructToolChainGeometry(){ if(LeCroy_HV_Card_Num>=LECROY_HV_CARDS_PER_CRATE) { LeCroy_HV_Card_Num=0; LeCroy_HV_Crate_Num++; } Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - TDC_Crate_Num, - TDC_Card_Num, - TDC_Chan_Num, - -1, // TDC has no level 2 signal handling - -1, - -1, - LeCroy_HV_Crate_Num, - LeCroy_HV_Card_Num, - LeCroy_HV_Chan_Num, - channelstatus::ON); + Position(0,0,0.), + 0, // stripside + 0, // stripnum + TDC_Crate_Num, + TDC_Card_Num, + TDC_Chan_Num, + -1, // TDC has no level 2 signal handling + -1, + -1, + LeCroy_HV_Crate_Num, + LeCroy_HV_Card_Num, + LeCroy_HV_Chan_Num, + channelstatus::ON); // Add this channel to the geometry if(verbosity>4) cout<<"Adding channel "<4) cout<<"printing geometry"<4) anniegeom->PrintChannels(); } - + // lappds // lappds moved to end such that all the other channels are assigned first for(int lappdi=0; lappdi=LAPPD_HV_CHANNELS_PER_CARD) { LAPPD_HV_Chan_Num=0; LAPPD_HV_Card_Num++; } if(LAPPD_HV_Card_Num>=LAPPD_HV_CARDS_PER_CRATE) { LAPPD_HV_Card_Num=0; LAPPD_HV_Crate_Num++; } - Channel lappdchannel( uniquechannelkey, - Position(xpos,ypos,0.), - stripside, - stripnum, - ACDC_Crate_Num, - ACDC_Card_Num, - ACDC_Chan_Num, - ACC_Crate_Num, - ACC_Card_Num, - ACC_Chan_Num, - LAPPD_HV_Crate_Num, - LAPPD_HV_Card_Num, - LAPPD_HV_Chan_Num, - channelstatus::ON); + Channel lappdchannel(uniquechannelkey, + Position(xpos,ypos,0.), + stripside, + stripnum, + ACDC_Crate_Num, + ACDC_Card_Num, + ACDC_Chan_Num, + ACC_Crate_Num, + ACC_Card_Num, + ACC_Chan_Num, + LAPPD_HV_Crate_Num, + LAPPD_HV_Card_Num, + LAPPD_HV_Chan_Num, + channelstatus::ON); // Add this channel to the geometry if(verbosity>4) cout<<"Adding channel "< LoadWCSim::LoadPMTMask(std::string path_to_pmtmask){ - + std::vector mask_vector; int temp_id; ifstream maskfile(path_to_pmtmask.c_str()); @@ -1556,6 +1568,6 @@ std::vector LoadWCSim::LoadPMTMask(std::string path_to_pmtmask){ mask_vector.push_back(temp_id); if (maskfile.eof()) break; } - + return mask_vector; } diff --git a/UserTools/LoadWCSim/LoadWCSim.h b/UserTools/LoadWCSim/LoadWCSim.h index c85e12454..fbd34f0f7 100644 --- a/UserTools/LoadWCSim/LoadWCSim.h +++ b/UserTools/LoadWCSim/LoadWCSim.h @@ -61,7 +61,8 @@ class LoadWCSim: public Tool { ///////////////////////////// int verbosity=1; int HistoricTriggeroffset; - int use_smeared_digit_time; // digit_time = (T): first photon smeared time, (F): first photon true time + int use_smeared_digit_time; // digit_time = (T): first photon smeared time, (F): find time internally + int firstHit; // under find time internally, digit_time = (T): first photon true time (F): Smear from median int LappdNumStrips; // number of Channels per LAPPD double LappdStripLength; // [mm] for calculating relative x position for dual-ended readout double LappdStripSeparation; // [mm] for calculating relative y position of each stripline diff --git a/UserTools/LoadWCSim/wcsimT.h b/UserTools/LoadWCSim/wcsimT.h index c7e2a54f1..161f070f9 100755 --- a/UserTools/LoadWCSim/wcsimT.h +++ b/UserTools/LoadWCSim/wcsimT.h @@ -47,7 +47,7 @@ public : WCSimRootOptions *wcsimrootopts=nullptr; // TODO implement a verbosity arg - int verbose=1; + int verbose=5; // List of branches TBranch *b_wcsimrootevent; //! @@ -138,10 +138,11 @@ wcsimT::~wcsimT() Int_t wcsimT::GetEntry(Long64_t entry) { - if(verbose>2) cout<<"getting wcsimT entry "<2) cout<<"let's change this getting wcsimT entry "<2) cout<<"Just Trying this time"<last_entry_of_current_tree){ - //std::cout<<"Abdout to retrieve the first entry of a new file: cleanup"<Print(); Long64_t localentry = fChain->LoadTree(entry); @@ -157,7 +158,7 @@ Int_t wcsimT::GetEntry(Long64_t entry) return -1; } fCurrent=fChain->GetTreeNumber(); - //std::cout<<"Loaded file "<GetTree()->SetBranchAddress("wcsimrootevent",&wcsimrootevent, &b_wcsimrootevent); @@ -176,6 +177,7 @@ Int_t wcsimT::GetEntry(Long64_t entry) //std::cout<2) std::cout<<"Got wcsimT entry "<GetEntry(entry); } diff --git a/UserTools/MeanTimeCheck/MeanTimeCheck.cpp b/UserTools/MeanTimeCheck/MeanTimeCheck.cpp new file mode 100644 index 000000000..65f6a4ef8 --- /dev/null +++ b/UserTools/MeanTimeCheck/MeanTimeCheck.cpp @@ -0,0 +1,185 @@ +#include "MeanTimeCheck.h" + +MeanTimeCheck::MeanTimeCheck():Tool(){} + + +bool MeanTimeCheck::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + + std::string output_filename; + m_variables.Get("verbosity", verbosity); + m_variables.Get("OutputFile", output_filename); + m_variables.Get("ShowEvent", ShowEvent); + Output_tfile = new TFile(output_filename.c_str(), "recreate"); + + delta = new TH1D("delta", "delta", 1000, -10, 30); + peakTime = new TH1D("Peak Time", "time", 1000, -10, 30); + basicAverage = new TH1D("basic average", "time", 1000, -10, 30); + weightedPeak = new TH1D("Weighted Peak", "time", 1000, -10, 30); + weightedAverage = new TH1D("Weighted Average", "time", 1000, -10, 30); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + return true; +} + + +bool MeanTimeCheck::Execute(){ + +Log("===========================================================================================", v_debug, verbosity); + + Log("MeanTimeCheck Tool: Executing", v_debug, verbosity); + auto* reco_event = m_data->Stores["RecoEvent"]; + if (!reco_event) { + Log("Error: The MeanTimeCheck tool could not find the ANNIEEvent Store", 0, verbosity); + return false; + } + + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum", MCEventNum); + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum", MCTriggerNum); + m_data->Stores.at("ANNIEEvent")->Get("EventNumber", EventNumber); + + //std::cout< 0 && EventNumber != ShowEvent) return true; + bool EventCutstatus = false; + auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus", EventCutstatus); + if (!get_evtstatus) { + Log("Error: The MeanTimeCheck tool could not find the Event selection status", v_error, verbosity); + return false; + } + if (!EventCutstatus) { + Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); + return true; + } + + auto get_vtx = m_data->Stores.at("RecoEvent")->Get("TrueVertex", TrueVtx); + auto get_digit = m_data->Stores.at("RecoEvent")->Get("RecoDigit", DigitList); + Position vtxPos = TrueVtx->GetPosition(); + Direction vtxDir = TrueVtx->GetDirection(); + double vtxT = TrueVtx->GetTime(); + VtxGeo = VertexGeometry::Instance(); + VtxGeo->LoadDigits(DigitList); + VtxGeo->CalcExtendedResiduals(vtxPos.X(), vtxPos.Y(), vtxPos.Z(), vtxT, vtxDir.X(), vtxDir.Y(), vtxDir.Z()); + int nhits = VtxGeo->GetNDigits(); + //std::cout<<"nhits: "<Fill(VtxGeo->GetDelta(n)); + //std::cout<<"Delta: "<GetDelta(n)<GetPeakTime(); + double WeightedAverage = this->GetWeightedAverage(); + double WeightedPeak = this-> GetWeightedPeak(); +std::cout<<"Check 2"<Fill(PeakTime); + weightedAverage->Fill(WeightedAverage); + weightedPeak->Fill(WeightedPeak); +std::cout<<"Check 3"<Stores.at("RecoEvent")->Set("meanTime", PeakTime); + + return true; + +} + + +bool MeanTimeCheck::Finalise(){ + + Output_tfile->cd(); + Output_tfile->Write(); + Output_tfile->Close(); + Log("MeanTimeCheck exitting", v_debug, verbosity); + + return true; +} + +double MeanTimeCheck::GetPeakTime() { + return delta->GetBinCenter(delta->GetMaximumBin()); +} + +double MeanTimeCheck::GetWeightedAverage() { + double Swx = 0.0; + double Sw = 0.0; + + double delta = 0.0; + double sigma = 0.0; + double weight = 0.0; + double deweight = 0.0; + double deltaAngle = 0.0; + double meanTime = 0.0; + + double myConeEdgeSigma = 7.0; // [degrees] + + for (int idigit = 0; idigit < this->VtxGeo->GetNDigits(); idigit++) { + int detType = this->VtxGeo->GetDigitType(idigit); + if (this->VtxGeo->IsFiltered(idigit)) { + delta = this->VtxGeo->GetDelta(idigit); + sigma = this->VtxGeo->GetDeltaSigma(idigit); + weight = 1.0 / (sigma*sigma); + // profile in angle + deltaAngle = this->VtxGeo->GetAngle(idigit) - Parameters::CherenkovAngle(); + // deweight hits outside cone + if (deltaAngle <= 0.0) { + deweight = 1.0; + } + else { + deweight = 1.0 / (1.0 + (deltaAngle*deltaAngle) / (myConeEdgeSigma*myConeEdgeSigma)); + } + Swx += deweight * weight*delta; //delta is expected vertex time + Sw += deweight * weight; + } + } + if (Sw > 0.0) { + meanTime = Swx * 1.0 / Sw; + } + +return meanTime; +} + +double MeanTimeCheck::GetWeightedPeak() { + double sigma = 0.0; + double deltaAngle = 0.0; + double weight = 0.0; + double deweight = 0.0; + double myConeEdgeSigma = 7.0; // [degrees] + double meanTime = 0.0; + vector deltaTime1; + vector deltaTime2; + vector TimeWeight; + + for (int idigit = 0; idigit < this->VtxGeo->GetNDigits(); idigit++) { + if (this->VtxGeo->IsFiltered(idigit)) { + deltaTime1.push_back(this->VtxGeo->GetDelta(idigit)); + deltaTime2.push_back(this->VtxGeo->GetDelta(idigit)); + sigma = this->VtxGeo->GetDeltaSigma(idigit); + weight = 1.0 / (sigma*sigma); + deltaAngle = this->VtxGeo->GetAngle(idigit) - Parameters::CherenkovAngle(); + if (deltaAngle <= 0.0) { + deweight = 1.0; + } + else { + deweight = 1.0 / (1.0 + (deltaAngle*deltaAngle) / (myConeEdgeSigma*myConeEdgeSigma)); + } + TimeWeight.push_back(deweight*weight); + } + } + int n = deltaTime1.size(); + std::sort(deltaTime1.begin(), deltaTime1.end()); + double timeMin = deltaTime1.at(int((n - 1)*0.05)); // 5% of the total entries + double timeMax = deltaTime1.at(int((n - 1)*0.90)); // 90% of the total entries + int nbins = int(n / 5); + TH1D *hDeltaTime = new TH1D("hDeltaTime", "hDeltaTime", nbins, timeMin, timeMax); + for (int i = 0; i < n; i++) { + hDeltaTime->Fill(deltaTime2.at(i), TimeWeight.at(i)); + hDeltaTime->Fill(deltaTime2.at(i)); + } + meanTime = hDeltaTime->GetBinCenter(hDeltaTime->GetMaximumBin()); + delete hDeltaTime; hDeltaTime = 0; + + return meanTime; +} diff --git a/UserTools/MeanTimeCheck/MeanTimeCheck.h b/UserTools/MeanTimeCheck/MeanTimeCheck.h new file mode 100644 index 000000000..3231ad881 --- /dev/null +++ b/UserTools/MeanTimeCheck/MeanTimeCheck.h @@ -0,0 +1,70 @@ +#ifndef MeanTimeCheck_H +#define MeanTimeCheck_H + +#include +#include +#include "TROOT.h" +#include "TChain.h" +#include "TFile.h" + +#include "Tool.h" +#include "TTree.h" +#include "TH2D.h" +#include "Parameters.h" +#include "VertexGeometry.h" +#include "Detector.h" + + +/** + * \class MeanTimeCheck + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. +* +* $Author: B.Richards $ +* $Date: 2019/05/28 10:44:00 $ +* Contact: b.richards@qmul.ac.uk +*/ +class MeanTimeCheck: public Tool { + + + public: + + MeanTimeCheck(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + + private: + +double BasicAverage(); +std::vector* DigitList = 0; +RecoVertex* TrueVtx = 0; +double GetPeakTime(); +double GetWeightedAverage(); +double GetWeightedPeak(); +TFile* Output_tfile = nullptr; +TTree* fVertexGeometry = nullptr; +uint64_t MCEventNum; +uint16_t MCTriggerNum; +uint32_t EventNumber; +TH1D *delta; +TH1D *peakTime; +TH1D *basicAverage; +TH1D *weightedAverage; +TH1D *weightedPeak; +VertexGeometry* VtxGeo; + +int verbosity = -1; +int ShowEvent = -1; +int v_error = 0; +int v_warning = 1; +int v_message = 2; +int v_debug = 3; +std::string logmessage; +int get_ok; + +}; + + +#endif diff --git a/UserTools/MeanTimeCheck/README.md b/UserTools/MeanTimeCheck/README.md new file mode 100644 index 000000000..81ae8f285 --- /dev/null +++ b/UserTools/MeanTimeCheck/README.md @@ -0,0 +1,20 @@ +# MeanTimeCheck + +MeanTimeCheck + +## Data + +Describe any data formats MeanTimeCheck creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for MeanTimeCheck. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp index 8022719e9..96400f859 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp @@ -1611,7 +1611,7 @@ bool PhaseIITreeMaker::FillMCTruthInfo() { } } else { Log("PhaseIITreeMaker Tool: Primary Pdgs information missing. Continuing to build tree",v_message,verbosity); - successful_load = false; + //successful_load = false; } int pi0count, pipcount, pimcount, K0count, Kpcount, Kmcount; diff --git a/UserTools/PhaseIITreeMakerDOE/PhaseIITreeMakerDOE.cpp b/UserTools/PhaseIITreeMakerDOE/PhaseIITreeMakerDOE.cpp new file mode 100644 index 000000000..7d35748de --- /dev/null +++ b/UserTools/PhaseIITreeMakerDOE/PhaseIITreeMakerDOE.cpp @@ -0,0 +1,428 @@ +#include "PhaseIITreeMakerDOE.h" + +PhaseIITreeMakerDOE::PhaseIITreeMakerDOE():Tool(){} + + +bool PhaseIITreeMakerDOE::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Usefull header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); //loading config file + //m_variables.Print(); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("verbose", verbosity); + m_variables.Get("muonMCTruth_fill", muonMCTruth_fill); + m_variables.Get("muonRecoDebug_fill", muonRecoDebug_fill); + m_variables.Get("muonTruthRecoDiff_fill", muonTruthRecoDiff_fill); + + std::string output_filename; + m_variables.Get("OutputFile", output_filename); + fOutput_tfile = new TFile(output_filename.c_str(), "recreate"); + fRecoTree = new TTree("phaseII", "ANNIE Phase II Reconstruction Tree"); + //Metadata for Events + fRecoTree->Branch("McEntryNumber",&fMCEventNum,"McEntryNumber/I"); + fRecoTree->Branch("triggerNumber",&fMCTriggerNum,"triggerNumber/I"); + fRecoTree->Branch("eventNumber",&fEventNumber,"eventNumber/I"); + + //Hit information (PMT and LAPPD) + //Always output in Phase II Reco Tree + fRecoTree->Branch("nhits",&fNhits,"fNhits/I"); + fRecoTree->Branch("filter",&fIsFiltered); + fRecoTree->Branch("digitX",&fDigitX); + fRecoTree->Branch("digitY",&fDigitY); + fRecoTree->Branch("digitZ",&fDigitZ); + fRecoTree->Branch("digitT",&fDigitT); + fRecoTree->Branch("digitQ",&fDigitQ); + fRecoTree->Branch("digitType", &fDigitType); + fRecoTree->Branch("digitDetID", &fDigitDetID); + + //Reconstructed variables after full Muon Reco Analysis + //Always output in Phase II Reco Tree + fRecoTree->Branch("recoVtxX",&fRecoVtxX,"recoVtxX/D"); + fRecoTree->Branch("recoVtxY",&fRecoVtxY,"recoVtxY/D"); + fRecoTree->Branch("recoVtxZ",&fRecoVtxZ,"recoVtxZ/D"); + fRecoTree->Branch("recoVtxTime",&fRecoVtxTime,"recoVtxTime/D"); + fRecoTree->Branch("recoDirX",&fRecoDirX,"recoDirX/D"); + fRecoTree->Branch("recoDirY",&fRecoDirY,"recoDirY/D"); + fRecoTree->Branch("recoDirZ",&fRecoDirZ,"recoDirZ/D"); + fRecoTree->Branch("recoTheta",&fRecoTheta,"recoTheta/D"); + fRecoTree->Branch("recoPhi",&fRecoPhi,"recoPhi/D"); + fRecoTree->Branch("recoVtxFOM",&fRecoVtxFOM,"recoVtxFOM/D"); + fRecoTree->Branch("recoStatus",&fRecoStatus,"recoStatus/I"); + + //MC truth information for muons + //Output to tree when muonMCTruth_fill = 1 in config + if (muonMCTruth_fill){ + fRecoTree->Branch("trueVtxX",&fTrueVtxX,"trueVtxX/D"); + fRecoTree->Branch("trueVtxY",&fTrueVtxY,"trueVtxY/D"); + fRecoTree->Branch("trueVtxZ",&fTrueVtxZ,"trueVtxZ/D"); + fRecoTree->Branch("trueVtxTime",&fTrueVtxTime,"trueVtxTime/D"); + fRecoTree->Branch("trueDirX",&fTrueDirX,"trueDirX/D"); + fRecoTree->Branch("trueDirY",&fTrueDirY,"trueDirY/D"); + fRecoTree->Branch("trueDirZ",&fTrueDirZ,"trueDirZ/D"); + fRecoTree->Branch("trueTheta",&fTrueTheta,"trueTheta/D"); + fRecoTree->Branch("truePhi",&fTruePhi,"truePhi/D"); + } + + // Reconstructed variables from each step in Muon Reco Analysis + // Currently output when muonRecoDebug_fill = 1 in config + if (muonRecoDebug_fill){ + fRecoTree->Branch("seedVtxX",&fSeedVtxX); + fRecoTree->Branch("seedVtxY",&fSeedVtxY); + fRecoTree->Branch("seedVtxZ",&fSeedVtxZ); + fRecoTree->Branch("seedVtxTime",&fSeedVtxTime,"seedVtxTime/D"); + + fRecoTree->Branch("pointPosX",&fPointPosX,"pointPosX/D"); + fRecoTree->Branch("pointPosY",&fPointPosY,"pointPosY/D"); + fRecoTree->Branch("pointPosZ",&fPointPosZ,"pointPosZ/D"); + fRecoTree->Branch("pointPosTime",&fPointPosTime,"pointPosTime/D"); + fRecoTree->Branch("pointPosFOM",&fPointPosFOM,"pointPosFOM/D"); + fRecoTree->Branch("pointPosStatus",&fPointPosStatus,"pointPosStatus/I"); + + fRecoTree->Branch("pointDirX",&fPointDirX,"pointDirX/D"); + fRecoTree->Branch("pointDirY",&fPointDirY,"pointDirY/D"); + fRecoTree->Branch("pointDirZ",&fPointDirZ,"pointDirZ/D"); + fRecoTree->Branch("pointDirTime",&fPointDirTime,"pointDirTime/D"); + fRecoTree->Branch("pointDirStatus",&fPointDirStatus,"pointDirStatus/D"); + fRecoTree->Branch("pointDirFOM",&fPointDirFOM,"pointDirFOM/D"); + + fRecoTree->Branch("pointVtxPosX",&fPointVtxPosX,"pointVtxPosX/D"); + fRecoTree->Branch("pointVtxPosY",&fPointVtxPosY,"pointVtxPosY/D"); + fRecoTree->Branch("pointVtxPosZ",&fPointVtxPosZ,"pointVtxPosZ/D"); + fRecoTree->Branch("pointVtxTime",&fPointVtxTime,"pointVtxTime/D"); + fRecoTree->Branch("pointVtxDirX",&fPointVtxDirX,"pointVtxDirX/D"); + fRecoTree->Branch("pointVtxDirY",&fPointVtxDirY,"pointVtxDirY/D"); + fRecoTree->Branch("pointVtxDirZ",&fPointVtxDirZ,"pointVtxDirZ/D"); + fRecoTree->Branch("pointVtxFOM",&fPointVtxFOM,"pointVtxFOM/D"); + fRecoTree->Branch("pointVtxStatus",&fPointVtxStatus,"pointVtxStatus/D"); + } + + // Difference in MC Truth and Muon Reconstruction Analysis + // Output to tree when muonTruthRecoDiff_fill = 1 in config + if (muonTruthRecoDiff_fill){ + fRecoTree->Branch("DeltaVtxX",&fDeltaVtxX,"DeltaVtxX/D"); + fRecoTree->Branch("DeltaVtxY",&fDeltaVtxY,"DeltaVtxY/D"); + fRecoTree->Branch("DeltaVtxZ",&fDeltaVtxZ,"DeltaVtxZ/D"); + fRecoTree->Branch("DeltaVtxR",&fDeltaVtxR,"DeltaVtxR/D"); + fRecoTree->Branch("DeltaVtxT",&fDeltaVtxT,"DeltaVtxT/D"); + fRecoTree->Branch("DeltaParallel",&fDeltaParallel,"DeltaParallel/D"); + fRecoTree->Branch("DeltaPerpendicular",&fDeltaPerpendicular,"DeltaPerpendicular/D"); + fRecoTree->Branch("DeltaAzimuth",&fDeltaAzimuth,"DeltaAzimuth/D"); + fRecoTree->Branch("DeltaZenith",&fDeltaZenith,"DeltaZenith/D"); + fRecoTree->Branch("DeltaAngle",&fDeltaAngle,"DeltaAngle/D"); + } + + return true; +} + +bool PhaseIITreeMakerDOE::Execute(){ + Log("===========================================================================================",v_debug,verbosity); + Log("PhaseIITreeMakerDOE Tool: Executing",v_debug,verbosity); + + // Reset variables + this->ResetVariables(); + // Get a pointer to the ANNIEEvent Store + auto* annie_event = m_data->Stores["RecoEvent"]; + if (!annie_event) { + Log("Error: The PhaseITreeMakerDOE tool could not find the RecoEvent Store", v_error, verbosity); + return false; + } + + // check if event passes the cut + bool EventCutstatus = false; + auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus",EventCutstatus); + if(!get_evtstatus) { + Log("Error: The PhaseITreeMakerDOE tool could not find the Event selection status", v_error, verbosity); + return false; + } + + if(!EventCutstatus) { + Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); + return true; + } + + // MC entry number + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum",fMCEventNum); + + // MC trigger number + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum",fMCTriggerNum); + + // ANNIE Event number + m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); + + std::string logmessage = " Retriving information for MCEntry "+to_string(fMCEventNum)+ + ", MCTrigger "+ to_string(fMCTriggerNum) + ", EventNumber " + to_string(fEventNumber); + Log(logmessage, v_message, verbosity); + + // Read digits + std::vector* digitList = nullptr; + m_data->Stores.at("RecoEvent")->Get("RecoDigit",digitList); ///> Get digits from "RecoEvent" + fNhits = digitList->size(); + for( auto& digit : *digitList ){ + fDigitX.push_back(digit.GetPosition().X()); + fDigitY.push_back(digit.GetPosition().Y()); + fDigitZ.push_back(digit.GetPosition().Z()); + fDigitT.push_back(digit.GetCalTime()); + fDigitQ.push_back(digit.GetCalCharge()); + fDigitType.push_back(digit.GetDigitType()); + fDigitDetID.push_back(digit.GetDetectorID()); + } + + // Read reconstructed Vertex + RecoVertex* recovtx = 0; + auto get_extendedvtx = m_data->Stores.at("RecoEvent")->Get("ExtendedVertex",recovtx); + if(!get_extendedvtx) { + Log("Error: The PhaseITreeMaker tool could not find ExtendedVertex", v_error, verbosity); + return false; + } + fRecoVtxX = recovtx->GetPosition().X(); + fRecoVtxY = recovtx->GetPosition().Y(); + fRecoVtxZ = recovtx->GetPosition().Z(); + fRecoVtxTime = recovtx->GetTime(); + fRecoVtxFOM = recovtx->GetFOM(); + fRecoDirX = recovtx->GetDirection().X(); + fRecoDirY = recovtx->GetDirection().Y(); + fRecoDirZ = recovtx->GetDirection().Z(); + fRecoTheta = TMath::ACos(fRecoDirZ); + if (fRecoDirX>0.0){ + fRecoPhi = atan(fRecoDirY/fRecoDirX); + } + if (fRecoDirX<0.0){ + fRecoPhi = atan(fRecoDirY/fRecoDirX); + if( fRecoDirY>0.0) fRecoPhi += TMath::Pi(); + if( fRecoDirY<=0.0) fRecoPhi -= TMath::Pi(); + } + if (fRecoDirX==0.0){ + if( fRecoDirY>0.0) fRecoPhi = 0.5*TMath::Pi(); + else if( fRecoDirY<0.0) fRecoPhi = -0.5*TMath::Pi(); + else fRecoPhi = 0; + } + fRecoStatus = recovtx->GetStatus(); + + // Read True Vertex if flag is set + RecoVertex* truevtx = 0; + auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex",truevtx); + if(get_muonMC){ + fTrueVtxX = truevtx->GetPosition().X(); + fTrueVtxY = truevtx->GetPosition().Y(); + fTrueVtxZ = truevtx->GetPosition().Z(); + fTrueVtxTime = truevtx->GetTime(); + fTrueDirX = truevtx->GetDirection().X(); + fTrueDirY = truevtx->GetDirection().Y(); + fTrueDirZ = truevtx->GetDirection().Z(); + fTrueTheta = TMath::ACos(fTrueDirZ); + if (fTrueDirX>0.0){ + fTruePhi = atan(fTrueDirY/fTrueDirX); + } + if (fTrueDirX<0.0){ + fTruePhi = atan(fTrueDirY/fTrueDirX); + if( fTrueDirY>0.0) fTruePhi += TMath::Pi(); + if( fTrueDirY<=0.0) fTruePhi -= TMath::Pi(); + } + if (fTrueDirX==0.0){ + if( fTrueDirY>0.0) fTruePhi = 0.5*TMath::Pi(); + else if( fTrueDirY<0.0) fTruePhi = -0.5*TMath::Pi(); + else fTruePhi = 0; + } + } else { + Log("PhaseIITreeMakerDOE Tool: No MC Truth data found; is this MC? Continuing to build remaining tree",v_message,verbosity); + } + + if (muonRecoDebug_fill){ + // Read Seed candidates + std::vector* seedvtxlist = 0; + auto get_seedvtxlist = m_data->Stores.at("RecoEvent")->Get("vSeedVtxList",seedvtxlist); ///> Get List of seeds from "RecoEvent" + if(get_seedvtxlist){ + for( auto& seed : *seedvtxlist ){ + fSeedVtxX.push_back(seed.GetPosition().X()); + fSeedVtxY.push_back(seed.GetPosition().Y()); + fSeedVtxZ.push_back(seed.GetPosition().Z()); + fSeedVtxTime = seed.GetTime(); + } + } else { + Log("PhaseIITreeMakerDOE Tool: No Seed List found. Continuing to build tree ",v_message,verbosity); + } + + // Read PointPosition-fitted Vertex + RecoVertex* pointposvtx = 0; + auto get_pointposdata = m_data->Stores.at("RecoEvent")->Get("PointPosition",pointposvtx); + if(get_pointposdata){ + fPointPosX = pointposvtx->GetPosition().X(); + fPointPosY = pointposvtx->GetPosition().Y(); + fPointPosZ = pointposvtx->GetPosition().Z(); + fPointPosTime = pointposvtx->GetTime(); + fPointPosFOM = pointposvtx->GetFOM(); + fPointPosStatus = pointposvtx->GetStatus(); + } else{ + Log("PhaseIITreeMakerDOE Tool: No PointPosition Tool data found. Continuing to build remaining tree",v_message,verbosity); + } + + // Read PointDirection-fitted Vertex + RecoVertex* pointdirvtx = 0; + auto get_pointdirdata = m_data->Stores.at("RecoEvent")->Get("PointDirection",pointdirvtx); + if(get_pointdirdata){ + fPointDirX = pointdirvtx->GetDirection().X(); + fPointDirY = pointdirvtx->GetDirection().Y(); + fPointDirZ = pointdirvtx->GetDirection().Z(); + fPointDirTime = pointdirvtx->GetTime(); + fPointDirFOM = pointdirvtx->GetFOM(); + fPointDirStatus = pointdirvtx->GetStatus(); + } else{ + Log("PhaseIITreeMakerDOE Tool: No PointDirection Tool data found. Continuing to build remaining tree",v_message,verbosity); + } + + // Read PointVertex Tool's fitted Vertex + RecoVertex* pointvtx = 0; + auto get_pointvtxdata = m_data->Stores.at("RecoEvent")->Get("PointVertex",pointvtx); + if(get_pointvtxdata){ + fPointVtxPosX = pointvtx->GetPosition().X(); + fPointVtxPosY = pointvtx->GetPosition().Y(); + fPointVtxPosZ = pointvtx->GetPosition().Z(); + fPointVtxDirX = pointvtx->GetDirection().X(); + fPointVtxDirY = pointvtx->GetDirection().Y(); + fPointVtxDirZ = pointvtx->GetDirection().Z(); + fPointVtxTime = pointvtx->GetTime(); + fPointVtxFOM = pointvtx->GetFOM(); + fPointVtxStatus = pointvtx->GetStatus(); + } else{ + Log("PhaseIITreeMakerDOE Tool: No PointVertex Tool data found. Continuing to build remaining tree",v_message,verbosity); + } + } + + + if (muonTruthRecoDiff_fill){ + //Let's fill in stuff from the RecoSummary + fDeltaVtxX = fRecoVtxX - fTrueVtxX; + fDeltaVtxY = fRecoVtxY - fTrueVtxY; + fDeltaVtxZ = fRecoVtxZ - fTrueVtxZ; + fDeltaVtxT = fRecoVtxTime - fTrueVtxTime; + fDeltaVtxR = sqrt(pow(fDeltaVtxX,2) + pow(fDeltaVtxY,2) + pow(fDeltaVtxZ,2)); + fDeltaParallel = fDeltaVtxX*fRecoDirX + fDeltaVtxY*fRecoDirY + fDeltaVtxZ*fRecoDirZ; + fDeltaPerpendicular = sqrt(pow(fDeltaVtxR,2) - pow(fDeltaParallel,2)); + fDeltaAzimuth = (fRecoTheta - fTrueTheta)/(TMath::Pi()/180.0); + fDeltaZenith = (fRecoPhi - fTruePhi)/(TMath::Pi()/180.0); + double cosphi = fTrueDirX*fRecoDirX+fTrueDirY*fRecoDirY+fTrueDirZ*fRecoDirZ; + double phi = TMath::ACos(cosphi); // radians + double TheAngle = phi/(TMath::Pi()/180.0); // radians->degrees + fDeltaAngle = TheAngle; + } + + fRecoTree->Fill(); + this->RecoSummary(); + return true; +} + +bool PhaseIITreeMakerDOE::Finalise(){ + fOutput_tfile->cd(); + fRecoTree->Write(); + fOutput_tfile->Close(); + + if(verbosity>0) cout<<"PhaseIITreeMakerDOE exitting"<degrees + std::cout << "============================================================================"< fIsFiltered; + std::vector fDigitX; + std::vector fDigitY; + std::vector fDigitZ; + std::vector fDigitT; + std::vector fDigitQ; + std::vector fDigitType; + std::vector fDigitDetID; + + // True muon + double fTrueVtxX; + double fTrueVtxY; + double fTrueVtxZ; + double fTrueVtxTime; + double fTrueDirX; + double fTrueDirY; + double fTrueDirZ; + double fTrueTheta; + double fTruePhi; + double fTrueEnergy; + + // Seed vertex + std::vector fSeedVtxX; + std::vector fSeedVtxY; + std::vector fSeedVtxZ; + double fSeedVtxTime; + + // Reco vertex + // Point Position Vertex + double fPointPosX; + double fPointPosY; + double fPointPosZ; + double fPointPosTime; + double fPointPosFOM; + int fPointPosStatus; + double fPointDirX; + double fPointDirY; + double fPointDirZ; + double fPointDirTime; + double fPointDirFOM; + int fPointDirStatus; + + // Point Vertex Finder + double fPointVtxPosX; + double fPointVtxPosY; + double fPointVtxPosZ; + double fPointVtxTime; + double fPointVtxDirX; + double fPointVtxDirY; + double fPointVtxDirZ; + double fPointVtxFOM; + int fPointVtxStatus; + + // Extended Vertex + double fRecoVtxX; + double fRecoVtxY; + double fRecoVtxZ; + double fRecoVtxTime; + double fRecoDirX; + double fRecoDirY; + double fRecoDirZ; + double fRecoVtxFOM; + double fRecoTheta; + double fRecoPhi; + int fRecoStatus; + + double fDeltaVtxX; + double fDeltaVtxY; + double fDeltaVtxZ; + double fDeltaVtxR; + double fDeltaVtxT; + double fDeltaParallel; + double fDeltaPerpendicular; + double fDeltaAzimuth; + double fDeltaZenith; + double fDeltaAngle; + + + /// \brief Integer that determines the level of logging to perform + int verbosity = 0; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; + int get_ok; + + /// \Integer flags that control additional output to the PhaseIITree + int muonMCTruth_fill = 0; //Output the MC truth information + int muonRecoDebug_fill = 0; //Outputs results of Reconstruction at each step (best fits, FOMs, etc.) + int muonTruthRecoDiff_fill = 0; //Output difference in truth and reconstructed values +}; + + +#endif diff --git a/UserTools/PhaseIITreeMakerDOE/README.md b/UserTools/PhaseIITreeMakerDOE/README.md new file mode 100644 index 000000000..03ad96506 --- /dev/null +++ b/UserTools/PhaseIITreeMakerDOE/README.md @@ -0,0 +1,36 @@ +# PhaseIITreeMakerDOE + +PhaseIITreeMakerDOE + +## Data + +Describe any data formats PhaseIITreeMakerDOE creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + +## Configuration + +Describe any configuration variables for PhaseIITreeMakerDOE. + +``` +verbose (1 or 0) +Defines the level of verbosity for outputs of PhaseIITreeMakerDOE algorithm. + +muonMCTruth_fill (1 or 0) +Input will determine if Truth information from files given is saved to the +reco tree. Will output to tree if 1. + +muonTruthRecoDiff_fill (1 or 0) +Input determines if the difference in truth and reco information is saved to +the reco tree. Will output to tree if 1. + +muonRecoDebug_fill (1 or 0) +Input determines if reconstruction variables at each step in the muon event +reconstruction chain are saved to the tree. Values include seeds from SeedVtxFinder, +fits from PointPosFinder, and FOMs for likelihood fits at each reconstruction step. +Will output to tree if 1. + +param1 value1 +param2 value2 +``` diff --git a/UserTools/Unity.h b/UserTools/Unity.h index dc6e501b7..cd6a8047e 100644 --- a/UserTools/Unity.h +++ b/UserTools/Unity.h @@ -56,6 +56,7 @@ #include "LAPPDAnalysis.h" #include "ExampleOverTool.h" #include "PhaseIITreeMaker.h" +#include "PhaseIITreeMakerDOE.h" #include "VertexGeometryCheck.h" #include "LikelihoodFitterCheck.h" #include "EventSelector.h" @@ -162,8 +163,11 @@ #include "GetLAPPDEvents.h" #include "LAPPDDataDecoder.h" #include "PythonScript.h" +#include "MeanTimeCheck.h" #include "ReweightEventsGenie.h" #include "FilterLAPPDEvents.h" +#include "VtxSeedFineGrid.h" +#include "DirectionGridCheck.h" #include "FilterEvents.h" #include "Stage1DataBuilder.h" #include "BeamFetcherV2.h" diff --git a/UserTools/VertexGeometryCheck/README.md b/UserTools/VertexGeometryCheck/README.md old mode 100644 new mode 100755 diff --git a/UserTools/VertexGeometryCheck/VertexGeometryCheck.cpp b/UserTools/VertexGeometryCheck/VertexGeometryCheck.cpp old mode 100644 new mode 100755 index 9cde9d960..3e18909e6 --- a/UserTools/VertexGeometryCheck/VertexGeometryCheck.cpp +++ b/UserTools/VertexGeometryCheck/VertexGeometryCheck.cpp @@ -12,6 +12,10 @@ bool VertexGeometryCheck::Initialise(std::string configfile, DataModel &data){ m_variables.Get("verbosity", verbosity); m_variables.Get("OutputFile", output_filename); m_variables.Get("ShowEvent", fShowEvent); + m_variables.Get("Theta", vertheta); + m_variables.Get("Phi", verphi); + m_variables.Get("StripTimePlot", StripTimePlot); + m_variables.Get("CleanHitsOnly", cleanHitsOnly); fOutput_tfile = new TFile(output_filename.c_str(), "recreate"); // Histograms @@ -31,7 +35,13 @@ bool VertexGeometryCheck::Initialise(std::string configfile, DataModel &data){ fpmttimesmear = new TH1D("pmttimesmear","pmttimesmear",100, 0, 1.0); fYvsDigitTheta_all = new TH2D("YvsDigitTheta_all", "Y vs DigitTheta", 400, -200, 200, 400, -200, 200); fYvsDigitTheta_all->GetXaxis()->SetTitle("DigitTheta [deg]"); - fYvsDigitTheta_all->GetYaxis()->SetTitle("Digit Y [cm]"); + fYvsDigitTheta_all->GetYaxis()->SetTitle("Digit Y [cm]"); + if (StripTimePlot > 0) { + StripHits1 = new TH2D("LAPPD Strip Time Residual", "LAPPD Strip Time Residual", 300, 0, 15, 400, -200, 200); + StripHits1->SetTitle("LAPPD Hit Time vs. strip"); + StripHits1->GetYaxis()->SetTitle("Hit Time"); + StripHits1->GetXaxis()->SetTitle("Strip Location(x)"); + } m_data= &data; //assigning transient data pointer ///////////////////////////////////////////////////////////////// @@ -39,142 +49,178 @@ bool VertexGeometryCheck::Initialise(std::string configfile, DataModel &data){ } -bool VertexGeometryCheck::Execute(){ - Log("===========================================================================================",v_debug,verbosity); - - Log("VertexGeometryCheck Tool: Executing",v_debug,verbosity); +bool VertexGeometryCheck::Execute() { + Log("===========================================================================================", v_debug, verbosity); - // Get a pointer to the ANNIEEvent Store - auto* reco_event = m_data->Stores["RecoEvent"]; - if (!reco_event) { - Log("Error: The PhaseITreeMaker tool could not find the ANNIEEvent Store", - 0, verbosity); - return false; - } - - // MC entry number - m_data->Stores.at("ANNIEEvent")->Get("MCEventNum",fMCEventNum); - - // MC trigger number - m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum",fMCTriggerNum); - - // ANNIE Event number - m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); - - // Only check this event - if(fShowEvent>0 && (int)fEventNumber!=fShowEvent) return true; - - // check if event passes the cut - bool EventCutstatus = false; - auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus",EventCutstatus); - if(!get_evtstatus) { - Log("Error: The VertexGeometryCheck tool could not find the Event selection status", v_error, verbosity); - return false; - } - if(!EventCutstatus) { - Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); - return true; - } - - // Read True Vertex - RecoVertex* truevtx = 0; - auto get_vtx = m_data->Stores.at("RecoEvent")->Get("TrueVertex",fTrueVertex); ///> Get digits from "RecoEvent" - if(!get_vtx){ - Log("VertexGeometryCheck Tool: Error retrieving TrueVertex! ",v_error,verbosity); - return true; - } - - // Retrive digits from RecoEvent - auto get_digit = m_data->Stores.at("RecoEvent")->Get("RecoDigit",fDigitList); ///> Get digits from "RecoEvent" - if(!get_digit){ - Log("VertexGeometryCheck Tool: Error retrieving RecoDigits,no digit from the RecoEvent!",v_error,verbosity); - return true; - } - - - double recoVtxX, recoVtxY, recoVtxZ, recoVtxT, recoDirX, recoDirY, recoDirZ; - double trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ; - double digitX, digitY, digitZ, digitT; - double dx, dy, dz, px, py, pz, ds, cosphi, sinphi, phi, phideg; - - Position vtxPos = fTrueVertex->GetPosition(); - Direction vtxDir = fTrueVertex->GetDirection(); - trueVtxX = vtxPos.X(); - trueVtxY = vtxPos.Y(); - trueVtxZ = vtxPos.Z(); - trueVtxT = fTrueVertex->GetTime(); - trueDirX = vtxDir.X(); - trueDirY = vtxDir.Y(); - trueDirZ = vtxDir.Z(); - - double ConeAngle = Parameters::CherenkovAngle(); - - FoMCalculator * myFoMCalculator = new FoMCalculator(); - VertexGeometry* myvtxgeo = VertexGeometry::Instance(); - myvtxgeo->LoadDigits(fDigitList); - myFoMCalculator->LoadVertexGeometry(myvtxgeo); //Load vertex geometry - int nhits = myvtxgeo->GetNDigits(); - myvtxgeo->CalcExtendedResiduals(trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ); - double meantime = myFoMCalculator->FindSimpleTimeProperties(ConeAngle); - fmeanres->Fill(meantime); - double fom = -999.999*100; - myFoMCalculator->TimePropertiesLnL(meantime,fom); - for(int n=0;nat(n).GetPosition().X(); - digitY = fDigitList->at(n).GetPosition().Y(); - digitZ = fDigitList->at(n).GetPosition().Z(); - digitT = fDigitList->at(n).GetCalTime(); - dx = digitX-trueVtxX; - dy = digitY-trueVtxY; - dz = digitZ-trueVtxZ; - ds = sqrt(dx*dx+dy*dy+dz*dz); - px = dx/ds; - py = dy/ds; - pz = dz/ds; - cosphi = 1.0; - sinphi = 1.0; - phi = 0.0; - phideg = 0.0; - // zenith angle relative to muon track direction - if( trueDirX*trueDirX + trueDirY*trueDirY + trueDirZ*trueDirZ>0.0 ){ - // zenith angle - cosphi = px*trueDirX+py*trueDirY+pz*trueDirZ; - phi = acos(cosphi); // radians - phideg = phi/(TMath::Pi()/180.0); // radians->degrees + Log("VertexGeometryCheck Tool: Executing", v_debug, verbosity); + + // Get a pointer to the ANNIEEvent Store + auto* reco_event = m_data->Stores["RecoEvent"]; + if (!reco_event) { + Log("Error: The PhaseITreeMaker tool could not find the ANNIEEvent Store", + 0, verbosity); + return false; } - // Y vs theta - double theta = 0.0; - double thetadeg = 0.0; - if( digitZ!=0.0 ){ - theta = atan(digitX/digitZ); + + // MC entry number + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum", fMCEventNum); + + // MC trigger number + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum", fMCTriggerNum); + + // ANNIE Event number + m_data->Stores.at("ANNIEEvent")->Get("EventNumber", fEventNumber); + + // Only check this event + if (fShowEvent > 0 && (int)fEventNumber != fShowEvent) return true; +std::cout<<"VtxGeometryCheck adding event "<Stores.at("RecoEvent")->Get("EventCutStatus", EventCutstatus); + if (!get_evtstatus) { + Log("Error: The VertexGeometryCheck tool could not find the Event selection status", v_error, verbosity); + //return false; } - if( digitZ<=0.0 ){ - if( digitX>0.0 ) theta += TMath::Pi(); - if( digitX<0.0 ) theta -= TMath::Pi(); + if (!EventCutstatus) { + Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); + //return true; } - thetadeg = theta/(TMath::Pi()/180.0); // radians->degrees - fYvsDigitTheta_all->Fill(thetadeg,digitY); - fdelta->Fill(myvtxgeo->GetDelta(n)); - fpointtres->Fill(myvtxgeo->GetPointResidual(n)); - if(myvtxgeo->GetDigitType(n)==RecoDigit::lappd_v0) flappdextendedtres->Fill(myvtxgeo->GetExtendedResidual(n)); - if(myvtxgeo->GetDigitType(n)==RecoDigit::PMT8inch) fpmtextendedtres->Fill(myvtxgeo->GetExtendedResidual(n)); - fltrack->Fill(myvtxgeo->GetDistTrack(n)); //cm - flphoton->Fill(myvtxgeo->GetDistPhoton(n)); //cm - fzenith->Fill(myvtxgeo->GetZenith(n)); // - fazimuth->Fill(myvtxgeo->GetAzimuth(n)); // - fconeangle->Fill(myvtxgeo->GetConeAngle(n)); // - fdigitcharge->Fill(myvtxgeo->GetDigitQ(n)); - fdigittime->Fill(digitT); - if(myvtxgeo->GetDigitType(n)==RecoDigit::lappd_v0) flappdtimesmear->Fill(Parameters::TimeResolution(RecoDigit::lappd_v0, myvtxgeo->GetDigitQ(n))); - if(myvtxgeo->GetDigitType(n)==RecoDigit::PMT8inch) fpmttimesmear->Fill(Parameters::TimeResolution(RecoDigit::PMT8inch, myvtxgeo->GetDigitQ(n))); - } - delete myFoMCalculator; + + // Read True Vertex + RecoVertex* truevtx = 0; + auto get_vtx = m_data->Stores.at("RecoEvent")->Get("TrueVertex", fTrueVertex); ///> Get digits from "RecoEvent" + if (!get_vtx) { + Log("VertexGeometryCheck Tool: Error retrieving TrueVertex! ", v_error, verbosity); + return true; + } + + // Retrive digits from RecoEvent + auto get_digit = m_data->Stores.at("RecoEvent")->Get("RecoDigit", fDigitList); ///> Get digits from "RecoEvent" + if (!get_digit) { + Log("VertexGeometryCheck Tool: Error retrieving RecoDigits,no digit from the RecoEvent!", v_error, verbosity); + return true; + } + + double recoVtxX, recoVtxY, recoVtxZ, recoVtxT, recoDirX, recoDirY, recoDirZ; + double trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ; + double digitX, digitY, digitZ, digitT; + double dx, dy, dz, px, py, pz, ds, cosphi, sinphi, phi, phideg; + + Position vtxPos = fTrueVertex->GetPosition(); + Direction vtxDir = fTrueVertex->GetDirection(); + trueVtxX = vtxPos.X(); + trueVtxY = vtxPos.Y(); + trueVtxZ = vtxPos.Z(); + trueVtxT = fTrueVertex->GetTime(); + trueDirX = vtxDir.X(); + trueDirY = vtxDir.Y(); + trueDirZ = vtxDir.Z(); + if (vertheta != -999 && verphi != -999) { + Log("overriding direction", v_debug, verbosity); + trueDirX = cos(vertheta) * sin(verphi); + trueDirY = sin(vertheta) * sin(verphi); + trueDirZ = cos(verphi); + } + + double ConeAngle = Parameters::CherenkovAngle(); + + FoMCalculator* myFoMCalculator = new FoMCalculator(); + VertexGeometry* myvtxgeo = VertexGeometry::Instance(); + myvtxgeo->LoadDigits(fDigitList); + myFoMCalculator->LoadVertexGeometry(myvtxgeo); //Load vertex geometry + int nhits = myvtxgeo->GetNDigits(); + myvtxgeo->CalcExtendedResiduals(trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ); + double meantime = myFoMCalculator->FindSimpleTimeProperties(ConeAngle); + fmeanres->Fill(meantime); + double fom = -999.999 * 100; + myFoMCalculator->TimePropertiesLnL(meantime, fom); + std::string stripPlotName; + int currentLAPPD = 0; + + int iStripHit = 0; + std::cout << "VGCheck entering for loop\n"; + for (int n = 0; n < nhits; n++) { + if (cleanHitsOnly && !(fDigitList->at(n).GetFilterStatus())) continue; + digitX = fDigitList->at(n).GetPosition().X(); + digitY = fDigitList->at(n).GetPosition().Y(); + digitZ = fDigitList->at(n).GetPosition().Z(); + digitT = fDigitList->at(n).GetCalTime(); + dx = digitX - trueVtxX; + dy = digitY - trueVtxY; + dz = digitZ - trueVtxZ; + ds = sqrt(dx * dx + dy * dy + dz * dz); + px = dx / ds; + py = dy / ds; + pz = dz / ds; + cosphi = 1.0; + sinphi = 1.0; + phi = 0.0; + phideg = 0.0; + // zenith angle relative to muon track direction + if (trueDirX * trueDirX + trueDirY * trueDirY + trueDirZ * trueDirZ > 0.0) { + // zenith angle + cosphi = px * trueDirX + py * trueDirY + pz * trueDirZ; + phi = acos(cosphi); // radians + phideg = phi / (TMath::Pi() / 180.0); // radians->degrees + } + // Y vs theta + double theta = 0.0; + double thetadeg = 0.0; + if (digitZ != 0.0) { + theta = atan(digitX / digitZ); + } + if (digitZ <= 0.0) { + if (digitX > 0.0) theta += TMath::Pi(); + if (digitX < 0.0) theta -= TMath::Pi(); + } + thetadeg = theta / (TMath::Pi() / 180.0); // radians->degrees + if(fDigitList->at(n).GetDigitType() == RecoDigit::PMT8inch)fYvsDigitTheta_all->Fill(thetadeg, digitY, digitT); + if(fDigitList->at(n).GetDigitType() == RecoDigit::lappd_v0)fYvsDigitTheta_all->Fill(thetadeg, digitY, digitT); + fdelta->Fill(myvtxgeo->GetDelta(n)); + fpointtres->Fill(myvtxgeo->GetPointResidual(n)); + if (myvtxgeo->GetDigitType(n) == RecoDigit::lappd_v0) flappdextendedtres->Fill(myvtxgeo->GetExtendedResidual(n)); + if (myvtxgeo->GetDigitType(n) == RecoDigit::PMT8inch) fpmtextendedtres->Fill(myvtxgeo->GetExtendedResidual(n)); + fltrack->Fill(myvtxgeo->GetDistTrack(n)); //cm + flphoton->Fill(myvtxgeo->GetDistPhoton(n)); //cm + fzenith->Fill(phideg/*myvtxgeo->GetZenith(n)*/); // + fazimuth->Fill(myvtxgeo->GetAzimuth(n)); // + fconeangle->Fill(myvtxgeo->GetConeAngle(n)); // + fdigitcharge->Fill(myvtxgeo->GetDigitQ(n)); + fdigittime->Fill(digitT); + if (myvtxgeo->GetDigitType(n) == RecoDigit::lappd_v0) flappdtimesmear->Fill(Parameters::TimeResolution(RecoDigit::lappd_v0, myvtxgeo->GetDigitQ(n))); + if (myvtxgeo->GetDigitType(n) == RecoDigit::PMT8inch) fpmttimesmear->Fill(Parameters::TimeResolution(RecoDigit::PMT8inch, myvtxgeo->GetDigitQ(n))); + std::cout << "VGCheck " << n << endl; + if (StripTimePlot > 0) { + if (fDigitList->at(n).GetDigitType() == RecoDigit::lappd_v0 && fDigitList->at(n).GetCalTime()>0 /* && fDigitList->at(n).GetDetectorID() == StripTimePlot*/) { + if (fDigitList->at(n).GetDetectorID() != currentLAPPD) + { + + if (currentLAPPD > 0 && iStripHit > 0) { + stripPlotName = "StripPlot_e" + std::to_string(fEventNumber) + "lappd" + std::to_string(currentLAPPD); + fOutput_tfile->cd(); + StripHits1->Write(stripPlotName.c_str()); + } + StripHits1->Reset(); + currentLAPPD = fDigitList->at(n).GetDetectorID(); + iStripHit = 0; + } + StripHits1->Fill(fDigitList->at(n).GetPosition().X(), fDigitList->at(n).GetCalTime() * 1000/*, fDigitList->at(n).GetCalCharge()*/); + iStripHit++; + std::cout << "VGCheck striphit"; + + } + } + } + + delete myFoMCalculator; + return true; } bool VertexGeometryCheck::Finalise(){ fOutput_tfile->cd(); fOutput_tfile->Write(); + if (StripTimePlot > 0) StripHits1->Write("lappdtimegradient"); fOutput_tfile->Close(); Log("VertexGeometryCheck exitting", v_debug,verbosity); return true; diff --git a/UserTools/VertexGeometryCheck/VertexGeometryCheck.h b/UserTools/VertexGeometryCheck/VertexGeometryCheck.h old mode 100644 new mode 100755 index 414f309b0..559ce7451 --- a/UserTools/VertexGeometryCheck/VertexGeometryCheck.h +++ b/UserTools/VertexGeometryCheck/VertexGeometryCheck.h @@ -64,7 +64,11 @@ class VertexGeometryCheck: public Tool { TH1D *fdigittime; TH1D *flappdtimesmear; TH1D *fpmttimesmear; - TH2D *fYvsDigitTheta_all; + TH2D* fYvsDigitTheta_all; + TH2D* StripHits1; + double vertheta = -999, verphi = -999; + int StripTimePlot = -1; + bool cleanHitsOnly = 0; /// verbosity levels: if 'verbosity' < this level, the message type will be logged. diff --git a/UserTools/VtxExtendedVertexFinder/README.md b/UserTools/VtxExtendedVertexFinder/README.md old mode 100644 new mode 100755 diff --git a/UserTools/VtxExtendedVertexFinder/VtxExtendedVertexFinder.h b/UserTools/VtxExtendedVertexFinder/VtxExtendedVertexFinder.h old mode 100644 new mode 100755 diff --git a/UserTools/VtxSeedFineGrid/README.md b/UserTools/VtxSeedFineGrid/README.md new file mode 100755 index 000000000..fc5f3d780 --- /dev/null +++ b/UserTools/VtxSeedFineGrid/README.md @@ -0,0 +1,20 @@ +# VtxSeedFineGrid + +VtxSeedFineGrid + +## Data + +Describe any data formats VtxSeedFineGrid creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for VtxSeedFineGrid. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.cpp b/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.cpp new file mode 100755 index 000000000..a7f443b3e --- /dev/null +++ b/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.cpp @@ -0,0 +1,470 @@ +#include "VtxSeedFineGrid.h" + +VtxSeedFineGrid::VtxSeedFineGrid():Tool(){} + + +bool VtxSeedFineGrid::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + m_variables.Get("verbosity", verbosity); + m_variables.Get("useTrueDir", useTrueDir); + m_variables.Get("useSimpleDir", useSimpleDir); + m_variables.Get("useMRDTrack", useMRDTrack); + m_variables.Get("usePastResolution", usePastResolution); + m_variables.Get("useDirectionGrid", useDirectionGrid); + m_variables.Get("multiGrid", multiGrid); + m_variables.Get("InputFile", InputFile); + + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + vSeedVtxList = nullptr; + + return true; +} + + +bool VtxSeedFineGrid::Execute(){ + Log("VtxSeedFineGrid Tool: Executing", v_debug, verbosity); + + auto* annie_event = m_data->Stores["RecoEvent"]; + if (!annie_event) { + Log("Error: VtxSeedFineGrid tool could not find the RecoEvent Store", v_error, verbosity); + return false; + } + + m_data->Stores.at("RecoEvent")->Get("vSeedVtxList", vSeedVtxList); + + auto get_vtx = m_data->Stores.at("RecoEvent")->Get("TrueVertex", fTrueVertex); ///> Get digits from "RecoEvent" +/* if (!get_vtx) { + Log("LikelihoodFitterCheck Tool: Error retrieving TrueVertex! ", v_error, verbosity); + return false; + }*/ + + // check if event passes the cut + bool EventCutstatus = false; + auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus", EventCutstatus); + if (!get_evtstatus) { + Log("Error: The PhaseITreeMaker tool could not find the Event selection status", v_error, verbosity); + //return false; + Log("running with reco cuts or none.",v_debug,verbosity); + EventCutstatus = true; + } + + if (!EventCutstatus) { + Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); + return true; + } + + // Retrive digits from RecoEvent + auto get_digit = m_data->Stores.at("RecoEvent")->Get("RecoDigit", fDigitList); ///> Get digits from "RecoEvent" + if (!get_digit) { + Log("LikelihoodFitterCheck Tool: Error retrieving RecoDigits,no digit from the RecoEvent!", v_error, verbosity); + return false; + } + auto get_flagsapp = m_data->Stores.at("RecoEvent")->Get("EventFlagApplied",fEventStatusApplied); + auto get_flags = m_data->Stores.at("RecoEvent")->Get("EventFlagged",fEventStatusFlagged); + if(!get_flagsapp || !get_flags) { + Log("PhaseITreeMaker tool: No Event status applied or flagged bitmask!!", v_error, verbosity); + //return false; + } + // check if event passes the cut + if((fEventStatusFlagged) != 0) { + Log("PhaseIITreeMaker Tool: Event was flagged with one of the active cuts.",v_debug, verbosity); + return true; + } + + if (useSimpleDir) { + Log("Using simple direction", v_debug, verbosity); + } + + if (useTrueDir && useMRDTrack) { + Log("Unable to use two directions; defaulting to true direction", v_debug, verbosity); //will change to not use true, to be more general, once MRD track usage is tested and acceptable + useMRDTrack = 0; + } + if (multiGrid) { + Log("Using MultiGrid(3)", v_debug, verbosity); //Currently using only three. May make variable later + std::cout << "Using MultiGrid(3)\n"; + } + + this->FindCenter(); + if (multiGrid) { + for (int i = 0; i < 3; i++) { + Center.push_back(vSeedVtxList->at(centerIndex[i]).GetPosition()); + } + } + else { Center.push_back(vSeedVtxList->at(centerIndex[0]).GetPosition()); } + this->GenerateFineGrid(); + for (int i = 0; i < Center.size(); i++) { + std::cout << "Center " << i << ": " << Center.at(i).X() << ", " << Center.at(i).Y() << ", " << Center.at(i).Z() << endl; + } + m_data->Stores.at("RecoEvent")->Set("vSeedVtxList", vSeedVtxList, true); + Center.clear(); + + return true; +} + + +bool VtxSeedFineGrid::Finalise(){ + Log("VtxSeedFineGrid exitting", v_debug, verbosity); + return true; +} + +Position VtxSeedFineGrid::FindCenter() { + double recoVtxX, recoVtxY, recoVtxZ, recoVtxT, recoDirX, recoDirY, recoDirZ; + double trueVtxX, trueVtxY, trueVtxZ, trueVtxT, trueDirX, trueDirY, trueDirZ; + double seedX, seedY, seedZ, seedT, seedDirX, seedDirY, seedDirZ; + double peakX, peakY, peakZ; + double bestFOM[3]; + + double ConeAngle = Parameters::CherenkovAngle(); + + // Get true Vertex information + Position vtxPos = fTrueVertex->GetPosition(); + Direction vtxDir = fTrueVertex->GetDirection(); + trueVtxX = vtxPos.X(); + trueVtxY = vtxPos.Y(); + trueVtxZ = vtxPos.Z(); + trueVtxT = fTrueVertex->GetTime(); + trueDirX = vtxDir.X(); + trueDirY = vtxDir.Y(); + trueDirZ = vtxDir.Z(); + peakX = trueVtxX; + peakY = trueVtxY; + peakZ = trueVtxZ; + bestFOM[0] = 0; bestFOM[1] = 0; bestFOM[2] = 0; + centerIndex[0] = 0; centerIndex[1] = 0; centerIndex[2] = 0; + RecoVertex iSeed; + RecoVertex thisCenterSeed; + + if (verbosity > 0) cout << "True vertex = (" << trueVtxX << ", " << trueVtxY << ", " << trueVtxZ << ", " << trueVtxT << ", " << trueDirX << ", " << trueDirY << ", " << trueDirZ << ")" << endl; + + FoMCalculator myFoMCalculator; + VertexGeometry* myvtxgeo = VertexGeometry::Instance(); + myvtxgeo->LoadDigits(fDigitList); + myFoMCalculator.LoadVertexGeometry(myvtxgeo); //Load vertex geometry + + // fom at true vertex position + double fom = -999.999 * 100; + double timefom = -999.999 * 100; + double conefom = -999.999 * 100; + myvtxgeo->CalcExtendedResiduals(trueVtxX, trueVtxY, trueVtxZ, 0.0, trueDirX, trueDirY, trueDirZ); + myFoMCalculator.TimePropertiesLnL(trueVtxT, timefom); + myFoMCalculator.ConePropertiesFoM(ConeAngle, conefom); + fom = timefom * 0.5 + conefom * 0.5; + if (verbosity > 0) cout << "VtxSeedFineGrid Tool: " << "FOM at true vertex = " << fom << endl; + + for (int m = 0; m < vSeedVtxList->size(); m++) { + RecoVertex* tempVertex = 0; + iSeed = vSeedVtxList->at(m); + seedX = iSeed.GetPosition().X(); + seedY = iSeed.GetPosition().Y(); + seedZ = iSeed.GetPosition().Z(); + seedT = trueVtxT; //Jingbo: should use median T + if (useTrueDir) { + seedDirX = trueDirX; + seedDirY = trueDirY; + seedDirZ = trueDirZ; + } + else if (useMRDTrack) { + iSeed.SetDirection(this->findDirectionMRD()); + seedDirY = iSeed.GetDirection().Y(); + seedDirZ = iSeed.GetDirection().Z(); + } + else if (useSimpleDir) { + tempVertex = this->FindSimpleDirection(&iSeed); + seedDirX = tempVertex->GetDirection().X(); + seedDirY = tempVertex->GetDirection().Y(); + seedDirZ = tempVertex->GetDirection().Z(); + delete tempVertex; tempVertex = 0; + } + /* else if (usePastResolution) { + TFile *f1 = new TFile(InputFile); + TTree *t1 = (TTree*)f1->Get("phaseIITriggerTree"); + t1->Draw("((trueAngle*TMath::Pi()/180)-MRDTrackAngle)>>hs1", "abs(deltaVtxR)<2000"); + TH1D *hres = (TH1D*)gDirectory->Get("hs1"); + double smear = hres->Random(); + iSeed.GetDirection()->SetPhi((smear)+findDirectionMRD().GetPhi()); + iSeed.GetDirection()->SetTheta(findDirectionMRD().GetTheta()); + }*/ + if (useDirectionGrid) { + for (int l = 0; l < 100; l++) { + double theta = (6 * TMath::Pi() / 50) * l; + double phi = (TMath::Pi() / 200) * l; + seedDirX = sin(phi)*cos(theta); + seedDirY = sin(phi)*sin(theta); + seedDirZ = cos(phi); + myvtxgeo->CalcExtendedResiduals(seedX, seedY, seedZ, seedT, seedDirX, seedDirY, seedDirZ); + int nhits = myvtxgeo->GetNDigits(); + double meantime = myFoMCalculator.FindSimpleTimeProperties(ConeAngle); + Double_t fom = -999.999 * 100; + double timefom = -999.999 * 100; + double conefom = -999.999 * 100; + double coneAngle = 42.0; + myFoMCalculator.TimePropertiesLnL(meantime, timefom); + myFoMCalculator.ConePropertiesFoM(coneAngle, conefom); + fom = timefom * 0.5 + conefom * 0.5; + + if (fom > bestFOM[0]) { + if (multiGrid) { + bestFOM[2] = bestFOM[1]; + bestFOM[1] = bestFOM[0]; + centerIndex[2] = centerIndex[1]; + centerIndex[1] = centerIndex[0]; + } + bestFOM[0] = fom; + peakX = seedX; + peakY = seedY; + peakZ = seedZ; + SeedDir = iSeed.GetDirection(); + thisCenterSeed = iSeed; + centerIndex[0] = m; + } + } + } + else { + + myvtxgeo->CalcExtendedResiduals(seedX, seedY, seedZ, seedT, seedDirX, seedDirY, seedDirZ); + int nhits = myvtxgeo->GetNDigits(); + double meantime = myFoMCalculator.FindSimpleTimeProperties(ConeAngle); + Double_t fom = -999.999 * 100; + double timefom = -999.999 * 100; + double conefom = -999.999 * 100; + double coneAngle = 42.0; + myFoMCalculator.TimePropertiesLnL(meantime, timefom); + myFoMCalculator.ConePropertiesFoM(coneAngle, conefom); + fom = timefom * 0.5 + conefom * 0.5; + std::cout << "seed (" << seedX<<","<Get("MRDTracks", Tracks); + m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numtracksinev); + + if (numtracksinev > 1) Log("Multiple tracks need work; just using first for now", v_debug, verbosity); + double gradx, grady, theta, phi; + Direction startVertex, endVertex, result; + BoostStore* thisTrack = &(Tracks->at(0)); + + thisTrack->Get("VTrackGradient", gradx); + thisTrack->Get("HTrackGradient", grady); + theta = atan(grady / gradx); + phi = asin(pow((gradx*gradx + grady * grady), 0.5)); + /*TRandom3 smear; + Direction vtxDir = fTrueVertex->GetDirection(); + Direction result; + result.SetTheta(smear.Gaus(vtxDir.GetTheta(), 0.4)); + result.SetPhi(smear.Gaus(vtxDir.GetPhi(), 0.4));*/ + result.SetTheta(theta); + result.SetPhi(phi); + + return result; +} + +RecoVertex* VtxSeedFineGrid::FindSimpleDirection(RecoVertex* myVertex) { + + /// get vertex position + double vtxX = myVertex->GetPosition().X(); + double vtxY = myVertex->GetPosition().Y(); + double vtxZ = myVertex->GetPosition().Z(); + double vtxTime = myVertex->GetTime(); + + std::cout<<"Simple Direction Input Position: (" << vtxX << "," << vtxY << "," << vtxZ << ")\n"; + // current status + // ============== + int status = myVertex->GetStatus(); + + /// loop over digits + /// ================ + double Swx = 0.0; + double Swy = 0.0; + double Swz = 0.0; + double Sw = 0.0; + double digitq = 0.; + double dx, dy, dz, ds, px, py, pz, q; + + RecoDigit digit; + for (int idigit = 0; idigit < fDigitList->size(); idigit++) { + digit = fDigitList->at(idigit); + if (digit.GetFilterStatus()) { + q = digit.GetCalCharge(); + dx = digit.GetPosition().X() - vtxX; + dy = digit.GetPosition().Y() - vtxY; + dz = digit.GetPosition().Z() - vtxZ; + ds = sqrt(dx*dx + dy * dy + dz * dz); + px = dx / ds; + py = dx / ds; + pz = dz / ds; + Swx += q * px; + Swy += q * py; + Swz += q * pz; + Sw += q; + } + } + + /// average direction + /// ================= + double dirX = 0.0; + double dirY = 0.0; + double dirZ = 0.0; + + int itr = 0; + bool pass = 0; + double fom = 0.0; + + if (Sw > 0.0) { + double qx = Swx / Sw; + double qy = Swy / Sw; + double qz = Swz / Sw; + double qs = sqrt(qx*qx + qy * qy + qz * qz); + + dirX = qx / qs; + dirY = qy / qs; + pass = 1; + } + + // set vertex and direction + // ======================== + RecoVertex* newVertex = new RecoVertex(); // Note: pointer must be deleted by the invoker + + if (pass) { + newVertex->SetVertex(vtxX, vtxY, vtxZ, vtxTime); + newVertex->SetDirection(dirX, dirY, dirZ); + newVertex->SetFOM(fom, itr, pass); + } + + // set status + // ========== + if (!pass) status |= RecoVertex::kFailSimpleDirection; + newVertex->SetStatus(status); + + // return vertex + // ============= + return newVertex; +} + +/*double VtxSeedFineGrid::GetMedianSeedTime(Position pos) { + double digitx, digity, digitz, digittime; + double dx, dy, dz, dr; + double fC, fN; + double seedtime; + int fThisDigit; + std::vector extraptimes; + for (int entry = 0; entry < vSeedDigitList.size(); entry++) { + fThisDigit = vSeedDigitList.at(entry); + digitx = fDigitList->at(fThisDigit).GetPosition().X(); + digity = fDigitList->at(fThisDigit).GetPosition().Y(); + digitz = fDigitList->at(fThisDigit).GetPosition().Z(); + digittime = fDigitList->at(fThisDigit).GetCalTime(); + //Now, find distance to seed position + dx = digitx - pos.X(); + dy = digity - pos.Y(); + dz = digitz - pos.Z(); + dr = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2)); + + //Back calculate to the vertex time using speed of light in H20 + //Very rough estimate; ignores muon path before Cherenkov production + //TODO: add charge weighting? Kinda like CalcSimpleVertex? + fC = Parameters::SpeedOfLight(); + fN = Parameters::Index0(); + seedtime = digittime - (dr / (fC / fN)); + extraptimes.push_back(seedtime); + } + //return the median of the extrapolated vertex times + size_t median_index = extraptimes.size() / 2; + std::nth_element(extraptimes.begin(), extraptimes.begin() + median_index, extraptimes.end()); + return extraptimes[median_index]; +}*/ diff --git a/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.h b/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.h new file mode 100755 index 000000000..cbe7770a9 --- /dev/null +++ b/UserTools/VtxSeedFineGrid/VtxSeedFineGrid.h @@ -0,0 +1,85 @@ +#ifndef VtxSeedFineGrid_H +#define VtxSeedFineGrid_H + +#include +#include + +#include "Tool.h" +#include "ANNIEGeometry.h" +#include "Parameters.h" +#include "TMath.h" +#include "TRandom.h" +#include "TRandom3.h" +#include "FoMCalculator.h" +#include "VertexGeometry.h" + + +/** + * \class VtxSeedFineGrid + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. +* +* $Author: F. Lemmons $ +* $Date: 2021/11/16 10:41:00 $ +* Contact: flemmons@fnal.gov +*/ +class VtxSeedFineGrid: public Tool { + + + public: + + VtxSeedFineGrid(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + + private: + Position FindCenter(); + + void GenerateFineGrid(); + + Direction findDirectionMRD(); + RecoVertex* FindSimpleDirection(RecoVertex* myVertex); + +// double GetMedianSeedTime(Position pos); + + + std::vector* vSeedVtxList = nullptr; + std::vector vSeedDigitList; + std::vector* fDigitList = nullptr; + + std::vector* SeedGridList = nullptr; + RecoVertex* fTrueVertex = 0; + std::vector Center; + Direction SeedDir; + int fThisDigit = 0; + int fSeedType = 2; + int centerIndex[3]; + int verbosity = -1; + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + bool useTrueDir = 1; + bool useSimpleDir = 0; + bool useMRDTrack = 0; + bool usePastResolution = 0; + bool useDirectionGrid = 0; + bool multiGrid = 0; + + // \brief Event Status flag masks + int fEventStatusApplied; + int fEventStatusFlagged; + + std::string InputFile =" "; + + std::vector* theMrdTracks; // the MRD tracks + int numtracksinev; + + std::string logmessage; + +}; + + +#endif diff --git a/UserTools/VtxSeedGenerator/README.md b/UserTools/VtxSeedGenerator/README.md old mode 100644 new mode 100755 diff --git a/UserTools/VtxSeedGenerator/VtxSeedGenerator.cpp b/UserTools/VtxSeedGenerator/VtxSeedGenerator.cpp old mode 100644 new mode 100755 index f7f0f8518..ab0f5682f --- a/UserTools/VtxSeedGenerator/VtxSeedGenerator.cpp +++ b/UserTools/VtxSeedGenerator/VtxSeedGenerator.cpp @@ -62,7 +62,9 @@ bool VtxSeedGenerator::Execute(){ auto get_evtstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus",EventCutstatus); if(!get_evtstatus) { Log("Error: The PhaseITreeMaker tool could not find the Event selection status", v_error, verbosity); - return false; + //return false; + Log("running with reco cuts or none.",v_debug, verbosity); + EventCutstatus = true; } if(!EventCutstatus) { Log("Message: This event doesn't pass the event selection. ", v_message, verbosity); diff --git a/UserTools/VtxSeedGenerator/VtxSeedGenerator.h b/UserTools/VtxSeedGenerator/VtxSeedGenerator.h old mode 100644 new mode 100755 diff --git a/VGCheck-pdfcharge.root b/VGCheck-pdfcharge.root new file mode 100644 index 000000000..315a9464e Binary files /dev/null and b/VGCheck-pdfcharge.root differ diff --git a/WCSim/WCSim b/WCSim/WCSim new file mode 160000 index 000000000..8f6e42bcc --- /dev/null +++ b/WCSim/WCSim @@ -0,0 +1 @@ +Subproject commit 8f6e42bcca5e6b105844004f601c6079bd96057a diff --git a/configfiles/VertexReco/PhaseIIDoE/DigitBuilderDoEConfig b/configfiles/VertexReco/PhaseIIDoE/DigitBuilderDoEConfig index 44b10449b..d28f55c5e 100644 --- a/configfiles/VertexReco/PhaseIIDoE/DigitBuilderDoEConfig +++ b/configfiles/VertexReco/PhaseIIDoE/DigitBuilderDoEConfig @@ -1,7 +1,7 @@ # DigitBuilder config file verbosity 3 -InputFile /AnnieShare/p2r_data/DoEProp/WCSimtrueQEvertexinfo_extv3.root +InputFile /Jingbo/Data/WCSimtrueQEvertexinfo_extv3.root # There are three configurations: "PMT_only", "LAPPD_only", "All" CURRENTLY NOT WORKING PhotoDetectorConfiguration All HistoricOffset 6670 diff --git a/configfiles/VertexReco/PhaseIIDoE/PhaseIITreeMakerConfig b/configfiles/VertexReco/PhaseIIDoE/PhaseIITreeMakerConfig index 4a3bf7692..d9269067d 100644 --- a/configfiles/VertexReco/PhaseIIDoE/PhaseIITreeMakerConfig +++ b/configfiles/VertexReco/PhaseIIDoE/PhaseIITreeMakerConfig @@ -4,6 +4,6 @@ muonRecoDebug_fill 1 muonMCTruth_fill 1 muonTruthRecoDiff_fill 1 -OutputFile /ToolAnalysis/ToolAnalysisDoE_All_FullReco.ntuple.root +OutputFile /Jingbo/ToolAnalysisDoE_All_FullReco.ntuple.root NumEventsWritten 1000 diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/DigitBuilderDoEConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/DigitBuilderDoEConfig index 659f2fc7b..60840fb54 100644 --- a/configfiles/VertexReco/PhaseIIRecoTruthDoE/DigitBuilderDoEConfig +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/DigitBuilderDoEConfig @@ -1,8 +1,8 @@ # DigitBuilder config file verbosity 3 -InputFile /AnnieShare/p2r_data/DoEProp/WCSimtrueQEvertexinfo_extv3.root +InputFile /Jingbo/Data/WCSimtrueQEvertexinfo_extv3.root # There are three configurations: "PMT_only", "LAPPD_only", "All" CURRENTLY NOT WORKING -PhotoDetectorConfiguration PMT_only +PhotoDetectorConfiguration All HistoricOffset 6670 -#LAPPDId 266 271 236 231 206 +LAPPDId 266 271 236 231 206 diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/LikelihoodFitterCheckConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/LikelihoodFitterCheckConfig new file mode 100644 index 000000000..6cb3f348f --- /dev/null +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/LikelihoodFitterCheckConfig @@ -0,0 +1,9 @@ +verbosity 5 +OutputFile /Jingbo/LFCheck-HET-20test073129.root +ifPlot2DFOM 1 +ShowEvent 0 +EventRange 20 +CleanEventsOnly 1 +UsePDFFile 0 +PDFFile /Jingbo/VGCheck-pdfcharge.root +SimpleDirectionTest 0 diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerConfig old mode 100644 new mode 100755 index 984d01df0..55d900ce0 --- a/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerConfig +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerConfig @@ -1,9 +1,20 @@ -verbose 3 +verbose 5 -muonRecoDebug_fill 0 -muonMCTruth_fill 1 +IsData 0 +RecoDebug_fill 1 +TankReco_fill 1 +MCTruth_fill 1 muonTruthRecoDiff_fill 1 +#pionKaonCount_fill 0 +TankHitInfo_fill 1 +#MRDHitInfo_fill 1 +TankRecoDigitInfo_fill 1 +#TankClusterProcessing 1 +#MRDClusterProcessing 1 +fillCleanEventsOnly 0 +#MRDReco_fill 0 +TriggerProcessing 1 -OutputFile /ToolAnalysis/ToolAnalysisDoE_PMTOnly.ntuple.root +OutputFile /Jingbo/vtxreco-DOE-test.root NumEventsWritten 2000 diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerDOEConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerDOEConfig new file mode 100644 index 000000000..3f9fdd8f7 --- /dev/null +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerDOEConfig @@ -0,0 +1,9 @@ +verbose 3 + +RecoDebug_fill 0 +MCTruth_fill 1 +muonTruthRecoDiff_fill 1 + +OutputFile /Jingbo/ToolAnalysisDoE_true_seeds_wcsim_extv8all_DOE.root +NumEventsWritten 2000 + diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolChainConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolChainConfig index 40ceee345..988f2afee 100644 --- a/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolChainConfig +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolChainConfig @@ -15,7 +15,7 @@ service_publish_sec -1 service_kick_sec -1 ##### Tools To Add ##### -Tools_File configfiles/VertexReco/PhaseIIDoE/ToolsConfig ## list of tools to run and their config files +Tools_File configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolsConfig ## list of tools to run and their config files ##### Run Type ##### Inline 1000 ## number of Execute steps in program, -1 infinite loop that is ended by user diff --git a/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolsConfig b/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolsConfig index d40b4ba0d..a5f368a60 100644 --- a/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolsConfig +++ b/configfiles/VertexReco/PhaseIIRecoTruthDoE/ToolsConfig @@ -1,4 +1,6 @@ -DigitBuilderDoE DigitBuilderDoE ./configfiles/VertexReco/PhaseIIDoE/DigitBuilderDoEConfig -EventSelectorDoE EventSelectorDoE ./configfiles/VertexReco/PhaseIIDoE/EventSelectorDoEConfig -VtxExtendedVertexFinder VtxExtendedVertexFinder ./configfiles/VertexReco/PhaseIIDoE/VtxExtendedVertexFinderConfig -PhaseIITreeMaker PhaseIITreeMaker ./configfiles/VertexReco/PhaseIIDoE/PhaseIITreeMakerConfig +DigitBuilderDoE DigitBuilderDoE ./configfiles/VertexReco/PhaseIIRecoTruthDoE/DigitBuilderDoEConfig +EventSelectorDoE EventSelectorDoE ./configfiles/VertexReco/PhaseIIRecoTruthDoE/EventSelectorDoEConfig +VtxExtendedVertexFinder VtxExtendedVertexFinder ./configfiles/VertexReco/PhaseIIRecoTruthDoE/VtxExtendedVertexFinderConfig +PhaseIITreeMakerDOE PhaseIITreeMakerDOE ./configfiles/VertexReco/PhaseIIRecoTruthDoE/PhaseIITreeMakerDOEConfig +VtxGeometryCheck VertexGeometryCheck ./configfiles/VertexReco/PhaseIIRecoTruthDoE/VertexGeometryCheckConfig +#LikelihoodFitterCheck LikelihoodFitterCheck ./configfiles/VertexReco/PhaseIIRecoTruthDoE/LikelihoodFitterCheckConfig