diff --git a/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml b/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml new file mode 100644 index 0000000000..75d43e65e5 --- /dev/null +++ b/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml @@ -0,0 +1,106 @@ +name: Fix missing final newline (CodeRabbit docstring PRs) + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + contents: write + pull-requests: read + +jobs: + fix_eof_newline: + runs-on: ubuntu-latest + steps: + - name: Guard - only CodeRabbit docstring PRs from same repo + id: guard + shell: bash + run: | + set -euo pipefail + + AUTHOR='${{ github.event.pull_request.user.login }}' + BASE_REPO='${{ github.event.pull_request.base.repo.full_name }}' + HEAD_REPO='${{ github.event.pull_request.head.repo.full_name }}' + TITLE='${{ github.event.pull_request.title }}' + + if [[ "$AUTHOR" != "coderabbitai[bot]" ]]; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Safety: only push to branches within the same repo + if [[ "$BASE_REPO" != "$HEAD_REPO" ]]; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # only run for docstring PRs + if ! echo "$TITLE" | grep -qi "docstring"; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "run=true" >> "$GITHUB_OUTPUT" + + - name: Checkout PR head + if: steps.guard.outputs.run == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + fetch-depth: 0 + + - name: Append final newline when missing (changed files only) + if: steps.guard.outputs.run == 'true' + shell: bash + run: | + set -euo pipefail + + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + + files=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- \ + '*.C' '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' || true) + + if [[ -z "${files}" ]]; then + echo "No relevant files changed." + exit 0 + fi + + changed=0 + for f in $files; do + [[ -f "$f" ]] || continue + + # For non-empty files: ensure last byte is '\n' + if [[ -s "$f" ]]; then + last_byte="$(tail -c 1 "$f" || true)" + if [[ "$last_byte" != $'\n' ]]; then + printf '\n' >> "$f" + echo "Fixed EOF newline: $f" + changed=1 + fi + fi + done + + if [[ "$changed" -eq 0 ]]; then + echo "All files already end with a newline." + exit 0 + fi + + git status --porcelain + git add -A + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git commit -m "Fix missing final newline in docstring PR" + + - name: Push fix commit back to PR branch + if: steps.guard.outputs.run == 'true' + shell: bash + run: | + set -euo pipefail + # If no commit was created, pushing will fail; so only push if HEAD is ahead. + if git rev-parse HEAD~1 >/dev/null 2>&1; then + git push origin "HEAD:${{ github.event.pull_request.head.ref }}" + fi diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.cc b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc new file mode 100644 index 0000000000..1cefa44dcd --- /dev/null +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc @@ -0,0 +1,346 @@ +#include "GlobaldEdxFitter.h" + +#include "bethe_bloch.h" +#include "TF1.h" +#include "TF2.h" +#include "TF3.h" +#include "TChain.h" +#include "TGraph.h" +#include "Math/Minimizer.h" +#include "Math/Functor.h" +#include "Math/Factory.h" + +void GlobaldEdxFitter::processResidualData(const std::string& infile, size_t ntracks, size_t skip) +{ + std::unique_ptr t = std::make_unique(); + t->Add((infile+"?#residualtree").c_str()); +// TFile* f = TFile::Open(infile.c_str()); +// TTree* t = (TTree*)f->Get("residualtree"); + + float px; + float py; + float pz; + float dedx; + float eta; + int nmaps; + int nintt; + int ntpc; + float dcaxy; + + t->SetBranchAddress("px",&px); + t->SetBranchAddress("py",&py); + t->SetBranchAddress("pz",&pz); + t->SetBranchAddress("dedx",&dedx); + t->SetBranchAddress("eta",&eta); + t->SetBranchAddress("nmaps",&nmaps); + t->SetBranchAddress("nintt",&nintt); + t->SetBranchAddress("ntpc",&ntpc); + t->SetBranchAddress("dcaxy",&dcaxy); + + size_t total_entries = t->GetEntriesFast(); + + for(size_t entry=skip; entry<(skip+ntracks); entry++) + { + if(entry==total_entries) + { + break; + } + if(entry % 1000 == 0) + { + std::cout << entry << std::endl; + } + t->GetEntry(entry); + if(nmaps>0 && nintt>0 && std::fabs(eta)<1. && dcaxy<0.5 && ntpc>30) + { + p.push_back(std::sqrt(px*px+py*py+pz*pz)); + dEdx.push_back(dedx); + } + } + std::cout << "number of good tracks: " << p.size() << std::endl; + //f->Close(); +} + +void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p) +{ + dEdx.push_back(trk_dEdx); + p.push_back(trk_p); +} + +double GlobaldEdxFitter::get_fitquality_new(double A) +{ + //double chi2 = 0.; + //double ndf = -1.; + + double pi_chi2 = 0.; + double K_chi2 = 0.; + double p_chi2 = 0.; + double d_chi2 = 0.; + double pi_ndf = -1.; + double K_ndf = -1.; + double p_ndf = -1.; + double d_ndf = -1.; + + for(size_t i=0; i GlobaldEdxFitter::get_betagamma(double A) +{ + std::vector betagamma; + for(size_t i=0; iGetMinimumXYZ(minA,minB,minC); + delete f; + return std::make_tuple(minA,minB,minC); +*/ + ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2"); + minimizer->SetMaxFunctionCalls(1000000); + minimizer->SetMaxIterations(10000); + minimizer->SetTolerance(0.1); + minimizer->SetPrintLevel(1); + ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1); + double step[1] = {.01}; + double variable[1] = {20.}; + minimizer->SetFunction(f); + minimizer->SetVariable(0,"A",variable[0],step[0]); + minimizer->Minimize(); + const double *xs = minimizer->X(); + delete minimizer; + return xs[0]; +} + +double GlobaldEdxFitter::get_minimum() +{ + TF1* f = create_TF1("temp"); + f->SetNpx(1000); + double minX = f->GetMinimumX(); + delete f; + return minX; +} + +std::pair GlobaldEdxFitter::get_minimum_ZS() +{ + TF2* f = create_TF2("temp"); + double minX; + double minY; + f->GetMinimumXY(minX,minY); + delete f; + return std::make_pair(minX,minY); +} + +TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A) +{ + std::vector betagamma = get_betagamma(A); + TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data()); + return g; +} + +TGraph* GlobaldEdxFitter::graph_vsp() +{ + TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data()); + return g; +} diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.h b/calibrations/tpc/dEdx/GlobaldEdxFitter.h new file mode 100644 index 0000000000..9d8dada662 --- /dev/null +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.h @@ -0,0 +1,69 @@ +#ifndef GLOBALDEDXFITTER_H +#define GLOBALDEDXFITTER_H + +#include "bethe_bloch.h" +#include "TF1.h" +#include "TF2.h" +#include "TF3.h" +#include "TChain.h" +#include "TGraph.h" +#include "Math/Minimizer.h" +#include "Math/Functor.h" +#include "Math/Factory.h" + +class GlobaldEdxFitter +{ + public: + explicit GlobaldEdxFitter(double xmin = 10., double xmax = 50.) + : min_norm(xmin), max_norm(xmax) + {}; + void processResidualData(const std::string& infile, + size_t ntracks = 200000, + size_t skip = 0); + void addTrack(double trk_dEdx, double trk_p); + size_t getNtracks() + { + return dEdx.size(); + } + + double get_fitquality(double norm, double ZS_loss = 0.); + double get_fitquality_new(double A); + TF1* create_TF1(const std::string& name); + TF2* create_TF2(const std::string& name); + TF3* create_TF3_new(const std::string& name); + double get_minimum(); + double get_minimum_new(); + std::pair get_minimum_ZS(); + void set_range(double xmin, double xmax, double ZSmin, double ZSmax) + { + min_norm = xmin; + max_norm = xmax; + min_ZS = ZSmin; + max_ZS = ZSmax; + } + void reset() + { + p.clear(); + dEdx.clear(); + } + std::vector get_betagamma(double A); + TGraph* graph_vsbetagamma(double A); + TGraph* graph_vsp(); + private: + std::vector p; + std::vector dEdx; + + double get_fitquality_functor(const double* x); + + double get_fitquality_wrapper(double* x, double* par); + double get_fitquality_wrapper_ZS(double* x, double* par); + double get_fitquality_wrapper_new(double* x, double* par); + double min_norm = 10.; + double max_norm = 50.; + double min_ZS = 0.; + double max_ZS = 200.; + double min_B = 8.; + double max_B = 12.; +}; + +#endif // GLOBALDEDXFITTER_H diff --git a/calibrations/tpc/dEdx/Makefile.am b/calibrations/tpc/dEdx/Makefile.am new file mode 100644 index 0000000000..d0eeaa9c5a --- /dev/null +++ b/calibrations/tpc/dEdx/Makefile.am @@ -0,0 +1,50 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -isystem$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +pkginclude_HEADERS = \ + dEdxFitter.h \ + GlobaldEdxFitter.h \ + bethe_bloch.h + +lib_LTLIBRARIES = \ + libdedxfitter.la + +libdedxfitter_la_SOURCES = \ + dEdxFitter.cc \ + GlobaldEdxFitter.cc + +libdedxfitter_la_LIBADD = \ + -lphool \ + -ltrack_io \ + -lg4detectors \ + -ltrackbase_historic \ + -ltrackbase_historic_io \ + -lglobalvertex \ + -lSubsysReco + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libdedxfitter.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/calibrations/tpc/dEdx/autogen.sh b/calibrations/tpc/dEdx/autogen.sh new file mode 100755 index 0000000000..dea267bbfd --- /dev/null +++ b/calibrations/tpc/dEdx/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/calibrations/tpc/dEdx/bethe_bloch.h b/calibrations/tpc/dEdx/bethe_bloch.h new file mode 100644 index 0000000000..a359a98294 --- /dev/null +++ b/calibrations/tpc/dEdx/bethe_bloch.h @@ -0,0 +1,208 @@ +#ifndef BETHE_BLOCH_H_ +#define BETHE_BLOCH_H_ + +#include + +namespace dedx_constants +{ + // hadron masses + constexpr double m_pi = 0.1396; // GeV + constexpr double m_K = 0.4937; // GeV + constexpr double m_p = 0.9382; // GeV + constexpr double m_d = 1.876; // GeV + + // electron mass [eV] + constexpr double m_e = 511e3; + + // TPC gas fractions + constexpr double ar_frac = 0.75; + constexpr double cf4_frac = 0.2; + constexpr double isobutane_frac = 0.05; + + // Mean excitation [src: W. Blum, W. Riegler, L. Rolandi, "Particle Detection with Drift Chambers"] + constexpr double ar_I = 188; // eV + constexpr double cf4_I = 115; // eV + constexpr double isobutane_I = 48.3; // eV + + // Mean excitation of mixture approximated using Bragg additivity rule + constexpr double sphenix_I = ar_frac*ar_I + cf4_frac*cf4_I + isobutane_frac*isobutane_I; +} + +// Bethe-Bloch fit function, vs. betagamma +// A = normalization constant, equal to (ADC conversion)*4pi*n*Z^2*e^4/(m_e*c^2*4pi*epsilon_0^2) +// B = A*(ln(2*m_e/I)-1) - (zero-suppression loss factor) +inline double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*TMath::Log(betagamma) + A/(beta*beta)*B - A - C; +} + +inline double bethe_bloch_new_2D(const double betagamma, const double A, const double B) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta) - B; +} + +inline double bethe_bloch_new_1D(const double betagamma, const double A) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta); +} + +// dE/dx for one gas species, up to normalization +inline double bethe_bloch_species(const double betagamma, const double I) +{ + const double m_e = 511e3; // eV + + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return 1./(beta*beta)*(TMath::Log(2.*m_e/I*betagamma*betagamma)-beta*beta); +} + +// dE/dx for TPC gas mixture, up to normalization +inline double bethe_bloch_total(const double betagamma) +{ + return dedx_constants::ar_frac * bethe_bloch_species(betagamma,dedx_constants::ar_I) + + dedx_constants::cf4_frac * bethe_bloch_species(betagamma,dedx_constants::cf4_I) + + dedx_constants::isobutane_frac * bethe_bloch_species(betagamma,dedx_constants::isobutane_I); +} + +inline Double_t bethe_bloch_new_wrapper(const Double_t* const x, const Double_t* const par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + + return bethe_bloch_new(betagamma,A,B,C); +} + +inline Double_t bethe_bloch_new_2D_wrapper(const Double_t* const x, const Double_t* const par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + + return bethe_bloch_new_2D(betagamma,A,B); +} + +inline Double_t bethe_bloch_new_1D_wrapper(const Double_t* const x, const Double_t* const par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + + return bethe_bloch_new_1D(betagamma,A); +} + +// wrapper function for TF1 constructor, for fitting +inline Double_t bethe_bloch_wrapper(const Double_t* const ln_bg, const Double_t* const par) +{ + Double_t betagamma = exp(ln_bg[0]); + + Double_t norm = par[0]; + + return norm * bethe_bloch_total(betagamma); +} + +inline Double_t bethe_bloch_vs_p_wrapper(const Double_t* const x, const Double_t* const par) +{ + Double_t p = x[0]; + Double_t norm = par[0]; + Double_t m = par[1]; + + return norm * bethe_bloch_total(fabs(p)/m); +} + +inline Double_t bethe_bloch_vs_logp_wrapper(const Double_t* const x, const Double_t* const par) +{ + Double_t p = pow(10.,x[0]); + Double_t norm = par[0]; + Double_t m = par[1]; + + return norm * bethe_bloch_total(fabs(p)/m); +} + +inline Double_t bethe_bloch_vs_p_wrapper_ZS(const Double_t* const x, const Double_t* const par) +{ + Double_t p = x[0]; + Double_t norm = par[0]; + Double_t m = par[1]; + Double_t ZS_loss = par[2]; + + return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; +} + +inline Double_t bethe_bloch_vs_p_wrapper_new(const Double_t* const x, const Double_t* const par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + Double_t m = par[3]; + + return bethe_bloch_new(fabs(p)/m,A,B,C); +} + +inline Double_t bethe_bloch_vs_p_wrapper_new_2D(const Double_t* const x, const Double_t* const par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t m = par[2]; + + return bethe_bloch_new_2D(fabs(p)/m,A,B); +} + +inline Double_t bethe_bloch_vs_p_wrapper_new_1D(const Double_t* const x, const Double_t* const par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t m = par[1]; + + return bethe_bloch_new_1D(fabs(p)/m,A); +} + +inline Double_t bethe_bloch_vs_logp_wrapper_ZS(const Double_t* const x, const Double_t* const par) +{ + Double_t p = pow(10.,x[0]); + Double_t norm = par[0]; + Double_t m = par[1]; + Double_t ZS_loss = par[2]; + + return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; +} + +inline Double_t bethe_bloch_vs_logp_wrapper_new(const Double_t* const x, const Double_t* const par) +{ + Double_t p = pow(10.,x[0]); + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + Double_t m = par[3]; + + return bethe_bloch_new(fabs(p)/m,A,B,C); +} + +inline Double_t bethe_bloch_vs_logp_wrapper_new_1D(const Double_t* const x, const Double_t* const par) +{ + Double_t p = pow(10.,x[0]); + Double_t A = par[0]; + Double_t m = par[1]; + + return bethe_bloch_new_1D(fabs(p)/m,A); +} + +// ratio of dE/dx between two particle species at the same momentum +// (useful for dE/dx peak fits) +inline double dedx_ratio(const double p, const double m1, const double m2) +{ + const double betagamma1 = fabs(p)/m1; + const double betagamma2 = fabs(p)/m2; + + return bethe_bloch_total(betagamma1)/bethe_bloch_total(betagamma2); +} + +#endif // BETHE_BLOCH_H_ diff --git a/calibrations/tpc/dEdx/configure.ac b/calibrations/tpc/dEdx/configure.ac new file mode 100644 index 0000000000..efef9411e9 --- /dev/null +++ b/calibrations/tpc/dEdx/configure.ac @@ -0,0 +1,16 @@ +AC_INIT( dEdxFitter,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl enable more warnings and make them fatal +dnl this package needs openmp which requires -fopenmp for clang +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Wshadow -Wextra -Werror" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/calibrations/tpc/dEdx/dEdxFitter.cc b/calibrations/tpc/dEdx/dEdxFitter.cc new file mode 100644 index 0000000000..4277d3f059 --- /dev/null +++ b/calibrations/tpc/dEdx/dEdxFitter.cc @@ -0,0 +1,249 @@ +#include "dEdxFitter.h" + +#include +#include +#include +#include +#include +#include + +#include + +//____________________________________ +dEdxFitter::dEdxFitter(const std::string &name): + SubsysReco(name), + fitter(std::make_unique()) +{ + //initialize +} + +//___________________________________ +int dEdxFitter::InitRun(PHCompositeNode * /*topNode*/) +{ + std::cout << PHWHERE << " Opening file " << _outfile << std::endl; + outf = new TFile( _outfile.c_str(), "RECREATE"); + + return 0; +} + +//__________________________________ +//Call user instructions for every event +int dEdxFitter::process_event(PHCompositeNode *topNode) +{ + _event++; + if(_event%1000==0) + { + std::cout << PHWHERE << "Events processed: " << _event << std::endl; + } + + GetNodes(topNode); + + if(Verbosity()>1) + { + std::cout << "--------------------------------" << std::endl; + std::cout << "event " << _event << std::endl; + } + + process_tracks(); + + return 0; +} + +//_____________________________________ +void dEdxFitter::process_tracks() +{ + + for(const auto &[key, track] : *_trackmap) + { + if(!track) + { + continue; + } + + double trackID = track->get_id(); + if(Verbosity()>1) + { + std::cout << "track ID " << trackID << std::endl; + } + if(std::isnan(track->get_x()) || + std::isnan(track->get_y()) || + std::isnan(track->get_z()) || + std::isnan(track->get_px()) || + std::isnan(track->get_py()) || + std::isnan(track->get_pz())) + { + std::cout << "malformed track:" << std::endl; + track->identify(); + std::cout << "skipping..." << std::endl; + continue; + } + + // ignore TPC-only tracks + if(!track->get_silicon_seed()) + { + if(Verbosity()>1) + { + std::cout << "TPC-only track, skipping..." << std::endl; + } + continue; + } + + std::tuple nclus = get_nclus(track); + int nmaps = std::get<0>(nclus); + int nintt = std::get<1>(nclus); + int ntpc = std::get<2>(nclus); + + if(nmaps>=nmaps_cut && nintt>=nintt_cut && ntpc>=ntpc_cut && std::fabs(track->get_eta())addTrack(get_dedx(track),track->get_p()); + } + + if(fitter->getNtracks() > ntracks_to_fit) + { + minima.push_back(fitter->get_minimum()); + fitter->reset(); + } + } +} + +std::tuple dEdxFitter::get_nclus(SvtxTrack* track) +{ + int nmaps = 0; + int nintt = 0; + int ntpc = 0; + + if(track->get_silicon_seed()) + { + for(auto it = track->get_silicon_seed()->begin_cluster_keys(); it != track->get_silicon_seed()->end_cluster_keys(); ++it) + { + TrkrDefs::cluskey ckey = *it; + auto trkrid = TrkrDefs::getTrkrId(ckey); + if(trkrid == TrkrDefs::mvtxId) + { + nmaps++; + } + else if(trkrid == TrkrDefs::inttId) + { + nintt++; + } + } + } + if(track->get_tpc_seed()) + { + for(auto it = track->get_tpc_seed()->begin_cluster_keys(); it != track->get_tpc_seed()->end_cluster_keys(); ++it) + { + ntpc++; + } + } + + return std::make_tuple(nmaps,nintt,ntpc); +} + +double dEdxFitter::get_dedx(SvtxTrack* track) +{ + float layerThicknesses[4] = {0.0, 0.0, 0.0, 0.0}; + // These are randomly chosen layer thicknesses for the TPC, to get the + // correct region thicknesses in an easy to pass way to the helper fxn + layerThicknesses[0] = _tpcgeom->GetLayerCellGeom(7)->get_thickness(); + layerThicknesses[1] = _tpcgeom->GetLayerCellGeom(8)->get_thickness(); + layerThicknesses[2] = _tpcgeom->GetLayerCellGeom(27)->get_thickness(); + layerThicknesses[3] = _tpcgeom->GetLayerCellGeom(50)->get_thickness(); + + return TrackAnalysisUtils::calc_dedx(track->get_tpc_seed(), _clustermap, _geometry, layerThicknesses); +} + +double dEdxFitter::get_dcaxy(SvtxTrack* track) +{ + auto vertexit = _vertexmap->find(track->get_vertex_id()); + if(vertexit != _vertexmap->end()) + { + SvtxVertex* vtx = vertexit->second; + Acts::Vector3 vertex(vtx->get_x(),vtx->get_y(),vtx->get_z()); + auto dcapair = TrackAnalysisUtils::get_dca(track,vertex); + return dcapair.first.first; + } + // if no vertex found + return std::numeric_limits::quiet_NaN(); +} + +//___________________________________ +void dEdxFitter::GetNodes(PHCompositeNode *topNode) +{ + + _trackmap = findNode::getClass(topNode,"SvtxTrackMap"); + if(!_trackmap && _event<2) + { + std::cout << PHWHERE << " cannot find SvtxTrackMap" << std::endl; + } + + _clustermap = findNode::getClass(topNode,"TRKR_CLUSTER"); + if(!_clustermap && _event<2) + { + std::cout << PHWHERE << " cannot find TrkrClusterContainer TRKR_CLUSTER" << std::endl; + } + + _geometry = findNode::getClass(topNode,"ActsGeometry"); + if(!_geometry && _event<2) + { + std::cout << PHWHERE << " cannot find ActsGeometry" << std::endl; + } + + _tpcgeom = findNode::getClass(topNode,"TPCGEOMCONTAINER"); + if(!_tpcgeom && _event<2) + { + std::cout << PHWHERE << " cannot find PHG4TpcGeomContainer TPCGEOMCONTAINER" << std::endl; + } + + _vertexmap = findNode::getClass(topNode,"SvtxVertexMap"); + if(!_vertexmap && _event<2) + { + std::cout << PHWHERE << " cannot find SvtxVertexMap" << std::endl; + } +} + +//______________________________________ +int dEdxFitter::End(PHCompositeNode * /*topNode*/) +{ + if(minima.empty()) + { + minima.push_back(fitter->get_minimum()); + } + + double avg_minimum = 0.; + for(double m : minima) + { + avg_minimum += m; + } + avg_minimum /= (double)minima.size(); + + outf->cd(); + + TF1* pi_band = new TF1("pi_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + pi_band->SetParameter(0,avg_minimum); + pi_band->SetParameter(1,dedx_constants::m_pi); + pi_band->Write(); + + TF1* K_band = new TF1("K_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + K_band->SetParameter(0,avg_minimum); + K_band->SetParameter(1,dedx_constants::m_K); + K_band->Write(); + + TF1* p_band = new TF1("p_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + p_band->SetParameter(0,avg_minimum); + p_band->SetParameter(1,dedx_constants::m_p); + p_band->Write(); + + TF1* d_band = new TF1("d_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + d_band->SetParameter(0,avg_minimum); + d_band->SetParameter(1,dedx_constants::m_d); + d_band->Write(); + + if(Verbosity()>0) + { + std::cout << "dEdxFitter extracted minimum: " << avg_minimum << std::endl; + } + + outf->Close(); + + return 0; +} diff --git a/calibrations/tpc/dEdx/dEdxFitter.h b/calibrations/tpc/dEdx/dEdxFitter.h new file mode 100644 index 0000000000..0dc4da0f0c --- /dev/null +++ b/calibrations/tpc/dEdx/dEdxFitter.h @@ -0,0 +1,94 @@ +#ifndef DEDXFITTER_H_ +#define DEDXFITTER_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "GlobaldEdxFitter.h" + +//Forward declerations +class PHCompositeNode; +class TFile; + +// dEdx fit analysis module +class dEdxFitter: public SubsysReco +{ + public: + //Default constructor + explicit dEdxFitter(const std::string &name="dEdxFitter"); + + //Initialization, called for initialization + int InitRun(PHCompositeNode * /*topNode*/) override; + + //Process Event, called for each event + int process_event(PHCompositeNode *topNode) override; + + //End, write and close files + int End(PHCompositeNode * /*topNode*/) override; + + //Change output filename + void set_filename(const char* file) + { + if(file) + { + _outfile = file; + } + } + + void set_nmaps_cut(int nmaps) + { nmaps_cut = nmaps; } + + void set_nintt_cut(int nintt) + { nintt_cut = nintt; } + + void set_ntpc_cut(int ntpc) + { ntpc_cut = ntpc; } + + void set_eta_cut(float eta) + { eta_cut = eta; } + + void set_dcaxy_cut(float dcaxy) + { dcaxy_cut = dcaxy; } + + void set_ntracks_to_fit(size_t ntrk) + { ntracks_to_fit = ntrk; } + + private: + //output filename + std::string _outfile = "dedx_outfile.root"; + TFile* outf = nullptr; + size_t _event = 0; + + SvtxTrackMap* _trackmap = nullptr; + TrkrClusterContainer* _clustermap = nullptr; + ActsGeometry* _geometry = nullptr; + PHG4TpcGeomContainer* _tpcgeom = nullptr; + SvtxVertexMap* _vertexmap = nullptr; + + //Get all the nodes + void GetNodes(PHCompositeNode * /*topNode*/); + + void process_tracks(); + + int nmaps_cut = 1; + int nintt_cut = 1; + int ntpc_cut = 30; + float eta_cut = 1.; + float dcaxy_cut = 0.5; + + size_t ntracks_to_fit = 40000; + std::vector minima; + std::unique_ptr fitter; + + std::tuple get_nclus(SvtxTrack* track); + double get_dedx(SvtxTrack* track); + double get_dcaxy(SvtxTrack* track); + +}; + +#endif //* DEDXFITTER_H_ *// diff --git a/calibrations/tpc/dEdx/test_sample_size.C b/calibrations/tpc/dEdx/test_sample_size.C new file mode 100644 index 0000000000..8464aba486 --- /dev/null +++ b/calibrations/tpc/dEdx/test_sample_size.C @@ -0,0 +1,200 @@ +#include "GlobaldEdxFitter.h" + +#include +#include +#include +#include +#include + +#include +#include + +void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877_*.root") +{ + std::vector samplesizes = {1000,2000,5000,10000,20000};//,50000,100000,200000,500000,1000000};//,2000000,5000000}; + + const int n_samples = 20; + const float fluctuation_ymin = 5.; + const float fluctuation_ymax = 26.; + const int distribution_nbins = 30; + const float distribution_xmin = 5.; + const float distribution_xmax = 26.; + + std::vector> fitvalues_all; + std::vector fitvalues_avg; + std::vector fitvalues_stdev; + + std::vector fluctuations; + std::vector distributions; + + std::vector dist_h; + + std::vector> gfs; + + for(int i=0; i()); + + const std::string& fluctuation_canvasname = "fluctuations_"+std::to_string((int)floor(samplesizes[i])); + const std::string& distribution_canvasname = "distributions_"+std::to_string((int)floor(samplesizes[i])); + fluctuations.push_back(new TCanvas(fluctuation_canvasname.c_str(),fluctuation_canvasname.c_str(),600,600)); + distributions.push_back(new TCanvas(distribution_canvasname.c_str(),distribution_canvasname.c_str(),600,600)); + + for(int j=0;jprocessResidualData(infile,floor(samplesizes[i]),j*samplesizes[i]); + double min = gfs[i]->get_minimum(); + std::cout << "minimum: " << min << std::endl; + fitvalues_all[i].push_back(min); + if(jreset(); + } +/* + tf1s[i]->cd(); + TF1* tf1copy = gfs[i]->create_TF1(("ntrk_"+std::to_string(samplesizes[i])).c_str()); + tf1copy->SetLineColor(base_color); + tf1copy->GetYaxis()->SetRangeUser(1.,tf1copy->GetMaximum()); + if(i==0) tf1copy->Draw(); + else tf1copy->Draw("SAME"); +*/ + } + } + + std::vector sample_index(n_samples); + std::iota(sample_index.begin(),sample_index.end(),0.); + + for(int i=0; icd(); + TGraph* g = new TGraph(n_samples,sample_index.data(),fitvalues_all[i].data()); + g->GetYaxis()->SetRangeUser(fluctuation_ymin,fluctuation_ymax); + g->SetMarkerStyle(kFullCircle); + g->SetMarkerSize(1.); + g->Draw("APL"); + + distributions[i]->cd(); + std::string hname = "h_"+std::to_string(floor(samplesizes[i])); + std::string htitle = "Distribution of fit results for sample size "+std::to_string(floor(samplesizes[i])); +/* + auto bounds = std::minmax_element(fitvalues_all[i].begin(),fitvalues_all[i].end()); + float lowerbound = floor(*bounds.first); + float upperbound = ceil(*bounds.second); +*/ + TH1F* h = new TH1F(hname.c_str(),htitle.c_str(),distribution_nbins,distribution_xmin,distribution_xmax); + for(int j=0; jFill(fitvalues_all[i][j]); + } + h->Draw(); + } + + for(int i=0; i errx(n_samples,0.); + + TCanvas* cg = new TCanvas("cg","sizes",600,600); + TGraph* g = new TGraphErrors(samplesizes.size(),samplesizes.data(),fitvalues_avg.data(),errx.data(),fitvalues_stdev.data()); + g->SetMarkerStyle(kFullCircle); + g->SetMarkerSize(1); + g->Draw("APL"); + cg->SetLogx(); + + TCanvas* cbg = new TCanvas("vsbetagamma","vsbetagamma",600,600); + TGraph* gbg = gfs.back()->graph_vsbetagamma(fitvalues_avg.back()); + gbg->SetMarkerStyle(kFullCircle); + gbg->SetMarkerSize(0.2); + gbg->Draw("AP"); + cbg->SetLogx(); + + double best_A = fitvalues_avg.back(); + + TF1* bethe = new TF1("bethebloch_vslnbg",bethe_bloch_new_1D_wrapper,0.,100.,2,1); + bethe->SetParameter(0,best_A); + bethe->SetNpx(1000); + bethe->Draw("SAME"); + + TF1* bethe_directfit = new TF1("bethebloch_directfit",bethe_bloch_new_1D_wrapper,0.,10.,1,1); + bethe_directfit->SetParameter(0,best_A); + bethe_directfit->SetLineColor(kBlue); + gbg->Fit(bethe_directfit); + double newbest_A = bethe_directfit->GetParameter(0); + std::cout << "new best: " << newbest_A << std::endl; + + TCanvas* cbands = new TCanvas("bands","bands",600,600); + TGraph* gp = gfs.back()->graph_vsp(); + gp->SetMarkerStyle(kFullCircle); + gp->SetMarkerSize(0.1); + gp->Draw("AP"); + cbands->SetLogx(); + + for(double mass : {dedx_constants::m_pi, dedx_constants::m_K, dedx_constants::m_p, dedx_constants::m_d}) + { + TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_p_wrapper_new_1D,0.,10.,2,1); + band->SetParameter(0,best_A); + band->SetParameter(1,mass); + band->SetNpx(1000); + band->Draw("SAME"); + + TF1* directband = new TF1(("directband_"+std::to_string(mass)).c_str(),bethe_bloch_vs_p_wrapper_new_1D,0.,10.,2,1); + directband->SetLineColor(kBlue); + directband->SetParameters(best_A,mass); + directband->SetNpx(1000); + directband->Draw("SAME"); + } + + TCanvas* cb = new TCanvas("fullbands","fullbands",600,600); + TFile* f_h = TFile::Open("/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/dedx/merged_dedx.root"); + TH2F* dedx_h = (TH2F*)f_h->Get("dedx_log_30"); + dedx_h->Draw("COLZ"); + cb->SetLogz(); + + for(double mass : {dedx_constants::m_pi, dedx_constants::m_K, dedx_constants::m_p, dedx_constants::m_d}) + { + TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_logp_wrapper_new_1D,-1.,5.,2,1); + band->SetParameter(0,best_A); + band->SetParameter(1,mass); + band->Draw("SAME"); + + TF1* directband = new TF1(("directband_"+std::to_string(mass)).c_str(),bethe_bloch_vs_logp_wrapper_new_1D,-1.,5.,2,1); + directband->SetLineColor(kBlue); + directband->SetParameters(newbest_A,mass); + directband->SetNpx(1000); + directband->Draw("SAME"); + } + + TFile* fout = new TFile("dedxfitvals.root","RECREATE"); + for(auto& c : fluctuations) + { + c->Write(); + } + for(auto& c : distributions) + { + c->Write(); + } + cg->Write(); + cbg->Write(); + cbands->Write(); + cb->Write(); + fout->Close(); +} diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc index 02ca208f25..506799c874 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc @@ -31,7 +31,6 @@ HepMCJetTrigger::HepMCJetTrigger(float trigger_thresh, int n_incom, bool up_lim, int HepMCJetTrigger::process_event(PHCompositeNode* topNode) { // std::cout << "HepMCJetTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; - n_evts++; if (this->set_event_limit == true) { // needed to keep all HepMC output at the same number of events if (n_good >= this->goal_event_number) @@ -39,6 +38,7 @@ int HepMCJetTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + n_evts++; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) { @@ -96,6 +96,11 @@ std::vector HepMCJetTrigger::findAllJets(HepMC::GenEvent* e1 if (!(*iter)->end_vertex() && (*iter)->status() == 1) { auto p = (*iter)->momentum(); + auto pd = std::abs((*iter)->pdg_id()); + if (pd >= 12 && pd <= 18) + { + continue; // keep jet in the expected behavioro + } fastjet::PseudoJet pj(p.px(), p.py(), p.pz(), p.e()); pj.set_user_index((*iter)->barcode()); input.push_back(pj); @@ -122,6 +127,10 @@ int HepMCJetTrigger::jetsAboveThreshold(const std::vector& j for (const auto& j : jets) { float const pt = j.pt(); + if (std::abs(j.eta()) > 1.1) + { + continue; + } if (pt > this->threshold) { n_good_jets++; diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h index 67a1a4fbe5..0917e42cdc 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h @@ -47,6 +47,8 @@ class HepMCJetTrigger : public SubsysReco /// Called at the end of all processing. /// Reset + int getNevts(){return this->n_evts;} + int getNgood(){return this->n_good;} private: bool isGoodEvent(HepMC::GenEvent* e1); @@ -54,9 +56,9 @@ class HepMCJetTrigger : public SubsysReco int jetsAboveThreshold(const std::vector& jets) const; float threshold{0.}; int goal_event_number{1000}; + bool set_event_limit{false}; int n_evts{0}; int n_good{0}; - bool set_event_limit{false}; }; #endif // HEPMCJETTRIGGER_H diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc new file mode 100644 index 0000000000..81d594e528 --- /dev/null +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -0,0 +1,369 @@ +#include "HepMCParticleTrigger.h" + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include +//____________________________________________________________________________.. +// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) +HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bool up_lim, const std::string& name) + : SubsysReco(name) + , threshold(trigger_thresh) + , goal_event_number(n_incom) + , set_event_limit(up_lim) + , _theEtaHigh(1.1) + , _theEtaLow(-1.1) + , _thePtHigh(999.9) + , _thePtLow(0) + , _thePHigh(999.9) + , _thePLow(-999.9) + , _thePzHigh(999.9) + , _thePzLow(-999.9) + , + + _doEtaHighCut(true) + , _doEtaLowCut(true) + , _doBothEtaCut(true) + , + + _doAbsEtaHighCut(false) + , _doAbsEtaLowCut(false) + , _doBothAbsEtaCut(false) + , + + _doPtHighCut(false) + , _doPtLowCut(false) + , _doBothPtCut(false) + , + _doPHighCut(false) + , _doPLowCut(false) + , _doBothPCut(false) + , + + _doPzHighCut(false) + , _doPzLowCut(false) + , _doBothPzCut(false) +{ + if (threshold != 0) + { + _doPtLowCut = true; + _thePtLow = threshold; + } +} + +//____________________________________________________________________________.. +int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) +{ + // std::cout << "HepMCParticleTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + if (this->set_event_limit == true) + { // needed to keep all HepMC output at the same number of events + if (n_good >= this->goal_event_number) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + } + n_evts++; + bool good_event{false}; + PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); + if (!phg) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + for (PHHepMCGenEventMap::ConstIter eventIter = phg->begin(); eventIter != phg->end(); ++eventIter) + { + PHHepMCGenEvent* hepev = eventIter->second; + if (!hepev) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + HepMC::GenEvent* ev = hepev->getEvent(); + if (!ev) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + good_event = isGoodEvent(ev); + if (!good_event) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + } + if (good_event) + { + n_good++; + } + return Fun4AllReturnCodes::EVENT_OK; +} +void HepMCParticleTrigger::AddParticle(int particlePid) +{ + _theParticles.push_back(particlePid); + return; +} +void HepMCParticleTrigger::AddParticles(const std::vector& particles) +{ + for (auto p : particles) + { + _theParticles.push_back(p); + } + return; +} + +void HepMCParticleTrigger::SetPtHigh(double pt) +{ + _thePtHigh = pt; + _doPtHighCut = true; + if (_doPtLowCut) + { + _doBothPtCut = true; + } + return; +} +void HepMCParticleTrigger::SetPtLow(double pt) +{ + _thePtLow = pt; + _doPtLowCut = true; + if (_doPtHighCut) + { + _doBothPtCut = true; + } + return; +} +void HepMCParticleTrigger::SetPtHighLow(double ptHigh, double ptLow) +{ + _thePtHigh = ptHigh; + _doPtHighCut = true; + _thePtLow = ptLow; + _doPtLowCut = true; + _doBothPtCut = true; + return; +} +void HepMCParticleTrigger::SetPHigh(double pt) +{ + _thePHigh = pt; + _doPHighCut = true; + if (_doPLowCut) + { + _doBothPCut = true; + } + return; +} +void HepMCParticleTrigger::SetPLow(double pt) +{ + _thePLow = pt; + _doPLowCut = true; + if (_doPHighCut) + { + _doBothPCut = true; + } + return; +} +void HepMCParticleTrigger::SetPHighLow(double ptHigh, double ptLow) +{ + _thePHigh = ptHigh; + _doPHighCut = true; + _thePLow = ptLow; + _doPLowCut = true; + _doBothPCut = true; + return; +} +void HepMCParticleTrigger::SetPzHigh(double pt) +{ + _thePzHigh = pt; + _doPzHighCut = true; + if (_doPzLowCut) + { + _doBothPzCut = true; + } + return; +} +void HepMCParticleTrigger::SetPzLow(double pt) +{ + _thePzLow = pt; + _doPzLowCut = true; + if (_doPzHighCut) + { + _doBothPzCut = true; + } + return; +} +void HepMCParticleTrigger::SetPzHighLow(double ptHigh, double ptLow) +{ + _thePzHigh = ptHigh; + _doPzHighCut = true; + _thePzLow = ptLow; + _doPzLowCut = true; + _doBothPzCut = true; + return; +} +void HepMCParticleTrigger::SetEtaHigh(double pt) +{ + _theEtaHigh = pt; + _doEtaHighCut = true; + if (_doEtaLowCut) + { + _doBothEtaCut = true; + } + return; +} +void HepMCParticleTrigger::SetEtaLow(double pt) +{ + _theEtaLow = pt; + _doEtaLowCut = true; + if (_doEtaHighCut) + { + _doBothEtaCut = true; + } + return; +} +void HepMCParticleTrigger::SetEtaHighLow(double ptHigh, double ptLow) +{ + _theEtaHigh = ptHigh; + _doEtaHighCut = true; + _theEtaLow = ptLow; + _doEtaLowCut = true; + _doBothEtaCut = true; + return; +} +void HepMCParticleTrigger::SetAbsEtaHigh(double pt) +{ + _theEtaHigh = pt; + _doAbsEtaHighCut = true; + if (_doAbsEtaLowCut) + { + _doBothAbsEtaCut = true; + } + return; +} +void HepMCParticleTrigger::SetAbsEtaLow(double pt) +{ + _theEtaLow = pt; + _doAbsEtaLowCut = true; + if (_doAbsEtaHighCut) + { + _doBothAbsEtaCut = true; + } + return; +} +void HepMCParticleTrigger::SetAbsEtaHighLow(double ptHigh, double ptLow) +{ + _theEtaHigh = ptHigh; + _doAbsEtaHighCut = true; + _theEtaLow = ptLow; + _doAbsEtaLowCut = true; + _doBothAbsEtaCut = true; + return; +} +bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) +{ + // this is really just the call to actually evaluate and return the filter + /*if (this->threshold == 0) + { + return true; + }*/ + std::vector n_trigger_particles = getParticles(e1); + for (auto ntp : n_trigger_particles) + { + if (ntp <= 0) + { + return false; // make sure all particles have at least 1 + } + } + return true; +} + +std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) +{ + std::vector n_trigger{}; + std::map particle_types; + for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) + { + if (m_doStableParticleOnly && ((*iter)->end_vertex() || (*iter)->status() != 1)) + { + continue; + } + auto p = (*iter)->momentum(); + float px = p.px(); + float py = p.py(); + float pz = p.pz(); + float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); + float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); + int pid = std::abs((*iter)->pdg_id()); + double eta = p.eta(); + if ((_doEtaHighCut || _doBothEtaCut) && eta > _theEtaHigh) + { + continue; + } + if ((_doEtaLowCut || _doBothEtaCut) && eta < _theEtaLow) + { + continue; + } + if ((_doAbsEtaHighCut || _doBothAbsEtaCut) && std::abs(eta) > _theEtaHigh) + { + continue; + } + if ((_doAbsEtaLowCut || _doBothAbsEtaCut) && std::abs(eta) < _theEtaLow) + { + continue; + } + if ((_doPtHighCut || _doBothPtCut) && pt > _thePtHigh) + { + continue; + } + if ((_doPtLowCut || _doBothPtCut) && pt < _thePtLow) + { + continue; + } + if ((_doPHighCut || _doBothPCut) && p_M > _thePHigh) + { + continue; + } + if ((_doPLowCut || _doBothPCut) && p_M < _thePLow) + { + continue; + } + if ((_doPzHighCut || _doBothPzCut) && pz > _thePzHigh) + { + continue; + } + if ((_doPzLowCut || _doBothPzCut) && pz < _thePzLow) + { + continue; + } + if (particle_types.contains(pid)) + { + particle_types[pid]++; + } + else + { + particle_types[pid] = 1; + } + } + n_trigger.reserve(_theParticles.size()); + for (auto p : _theParticles) + { + n_trigger.push_back(particleAboveThreshold(particle_types, p)); // make sure we have at least one of each required particle + } + return n_trigger; +} +int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_particles, int trigger_particle) +{ + // search through for the number of identified trigger particles passing cuts + auto it = n_particles.find(std::abs(trigger_particle)); + if (it != n_particles.end()) + { + return it->second; + } + return 0; +} diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h new file mode 100644 index 0000000000..e0494cb3e7 --- /dev/null +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -0,0 +1,115 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef HEPMCPARTICLETRIGGER_H +#define HEPMCPARTICLETRIGGER_H + +#include + +#include + +#include +#include +#include +#include + +class PHCompositeNode; +namespace HepMC +{ + class GenEvent; +} + +class HepMCParticleTrigger : public SubsysReco +{ + public: + HepMCParticleTrigger(float trigger_thresh = 10., int n_incom = 1000, bool up_lim = false, const std::string& name = "HepMCParticleTrigger"); + + ~HepMCParticleTrigger() override = default; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode* topNode) override; + + /// Clean up internals after each event. + + /// Called at the end of each run. + + /// Called at the end of all processing. + + /// Reset + void AddParticles(const std::vector&); //exclusively take input in the form of a pdg_ids (22 for photon, primary use case) + void AddParticle(int); + + /* void AddParents(const std::string &parents); + void AddParents(int parent); + void AddParents(std::vector parents); + void AddParentspID(std::vector parents); + */ + void SetPtHigh(double); + void SetPtLow(double); + void SetPtHighLow(double, double); + + void SetPHigh(double); + void SetPLow(double); + void SetPHighLow(double, double); + + void SetEtaHigh(double); + void SetEtaLow(double); + void SetEtaHighLow(double, double); + + void SetAbsEtaHigh(double); + void SetAbsEtaLow(double); + void SetAbsEtaHighLow(double, double); + + void SetPzHigh(double); + void SetPzLow(double); + void SetPzHighLow(double, double); + + void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } + int getNevts(){return this->n_evts;} + int getNgood(){return this->n_good;} + + private: + bool isGoodEvent(HepMC::GenEvent* e1); + std::vector getParticles(HepMC::GenEvent* e1); + int particleAboveThreshold(const std::map& n_particles, int particle); + // std::vector _theParentsi {}; + std::vector _theParticles{}; + bool m_doStableParticleOnly{true}; + float threshold{0.}; + int goal_event_number{1000}; + bool set_event_limit{false}; + int n_evts{0}; + int n_good{0}; + + float _theEtaHigh{1.1}; + float _theEtaLow{-1.1}; + float _thePtHigh{999.9}; + float _thePtLow{-999.9}; + float _thePHigh{999.9}; + float _thePLow{-999.9}; + float _thePzHigh{999.9}; + float _thePzLow{-999.9}; + + bool _doEtaHighCut{true}; + bool _doEtaLowCut{true}; + bool _doBothEtaCut{true}; + + bool _doAbsEtaHighCut{false}; + bool _doAbsEtaLowCut{false}; + bool _doBothAbsEtaCut{false}; + + bool _doPtHighCut{false}; + bool _doPtLowCut{false}; + bool _doBothPtCut{false}; + + bool _doPHighCut{false}; + bool _doPLowCut{false}; + bool _doBothPCut{false}; + + bool _doPzHighCut{false}; + bool _doPzLowCut{false}; + bool _doBothPzCut{false}; +}; + +#endif // HEPMCPARTICLETRIGGER_H diff --git a/generators/Herwig/HepMCTrigger/Makefile.am b/generators/Herwig/HepMCTrigger/Makefile.am index 17ef6c4221..9807a9a78e 100644 --- a/generators/Herwig/HepMCTrigger/Makefile.am +++ b/generators/Herwig/HepMCTrigger/Makefile.am @@ -12,20 +12,31 @@ AM_LDFLAGS = \ `fastjet-config --libs` pkginclude_HEADERS = \ - HepMCJetTrigger.h + HepMCJetTrigger.h \ + HepMCParticleTrigger.h lib_LTLIBRARIES = \ - libHepMCJetTrigger.la + libHepMCJetTrigger.la \ + libHepMCParticleTrigger.la libHepMCJetTrigger_la_SOURCES = \ HepMCJetTrigger.cc +libHepMCParticleTrigger_la_SOURCES = \ + HepMCParticleTrigger.cc + libHepMCJetTrigger_la_LIBADD = \ -lphool \ -lSubsysReco \ -lfun4all \ -lphhepmc +libHepMCParticleTrigger_la_LIBADD = \ + -lphool \ + -lSubsysReco \ + -lfun4all \ + -lphhepmc + BUILT_SOURCES = testexternals.cc noinst_PROGRAMS = \ diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 9aa14d4684..58b1f67e5d 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -33,6 +33,20 @@ #include #include // for operator<<, endl +/** + * @brief Construct a PHPythia8 generator instance and configure HepMC conversion. + * + * Initializes the Pythia8 engine using the path from the environment variable + * `PYTHIA8`, configures a HepMC::Pythia8ToHepMC converter to store process, + * PDF, and cross-section information, and sets the default embedding ID to 1. + * The constructor preserves and restores std::cout formatting around Pythia8 + * construction to avoid altering global stream state. + * + * If `PYTHIA8` is not set, an error message is printed and the Pythia8 instance + * remains uninitialized. + * + * @param name Name forwarded to the SubsysReco base class (module instance name). + */ PHPythia8::PHPythia8(const std::string &name) : SubsysReco(name) { @@ -45,8 +59,12 @@ PHPythia8::PHPythia8(const std::string &name) std::string thePath(charPath); thePath += "/xmldoc/"; + // the pythia8 ctor messes with the formatting, so we save the cout state here + // and restore it later + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); m_Pythia8.reset(new Pythia8::Pythia(thePath)); - + std::cout.copyfmt(old_state); m_Pythia8ToHepMC.reset(new HepMC::Pythia8ToHepMC()); m_Pythia8ToHepMC->set_store_proc(true); m_Pythia8ToHepMC->set_store_pdf(true); @@ -55,6 +73,18 @@ PHPythia8::PHPythia8(const std::string &name) PHHepMCGenHelper::set_embedding_id(1); // default embedding ID to 1 } +/** + * @brief Initialize the Pythia8 generator, configure nodes, and seed the RNG. + * + * Performs module initialization: reads an optional configuration file and any + * queued Pythia command strings, creates the required node tree under the + * provided top-level node, sets Pythia's random seed (mapped from PHRandomSeed + * into Pythia's valid range) and prints it for reproducibility, then calls + * Pythia8::init(). + * + * @param topNode Top-level PHCompositeNode under which generator nodes are created. + * @return int Fun4All return code; returns Fun4AllReturnCodes::EVENT_OK on success. + */ int PHPythia8::Init(PHCompositeNode *topNode) { if (!m_ConfigFileName.empty()) @@ -92,8 +122,15 @@ int PHPythia8::Init(PHCompositeNode *topNode) // print out seed so we can make this is reproducible std::cout << "PHPythia8 random seed: " << seed << std::endl; + +// pythia again messes with the cout formatting + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); // save current state + m_Pythia8->init(); + std::cout.copyfmt(old_state); // restore state to saved state + return Fun4AllReturnCodes::EVENT_OK; } @@ -170,6 +207,9 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) bool passedGen = false; bool passedTrigger = false; // int genCounter = 0; +// pythia again messes with the cout formatting in its event loop + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); // save current state while (!passedTrigger) { @@ -245,6 +285,7 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) if (!success) { std::cout << "PHPythia8::process_event - Failed to add event to HepMC record!" << std::endl; + std::cout.copyfmt(old_state); // restore state to saved state return Fun4AllReturnCodes::ABORTRUN; } @@ -265,6 +306,8 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) ++m_EventCount; + std::cout.copyfmt(old_state); // restore state to saved state + // save statistics if (m_IntegralNode) { diff --git a/generators/phhepmc/PHHepMCGenEventv1.cc b/generators/phhepmc/PHHepMCGenEventv1.cc index bc8eef6f41..3aa7515365 100644 --- a/generators/phhepmc/PHHepMCGenEventv1.cc +++ b/generators/phhepmc/PHHepMCGenEventv1.cc @@ -9,6 +9,7 @@ #include #include // for cout +#include #include // for map #include #include // for swap @@ -109,6 +110,6 @@ float PHHepMCGenEventv1::get_flow_psi(unsigned int n) const return it->second; } - std::cout << "PHHepMCGenEventv1::get_flow_psi - Warning - requested reaction plane angle psi_n for n=" << n << " does not exist. Returning 0.0" << std::endl; - return 0.0F; + std::cout << "PHHepMCGenEventv1::get_flow_psi - Warning - requested reaction plane angle psi_n for n=" << n << " does not exist. Returning NAN" << std::endl; + return std::numeric_limits::quiet_NaN(); } diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 2451672807..fe815df37f 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -84,7 +84,23 @@ int CaloValid::Init(PHCompositeNode* /*unused*/) return Fun4AllReturnCodes::EVENT_OK; } -// Note: InitRun cannot be made static as it modifies member variable m_species +/** + * @brief Determine the collision species for the current run and set m_species. + * + * Reads the RunHeader from the provided node tree, inspects the run number, and sets + * the member variable `m_species` to one of the recognized values ("pp", "AuAu", "OO"). + * If the run number does not match any known range or the RunHeader is missing, + * `m_species` remains unchanged (default behavior uses "pp" elsewhere) and a diagnostic + * message may be printed depending on verbosity. + * + * Recognized mappings: + * - RUN2PP_* -> "pp" + * - RUN2AUAU_* or RUN3AUAU_* -> "AuAu" + * - RUN3OO_* -> "OO" + * + * @param topNode Top-level node of the event tree used to locate the RunHeader. + * @return int EVENT_OK on success. + */ int CaloValid::InitRun(PHCompositeNode* topNode) { RunHeader* runhdr = findNode::getClass(topNode, "RunHeader"); @@ -117,6 +133,14 @@ int CaloValid::InitRun(PHCompositeNode* topNode) std::cout << "This run is from Run-3 Au+Au.\n"; } } + else if (runnumber >= RunnumberRange::RUN3OO_FIRST && runnumber <= RunnumberRange::RUN3OO_LAST) + { + m_species = "OO"; + if (Verbosity() > 0) + { + std::cout << "This run is from Run-3 O+O.\n"; + } + } else { if (Verbosity() > 0) @@ -142,6 +166,20 @@ int CaloValid::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } +/** + * @brief Process event towers, triggers, MBD, and clusters to populate QA histograms. + * + * Reads event header, vertex, trigger (GL1), calibrated and raw tower containers for + * CEMC/HCAL (inner/outer), MBD PMTs, and CEMC clusters; computes per-detector totals, + * downscaled correlations, per-channel and per-tower QA, pi0 candidate invariant masses, + * and trigger/alignment summaries, then fills the corresponding histograms and profiles. + * + * @param topNode Top-level PHCompositeNode containing event data (towers, clusters, + * trigger/GL1 packets, vertex map, and MBD PMTs). + * @return Fun4AllReturnCodes::EVENT_OK on success; may return other Fun4All return codes + * or 0 on error conditions encountered while processing nodes. + * + */ int CaloValid::process_towers(PHCompositeNode* topNode) { //---------------------------Event header--------------------------------// @@ -176,7 +214,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) float ihcaldownscale; float ohcaldownscale; float mbddownscale; - float adc_threshold; + float adc_threshold_hcal; + float adc_threshold_emcal; float emcal_hit_threshold; float emcal_highhit_threshold; float ohcal_hit_threshold; @@ -190,7 +229,28 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 55000. / 300.; ohcaldownscale = 265000. / 600.; mbddownscale = 2800.0; - adc_threshold = 15.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; + + emcal_hit_threshold = 0.5; // GeV + ohcal_hit_threshold = 0.5; + ihcal_hit_threshold = 0.25; + + emcal_highhit_threshold = 3.0; + ohcal_highhit_threshold = 3.0; + ihcal_highhit_threshold = 3.0; + } + else if (m_species == "OO") + { + // Scale by the ratio of nucleons: OO/AuAu + float scale_factor = 16. / 197.; + + emcaldownscale = (1350000. / 800.) * scale_factor; + ihcaldownscale = (55000. / 300.) * scale_factor; + ohcaldownscale = (265000. / 600.) * scale_factor; + mbddownscale = 2800.0 * scale_factor; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -206,7 +266,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 4000. / 300.; ohcaldownscale = 25000. / 600.; mbddownscale = 200.0; - adc_threshold = 100.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -335,13 +396,16 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalcemc += offlineenergy; + if (isGood) + { + totalcemc += offlineenergy; + } h_emcaltime->Fill(_timef); if (offlineenergy > emcal_hit_threshold) { h_cemc_etaphi_time->Fill(ieta, iphi, _timef); h_cemc_etaphi->Fill(ieta, iphi); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_cemc_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } @@ -407,14 +471,17 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalihcal += offlineenergy; + if (isGood) + { + totalihcal += offlineenergy; + } h_ihcaltime->Fill(_timef); if (offlineenergy > ihcal_hit_threshold) { h_ihcal_etaphi->Fill(ieta, iphi); h_ihcal_etaphi_time->Fill(ieta, iphi, _timef); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_ihcal_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } @@ -472,14 +539,17 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalohcal += offlineenergy; + if (isGood) + { + totalohcal += offlineenergy; + } h_ohcaltime->Fill(_timef); if (offlineenergy > ohcal_hit_threshold) { h_ohcal_etaphi_time->Fill(ieta, iphi, _timef); h_ohcal_etaphi->Fill(ieta, iphi); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_ohcal_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } @@ -519,7 +589,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_emcal) { h_cemc_etaphi_fracHitADC->Fill(ieta, iphi, 1); h_cemc_etaphi_time_raw->Fill(ieta, iphi, raw_time); @@ -549,7 +619,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ohcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ohcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); @@ -579,7 +649,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ihcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ihcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); diff --git a/offline/QA/Calorimeters/CaloValid.h b/offline/QA/Calorimeters/CaloValid.h index 2e2f9e278e..baaede0fe5 100644 --- a/offline/QA/Calorimeters/CaloValid.h +++ b/offline/QA/Calorimeters/CaloValid.h @@ -55,7 +55,7 @@ class CaloValid : public SubsysReco TriggerAnalyzer* trigAna{nullptr}; TH3* h_pi0_trigIB_mass{nullptr}; - std::vector triggerIndices{10, 28, 29, 30, 31}; // MBD NS>=1, Photon Triggers + std::vector triggerIndices{10, 12, 28, 29, 30, 31}; // MBD NS>=1, Photon Triggers TH1* h_cemc_channel_pedestal[128 * 192]{nullptr}; TH1* h_ihcal_channel_pedestal[32 * 48]{nullptr}; diff --git a/offline/QA/Tracking/Makefile.am b/offline/QA/Tracking/Makefile.am index f5d87546f1..75cbdf164b 100644 --- a/offline/QA/Tracking/Makefile.am +++ b/offline/QA/Tracking/Makefile.am @@ -17,6 +17,7 @@ pkginclude_HEADERS = \ TpcSeedsQA.h \ TpcSiliconQA.h \ SiliconSeedsQA.h \ + StateClusterResidualsQA.h \ MicromegasClusterQA.h \ CosmicTrackQA.h \ TrackFittingQA.h \ @@ -32,6 +33,7 @@ libtrackingqa_la_SOURCES = \ TpcSeedsQA.cc \ TpcSiliconQA.cc \ SiliconSeedsQA.cc \ + StateClusterResidualsQA.cc \ MicromegasClusterQA.cc \ CosmicTrackQA.cc \ TrackFittingQA.cc \ diff --git a/offline/QA/Tracking/MicromegasClusterQA.cc b/offline/QA/Tracking/MicromegasClusterQA.cc index 41efeffaa7..6feb510c54 100644 --- a/offline/QA/Tracking/MicromegasClusterQA.cc +++ b/offline/QA/Tracking/MicromegasClusterQA.cc @@ -73,6 +73,9 @@ int MicromegasClusterQA::InitRun(PHCompositeNode* topNode) << (m_calibration_filename.empty() ? "unspecified" : m_calibration_filename) << std::endl; + std::cout << "MicromegasClusterQA::InitRun - m_sample_min: " << m_sample_min << std::endl; + std::cout << "MicromegasClusterQA::InitRun - m_sample_max: " << m_sample_max << std::endl; + // read calibrations if (!m_calibration_filename.empty()) { @@ -162,6 +165,13 @@ int MicromegasClusterQA::process_event(PHCompositeNode* topNode) // find associated hits const auto hit_range = m_cluster_hit_map->getHits(ckey); + // check hit samples + // if none of the associated hits' sample is within acceptable range, skip the cluster + if( std::none_of( hit_range.first, hit_range.second, + [this]( const TrkrClusterHitAssoc::Map::value_type& pair ) + { return MicromegasDefs::getSample( pair.second ) >= m_sample_min && MicromegasDefs::getSample( pair.second ) < m_sample_max; } ) ) + { continue; } + // store cluster size and fill cluster size histogram const int cluster_size = std::distance(hit_range.first, hit_range.second); m_h_cluster_size->Fill(detid, cluster_size); diff --git a/offline/QA/Tracking/MicromegasClusterQA.h b/offline/QA/Tracking/MicromegasClusterQA.h index 338e5302de..d6de8344c4 100644 --- a/offline/QA/Tracking/MicromegasClusterQA.h +++ b/offline/QA/Tracking/MicromegasClusterQA.h @@ -51,6 +51,13 @@ class MicromegasClusterQA : public SubsysReco m_calibration_filename = value; } + /// set min sample for signal hits + void set_sample_min(uint16_t value) { m_sample_min = value; } + + /// set max sample for signal hits + void set_sample_max(uint16_t value) { m_sample_max = value; } + + private: void create_histograms(); @@ -98,6 +105,12 @@ class MicromegasClusterQA : public SubsysReco /// keep track of detector names std::vector m_detector_names; + /// min sample for signal + uint16_t m_sample_min = 0; + + /// max sample for signal + uint16_t m_sample_max = 1024; + ///@name calibration filename //@{ diff --git a/offline/QA/Tracking/SiliconSeedsQA.cc b/offline/QA/Tracking/SiliconSeedsQA.cc index 14a9feeaed..012caf26ff 100644 --- a/offline/QA/Tracking/SiliconSeedsQA.cc +++ b/offline/QA/Tracking/SiliconSeedsQA.cc @@ -248,7 +248,7 @@ void SiliconSeedsQA::createHistos() } { - h_trackcrossing = new TH1F(std::string(getHistoPrefix() + "trackcrossing").c_str(), "Track beam bunch crossing;Track crossing;Entries", 110, -10, 100); + h_trackcrossing = new TH1F(std::string(getHistoPrefix() + "trackcrossing").c_str(), "Track beam bunch crossing;Track crossing;Entries", 1000, -200, 800); hm->registerHisto(h_trackcrossing); } diff --git a/offline/QA/Tracking/StateClusterResidualsQA.cc b/offline/QA/Tracking/StateClusterResidualsQA.cc new file mode 100644 index 0000000000..d2239ede5d --- /dev/null +++ b/offline/QA/Tracking/StateClusterResidualsQA.cc @@ -0,0 +1,400 @@ +#include "StateClusterResidualsQA.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +namespace +{ + template + inline T square (T const& t) { return t * t; } + + template + class range_adaptor + { + public: + explicit range_adaptor( + T const& begin, + T const& end) + : m_begin(begin) + , m_end(end) + { + } + T const& begin() { return m_begin; } + T const& end() { return m_end; } + + private: + T m_begin; + T m_end; + }; +} // namespace + +StateClusterResidualsQA::StateClusterResidualsQA(const std::string& name) + : SubsysReco(name) +{ +} + +int StateClusterResidualsQA::InitRun( + PHCompositeNode* top_node) +{ + createHistos(); + + // F4A will not actually ABORTRUN unless that return code is issued here + auto* track_map = findNode::getClass(top_node, m_track_map_node_name); + if (!track_map) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get track map:\n" + << "\t\"" << m_track_map_node_name << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto* cluster_map = findNode::getClass(top_node, m_clusterContainerName); + if (!cluster_map) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get cluster map:\n" + << "\t\"" << m_clusterContainerName << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto *geometry = findNode::getClass(top_node, "ActsGeometry"); + if (!geometry) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get ActsGeometry:\n" + << "\t\"" << "ActsGeometry" << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto* hm = QAHistManagerDef::getHistoManager(); + if (!hm) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get QAHistManager\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + for (const auto& cfg : m_pending) + { + if (m_use_local_coords) + { + m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_rphi")))); + m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_z")))); + m_histograms_layer_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_layer_rphi")))); + m_histograms_layer_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_layer_z")))); + m_histograms_phi_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_phi_rphi")))); + m_histograms_phi_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_phi_z")))); + m_histograms_eta_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_eta_rphi")))); + m_histograms_eta_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_eta_z")))); + } + else + { + m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_x")))); + m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_y")))); + m_histograms_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_z")))); + m_histograms_layer_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_x")))); + m_histograms_layer_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_y")))); + m_histograms_layer_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_z")))); + m_histograms_phi_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_x")))); + m_histograms_phi_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_y")))); + m_histograms_phi_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_z")))); + m_histograms_eta_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_x")))); + m_histograms_eta_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_y")))); + m_histograms_eta_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_z")))); + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +int StateClusterResidualsQA::process_event(PHCompositeNode* top_node) +{ + auto* track_map = findNode::getClass(top_node, m_track_map_node_name); + auto *cluster_map = findNode::getClass(top_node, m_clusterContainerName); + auto *geometry = findNode::getClass(top_node, "ActsGeometry"); + + for (auto const& [idkey, track] : *track_map) + { + if (!track) + { + continue; + } + + // count states + std::map counters = { + {TrkrDefs::mvtxId, 0}, + {TrkrDefs::inttId, 0}, + {TrkrDefs::tpcId, 0}, + {TrkrDefs::micromegasId, 0}, + }; + + for (auto const& [path_length, state] : range_adaptor(track->begin_states(), track->end_states())) + { + // There is an additional state representing the vertex at the beginning of the map, + // but getTrkrId will return 0 for its corresponding cluster + // Identify it as having path_length identically equal to 0 + if (path_length == 0) { continue; } + + auto trkr_id = static_cast(TrkrDefs::getTrkrId(state->get_cluskey())); + auto itr = counters.find(trkr_id); + if (itr == counters.end()) { continue; } + ++itr->second; + } + + float track_eta = track->get_eta(); + float track_phi = track->get_phi(); + float track_pt = track->get_pt(); + int h = 0; + for (const auto& cfg : m_pending) + { + if (cfg.charge != 0) + { + if ((cfg.charge < 0) && track->get_positive_charge()) + { + continue; + } + if ((cfg.charge > 0) && !(track->get_positive_charge())) + { + continue; + } + } + if (cfg.min_mvtx_clusters <= counters[TrkrDefs::mvtxId] && cfg.max_mvtx_clusters >= counters[TrkrDefs::mvtxId] + && cfg.min_intt_clusters <= counters[TrkrDefs::inttId] && cfg.max_intt_clusters >= counters[TrkrDefs::inttId] + && cfg.min_tpc_clusters <= counters[TrkrDefs::tpcId] && cfg.max_tpc_clusters >= counters[TrkrDefs::tpcId] + && cfg.phi_min <= track_phi && cfg.phi_max >= track_phi + && cfg.eta_min <= track_eta && cfg.eta_max >= track_eta + && cfg.pt_min <= track_pt && cfg.pt_max >= track_pt) + { + for (auto const& [path_length, state] : range_adaptor(track->begin_states(), track->end_states())) + { + if (path_length == 0) { continue; } + + auto *cluster = cluster_map->findCluster(state->get_cluskey()); + if (!cluster) + { + continue; + } + + float state_x; + float state_y; + float state_z; + float cluster_x; + float cluster_y; + float cluster_z; + if (m_use_local_coords == true) + { + state_x = state->get_localX(); + state_y = state->get_localY(); + Acts::Vector2 loc = geometry->getLocalCoords(state->get_cluskey(), cluster); + cluster_x = loc.x(); + cluster_y = loc.y(); + m_histograms_x[h]->Fill(state_x - cluster_x); + m_histograms_y[h]->Fill(state_y - cluster_y); + m_histograms_layer_x[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_x - cluster_x); + m_histograms_layer_y[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_y - cluster_y); + m_histograms_phi_x[h]->Fill(state->get_phi(), state_x - cluster_x); + m_histograms_phi_y[h]->Fill(state->get_phi(), state_y - cluster_y); + m_histograms_eta_x[h]->Fill(state->get_eta(), state_x - cluster_x); + m_histograms_eta_y[h]->Fill(state->get_eta(), state_y - cluster_y); + } + else + { + state_x = state->get_x(); + state_y = state->get_y(); + state_z = state->get_z(); + Acts::Vector3 glob = geometry->getGlobalPosition(state->get_cluskey(), cluster); + cluster_x = glob.x(); + cluster_y = glob.y(); + cluster_z = glob.z(); + m_histograms_x[h]->Fill(state_x - cluster_x); + m_histograms_y[h]->Fill(state_y - cluster_y); + m_histograms_z[h]->Fill(state_z - cluster_z); + m_histograms_layer_x[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_x - cluster_x); + m_histograms_layer_y[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_y - cluster_y); + m_histograms_layer_z[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_z - cluster_z); + m_histograms_phi_x[h]->Fill(state->get_phi(), state_x - cluster_x); + m_histograms_phi_y[h]->Fill(state->get_phi(), state_y - cluster_y); + m_histograms_phi_z[h]->Fill(state->get_phi(), state_z - cluster_z); + m_histograms_eta_x[h]->Fill(state->get_eta(), state_x - cluster_x); + m_histograms_eta_y[h]->Fill(state->get_eta(), state_y - cluster_y); + m_histograms_eta_z[h]->Fill(state->get_eta(), state_z - cluster_z); + } + } + } + ++h; + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +void StateClusterResidualsQA::createHistos() +{ + auto *hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + for (const auto& cfg : m_pending) + { + if (m_use_local_coords) + { + TH1F* h_new_x = new TH1F( + (cfg.name + "_local_rphi").c_str(), + ";State-Cluster Local r#phi Residual [cm];Entries", + m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + h_new_x->SetMarkerColor(kBlue); + h_new_x->SetLineColor(kBlue); + hm->registerHisto(h_new_x); + TH1F* h_new_y = new TH1F( + (cfg.name + "_local_z").c_str(), + ";State-Cluster Local Z Residual [cm];Entries", + m_nBins, cfg.z_local_lower, cfg.z_local_upper); + h_new_y->SetMarkerColor(kBlue); + h_new_y->SetLineColor(kBlue); + hm->registerHisto(h_new_y); + TH2F* h_new_layer_x = new TH2F( + (cfg.name + "_local_layer_rphi").c_str(), + ";Layer Number;State-Cluster Local r#phi Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_layer_x); + TH2F* h_new_layer_y = new TH2F( + (cfg.name + "_local_layer_z").c_str(), + ";Layer Number;State-Cluster Local Z Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_layer_y); + TH2F* h_new_phi_x = new TH2F( + (cfg.name + "_local_phi_rphi").c_str(), + ";#phi [rad];State-Cluster Local r#phi Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_phi_x); + TH2F* h_new_phi_y = new TH2F( + (cfg.name + "_local_phi_z").c_str(), + ";#phi [rad];State-Cluster Local Z Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_phi_y); + TH2F* h_new_eta_x = new TH2F( + (cfg.name + "_local_eta_rphi").c_str(), + ";#eta;State-Cluster Local r#phi Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_eta_x); + TH2F* h_new_eta_y = new TH2F( + (cfg.name + "_local_eta_z").c_str(), + ";#eta;State-Cluster Local Z Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_eta_y); + } + else + { + TH1F* h_new_x = new TH1F( + (cfg.name + "_x").c_str(), + ";State-Cluster X Residual [cm];Entries", + m_nBins, cfg.x_lower, cfg.x_upper); + h_new_x->SetMarkerColor(kBlue); + h_new_x->SetLineColor(kBlue); + hm->registerHisto(h_new_x); + TH1F* h_new_y = new TH1F( + (cfg.name + "_y").c_str(), + ";State-Cluster Y Residual [cm];Entries", + m_nBins, cfg.y_lower, cfg.y_upper); + h_new_y->SetMarkerColor(kBlue); + h_new_y->SetLineColor(kBlue); + hm->registerHisto(h_new_y); + TH1F* h_new_z = new TH1F( + (cfg.name + "_z").c_str(), + ";State-Cluster Z Residual [cm];Entries", + m_nBins, cfg.z_lower, cfg.z_upper); + h_new_z->SetMarkerColor(kBlue); + h_new_z->SetLineColor(kBlue); + hm->registerHisto(h_new_z); + TH2F* h_new_layer_x = new TH2F( + (cfg.name + "_layer_x").c_str(), + ";Layer Number;State-Cluster Local X Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_layer_x); + TH2F* h_new_layer_y = new TH2F( + (cfg.name + "_layer_y").c_str(), + ";Layer Number;State-Cluster Local Y Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_layer_y); + TH2F* h_new_layer_z = new TH2F( + (cfg.name + "_layer_z").c_str(), + ";Layer Number;State-Cluster Local Z Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_layer_z); + TH2F* h_new_phi_x = new TH2F( + (cfg.name + "_phi_x").c_str(), + ";#phi [rad];State-Cluster Local X Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_phi_x); + TH2F* h_new_phi_y = new TH2F( + (cfg.name + "_phi_y").c_str(), + ";#phi [rad];State-Cluster Local Y Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_phi_y); + TH2F* h_new_phi_z = new TH2F( + (cfg.name + "_phi_z").c_str(), + ";#phi [rad];State-Cluster Local Z Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_phi_z); + TH2F* h_new_eta_x = new TH2F( + (cfg.name + "_eta_x").c_str(), + ";#eta;State-Cluster Local X Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_eta_x); + TH2F* h_new_eta_y = new TH2F( + (cfg.name + "_eta_y").c_str(), + ";#eta;State-Cluster Local Y Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_eta_y); + TH2F* h_new_eta_z = new TH2F( + (cfg.name + "_eta_z").c_str(), + ";#eta;State-Cluster Local Z Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_eta_z); + } + } +} + +int StateClusterResidualsQA::EndRun(const int /*unused*/) +{ + auto *hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/QA/Tracking/StateClusterResidualsQA.h b/offline/QA/Tracking/StateClusterResidualsQA.h new file mode 100644 index 0000000000..587178ef9b --- /dev/null +++ b/offline/QA/Tracking/StateClusterResidualsQA.h @@ -0,0 +1,181 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef STATECLUSTERRESIDUALSQA_H +#define STATECLUSTERRESIDUALSQA_H + +#include + +#include +#include +#include +#include +#include + +class PHCompositeNode; +class TH1; +class TH2; + +struct ResidualHistConfig +{ + std::string name = "h_StateClusterResidualsQA_"; + std::string title = ";Residual [cm];Entries"; + + int min_mvtx_clusters = 0; + int max_mvtx_clusters = 3; + int min_intt_clusters = 0; + int max_intt_clusters = 4; + int min_tpc_clusters = 0; + int max_tpc_clusters = 48; + + float phi_min = -M_PI; + float phi_max = M_PI; + float eta_min = -1.1; + float eta_max = 1.1; + + float pt_min = 0.0; + float pt_max = FLT_MAX; + + int charge = 0; + + float rphi_local_lower = -0.5; + float rphi_local_upper = 0.5; + float z_local_lower = -0.5; + float z_local_upper = 0.5; + float x_lower = -0.5; + float x_upper = 0.5; + float y_lower = -0.5; + float y_upper = 0.5; + float z_lower = -0.5; + float z_upper = 0.5; +}; + +class StateClusterResidualsQA : public SubsysReco +{ + public: + StateClusterResidualsQA(const std::string& name = "StateClusterResidualsQA"); + ~StateClusterResidualsQA() override = default; + + /// sets the name of node to retrieve the track map from (default member value is "SvtxTrackMap") + void set_track_map_name(std::string const& track_map_node_name) { m_track_map_node_name = track_map_node_name; } + + StateClusterResidualsQA& addHistogram(const std::string& name) + { + ResidualHistConfig cfg; + cfg.name += name; + m_pending.push_back(cfg); + return *this; + } + StateClusterResidualsQA& setNMvtx(int min, int max) + { + m_pending.back().min_mvtx_clusters = min; + m_pending.back().max_mvtx_clusters = max; + return *this; + } + StateClusterResidualsQA& setNIntt(int min, int max) + { + m_pending.back().min_intt_clusters = min; + m_pending.back().max_intt_clusters = max; + return *this; + } + StateClusterResidualsQA& setNTpc(int min, int max) + { + m_pending.back().min_tpc_clusters = min; + m_pending.back().max_tpc_clusters = max; + return *this; + } + StateClusterResidualsQA& setPhiRange(float min, float max) + { + m_pending.back().phi_min = min; + m_pending.back().phi_max = max; + return *this; + } + StateClusterResidualsQA& setEtaRange(float min, float max) + { + m_pending.back().eta_min = min; + m_pending.back().eta_max = max; + return *this; + } + StateClusterResidualsQA& setPtRange(float min, float max) + { + m_pending.back().pt_min = min; + m_pending.back().pt_max = max; + return *this; + } + StateClusterResidualsQA& setXRange(float min, float max) + { + m_pending.back().x_lower = min; + m_pending.back().x_upper = max; + return *this; + } + StateClusterResidualsQA& setYRange(float min, float max) + { + m_pending.back().y_lower = min; + m_pending.back().y_upper = max; + return *this; + } + StateClusterResidualsQA& setZRange(float min, float max) + { + m_pending.back().z_lower = min; + m_pending.back().z_upper = max; + return *this; + } + StateClusterResidualsQA& setLocalRphiRange(float min, float max) + { + m_pending.back().rphi_local_lower = min; + m_pending.back().rphi_local_upper = max; + return *this; + } + StateClusterResidualsQA& setLocalZRange(float min, float max) + { + m_pending.back().z_local_lower = min; + m_pending.back().z_local_upper = max; + return *this; + } + StateClusterResidualsQA& setPositiveTracks() + { + m_pending.back().charge = 1; + return *this; + } + StateClusterResidualsQA& setNegativeTracks() + { + m_pending.back().charge = -1; + return *this; + } + + void setUseLocalCoords() + { + m_use_local_coords = true; + } + + void createHistos(); + + int InitRun(PHCompositeNode*) override; + + int process_event(PHCompositeNode*) override; + + int EndRun(const int runnumber) override; + + private: + std::vector m_pending; + + std::string m_track_map_node_name = "SvtxTrackMap"; + std::string m_clusterContainerName = "TRKR_CLUSTER"; + + int m_nBins = 50; + bool m_use_local_coords = false; + + std::vector m_histograms_x{}; + std::vector m_histograms_y{}; + std::vector m_histograms_z{}; + std::vector m_histograms_layer_x{}; + std::vector m_histograms_layer_y{}; + std::vector m_histograms_layer_z{}; + std::vector m_histograms_phi_x{}; + std::vector m_histograms_phi_y{}; + std::vector m_histograms_phi_z{}; + std::vector m_histograms_eta_x{}; + std::vector m_histograms_eta_y{}; + std::vector m_histograms_eta_z{}; +}; + +#endif // TRACKFITTINGQA_H diff --git a/offline/framework/ffamodules/CDBInterface.cc b/offline/framework/ffamodules/CDBInterface.cc index 2b4feef203..2a0b3e1b3c 100644 --- a/offline/framework/ffamodules/CDBInterface.cc +++ b/offline/framework/ffamodules/CDBInterface.cc @@ -185,11 +185,14 @@ std::string CDBInterface::getUrl(const std::string &domain, const std::string &f std::cout << "... reply: " << return_url << std::endl; } } - auto pret = m_UrlVector.insert(make_tuple(domain_noconst, return_url, timestamp)); - if (!pret.second && Verbosity() > 1) + if (! return_url.empty()) { - std::cout << PHWHERE << "not adding again " << domain_noconst << ", url: " << return_url - << ", time stamp: " << timestamp << std::endl; + auto pret = m_UrlVector.insert(make_tuple(domain_noconst, return_url, timestamp)); + if (!pret.second && Verbosity() > 1) + { + std::cout << PHWHERE << "not adding again " << domain_noconst << ", url: " << return_url + << ", time stamp: " << timestamp << std::endl; + } } return return_url; } diff --git a/offline/framework/ffamodules/CDBInterface.h b/offline/framework/ffamodules/CDBInterface.h index c88fae9dee..4132b35a34 100644 --- a/offline/framework/ffamodules/CDBInterface.h +++ b/offline/framework/ffamodules/CDBInterface.h @@ -10,7 +10,6 @@ #include #include // for tuple -class PHCompositeNode; class SphenixClient; class CDBInterface : public SubsysReco diff --git a/offline/framework/ffamodules/FlagHandler.h b/offline/framework/ffamodules/FlagHandler.h index f5cc06bcdb..fd7e40cca3 100644 --- a/offline/framework/ffamodules/FlagHandler.h +++ b/offline/framework/ffamodules/FlagHandler.h @@ -7,14 +7,12 @@ #include -class PHCompositeNode; - class FlagHandler : public SubsysReco { public: FlagHandler(const std::string &name = "FlagHandler"); - ~FlagHandler() override {} + ~FlagHandler() override = default; /** Create the Flag Node if it does not exist, if it exists, read back flags and copy them into recoConsts diff --git a/offline/framework/ffamodules/HeadReco.cc b/offline/framework/ffamodules/HeadReco.cc index 75e879fdff..17214758c8 100644 --- a/offline/framework/ffamodules/HeadReco.cc +++ b/offline/framework/ffamodules/HeadReco.cc @@ -84,10 +84,13 @@ int HeadReco::process_event(PHCompositeNode *topNode) { evtheader->set_ImpactParameter(hi->impact_parameter()); evtheader->set_EventPlaneAngle(hi->event_plane_angle()); - for (unsigned int n = 1; n <= 6; ++n) - { - evtheader->set_FlowPsiN(n, genevt->get_flow_psi(n)); - } + if (! genevt->get_flow_psi_map().empty()) + { + for (unsigned int n = 1; n <= 6; ++n) + { + evtheader->set_FlowPsiN(n, genevt->get_flow_psi(n)); + } + } evtheader->set_eccentricity(hi->eccentricity()); evtheader->set_ncoll(hi->Ncoll()); evtheader->set_npart(hi->Npart_targ() + hi->Npart_proj()); diff --git a/offline/framework/ffamodules/HeadReco.h b/offline/framework/ffamodules/HeadReco.h index ca2f6cf34e..53fbc3c6c3 100644 --- a/offline/framework/ffamodules/HeadReco.h +++ b/offline/framework/ffamodules/HeadReco.h @@ -7,13 +7,11 @@ #include // for string -class PHCompositeNode; - class HeadReco : public SubsysReco { public: HeadReco(const std::string &name = "HeadReco"); - ~HeadReco() override {} + ~HeadReco() override = default; int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; diff --git a/offline/framework/ffamodules/SyncReco.h b/offline/framework/ffamodules/SyncReco.h index 0a490302a0..73d0954593 100644 --- a/offline/framework/ffamodules/SyncReco.h +++ b/offline/framework/ffamodules/SyncReco.h @@ -5,13 +5,11 @@ #include -class PHCompositeNode; - class SyncReco : public SubsysReco { public: SyncReco(const std::string &name = "SYNC"); - ~SyncReco() override {} + ~SyncReco() override = default; int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; @@ -24,7 +22,7 @@ class SyncReco : public SubsysReco // just if we need to override the segment for e.g. embedding // where we want to reuse hijing files which normally set // the segment number - int forced_segment = -1; + int forced_segment {-1}; }; #endif /* FFAMODULES_SYNCRECO_H */ diff --git a/offline/framework/ffamodules/Timing.cc b/offline/framework/ffamodules/Timing.cc index f662ba1b33..16210e4f73 100644 --- a/offline/framework/ffamodules/Timing.cc +++ b/offline/framework/ffamodules/Timing.cc @@ -3,8 +3,6 @@ #include #include // for SubsysReco -#include - #include Timing::Timing(const std::string &name) diff --git a/offline/framework/ffamodules/Timing.h b/offline/framework/ffamodules/Timing.h index 01b95638e0..a9a5ccd39d 100644 --- a/offline/framework/ffamodules/Timing.h +++ b/offline/framework/ffamodules/Timing.h @@ -8,15 +8,13 @@ #include // for string #include -class PHCompositeNode; - class Timing : public SubsysReco { public: Timing(const std::string &name = "Timing"); - ~Timing() override {} - int InitRun(PHCompositeNode *topNode) override; - int process_event(PHCompositeNode *topNode) override; + ~Timing() override = default; + int InitRun(PHCompositeNode * /*topNode*/) override; + int process_event(PHCompositeNode * /*topNode*/) override; void SetCallCounter(unsigned int i) { calls = i; } private: diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index cc59083d8c..1f71d9897f 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -74,7 +74,9 @@ "33" => "JS pythia8 Jet ptmin = 15GeV", "34" => "JS pythia8 Jet ptmin = 50GeV", "35" => "JS pythia8 Jet ptmin = 70GeV", - "36" => "JS pythia8 Jet ptmin = 5GeV" + "36" => "JS pythia8 Jet ptmin = 5GeV", + "37" => "hijing O+O (0-15fm)", + "38" => "JS pythia8 Jet ptmin = 60GeV", ); my %pileupdesc = ( @@ -147,6 +149,7 @@ my $AuAu_pileupstring; my $pp_pileupstring; my $pAu_pileupstring; +my $OO_pileupstring; my $pileupstring; if (! defined $runnumber && $#newargs >= 0) @@ -167,6 +170,7 @@ } my $pAu_bkgpileup = sprintf("_bkg_0_20fm"); my $AuAu_bkgpileup = sprintf("_bkg_0_10fm"); +my $OO_bkgpileup = sprintf("_bkg_0_15fm"); if ($pileup == 1) { $AuAu_pileupstring = sprintf("_50kHz%s",$AuAu_bkgpileup); @@ -192,12 +196,14 @@ else { $pp_pileupstring = sprintf("_%dkHz",$pileup); - $AuAu_pileupstring = sprintf("_%dkHz%s",$AuAu_bkgpileup); + $AuAu_pileupstring = sprintf("_%dkHz%s",$pileup, $AuAu_bkgpileup); + $OO_pileupstring = sprintf("_%dkHz%s",$pileup,$OO_bkgpileup); } if (defined $nobkgpileup) { $pp_pileupstring = sprintf(""); $AuAu_pileupstring = sprintf(""); + $OO_pileupstring = sprintf(""); } my $embedok = 0; @@ -926,6 +932,49 @@ $pileupstring = $pp_pileupstring; &commonfiletypes(); } + elsif ($prodtype == 37) + { + if (defined $nopileup) + { + $filenamestring = sprintf("sHijing_OO_0_15fm"); + } + else + { + $filenamestring = sprintf("sHijing_OO_0_15fm%s",$OO_pileupstring); + } + $notlike{$filenamestring} = ["pythia8" ,"single", "special"]; + $pileupstring = $AuAu_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 38) + { + $embedok = 1; + $filenamestring = "pythia8_Jet60"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } else { diff --git a/offline/framework/fun4all/Fun4AllServer.cc b/offline/framework/fun4all/Fun4AllServer.cc index 9d8779204e..9dc68afbb0 100644 --- a/offline/framework/fun4all/Fun4AllServer.cc +++ b/offline/framework/fun4all/Fun4AllServer.cc @@ -128,9 +128,9 @@ void Fun4AllServer::InitAll() { gSystem->IgnoreSignal((ESignals) i); } + m_saved_cout_state.copyfmt(std::cout); // save current state Fun4AllMonitoring::instance()->Snapshot("StartUp"); - std::string histomanagername; - histomanagername = Name() + "HISTOS"; + std::string histomanagername = Name() + "HISTOS"; ServerHistoManager = new Fun4AllHistoManager(histomanagername); registerHistoManager(ServerHistoManager); double uplim = NFRAMEWORKBINS - 0.5; @@ -245,6 +245,7 @@ int Fun4AllServer::registerSubsystem(SubsysReco *subsystem, const std::string &t << subsystem->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting gROOT->cd(currdir.c_str()); if (iret) { @@ -576,6 +577,7 @@ int Fun4AllServer::process_event() ffamemtracker->Snapshot("Fun4AllServerProcessEvent"); #endif int retcode = Subsystem.first->process_event(Subsystem.second); + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting #ifdef FFAMEMTRACKER ffamemtracker->Snapshot("Fun4AllServerProcessEvent"); #endif @@ -899,6 +901,7 @@ int Fun4AllServer::BeginRun(const int runno) for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) { iret = BeginRunSubsystem(*iter); + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } for (; !NewSubsystems.empty(); NewSubsystems.pop_front()) { @@ -1092,6 +1095,7 @@ int Fun4AllServer::EndRun(const int runno) << (*iter).first->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } gROOT->cd(currdir.c_str()); @@ -1144,6 +1148,7 @@ int Fun4AllServer::End() << (*iter).first->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } gROOT->cd(currdir.c_str()); PHNodeIterator nodeiter(TopNode); diff --git a/offline/framework/fun4all/Fun4AllServer.h b/offline/framework/fun4all/Fun4AllServer.h index 0c7ea72c14..9f360b9502 100644 --- a/offline/framework/fun4all/Fun4AllServer.h +++ b/offline/framework/fun4all/Fun4AllServer.h @@ -143,7 +143,8 @@ class Fun4AllServer : public Fun4AllBase int eventnumber{0}; int eventcounter{0}; int keep_db_connected{0}; - + + std::ios m_saved_cout_state{nullptr}; std::vector ComplaintList; std::vector ResetNodeList {"DST"}; std::vector> Subsystems; diff --git a/offline/framework/fun4all/InputFileHandler.cc b/offline/framework/fun4all/InputFileHandler.cc index 8939b67568..0fdc858db8 100644 --- a/offline/framework/fun4all/InputFileHandler.cc +++ b/offline/framework/fun4all/InputFileHandler.cc @@ -3,10 +3,13 @@ #include +#include + #include #include #include #include +#include int InputFileHandler::AddFile(const std::string &filename) { @@ -89,6 +92,19 @@ int InputFileHandler::OpenNextFile() { std::cout << PHWHERE << " opening next file: " << *iter << std::endl; } + if (!GetOpeningScript().empty()) + { + std::vector stringvec; + stringvec.push_back(*iter); + if (!m_FileName.empty()) + { + stringvec.push_back(m_FileName); + } + if (RunBeforeOpening(stringvec)) + { + std::cout << PHWHERE << " RunBeforeOpening() failed" << std::endl; + } + } if (fileopen(*iter)) { std::cout << PHWHERE << " could not open file: " << *iter << std::endl; @@ -145,3 +161,40 @@ int InputFileHandler::fileopen(const std::string &fname) std::cout << "InputFileHandler::fileopen opening " << fname << std::endl; return 0; } + +int InputFileHandler::RunBeforeOpening(const std::vector &stringvec) +{ + if (m_RunBeforeOpeningScript.empty()) + { + return 0; + } + if (!std::filesystem::exists(m_RunBeforeOpeningScript)) + { + std::cout << PHWHERE << " script " << m_RunBeforeOpeningScript << " not found" + << std::endl; + return -1; + } + if (!((std::filesystem::status(m_RunBeforeOpeningScript).permissions() & std::filesystem::perms::owner_exec) == std::filesystem::perms::owner_exec)) + { + std::cout << PHWHERE << "RunBeforeOpeningScript script " + << m_RunBeforeOpeningScript << " is not owner executable" << std::endl; + return -1; + } + std::string fullcmd = m_RunBeforeOpeningScript + " " + m_OpeningArgs; + for (const auto& iter : stringvec) + { + fullcmd += " " + iter; + } + + if (m_Verbosity > 1) + { + std::cout << PHWHERE << " running " << fullcmd << std::endl; + } + unsigned int iret = gSystem->Exec(fullcmd.c_str()); + + if (iret) + { + iret = iret >> 8U; + } + return static_cast (iret); +} diff --git a/offline/framework/fun4all/InputFileHandler.h b/offline/framework/fun4all/InputFileHandler.h index 823ae33b38..49df4aa379 100644 --- a/offline/framework/fun4all/InputFileHandler.h +++ b/offline/framework/fun4all/InputFileHandler.h @@ -4,13 +4,14 @@ #include #include #include +#include class InputFileHandler { public: InputFileHandler() = default; virtual ~InputFileHandler() = default; - virtual int fileopen(const std::string & /*filename*/);// { return 0; } + virtual int fileopen(const std::string & /*filename*/); // { return 0; } virtual int fileclose() { return -1; } virtual int ResetFileList(); @@ -32,12 +33,19 @@ class InputFileHandler std::pair::const_iterator, std::list::const_iterator> FileOpenListBeginEnd() { return std::make_pair(m_FileListOpened.begin(), m_FileListOpened.end()); } const std::list &GetFileList() const { return m_FileListCopy; } const std::list &GetFileOpenedList() const { return m_FileListOpened; } + void SetOpeningScript(const std::string &script) { m_RunBeforeOpeningScript = script; } + const std::string &GetOpeningScript() const { return m_RunBeforeOpeningScript; } + void SetOpeningScriptArgs(const std::string &args) { m_OpeningArgs = args; } + const std::string &GetOpeningScriptArgs() const { return m_OpeningArgs; } + int RunBeforeOpening(const std::vector &stringvec); private: int m_IsOpen{0}; int m_Repeat{0}; uint64_t m_Verbosity{0}; std::string m_FileName; + std::string m_RunBeforeOpeningScript; + std::string m_OpeningArgs; std::list m_FileList; std::list m_FileListCopy; std::list m_FileListOpened; // all files which were opened during running diff --git a/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc b/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc index 78b3e3a365..0bea81197b 100644 --- a/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc +++ b/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc @@ -776,9 +776,15 @@ int Fun4AllStreamingInputManager::FillIntt() { h_taggedAllFee_intt->Fill(refbcobitshift); } - while (m_InttRawHitMap.begin()->first <= select_crossings - m_intt_negative_bco) + + for (auto& [bco, hitinfo] : m_InttRawHitMap) { - for (auto *intthititer : m_InttRawHitMap.begin()->second.InttRawHitVector) + if (bco > select_crossings) + { + break; + } + + for (auto *intthititer : hitinfo.InttRawHitVector) { if (Verbosity() > 1) { @@ -788,25 +794,9 @@ int Fun4AllStreamingInputManager::FillIntt() } inttcont->AddHit(intthititer); } - for (auto *iter : m_InttInputVector) - { - iter->CleanupUsedPackets(m_InttRawHitMap.begin()->first); - if (m_intt_negative_bco < 2) // triggered mode - { - iter->clearPacketBClkStackMap(m_InttRawHitMap.begin()->first); - iter->clearFeeGTML1BCOMap(m_InttRawHitMap.begin()->first); - } - } - m_InttRawHitMap.begin()->second.InttRawHitVector.clear(); - m_InttRawHitMap.erase(m_InttRawHitMap.begin()); - if (m_InttRawHitMap.empty()) - { - break; - } - } + } return 0; } - int Fun4AllStreamingInputManager::FillMvtx() { int iret = FillMvtxPool(); @@ -846,7 +836,7 @@ int Fun4AllStreamingInputManager::FillMvtx() } select_crossings += m_RefBCO; - uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? 0 : m_RefBCO - m_mvtx_bco_range; + uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_negative_bco ? 0 : m_RefBCO - m_mvtx_negative_bco; if (Verbosity() > 2) { std::cout << "select MVTX crossings" @@ -981,90 +971,42 @@ int Fun4AllStreamingInputManager::FillMvtx() } taggedPacketsFEEs.clear(); - if (m_mvtx_is_triggered) + uint64_t lower_limit = m_mvtx_is_triggered ? select_crossings : select_crossings - m_mvtx_bco_range - m_mvtx_negative_bco; + uint64_t upper_limit = m_mvtx_is_triggered ? select_crossings + m_mvtx_bco_range : select_crossings; + + for (auto& [bco, hitinfo] : m_MvtxRawHitMap) { - while (select_crossings <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings + m_mvtx_bco_range) // triggered + if (bco < lower_limit) { - if (Verbosity() > 2) - { - std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first - << " ref: 0x" << select_crossings << std::dec << std::endl; - } - for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector) - { - if (Verbosity() > 1) - { - mvtxFeeIdInfo->identify(); - } - mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); - delete mvtxFeeIdInfo; - } - m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear(); - mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco); + continue; + } + if (bco > upper_limit) + { + break; + } - for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector) - { - if (Verbosity() > 1) - { - mvtxhititer->identify(); - } - mvtxcont->AddHit(mvtxhititer); - } - for (auto *iter : m_MvtxInputVector) - { - iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first); - } - m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear(); - m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear(); - m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin()); - // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx() - if (m_MvtxRawHitMap.empty()) - { - break; - } + if (Verbosity() > 2) + { + std::cout << "Adding 0x" << std::hex << bco + << " ref: 0x" << select_crossings << std::dec << std::endl; } - } - else - { - while (select_crossings - m_mvtx_bco_range - m_mvtx_negative_bco <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings) // streamed + for (auto *mvtxFeeIdInfo : hitinfo.MvtxFeeIdInfoVector) { - if (Verbosity() > 2) - { - std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first - << " ref: 0x" << select_crossings << std::dec << std::endl; - } - for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector) + if (Verbosity() > 1) { - if (Verbosity() > 1) - { - mvtxFeeIdInfo->identify(); - } - mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); - delete mvtxFeeIdInfo; + mvtxFeeIdInfo->identify(); } - m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear(); - mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco); + mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); + } + mvtxEvtHeader->AddL1Trg(hitinfo.MvtxL1TrgBco); - for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector) - { - if (Verbosity() > 1) - { - mvtxhititer->identify(); - } - mvtxcont->AddHit(mvtxhititer); - } - for (auto *iter : m_MvtxInputVector) - { - iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first); - } - m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear(); - m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear(); - m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin()); - // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx() - if (m_MvtxRawHitMap.empty()) + for (auto *mvtxhititer : hitinfo.MvtxRawHitVector) + { + if (Verbosity() > 1) { - break; + mvtxhititer->identify(); } + mvtxcont->AddHit(mvtxhititer); } } @@ -1422,7 +1364,7 @@ int Fun4AllStreamingInputManager::FillMicromegasPool() int Fun4AllStreamingInputManager::FillMvtxPool() { - uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? m_mvtx_bco_range : m_RefBCO - m_mvtx_bco_range; + uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_negative_bco ? m_mvtx_negative_bco : m_RefBCO - m_mvtx_negative_bco; for (auto *iter : m_MvtxInputVector) { if (Verbosity() > 3) diff --git a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc index 7500e3badf..89c0caa9f3 100644 --- a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc +++ b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc @@ -607,6 +607,7 @@ void SingleMicromegasPoolInput_v2::createQAHistos() m_evaluation_file.reset(new TFile(m_evaluation_filename.c_str(), "RECREATE")); m_evaluation_tree = new TTree("T", "T"); m_evaluation_tree->Branch("is_heartbeat", &m_waveform.is_heartbeat); + m_evaluation_tree->Branch("matched", &m_waveform.matched); m_evaluation_tree->Branch("packet_id", &m_waveform.packet_id); m_evaluation_tree->Branch("fee_id", &m_waveform.fee_id); m_evaluation_tree->Branch("channel", &m_waveform.channel); @@ -912,6 +913,13 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int // try get gtm bco matching fee const auto& fee_bco = payload.bx_timestamp; + if( m_do_evaluation ) + { + m_waveform.is_heartbeat = is_heartbeat; + m_waveform.fee_id = fee_id; + m_waveform.channel = payload.channel; + m_waveform.fee_bco = fee_bco; + } // find matching gtm bco uint64_t gtm_bco = 0; @@ -920,9 +928,20 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int { // assign gtm bco gtm_bco = result.value(); - } - else - { + if( m_do_evaluation ) + { + m_waveform.matched = true; + m_waveform.gtm_bco_matched = gtm_bco; + { + const auto predicted = bco_matching_information.get_predicted_fee_bco(gtm_bco);; + if( predicted ) + { + m_waveform.fee_bco_predicted_matched = predicted.value(); + } + } + m_evaluation_tree->Fill(); + } + } else { // increment counter and histogram ++m_waveform_counters[packet_id].dropped_bco; ++m_fee_waveform_counters[fee_id].dropped_bco; @@ -935,28 +954,16 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int ++m_fee_heartbeat_counters[fee_id].dropped_bco; } - // skip the waverform - continue; - } - - if (m_do_evaluation) - { - m_waveform.is_heartbeat = (payload.type == HEARTBEAT_T); - m_waveform.fee_id = fee_id; - m_waveform.channel = payload.channel; - m_waveform.fee_bco = fee_bco; - - m_waveform.gtm_bco_matched = gtm_bco; + if( m_do_evaluation ) { - const auto predicted = bco_matching_information.get_predicted_fee_bco(gtm_bco); - ; - if (predicted) - { - m_waveform.fee_bco_predicted_matched = predicted.value(); - } + m_waveform.matched = false; + m_waveform.gtm_bco_matched = 0; + m_waveform.fee_bco_predicted_matched = 0; + m_evaluation_tree->Fill(); } - m_evaluation_tree->Fill(); + // skip the waverform + continue; } // ignore heartbeat waveforms diff --git a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h index d8c3c1da62..3746b9eb41 100644 --- a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h +++ b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h @@ -230,6 +230,9 @@ class SingleMicromegasPoolInput_v2 : public SingleStreamingInput /// true if measurement is hearbeat bool is_heartbeat = false; + /// true if matched + bool matched = false; + /// ll1 bco uint64_t gtm_bco_first {0}; diff --git a/offline/framework/fun4allraw/SingleMvtxPoolInput.cc b/offline/framework/fun4allraw/SingleMvtxPoolInput.cc index de98a9936e..4ce498ee9e 100644 --- a/offline/framework/fun4allraw/SingleMvtxPoolInput.cc +++ b/offline/framework/fun4allraw/SingleMvtxPoolInput.cc @@ -1,7 +1,7 @@ #include "SingleMvtxPoolInput.h" -#include "MvtxRawDefs.h" #include "Fun4AllStreamingInputManager.h" +#include "MvtxRawDefs.h" #include "mvtx_pool.h" #include @@ -29,7 +29,8 @@ #include SingleMvtxPoolInput::SingleMvtxPoolInput(const std::string &name) - : SingleStreamingInput(name), plist(new Packet *[2]) + : SingleStreamingInput(name) + , plist(new Packet *[2]) { m_rawHitContainerName = "MVTXRAWHIT"; @@ -161,7 +162,7 @@ void SingleMvtxPoolInput::FillPool(const uint64_t minBCO) m_BclkStack.insert(strb_bco); m_FEEBclkMap[feeId] = strb_bco; - if (strb_bco < minBCO - m_NegativeBco) + if (strb_bco < minBCO) { continue; } @@ -206,7 +207,7 @@ void SingleMvtxPoolInput::FillPool(const uint64_t minBCO) auto it = m_BclkStack.lower_bound(lv1Bco); // auto const strb_it = (it == m_BclkStack.begin()) ? (*it == lv1Bco ? it : m_BclkStack.cend()) : --it; // this is equivalent but human readable for the above: - auto strb_it = m_BclkStack.cend(); + auto strb_it = m_BclkStack.cend(); if (it == m_BclkStack.begin()) { @@ -462,7 +463,7 @@ void SingleMvtxPoolInput::ConfigureStreamingInputManager() else if (m_strobeWidth > 9 && m_strobeWidth < 11) { m_BcoRange = 500; - m_NegativeBco = 500; + m_NegativeBco = 120; } else if (m_strobeWidth < 1) // triggered mode { diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.cc b/offline/framework/fun4allraw/SingleTriggeredInput.cc index 3bb6b30a2b..80e9f49a64 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.cc +++ b/offline/framework/fun4allraw/SingleTriggeredInput.cc @@ -352,6 +352,12 @@ int SingleTriggeredInput::FillEventVector() m_bclkarray_map[pid][0] = tmp; m_bclkdiffarray_map[pid].fill(std::numeric_limits::max()); + static bool firstclockarray=true; + if(firstclockarray){ + std::cout << "first clock call pid " << pid << " m_bclkarray_map[pid][0] : " << m_bclkarray_map[pid][0] << std::endl; + firstclockarray=false; + } + if ( representative_pid == -1 ) { representative_pid = pid; @@ -368,12 +374,17 @@ int SingleTriggeredInput::FillEventVector() while (i < pooldepth) { Event* evt{nullptr}; + bool skiptrace = false; if (this != Gl1Input()) { auto* gl1 = dynamic_cast(Gl1Input()); if (gl1) { int nskip = gl1->GetGl1SkipArray()[i]; + if(nskip >0) + { + skiptrace = true; + } while (nskip > 0) { @@ -391,6 +402,7 @@ int SingleTriggeredInput::FillEventVector() if (skip_evt->getEvtType() != DATAEVENT) { + delete skip_evt; continue; } @@ -412,14 +424,91 @@ int SingleTriggeredInput::FillEventVector() { if (Verbosity() > 0) { - std::cout << Name() << ": Early stop of SEB skip after " << (gl1->GetGl1SkipArray()[i] - nskip) << " from intial " << gl1->GetGl1SkipArray()[i] << " events." << std::endl; + std::cout << Name() << ": Early stop in pool " << i << " of SEB skip after " << (gl1->GetGl1SkipArray()[i] - nskip) << " from intial " << gl1->GetGl1SkipArray()[i] << " events. gl1diff vs sebdiff : " << gl1_diff << " vs " << seb_diff << std::endl; } evt = skip_evt; + skiptrace = false; break; } delete skip_evt; nskip--; } + + if(skiptrace) + { + evt = GetEventIterator()->getNextEvent(); + while (!evt) + { + fileclose(); + if (OpenNextFile() == InputFileHandlerReturnCodes::FAILURE) + { + FilesDone(1); + return -1; + } + evt = GetEventIterator()->getNextEvent(); + } + if (evt->getEvtType() != DATAEVENT) + { + if (Verbosity() > 0) + { + std::cout << Name() << " dropping non data event: " << evt->getEvtSequence() << std::endl; + } + delete evt; + continue; + } + + Packet* pkt = evt->getPacket(representative_pid); + if (!pkt) + { + std::cout << "representative packet invalid inside skiptrace.. continuing.." << std::endl; + continue; + } + FillPacketClock(evt, pkt, i); + uint64_t seb_diff = m_bclkdiffarray_map[representative_pid][i]; + int gl1pid = Gl1Input()->m_bclkdiffarray_map.begin()->first; + uint64_t gl1_diff = gl1->m_bclkdiffarray_map[gl1pid][i]; + + bool clockconsistency=true; + if (seb_diff != gl1_diff) + { + clockconsistency=false; + int clockconstcount = 0; + while(!clockconsistency && clockconstcount<5) + { + std::cout << Name() << ": Still inconsistent clock diff after Gl1 drop. gl1diff vs sebdiff : " << gl1_diff << " vs " << seb_diff << std::endl; + delete pkt; + delete evt; + evt = GetEventIterator()->getNextEvent(); + while (!evt) + { + fileclose(); + if (OpenNextFile() == InputFileHandlerReturnCodes::FAILURE) + { + FilesDone(1); + return -1; + } + evt = GetEventIterator()->getNextEvent(); + } + pkt = evt->getPacket(representative_pid); + if (!pkt) + { + std::cout << "representative packet invalid inside skiptrace.. continuing.." << std::endl; + continue; + } + + FillPacketClock(evt, pkt, i); + uint64_t seb_diff_next = m_bclkdiffarray_map[representative_pid][i]; + uint64_t gl1_diff_next = gl1->m_bclkdiffarray_map[gl1pid][i]; + std::cout << "seb_diff_next : " << seb_diff_next << " , gl1_diff_next : " << gl1_diff_next << std::endl; + if(seb_diff_next == gl1_diff_next) + { + clockconsistency=true; + std::cout << Name() << " : recovered by additional skip in skiptrace" << std::endl; + } + clockconstcount++; + } + } + } } } @@ -485,14 +574,16 @@ int SingleTriggeredInput::FillEventVector() } FillPacketClock(thisevt, pkt, i); m_PacketEventDeque[pid].push_back(thisevt); + delete pkt; - + if (representative_pid == -1 && m_PacketShiftOffset[pid] == 0) { representative_pid = pid; } } i++; + eventcounter++; } size_t minSize = pooldepth; @@ -1116,16 +1207,15 @@ int SingleTriggeredInput::ReadEvent() [](const std::pair& p) { return p.second == 0; }); std::set events_to_delete; - for (auto& [pid, dq] : m_PacketEventDeque) { if(m_PacketAlignmentProblem[pid]) { continue; } + Event* evt = dq.front(); Packet* packet = evt->getPacket(pid); - int packet_id = packet->getIdentifier(); if (packet_id != pid) { @@ -1137,7 +1227,6 @@ int SingleTriggeredInput::ReadEvent() CaloPacket *newhit = findNode::getClass(m_topNode, packet_id); newhit->Reset(); - if (m_DitchPackets.contains(packet_id) && m_DitchPackets[packet_id].contains(0)) { newhit->setStatus(OfflinePacket::PACKET_DROPPED); diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.h b/offline/framework/fun4allraw/SingleTriggeredInput.h index 088be73bef..d7d825b02a 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.h +++ b/offline/framework/fun4allraw/SingleTriggeredInput.h @@ -34,9 +34,6 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler virtual void FillPool(); virtual void RunNumber(const int runno) { m_RunNumber = runno; } virtual int RunNumber() const { return m_RunNumber; } - virtual void EventNumber(const int i) { m_EventNumber = i; } - virtual int EventNumber() const { return m_EventNumber; } - virtual int EventsInThisFile() const { return m_EventsThisFile; } virtual int fileopen(const std::string &filename) override; virtual int fileclose() override; virtual int AllDone() const { return m_AllDone; } @@ -45,6 +42,8 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler virtual void FilesDone(const int i) { m_FilesDone = i; } virtual void EventAlignmentProblem(const int i) { m_EventAlignmentProblem = i; } virtual int EventAlignmentProblem() const { return m_EventAlignmentProblem; } + virtual void EventNumber(const int i) { m_EventNumber = i; } + virtual int EventNumber() const { return m_EventNumber; } virtual void CreateDSTNodes(Event *evt); // these ones are used directly by the derived classes, maybe later // move to cleaner accessors @@ -94,7 +93,6 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler int m_AllDone{0}; uint64_t m_Event{0}; int m_EventNumber{0}; - int m_EventsThisFile{0}; int m_EventAlignmentProblem{0}; int m_FilesDone{0}; int m_LastEvent{std::numeric_limits::max()}; @@ -114,6 +112,7 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler std::map m_PacketAlignmentProblem; std::map m_PrevPoolLastDiffBad; std::map m_PreviousValidBCOMap; + long long eventcounter{0}; }; #endif diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index a9a860e583..2c809f2fb9 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -1,7 +1,23 @@ #ifndef PHOOL_RUNNUMBERRANGE_H #define PHOOL_RUNNUMBERRANGE_H -// first and last physics run +/** + * Defines run-number range constants and special run markers used to identify physics data-taking periods. + * + * Each constant names the first or last run number (or a special marker) for a given data-taking period. + * + * @var RUN2PP_FIRST First Run 2 proton-proton physics run. + * @var RUN2PP_LAST Last Run 2 proton-proton physics run. + * @var RUN2AUAU_FIRST First Run 2 Au+Au (heavy-ion) physics run. + * @var RUN2AUAU_LAST Last Run 2 Au+Au (heavy-ion) physics run. + * @var RUN3_TPCFW_CLOCK_CHANGE Run 3 marker for the TPC Forward clock change. + * @var RUN3AUAU_FIRST First Run 3 Au+Au (heavy-ion) physics run. + * @var RUN3AUAU_LAST Last Run 3 Au+Au (heavy-ion) physics run. + * @var RUN3PP_FIRST First Run 3 proton-proton (beam) physics run. + * @var RUN3PP_LAST Last Run 3 proton-proton physics run. + * @var RUN3OO_FIRST Temporary placeholder for the first Run 3 OO run (to be updated once OO starts). + * @var RUN3OO_LAST Temporary upper bound for Run 3 OO runs. + */ namespace RunnumberRange { static const int RUN2PP_FIRST = 47286; @@ -12,7 +28,9 @@ namespace RunnumberRange static const int RUN3AUAU_FIRST = 66457; static const int RUN3AUAU_LAST = 78954; static const int RUN3PP_FIRST = 79146; // first beam data - static const int RUN3PP_LAST = 100000; + static const int RUN3PP_LAST = 81668; + static const int RUN3OO_FIRST = 82300; // TEMP (to be updated once OO starts) + static const int RUN3OO_LAST = 200000; } #endif diff --git a/offline/packages/CaloEmbedding/CombineTowerInfo.cc b/offline/packages/CaloEmbedding/CombineTowerInfo.cc new file mode 100644 index 0000000000..3e5150d194 --- /dev/null +++ b/offline/packages/CaloEmbedding/CombineTowerInfo.cc @@ -0,0 +1,99 @@ +#include "CombineTowerInfo.h" + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +//____________________________________________________________________________ +CombineTowerInfo::CombineTowerInfo(const std::string& name) + : SubsysReco(name) +{ +} + +//____________________________________________________________________________ +int CombineTowerInfo::InitRun(PHCompositeNode* topNode) +{ + if (m_inputNodeA.empty() || m_inputNodeB.empty() || m_outputNode.empty()) + { + throw std::runtime_error("CombineTowerInfo: input/output node names not set"); + } + + CreateNodes(topNode); + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________ +void CombineTowerInfo::CreateNodes(PHCompositeNode* topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode* dstNode = + dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + + if (!dstNode) + { + throw std::runtime_error("CombineTowerInfo: DST node not found"); + } + + PHCompositeNode *DetNode = dynamic_cast(iter.findFirst("PHCompositeNode", m_detector)); + + m_towersA = findNode::getClass(topNode, m_inputNodeA); + m_towersB = findNode::getClass(topNode, m_inputNodeB); + + if (!m_towersB) + { + std::cout << "CombineTowerInfo: " <(dstNode, m_outputNode); + if (!m_towersOut) + { + m_towersOut = + dynamic_cast(m_towersA->CloneMe()); + + auto* node = new PHIODataNode( + m_towersOut, m_outputNode, "PHObject"); + + DetNode->addNode(node); + } + + if (m_towersA->size() != m_towersB->size()) + { + throw std::runtime_error("CombineTowerInfo: input containers have different sizes"); + } +} + +//____________________________________________________________________________ +int CombineTowerInfo::process_event(PHCompositeNode* /*topNode*/) +{ + const unsigned int ntowers = m_towersA->size(); + + for (unsigned int ich = 0; ich < ntowers; ++ich) + { + TowerInfo* towerA = m_towersA->get_tower_at_channel(ich); + TowerInfo* towerB = m_towersB->get_tower_at_channel(ich); + TowerInfo* towerO = m_towersOut->get_tower_at_channel(ich); + + towerO->copy_tower(towerA); + + const float e_sum = towerA->get_energy() + towerB->get_energy(); + towerO->set_energy(e_sum); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + diff --git a/offline/packages/CaloEmbedding/CombineTowerInfo.h b/offline/packages/CaloEmbedding/CombineTowerInfo.h new file mode 100644 index 0000000000..ab96a918e6 --- /dev/null +++ b/offline/packages/CaloEmbedding/CombineTowerInfo.h @@ -0,0 +1,39 @@ +#ifndef COMBINETOWERINFO_H +#define COMBINETOWERINFO_H + +#include + +#include + +class PHCompositeNode; +class TowerInfoContainer; + +class CombineTowerInfo : public SubsysReco +{ + public: + explicit CombineTowerInfo(const std::string& name = "CombineTowerInfo"); + ~CombineTowerInfo() override = default; + + int InitRun(PHCompositeNode* topNode) override; + int process_event(PHCompositeNode* topNode) override; + + void set_inputNodeA(const std::string& name) { m_inputNodeA = name; } + void set_inputNodeB(const std::string& name) { m_inputNodeB = name; } + void set_outputNode(const std::string& name) { m_outputNode = name; } + void set_detector(const std::string& name) { m_detector = name; } + + private: + void CreateNodes(PHCompositeNode* topNode); + + std::string m_inputNodeA; + std::string m_inputNodeB; + std::string m_outputNode; + std::string m_detector; + + TowerInfoContainer* m_towersA{nullptr}; + TowerInfoContainer* m_towersB{nullptr}; + TowerInfoContainer* m_towersOut{nullptr}; +}; + +#endif + diff --git a/offline/packages/CaloEmbedding/CopyIODataNodes.cc b/offline/packages/CaloEmbedding/CopyIODataNodes.cc index 0d4d4536ff..08428dccfe 100644 --- a/offline/packages/CaloEmbedding/CopyIODataNodes.cc +++ b/offline/packages/CaloEmbedding/CopyIODataNodes.cc @@ -7,6 +7,9 @@ #include +#include +#include + #include #include @@ -57,6 +60,10 @@ int CopyIODataNodes::InitRun(PHCompositeNode *topNode) { CreateSyncObject(topNode, se->topNode()); } + if (m_CopyTowerInfoFlag) + { + CreateTowerInfo(topNode, se->topNode()); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -89,6 +96,10 @@ int CopyIODataNodes::process_event(PHCompositeNode *topNode) { CopySyncObject(topNode, se->topNode()); } + if (m_CopyTowerInfoFlag) + { + CopyTowerInfo(topNode, se->topNode()); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -293,6 +304,29 @@ void CopyIODataNodes::CopyMinimumBiasInfo(PHCompositeNode *from_topNode, PHCompo return; } +void CopyIODataNodes::CopyTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) +{ + TowerInfoContainer *from_towerInfo = findNode::getClass(from_topNode, from_towerInfo_name); + TowerInfoContainer *to_towerInfo = findNode::getClass( to_topNode, to_towerInfo_name); + unsigned int ntowers = from_towerInfo->size(); + for (unsigned int ch = 0; ch < ntowers; ++ch) + { + TowerInfo *from_tow = from_towerInfo->get_tower_at_channel(ch); + to_towerInfo->get_tower_at_channel(ch)->copy_tower(from_tow); + } + + if (Verbosity() > 0) + { + std::cout << "From TowerInfoContainer identify()" << std::endl; + from_towerInfo->identify(); + std::cout << "To TowerInfoCOntainer identify()" << std::endl; + to_towerInfo->identify(); + } + + return; +} + + void CopyIODataNodes::CreateMbdOut(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) { @@ -330,6 +364,36 @@ void CopyIODataNodes::CreateMbdOut(PHCompositeNode *from_topNode, PHCompositeNod } +void CopyIODataNodes::CreateTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) +{ + std::cout << "copying tower info" << std::endl; + TowerInfoContainer *from_towerInfo = findNode::getClass(from_topNode, from_towerInfo_name); + if (!from_towerInfo) + { + std::cout << "Could not locate TowerInfoContainer on " << from_topNode->getName() << std::endl; + m_CopyTowerInfoFlag = false; + return; + } + TowerInfoContainer *to_towerInfo = findNode::getClass(to_topNode, to_towerInfo_name); + if (!to_towerInfo) + { + PHNodeIterator iter(to_topNode); + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + dstNode = new PHCompositeNode("DST"); + to_topNode->addNode(dstNode); + } + to_towerInfo = dynamic_cast(from_towerInfo->CloneMe()); + PHIODataNode *newNode = new PHIODataNode(to_towerInfo, to_towerInfo_name, "PHObject"); + dstNode->addNode(newNode); + } + return; +} + + + + void CopyIODataNodes::CopyMbdOut(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) { MbdOut *from_mbdout = findNode::getClass(from_topNode, "MbdOut"); diff --git a/offline/packages/CaloEmbedding/CopyIODataNodes.h b/offline/packages/CaloEmbedding/CopyIODataNodes.h index 08626bdafb..5045792a2d 100644 --- a/offline/packages/CaloEmbedding/CopyIODataNodes.h +++ b/offline/packages/CaloEmbedding/CopyIODataNodes.h @@ -35,6 +35,13 @@ class CopyIODataNodes : public SubsysReco void CopyMbdOut(bool flag = true) { m_CopyMbdOutFlag = flag; } void CopyRunHeader(bool flag = true) { m_CopyRunHeaderFlag = flag; } void CopySyncObject(bool flag = true) { m_CopySyncObjectFlag = flag; } + void set_CopyTowerInfo(const std::string& set_from_towerInfo_name,const std::string& set_to_towerInfo_name) + { + from_towerInfo_name = set_from_towerInfo_name; + to_towerInfo_name = set_to_towerInfo_name; + m_CopyTowerInfoFlag = true; + return; + } private: void CreateCentralityInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); @@ -56,6 +63,8 @@ class CopyIODataNodes : public SubsysReco void CreateSyncObject(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); void CopySyncObject(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); + void CopyTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); + void CreateTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); bool m_CopyCentralityInfoFlag = true; bool m_CopyEventHeaderFlag = true; @@ -64,6 +73,10 @@ class CopyIODataNodes : public SubsysReco bool m_CopyMbdOutFlag = true; bool m_CopyRunHeaderFlag = true; bool m_CopySyncObjectFlag = true; + bool m_CopyTowerInfoFlag = false; + + std::string from_towerInfo_name = {}; + std::string to_towerInfo_name = {}; }; #endif // COPYIODATANODES_H diff --git a/offline/packages/CaloEmbedding/Makefile.am b/offline/packages/CaloEmbedding/Makefile.am index 9731b33cb8..f9dd1faa22 100644 --- a/offline/packages/CaloEmbedding/Makefile.am +++ b/offline/packages/CaloEmbedding/Makefile.am @@ -13,6 +13,7 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ caloTowerEmbed.h \ CopyIODataNodes.h \ + CombineTowerInfo.h \ HepMCCollisionVertex.h lib_LTLIBRARIES = \ @@ -21,6 +22,7 @@ lib_LTLIBRARIES = \ libCaloEmbedding_la_SOURCES = \ caloTowerEmbed.cc \ CopyIODataNodes.cc \ + CombineTowerInfo.cc \ HepMCCollisionVertex.cc libCaloEmbedding_la_LIBADD = \ diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 632cd8161d..a84706599d 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -75,6 +75,14 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) WaveformProcessing->set_bitFlipRecovery(m_dobitfliprecovery); } + // Set functional fit parameters + if (_processingtype == CaloWaveformProcessing::FUNCFIT) + { + WaveformProcessing->set_funcfit_type(m_funcfit_type); + WaveformProcessing->set_powerlaw_params(m_powerlaw_power, m_powerlaw_decay); + WaveformProcessing->set_doubleexp_params(m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, m_doubleexp_ratio); + } + if (m_dettype == CaloTowerDefs::CEMC) { m_detector = "CEMC"; @@ -476,6 +484,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) towerinfo->set_pedestal(processed_waveforms.at(idx).at(2)); towerinfo->set_chi2(processed_waveforms.at(idx).at(3)); bool SZS = isSZS(processed_waveforms.at(idx).at(1), processed_waveforms.at(idx).at(3)); + if (processed_waveforms.at(idx).at(4) == 0) { towerinfo->set_isRecovered(false); diff --git a/offline/packages/CaloReco/CaloTowerBuilder.h b/offline/packages/CaloReco/CaloTowerBuilder.h index cb22806903..0fc5694638 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.h +++ b/offline/packages/CaloReco/CaloTowerBuilder.h @@ -94,6 +94,26 @@ class CaloTowerBuilder : public SubsysReco m_dobitfliprecovery = dobitfliprecovery; } + // Functional fit options: 0 = PowerLawExp, 1 = PowerLawDoubleExp + void set_funcfit_type(int type) + { + m_funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + m_powerlaw_power = power; + m_powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + m_doubleexp_power = power; + m_doubleexp_peaktime1 = peaktime1; + m_doubleexp_peaktime2 = peaktime2; + m_doubleexp_ratio = ratio; + } + void set_tbt_softwarezerosuppression(const std::string &url) { m_zsURL = url; @@ -150,6 +170,15 @@ class CaloTowerBuilder : public SubsysReco std::string m_directURL; std::string m_zsURL; std::string m_zs_fieldname{"zs_threshold"}; + + // Functional fit parameters + int m_funcfit_type{1}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp + double m_powerlaw_power{4.0}; + double m_powerlaw_decay{1.5}; + double m_doubleexp_power{2.0}; + double m_doubleexp_peaktime1{5.0}; + double m_doubleexp_peaktime2{5.0}; + double m_doubleexp_ratio{0.3}; }; #endif // CALOTOWERBUILDER_H diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index f5163275a0..266072dfbe 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -21,7 +22,7 @@ #include #include -static ROOT::TThreadExecutor *t = new ROOT::TThreadExecutor(1);// NOLINT(misc-use-anonymous-namespace) +static ROOT::TThreadExecutor *t = new ROOT::TThreadExecutor(1); // NOLINT(misc-use-anonymous-namespace) double CaloWaveformFitting::template_function(double *x, double *par) { Double_t v1 = (par[0] * h_template->Interpolate(x[0] - par[1])) + par[2]; @@ -619,3 +620,253 @@ float CaloWaveformFitting::psinc(float time, std::vector &vec_signal_samp return sum; } + +double CaloWaveformFitting::SignalShape_PowerLawExp(double *x, double *par) +{ + // par[0]: Amplitude + // par[1]: Sample Start (t0) + // par[2]: Power + // par[3]: Decay + // par[4]: Pedestal + double pedestal = par[4]; + if (x[0] < par[1]) + { + return pedestal; + } + double signal = par[0] * pow((x[0] - par[1]), par[2]) * exp(-(x[0] - par[1]) * par[3]); + return pedestal + signal; +} + +double CaloWaveformFitting::SignalShape_PowerLawDoubleExp(double *x, double *par) +{ + // par[0]: Amplitude + // par[1]: Sample Start (t0) + // par[2]: Power + // par[3]: Peak Time 1 + // par[4]: Pedestal + // par[5]: Amplitude ratio + // par[6]: Peak Time 2 + double pedestal = par[4]; + if (x[0] < par[1]) + { + return pedestal; + } + double signal = par[0] * pow((x[0] - par[1]), par[2]) * + (((1.0 - par[5]) / pow(par[3], par[2]) * exp(par[2])) * + exp(-(x[0] - par[1]) * (par[2] / par[3])) + + (par[5] / pow(par[6], par[2]) * exp(par[2])) * + exp(-(x[0] - par[1]) * (par[2] / par[6]))); + return pedestal + signal; +} + +std::vector> CaloWaveformFitting::calo_processing_funcfit(const std::vector> &chnlvector) +{ + std::vector> fit_values; + int nchnls = chnlvector.size(); + + for (int m = 0; m < nchnls; m++) + { + const std::vector &v = chnlvector.at(m); + int nsamples = v.size(); + + float amp = 0; + float time = 0; + float ped = 0; + float chi2 = std::numeric_limits::quiet_NaN(); + + // Handle zero-suppressed samples (2-sample case) + if (nsamples == _nzerosuppresssamples) + { + amp = v.at(1) - v.at(0); + time = std::numeric_limits::quiet_NaN(); + ped = v.at(0); + if (v.at(0) != 0 && v.at(1) == 0) + { + chi2 = 1000000; + } + fit_values.push_back({amp, time, ped, chi2, 0}); + continue; + } + + // Find peak position and estimate pedestal + float maxheight = 0; + int maxbin = 0; + for (int i = 0; i < nsamples; i++) + { + if (v.at(i) > maxheight) + { + maxheight = v.at(i); + maxbin = i; + } + } + + float pedestal = 1500; + if (maxbin > 4) + { + pedestal = 0.5 * (v.at(maxbin - 4) + v.at(maxbin - 5)); + } + else if (maxbin > 3) + { + pedestal = v.at(maxbin - 4); + } + else + { + pedestal = 0.5 * (v.at(nsamples - 3) + v.at(nsamples - 2)); + } + + // Software zero suppression check + if ((_bdosoftwarezerosuppression && v.at(6) - v.at(0) < _nsoftwarezerosuppression) || + (_maxsoftwarezerosuppression && maxheight - pedestal < _nsoftwarezerosuppression)) + { + amp = v.at(6) - v.at(0); + time = std::numeric_limits::quiet_NaN(); + ped = v.at(0); + if (v.at(0) != 0 && v.at(1) == 0) + { + chi2 = 1000000; + } + fit_values.push_back({amp, time, ped, chi2, 0}); + continue; + } + + // Create histogram for fitting + TH1F h("h_funcfit", "", nsamples, -0.5, nsamples - 0.5); + int ndata = 0; + for (int i = 0; i < nsamples; ++i) + { + if ((v.at(i) == 16383) && _handleSaturation) + { + continue; + } + h.SetBinContent(i + 1, v.at(i)); + h.SetBinError(i + 1, 1); + ndata++; + } + + // If too many saturated, use all data + if (ndata < (nsamples - 4)) + { + ndata = nsamples; + for (int i = 0; i < nsamples; ++i) + { + h.SetBinContent(i + 1, v.at(i)); + h.SetBinError(i + 1, 1); + } + } + + double fit_amp = 0; + double fit_time = 0; + double fit_ped = 0; + double chi2val = 0; + int npar = 0; + + if (m_funcfit_type == POWERLAWEXP) + { + // Create fit function with 5 parameters + TF1 f("f_powerlaw", SignalShape_PowerLawExp, 0, nsamples, 5); + npar = 5; + + // Set initial parameters + double risetime = m_powerlaw_power / m_powerlaw_decay; + double par[5]; + par[0] = maxheight - pedestal; // Amplitude + par[1] = maxbin - risetime; // t0 + par[1] = std::max(par[1], 0); + par[2] = m_powerlaw_power; // Power + par[3] = m_powerlaw_decay; // Decay + par[4] = pedestal; // Pedestal + + f.SetParameters(par); + f.SetParLimits(0, (maxheight - pedestal) * 0.5, (maxheight - pedestal) * 10); + f.SetParLimits(1, 0, nsamples); + f.SetParLimits(2, 0, 10.0); + f.SetParLimits(3, 0, 10.0); + f.SetParLimits(4, pedestal - std::abs(maxheight - pedestal), pedestal + std::abs(maxheight - pedestal)); + + // Perform fit + h.Fit(&f, "QRN0W", "", 0, nsamples); + + // Calculate peak amplitude and time from fit parameters + // Peak height is (p0 * Power(p2/p3, p2)) / exp(p2) + fit_amp = (f.GetParameter(0) * pow(f.GetParameter(2) / f.GetParameter(3), f.GetParameter(2))) / exp(f.GetParameter(2)); + // Peak time is t0 + power/decay + fit_time = f.GetParameter(1) + f.GetParameter(2) / f.GetParameter(3); + fit_ped = f.GetParameter(4); + + // Calculate chi2 + for (int i = 0; i < nsamples; i++) + { + if (h.GetBinContent(i + 1) > 0) + { + double diff = h.GetBinContent(i + 1) - f.Eval(i); + chi2val += diff * diff; + } + } + } + else // POWERLAWDOUBLEEXP + { + // Create fit function with 7 parameters + TF1 f("f_doubleexp", SignalShape_PowerLawDoubleExp, 0, nsamples, 7); + npar = 7; + + // Set initial parameters + double risetime = 2.0; + double par[7]; + par[0] = (maxheight - pedestal) * 0.7; // Amplitude + par[1] = maxbin - risetime; // t0 + par[1] = std::max(par[1], 0); + par[2] = m_doubleexp_power; // Power + par[3] = m_doubleexp_peaktime1; // Peak Time 1 + par[4] = pedestal; // Pedestal + par[5] = m_doubleexp_ratio; // Amplitude ratio + par[6] = m_doubleexp_peaktime2; // Peak Time 2 + + f.SetParameters(par); + f.SetParLimits(0, (maxheight - pedestal) * -1.5, (maxheight - pedestal) * 1.5); + f.SetParLimits(1, maxbin - 3 * risetime, maxbin + risetime); + f.SetParLimits(2, 1, 5.0); + f.SetParLimits(3, risetime * 0.5, risetime * 4); + f.SetParLimits(4, pedestal - std::abs(maxheight - pedestal), pedestal + std::abs(maxheight - pedestal)); + f.SetParLimits(5, 0, 1); + f.SetParLimits(6, risetime * 0.5, risetime * 4); + + // Perform fit + h.Fit(&f, "QRN0W", "", 0, nsamples); + + // Find peak by evaluating the function + double peakpos1 = f.GetParameter(3); + double peakpos2 = f.GetParameter(6); + double max_peakpos = f.GetParameter(1) + (peakpos1 > peakpos2 ? peakpos1 : peakpos2); + max_peakpos = std::min(max_peakpos, nsamples - 1); + + fit_time = f.GetMaximumX(f.GetParameter(1), max_peakpos); + fit_amp = f.Eval(fit_time) - f.GetParameter(4); + fit_ped = f.GetParameter(4); + + // Calculate chi2 + for (int i = 0; i < nsamples; i++) + { + if (h.GetBinContent(i + 1) > 0) + { + double diff = h.GetBinContent(i + 1) - f.Eval(i); + chi2val += diff * diff; + } + } + } + + int ndf = ndata - npar; + if (ndf > 0) + { + chi2val /= ndf; + } + else + { + chi2val = std::numeric_limits::quiet_NaN(); + } + + fit_values.push_back({static_cast(fit_amp), static_cast(fit_time), + static_cast(fit_ped), static_cast(chi2val), 0}); + } + + return fit_values; +} diff --git a/offline/packages/CaloReco/CaloWaveformFitting.h b/offline/packages/CaloReco/CaloWaveformFitting.h index 1a9f887305..648d6ab0fa 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.h +++ b/offline/packages/CaloReco/CaloWaveformFitting.h @@ -9,6 +9,12 @@ class TProfile; class CaloWaveformFitting { public: + enum FuncFitType + { + POWERLAWEXP = 0, + POWERLAWDOUBLEEXP = 1, + }; + CaloWaveformFitting() = default; ~CaloWaveformFitting(); @@ -61,9 +67,34 @@ class CaloWaveformFitting std::vector> calo_processing_templatefit(std::vector> chnlvector); static std::vector> calo_processing_fast(const std::vector> &chnlvector); std::vector> calo_processing_nyquist(const std::vector> &chnlvector); + std::vector> calo_processing_funcfit(const std::vector> &chnlvector); void initialize_processing(const std::string &templatefile); + // Power-law fit function: amplitude * (x-t0)^power * exp(-(x-t0)*decay) + pedestal + static double SignalShape_PowerLawExp(double *x, double *par); + // Double exponential power-law fit function + static double SignalShape_PowerLawDoubleExp(double *x, double *par); + + void set_funcfit_type(FuncFitType type) + { + m_funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + m_powerlaw_power = power; + m_powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + m_doubleexp_power = power; + m_doubleexp_peaktime1 = peaktime1; + m_doubleexp_peaktime2 = peaktime2; + m_doubleexp_ratio = ratio; + } + private: static void FastMax(float x0, float x1, float x2, float y0, float y1, float y2, float &xmax, float &ymax); std::vector NyquistInterpolation(std::vector &vec_signal_samples); @@ -97,5 +128,18 @@ class CaloWaveformFitting std::string url_template; std::string url_onnx; std::string m_model_name; + + // Functional fit type selector + FuncFitType m_funcfit_type{POWERLAWDOUBLEEXP}; + + // Power-law fit parameters + double m_powerlaw_power{4.0}; + double m_powerlaw_decay{1.5}; + + // Double exponential fit parameters + double m_doubleexp_power{2.0}; + double m_doubleexp_peaktime1{5.0}; + double m_doubleexp_peaktime2{5.0}; + double m_doubleexp_ratio{0.3}; }; #endif diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 4e51f71f45..057e427627 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -65,6 +65,19 @@ void CaloWaveformProcessing::initialize_processing() m_Fitter = new CaloWaveformFitting(); m_Fitter->initialize_processing(url_template); } + else if (m_processingtype == CaloWaveformProcessing::FUNCFIT) + { + m_Fitter = new CaloWaveformFitting(); + // Set functional fit type and parameters + m_Fitter->set_funcfit_type(static_cast(_funcfit_type)); + m_Fitter->set_powerlaw_params(_powerlaw_power, _powerlaw_decay); + m_Fitter->set_doubleexp_params(_doubleexp_power, _doubleexp_peaktime1, _doubleexp_peaktime2, _doubleexp_ratio); + if (_bdosoftwarezerosuppression) + { + m_Fitter->set_softwarezerosuppression(_bdosoftwarezerosuppression, _nsoftwarezerosuppression); + } + m_Fitter->set_handleSaturation(true); + } } std::vector> CaloWaveformProcessing::process_waveform(std::vector> waveformvector) @@ -91,6 +104,10 @@ std::vector> CaloWaveformProcessing::process_waveform(std::ve { fitresults = m_Fitter->calo_processing_nyquist(waveformvector); } + if (m_processingtype == CaloWaveformProcessing::FUNCFIT) + { + fitresults = m_Fitter->calo_processing_funcfit(waveformvector); + } return fitresults; } @@ -169,7 +186,7 @@ std::vector> CaloWaveformProcessing::calo_processing_ONNX(con { // downstream onnx does not have a static input vector API, // so we need to make a copy - std::vector vtmp(v); //NOLINT(performance-unnecessary-copy-initialization) + std::vector vtmp(v); // NOLINT(performance-unnecessary-copy-initialization) val = onnxInference(onnxmodule, vtmp, 1, onnxlib::n_input, onnxlib::n_output); unsigned int nvals = val.size(); for (unsigned int i = 0; i < nvals; i++) diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index 8a5a5bbbe6..b657459d6c 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -20,6 +20,7 @@ class CaloWaveformProcessing : public SubsysReco FAST = 3, NYQUIST = 4, TEMPLATE_NOSAT = 5, + FUNCFIT = 6, }; CaloWaveformProcessing() = default; @@ -75,6 +76,26 @@ class CaloWaveformProcessing : public SubsysReco _dobitfliprecovery = dobitfliprecovery; } + // Functional fit options: 0 = PowerLawExp, 1 = PowerLawDoubleExp + void set_funcfit_type(int type) + { + _funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + _powerlaw_power = power; + _powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + _doubleexp_power = power; + _doubleexp_peaktime1 = peaktime1; + _doubleexp_peaktime2 = peaktime2; + _doubleexp_ratio = ratio; + } + std::vector> process_waveform(std::vector> waveformvector); std::vector> calo_processing_ONNX(const std::vector> &chnlvector); @@ -108,6 +129,15 @@ class CaloWaveformProcessing : public SubsysReco std::string m_model_name{"CEMC_ONNX"}; std::array m_Onnx_factor{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; std::array m_Onnx_offset{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; + + // Functional fit parameters + int _funcfit_type{1}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp + double _powerlaw_power{4.0}; + double _powerlaw_decay{1.5}; + double _doubleexp_power{2.0}; + double _doubleexp_peaktime1{5.0}; + double _doubleexp_peaktime2{5.0}; + double _doubleexp_ratio{0.3}; }; #endif diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.cc b/offline/packages/CaloReco/PhotonClusterBuilder.cc index 263ae04ef0..edcf5f4418 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.cc +++ b/offline/packages/CaloReco/PhotonClusterBuilder.cc @@ -566,6 +566,7 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster photon->set_shower_shape_parameter("et3", showershape[2]); photon->set_shower_shape_parameter("et4", showershape[3]); photon->set_shower_shape_parameter("e11", e11); + photon->set_shower_shape_parameter("e22", showershape[8] + showershape[9] + showershape[10] + showershape[11]); photon->set_shower_shape_parameter("e33", e33); photon->set_shower_shape_parameter("e55", e55); photon->set_shower_shape_parameter("e77", e77); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 38b60d55ba..8c049f30d6 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -148,7 +148,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no tracks" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } if (!m_use_fake_pv) @@ -162,7 +162,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no vertices" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } } else @@ -174,10 +174,9 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no vertices" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } } - } createDecay(topNode, mother, vertex_kfparticle, daughters, intermediates, nPVs); diff --git a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc index 8fe89b5019..aeb01dee62 100644 --- a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc +++ b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc @@ -51,9 +51,9 @@ namespace PHGenFit const std::string& /*track_rep_choice*/, const bool doEventDisplay) : verbosity(1000) + , _tgeo_manager(new TGeoManager("Default", "Geane geometry")) , _doEventDisplay(doEventDisplay) { - _tgeo_manager = new TGeoManager("Default", "Geane geometry"); TGeoManager::Import(tgeo_file_name.data()); assert(field); @@ -73,26 +73,24 @@ namespace PHGenFit } // init fitter - if (fitter_choice.compare("KalmanFitterRefTrack") == 0) + if (fitter_choice == "KalmanFitterRefTrack") { _fitter = new genfit::KalmanFitterRefTrack(); } - else if (fitter_choice.compare("KalmanFitter") == 0) -// NOLINTNEXTLINE(bugprone-branch-clone) - { + else if (fitter_choice == "KalmanFitter") + { // NOLINT(bugprone-branch-clone) _fitter = new genfit::KalmanFitter(); } - else if (fitter_choice.compare("DafSimple") == 0) + else if (fitter_choice == "DafSimple") { _fitter = new genfit::DAF(false); } - else if (fitter_choice.compare("DafRef") == 0) + else if (fitter_choice == "DafRef") { _fitter = new genfit::DAF(true); } else -// NOLINTNEXTLINE(bugprone-branch-clone) - { + { // NOLINT(bugprone-branch-clone) _fitter = new genfit::KalmanFitter(); } @@ -235,7 +233,7 @@ namespace PHGenFit { _fitter = new genfit::KalmanFitterRefTrack(); } - if (fitter_choice == PHGenFit::Fitter::DafSimple) + else if (fitter_choice == PHGenFit::Fitter::DafSimple) { _fitter = new genfit::DAF(false); } @@ -289,19 +287,19 @@ namespace PHGenFit } // init fitter - if (fitter_choice.compare("KalmanFitterRefTrack") == 0) + if (fitter_choice == "KalmanFitterRefTrack") { _fitter = new genfit::KalmanFitterRefTrack(); } - else if (fitter_choice.compare("KalmanFitter") == 0) + else if (fitter_choice == "KalmanFitter") { _fitter = new genfit::KalmanFitter(); } - else if (fitter_choice.compare("DafSimple") == 0) + else if (fitter_choice == "DafSimple") { _fitter = new genfit::DAF(false); } - else if (fitter_choice.compare("DafRef") == 0) + else if (fitter_choice == "DafRef") { _fitter = new genfit::DAF(true); } diff --git a/offline/packages/PHGenFitPkg/PHGenFit/Track.cc b/offline/packages/PHGenFitPkg/PHGenFit/Track.cc index b1643e8cd0..0e06f15984 100644 --- a/offline/packages/PHGenFitPkg/PHGenFit/Track.cc +++ b/offline/packages/PHGenFitPkg/PHGenFit/Track.cc @@ -48,8 +48,8 @@ #define WILD_DOUBLE (-999999) -//#define _DEBUG_ -//#define _PRINT_MATRIX_ +// #define _DEBUG_ +// #define _PRINT_MATRIX_ #ifdef _DEBUG_ #include @@ -60,11 +60,10 @@ ofstream fout_matrix("matrix.txt"); namespace PHGenFit { Track::Track(genfit::AbsTrackRep* rep, const TVector3& seed_pos, const TVector3& seed_mom, const TMatrixDSym& seed_cov, const int v) + : verbosity(v) { // TODO Add input param check - verbosity = v; - genfit::MeasuredStateOnPlane seedMSoP(rep); seedMSoP.setPosMomCov(seed_pos, seed_mom, seed_cov); // const genfit::StateOnPlane seedSoP(seedMSoP); @@ -78,12 +77,12 @@ namespace PHGenFit } Track::Track(const PHGenFit::Track& t) + : verbosity(t.verbosity) + , _track(new genfit::Track(*(t.getGenFitTrack()))) + , _clusterIDs(t.get_cluster_IDs()) + , _clusterkeys(t.get_cluster_keys()) + , _vertex_id(t.get_vertex_id()) { - _track = new genfit::Track(*(t.getGenFitTrack())); - verbosity = t.verbosity; - _clusterIDs = t.get_cluster_IDs(); - _clusterkeys = t.get_cluster_keys(); - _vertex_id = t.get_vertex_id(); } int Track::addMeasurement(PHGenFit::Measurement* measurement) @@ -191,10 +190,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } double Track::extrapolateToLine(genfit::MeasuredStateOnPlane& state, const TVector3& line_point, const TVector3& line_direction, const int tr_point_id) const @@ -240,10 +237,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } double Track::extrapolateToCylinder(genfit::MeasuredStateOnPlane& state, double radius, const TVector3& line_point, const TVector3& line_direction, const int tr_point_id, const int direction) const @@ -361,10 +356,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } int Track::updateOneMeasurementKalman( @@ -385,7 +378,7 @@ namespace PHGenFit << std::endl; #endif - if (measurements.size() == 0) + if (measurements.empty()) { return -1; } @@ -437,11 +430,11 @@ namespace PHGenFit #endif continue; } - //#ifdef _DEBUG_ + // #ifdef _DEBUG_ // std::cout << __LINE__ << "\n ###################################################################"<Print(); // std::cout << __LINE__ << "\n ###################################################################"<getFittedState(true)); @@ -579,7 +572,7 @@ namespace PHGenFit // std::cout << err_phi << "\t" << err_z << "\t"; } #endif - for (auto rawMeasurement : rawMeasurements) + for (auto* rawMeasurement : rawMeasurements) { fi->addMeasurementsOnPlane( rawMeasurement->constructMeasurementsOnPlane(*state)); @@ -598,7 +591,7 @@ namespace PHGenFit << ": size of fi's MeasurementsOnPlane: " << measurements_on_plane.size() << std::endl; #endif - for (auto it : measurements_on_plane) + for (auto* it : measurements_on_plane) { const genfit::MeasurementOnPlane& mOnPlane = *it; // const double weight = mOnPlane.getWeight(); @@ -769,10 +762,7 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + return state; } double Track::get_chi2() const diff --git a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc index b519fd472e..224d172a24 100644 --- a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc +++ b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc @@ -20,6 +20,12 @@ TriggerDSTSkimmer::TriggerDSTSkimmer(const std::string &name) //____________________________________________________________________________.. int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) { + + if ((accepted_events >= max_accept) && use_max_accept) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + if (Verbosity() > 0) { if (ievent % 1000 == 0) @@ -45,7 +51,7 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) if (n_trigger_index != 0) { bool trigger_fired = false; - Gl1Packet *_gl1PacketInfo = findNode::getClass(topNode, "GL1Packet"); + Gl1Packet *_gl1PacketInfo = findNode::getClass(topNode, 14001); int gl1_trigger_vector_scaled[64] = {0}; if (_gl1PacketInfo) { @@ -61,6 +67,7 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) std::cout << "TriggerDSTSkimmer::process_event - Error - Can't find Trigger Node Gl1Packet therefore no selection can be made" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } + for (int it = 0; it < n_trigger_index; ++it) { if (gl1_trigger_vector_scaled[m_trigger_index[it]] == 1) @@ -74,5 +81,8 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + + accepted_events++; + return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h index dfb2c47a7c..9919df06b7 100644 --- a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h +++ b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h @@ -22,10 +22,22 @@ class TriggerDSTSkimmer : public SubsysReco void SetTrigger(std::vector &trigger_vector) {m_trigger_index = trigger_vector;} + void set_accept_max(int max_events) + { + use_max_accept = true; + max_accept = max_events; + return; + } + private: std::vector m_trigger_index{10}; int ievent{0}; + + int accepted_events{0}; + int max_accept{0}; + bool use_max_accept{false}; + }; #endif // JETDSTSKIMMER_H diff --git a/offline/packages/TrackingDiagnostics/TrackResiduals.cc b/offline/packages/TrackingDiagnostics/TrackResiduals.cc index 894dfb4d3c..d029ded711 100644 --- a/offline/packages/TrackingDiagnostics/TrackResiduals.cc +++ b/offline/packages/TrackingDiagnostics/TrackResiduals.cc @@ -1728,6 +1728,7 @@ void TrackResiduals::createBranches() m_clustree->Branch("timebucket", &m_timebucket, "m_timebucket/I"); m_clustree->Branch("segtype", &m_segtype, "m_segtype/I"); m_clustree->Branch("tile", &m_tileid, "m_tileid/I"); + m_clustree->Branch("layer", &m_scluslayer, "m_scluslayer/I"); m_tree = new TTree("residualtree", "A tree with track, cluster, and state info"); m_tree->Branch("run", &m_runnumber, "m_runnumber/I"); diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc index 6ee6d35395..abc91cbf52 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc @@ -31,10 +31,15 @@ #include #include +#include + +#include + #include #include #include +#include #include @@ -158,6 +163,7 @@ enum n_hit // NOLINT(readability-enum-initial-value, performance-enum-size) nhitcellID, nhitecell, nhitphibin, + nhitzbin, nhittbin, nhitphi, nhitr, @@ -330,7 +336,7 @@ int TrkrNtuplizer::Init(PHCompositeNode* /*unused*/) std::string str_vertex = {"vertexID:vx:vy:vz:ntracks:chi2:ndof"}; std::string str_event = {"event:seed:run:seg:job"}; - std::string str_hit = {"hitID:e:adc:layer:phielem:zelem:cellID:ecell:phibin:tbin:phi:r:x:y:z"}; + std::string str_hit = {"hitID:e:adc:layer:phielem:zelem:cellID:ecell:phibin:zbin:tbin:phi:r:x:y:z"}; std::string str_cluster = {"locx:locy:x:y:z:r:phi:eta:theta:phibin:tbin:fee:chan:sampa:ex:ey:ez:ephi:pez:pephi:e:adc:maxadc:thick:afac:bfac:dcal:layer:phielem:zelem:size:phisize:zsize:pedge:redge:ovlp:trackID:niter"}; std::string str_seed = {"seedID:siter:spt:sptot:seta:sphi:syxint:srzint:sxyslope:srzslope:sX0:sY0:sdZ0:sR0:scharge:sdedx:spidedx:skdedx:sprdedx:sn1pix:snsil:sntpc:snhits"}; std::string str_residual = {"alpha:beta:resphio:resphi:resz"}; @@ -560,6 +566,13 @@ int TrkrNtuplizer::InitRun(PHCompositeNode* topNode) } AdcClockPeriod = geom->GetFirstLayerCellGeom()->get_zstep(); + _inttGeom = findNode::getClass(topNode, "CYLINDERGEOM_INTT"); + if (_do_hit_eval && !_inttGeom) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERGEOM_INTT" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + // Create Fee Map auto* geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); { @@ -1464,6 +1477,11 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) fx_hit[n_hit::nhitphielem] = -666; fx_hit[n_hit::nhitzelem] = -666; + if (layer_local < 3) + { + fx_hit[n_hit::nhitphielem] = MvtxDefs::getStaveId(hitset_key); + fx_hit[n_hit::nhitzelem] = MvtxDefs::getChipId(hitset_key); + } if (layer_local >= 3 && layer_local < 7) { fx_hit[n_hit::nhitphielem] = InttDefs::getLadderPhiId(hitset_key); @@ -1485,18 +1503,65 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } } */ - fx_hit[n_hit::nhitphielem] = TpcDefs::getSectorId(hitset_key); - fx_hit[n_hit::nhitzelem] = TpcDefs::getSide(hitset_key); + //fx_hit[n_hit::nhitphielem] = TpcDefs::getSectorId(hitset_key); + //fx_hit[n_hit::nhitzelem] = TpcDefs::getSide(hitset_key); fx_hit[n_hit::nhitcellID] = 0; fx_hit[n_hit::nhitecell] = hit->getAdc(); fx_hit[n_hit::nhitphibin] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhittbin] = std::numeric_limits::quiet_NaN(); + fx_hit[n_hit::nhitzbin] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitphi] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitr] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitx] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhity] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitz] = std::numeric_limits::quiet_NaN(); + if (layer_local < _nlayers_maps) + { + int row = MvtxDefs::getRow(hit_key); + int col = MvtxDefs::getCol(hit_key); + + float localX = std::numeric_limits::quiet_NaN(); + float localZ = std::numeric_limits::quiet_NaN(); + SegmentationAlpide::detectorToLocal(row,col,localX,localZ); + Acts::Vector2 local(localX * Acts::UnitConstants::cm, localZ * Acts::UnitConstants::cm); + + const auto& surface = m_tGeometry->maps().getSiliconSurface(hitset_key); + auto glob = surface->localToGlobal(m_tGeometry->geometry().getGeoContext(), local, Acts::Vector3()); + + fx_hit[n_hit::nhitphibin] = row; + fx_hit[n_hit::nhitzbin] = col; + fx_hit[n_hit::nhittbin] = MvtxDefs::getStrobeId(hitset_key); + fx_hit[n_hit::nhitx] = glob.x() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhity] = glob.y() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitz] = glob.z() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitr] = sqrt(glob.x()*glob.x()+glob.y()*glob.y()) / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); + } + + if (layer_local >= _nlayers_maps && layer_local < _nlayers_intt) + { + int row = InttDefs::getRow(hit_key); + int col = InttDefs::getCol(hit_key); + + CylinderGeomIntt* intt_cylinder = dynamic_cast(_inttGeom->GetLayerGeom(layer_local)); + double localcoords[3]; + intt_cylinder->find_strip_center_localcoords(InttDefs::getLadderZId(hitset_key),row,col,localcoords); + + Acts::Vector2 local(localcoords[1]*Acts::UnitConstants::cm,localcoords[2]*Acts::UnitConstants::cm); + const auto& surface = m_tGeometry->maps().getSiliconSurface(hitset_key); + auto glob = surface->localToGlobal(m_tGeometry->geometry().getGeoContext(), local, Acts::Vector3()); + + fx_hit[n_hit::nhitphibin] = row; + fx_hit[n_hit::nhitzbin] = col; + fx_hit[n_hit::nhittbin] = InttDefs::getTimeBucketId(hitset_key); + fx_hit[n_hit::nhitx] = glob.x() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhity] = glob.y() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitz] = glob.z() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitr] = sqrt(glob.x()*glob.x()+glob.y()*glob.y()) / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); + } + if (layer_local >= _nlayers_maps + _nlayers_intt && layer_local < _nlayers_maps + _nlayers_intt + _nlayers_tpc) { PHG4TpcGeom* GeoLayer_local = _geom_container->GetLayerCellGeom(layer_local); @@ -1618,7 +1683,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } TrackSeedContainer* _tpc_seeds = findNode::getClass(topNode, "TpcTrackSeedContainer"); - if (!_tpc_seeds) + if (!_tpc_seeds && _do_tpcseed_eval) { std::cout << PHWHERE << " ERROR: Can't find " << "TpcTrackSeedContainer" << std::endl; @@ -1737,9 +1802,9 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } else { - pidedx = f_pion_minus->Eval(tptot); - kdedx = f_kaon_minus->Eval(tptot); - prdedx = f_proton_plus->Eval(tptot); + pidedx = f_pion_minus->Eval(-tptot); + kdedx = f_kaon_minus->Eval(-tptot); + prdedx = f_proton_minus->Eval(-tptot); } float n1pix = get_n1pix(tpcseed); float fx_seed[n_seed::seedsize] = {(float) trackID, 0, tpt, tptot, teta, tphi, xyint, rzint, xyslope, rzslope, tX0, tY0, tZ0, R0, charge, dedx, pidedx, kdedx, prdedx, n1pix, nsil_local, ntpc_local, nhits_local}; @@ -1933,9 +1998,9 @@ void TrkrNtuplizer::FillTrack(float fX[50], SvtxTrack* track, GlobalVertexMap* v } else { - fX[n_track::ntrknpidedx] = f_pion_minus->Eval(trptot); - fX[n_track::ntrknkdedx] = f_kaon_minus->Eval(trptot); - fX[n_track::ntrknprdedx] = f_proton_minus->Eval(trptot); + fX[n_track::ntrknpidedx] = f_pion_minus->Eval(-trptot); + fX[n_track::ntrknkdedx] = f_kaon_minus->Eval(-trptot); + fX[n_track::ntrknprdedx] = f_proton_minus->Eval(-trptot); } for (SvtxTrack::ConstClusterKeyIter iter_local = tpcseed->begin_cluster_keys(); diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h index 4e9df30628..ac341f1a45 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h @@ -35,6 +35,7 @@ class SvtxVertexMap; class TrkrClusterContainer; class ActsGeometry; class PHG4TpcGeomContainer; +class PHG4CylinderGeomContainer; class GlobalVertexMap; // class ClusterErrorPara; @@ -157,6 +158,7 @@ class TrkrNtuplizer : public SubsysReco SvtxTrackMap *_trackmap{nullptr}; ActsGeometry *_tgeometry{nullptr}; PHG4TpcGeomContainer *_geom_container{nullptr}; + PHG4CylinderGeomContainer *_inttGeom{nullptr}; float m_ZDC_coincidence{0}; float m_mbd_rate{0}; float m_rawzdc{0}; diff --git a/offline/packages/globalvertex/GlobalVertex.h b/offline/packages/globalvertex/GlobalVertex.h index 2a42abbba6..3124cea282 100644 --- a/offline/packages/globalvertex/GlobalVertex.h +++ b/offline/packages/globalvertex/GlobalVertex.h @@ -78,8 +78,8 @@ class GlobalVertex : public PHObject virtual float get_error(unsigned int /*i*/, unsigned int /*j*/) const { return std::numeric_limits::quiet_NaN(); } virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) { return; } - virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) { return; } + virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) { return; } virtual bool empty_vtxs() const { return true; } virtual size_t size_vtxs() const { return 0; } diff --git a/offline/packages/globalvertex/GlobalVertexReco.cc b/offline/packages/globalvertex/GlobalVertexReco.cc index 4f50bbc1b6..73681759cc 100644 --- a/offline/packages/globalvertex/GlobalVertexReco.cc +++ b/offline/packages/globalvertex/GlobalVertexReco.cc @@ -3,7 +3,7 @@ //#include "GlobalVertex.h" // for GlobalVertex, GlobalVe... #include "GlobalVertexMap.h" // for GlobalVertexMap #include "GlobalVertexMapv1.h" -#include "GlobalVertexv2.h" +#include "GlobalVertexv3.h" #include "MbdVertex.h" #include "MbdVertexMap.h" #include "CaloVertex.h" @@ -140,7 +140,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } // we have a matching pair - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::SVTX, svtx); @@ -193,7 +193,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } // we have a standalone SVTX vertex - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); @@ -243,7 +243,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::MBD, mbd); @@ -282,7 +282,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::CALO, calo); @@ -337,7 +337,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::CALO, calo); @@ -354,7 +354,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } else { - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::MBD, mbd); @@ -393,7 +393,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) tvertex->set_t(0); tvertex->set_t_err(0); // 0.1 - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->clone_insert_vtx(GlobalVertex::TRUTH, tvertex); globalmap->insert(vertex); if (truthmap) diff --git a/offline/packages/globalvertex/GlobalVertexv2.h b/offline/packages/globalvertex/GlobalVertexv2.h index 06a4d637f0..4c7a077df7 100644 --- a/offline/packages/globalvertex/GlobalVertexv2.h +++ b/offline/packages/globalvertex/GlobalVertexv2.h @@ -29,8 +29,22 @@ class GlobalVertexv2 : public GlobalVertex unsigned int get_id() const override { return _id; } void set_id(unsigned int id) override { _id = id; } - unsigned int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(unsigned int bco) override { _bco = bco; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_bco); + } + + void set_beam_crossing(short int bco) override + { + if (bco == short_int_max) + { + _bco = std::numeric_limits::max(); + return; + } + + const short int bco_ro = rollover_short(bco); + _bco = static_cast(bco_ro); + } float get_t() const override; float get_t_err() const override; @@ -65,6 +79,25 @@ class GlobalVertexv2 : public GlobalVertex GlobalVertex::VertexIter end_vertexes() override { return _vtxs.end(); } private: + static constexpr short int short_int_max = std::numeric_limits::max(); + + static short int rollover_short(short int bco) + { + if (bco == short_int_max) return short_int_max; + if (bco >= 0) return bco; + return static_cast(static_cast(short_int_max) + static_cast(bco)); + } + + static short int rollover_from_unsignedint(unsigned int bco) + { + if (bco == std::numeric_limits::max()) return short_int_max; + if (bco <= static_cast(short_int_max)) return static_cast(bco); + + const short int bco_ro = static_cast(static_cast(bco)); + if (bco_ro >= 0) return bco_ro; + return rollover_short(bco_ro); + } + unsigned int _id{std::numeric_limits::max()}; unsigned int _bco{std::numeric_limits::max()}; //< global bco std::map _vtxs; //< list of vtxs diff --git a/offline/packages/globalvertex/GlobalVertexv3.cc b/offline/packages/globalvertex/GlobalVertexv3.cc new file mode 100644 index 0000000000..1504a7cd3d --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3.cc @@ -0,0 +1,231 @@ +#include "GlobalVertexv3.h" + +#include + +GlobalVertexv3::GlobalVertexv3(const unsigned int id) + : _id(id) +{ +} + +GlobalVertexv3::~GlobalVertexv3() +{ + GlobalVertexv3::Reset(); +} + +void GlobalVertexv3::Reset() +{ + for (auto& _vtx : _vtxs) + { + for (const auto* vertex : _vtx.second) + { + delete vertex; + } + } + _vtxs.clear(); +} + +void GlobalVertexv3::identify(std::ostream& os) const +{ + os << "---GlobalVertexv3-----------------------" << std::endl; + + os << " list of vtx ids: " << std::endl; + for (ConstVertexIter iter = begin_vertexes(); iter != end_vertexes(); ++iter) + { + os << " Vertex type " << iter->first << " has " << iter->second.size() + << " vertices associated to it" << std::endl; + for (const auto& vertex : iter->second) + { + vertex->identify(); + } + } + + os << "-----------------------------------------------" << std::endl; +} + +int GlobalVertexv3::isValid() const +{ + if (_vtxs.empty()) + { + return 0; + } + return 1; +} + +void GlobalVertexv3::insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) +{ + auto it = _vtxs.find(type); + if (it == _vtxs.end()) + { + VertexVector vector; + vector.push_back(vertex); + _vtxs.insert(std::make_pair(type, vector)); + return; + } + + it->second.push_back(vertex); +} + +void GlobalVertexv3::clone_insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) +{ + auto it = _vtxs.find(type); + Vertex* clone = dynamic_cast(vertex->CloneMe()); + if (it == _vtxs.end()) + { + VertexVector vector; + vector.push_back(clone); + _vtxs.insert(std::make_pair(type, vector)); + return; + } + + it->second.push_back(clone); +} + +size_t GlobalVertexv3::count_vtxs(GlobalVertex::VTXTYPE type) const +{ + auto it = _vtxs.find(type); + if (it == _vtxs.end()) + { + return 0; + } + + return it->second.size(); +} + +float GlobalVertexv3::get_t() const +{ + auto it = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (it == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + return it->second[0]->get_t(); +} + +float GlobalVertexv3::get_t_err() const +{ + auto it = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (it == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + return it->second[0]->get_t_err(); +} + +float GlobalVertexv3::get_x() const { return get_position(0); } +float GlobalVertexv3::get_y() const { return get_position(1); } +float GlobalVertexv3::get_z() const { return get_position(2); } + +float GlobalVertexv3::get_position(unsigned int coor) const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + auto mbdit = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (mbdit == _vtxs.end()) + { + auto caloit = _vtxs.find(GlobalVertex::VTXTYPE::CALO); + if (caloit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + return caloit->second[0]->get_position(coor); + } + return mbdit->second[0]->get_position(coor); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float pos = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + pos = vertex->get_position(coor); + } + } + + return pos; +} + +float GlobalVertexv3::get_chisq() const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float chisq = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + chisq = vertex->get_chisq(); + } + } + + return chisq; +} + +unsigned int GlobalVertexv3::get_ndof() const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + return std::numeric_limits::max(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + unsigned int ndf = std::numeric_limits::max(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + ndf = vertex->get_ndof(); + } + } + + return ndf; +} + +float GlobalVertexv3::get_error(unsigned int i, unsigned int j) const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + auto mbdit = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (mbdit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + // MBD only has z error defined + if (i == 2 && j == 2) + { + return mbdit->second[0]->get_z_err(); + } + + return std::numeric_limits::quiet_NaN(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float err = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + err = vertex->get_error(i, j); + } + } + + return err; +} diff --git a/offline/packages/globalvertex/GlobalVertexv3.h b/offline/packages/globalvertex/GlobalVertexv3.h new file mode 100644 index 0000000000..c89e51e5c9 --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3.h @@ -0,0 +1,73 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_GLOBALVERTEXV3_H +#define GLOBALVERTEX_GLOBALVERTEXV3_H + +#include "GlobalVertex.h" + +#include // for size_t +#include +#include +#include + +class PHObject; + +class GlobalVertexv3 : public GlobalVertex +{ + public: + GlobalVertexv3() = default; + GlobalVertexv3(const unsigned int id); + ~GlobalVertexv3() override; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override; + int isValid() const override; + PHObject* CloneMe() const override { return new GlobalVertexv3(*this); } + + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + short int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(short int bco) override { _bco = bco; } + + float get_t() const override; + float get_t_err() const override; + float get_x() const override; + float get_y() const override; + float get_z() const override; + float get_chisq() const override; + unsigned int get_ndof() const override; + float get_position(unsigned int coor) const override; + float get_error(unsigned int i, unsigned int j) const override; + + // + // associated vertex methods + // + bool empty_vtxs() const override { return _vtxs.empty(); } + size_t size_vtxs() const override { return _vtxs.size(); } + size_t count_vtxs(GlobalVertex::VTXTYPE type) const override; + + void clear_vtxs() override { _vtxs.clear(); } + void insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) override; + void clone_insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) override; + size_t erase_vtxs(GlobalVertex::VTXTYPE type) override { return _vtxs.erase(type); } + void erase_vtxs(GlobalVertex::VertexIter iter) override { _vtxs.erase(iter); } + + GlobalVertex::ConstVertexIter begin_vertexes() const override { return _vtxs.begin(); } + GlobalVertex::ConstVertexIter find_vertexes(GlobalVertex::VTXTYPE type) const override { return _vtxs.find(type); } + GlobalVertex::ConstVertexIter end_vertexes() const override { return _vtxs.end(); } + + GlobalVertex::VertexIter begin_vertexes() override { return _vtxs.begin(); } + GlobalVertex::VertexIter find_vertexes(GlobalVertex::VTXTYPE type) override { return _vtxs.find(type); } + GlobalVertex::VertexIter end_vertexes() override { return _vtxs.end(); } + + private: + unsigned int _id{std::numeric_limits::max()}; + short int _bco{std::numeric_limits::max()}; //< global bco (signed short) + std::map _vtxs; //< list of vtxs + + ClassDefOverride(GlobalVertexv3, 3); +}; + +#endif diff --git a/offline/packages/globalvertex/GlobalVertexv3LinkDef.h b/offline/packages/globalvertex/GlobalVertexv3LinkDef.h new file mode 100644 index 0000000000..8cd2f1abf7 --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class GlobalVertexv3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/Makefile.am b/offline/packages/globalvertex/Makefile.am index 5cedef884d..0ff0587389 100644 --- a/offline/packages/globalvertex/Makefile.am +++ b/offline/packages/globalvertex/Makefile.am @@ -30,17 +30,20 @@ pkginclude_HEADERS = \ GlobalVertex.h \ GlobalVertexv1.h \ GlobalVertexv2.h \ + GlobalVertexv3.h \ GlobalVertexMap.h \ GlobalVertexMapv1.h \ GlobalVertexReco.h \ MbdVertex.h \ MbdVertexv1.h \ MbdVertexv2.h \ + MbdVertexv3.h \ MbdVertexMap.h \ MbdVertexMapv1.h \ SvtxVertex.h \ SvtxVertex_v1.h \ SvtxVertex_v2.h \ + SvtxVertex_v3.h \ SvtxVertexMap.h \ SvtxVertexMap_v1.h \ TruthVertex.h \ @@ -57,16 +60,19 @@ ROOTDICTS = \ GlobalVertex_Dict.cc \ GlobalVertexv1_Dict.cc \ GlobalVertexv2_Dict.cc \ + GlobalVertexv3_Dict.cc \ GlobalVertexMap_Dict.cc \ GlobalVertexMapv1_Dict.cc \ MbdVertex_Dict.cc \ MbdVertexv1_Dict.cc \ MbdVertexv2_Dict.cc \ + MbdVertexv3_Dict.cc \ MbdVertexMap_Dict.cc \ MbdVertexMapv1_Dict.cc \ SvtxVertex_Dict.cc \ SvtxVertex_v1_Dict.cc \ SvtxVertex_v2_Dict.cc \ + SvtxVertex_v3_Dict.cc \ SvtxVertexMap_Dict.cc \ SvtxVertexMap_v1_Dict.cc \ TruthVertex_Dict.cc \ @@ -87,15 +93,18 @@ libglobalvertex_io_la_SOURCES = \ GlobalVertex.cc \ GlobalVertexv1.cc \ GlobalVertexv2.cc \ + GlobalVertexv3.cc \ GlobalVertexMap.cc \ GlobalVertexMapv1.cc \ MbdVertexv1.cc \ MbdVertexv2.cc \ + MbdVertexv3.cc \ MbdVertexMap.cc \ MbdVertexMapv1.cc \ SvtxVertex.cc \ SvtxVertex_v1.cc \ SvtxVertex_v2.cc \ + SvtxVertex_v3.cc \ SvtxVertexMap.cc \ SvtxVertexMap_v1.cc \ TruthVertex.cc \ diff --git a/offline/packages/globalvertex/MbdVertex.h b/offline/packages/globalvertex/MbdVertex.h index 6d0900b768..ed8d18e1d8 100644 --- a/offline/packages/globalvertex/MbdVertex.h +++ b/offline/packages/globalvertex/MbdVertex.h @@ -36,8 +36,12 @@ class MbdVertex : public Vertex virtual float get_z_err() const override { return std::numeric_limits::quiet_NaN(); } virtual void set_z_err(float) override {} - virtual unsigned int get_beam_crossing() const override { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) override {} + virtual short int get_beam_crossing() const override + { + return std::numeric_limits::max(); + } + virtual void set_beam_crossing(short int) override {} + virtual void set_bbc_ns(int, int, float, float) override {} virtual int get_bbc_npmt(int) const override { return std::numeric_limits::max(); } diff --git a/offline/packages/globalvertex/MbdVertexv2.h b/offline/packages/globalvertex/MbdVertexv2.h index bee34059e4..3b3482ed4f 100644 --- a/offline/packages/globalvertex/MbdVertexv2.h +++ b/offline/packages/globalvertex/MbdVertexv2.h @@ -44,12 +44,56 @@ class MbdVertexv2 : public MbdVertex float get_position(unsigned int coor) const override; - unsigned int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(unsigned int bco) override { _bco = bco; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_bco); + } + void set_beam_crossing(short int bco) override + { + if (bco == short_int_max) + { + _bco = std::numeric_limits::max(); + return; + } + + const short int bco_ro = rollover_short(bco); + _bco = static_cast(bco_ro); + } private: + static constexpr short int short_int_max = std::numeric_limits::max(); // 32767 + + static short int rollover_short(short int bco) + { + if (bco == short_int_max) return short_int_max; + if (bco >= 0) return bco; + + const int bco_ro = static_cast(short_int_max) + static_cast(bco); // bco negative + return static_cast(bco_ro); + } + + static short int rollover_from_unsignedint(unsigned int bco) + { + // if unsigned int max, return short int max + if (bco == std::numeric_limits::max()) + { + return short_int_max; + } + + // common case: [0, 32767] + if (bco <= static_cast(short_int_max)) + { + return static_cast(bco); + } + + const short int bco_ro = static_cast(static_cast(bco)); + if (bco_ro >= 0) return bco_ro; + + return rollover_short(bco_ro); + } + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container - unsigned int _bco{std::numeric_limits::max()}; //< global bco + unsigned int _bco{std::numeric_limits::max()}; //< global bco (legacy storage) float _t{std::numeric_limits::quiet_NaN()}; //< collision time float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty float _z{std::numeric_limits::quiet_NaN()}; //< collision position z diff --git a/offline/packages/globalvertex/MbdVertexv3.cc b/offline/packages/globalvertex/MbdVertexv3.cc new file mode 100644 index 0000000000..9c76f521a3 --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3.cc @@ -0,0 +1,60 @@ +#include "MbdVertexv3.h" + +#include +#include + +void MbdVertexv3::identify(std::ostream& os) const +{ + os << "---MbdVertexv3--------------------------------" << std::endl; + os << "vertexid: " << get_id() << std::endl; + os << " t = " << get_t() << " +/- " << get_t_err() << std::endl; + os << " z = " << get_z() << " +/- " << get_z_err() << std::endl; + os << " bco = " << get_beam_crossing() << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int MbdVertexv3::isValid() const +{ + if (_id == std::numeric_limits::max()) + { + return 0; + } + if (std::isnan(_t)) + { + return 0; + } + if (std::isnan(_t_err)) + { + return 0; + } + if (std::isnan(_z)) + { + return 0; + } + if (std::isnan(_z_err)) + { + return 0; + } + + return 1; +} + +float MbdVertexv3::get_position(unsigned int coor) const +{ + if (coor == 0) + { + return get_x(); + } + if (coor == 1) + { + return get_y(); + } + if (coor == 2) + { + return get_z(); + } + + return std::numeric_limits::quiet_NaN(); +} diff --git a/offline/packages/globalvertex/MbdVertexv3.h b/offline/packages/globalvertex/MbdVertexv3.h new file mode 100644 index 0000000000..7d59c82d79 --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3.h @@ -0,0 +1,60 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_MBDVERTEXV3_H +#define GLOBALVERTEX_MBDVERTEXV3_H + +#include "MbdVertex.h" + +#include +#include + +class MbdVertexv3 : public MbdVertex +{ + public: + MbdVertexv3() = default; + ~MbdVertexv3() override = default; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = MbdVertexv3(); } + int isValid() const override; + PHObject* CloneMe() const override { return new MbdVertexv3(*this); } + + // vertex info + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + float get_t() const override { return _t; } + void set_t(float t) override { _t = t; } + + float get_t_err() const override { return _t_err; } + void set_t_err(float t_err) override { _t_err = t_err; } + + // Return 0 for now, can implement beam spot + float get_x() const override { return 0; } + float get_y() const override { return 0; } + + float get_z() const override { return _z; } + void set_z(float z) override { _z = z; } + + float get_z_err() const override { return _z_err; } + void set_z_err(float z_err) override { _z_err = z_err; } + + float get_position(unsigned int coor) const override; + + // beam crossing methods (v3: native signed short storage) + short int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(short int bco) override { _bco = bco; } + + private: + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container + short int _bco{std::numeric_limits::max()}; //< global bco (signed short) + float _t{std::numeric_limits::quiet_NaN()}; //< collision time + float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty + float _z{std::numeric_limits::quiet_NaN()}; //< collision position z + float _z_err{std::numeric_limits::quiet_NaN()}; //< collision position z uncertainty + + ClassDefOverride(MbdVertexv3, 1); +}; + +#endif diff --git a/offline/packages/globalvertex/MbdVertexv3LinkDef.h b/offline/packages/globalvertex/MbdVertexv3LinkDef.h new file mode 100644 index 0000000000..b55e4bf42d --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class MbdVertexv3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/SvtxVertex_v2.h b/offline/packages/globalvertex/SvtxVertex_v2.h index 24ccbfc0ca..32d19eda66 100644 --- a/offline/packages/globalvertex/SvtxVertex_v2.h +++ b/offline/packages/globalvertex/SvtxVertex_v2.h @@ -54,8 +54,21 @@ class SvtxVertex_v2 : public SvtxVertex float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar - unsigned int get_beam_crossing() const override { return _beamcrossing; } - void set_beam_crossing(unsigned int cross) override { _beamcrossing = cross; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_beamcrossing); + } + void set_beam_crossing(short int cross) override + { + if (cross == short_int_max) + { + _beamcrossing = std::numeric_limits::max(); + return; + } + + const short int cross_ro = rollover_short(cross); + _beamcrossing = static_cast(cross_ro); + } // // associated track ids methods @@ -73,6 +86,37 @@ class SvtxVertex_v2 : public SvtxVertex TrackIter end_tracks() override { return _track_ids.end(); } private: + static constexpr short int short_int_max = std::numeric_limits::max(); // 32767 + // for unsigned int to short int conversion (rollover) + static short int rollover_short(short int cross) + { + if (cross == short_int_max) return short_int_max; + if (cross >= 0) return cross; + + const int cross_ro = static_cast(short_int_max) + static_cast(cross); // cross negative + return static_cast(cross_ro); + } + + static short int rollover_from_unsignedint(unsigned int cross) + { + // if unsigned int max, return short int max + if (cross == std::numeric_limits::max()) + { + return short_int_max; + } + + // Common case: [0, 32767] + if (cross <= static_cast(short_int_max)) + { + return static_cast(cross); + } + + const short int cross_ro = static_cast(static_cast(cross)); + if (cross_ro >= 0) return cross_ro; + + return rollover_short(cross_ro); + } + unsigned int covar_index(unsigned int i, unsigned int j) const; unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container diff --git a/offline/packages/globalvertex/SvtxVertex_v3.cc b/offline/packages/globalvertex/SvtxVertex_v3.cc new file mode 100644 index 0000000000..731a2c841f --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3.cc @@ -0,0 +1,113 @@ +#include "SvtxVertex_v3.h" + +#include +#include +#include +#include // for swap + +SvtxVertex_v3::SvtxVertex_v3() +{ + std::fill(std::begin(_pos), std::end(_pos), std::numeric_limits::quiet_NaN()); + std::fill(std::begin(_err), std::end(_err), std::numeric_limits::quiet_NaN()); +} + +void SvtxVertex_v3::identify(std::ostream& os) const +{ + os << "---SvtxVertex_v3--------------------" << std::endl; + os << "vertexid: " << get_id() << std::endl; + + os << " t0 = " << get_t() << std::endl; + os << " beam crossing = " << get_beam_crossing() << std::endl; + os << " (x,y,z) = (" << get_position(0); + os << ", " << get_position(1) << ", "; + os << get_position(2) << ") cm" << std::endl; + + os << " chisq = " << get_chisq() << ", "; + os << " ndof = " << get_ndof() << std::endl; + + os << " ( "; + os << get_error(0, 0) << " , "; + os << get_error(0, 1) << " , "; + os << get_error(0, 2) << " )" << std::endl; + os << " err = ( "; + os << get_error(1, 0) << " , "; + os << get_error(1, 1) << " , "; + os << get_error(1, 2) << " )" << std::endl; + os << " ( "; + os << get_error(2, 0) << " , "; + os << get_error(2, 1) << " , "; + os << get_error(2, 2) << " )" << std::endl; + + os << " list of tracks ids: "; + for (ConstTrackIter iter = begin_tracks(); iter != end_tracks(); ++iter) + { + os << *iter << " "; + } + os << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int SvtxVertex_v3::isValid() const +{ + if (_id == std::numeric_limits::max()) + { + return 0; + } + if (std::isnan(_t0)) + { + return 0; + } + if (std::isnan(_chisq)) + { + return 0; + } + if (_ndof == std::numeric_limits::max()) + { + return 0; + } + + for (float _po : _pos) + { + if (std::isnan(_po)) + { + return 0; + } + } + for (int j = 0; j < 3; ++j) + { + for (int i = j; i < 3; ++i) + { + if (std::isnan(get_error(i, j))) + { + return 0; + } + } + } + if (_track_ids.empty()) + { + return 0; + } + return 1; +} + +void SvtxVertex_v3::set_error(unsigned int i, unsigned int j, float value) +{ + _err[covar_index(i, j)] = value; + return; +} + +float SvtxVertex_v3::get_error(unsigned int i, unsigned int j) const +{ + return _err[covar_index(i, j)]; +} + +unsigned int SvtxVertex_v3::covar_index(unsigned int i, unsigned int j) const +{ + if (i > j) + { + std::swap(i, j); + } + return i + 1 + (j + 1) * (j) / 2 - 1; +} diff --git a/offline/packages/globalvertex/SvtxVertex_v3.h b/offline/packages/globalvertex/SvtxVertex_v3.h new file mode 100644 index 0000000000..74a75d90ea --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3.h @@ -0,0 +1,89 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_SVTXVERTEXV3_H +#define GLOBALVERTEX_SVTXVERTEXV3_H + +#include "SvtxVertex.h" + +#include // for size_t +#include +#include +#include + +class PHObject; + +class SvtxVertex_v3 : public SvtxVertex +{ + public: + SvtxVertex_v3(); + ~SvtxVertex_v3() override {} + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = SvtxVertex_v3(); } + int isValid() const override; + PHObject* CloneMe() const override { return new SvtxVertex_v3(*this); } + + // vertex info + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + float get_t() const override { return _t0; } + void set_t(float t0) override { _t0 = t0; } + + float get_x() const override { return _pos[0]; } + void set_x(float x) override { _pos[0] = x; } + + float get_y() const override { return _pos[1]; } + void set_y(float y) override { _pos[1] = y; } + + float get_z() const override { return _pos[2]; } + void set_z(float z) override { _pos[2] = z; } + + float get_chisq() const override { return _chisq; } + void set_chisq(float chisq) override { _chisq = chisq; } + + unsigned int get_ndof() const override { return _ndof; } + void set_ndof(unsigned int ndof) override { _ndof = ndof; } + + float get_position(unsigned int coor) const override { return _pos[coor]; } + void set_position(unsigned int coor, float xi) override { _pos[coor] = xi; } + + float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar + void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar + + // v3 uses signed short + short int get_beam_crossing() const override { return _beamcrossing; } + void set_beam_crossing(short int cross) override { _beamcrossing = cross; } + + // + // associated track ids methods + // + void clear_tracks() override { _track_ids.clear(); } + bool empty_tracks() override { return _track_ids.empty(); } + size_t size_tracks() const override { return _track_ids.size(); } + void insert_track(unsigned int trackid) override { _track_ids.insert(trackid); } + size_t erase_track(unsigned int trackid) override { return _track_ids.erase(trackid); } + ConstTrackIter begin_tracks() const override { return _track_ids.begin(); } + ConstTrackIter find_track(unsigned int trackid) const override { return _track_ids.find(trackid); } + ConstTrackIter end_tracks() const override { return _track_ids.end(); } + TrackIter begin_tracks() override { return _track_ids.begin(); } + TrackIter find_track(unsigned int trackid) override { return _track_ids.find(trackid); } + TrackIter end_tracks() override { return _track_ids.end(); } + + private: + unsigned int covar_index(unsigned int i, unsigned int j) const; + + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container + float _t0{std::numeric_limits::quiet_NaN()}; //< collision time + float _pos[3]{}; //< collision position x,y,z + float _chisq{std::numeric_limits::quiet_NaN()}; //< vertex fit chisq + unsigned int _ndof{std::numeric_limits::max()}; //< degrees of freedom + float _err[6]{}; //< error covariance matrix (packed storage) (+/- cm^2) + std::set _track_ids; //< list of track ids + short int _beamcrossing{std::numeric_limits::max()}; + + ClassDefOverride(SvtxVertex_v3, 3); +}; + +#endif diff --git a/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h b/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h new file mode 100644 index 0000000000..7b6506845d --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class SvtxVertex_v3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/Vertex.h b/offline/packages/globalvertex/Vertex.h index 7bbfa5f381..e475bfb95d 100644 --- a/offline/packages/globalvertex/Vertex.h +++ b/offline/packages/globalvertex/Vertex.h @@ -62,8 +62,8 @@ class Vertex : public PHObject virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) {} // beam crossing methods - virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) {} + virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) {} // bbcvertex methods virtual void set_bbc_ns(int, int, float, float) {} diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 9823d337f6..78a930a8a0 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -14,6 +14,10 @@ #include #include +#include +#include +#include + #include #include @@ -52,9 +56,57 @@ DetermineTowerBackground::DetermineTowerBackground(const std::string &name) int DetermineTowerBackground::InitRun(PHCompositeNode *topNode) { + if (_do_flow == 4) + { + if (Verbosity()) + { + std::cout << "Loading the average calo v2" << std::endl; + } + if (LoadCalibrations()) + { + std::cout << "Load calibrations failed." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + } + return CreateNode(topNode); } +int DetermineTowerBackground::LoadCalibrations() +{ + + CDBTTree *cdbtree_calo_v2 = nullptr; + + std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); + if (m_overwrite_average_calo_v2) + { + calibdir = m_overwrite_average_calo_v2_path; + } + + if (calibdir.empty()) + { + std::cout << "Could not find filename for calo average v2, exiting" << std::endl; + exit(-1); + } + + cdbtree_calo_v2 = new CDBTTree(calibdir); + + + cdbtree_calo_v2->LoadCalibrations(); + + _CENTRALITY_V2.assign(100,0); + + for (int icent = 0; icent < 100; icent++) + { + _CENTRALITY_V2[icent] = cdbtree_calo_v2->GetFloatValue(icent, "jet_calo_v2"); + } + + delete cdbtree_calo_v2; + + return Fun4AllReturnCodes::EVENT_OK; +} + int DetermineTowerBackground::process_event(PHCompositeNode *topNode) { @@ -481,7 +533,103 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) } } - if ( _do_flow >= 1 ) + + // Get psi + if (_do_flow == 2) + { // HIJING truth flow extraction + PHG4TruthInfoContainer *truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + + if (!truthinfo) + { + std::cout << "DetermineTowerBackground::process_event: FATAL , G4TruthInfo does not exist , cannot extract truth flow with do_flow = " << _do_flow << std::endl; + return -1; + } + + PHG4TruthInfoContainer::Range range = truthinfo->GetPrimaryParticleRange(); + + float Hijing_Qx = 0; + float Hijing_Qy = 0; + + for (PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter) + { + PHG4Particle *g4particle = iter->second; + + if (truthinfo->isEmbeded(g4particle->get_track_id()) != 0) + { + continue; + } + + TLorentzVector t; + t.SetPxPyPzE(g4particle->get_px(), g4particle->get_py(), g4particle->get_pz(), g4particle->get_e()); + + float truth_pt = t.Pt(); + if (truth_pt < 0.4) + { + continue; + } + float truth_eta = t.Eta(); + if (std::fabs(truth_eta) > 1.1) + { + continue; + } + float truth_phi = t.Phi(); + int truth_pid = g4particle->get_pid(); + + if (Verbosity() > 10) + { + std::cout << "DetermineTowerBackground::process_event: determining truth flow, using particle w/ pt / eta / phi " << truth_pt << " / " << truth_eta << " / " << truth_phi << " , embed / PID = " << truthinfo->isEmbeded(g4particle->get_track_id()) << " / " << truth_pid << std::endl; + } + + Hijing_Qx += truth_pt * std::cos(2 * truth_phi); + Hijing_Qy += truth_pt * std::sin(2 * truth_phi); + } + + _Psi2 = std::atan2(Hijing_Qy, Hijing_Qx) / 2.0; + + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: flow extracted from Hijing truth particles, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; + } + } + else if (_do_flow == 3 || _do_flow == 4) + { // sEPD event plane extraction + // get event plane map + EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!epmap) + { + std::cout << "DetermineTowerBackground::process_event: FATAL, EventplaneinfoMap does not exist, cannot extract sEPD flow with do_flow = " << _do_flow << std::endl; + exit(-1); + } + if (!(epmap->empty())) + { + auto *EPDNS = epmap->get(EventplaneinfoMap::sEPDNS); + _Psi2 = EPDNS->get_shifted_psi(2); + } + else + { + _is_flow_failure = true; + _Psi2 = 0; + } + + // Safety check + if (!std::isfinite(_Psi2)) + { + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: WARNING Psi2 is non-finite (NaN or Inf), setting Psi2 = 0." << std::endl; + } + _is_flow_failure = true; + _Psi2 = 0; + } + + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: flow extracted from sEPD, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; + } + + } + + if ( _do_flow >= 1 && _do_flow < 4) { if (Verbosity() > 0) @@ -754,88 +902,6 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) { // Calo event plane _Psi2 = std::atan2(Q_y, Q_x) / 2.0; } - else if (_do_flow == 2) - { // HIJING truth flow extraction - PHG4TruthInfoContainer *truthinfo = findNode::getClass(topNode, "G4TruthInfo"); - - if (!truthinfo) - { - std::cout << "DetermineTowerBackground::process_event: FATAL , G4TruthInfo does not exist , cannot extract truth flow with do_flow = " << _do_flow << std::endl; - return -1; - } - - PHG4TruthInfoContainer::Range range = truthinfo->GetPrimaryParticleRange(); - - float Hijing_Qx = 0; - float Hijing_Qy = 0; - - for (PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter) - { - PHG4Particle *g4particle = iter->second; - - if (truthinfo->isEmbeded(g4particle->get_track_id()) != 0) - { - continue; - } - - TLorentzVector t; - t.SetPxPyPzE(g4particle->get_px(), g4particle->get_py(), g4particle->get_pz(), g4particle->get_e()); - - float truth_pt = t.Pt(); - if (truth_pt < 0.4) - { - continue; - } - float truth_eta = t.Eta(); - if (std::fabs(truth_eta) > 1.1) - { - continue; - } - float truth_phi = t.Phi(); - int truth_pid = g4particle->get_pid(); - - if (Verbosity() > 10) - { - std::cout << "DetermineTowerBackground::process_event: determining truth flow, using particle w/ pt / eta / phi " << truth_pt << " / " << truth_eta << " / " << truth_phi << " , embed / PID = " << truthinfo->isEmbeded(g4particle->get_track_id()) << " / " << truth_pid << std::endl; - } - - Hijing_Qx += truth_pt * std::cos(2 * truth_phi); - Hijing_Qy += truth_pt * std::sin(2 * truth_phi); - } - - _Psi2 = std::atan2(Hijing_Qy, Hijing_Qx) / 2.0; - - if (Verbosity() > 0) - { - std::cout << "DetermineTowerBackground::process_event: flow extracted from Hijing truth particles, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; - } - } - else if (_do_flow == 3) - { // sEPD event plane extraction - // get event plane map - EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); - if (!epmap) - { - std::cout << "DetermineTowerBackground::process_event: FATAL, EventplaneinfoMap does not exist, cannot extract sEPD flow with do_flow = " << _do_flow << std::endl; - exit(-1); - } - if (!(epmap->empty())) - { - auto *EPDNS = epmap->get(EventplaneinfoMap::sEPDNS); - _Psi2 = EPDNS->get_shifted_psi(2); - } - else - { - _is_flow_failure = true; - _Psi2 = 0; - } - - if (Verbosity() > 0) - { - std::cout << "DetermineTowerBackground::process_event: flow extracted from sEPD, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; - } - - } if (std::isnan(_Psi2) || std::isinf(_Psi2)) { @@ -890,7 +956,30 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) std::cout << "DetermineTowerBackground::process_event: flow extraction successful, Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) , v2 = " << _v2 << std::endl; } } // if do flow + else if (_do_flow == 4) + { + CentralityInfo *centinfo = findNode::getClass(topNode, "CentralityInfo"); + + if (!centinfo) + { + std::cout << "DetermineTowerBackground::process_event: FATAL, CentralityInfo does not exist, cannot extract centrality with do_flow = " << _do_flow << std::endl; + exit(-1); + } + + int centrality_bin = centinfo->get_centrality_bin(CentralityInfo::PROP::mbd_NS); + + if (centrality_bin > 0 && centrality_bin < 95) + { + _v2 = _CENTRALITY_V2[centrality_bin]; + } + else + { + _v2 = 0; + _is_flow_failure = true; + _Psi2 = 0; + } + } // now calculate energy densities... _nTowers = 0; // store how many towers were used to determine bkg diff --git a/offline/packages/jetbackground/DetermineTowerBackground.h b/offline/packages/jetbackground/DetermineTowerBackground.h index a8a6d0209c..ed9e34bf9a 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.h +++ b/offline/packages/jetbackground/DetermineTowerBackground.h @@ -13,6 +13,7 @@ #include #include #include +#include // forward declarations class PHCompositeNode; @@ -37,7 +38,11 @@ class DetermineTowerBackground : public SubsysReco void SetBackgroundOutputName(const std::string &name) { _backgroundName = name; } void SetSeedType(int seed_type) { _seed_type = seed_type; } void SetFlow(int do_flow) { _do_flow = do_flow; }; - + void SetOverwriteCaloV2(std::string &url) + { + m_overwrite_average_calo_v2 = true; + m_overwrite_average_calo_v2_path = url; + } void SetSeedJetD(float D) { _seed_jet_D = D; }; void SetSeedJetPt(float pt) { _seed_jet_pt = pt; }; void SetSeedMaxConst(float max_const) { _seed_max_const = max_const; }; @@ -55,6 +60,13 @@ class DetermineTowerBackground : public SubsysReco int CreateNode(PHCompositeNode *topNode); void FillNode(PHCompositeNode *topNode); + int LoadCalibrations(); + + std::vector _CENTRALITY_V2; + std::string m_calibName = "JET_AVERAGE_CALO_V2_SEPD_PSI2"; + bool m_overwrite_average_calo_v2{false}; + std::string m_overwrite_average_calo_v2_path; + int _do_flow{0}; float _v2{0}; float _Psi2{0}; diff --git a/offline/packages/jetbackground/Makefile.am b/offline/packages/jetbackground/Makefile.am index 6fe9740a4e..ad45676fbe 100644 --- a/offline/packages/jetbackground/Makefile.am +++ b/offline/packages/jetbackground/Makefile.am @@ -24,6 +24,8 @@ libjetbackground_la_LDFLAGS = \ libjetbackground_la_LIBADD = \ libjetbackground_io.la \ -lcalo_io \ + -lcentrality_io \ + -lcdbobjects \ -lConstituentSubtractor \ -leventplaneinfo_io \ -lglobalvertex \ @@ -33,6 +35,7 @@ libjetbackground_la_LIBADD = \ -lphg4hit \ -lphparameter \ -lqautils \ + -lffamodules \ -lSubsysReco pkginclude_HEADERS = \ diff --git a/offline/packages/jetbase/TowerJetInput.cc b/offline/packages/jetbase/TowerJetInput.cc index f58249ad04..052a6c1828 100644 --- a/offline/packages/jetbase/TowerJetInput.cc +++ b/offline/packages/jetbase/TowerJetInput.cc @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 22b1e9930d..3ebe139ffb 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -86,6 +86,17 @@ int MbdCalib::Download_All() } Download_SampMax(sampmax_url); + std::string status_url = _cdb->getUrl("MBD_STATUS"); + if ( ! status_url.empty() ) + { + // if this doesn't exist, the status is assumed to be all good + Download_Status(status_url); + } + if (Verbosity() > 0) + { + std::cout << "status_url " << status_url << std::endl; + } + if ( !_rawdstflag ) { std::string ped_url = _cdb->getUrl("MBD_PED"); @@ -97,6 +108,11 @@ int MbdCalib::Download_All() std::string pileup_url = _cdb->getUrl("MBD_PILEUP"); + if ( pileup_url.empty() ) + { + std::cerr << "ERROR, MBD_PILEUP missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "pileup_url " << pileup_url << std::endl; @@ -106,6 +122,11 @@ int MbdCalib::Download_All() if (do_templatefit) { std::string shape_url = _cdb->getUrl("MBD_SHAPES"); + if ( shape_url.empty() ) + { + std::cerr << "ERROR, MBD_SHAPES missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "shape_url " << shape_url << std::endl; @@ -176,6 +197,9 @@ int MbdCalib::Download_All() std::string sampmax_file = bbc_caldir + "/mbd_sampmax.calib"; Download_SampMax(sampmax_file); + std::string status_file = bbc_caldir + "/mbd_status.calib"; + Download_Status(status_file); + if ( !_rawdstflag ) { std::string ped_file = bbc_caldir + "/mbd_ped.calib"; @@ -617,8 +641,6 @@ int MbdCalib::Download_Ped(const std::string& dbase_location) if ( std::isnan(_pedmean[0]) ) { std::cout << PHWHERE << ", WARNING, ped calib missing, " << dbase_location << std::endl; - _status = -1; - return _status; } return 1; @@ -681,6 +703,74 @@ int MbdCalib::Download_SampMax(const std::string& dbase_location) if ( _sampmax[0] == -1 ) { std::cout << PHWHERE << ", WARNING, sampmax calib missing, " << dbase_location << std::endl; + } + + return 1; +} + +int MbdCalib::Download_Status(const std::string& dbase_location) +{ + // Reset All Values + _mbdstatus.fill(-1); + + TString dbase_file = dbase_location; + +#ifndef ONLINE + if (dbase_file.EndsWith(".root")) // read from database + { + CDBTTree* cdbttree = new CDBTTree(dbase_location); + cdbttree->LoadCalibrations(); + + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + _mbdstatus[ifeech] = cdbttree->GetIntValue(ifeech, "status"); + if (Verbosity() > 0) + { + if (ifeech < 5 || ifeech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << ifeech << "\t" << _mbdstatus[ifeech] << std::endl; + } + } + } + delete cdbttree; + } +#endif + + if (dbase_file.EndsWith(".calib")) // read from text file + { + std::ifstream infile(dbase_location); + if (!infile.is_open()) + { + std::cout << PHWHERE << "unable to open " << dbase_location << std::endl; + _status = -3; + return _status; + } + + int feech = -1; + while (infile >> feech) + { + if (feech < 0 || feech >= MbdDefs::MBD_N_FEECH) + { + std::cout << "ERROR, invalid FEECH " << feech << " in MBD status calibration" << std::endl; + _status = -4; + return _status; + } + infile >> _mbdstatus[feech]; + if (Verbosity() > 0) + { + if (feech < 5 || feech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << "status\t" << feech << "\t" << _mbdstatus[feech] << std::endl; + } + } + } + infile.close(); + } + + + if ( _mbdstatus[0] == -1 ) + { + std::cout << PHWHERE << ", WARNING, status calib seems bad, " << dbase_location << std::endl; _status = -1; return _status; // file not found } @@ -1225,7 +1315,6 @@ int MbdCalib::Download_TimeRMS(const std::string& dbase_location) trms.clear(); } std::fill(_trms_npts.begin(), _trms_npts.end(), 0); - TString dbase_file = dbase_location; #ifndef ONLINE @@ -1331,9 +1420,10 @@ int MbdCalib::Download_TimeRMS(const std::string& dbase_location) if ( _trms_y[0].empty() ) { - std::cout << PHWHERE << ", ERROR, unknown file type, " << dbase_location << std::endl; - _status = -1; - return _status; // file not found + std::cout << PHWHERE << ", WARNING, trms calib missing " << dbase_location << std::endl; +// _status = -1; +// return _status; // file not found + return 0; } // Now we interpolate the trms @@ -1591,6 +1681,52 @@ int MbdCalib::Write_SampMax(const std::string& dbfile) return 1; } +#ifndef ONLINE +int MbdCalib::Write_CDB_Status(const std::string& dbfile) +{ + CDBTTree* cdbttree{ nullptr }; + + std::cout << "Creating " << dbfile << std::endl; + cdbttree = new CDBTTree( dbfile ); + cdbttree->SetSingleIntValue("version", 1); + cdbttree->CommitSingle(); + + std::cout << "STATUS" << std::endl; + for (size_t ifeech = 0; ifeech < _mbdstatus.size(); ifeech++) + { + // store in a CDBTree + cdbttree->SetIntValue(ifeech, "status", _mbdstatus[ifeech]); + + if (ifeech < 12 || ifeech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << ifeech << "\t" << cdbttree->GetIntValue(ifeech, "status") << std::endl; + } + } + + cdbttree->Commit(); + // cdbttree->Print(); + + // for now we create the tree after reading it + cdbttree->WriteCDBTTree(); + delete cdbttree; + + return 1; +} +#endif + +int MbdCalib::Write_Status(const std::string& dbfile) +{ + std::ofstream cal_file; + cal_file.open(dbfile); + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + cal_file << ifeech << "\t" << _mbdstatus[ifeech] << std::endl; + } + cal_file.close(); + + return 1; +} + #ifndef ONLINE int MbdCalib::Write_CDB_TTT0(const std::string& dbfile) { @@ -1930,6 +2066,40 @@ int MbdCalib::Write_CDB_TimeCorr(const std::string& dbfile) } #endif +int MbdCalib::Write_TimeCorr(const std::string& dbfile) +{ + std::ofstream cal_timecorr_file; + cal_timecorr_file.open(dbfile); + if (!cal_timecorr_file.is_open()) + { + std::cout << PHWHERE << "unable to open " << dbfile << std::endl; + return -1; + } + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + if ( _mbdgeom->get_type(ifeech) == 1 ) + { + continue; // skip q-channels + } + cal_timecorr_file << ifeech << "\t" << _tcorr_npts[ifeech] << "\t" << _tcorr_minrange[ifeech] << "\t" << _tcorr_maxrange[ifeech] << std::endl; + for (int ipt=0; ipt<_tcorr_npts[ifeech]; ipt++) + { + cal_timecorr_file << _tcorr_y[ifeech][ipt]; + if ( ipt%10 == 9 ) + { + cal_timecorr_file << std::endl; + } + else + { + cal_timecorr_file << " "; + } + } + } + cal_timecorr_file.close(); + + return 1; +} + #ifndef ONLINE int MbdCalib::Write_CDB_SlewCorr(const std::string& dbfile) { @@ -2353,6 +2523,7 @@ void MbdCalib::Reset() Reset_Thresholds(); _sampmax.fill(-1); + _mbdstatus.fill(0); } void MbdCalib::set_ped(const int ifeech, const float m, const float merr, const float s, const float serr) diff --git a/offline/packages/mbd/MbdCalib.h b/offline/packages/mbd/MbdCalib.h index 6d7208f631..49129ac749 100644 --- a/offline/packages/mbd/MbdCalib.h +++ b/offline/packages/mbd/MbdCalib.h @@ -37,6 +37,7 @@ class MbdCalib float get_ped(const int ifeech) const { return _pedmean[ifeech]; } float get_pedrms(const int ifeech) const { return _pedsigma[ifeech]; } int get_sampmax(const int ifeech) const { return _sampmax[ifeech]; } + int get_status(const int ifeech) const { return _mbdstatus[ifeech]; } float get_tcorr(const int ifeech, const int tdc) const { if (tdc<0) { @@ -108,6 +109,7 @@ class MbdCalib TGraph *get_lut_graph(const int pmtch, std::string_view type); void set_sampmax(const int ifeech, const int val) { _sampmax[ifeech] = val; } + void set_status(const int ifeech, const int val) { _mbdstatus[ifeech] = val; } void set_ped(const int ifeech, const float m, const float merr, const float s, const float serr); void set_tt0(const int ipmt, const float t0) { _ttfit_t0mean[ipmt] = t0; } void set_tq0(const int ipmt, const float t0) { _tqfit_t0mean[ipmt] = t0; } @@ -118,6 +120,7 @@ class MbdCalib int Download_T0Corr(const std::string& dbase_location); int Download_Ped(const std::string& dbase_location); int Download_SampMax(const std::string& dbase_location); + int Download_Status(const std::string& dbase_location); int Download_Shapes(const std::string& dbase_location); int Download_TimeCorr(const std::string& dbase_location); int Download_SlewCorr(const std::string& dbase_location); @@ -128,6 +131,7 @@ class MbdCalib #ifndef ONLINE int Write_CDB_SampMax(const std::string& dbfile); + int Write_CDB_Status(const std::string& dbfile); int Write_CDB_TTT0(const std::string& dbfile); int Write_CDB_TQT0(const std::string& dbfile); int Write_CDB_T0Corr(const std::string& dbfile); @@ -143,10 +147,12 @@ class MbdCalib #endif int Write_SampMax(const std::string& dbfile); + int Write_Status(const std::string& dbfile); int Write_TQT0(const std::string& dbfile); int Write_TTT0(const std::string& dbfile); int Write_T0Corr(const std::string& dbfile); int Write_Ped(const std::string& dbfile); + int Write_TimeCorr(const std::string& dbfile); int Write_Gains(const std::string& dbfile); int Write_Pileup(const std::string& dbfile); int Write_Thresholds(const std::string& dbfile); @@ -231,6 +237,9 @@ class MbdCalib // SampMax (Peak of waveform) std::array _sampmax{}; + // Status (MBD Channel Status) + std::array _mbdstatus{}; + // Pileup waveform correction std::array _pileup_p0{}; std::array _pileup_p0err{}; diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index d8c72b4395..72cecb212d 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -35,6 +35,7 @@ #include #include #include +#include MbdEvent::MbdEvent(const int cal_pass, const bool proc_charge) : _nsamples(MbdDefs::MAX_SAMPLES), @@ -150,10 +151,16 @@ int MbdEvent::InitRun() _mbdcal->SetRawDstFlag( _rawdstflag ); _mbdcal->SetFitsOnly( _fitsonly ); - _mbdcal->Download_All(); if ( _simflag == 0 ) // do following for real data { + // Download calibrations + int status = _mbdcal->Download_All(); + if ( status == -1 ) + { + return Fun4AllReturnCodes::ABORTRUN; + } + // load pass1 calibs from local file for calpass2+ if ( _calpass>1 ) { @@ -175,35 +182,36 @@ int MbdEvent::InitRun() _calib_done = 0; std::cout << PHWHERE << ",no sampmax calib, determining it on the fly using first " << _no_sampmax << " evts." << std::endl; } - } - // Init parameters of the signal processing - for (int ifeech = 0; ifeech < MbdDefs::BBC_N_FEECH; ifeech++) - { - _mbdsig[ifeech].SetCalib(_mbdcal); - - // Do evt-by-evt pedestal using sample range below - if ( _calpass==1 || _is_online || _no_sampmax>0 ) + // Init parameters of the signal processing + for (int ifeech = 0; ifeech < MbdDefs::BBC_N_FEECH; ifeech++) { - _mbdsig[ifeech].SetEventPed0Range(0,1); - } - else - { - const int presamp = 5; // start from 5 samples before sampmax - const int nsamps = -1; // use all to sample 0 - _mbdsig[ifeech].SetEventPed0PreSamp(presamp, nsamps, _mbdcal->get_sampmax(ifeech)); - } + _mbdsig[ifeech].SetCalib(_mbdcal); - // Read in template if specified - if ( do_templatefit && _mbdgeom->get_type(ifeech)==1 ) - { - // std::cout << PHWHERE << "Reading template " << ifeech << std::endl; - // std::cout << "SIZES0 " << _mbdcal->get_shape(ifeech).size() << std::endl; - // Should set template size automatically here - _mbdsig[ifeech].SetTemplate(_mbdcal->get_shape(ifeech), _mbdcal->get_sherr(ifeech)); - _mbdsig[ifeech].SetMinMaxFitTime(_mbdcal->get_sampmax(ifeech) - 2 - 3, _mbdcal->get_sampmax(ifeech) - 2 + 3); - //_mbdsig[ifeech].SetMinMaxFitTime( 0, 31 ); + // Do evt-by-evt pedestal using sample range below + if ( _calpass==1 || _is_online || _no_sampmax>0 ) + { + _mbdsig[ifeech].SetEventPed0Range(0,1); + } + else + { + const int presamp = 5; // start from 5 samples before sampmax + const int nsamps = -1; // use all to sample 0 + _mbdsig[ifeech].SetEventPed0PreSamp(presamp, nsamps, _mbdcal->get_sampmax(ifeech)); + } + + // Read in template if specified + if ( do_templatefit && _mbdgeom->get_type(ifeech)==1 ) + { + // std::cout << PHWHERE << "Reading template " << ifeech << std::endl; + // std::cout << "SIZES0 " << _mbdcal->get_shape(ifeech).size() << std::endl; + // Should set template size automatically here + _mbdsig[ifeech].SetTemplate(_mbdcal->get_shape(ifeech), _mbdcal->get_sherr(ifeech)); + _mbdsig[ifeech].SetMinMaxFitTime(_mbdcal->get_sampmax(ifeech) - 2 - 3, _mbdcal->get_sampmax(ifeech) - 2 + 3); + //_mbdsig[ifeech].SetMinMaxFitTime( 0, 31 ); + } } + } if ( _calpass > 0 ) @@ -361,6 +369,23 @@ int MbdEvent::End() orig_dir->cd(); } + // Write out MbdSig eval histograms + if ( _doeval ) + { + TDirectory *orig_dir = gDirectory; + + // _doeval is overloaded with segment_number+1 + std::string savefname = std::format("mbdfiteval_{:08}-{:05}.root",_runnum,_doeval-1); + _evalfile = std::make_unique(savefname.c_str(),"RECREATE"); + + for (auto & sig : _mbdsig) + { + sig.WriteChi2Hist(); + } + + orig_dir->cd(); + } + return 1; } @@ -397,7 +422,13 @@ void MbdEvent::Clear() bool MbdEvent::isbadtch(const int ipmtch) { - return std::fabs(_mbdcal->get_tt0(ipmtch))>100.; + int feech = _mbdgeom->get_feech(ipmtch,0); + if ( _mbdcal->get_status(feech) > 0 ) + { + return true; + } + + return false; } @@ -451,6 +482,7 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc if (dstp[ipkt]) { _nsamples = dstp[ipkt]->iValue(0, "SAMPLES"); + { static bool printcount{true}; if ( printcount && Verbosity() > 0) @@ -460,6 +492,13 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc } } + // skip empty packets, corrupt event + if ( _nsamples == 0 ) + { + std::cout << PHWHERE << " ERROR, evt " << m_evt << " no samples in Packet " << pktid << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + m_xmitclocks[ipkt] = static_cast(dstp[ipkt]->iValue(0, "CLOCK")); m_femclocks[ipkt][0] = static_cast(dstp[ipkt]->iValue(0, "FEMCLOCK")); @@ -484,9 +523,17 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc } _mbdsig[feech].SetNSamples( _nsamples ); - _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); - + + if ( _nsamples > 0 && _nsamples <= 30 ) + { + _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); + } /* + else + { + std::cout << PHWHERE << " empty feech " << feech << std::endl; + } + std::cout << "feech " << feech << std::endl; _mbdsig[feech].Print(); */ @@ -565,6 +612,7 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer if (p[ipkt]) { _nsamples = p[ipkt]->iValue(0, "SAMPLES"); + { static int counter = 0; if ( counter<1 ) @@ -574,6 +622,15 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer counter++; } + // If packets are missing, stop processing event + if ( _nsamples == 0 ) + { + std::cout << PHWHERE << " ERROR, skipping evt " << m_evt << " nsamples = 0 " << pktid << std::endl; + delete p[ipkt]; + p[ipkt] = nullptr; + return Fun4AllReturnCodes::ABORTEVENT; + } + m_xmitclocks[ipkt] = static_cast(p[ipkt]->iValue(0, "CLOCK")); m_femclocks[ipkt][0] = static_cast(p[ipkt]->iValue(0, "FEMCLOCK")); @@ -637,8 +694,9 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) // Do a quick sanity check that all fem counters agree if (m_xmitclocks[0] != m_xmitclocks[1]) { - std::cout << __FILE__ << ":" << __LINE__ << " ERROR, xmitclocks don't agree" << std::endl; + std::cout << __FILE__ << ":" << __LINE__ << " ERROR, xmitclocks don't agree, evt " << m_evt << std::endl; } + /* // format changed in run2024, need to update check for (auto &femclock : femclocks) @@ -673,20 +731,24 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) int pmtch = _mbdgeom->get_pmt(ifeech); int type = _mbdgeom->get_type(ifeech); // 0 = T-channel, 1 = Q-channel + if ( _mbdsig[ifeech].GetNSamples()==0 ) + { + continue; + } + // time channel if (type == 0) { m_ttdc[pmtch] = _mbdsig[ifeech].MBDTDC(_mbdcal->get_sampmax(ifeech)); - if ( m_ttdc[pmtch] < 40. || std::isnan(m_ttdc[pmtch]) || isbadtch(pmtch) ) + if ( m_ttdc[pmtch] < 40. || std::isnan(m_ttdc[pmtch]) ) { m_ttdc[pmtch] = std::numeric_limits::quiet_NaN(); // no hit } } - else if ( type == 1 && (!std::isnan(m_ttdc[pmtch]) || isbadtch(pmtch) || _always_process_charge ) ) + else if ( type == 1 && (!std::isnan(m_ttdc[pmtch]) || _always_process_charge ) ) { // we process charge channels which have good time hit - // or have time channels marked as bad // or have always_process_charge set to 1 (useful for threshold studies) // Use dCFD method to seed time in charge channels (or as primary if not fitting template) @@ -700,21 +762,18 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) //std::cout << "fittemplate" << std::endl; _mbdsig[ifeech].FitTemplate( _mbdcal->get_sampmax(ifeech) ); + /* if ( _verbose ) { std::cout << "tt " << ifeech << " " << pmtch << " " << m_pmttt[pmtch] << std::endl; } + */ m_qtdc[pmtch] = _mbdsig[ifeech].GetTime(); // in units of sample number m_ampl[ifeech] = _mbdsig[ifeech].GetAmpl(); // in units of adc } // calpass 2, uncal_mbd. template fit. make sure qgain = 1, tq_t0 = 0 - // In Run 1 (runs before 40000), we didn't set hardware thresholds, and instead set a software threshold of 0.25 - if ( ((m_ampl[ifeech] < (_mbdcal->get_qgain(pmtch) * 0.25)) && (_runnum < 40000)) || std::fabs(_mbdcal->get_tq0(pmtch))>100. ) - { - m_qtdc[pmtch] = std::numeric_limits::quiet_NaN(); - } } } @@ -739,11 +798,17 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc int pmtch = _mbdgeom->get_pmt(ifeech); int type = _mbdgeom->get_type(ifeech); // 0 = T-channel, 1 = Q-channel + if ( _mbdsig[ifeech].GetNSamples()==0 ) + { + continue; + } + // time channel if (type == 0) { if ( std::isnan(bbcraws->get_pmt(pmtch)->get_ttdc()) || isbadtch(pmtch) ) { + // time channel has no hit or is marked as bad m_pmttt[pmtch] = std::numeric_limits::quiet_NaN(); // no hit } else @@ -754,6 +819,16 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc m_pmttt[pmtch] -= _mbdcal->get_tt0(pmtch); } + /* + if ( !std::isnan(m_pmttt[pmtch]) ) + { + std::cout << "pmttt " << m_evt << "\t" << pmtch << "\t" << m_pmttt[pmtch] << "\t" + << bbcraws->get_pmt(pmtch)->get_ttdc() << "\t" + << _mbdcal->get_tcorr(ifeech,bbcraws->get_pmt(pmtch)->get_ttdc()) << "\t" + << _mbdcal->get_tt0(pmtch) << std::endl; + } + */ + } else if ( type == 1 && (!std::isnan(bbcraws->get_pmt(pmtch)->get_ttdc()) || isbadtch(pmtch) || _always_process_charge ) ) { @@ -761,7 +836,15 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc // or have time channels marked as bad // or have always_process_charge set to 1 (useful for threshold studies) - m_pmttq[pmtch] = bbcraws->get_pmt(pmtch)->get_qtdc(); + // In Run 1 (runs before 40000), we didn't set hardware thresholds, and instead set a software threshold of 0.25 + if ( ((bbcraws->get_pmt(pmtch)->get_adc() < (_mbdcal->get_qgain(pmtch) * 0.25)) && (_runnum < 40000)) || std::fabs(_mbdcal->get_tq0(pmtch))>100. ) + { + m_pmttq[pmtch] = std::numeric_limits::quiet_NaN(); + } + else + { + m_pmttq[pmtch] = bbcraws->get_pmt(pmtch)->get_qtdc(); + } if ( !std::isnan(m_pmttq[pmtch]) ) { @@ -770,17 +853,15 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc m_pmttq[pmtch] = m_pmttq[pmtch] - _mbdcal->get_tq0(pmtch); // if ( m_pmttq[pmtch]<-50. && ifeech==255 ) std::cout << "hit_times " << ifeech << "\t" << m_pmttq[pmtch] << std::endl; - // if ( arm==1 ) std::cout << "hit_times " << ifeech << "\t" << setw(10) << m_pmttq[pmtch] << "\t" << board << "\t" << TRIG_SAMP[board] << std::endl; // if tt is bad, use tq - if ( std::fabs(_mbdcal->get_tt0(pmtch))>100. ) + if ( _mbdcal->get_status(ifeech-8)>0 ) { m_pmttt[pmtch] = m_pmttq[pmtch]; } else { // we have a good tt ch. correct for slew if there is a hit - //if ( ifeech==0 ) std::cout << "applying scorr" << std::endl; if ( !std::isnan(m_pmttt[pmtch]) ) { m_pmttt[pmtch] -= _mbdcal->get_scorr(ifeech-8,bbcraws->get_pmt(pmtch)->get_adc()); @@ -854,8 +935,14 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc */ TGraphErrors *gsubpulse = _mbdsig[ifeech].GetGraph(); - Double_t *y = gsubpulse->GetY(); - h2_trange->Fill( y[samp_max], pmtch ); // fill ped-subtracted tdc + if ( gsubpulse ) + { + Double_t *y = gsubpulse->GetY(); + if ( y ) + { + h2_trange->Fill( y[samp_max], pmtch ); // fill ped-subtracted tdc + } + } } } diff --git a/offline/packages/mbd/MbdEvent.h b/offline/packages/mbd/MbdEvent.h index ede1670171..5abd48aeae 100644 --- a/offline/packages/mbd/MbdEvent.h +++ b/offline/packages/mbd/MbdEvent.h @@ -74,6 +74,7 @@ class MbdEvent void set_EventNumber(int ievt) { m_evt = ievt; } void set_debug(const int d) { _debug = d; } + void set_doeval(const int d) { _doeval = d; } MbdSig *GetSig(const int ipmt) { return &_mbdsig[ipmt]; } @@ -196,12 +197,14 @@ class MbdEvent // debug stuff TCanvas *ac{nullptr}; // for plots used during debugging void PlotDebug(); + int _doeval{0}; + std::unique_ptr _evalfile{nullptr}; std::unique_ptr _synctfile{nullptr}; TTree *_syncttree{nullptr}; Double_t _refz{ std::numeric_limits::quiet_NaN() }; - std::vector bbevt; + std::vector bbevt; std::vector bbclk; - std::vector mybbz; + std::vector mybbz; std::vector bco; std::vector intz; std::vector bbz; diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index c19ed37ba9..fe4dc62049 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -7,7 +7,7 @@ #include "MbdPmtSimContainerV1.h" #include -#include +#include #include @@ -61,11 +61,17 @@ int MbdReco::InitRun(PHCompositeNode *topNode) } int ret = getNodes(topNode); + if ( ret != Fun4AllReturnCodes::EVENT_OK ) + { + return ret; + } m_mbdevent->SetSim(_simflag); m_mbdevent->SetRawDstFlag(_rawdstflag); m_mbdevent->SetFitsOnly(_fitsonly); - m_mbdevent->InitRun(); + m_mbdevent->set_doeval(_fiteval); + + ret = m_mbdevent->InitRun(); return ret; } @@ -103,7 +109,8 @@ int MbdReco::process_event(PHCompositeNode *topNode) int status = Fun4AllReturnCodes::EVENT_OK; if ( m_evtheader!=nullptr ) { - m_mbdevent->set_EventNumber( m_evtheader->get_EvtSequence() ); + _evtnum = m_evtheader->get_EvtSequence(); + m_mbdevent->set_EventNumber( _evtnum ); } if ( m_event!=nullptr ) @@ -125,7 +132,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) static int counter = 0; if ( counter<3 ) { - std::cout << PHWHERE << " Warning, MBD discarding event " << std::endl; + std::cout << PHWHERE << " Warning, MBD discarding event " << _evtnum << std::endl; counter++; } return Fun4AllReturnCodes::DISCARDEVENT; @@ -135,7 +142,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) static int counter = 0; if ( counter<3 ) { - std::cout << PHWHERE << " Warning, MBD aborting event " << std::endl; + std::cout << PHWHERE << " Warning, MBD aborting event " << _evtnum << std::endl; counter++; } return Fun4AllReturnCodes::ABORTEVENT; @@ -171,7 +178,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) // For multiple global vertex if (m_mbdevent->get_bbcn(0) > 0 && m_mbdevent->get_bbcn(1) > 0 && _calpass==0 ) { - auto *vertex = new MbdVertexv2(); + auto *vertex = new MbdVertexv3(); vertex->set_t(m_mbdevent->get_bbct0()); vertex->set_z(m_mbdevent->get_bbcz()); vertex->set_z_err(0.6); diff --git a/offline/packages/mbd/MbdReco.h b/offline/packages/mbd/MbdReco.h index 0dfc7d7cbc..eced3b89e9 100644 --- a/offline/packages/mbd/MbdReco.h +++ b/offline/packages/mbd/MbdReco.h @@ -34,10 +34,11 @@ class MbdReco : public SubsysReco int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void DoOnlyFits() { _fitsonly = 1; } + void DoOnlyFits() { _fitsonly = 1; } + void DoFitEval(const int s) { _fiteval = s; } void SetCalPass(const int calpass) { _calpass = calpass; } void SetProcChargeCh(const bool s) { _always_process_charge = s; } - void SetMbdTrigOnly(const int m) { _mbdonly = m; } + void SetMbdTrigOnly(const int m) { _mbdonly = m; } private: int createNodes(PHCompositeNode *topNode); @@ -48,10 +49,13 @@ class MbdReco : public SubsysReco int _mbdonly{0}; // only use mbd triggers int _rawdstflag{0}; // dst with raw container int _fitsonly{0}; // stop reco after waveform fits (for DST_CALOFIT pass) + int _fiteval{0}; // overload with segment+1 float m_tres = 0.05; std::unique_ptr m_gaussian = nullptr; + int _evtnum{-1}; + std::unique_ptr m_mbdevent{nullptr}; Event *m_event{nullptr}; std::arraym_mbdpacket{nullptr}; diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index ae1f821a4e..1118ba2e60 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -74,10 +74,13 @@ void MbdSig::Init() ped_tail = new TF1("ped_tail","[0]+[1]*exp(-[2]*x)",0,2); ped_tail->SetLineColor(2); - // uncomment this to write out waveforms from events that have pileup from prev. crossing + name = "h_chi2ndf"; name += _ch; + h_chi2ndf = new TH1F(name,name,2000,0,100); + + // uncomment this to write out waveforms from events that have pileup from prev. crossing or next crossing /* name = "mbdsig"; name += _ch; name += ".txt"; - _pileupfile = new ofstream(name); + _pileupfile = new std::ofstream(name); */ } @@ -142,8 +145,10 @@ MbdSig::~MbdSig() delete hAmpl; delete hTime; delete template_fcn; + delete twotemplate_fcn; delete ped_fcn; delete ped_tail; + delete h_chi2ndf; } void MbdSig::SetEventPed0PreSamp(const Int_t presample, const Int_t nsamps, const int max_samp) @@ -251,6 +256,7 @@ void MbdSig::SetXY(const Float_t* x, const Float_t* y, const int invert) { gRawPulse->Draw("ap"); gRawPulse->GetHistogram()->SetTitle(gRawPulse->GetName()); + gPad->SetGridx(1); gPad->SetGridy(1); PadUpdate(); } @@ -412,6 +418,11 @@ Double_t MbdSig::GetSplineAmpl() return f_ampl; } +void MbdSig::WriteChi2Hist() +{ + h_chi2ndf->Write(); +} + void MbdSig::WritePedHist() { hPed0->Write(); @@ -619,6 +630,7 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) //std::cout << PHWHERE << std::endl; gRawPulse->Fit( ped_fcn, "RNQ" ); + /* double chi2ndf = ped_fcn->GetChisquare()/ped_fcn->GetNDF(); if ( _pileupfile != nullptr && chi2ndf > 4.0 ) { @@ -629,6 +641,7 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) } *_pileupfile << std::endl; } + */ } double chi2 = ped_fcn->GetChisquare(); @@ -988,6 +1001,12 @@ void MbdSig::PadUpdate() const } } +Double_t MbdSig::TwoTemplateFcn(const Double_t* x, const Double_t* par) +{ + Double_t f = TemplateFcn(x,par) + TemplateFcn(x,par+2); + return f; +} + Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) { // par[0] is the amplitude (relative to the spline amplitude) @@ -1106,8 +1125,13 @@ Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) int MbdSig::FitTemplate( const Int_t sampmax ) { //std::cout << PHWHERE << std::endl; //chiu - //_verbose = 100; // uncomment to see fits - //_verbose = 12; // don't see pedestal fits + /* + if ( _evt_counter==2142 && _ch==92 ) + { + _verbose = 100; // uncomment to see fits + //_verbose = 12; // don't see pedestal fits + } + */ // Check if channel is empty if (gSubPulse->GetN() == 0) @@ -1124,30 +1148,44 @@ int MbdSig::FitTemplate( const Int_t sampmax ) int nsaturated = 0; for (int ipt=0; ipt 16370. ) + if ( rawsamps[ipt] > 16370. ) // don't trust adc near edge { nsaturated++; } } /* - if ( nsaturated>2 && _ch==185 ) + //if ( nsaturated>2 && _ch==185 ) + if ( nsaturated>2 ) { _verbose = 12; } */ - if (_verbose > 0) { - std::cout << "Fitting ch " << _ch << std::endl; + std::cout << "Fitting ch sampmax " << _ch << "\t" << sampmax << std::endl; } // Get x and y of maximum Double_t x_at_max{-1.}; Double_t ymax{0.}; - if ( sampmax>=0 ) + if ( sampmax>0 ) { - gSubPulse->GetPoint(sampmax, x_at_max, ymax); + for (int isamp=sampmax-1; isamp<=sampmax+1; isamp++) + { + if ( (isamp>=gSubPulse->GetN()) ) + { + continue; + } + double adcval = gSubPulse->GetPointY(isamp); + if ( adcval>ymax ) + { + ymax = adcval; + x_at_max = isamp; + } + } + + //gSubPulse->GetPoint(sampmax, x_at_max, ymax); if ( nsaturated<=3 ) { x_at_max -= 2.0; @@ -1176,6 +1214,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) gSubPulse->Draw("ap"); gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); gPad->SetGridy(1); + gPad->SetGridx(1); PadUpdate(); } @@ -1184,23 +1223,15 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } template_fcn->SetParameters(ymax, x_at_max); - // template_fcn->SetParLimits(1, fit_min_time, fit_max_time); - // template_fcn->SetParLimits(1, 3, 15); - // template_fcn->SetRange(template_min_xrange,template_max_xrange); if ( nsaturated<=3 ) { - template_fcn->SetRange(0, _nsamples); + template_fcn->SetRange(0, x_at_max+4.2); } else { template_fcn->SetRange(0, sampmax + nsaturated - 0.5); } - if ( gSubPulse->GetN()==0 )//chiu - { - std::cout << PHWHERE << " gSubPulse 0" << std::endl; - } - if (_verbose == 0) { //std::cout << PHWHERE << std::endl; @@ -1214,24 +1245,88 @@ int MbdSig::FitTemplate( const Int_t sampmax ) gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); gPad->SetGridy(1); PadUpdate(); - //std::cout << "doing fit2 " << _verbose << std::endl; - //std::cout << "doing fit3 " << _verbose << std::endl; //gSubPulse->Print("ALL"); } // Get fit parameters f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); - if ( f_time<0. || f_time>_nsamples ) + f_chi2 = template_fcn->GetChisquare(); + f_ndf = template_fcn->GetNDF(); + + // Good fit + if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) + { + h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; + return 1; + } + + // fit was out of time, likely from pileup, try two waveforms + if ( (f_time<(sampmax-2.5) || f_time>sampmax) && (nsaturated<=3) ) + { + //_verbose = 100; //chiu + + if ( _verbose ) + { + std::cout << "BADTIME " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time << std::endl; + gSubPulse->Draw("ap"); + template_fcn->Draw("same"); + PadUpdate(); + } + + twotemplate_fcn->SetParameters(ymax,x_at_max,ymax,10); + twotemplate_fcn->SetRange(0,_nsamples); + + if (_verbose == 0) + { + gSubPulse->Fit(twotemplate_fcn, "RNQ"); + } + else + { + std::cout << "doing fit1 " << x_at_max << "\t" << ymax << std::endl; + gSubPulse->Fit(twotemplate_fcn, "R"); + gSubPulse->Draw("ap"); + gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); + gPad->SetGridy(1); + PadUpdate(); + //gSubPulse->Print("ALL"); + } + + //PadUpdate(); + + // Get fit parameters + f_ampl = twotemplate_fcn->GetParameter(0); + f_time = twotemplate_fcn->GetParameter(1); + f_chi2 = twotemplate_fcn->GetChisquare(); + f_ndf = twotemplate_fcn->GetNDF(); + + // Good fit + if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) + { + h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; + return 1; + } + } + + + /* chiu + if ( f_time<0. || f_time>9 ) { + _verbose = 100; f_time = _nsamples*0.5; // bad fit last time } + */ // refit with new range to exclude after-pulses - template_fcn->SetParameters( f_ampl, f_time ); + template_fcn->SetParameters(ymax, x_at_max); + //template_fcn->SetParameters( f_ampl, f_time ); + if ( nsaturated<=3 ) { - template_fcn->SetRange( 0., f_time+4.0 ); + template_fcn->SetRange(0, x_at_max+4.2); + //template_fcn->SetRange( 0., f_time+4.0 ); } else { @@ -1242,16 +1337,16 @@ int MbdSig::FitTemplate( const Int_t sampmax ) { //std::cout << PHWHERE << std::endl; int fit_status = gSubPulse->Fit(template_fcn, "RNQ"); - if ( fit_status<0 ) + if ( fit_status<0 && _verbose>0 ) { std::cout << PHWHERE << "\t" << fit_status << std::endl; gSubPulse->Print("ALL"); gSubPulse->Draw("ap"); gSubPulse->Fit(template_fcn, "R"); - std::cout << "ampl time before refit " << f_ampl << "\t" << f_time << std::endl; + std::cout << "ampl time before refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); - std::cout << "ampl time after refit " << f_ampl << "\t" << f_time << std::endl; + std::cout << "ampl time after refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; PadUpdate(); std::string junk; std::cin >> junk; @@ -1269,6 +1364,18 @@ int MbdSig::FitTemplate( const Int_t sampmax ) f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); + f_chi2 = template_fcn->GetChisquare(); + f_ndf = template_fcn->GetNDF(); + + h_chi2ndf->Fill( f_chi2/f_ndf ); + + /* + if ( (f_chi2/f_ndf) > 100. ) //chiu + { + std::cout << "very bad chi2ndf after refit " << f_ampl << "\t" << f_time << "\t" << f_chi2/f_ndf << std::endl; + //_verbose = 100; + } + */ //if ( f_time<0 || f_time>30 ) //if ( (_ch==185||_ch==155||_ch==249) && (fabs(f_ampl) > 44000.) ) @@ -1282,6 +1389,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) std::cout << " " << template_fcn->GetChisquare()/template_fcn->GetNDF() << std::endl; gSubPulse->Draw("ap"); gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); + gPad->SetGridx(1); gPad->SetGridy(1); template_fcn->SetLineColor(4); template_fcn->Draw("same"); @@ -1323,6 +1431,16 @@ int MbdSig::SetTemplate(const std::vector& shape, const std::vectorSetParName(1, "time"); SetTemplateSize(900, 1000, -10., 20.); + name = "twotemplate_fcn"; + name += _ch; + twotemplate_fcn = new TF1(name, this, &MbdSig::TwoTemplateFcn, 0, _nsamples, 4, "MbdSig", "TwoTemplateFcn"); + twotemplate_fcn->SetLineColor(3); + twotemplate_fcn->SetParameters(1, 6, 1,8); + twotemplate_fcn->SetParName(0, "ampl"); + twotemplate_fcn->SetParName(1, "time"); + twotemplate_fcn->SetParName(2, "ampl2"); + twotemplate_fcn->SetParName(3, "time2"); + if (_verbose) { std::cout << "SHAPE " << _ch << std::endl; diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index 0b8b420ffa..a3ee986c33 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -32,6 +32,8 @@ class MbdSig void SetY(const Float_t *y, const int invert = 1); void SetXY(const Float_t *x, const Float_t *y, const int invert = 1); + int GetNSamples() { return _nsamples; } + void SetCalib(MbdCalib *mcal); TH1 *GetHist() { return hpulse; } @@ -109,10 +111,12 @@ class MbdSig // Double_t FitPulse(); void SetTimeOffset(const Double_t o) { f_time_offset = o; } Double_t TemplateFcn(const Double_t *x, const Double_t *par); + Double_t TwoTemplateFcn(const Double_t *x, const Double_t *par); TF1 *GetTemplateFcn() { return template_fcn; } void SetMinMaxFitTime(const Double_t mintime, const Double_t maxtime); void WritePedHist(); + void WriteChi2Hist(); void DrawWaveform(); /// Draw Subtracted Waveform void PadUpdate() const; @@ -142,6 +146,9 @@ class MbdSig Double_t f_integral{0.}; /** integral */ + Double_t f_chi2{0.}; + Double_t f_ndf{0.}; + TH1 *hRawPulse{nullptr}; //! TH1 *hSubPulse{nullptr}; //! TH1 *hpulse{nullptr}; //! @@ -180,19 +187,17 @@ class MbdSig Int_t template_npointsy{0}; Double_t template_begintime{0.}; Double_t template_endtime{0.}; - // Double_t template_min_good_amplitude{20.}; //! for template, in original units of waveform data - // Double_t template_max_good_amplitude{4080.}; //! for template, in original units of waveform data - // Double_t template_min_xrange{0.}; //! for template, in original units of waveform data - // Double_t template_max_xrange{0.}; //! for template, in original units of waveform data std::vector template_y; std::vector template_yrms; TF1 *template_fcn{nullptr}; + TF1 *twotemplate_fcn{nullptr}; Double_t fit_min_time{}; //! min time for fit, in original units of waveform data Double_t fit_max_time{}; //! max time for fit, in original units of waveform data std::ofstream *_pileupfile{nullptr}; // for writing out waveforms from prev. crossing pileup // use for calibrating out the tail from these events + TH1 *h_chi2ndf{nullptr}; //! for eval int _verbose{0}; }; diff --git a/offline/packages/micromegas/MicromegasClusterizer.cc b/offline/packages/micromegas/MicromegasClusterizer.cc index c57d6ed3f5..5da9264c11 100644 --- a/offline/packages/micromegas/MicromegasClusterizer.cc +++ b/offline/packages/micromegas/MicromegasClusterizer.cc @@ -157,8 +157,13 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) // geometry PHG4CylinderGeomContainer* geonode = nullptr; for( std::string geonodename: {"CYLINDERGEOM_MICROMEGAS_FULL", "CYLINDERGEOM_MICROMEGAS" } ) - { if(( geonode = findNode::getClass(topNode, geonodename.c_str()) )) { break; -}} + { + // try load node and test + geonode = findNode::getClass(topNode, geonodename); + if( geonode ) { break;} + } + + //ma assert(geonode); // hitset container @@ -182,8 +187,8 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) for( auto hitset_it = hitset_range.first; hitset_it != hitset_range.second; ++hitset_it ) { // get hitset, key and layer - TrkrHitSet* hitset = hitset_it->second; - const TrkrDefs::hitsetkey hitsetkey = hitset_it->first; + const auto& [hitsetkey, hitset] = *hitset_it; + const auto layer = TrkrDefs::getLayer(hitsetkey); const auto tileid = MicromegasDefs::getTileId(hitsetkey); @@ -215,17 +220,32 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) using range_list_t = std::vector; range_list_t ranges; - // loop over hits - const auto hit_range = hitset->getHits(); + // Make a local copy of hitsets, sorted along strips + /* when there are multiple hits on the same strip, only the first one (in time) is kept */ + class StripSortFtor + { + public: + bool operator() ( const TrkrDefs::hitkey& first, const TrkrDefs::hitkey& second ) const + { return MicromegasDefs::getStrip(first) < MicromegasDefs::getStrip(second); } + }; + + using LocalMap = std::map; + LocalMap local_hitmap; + + { + // loop over hits + const auto hit_range = hitset->getHits(); + std::copy( hit_range.first, hit_range.second, std::inserter(local_hitmap, local_hitmap.end()) ); + } // keep track of first iterator of runing cluster - auto begin = hit_range.first; + auto begin = local_hitmap.begin(); // keep track of previous strip uint16_t previous_strip = 0; bool first = true; - for( auto hit_it = hit_range.first; hit_it != hit_range.second; ++hit_it ) + for( auto hit_it = local_hitmap.begin(); hit_it != local_hitmap.end(); ++hit_it ) { // get hit key @@ -233,18 +253,11 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) // get strip number const auto strip = MicromegasDefs::getStrip( hitkey ); - - if( first ) + if( !first && (strip - previous_strip > 1 ) ) { - previous_strip = strip; - first = false; - continue; - - } else if( strip - previous_strip > 1 ) { - // store current cluster range - ranges.push_back( std::make_pair( begin, hit_it ) ); + ranges.emplace_back( begin, hit_it ); // reinitialize begin of next cluster range begin = hit_it; @@ -252,13 +265,13 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) } // update previous strip + first = false; previous_strip = strip; } // store last cluster - if( begin != hit_range.second ) { ranges.push_back( std::make_pair( begin, hit_range.second ) ); -} + if( begin != local_hitmap.end() ) { ranges.emplace_back( begin, local_hitmap.end() ); } // initialize cluster count int cluster_count = 0; diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc index a5269617f7..1c34357280 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc @@ -203,13 +203,14 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) // loop over sample_range find maximum const auto sample_range = std::make_pair(rawhit->get_sample_begin(), rawhit->get_sample_end()); - std::vector adc_list; + using sample_pair_t = std::pair; + std::vector adc_list; for (auto is = std::max(m_sample_min, sample_range.first); is < std::min(m_sample_max, sample_range.second); ++is) { const uint16_t adc = rawhit->get_adc(is); if (adc != MicromegasDefs::m_adc_invalid) { - adc_list.push_back(adc); + adc_list.emplace_back(is, adc); } } @@ -220,16 +221,18 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) // get max adc value in range /* TODO: use more advanced signal processing */ - auto max_adc = *std::max_element(adc_list.begin(), adc_list.end()); + auto max_adc = *std::max_element(adc_list.begin(), adc_list.end(), + [](const sample_pair_t& first, const sample_pair_t& second) + { return first.second < second.second; } ); // compare to hard min_adc value - if (max_adc < m_min_adc) + if (max_adc.second < m_min_adc) { continue; } // compare to threshold - if (max_adc < pedestal + m_n_sigma * rms) + if (max_adc.second < pedestal + m_n_sigma * rms) { continue; } @@ -243,7 +246,8 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) << " tile: " << tile << " channel: " << channel << " strip: " << strip - << " adc: " << max_adc + << " sample: " << max_adc.first + << " adc: " << max_adc.second << std::endl; } @@ -251,19 +255,19 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) const auto hitset_it = trkrhitsetcontainer->findOrAddHitSet(hitsetkey); // generate hit key - const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip); + const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip, max_adc.first); // find existing hit, or create - auto hit = hitset_it->second->getHit(hitkey); + auto* hit = hitset_it->second->getHit(hitkey); if (hit) { - // std::cout << "MicromegasCombinedDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; + std::cout << "MicromegasCombinedDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; continue; } // create hit, assign adc and insert in hitset hit = new TrkrHitv2; - hit->setAdc(max_adc); + hit->setAdc(max_adc.second); hitset_it->second->addHitSpecificKey(hitkey, hit); // increment counter diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h index 32eebc56e0..33033f1992 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h @@ -49,10 +49,10 @@ class MicromegasCombinedDataDecoder : public SubsysReco /** This removes faulty channels for which calibration has failed */ void set_min_adc(double value) { m_min_adc = value; } - /// set min sample for noise estimation + /// set min sample for signal hits void set_sample_min(uint16_t value) { m_sample_min = value; } - /// set min sample for noise estimation + /// set max sample for signal hits void set_sample_max(uint16_t value) { m_sample_max = value; } private: @@ -85,7 +85,7 @@ class MicromegasCombinedDataDecoder : public SubsysReco uint16_t m_sample_min = 0; /// max sample for signal - uint16_t m_sample_max = 100; + uint16_t m_sample_max = 1024; /// keep track of number of hits per hitsetid using hitcountmap_t = std::map; diff --git a/offline/packages/micromegas/MicromegasDefs.cc b/offline/packages/micromegas/MicromegasDefs.cc index 0766d78b8e..8a35461492 100644 --- a/offline/packages/micromegas/MicromegasDefs.cc +++ b/offline/packages/micromegas/MicromegasDefs.cc @@ -25,11 +25,12 @@ namespace * 8 - 16 segmentation type * 0 - 8 tile id */ - static constexpr unsigned int kBitShiftSegmentation = 8; - static constexpr unsigned int kBitShiftTileId = 0; + constexpr unsigned int kBitShiftSegmentation = 8; + constexpr unsigned int kBitShiftTileId = 0; //! bit shift for hit key - static constexpr unsigned int kBitShiftStrip = 0; + constexpr unsigned int kBitShiftStrip = 0; + constexpr unsigned int kBitShiftSample = 8; } @@ -41,10 +42,10 @@ namespace MicromegasDefs { TrkrDefs::hitsetkey key = TrkrDefs::genHitSetKey(TrkrDefs::TrkrId::micromegasId, layer); - TrkrDefs::hitsetkey tmp = to_underlying_type(type); + TrkrDefs::hitsetkey tmp = to_underlying_type(type)&0x1U; key |= (tmp << kBitShiftSegmentation); - tmp = tile; + tmp = tile&0xFFU; key |= (tmp << kBitShiftTileId); return key; @@ -54,28 +55,36 @@ namespace MicromegasDefs SegmentationType getSegmentationType(TrkrDefs::hitsetkey key) { TrkrDefs::hitsetkey tmp = (key >> kBitShiftSegmentation); - return static_cast(tmp); + return static_cast(tmp&0x1U); } //________________________________________________________________ uint8_t getTileId(TrkrDefs::hitsetkey key) { TrkrDefs::hitsetkey tmp = (key >> kBitShiftTileId); - return tmp; + return tmp&0xFFU; } //________________________________________________________________ - TrkrDefs::hitkey genHitKey(uint16_t strip) + TrkrDefs::hitkey genHitKey(uint16_t strip, uint16_t sample) { - TrkrDefs::hitkey key = strip << kBitShiftStrip; - return key; + const TrkrDefs::hitkey key = (strip&0xFFU) << kBitShiftStrip; + const TrkrDefs::hitkey tmp = (sample&0xFFFFU) << kBitShiftSample; + return key|tmp; } //________________________________________________________________ - uint16_t getStrip( TrkrDefs::hitkey key ) + uint8_t getStrip( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftStrip); - return tmp; + return tmp & 0xFFU; + } + + //________________________________________________________________ + uint16_t getSample( TrkrDefs::hitkey key ) + { + TrkrDefs::hitkey tmp = (key >> kBitShiftSample); + return tmp & 0xFFFFU; } //________________________________________________________________ diff --git a/offline/packages/micromegas/MicromegasDefs.h b/offline/packages/micromegas/MicromegasDefs.h index c95fdffd72..b206b8f895 100644 --- a/offline/packages/micromegas/MicromegasDefs.h +++ b/offline/packages/micromegas/MicromegasDefs.h @@ -60,11 +60,15 @@ namespace MicromegasDefs /*! * @brief Generate a hitkey from strip index inside tile * @param[in] strip strip index + * @param[in] sample sample index */ - TrkrDefs::hitkey genHitKey(uint16_t strip ); + TrkrDefs::hitkey genHitKey(uint16_t strip, uint16_t sample = 0 ); //! get strip from hit key - uint16_t getStrip(TrkrDefs::hitkey); + uint8_t getStrip(TrkrDefs::hitkey); + + //! get sample from hit key + uint16_t getSample(TrkrDefs::hitkey); /*! * @brief Get the segmentation type from cluster key diff --git a/offline/packages/mvtx/CylinderGeom_Mvtx.cc b/offline/packages/mvtx/CylinderGeom_Mvtx.cc index e220d1474d..ab22c80bdc 100644 --- a/offline/packages/mvtx/CylinderGeom_Mvtx.cc +++ b/offline/packages/mvtx/CylinderGeom_Mvtx.cc @@ -8,7 +8,6 @@ #include #include // for operator<<, basic_ostream::operator<<, basic_... -using namespace std; using Segmentation = SegmentationAlpide; CylinderGeom_Mvtx::CylinderGeom_Mvtx( @@ -89,7 +88,7 @@ void CylinderGeom_Mvtx::get_sensor_indices_from_world_coords(std::vector double chip_delta_z = (inner_loc_chip_in_module[8][2] - inner_loc_chip_in_module[0][2]) / 8.0; // int chip_tmp = (int) (world[2]/chip_delta_z) + 4; // 0-9 int chip_tmp = round(world[2] / chip_delta_z) + 4; // 0-9 - // std::cout << " z " << world[2] << " chip_delta_z " << chip_delta_z << " chip_tmp " << chip_tmp << endl; + // std::cout << " z " << world[2] << " chip_delta_z " << chip_delta_z << " chip_tmp " << chip_tmp << std::endl; stave_index = stave_tmp; chip_index = chip_tmp; @@ -102,15 +101,15 @@ bool CylinderGeom_Mvtx::get_pixel_from_local_coords(TVector3 sensor_local, int& double EPS = 5e-6; if (fabs(fabs(sensor_local.X()) - SegmentationAlpide::ActiveMatrixSizeRows / 2.F) < EPS) { - // cout << " Adjusting X, before X= " << sensor_local.X() << endl; + // std::cout << " Adjusting X, before X= " << sensor_local.X() << std::endl; sensor_local.SetX(((sensor_local.X() < 0) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeRows / 2.F - EPS)); - // cout << " Adjusting X, after X= " << sensor_local.X() << endl; + // std::cout << " Adjusting X, after X= " << sensor_local.X() << std::endl; } if (fabs(fabs(sensor_local.Z()) - SegmentationAlpide::ActiveMatrixSizeCols / 2.F) < EPS) { - // cout << " Adjusting Z, before Z= " << sensor_local.Z() << endl; + // std::cout << " Adjusting Z, before Z= " << sensor_local.Z() << std::endl; sensor_local.SetZ(((sensor_local.Z() < 0) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeCols / 2.F - EPS)); - // cout << " Adjusting Z, after Z= " << sensor_local.Z() << endl; + // std::cout << " Adjusting Z, after Z= " << sensor_local.Z() << std::endl; } // YCM (2020-01-02): go from sensor to chip local coords TVector3 in_chip = sensor_local; @@ -122,21 +121,22 @@ bool CylinderGeom_Mvtx::get_pixel_from_local_coords(TVector3 sensor_local, int& int CylinderGeom_Mvtx::get_pixel_from_local_coords(const TVector3& sensor_local) { - int Ngridx, Ngridz; + int Ngridx; + int Ngridz; bool px_in = get_pixel_from_local_coords(sensor_local, Ngridx, Ngridz); if (!px_in) { - cout << PHWHERE + std::cout << PHWHERE << " Pixel is out sensor. (" << sensor_local.X() << ", " << sensor_local.Y() << ", " << sensor_local.Z() << ")." - << endl; + << std::endl; } if (Ngridx < 0 || Ngridx >= get_NX() || Ngridz < 0 || Ngridz >= get_NZ()) { - cout << PHWHERE << "Wrong pixel value X= " << Ngridx << " and Z= " << Ngridz << endl; + std::cout << PHWHERE << "Wrong pixel value X= " << Ngridx << " and Z= " << Ngridz << std::endl; } // numbering starts at zero @@ -157,8 +157,8 @@ TVector3 CylinderGeom_Mvtx::get_local_coords_from_pixel(int iRow, int iCol) bool check = SegmentationAlpide::detectorToLocal((float) iRow, (float) iCol, local); if (!check) { - cout << PHWHERE << "Pixel coord ( " << iRow << ", " << iCol << " )" - << "out of range" << endl; + std::cout << PHWHERE << "Pixel coord ( " << iRow << ", " << iCol << " )" + << "out of range" << std::endl; } // Transform location in chip to location in sensors TVector3 trChipToSens(loc_sensor_in_chip[0], @@ -177,7 +177,7 @@ void CylinderGeom_Mvtx::identify(std::ostream& os) const << ", pixel_x: " << pixel_x << ", pixel_z: " << pixel_z << ", pixel_thickness: " << pixel_thickness - << endl; + << std::endl; return; } @@ -192,17 +192,17 @@ int CylinderGeom_Mvtx::get_NX() const return SegmentationAlpide::NRows; } -int CylinderGeom_Mvtx::get_pixel_X_from_pixel_number(int NXZ) +int CylinderGeom_Mvtx::get_pixel_X_from_pixel_number(int NXZ) const { return NXZ % get_NX(); } -int CylinderGeom_Mvtx::get_pixel_Z_from_pixel_number(int NXZ) +int CylinderGeom_Mvtx::get_pixel_Z_from_pixel_number(int NXZ) const { return NXZ / get_NX(); } -int CylinderGeom_Mvtx::get_pixel_number_from_xbin_zbin(int xbin, int zbin) // obsolete +int CylinderGeom_Mvtx::get_pixel_number_from_xbin_zbin(int xbin, int zbin) const // obsolete { return xbin + zbin * get_NX(); } diff --git a/offline/packages/mvtx/CylinderGeom_Mvtx.h b/offline/packages/mvtx/CylinderGeom_Mvtx.h index e28da2c594..047673a549 100644 --- a/offline/packages/mvtx/CylinderGeom_Mvtx.h +++ b/offline/packages/mvtx/CylinderGeom_Mvtx.h @@ -13,7 +13,7 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom public: CylinderGeom_Mvtx( int layer, - int in_Nstaves, + int in_N_staves, double in_layer_nominal_radius, double in_phistep, double in_phitilt, @@ -31,7 +31,7 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom { } - ~CylinderGeom_Mvtx() override {} + ~CylinderGeom_Mvtx() override = default; // from PHObject void identify(std::ostream& os = std::cout) const override; @@ -53,11 +53,11 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom TVector3 get_local_coords_from_pixel(int NXZ); TVector3 get_local_coords_from_pixel(int iRow, int iCol); - int get_pixel_X_from_pixel_number(int NXZ); + int get_pixel_X_from_pixel_number(int NXZ) const; - int get_pixel_Z_from_pixel_number(int NXZ); + int get_pixel_Z_from_pixel_number(int NXZ) const; - int get_pixel_number_from_xbin_zbin(int xbin, int zbin); // obsolete + int get_pixel_number_from_xbin_zbin(int xbin, int zbin) const; // obsolete double get_stave_phi_tilt() const { return stave_phi_tilt; } double get_stave_phi_0() const { return stave_phi_0; } diff --git a/offline/packages/mvtx/MvtxClusterPruner.cc b/offline/packages/mvtx/MvtxClusterPruner.cc index 24d41db63d..456b302dd9 100644 --- a/offline/packages/mvtx/MvtxClusterPruner.cc +++ b/offline/packages/mvtx/MvtxClusterPruner.cc @@ -12,108 +12,116 @@ #include #include -#include #include +#include -#include #include +#include namespace { //! range adaptor to be able to use range-based for loop - template class range_adaptor + template + class range_adaptor { - public: - range_adaptor( const T& range ):m_range(range){} - const typename T::first_type& begin() {return m_range.first;} - const typename T::second_type& end() {return m_range.second;} - private: + public: + explicit range_adaptor(const T& range) + : m_range(range) + { + } + const typename T::first_type& begin() { return m_range.first; } + const typename T::second_type& end() { return m_range.second; } + + private: T m_range; }; // print cluster information - void print_cluster_information( TrkrDefs::cluskey ckey, TrkrCluster* cluster ) + void print_cluster_information(TrkrDefs::cluskey ckey, TrkrCluster* cluster) { - if( cluster ) + if (cluster) { std::cout << " MVTX cluster: " << ckey - << " position: (" << cluster->getLocalX() << ", " << cluster->getLocalY() << ")" - << " size: " << (int)cluster->getSize() - << " layer: " << (int)TrkrDefs::getLayer(ckey) - << " stave: " << (int) MvtxDefs::getStaveId(ckey) - << " chip: " << (int)MvtxDefs::getChipId(ckey) - << " strobe: " << (int)MvtxDefs::getStrobeId(ckey) - << " index: " << (int)TrkrDefs::getClusIndex(ckey) - << std::endl; - } else { + << " position: (" << cluster->getLocalX() << ", " << cluster->getLocalY() << ")" + << " size: " << (int) cluster->getSize() + << " layer: " << (int) TrkrDefs::getLayer(ckey) + << " stave: " << (int) MvtxDefs::getStaveId(ckey) + << " chip: " << (int) MvtxDefs::getChipId(ckey) + << " strobe: " << MvtxDefs::getStrobeId(ckey) + << " index: " << (int) TrkrDefs::getClusIndex(ckey) + << std::endl; + } + else + { std::cout << " MVTX cluster: " << ckey - << " layer: " << (int)TrkrDefs::getLayer(ckey) - << " stave: " << (int) MvtxDefs::getStaveId(ckey) - << " chip: " << (int)MvtxDefs::getChipId(ckey) - << " strobe: " << (int)MvtxDefs::getStrobeId(ckey) - << " index: " << (int)TrkrDefs::getClusIndex(ckey) - << std::endl; + << " layer: " << (int) TrkrDefs::getLayer(ckey) + << " stave: " << (int) MvtxDefs::getStaveId(ckey) + << " chip: " << (int) MvtxDefs::getChipId(ckey) + << " strobe: " << MvtxDefs::getStrobeId(ckey) + << " index: " << (int) TrkrDefs::getClusIndex(ckey) + << std::endl; } } using hitkeyset_t = std::set; - using clustermap_t = std::map; + using clustermap_t = std::map; -} +} // namespace //_____________________________________________________________________________ -MvtxClusterPruner::MvtxClusterPruner(const std::string &name) +MvtxClusterPruner::MvtxClusterPruner(const std::string& name) : SubsysReco(name) { } //_____________________________________________________________________________ -int MvtxClusterPruner::InitRun(PHCompositeNode * /*topNode*/) +int MvtxClusterPruner::InitRun(PHCompositeNode* /*topNode*/) { std::cout << "MvtxClusterPruner::InitRun - m_use_strict_matching: " << m_use_strict_matching << std::endl; return Fun4AllReturnCodes::EVENT_OK; } //_____________________________________________________________________________ -int MvtxClusterPruner::process_event(PHCompositeNode *topNode) +int MvtxClusterPruner::process_event(PHCompositeNode* topNode) { // load relevant nodes - auto trkrclusters = findNode::getClass(topNode, "TRKR_CLUSTER"); - if( !trkrclusters ) + auto* trkrclusters = findNode::getClass(topNode, "TRKR_CLUSTER"); + if (!trkrclusters) { std::cout << "MvtxClusterPruner::process_event - TRKR_CLUSTER not found. Doing nothing" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); - if( !clusterhitassoc ) + auto* clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + if (!clusterhitassoc) { std::cout << "MvtxClusterPruner::process_event - TRKR_CLUSTERHITASSOC not found. Doing nothing" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } // lambda method to create map of cluster keys and associated hits - auto get_cluster_map = [trkrclusters,clusterhitassoc]( TrkrDefs::hitsetkey key ) + auto get_cluster_map = [trkrclusters, clusterhitassoc](TrkrDefs::hitsetkey key) { clustermap_t out; // get all clusters for this hitsetkey - const auto cluster_range= trkrclusters->getClusters(key); - for( const auto& [ckey,cluster]:range_adaptor(cluster_range) ) + const auto cluster_range = trkrclusters->getClusters(key); + for (const auto& [ckey, cluster] : range_adaptor(cluster_range)) { // get associated hits const auto& hit_range = clusterhitassoc->getHits(ckey); hitkeyset_t hitkeys; - std::transform(hit_range.first, hit_range.second, std::inserter(hitkeys,hitkeys.end()), - [](const TrkrClusterHitAssoc::Map::value_type& pair ){ return pair.second; }); - out.emplace(ckey,std::move(hitkeys)); + std::transform(hit_range.first, hit_range.second, std::inserter(hitkeys, hitkeys.end()), + [](const TrkrClusterHitAssoc::Map::value_type& pair) + { return pair.second; }); + out.emplace(ckey, std::move(hitkeys)); } return out; }; // loop over MVTX hitset keys const auto hitsetkeys = trkrclusters->getHitSetKeys(TrkrDefs::mvtxId); - for( const auto& hitsetkey:hitsetkeys ) + for (const auto& hitsetkey : hitsetkeys) { // get layer, stave, chip and current strobe const auto layer = TrkrDefs::getLayer(hitsetkey); @@ -125,111 +133,109 @@ int MvtxClusterPruner::process_event(PHCompositeNode *topNode) const auto cluster_map1 = get_cluster_map(hitsetkey); // get clusters for the next strobe - int next_strobe = current_strobe+1; + int next_strobe = current_strobe + 1; const auto hitsetkey_next_strobe = MvtxDefs::genHitSetKey(layer, stave, chip, next_strobe); const auto clusterk_map2 = get_cluster_map(hitsetkey_next_strobe); // loop over clusters from first range - for( auto [ckey1,hitkeys1]:cluster_map1) + for (auto [ckey1, hitkeys1] : cluster_map1) { // increment counter ++m_cluster_counter_total; // get correcponding cluser - auto cluster1 = Verbosity() ? trkrclusters->findCluster(ckey1):nullptr; + auto* cluster1 = Verbosity() ? trkrclusters->findCluster(ckey1) : nullptr; // loop over clusters from second range - for( auto [ckey2,hitkeys2]:clusterk_map2) + for (auto [ckey2, hitkeys2] : clusterk_map2) { - auto cluster2 = Verbosity() ? trkrclusters->findCluster(ckey2):nullptr; + auto* cluster2 = Verbosity() ? trkrclusters->findCluster(ckey2) : nullptr; - if( m_use_strict_matching ) + if (m_use_strict_matching) { // see if hitsets are identical - if(hitkeys1 == hitkeys2) + if (hitkeys1 == hitkeys2) { // increment counter ++m_cluster_counter_deleted; - if( Verbosity() ) + if (Verbosity()) { std::cout << "Removing cluster "; - print_cluster_information( ckey2, cluster2); + print_cluster_information(ckey2, cluster2); std::cout << "Keeping cluster "; - print_cluster_information( ckey1, cluster1); + print_cluster_information(ckey1, cluster1); } // always remove second cluster trkrclusters->removeCluster(ckey2); break; } - - } else { - + } + else + { // make sure first set is larger than second const bool swapped = hitkeys2.size() > hitkeys1.size(); - if( swapped ) { std::swap(hitkeys2,hitkeys1); } + if (swapped) + { + std::swap(hitkeys2, hitkeys1); + } // see if hitkeys2 is a subset of hitkeys1 - if( std::includes(hitkeys1.begin(), hitkeys1.end(), hitkeys2.begin(), hitkeys2.end()) ) + if (std::includes(hitkeys1.begin(), hitkeys1.end(), hitkeys2.begin(), hitkeys2.end())) { // increment counter ++m_cluster_counter_deleted; - if( swapped ) + if (swapped) { - - if( Verbosity() ) + if (Verbosity()) { std::cout << "Removing cluster "; - print_cluster_information( ckey1, cluster1); + print_cluster_information(ckey1, cluster1); std::cout << "Keeping cluster "; - print_cluster_information( ckey2, cluster2); + print_cluster_information(ckey2, cluster2); } // remove first cluster trkrclusters->removeCluster(ckey1); break; - } else { - - if( Verbosity() ) - { - std::cout << "Removing cluster "; - print_cluster_information( ckey2, cluster2); - - std::cout << "Keeping cluster "; - print_cluster_information( ckey1, cluster1); - } + } + if (Verbosity()) + { + std::cout << "Removing cluster "; + print_cluster_information(ckey2, cluster2); - // remove second cluster - trkrclusters->removeCluster(ckey2); + std::cout << "Keeping cluster "; + print_cluster_information(ckey1, cluster1); } + + // remove second cluster + trkrclusters->removeCluster(ckey2); } - } // strict matching + } // strict matching - } // second cluster loop - } // first cluster loop - } // hitsetkey loop + } // second cluster loop + } // first cluster loop + } // hitsetkey loop return Fun4AllReturnCodes::EVENT_OK; - } //_____________________________________________________________________________ -int MvtxClusterPruner::End(PHCompositeNode * /*topNode*/) +int MvtxClusterPruner::End(PHCompositeNode* /*topNode*/) { - std::cout << "MvtxClusterPruner::End -" - << " m_cluster_counter_total: " << m_cluster_counter_total - << std::endl; - std::cout << "MvtxClusterPruner::End -" - << " m_cluster_counter_deleted: " << m_cluster_counter_deleted - << " fraction: " << double( m_cluster_counter_deleted )/m_cluster_counter_total - << std::endl; + << " m_cluster_counter_total: " << m_cluster_counter_total + << std::endl; + std::cout << "MvtxClusterPruner::End -" + << " m_cluster_counter_deleted: " << m_cluster_counter_deleted + << " fraction: " << double(m_cluster_counter_deleted) / m_cluster_counter_total + << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/mvtx/MvtxClusterizer.cc b/offline/packages/mvtx/MvtxClusterizer.cc index 7970b369eb..eb54930acd 100644 --- a/offline/packages/mvtx/MvtxClusterizer.cc +++ b/offline/packages/mvtx/MvtxClusterizer.cc @@ -63,7 +63,7 @@ namespace /// convenience square method template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -71,65 +71,45 @@ namespace bool MvtxClusterizer::are_adjacent( const std::pair &lhs, - const std::pair &rhs) + const std::pair &rhs) const { if (GetZClustering()) { return - // column adjacent - ( (MvtxDefs::getCol(lhs.first) > MvtxDefs::getCol(rhs.first)) ? - MvtxDefs::getCol(lhs.first)<=MvtxDefs::getCol(rhs.first)+1: - MvtxDefs::getCol(rhs.first)<=MvtxDefs::getCol(lhs.first)+1) && + // column adjacent + ((MvtxDefs::getCol(lhs.first) > MvtxDefs::getCol(rhs.first)) ? MvtxDefs::getCol(lhs.first) <= MvtxDefs::getCol(rhs.first) + 1 : MvtxDefs::getCol(rhs.first) <= MvtxDefs::getCol(lhs.first) + 1) && - // row adjacent - ( (MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? - MvtxDefs::getRow(lhs.first)<=MvtxDefs::getRow(rhs.first)+1: - MvtxDefs::getRow(rhs.first)<=MvtxDefs::getRow(lhs.first)+1); - - } else { - - return + // row adjacent + ((MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? MvtxDefs::getRow(lhs.first) <= MvtxDefs::getRow(rhs.first) + 1 : MvtxDefs::getRow(rhs.first) <= MvtxDefs::getRow(lhs.first) + 1); + } + return // column identical - MvtxDefs::getCol(rhs.first)==MvtxDefs::getCol(lhs.first) && + MvtxDefs::getCol(rhs.first) == MvtxDefs::getCol(lhs.first) && // row adjacent - ( (MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? - MvtxDefs::getRow(lhs.first)<=MvtxDefs::getRow(rhs.first)+1: - MvtxDefs::getRow(rhs.first)<=MvtxDefs::getRow(lhs.first)+1); - - } + ((MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? MvtxDefs::getRow(lhs.first) <= MvtxDefs::getRow(rhs.first) + 1 : MvtxDefs::getRow(rhs.first) <= MvtxDefs::getRow(lhs.first) + 1); } -bool MvtxClusterizer::are_adjacent(RawHit *lhs, RawHit *rhs) +bool MvtxClusterizer::are_adjacent(RawHit *lhs, RawHit *rhs) const { if (GetZClustering()) { return - // phi adjacent (== column) - ((lhs->getPhiBin() > rhs->getPhiBin()) ? - lhs->getPhiBin() <= rhs->getPhiBin()+1: - rhs->getPhiBin() <= lhs->getPhiBin()+1) && + // phi adjacent (== column) + ((lhs->getPhiBin() > rhs->getPhiBin()) ? lhs->getPhiBin() <= rhs->getPhiBin() + 1 : rhs->getPhiBin() <= lhs->getPhiBin() + 1) && - // time adjacent (== row) - ((lhs->getTBin() > rhs->getTBin()) ? - lhs->getTBin() <= rhs->getTBin()+1: - rhs->getTBin() <= lhs->getTBin()+1); - - } else { - - return + // time adjacent (== row) + ((lhs->getTBin() > rhs->getTBin()) ? lhs->getTBin() <= rhs->getTBin() + 1 : rhs->getTBin() <= lhs->getTBin() + 1); + } + return // phi identical (== column) lhs->getPhiBin() == rhs->getPhiBin() && // time adjacent (== row) - ((lhs->getTBin() > rhs->getTBin()) ? - lhs->getTBin() <= rhs->getTBin()+1: - rhs->getTBin() <= lhs->getTBin()+1); - - } + ((lhs->getTBin() > rhs->getTBin()) ? lhs->getTBin() <= rhs->getTBin() + 1 : rhs->getTBin() <= lhs->getTBin() + 1); } MvtxClusterizer::MvtxClusterizer(const std::string &name) @@ -165,7 +145,7 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { @@ -183,7 +163,7 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { @@ -208,14 +188,14 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) if (!mClusHitsVerbose) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); dstNode->addNode(DetNode); } mClusHitsVerbose = new ClusHitsVerbosev1(); - auto newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); + auto *newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); DetNode->addNode(newNode); } } @@ -227,13 +207,13 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << "====================== MvtxClusterizer::InitRun() " - "=====================" - << std::endl; + "=====================" + << std::endl; std::cout << " Z-dimension Clustering = " << std::boolalpha << m_makeZClustering - << std::noboolalpha << std::endl; + << std::noboolalpha << std::endl; std::cout << "==================================================================" - "=========" - << std::endl; + "=========" + << std::endl; } return Fun4AllReturnCodes::EVENT_OK; @@ -283,7 +263,7 @@ int MvtxClusterizer::process_event(PHCompositeNode *topNode) // reset MVTX clusters and cluster associations const auto hitsetkeys = m_clusterlist->getHitSetKeys(TrkrDefs::mvtxId); - for( const auto& hitsetkey:hitsetkeys) + for (const auto &hitsetkey : hitsetkeys) { m_clusterlist->removeClusters(hitsetkey); m_clusterhitassoc->removeAssocs(hitsetkey); @@ -337,8 +317,8 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) unsigned int chip = MvtxDefs::getChipId(hitsetitr->first); unsigned int strobe = MvtxDefs::getStrobeId(hitsetitr->first); std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first - << " layer " << layer << " stave " << stave << " chip " << chip - << " strobe " << strobe << std::endl; + << " layer " << layer << " stave " << stave << " chip " << chip + << " strobe " << strobe << std::endl; } if (Verbosity() > 2) @@ -394,7 +374,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) std::vector component(num_vertices(G)); // this is the actual clustering, performed by boost - boost::connected_components(G, &component[0]); + boost::connected_components(G, component.data()); // Loop over the components(hits) compiling a list of the // unique connected groups (ie. clusters). @@ -405,7 +385,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) cluster_ids.insert(component[i]); clusters.insert(make_pair(component[i], hitvec[i])); } - for (const auto& clusid:cluster_ids) + for (const auto &clusid : cluster_ids) { auto clusrange = clusters.equal_range(clusid); auto ckey = TrkrDefs::genClusKey(hitset->getHitSetKey(), clusid); @@ -413,7 +393,8 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) // determine the size of the cluster in phi and z std::set phibins; std::set zbins; - std::map m_phi, m_z; // Note, there are no "cut" bins for Svtx Clusters + std::map m_phi; + std::map m_z; // Note, there are no "cut" bins for Svtx Clusters // determine the cluster position... double locxsum = 0.; @@ -426,7 +407,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) // we need the geometry object for this layer to get the global positions int layer = TrkrDefs::getLayer(ckey); - auto layergeom = dynamic_cast(geom_container->GetLayerGeom(layer)); + auto *layergeom = dynamic_cast(geom_container->GetLayerGeom(layer)); if (!layergeom) { exit(1); @@ -574,11 +555,11 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer - << " rad " << layergeom->get_radius() << " phibins " - << phibins.size() << " pitch " << pitch << " phisize " << phisize - << " zbins " << zbins.size() << " length " << length << " zsize " - << zsize << " local x " << locclusx << " local y " << locclusz - << std::endl; + << " rad " << layergeom->get_radius() << " phibins " + << phibins.size() << " pitch " << pitch << " phisize " << phisize + << " zbins " << zbins.size() << " length " << length << " zsize " + << zsize << " local x " << locclusx << " local y " << locclusz + << std::endl; } auto clus = std::make_unique(); @@ -605,7 +586,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) } } // clusitr loop - } // loop over hitsets + } // loop over hitsets if (Verbosity() > 1) { @@ -650,8 +631,8 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) unsigned int chip = MvtxDefs::getChipId(hitsetitr->first); unsigned int strobe = MvtxDefs::getStrobeId(hitsetitr->first); std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first - << " layer " << layer << " stave " << stave << " chip " << chip - << " strobe " << strobe << std::endl; + << " layer " << layer << " stave " << stave << " chip " << chip + << " strobe " << strobe << std::endl; } if (Verbosity() > 2) @@ -695,7 +676,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) std::vector component(num_vertices(G)); // this is the actual clustering, performed by boost - boost::connected_components(G, &component[0]); + boost::connected_components(G, component.data()); // Loop over the components(hits) compiling a list of the // unique connected groups (ie. clusters). @@ -709,7 +690,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) } // std::cout << "found cluster #: "<< clusters.size()<< std::endl; // loop over the componenets and make clusters - for( const auto& clusid:cluster_ids) + for (const auto &clusid : cluster_ids) { auto clusrange = clusters.equal_range(clusid); @@ -731,7 +712,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) // we need the geometry object for this layer to get the global positions int layer = TrkrDefs::getLayer(ckey); - auto layergeom = dynamic_cast( + auto *layergeom = dynamic_cast( geom_container->GetLayerGeom(layer)); if (!layergeom) { @@ -845,11 +826,11 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer - << " rad " << layergeom->get_radius() << " phibins " - << phibins.size() << " pitch " << pitch << " phisize " << phisize - << " zbins " << zbins.size() << " length " << length << " zsize " - << zsize << " local x " << locclusx << " local y " << locclusz - << std::endl; + << " rad " << layergeom->get_radius() << " phibins " + << phibins.size() << " pitch " << pitch << " phisize " << phisize + << " zbins " << zbins.size() << " length " << length << " zsize " + << zsize << " local x " << locclusx << " local y " << locclusz + << std::endl; } auto clus = std::make_unique(); @@ -875,7 +856,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) m_clusterlist->addClusterSpecifyKey(ckey, clus.release()); } } // clusitr loop - } // loop over hitsets + } // loop over hitsets if (Verbosity() > 1) { @@ -898,11 +879,11 @@ void MvtxClusterizer::PrintClusters(PHCompositeNode *topNode) } std::cout << "================= After MvtxClusterizer::process_event() " - "====================" - << std::endl; + "====================" + << std::endl; std::cout << " There are " << clusterlist->size() - << " clusters recorded: " << std::endl; + << " clusters recorded: " << std::endl; if (Verbosity() > 3) { @@ -910,8 +891,8 @@ void MvtxClusterizer::PrintClusters(PHCompositeNode *topNode) } std::cout << "==================================================================" - "=========" - << std::endl; + "=========" + << std::endl; } return; diff --git a/offline/packages/mvtx/MvtxClusterizer.h b/offline/packages/mvtx/MvtxClusterizer.h index ce4794b5d1..10c65914cd 100644 --- a/offline/packages/mvtx/MvtxClusterizer.h +++ b/offline/packages/mvtx/MvtxClusterizer.h @@ -65,8 +65,8 @@ class MvtxClusterizer : public SubsysReco private: // bool are_adjacent(const pixel lhs, const pixel rhs); bool record_ClusHitsVerbose{false}; - bool are_adjacent(const std::pair &lhs, const std::pair &rhs); - bool are_adjacent(RawHit *lhs, RawHit *rhs); + bool are_adjacent(const std::pair &lhs, const std::pair &rhs) const; + bool are_adjacent(RawHit *lhs, RawHit *rhs) const; void ClusterMvtx(PHCompositeNode *topNode); void ClusterMvtxRaw(PHCompositeNode *topNode); diff --git a/offline/packages/mvtx/MvtxHitPruner.cc b/offline/packages/mvtx/MvtxHitPruner.cc index 4f141a4c3f..58cbb423c4 100644 --- a/offline/packages/mvtx/MvtxHitPruner.cc +++ b/offline/packages/mvtx/MvtxHitPruner.cc @@ -51,26 +51,33 @@ namespace { //! range adaptor to be able to use range-based for loop - template class range_adaptor + template + class range_adaptor { - public: - range_adaptor( const T& range ):m_range(range){} - const typename T::first_type& begin() {return m_range.first;} - const typename T::second_type& end() {return m_range.second;} - private: + public: + explicit range_adaptor(const T& range) + : m_range(range) + { + } + const typename T::first_type& begin() { return m_range.first; } + const typename T::second_type& end() { return m_range.second; } + + private: T m_range; }; -} +} // namespace -MvtxHitPruner::MvtxHitPruner(const std::string &name) +MvtxHitPruner::MvtxHitPruner(const std::string& name) : SubsysReco(name) { } -int MvtxHitPruner::InitRun(PHCompositeNode * /*topNode*/) -{ return Fun4AllReturnCodes::EVENT_OK; } +int MvtxHitPruner::InitRun(PHCompositeNode* /*topNode*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} -int MvtxHitPruner::process_event(PHCompositeNode *topNode) +int MvtxHitPruner::process_event(PHCompositeNode* topNode) { // get node containing the digitized hits m_hits = findNode::getClass(topNode, "TRKR_HITSET"); @@ -93,12 +100,14 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) std::set bare_hitset_set; const auto hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::mvtxId); - for( const auto& [hitsetkey,hitset]:range_adaptor(hitsetrange) ) + for (const auto& [hitsetkey, hitset] : range_adaptor(hitsetrange)) { - // get strobe, skip if already zero const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) continue; + if (strobe == 0) + { + continue; + } // get the hitsetkey value for strobe 0 const auto bare_hitsetkey = MvtxDefs::resetStrobe(hitsetkey); @@ -117,43 +126,46 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) for (const auto& bare_hitsetkey : bare_hitset_set) { // find matching hitset of creater - auto bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; + auto* bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - bare_hitset " << bare_hitsetkey - << " initially has " << bare_hitset->size() << " hits " - << std::endl; + << "MvtxHitPruner::process_event - bare_hitset " << bare_hitsetkey + << " initially has " << bare_hitset->size() << " hits " + << std::endl; } // get all hitsets with non-zero strobe that match the bare hitset key auto bare_hitsetrange = hitset_multimap.equal_range(bare_hitsetkey); - for( const auto& [unused,hitsetkey]:range_adaptor(bare_hitsetrange) ) + for (const auto& [unused, hitsetkey] : range_adaptor(bare_hitsetrange)) { const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) continue; + if (strobe == 0) + { + continue; + } if (Verbosity()) { std::cout << "MvtxHitPruner::process_event -" - << " process hitsetkey " << hitsetkey - << " from strobe " << strobe - << " for bare_hitsetkey " << bare_hitsetkey - << std::endl; + << " process hitsetkey " << hitsetkey + << " from strobe " << strobe + << " for bare_hitsetkey " << bare_hitsetkey + << std::endl; } // copy all hits to the hitset with strobe 0 - auto hitset = m_hits->findHitSet(hitsetkey); + auto* hitset = m_hits->findHitSet(hitsetkey); if (Verbosity()) { std::cout << "MvtxHitPruner::process_event - hitsetkey " << hitsetkey - << " has strobe " << strobe << " and has " << hitset->size() - << " hits, so copy it" << std::endl; + << " has strobe " << strobe << " and has " << hitset->size() + << " hits, so copy it" << std::endl; } TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - for( const auto& [hitkey,old_hit]:range_adaptor(hitrangei) ) + for (const auto& [hitkey, old_hit] : range_adaptor(hitrangei)) { if (Verbosity()) { @@ -166,9 +178,9 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - hitkey " << hitkey - << " is already in bare hitsest, do not copy" - << std::endl; + << "MvtxHitPruner::process_event - hitkey " << hitkey + << " is already in bare hitsest, do not copy" + << std::endl; } continue; } @@ -177,11 +189,11 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - copying over hitkey " - << hitkey << std::endl; + << "MvtxHitPruner::process_event - copying over hitkey " + << hitkey << std::endl; } - auto new_hit = new TrkrHitv2; + auto* new_hit = new TrkrHitv2; new_hit->CopyFrom(old_hit); bare_hitset->addHitSpecificKey(hitkey, new_hit); } diff --git a/offline/packages/mvtx/SegmentationAlpide.cc b/offline/packages/mvtx/SegmentationAlpide.cc index 6b9aecddd0..0b1aae48cf 100644 --- a/offline/packages/mvtx/SegmentationAlpide.cc +++ b/offline/packages/mvtx/SegmentationAlpide.cc @@ -5,16 +5,15 @@ */ #include "SegmentationAlpide.h" -#include - #include +#include void SegmentationAlpide::print() { - std::cout << (boost::format("Pixel size: %.2f (along %d rows) %.2f (along %d columns) microns") % (PitchRow * 1e4) % NRows % (PitchCol * 1e4) % NCols).str() + std::cout << std::format("Pixel size: {:.2f} (along {} rows) {:.2f} (along {} columns) microns", (PitchRow * 1e4), NRows, (PitchCol * 1e4), NCols) << std::endl; - std::cout << (boost::format("Passive edges: bottom: %.2f, top: %.2f, left/right: %.2f microns") % (PassiveEdgeReadOut * 1e4) % (PassiveEdgeTop * 1e4) % (PassiveEdgeSide * 1e4)).str() + std::cout << std::format("Passive edges: bottom: {:.2f}, top: {:.2f}, left/right: {:.2f} microns", (PassiveEdgeReadOut * 1e4), (PassiveEdgeTop * 1e4), (PassiveEdgeSide * 1e4)) << std::endl; - std::cout << (boost::format("Active/Total size: %.6f/%.6f (rows) %.6f/%.6f (cols) cm") % ActiveMatrixSizeRows % SensorSizeRows % ActiveMatrixSizeCols % SensorSizeCols).str() + std::cout << std::format("Active/Total size: {:.6f}/{:.6f} (rows) {:.6f}/{:.6f} (cols) cm", ActiveMatrixSizeRows, SensorSizeRows, ActiveMatrixSizeCols, SensorSizeCols) << std::endl; } diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 170f95944d..754ee8d248 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -31,13 +31,10 @@ #include #include +#include #include #include #include -//#include -//#include -#include -//#include #include #include @@ -46,15 +43,16 @@ #include #include // for sqrt, cos, sin +#include #include #include #include // for _Rb_tree_cons... +#include +#include #include +#include #include // for pair #include -#include -#include -#include #include @@ -68,12 +66,9 @@ using adcKey = std::pair; using pointKeyLaser = std::pair; using hitData = std::pair; - -int layerMins[3] = {7,23,39}; +int layerMins[3] = {7, 23, 39}; int layerMaxes[3] = {22, 38, 54}; - - namespace { struct thread_data @@ -101,28 +96,25 @@ namespace pthread_mutex_t mythreadlock; const std::vector neighborOffsets = { - point(1, 0, 0), point(-1, 0, 0), - point(0, 1, 0), point(0, -1, 0), - point(0, 0, 1), point(0, 0, -1), - point(0, 0, 2), point(0, 0, -2) - }; - + point(1, 0, 0), point(-1, 0, 0), + point(0, 1, 0), point(0, -1, 0), + point(0, 0, 1), point(0, 0, -1), + point(0, 0, 2), point(0, 0, -2)}; - double layerFunction(double *x, double *par) + double layerFunction(double *x, const double *par) { double A = par[0]; double mu = par[1]; - double binCenter = round(x[0]); double overlapLow = std::max(binCenter - 0.5, mu - 0.5); double overlapHigh = std::min(binCenter + 0.5, mu + 0.5); double overlap = overlapHigh - overlapLow; - if(overlap <= 0.0) + if (overlap <= 0.0) { return 0.0; } - return A*overlap; + return A * overlap; /* if(fabs(x[0] - mu) < 1) { @@ -131,28 +123,26 @@ namespace } return 0.0; */ - - } double phiFunction(double *x, double *par) { - if(par[2] < 0.0) + if (par[2] < 0.0) { return 0.0; } - return par[0] * TMath::Gaus(x[0],par[1],par[2],false); + return par[0] * TMath::Gaus(x[0], par[1], par[2], false); } double timeFunction(double *x, double *par) { - if(par[2] < 0.0) + if (par[2] < 0.0) { return 0.0; } - double g = TMath::Gaus(x[0],par[1],par[2],true); - double cdf = 1 + TMath::Erfc(par[3]*(x[0]-par[1])/(sqrt(2.0)*par[2])); - return par[0]*g*cdf; + double g = TMath::Gaus(x[0], par[1], par[2], true); + double cdf = 1 + TMath::Erfc(par[3] * (x[0] - par[1]) / (sqrt(2.0) * par[2])); + return par[0] * g * cdf; } void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey) @@ -160,21 +150,22 @@ namespace std::vector> regions; std::vector unvisited; - for(auto &clusHit : clusHits) + unvisited.reserve(clusHits.size()); + for (auto &clusHit : clusHits) { unvisited.push_back(clusHit); } - while(!unvisited.empty()) + while (!unvisited.empty()) { std::vector region; std::queue q; unsigned int mIndex = 0; - int i=0; - for(auto hit : unvisited) + int i = 0; + for (auto hit : unvisited) { - if(hit.second.second.first == maxKey.first && hit.second.second.second == maxKey.second) + if (hit.second.second.first == maxKey.first && hit.second.second.second == maxKey.second) { mIndex = i; break; @@ -183,11 +174,11 @@ namespace } auto seed = unvisited[mIndex]; - unvisited.erase(unvisited.begin()+mIndex); + unvisited.erase(unvisited.begin() + mIndex); q.push(seed); region.push_back(seed); - while(!q.empty()) + while (!q.empty()) { float ix = q.front().first.get<0>(); float iy = q.front().first.get<1>(); @@ -200,13 +191,12 @@ namespace float ny = iy + neigh.get<1>(); float nz = iz + neigh.get<2>(); - for(unsigned int v=0; v() - nx) < 0.01 && fabs(unvisited[v].first.get<1>() - ny) < 0.01 && fabs(unvisited[v].first.get<2>() - nz) < 0.01) + if (fabs(unvisited[v].first.get<0>() - nx) < 0.01 && fabs(unvisited[v].first.get<1>() - ny) < 0.01 && fabs(unvisited[v].first.get<2>() - nz) < 0.01) { auto newSeed = unvisited[v]; - unvisited.erase(unvisited.begin()+v); + unvisited.erase(unvisited.begin() + v); q.push(newSeed); region.push_back(newSeed); break; @@ -215,18 +205,15 @@ namespace } } regions.push_back(region); - } clusHits.clear(); - for(auto hit : regions[0]) + for (auto hit : regions[0]) { clusHits.push_back(hit); } - } - void remove_hits(std::vector &clusHits, bgi::rtree> &rtree, std::multimap &adcMap) { for (auto &clusHit : clusHits) @@ -237,51 +224,44 @@ namespace for (auto iterAdc = adcMap.begin(); iterAdc != adcMap.end();) { - if(iterAdc->second.second == spechitkey) - { - iterAdc = adcMap.erase(iterAdc); - break; - } - else - { - ++iterAdc; - } + if (iterAdc->second.second == spechitkey) + { + iterAdc = adcMap.erase(iterAdc); + break; + } + + ++iterAdc; } } - } void calc_cluster_parameter(std::vector &clusHits, thread_data &my_data, std::pair maxADCKey) { - - - findConnectedRegions3(clusHits, maxADCKey); - double rSum = 0.0; double phiSum = 0.0; double tSum = 0.0; - + double layerSum = 0.0; double iphiSum = 0.0; double itSum = 0.0; - + double adcSum = 0.0; - + double maxAdc = 0.0; TrkrDefs::hitsetkey maxKey = 0; - + unsigned int nHits = clusHits.size(); - + auto *clus = new LaserClusterv2; - + int meanSide = 0; - + std::vector usedLayer; std::vector usedIPhi; std::vector usedIT; - + double meanLayer = 0.0; double meanIPhi = 0.0; double meanIT = 0.0; @@ -293,113 +273,110 @@ namespace unsigned int adc = clusHit.second.first; int side = TpcDefs::getSide(spechitkey.second); - + if (side) { - meanSide++; + meanSide++; } else { - meanSide--; + meanSide--; } - + PHG4TpcGeom *layergeom = my_data.geom_container->GetLayerCellGeom((int) coords[0]); - + double r = layergeom->get_radius(); double phi = layergeom->get_phi(coords[1], side); double t = layergeom->get_zcenter(fabs(coords[2])); - + double hitzdriftlength = t * my_data.tGeometry->get_drift_velocity(); double hitZ = my_data.tdriftmax * my_data.tGeometry->get_drift_velocity() - hitzdriftlength; - - - bool foundLayer = false; - for (float i : usedLayer) - { - if (coords[0] == i) - { - foundLayer = true; - break; - } - } - - if (!foundLayer) - { - usedLayer.push_back(coords[0]); - } - - bool foundIPhi = false; - for (float i : usedIPhi) - { - if (coords[1] == i) - { - foundIPhi = true; - break; - } - } - - if (!foundIPhi) - { - usedIPhi.push_back(coords[1]); - } - - bool foundIT = false; - for (float i : usedIT) - { - if (coords[2] == i) - { - foundIT = true; - break; - } - } - - if (!foundIT) - { - usedIT.push_back(coords[2]); - } - - clus->addHit(); - clus->setHitLayer(clus->getNhits() - 1, coords[0]); - clus->setHitIPhi(clus->getNhits() - 1, coords[1]); - clus->setHitIT(clus->getNhits() - 1, coords[2]); - clus->setHitX(clus->getNhits() - 1, r * cos(phi)); - clus->setHitY(clus->getNhits() - 1, r * sin(phi)); - clus->setHitZ(clus->getNhits() - 1, hitZ); - clus->setHitAdc(clus->getNhits() - 1, (float) adc); - - rSum += r * adc; - phiSum += phi * adc; - tSum += t * adc; - - layerSum += coords[0] * adc; - iphiSum += coords[1] * adc; - itSum += coords[2] * adc; - - meanLayer += coords[0]; - meanIPhi += coords[1]; - meanIT += coords[2]; - - adcSum += adc; - - if (adc > maxAdc) - { - maxAdc = adc; - maxKey = spechitkey.second; - } - - } - + + bool foundLayer = false; + for (float i : usedLayer) + { + if (coords[0] == i) + { + foundLayer = true; + break; + } + } + + if (!foundLayer) + { + usedLayer.push_back(coords[0]); + } + + bool foundIPhi = false; + for (float i : usedIPhi) + { + if (coords[1] == i) + { + foundIPhi = true; + break; + } + } + + if (!foundIPhi) + { + usedIPhi.push_back(coords[1]); + } + + bool foundIT = false; + for (float i : usedIT) + { + if (coords[2] == i) + { + foundIT = true; + break; + } + } + + if (!foundIT) + { + usedIT.push_back(coords[2]); + } + + clus->addHit(); + clus->setHitLayer(clus->getNhits() - 1, coords[0]); + clus->setHitIPhi(clus->getNhits() - 1, coords[1]); + clus->setHitIT(clus->getNhits() - 1, coords[2]); + clus->setHitX(clus->getNhits() - 1, r * cos(phi)); + clus->setHitY(clus->getNhits() - 1, r * sin(phi)); + clus->setHitZ(clus->getNhits() - 1, hitZ); + clus->setHitAdc(clus->getNhits() - 1, (float) adc); + + rSum += r * adc; + phiSum += phi * adc; + tSum += t * adc; + + layerSum += coords[0] * adc; + iphiSum += coords[1] * adc; + itSum += coords[2] * adc; + + meanLayer += coords[0]; + meanIPhi += coords[1]; + meanIT += coords[2]; + + adcSum += adc; + + if (adc > maxAdc) + { + maxAdc = adc; + maxKey = spechitkey.second; + } + } + if (nHits == 0) { return; } - double clusR = rSum / adcSum; double clusPhi = phiSum / adcSum; double clusT = tSum / adcSum; double zdriftlength = clusT * my_data.tGeometry->get_drift_velocity(); - + double clusX = clusR * cos(clusPhi); double clusY = clusR * sin(clusPhi); double clusZ = my_data.tdriftmax * my_data.tGeometry->get_drift_velocity() - zdriftlength; @@ -408,10 +385,10 @@ namespace clusZ = -clusZ; for (int i = 0; i < (int) clus->getNhits(); i++) { - clus->setHitZ(i, -1 * clus->getHitZ(i)); + clus->setHitZ(i, -1 * clus->getHitZ(i)); } } - + std::sort(usedLayer.begin(), usedLayer.end()); std::sort(usedIPhi.begin(), usedIPhi.end()); std::sort(usedIT.begin(), usedIT.end()); @@ -419,30 +396,28 @@ namespace meanLayer = meanLayer / nHits; meanIPhi = meanIPhi / nHits; meanIT = meanIT / nHits; - + double sigmaLayer = 0.0; double sigmaIPhi = 0.0; double sigmaIT = 0.0; - + double sigmaWeightedLayer = 0.0; double sigmaWeightedIPhi = 0.0; double sigmaWeightedIT = 0.0; - - pthread_mutex_lock(&mythreadlock); - my_data.hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); + pthread_mutex_lock(&mythreadlock); + my_data.hitHist = new TH3D(std::format("hitHist_event{}_side{}_sector{}_module{}_cluster{}", my_data.eventNum, (int) my_data.side, (int) my_data.sector, (int) my_data.module, (int) my_data.cluster_vector.size()).c_str(), ";layer;iphi;it", usedLayer.size() + 2, usedLayer[0] - 1.5, *usedLayer.rbegin() + 1.5, usedIPhi.size() + 2, usedIPhi[0] - 1.5, *usedIPhi.rbegin() + 1.5, usedIT.size() + 2, usedIT[0] - 1.5, *usedIT.rbegin() + 1.5); - //TH3D *hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); + // TH3D *hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); for (int i = 0; i < (int) clus->getNhits(); i++) { - my_data.hitHist->Fill(clus->getHitLayer(i), clus->getHitIPhi(i), clus->getHitIT(i), clus->getHitAdc(i)); sigmaLayer += pow(clus->getHitLayer(i) - meanLayer, 2); sigmaIPhi += pow(clus->getHitIPhi(i) - meanIPhi, 2); sigmaIT += pow(clus->getHitIT(i) - meanIT, 2); - + sigmaWeightedLayer += clus->getHitAdc(i) * pow(clus->getHitLayer(i) - (layerSum / adcSum), 2); sigmaWeightedIPhi += clus->getHitAdc(i) * pow(clus->getHitIPhi(i) - (iphiSum / adcSum), 2); sigmaWeightedIT += clus->getHitAdc(i) * pow(clus->getHitIT(i) - (itSum / adcSum), 2); @@ -451,20 +426,18 @@ namespace bool fitSuccess = false; ROOT::Fit::Fitter *fit3D = new ROOT::Fit::Fitter; - if(my_data.doFitting) + if (my_data.doFitting) { - double par_init[7] = { - maxAdc, - meanLayer, - meanIPhi, 0.75, - meanIT, 0.5, 1 - }; + maxAdc, + meanLayer, + meanIPhi, 0.75, + meanIT, 0.5, 1}; double satThreshold = 900.0; double sigma_ADC = 20.0; - auto nll = [&](const double* par) + auto nll = [&](const double *par) { double nll_val = 0.0; @@ -472,37 +445,37 @@ namespace int ny = my_data.hitHist->GetNbinsY(); int nz = my_data.hitHist->GetNbinsZ(); - double parLayer[2] = {1.0,par[1]}; - double parPhi[4] = {1.0,par[2],par[3]}; - double parTime[4] = {1.0,par[4],par[5],par[6]}; + double parLayer[2] = {1.0, par[1]}; + double parPhi[4] = {1.0, par[2], par[3]}; + double parTime[4] = {1.0, par[4], par[5], par[6]}; double xyz[3]; for (int i = 1; i <= nx; ++i) { - xyz[0] = my_data.hitHist->GetXaxis()->GetBinCenter(i); + xyz[0] = my_data.hitHist->GetXaxis()->GetBinCenter(i); for (int j = 1; j <= ny; ++j) { - xyz[1] = my_data.hitHist->GetYaxis()->GetBinCenter(j); + xyz[1] = my_data.hitHist->GetYaxis()->GetBinCenter(j); for (int k = 1; k <= nz; ++k) { xyz[2] = my_data.hitHist->GetZaxis()->GetBinCenter(k); double observed = my_data.hitHist->GetBinContent(i, j, k); - double expected = par[0]*layerFunction(&xyz[0], parLayer)*phiFunction(&xyz[1], parPhi)*timeFunction(&xyz[2], parTime); + double expected = par[0] * layerFunction(&xyz[0], parLayer) * phiFunction(&xyz[1], parPhi) * timeFunction(&xyz[2], parTime); - if(observed <= my_data.adc_threshold) + if (observed <= my_data.adc_threshold) { double arg = (expected - my_data.adc_threshold) / (sqrt(2.0) * sigma_ADC); double tail_prob = 0.5 * TMath::Erfc(arg); nll_val -= log(tail_prob + 1e-12); } - else if(observed < satThreshold) + else if (observed < satThreshold) { double resid = (observed - expected) / sigma_ADC; nll_val += 0.5 * (resid * resid + log(2 * TMath::Pi() * sigma_ADC * sigma_ADC)); } - else if(observed >= satThreshold) + else if (observed >= satThreshold) { double arg = (satThreshold - expected) / (sqrt(2.0) * sigma_ADC); double tail_prob = 0.5 * TMath::Erfc(arg); @@ -518,35 +491,33 @@ namespace fit3D->Config().ParSettings(0).SetName("amp"); fit3D->Config().ParSettings(0).SetStepSize(10); - fit3D->Config().ParSettings(0).SetLimits(0,5000); + fit3D->Config().ParSettings(0).SetLimits(0, 5000); fit3D->Config().ParSettings(1).SetName("mu_layer"); fit3D->Config().ParSettings(1).SetStepSize(0.1); - fit3D->Config().ParSettings(1).SetLimits(usedLayer[0],*usedLayer.rbegin()); + fit3D->Config().ParSettings(1).SetLimits(usedLayer[0], *usedLayer.rbegin()); fit3D->Config().ParSettings(2).SetName("mu_phi"); fit3D->Config().ParSettings(2).SetStepSize(0.1); - fit3D->Config().ParSettings(2).SetLimits(usedIPhi[0],*usedIPhi.rbegin()); + fit3D->Config().ParSettings(2).SetLimits(usedIPhi[0], *usedIPhi.rbegin()); fit3D->Config().ParSettings(3).SetName("sig_phi"); fit3D->Config().ParSettings(3).SetStepSize(0.1); - fit3D->Config().ParSettings(3).SetLimits(0.01,2); + fit3D->Config().ParSettings(3).SetLimits(0.01, 2); fit3D->Config().ParSettings(4).SetName("mu_t"); fit3D->Config().ParSettings(4).SetStepSize(0.1); - fit3D->Config().ParSettings(4).SetLimits(usedIT[0],*usedIT.rbegin()); + fit3D->Config().ParSettings(4).SetLimits(usedIT[0], *usedIT.rbegin()); fit3D->Config().ParSettings(5).SetName("sig_t"); fit3D->Config().ParSettings(5).SetStepSize(0.1); - fit3D->Config().ParSettings(5).SetLimits(0.01,10); + fit3D->Config().ParSettings(5).SetLimits(0.01, 10); fit3D->Config().ParSettings(6).SetName("lambda_t"); fit3D->Config().ParSettings(6).SetStepSize(0.01); - fit3D->Config().ParSettings(6).SetLimits(0,5); + fit3D->Config().ParSettings(6).SetLimits(0, 5); - - if(usedLayer.size() == 1) + if (usedLayer.size() == 1) { fit3D->Config().ParSettings(1).Fix(); } fitSuccess = fit3D->FitFCN(); - if (my_data.Verbosity > 2) { std::cout << "fit success: " << fitSuccess << std::endl; @@ -554,13 +525,9 @@ namespace } pthread_mutex_unlock(&mythreadlock); - - - if(my_data.doFitting && fitSuccess) + if (my_data.doFitting && fitSuccess) { - - const ROOT::Fit::FitResult& result = fit3D->Result(); - + const ROOT::Fit::FitResult &result = fit3D->Result(); PHG4TpcGeom *layergeomLow = my_data.geom_container->GetLayerCellGeom((int) floor(result.Parameter(1))); PHG4TpcGeom *layergeomHigh = my_data.geom_container->GetLayerCellGeom((int) ceil(result.Parameter(1))); @@ -569,12 +536,12 @@ namespace double RHigh = layergeomHigh->get_radius(); double phiHigh_RLow = -999.0; - if(ceil(result.Parameter(2)) < layergeomLow->get_phibins()) + if (ceil(result.Parameter(2)) < layergeomLow->get_phibins()) { phiHigh_RLow = layergeomLow->get_phi(ceil(result.Parameter(2)), (meanSide < 0 ? 0 : 1)); } double phiHigh_RHigh = -999.0; - if(ceil(result.Parameter(2)) < layergeomHigh->get_phibins()) + if (ceil(result.Parameter(2)) < layergeomHigh->get_phibins()) { phiHigh_RHigh = layergeomHigh->get_phi(ceil(result.Parameter(2)), (meanSide < 0 ? 0 : 1)); } @@ -587,18 +554,17 @@ namespace double meanPhi_RLow = ((result.Parameter(2) - floor(result.Parameter(2)))) * (phiHigh_RLow - phiLow_RLow) + phiLow_RLow; double meanPhi_RHigh = ((result.Parameter(2) - floor(result.Parameter(2)))) * (phiHigh_RHigh - phiLow_RHigh) + phiLow_RHigh; - double meanPhi = 0.5*(meanPhi_RLow + meanPhi_RHigh); - if(phiHigh_RLow == -999.0 && phiHigh_RHigh != -999.0) + double meanPhi = 0.5 * (meanPhi_RLow + meanPhi_RHigh); + if (phiHigh_RLow == -999.0 && phiHigh_RHigh != -999.0) { meanPhi = meanPhi_RHigh; } - else if(phiHigh_RLow != -999.0 && phiHigh_RHigh == -999.0) + else if (phiHigh_RLow != -999.0 && phiHigh_RHigh == -999.0) { meanPhi = meanPhi_RLow; } - - if(phiHigh_RLow == -999.0 && phiHigh_RHigh == -999.0) + if (phiHigh_RLow == -999.0 && phiHigh_RHigh == -999.0) { clus->setAdc(adcSum); clus->setX(clusX); @@ -619,10 +585,10 @@ namespace clus->setSDWeightedIT(sqrt(sigmaWeightedIT / adcSum)); } else - { + { clus->setAdc(adcSum); - clus->setX(meanR*cos(meanPhi)); - clus->setY(meanR*sin(meanPhi)); + clus->setX(meanR * cos(meanPhi)); + clus->setY(meanR * sin(meanPhi)); clus->setZ(clusZ); clus->setFitMode(true); clus->setLayer(result.Parameter(1)); @@ -663,25 +629,18 @@ namespace const auto ckey = TrkrDefs::genClusKey(maxKey, my_data.cluster_vector.size()); my_data.cluster_vector.push_back(clus); my_data.cluster_key_vector.push_back(ckey); - - if(fit3D) - { - delete fit3D; - } - if(my_data.hitHist) + delete fit3D; + + if (my_data.hitHist) { delete my_data.hitHist; my_data.hitHist = nullptr; } - - } - void ProcessModuleData(thread_data *my_data) { - if (my_data->Verbosity > 2) { pthread_mutex_lock(&mythreadlock); @@ -693,85 +652,84 @@ namespace std::multimap adcMap; - if (my_data->hitsets.size() == 0) + if (my_data->hitsets.empty()) { return; } - for(int i=0; i<(int)my_data->hitsets.size(); i++) + for (int i = 0; i < (int) my_data->hitsets.size(); i++) { auto *hitset = my_data->hitsets[i]; unsigned int layer = my_data->layers[i]; bool side = my_data->side; unsigned int sector = my_data->sector; - TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, (int)side); + TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, (int) side); TrkrHitSet::ConstRange hitrangei = hitset->getHits(); for (TrkrHitSet::ConstIterator hitr = hitrangei.first; hitr != hitrangei.second; ++hitr) { - float_t fadc = hitr->second->getAdc(); - unsigned short adc = 0; - if (fadc > my_data->adc_threshold) - { - adc = (unsigned short) fadc; - } - else - { - continue; - } - - int iphi = TpcDefs::getPad(hitr->first); - int it = TpcDefs::getTBin(hitr->first); - - if(fabs(it - my_data->peakTimeBin) > 5) - { - continue; - } - - point coords = point((int) layer, iphi, it); - - std::vector testduplicate; - rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()) - { - testduplicate.clear(); - continue; - } - - TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - - auto spechitkey = std::make_pair(hitKey, hitsetKey); - pointKeyLaser coordsKey = std::make_pair(coords, spechitkey); - adcMap.insert(std::make_pair(adc, coordsKey)); + float_t fadc = hitr->second->getAdc(); + unsigned short adc = 0; + if (fadc > my_data->adc_threshold) + { + adc = (unsigned short) fadc; + } + else + { + continue; + } + + int iphi = TpcDefs::getPad(hitr->first); + int it = TpcDefs::getTBin(hitr->first); + + if (fabs(it - my_data->peakTimeBin) > 5) + { + continue; + } + + point coords = point((int) layer, iphi, it); + + std::vector testduplicate; + rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; + } + + TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); + + auto spechitkey = std::make_pair(hitKey, hitsetKey); + pointKeyLaser coordsKey = std::make_pair(coords, spechitkey); + adcMap.insert(std::make_pair(adc, coordsKey)); auto adckey = std::make_pair(adc, spechitkey); - rtree.insert(std::make_pair(point(1.0*layer, 1.0*iphi, 1.0*it), adckey)); + rtree.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), adckey)); } } - //finished filling rtree + // finished filling rtree - while (adcMap.size() > 0) + while (!adcMap.empty()) { auto iterKey = adcMap.rbegin(); - if(iterKey == adcMap.rend()) + if (iterKey == adcMap.rend()) { - break; + break; } - auto coords = iterKey->second.first; int layer = coords.get<0>(); int iphi = coords.get<1>(); int it = coords.get<2>(); - + if (my_data->Verbosity > 2) { pthread_mutex_lock(&mythreadlock); - std::cout << "working on cluster " << my_data->cluster_vector.size() << " side: " << my_data->side << " sector: " << my_data->sector << " module: " << (layer<23 ? 1 : (layer<39 ? 2 : 3) ) << std::endl; + // NOLINTNEXTLINE (readability-avoid-nested-conditional-operator) + std::cout << "working on cluster " << my_data->cluster_vector.size() << " side: " << my_data->side << " sector: " << my_data->sector << " module: " << (layer < 23 ? 1 : (layer < 39 ? 2 : 3)) << std::endl; pthread_mutex_unlock(&mythreadlock); - } std::vector clusHits; @@ -781,17 +739,16 @@ namespace calc_cluster_parameter(clusHits, *my_data, iterKey->second.second); remove_hits(clusHits, rtree, adcMap); - } } void *ProcessModule(void *threadarg) { - auto my_data = static_cast(threadarg); + auto *my_data = static_cast(threadarg); ProcessModuleData(my_data); pthread_exit(nullptr); } -} //namespace +} // namespace LaserClusterizer::LaserClusterizer(const std::string &name) : SubsysReco(name) @@ -818,7 +775,7 @@ int LaserClusterizer::InitRun(PHCompositeNode *topNode) { laserClusterNodeName = "LAMINATION_CLUSTER"; } - auto laserclusters = findNode::getClass(dstNode, laserClusterNodeName); + auto *laserclusters = findNode::getClass(dstNode, laserClusterNodeName); if (!laserclusters) { PHNodeIterator dstiter(dstNode); @@ -835,7 +792,7 @@ int LaserClusterizer::InitRun(PHCompositeNode *topNode) new PHIODataNode(laserclusters, laserClusterNodeName, "PHObject"); DetNode->addNode(LaserClusterContainerNode); } - + m_geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!m_geom_container) @@ -873,7 +830,7 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - if((eventHeader->get_RunNumber() > 66153 && !m_laserEventInfo->isGl1LaserEvent()) || (eventHeader->get_RunNumber() <= 66153 && !m_laserEventInfo->isLaserEvent())) + if ((eventHeader->get_RunNumber() > 66153 && !m_laserEventInfo->isGl1LaserEvent()) || (eventHeader->get_RunNumber() <= 66153 && !m_laserEventInfo->isLaserEvent())) { return Fun4AllReturnCodes::EVENT_OK; } @@ -897,7 +854,7 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + // get node for clusters std::string laserClusterNodeName = "LASER_CLUSTER"; if (m_lamination) @@ -921,8 +878,8 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - TrkrHitSetContainer::ConstRange hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId);; - + TrkrHitSetContainer::ConstRange hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); + struct thread_pair_t { pthread_t thread{}; @@ -938,123 +895,122 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) if (pthread_mutex_init(&mythreadlock, nullptr) != 0) { - std::cout << std::endl << " mutex init failed" << std::endl; + std::cout << std::endl + << " mutex init failed" << std::endl; return 1; } - - for (unsigned int sec=0; sec<12; sec++) + + for (unsigned int sec = 0; sec < 12; sec++) { - for (int s=0; s<2; s++) + for (int s = 0; s < 2; s++) { - for (unsigned int mod=0; mod<3; mod++) + for (unsigned int mod = 0; mod < 3; mod++) { - - if(Verbosity() > 2) + if (Verbosity() > 2) { std::cout << "making thread for side: " << s << " sector: " << sec << " module: " << mod << std::endl; } - thread_pair_t &thread_pair = threads.emplace_back(); - - std::vector hitsets; - std::vector layers; - - std::vector cluster_vector; - std::vector cluster_key_vector; - - for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; - hitsetitr != hitsetrange.second; - ++hitsetitr) - { - unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); - int side = TpcDefs::getSide(hitsetitr->first); - unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); - if (sector != sec || side != s) - { - continue; - } - if ((mod==0 && (layer<7 || layer>22)) || (mod==1 && (layer<=22 || layer>38) ) || (mod==2 && (layer<=38 || layer>54))) - { - continue; - } - - TrkrHitSet *hitset = hitsetitr->second; - - hitsets.push_back(hitset); - layers.push_back(layer); - - } - - thread_pair.data.geom_container = m_geom_container; - thread_pair.data.tGeometry = m_tGeometry; - thread_pair.data.hitsets = hitsets; - thread_pair.data.layers = layers; - thread_pair.data.side = (bool)s; - thread_pair.data.sector = sec; + thread_pair_t &thread_pair = threads.emplace_back(); + + std::vector hitsets; + std::vector layers; + + std::vector cluster_vector; + std::vector cluster_key_vector; + + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; + hitsetitr != hitsetrange.second; + ++hitsetitr) + { + unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); + int side = TpcDefs::getSide(hitsetitr->first); + unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); + if (sector != sec || side != s) + { + continue; + } + if ((mod == 0 && (layer < 7 || layer > 22)) || (mod == 1 && (layer <= 22 || layer > 38)) || (mod == 2 && (layer <= 38 || layer > 54))) + { + continue; + } + + TrkrHitSet *hitset = hitsetitr->second; + + hitsets.push_back(hitset); + layers.push_back(layer); + } + + thread_pair.data.geom_container = m_geom_container; + thread_pair.data.tGeometry = m_tGeometry; + thread_pair.data.hitsets = hitsets; + thread_pair.data.layers = layers; + thread_pair.data.side = (bool) s; + thread_pair.data.sector = sec; thread_pair.data.module = mod; - thread_pair.data.cluster_vector = cluster_vector; - thread_pair.data.cluster_key_vector = cluster_key_vector; - thread_pair.data.adc_threshold = m_adc_threshold; - thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); - thread_pair.data.layerMin = 3; - thread_pair.data.layerMax = 3; - thread_pair.data.tdriftmax = m_tdriftmax; + thread_pair.data.cluster_vector = cluster_vector; + thread_pair.data.cluster_key_vector = cluster_key_vector; + thread_pair.data.adc_threshold = m_adc_threshold; + thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); + thread_pair.data.layerMin = 3; + thread_pair.data.layerMax = 3; + thread_pair.data.tdriftmax = m_tdriftmax; thread_pair.data.eventNum = m_event; thread_pair.data.Verbosity = Verbosity(); thread_pair.data.hitHist = nullptr; thread_pair.data.doFitting = m_do_fitting; - int rc; - rc = pthread_create(&thread_pair.thread, &attr, ProcessModule, (void *) &thread_pair.data); - - if (rc) - { - std::cout << "Error:unable to create thread," << rc << std::endl; - } - - if (m_do_sequential) - { - //wait for termination of thread - int rc2 = pthread_join(thread_pair.thread, nullptr); - if (rc2) - { - std::cout << "Error:unable to join," << rc2 << std::endl; - } - - //add clusters from thread to laserClusterContainer - const auto &data(thread_pair.data); - for(int index = 0; index < (int) data.cluster_vector.size(); ++index) - { - auto cluster = data.cluster_vector[index]; - const auto ckey = data.cluster_key_vector[index]; - - m_clusterlist->addClusterSpecifyKey(ckey, cluster); - } - } + int rc; + rc = pthread_create(&thread_pair.thread, &attr, ProcessModule, (void *) &thread_pair.data); + + if (rc) + { + std::cout << "Error:unable to create thread," << rc << std::endl; + } + + if (m_do_sequential) + { + // wait for termination of thread + int rc2 = pthread_join(thread_pair.thread, nullptr); + if (rc2) + { + std::cout << "Error:unable to join," << rc2 << std::endl; + } + + // add clusters from thread to laserClusterContainer + const auto &data(thread_pair.data); + for (int index = 0; index < (int) data.cluster_vector.size(); ++index) + { + auto *cluster = data.cluster_vector[index]; + const auto ckey = data.cluster_key_vector[index]; + + m_clusterlist->addClusterSpecifyKey(ckey, cluster); + } + } } } } - + pthread_attr_destroy(&attr); if (!m_do_sequential) { - for (const auto & thread_pair : threads) + for (const auto &thread_pair : threads) { int rc2 = pthread_join(thread_pair.thread, nullptr); if (rc2) { - std::cout << "Error:unable to join," << rc2 << std::endl; + std::cout << "Error:unable to join," << rc2 << std::endl; } - - //const auto &data(thread_pair.data); - - for(int index = 0; index < (int) thread_pair.data.cluster_vector.size(); ++index) + + // const auto &data(thread_pair.data); + + for (int index = 0; index < (int) thread_pair.data.cluster_vector.size(); ++index) { - auto cluster = thread_pair.data.cluster_vector[index]; - const auto ckey = thread_pair.data.cluster_key_vector[index]; - - m_clusterlist->addClusterSpecifyKey(ckey, cluster); + auto *cluster = thread_pair.data.cluster_vector[index]; + const auto ckey = thread_pair.data.cluster_key_vector[index]; + + m_clusterlist->addClusterSpecifyKey(ckey, cluster); } } } @@ -1067,5 +1023,4 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) } return Fun4AllReturnCodes::EVENT_OK; - } diff --git a/offline/packages/tpc/LaserEventIdentifier.cc b/offline/packages/tpc/LaserEventIdentifier.cc index 8b6035db05..5968d2f09f 100644 --- a/offline/packages/tpc/LaserEventIdentifier.cc +++ b/offline/packages/tpc/LaserEventIdentifier.cc @@ -130,7 +130,7 @@ int LaserEventIdentifier::process_event(PHCompositeNode *topNode) } else if(m_runnumber > 66153) { - if ((gl1pkt->getGTMAllBusyVector() & (1<<14)) == 0) + if ((gl1pkt->getGTMAllBusyVector() & (1U<<14U)) == 0) { m_laserEventInfo->setIsGl1LaserEvent(true); m_laserEventInfo->setIsGl1LaserPileupEvent(false); diff --git a/offline/packages/tpc/Tpc3DClusterizer.cc b/offline/packages/tpc/Tpc3DClusterizer.cc index e19cbf507f..562231b71b 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.cc +++ b/offline/packages/tpc/Tpc3DClusterizer.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -72,7 +73,7 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto laserclusters = findNode::getClass(dstNode, "LASER_CLUSTER"); + auto *laserclusters = findNode::getClass(dstNode, "LASER_CLUSTER"); if (!laserclusters) { PHNodeIterator dstiter(dstNode); @@ -111,13 +112,14 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) m_clusterTree->Branch("time_erase", &time_erase); m_clusterTree->Branch("time_all", &time_all); } - - if (m_output){ + + if (m_output) + { m_outputFile = new TFile(m_outputFileName.c_str(), "RECREATE"); - m_clusterNT = new TNtuple("clus3D", "clus3D","event:seed:x:y:z:r:phi:phibin:tbin:adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize"); + m_clusterNT = new TNtuple("clus3D", "clus3D", "event:seed:x:y:z:r:phi:phibin:tbin:adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize"); } - + m_geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!m_geom_container) @@ -145,10 +147,13 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) { ++m_event; - recoConsts* rc = recoConsts::instance(); - if (rc->FlagExist("RANDOMSEED")){ - m_seed = (int)rc->get_IntFlag("RANDOMSEED"); - } else { + recoConsts *rc = recoConsts::instance(); + if (rc->FlagExist("RANDOMSEED")) + { + m_seed = rc->get_IntFlag("RANDOMSEED"); + } + else + { m_seed = std::numeric_limits::quiet_NaN(); } @@ -163,11 +168,12 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) } // get node containing the digitized hits m_hits = findNode::getClass(topNode, "TRKR_HITSET"); - if (!m_hits){ + if (!m_hits) + { std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + // get node for clusters m_clusterlist = findNode::getClass(topNode, "LASER_CLUSTER"); if (!m_clusterlist) @@ -193,7 +199,8 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) bgi::rtree> rtree_reject; for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; hitsetitr != hitsetrange.second; - ++hitsetitr){ + ++hitsetitr) + { TrkrHitSet *hitset = hitsetitr->second; unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); int side = TpcDefs::getSide(hitsetitr->first); @@ -202,49 +209,54 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) TrkrHitSet::ConstRange hitrangei = hitset->getHits(); for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr){ + hitr != hitrangei.second; + ++hitr) + { int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc());// - m_pedestal; // proper int rounding +0.5 + float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; - if (fadc > 0){ - adc = (unsigned short) fadc; + if (fadc > 0) + { + adc = (unsigned short) fadc; } - if (adc <= 0){ - continue; + if (adc <= 0) + { + continue; } - + std::vector testduplicate; rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()){ - testduplicate.clear(); - continue; + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; } TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - + auto spechitkey = std::make_pair(hitKey, hitsetKey); rtree_reject.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), spechitkey)); } } - + std::multimap, std::array>> adcMap; // std::cout << "n hitsets: " << std::distance(hitsetrange.first,hitsetrange.second) // << std::endl; for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; hitsetitr != hitsetrange.second; - ++hitsetitr){ + ++hitsetitr) + { TrkrHitSet *hitset = hitsetitr->second; unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); int side = TpcDefs::getSide(hitsetitr->first); unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); - //PHG4TpcGeom *layergeom = m_geom_container->GetLayerCellGeom(layer); - // double r = layergeom->get_radius(); - + // PHG4TpcGeom *layergeom = m_geom_container->GetLayerCellGeom(layer); + // double r = layergeom->get_radius(); + TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, side); TrkrHitSet::ConstRange hitrangei = hitset->getHits(); @@ -252,74 +264,122 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) // << std::endl; // int nhits = 0; for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr){ + hitr != hitrangei.second; + ++hitr) + { int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc());// - m_pedestal; // proper int rounding +0.5 + float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; // std::cout << " nhit: " << nhits++ << "adc: " << fadc << " phi: " << iphi << " it: " << it << std::endl; - if (fadc > 0){ - adc = (unsigned short) fadc; + if (fadc > 0) + { + adc = (unsigned short) fadc; } - if (adc <= 0){ - continue; + if (adc <= 0) + { + continue; } - if(layer>=7+32){ - //if(side==1)continue; - if(abs(iphi-0)<=2) continue; - if(abs(iphi-191)<=2) continue; - if(abs(iphi-206)<=1) continue; - if(abs(iphi-383)<=2) continue; - if(abs(iphi-576)<=2) continue; - if(abs(iphi-767)<=2) continue; - if(abs(iphi-960)<=2) continue; - if(abs(iphi-1522)<=2) continue; - if(abs(iphi-1344)<=2) continue; - if(abs(iphi-1536)<=2) continue; - if(abs(iphi-1728)<=2) continue; - if(abs(iphi-1920)<=2) continue; - if(abs(iphi-2111)<=2) continue; - if(abs(iphi-2303)<=2) continue; + if (layer >= 7 + 32) + { + // if(side==1)continue; + if (abs(iphi - 0) <= 2) + { + continue; + } + if (abs(iphi - 191) <= 2) + { + continue; + } + if (abs(iphi - 206) <= 1) + { + continue; + } + if (abs(iphi - 383) <= 2) + { + continue; + } + if (abs(iphi - 576) <= 2) + { + continue; + } + if (abs(iphi - 767) <= 2) + { + continue; + } + if (abs(iphi - 960) <= 2) + { + continue; + } + if (abs(iphi - 1522) <= 2) + { + continue; + } + if (abs(iphi - 1344) <= 2) + { + continue; + } + if (abs(iphi - 1536) <= 2) + { + continue; + } + if (abs(iphi - 1728) <= 2) + { + continue; + } + if (abs(iphi - 1920) <= 2) + { + continue; + } + if (abs(iphi - 2111) <= 2) + { + continue; + } + if (abs(iphi - 2303) <= 2) + { + continue; + } } /* double phi = layergeom->get_phi(iphi); double m_sampa_tbias = 39.6; double zdriftlength = (layergeom->get_zcenter(it)+ m_sampa_tbias) * m_tGeometry->get_drift_velocity(); - + float x = r * cos(phi); float y = r * sin(phi); float z = m_tdriftmax * m_tGeometry->get_drift_velocity() - zdriftlength; if (side == 0){ - z = -z; - it = -it; + z = -z; + it = -it; } */ std::array coords = {(int) layer, iphi, it}; - + std::vector testduplicate; rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()){ - testduplicate.clear(); - continue; + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; } - - //test for isolated hit + + // test for isolated hit std::vector testisolated; rtree_reject.query(bgi::intersects(box(point(layer - 1.001, iphi - 1.001, it - 1.001), - point(layer + 1.001, iphi + 1.001, it + 1.001))), - std::back_inserter(testisolated)); - if(testisolated.size()==1){ - //testisolated.clear(); - continue; + point(layer + 1.001, iphi + 1.001, it + 1.001))), + std::back_inserter(testisolated)); + if (testisolated.size() == 1) + { + // testisolated.clear(); + continue; } - + TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - + auto spechitkey = std::make_pair(hitKey, hitsetKey); auto keyCoords = std::make_pair(spechitkey, coords); adcMap.insert(std::make_pair(adc, keyCoords)); @@ -327,38 +387,43 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) rtree.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), spechitkey)); } } - - if (Verbosity() > 1){ + + if (Verbosity() > 1) + { std::cout << "finished looping over hits" << std::endl; std::cout << "map size: " << adcMap.size() << std::endl; std::cout << "rtree size: " << rtree.size() << std::endl; } - + // done filling rTree - + t_all->restart(); - - while (adcMap.size() > 0){ + + while (!adcMap.empty()) + { auto iterKey = adcMap.rbegin(); - if (iterKey == adcMap.rend()){ + if (iterKey == adcMap.rend()) + { break; } - + auto coords = iterKey->second.second; int layer = coords[0]; int iphi = coords[1]; int it = coords[2]; - + int layerMax = layer + 1; - if (layer == 22 || layer == 38 || layer == 54){ + if (layer == 22 || layer == 38 || layer == 54) + { layerMax = layer; } int layerMin = layer - 1; - if (layer == 7 || layer == 23 || layer == 39){ + if (layer == 7 || layer == 23 || layer == 39) + { layerMin = layer; } - + std::vector clusHits; t_search->restart(); @@ -376,21 +441,24 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) clusHits.clear(); } - if (m_debug){ + if (m_debug) + { m_nClus = (int) m_eventClusters.size(); } t_all->stop(); - if (m_debug){ + if (m_debug) + { time_search = t_search->get_accumulated_time() / 1000.; time_clus = t_clus->get_accumulated_time() / 1000.; time_erase = t_erase->get_accumulated_time() / 1000.; time_all = t_all->get_accumulated_time() / 1000.; - + m_clusterTree->Fill(); } - - if (Verbosity()){ + + if (Verbosity()) + { std::cout << "rtree search time: " << t_search->get_accumulated_time() / 1000. << " sec" << std::endl; std::cout << "clustering time: " << t_clus->get_accumulated_time() / 1000. << " sec" << std::endl; std::cout << "erasing time: " << t_erase->get_accumulated_time() / 1000. << " sec" << std::endl; @@ -401,30 +469,33 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } -int Tpc3DClusterizer::ResetEvent(PHCompositeNode * /*topNode*/){ +int Tpc3DClusterizer::ResetEvent(PHCompositeNode * /*topNode*/) +{ m_itHist_0->Reset(); m_itHist_1->Reset(); - + if (m_debug) - { - m_tHist_0->Reset(); - m_tHist_1->Reset(); - - m_eventClusters.clear(); - } - + { + m_tHist_0->Reset(); + m_tHist_1->Reset(); + + m_eventClusters.clear(); + } + return Fun4AllReturnCodes::EVENT_OK; } int Tpc3DClusterizer::End(PHCompositeNode * /*topNode*/) { - if (m_debug){ + if (m_debug) + { m_debugFile->cd(); m_clusterTree->Write(); m_debugFile->Close(); } - if (m_output){ + if (m_output) + { m_outputFile->cd(); m_clusterNT->Write(); m_outputFile->Close(); @@ -434,7 +505,7 @@ int Tpc3DClusterizer::End(PHCompositeNode * /*topNode*/) void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHits, std::multimap, std::array>> &adcMap) { - //std::cout << "nu clus" << std::endl; + // std::cout << "nu clus" << std::endl; double rSum = 0.0; double phiSum = 0.0; double tSum = 0.0; @@ -449,9 +520,12 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi TrkrDefs::hitsetkey maxKey = 0; unsigned int nHits = clusHits.size(); - int iphimin = 6666, iphimax = -1; - int ilaymin = 6666, ilaymax = -1; - float itmin = 66666666.6, itmax = -6666666666.6; + int iphimin = 6666; + int iphimax = -1; + int ilaymin = 6666; + int ilaymax = -1; + float itmin = 66666666.6; + float itmax = -6666666666.6; auto *clus = new LaserClusterv1; for (auto &clusHit : clusHits) @@ -468,21 +542,21 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi double phi = layergeom->get_phi(coords[1], side); double t = layergeom->get_zcenter(fabs(coords[2])); int tbin = coords[2]; - int lay = coords[0];//TrkrDefs::getLayer(spechitkey.second); + int lay = coords[0]; // TrkrDefs::getLayer(spechitkey.second); double hitzdriftlength = t * m_tGeometry->get_drift_velocity(); double hitZ = m_tdriftmax * m_tGeometry->get_drift_velocity() - hitzdriftlength; /*std::cout << " lay: " << lay - << " phi: " << phi - << " t: " << t - << " side: " << side - << std::endl; + << " phi: " << phi + << " t: " << t + << " side: " << side + << std::endl; */ - if(phiiphimax){iphimax = phi;} - if(layilaymax){ilaymax = lay;} - if(tbinitmax){itmax = tbin;} + iphimin = std::min(phi, iphimin); + iphimax = std::max(phi, iphimax); + ilaymin = std::min(lay, ilaymin); + ilaymax = std::max(lay, ilaymax); + itmin = std::min(tbin, itmin); + itmax = std::max(tbin, itmax); for (auto &iterKey : adcMap) { @@ -522,7 +596,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi if (nHits == 0) { - std::cout << "no hits"<< std::endl; + std::cout << "no hits" << std::endl; return; } @@ -554,55 +628,57 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi clus->setLayer(layerSum / adcSum); clus->setIPhi(iphiSum / adcSum); clus->setIT(itSum / adcSum); - int phisize = iphimax - iphimin + 1; - int lsize = ilaymax - ilaymin + 1; - int tsize = itmax - itmin +1; + int phisize = iphimax - iphimin + 1; + int lsize = ilaymax - ilaymin + 1; + int tsize = itmax - itmin + 1; if (m_debug) { m_currentCluster = (LaserCluster *) clus->CloneMe(); m_eventClusters.push_back((LaserCluster *) m_currentCluster->CloneMe()); } // if(nHits>1&&tsize>5){ - if(nHits>=1){ + if (nHits >= 1) + { const auto ckey = TrkrDefs::genClusKey(maxKey, m_clusterlist->size()); m_clusterlist->addClusterSpecifyKey(ckey, clus); - } else { + } + else + { delete clus; } - - //event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize + // event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize //"event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize" /* std::cout << " l size: " << lsize - << " phisize : " << phisize - << " tsize: " << tsize - << " maxside: " << maxside - << std::endl; + << " phisize : " << phisize + << " tsize: " << tsize + << " maxside: " << maxside + << std::endl; */ // if (m_output){ - float fX[20] = {0}; - int n = 0; - fX[n++] = m_event; - fX[n++] = m_seed; - fX[n++] = clusX; - fX[n++] = clusY; - fX[n++] = clusZ; - fX[n++] = clusR; - fX[n++] = clusPhi; - fX[n++] = clusiPhi; - fX[n++] = clusT; - fX[n++] = adcSum; - fX[n++] = maxAdc; - fX[n++] = (layerSum/adcSum); - fX[n++] = maxsector; - fX[n++] = maxside; - fX[n++] = nHits; - fX[n++] = phisize; - fX[n++] = tsize; - fX[n++] = lsize; - m_clusterNT->Fill(fX); - // } + float fX[20] = {0}; + int n = 0; + fX[n++] = m_event; + fX[n++] = m_seed; + fX[n++] = clusX; + fX[n++] = clusY; + fX[n++] = clusZ; + fX[n++] = clusR; + fX[n++] = clusPhi; + fX[n++] = clusiPhi; + fX[n++] = clusT; + fX[n++] = adcSum; + fX[n++] = maxAdc; + fX[n++] = (layerSum / adcSum); + fX[n++] = maxsector; + fX[n++] = maxside; + fX[n++] = nHits; + fX[n++] = phisize; + fX[n++] = tsize; + fX[n++] = lsize; + m_clusterNT->Fill(fX); + // } } void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rtree> &rtree, std::multimap, std::array>> &adcMap) @@ -611,10 +687,11 @@ void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rt { auto spechitkey = clusHit.second; - if(rtree.size()==0){ + if (rtree.empty()) + { std::cout << "not good" << std::endl; } - //rtree.remove(clusHit); + // rtree.remove(clusHit); for (auto iterAdc = adcMap.begin(); iterAdc != adcMap.end();) { @@ -623,10 +700,8 @@ void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rt iterAdc = adcMap.erase(iterAdc); break; } - else - { - ++iterAdc; - } + + ++iterAdc; } } } diff --git a/offline/packages/tpc/TpcClusterMover.cc b/offline/packages/tpc/TpcClusterMover.cc index 643fe5587f..39c5e156d4 100644 --- a/offline/packages/tpc/TpcClusterMover.cc +++ b/offline/packages/tpc/TpcClusterMover.cc @@ -17,19 +17,20 @@ namespace { - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector3& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v) { out << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"; return out; } -} +} // namespace TpcClusterMover::TpcClusterMover() + : inner_tpc_spacing((mid_tpc_min_radius - inner_tpc_min_radius) / 16.0) + , mid_tpc_spacing((outer_tpc_min_radius - mid_tpc_min_radius) / 16.0) + , outer_tpc_spacing((outer_tpc_max_radius - outer_tpc_min_radius) / 16.0) { // initialize layer radii - inner_tpc_spacing = (mid_tpc_min_radius - inner_tpc_min_radius) / 16.0; - mid_tpc_spacing = (outer_tpc_min_radius - mid_tpc_min_radius) / 16.0; - outer_tpc_spacing = (outer_tpc_max_radius - outer_tpc_min_radius) / 16.0; + for (int i = 0; i < 16; ++i) { layer_radius[i] = inner_tpc_min_radius + (double) i * inner_tpc_spacing + 0.5 * inner_tpc_spacing; @@ -44,7 +45,7 @@ TpcClusterMover::TpcClusterMover() } } -void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer *cellgeo) +void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer* cellgeo) { if (_verbosity > 0) { @@ -65,7 +66,6 @@ void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer *cellgeo) //____________________________________________________________________________.. std::vector> TpcClusterMover::processTrack(const std::vector>& global_in) { - // Get the global positions of the TPC clusters for this track, already corrected for distortions, and move them to the surfaces // The input object contains all clusters for the track @@ -74,7 +74,7 @@ std::vector> TpcClusterMover::proces std::vector tpc_global_vec; std::vector tpc_cluskey_vec; - for (const auto& [ckey,global]:global_in) + for (const auto& [ckey, global] : global_in) { const auto trkrid = TrkrDefs::getTrkrId(ckey); if (trkrid == TrkrDefs::tpcId) @@ -85,7 +85,7 @@ std::vector> TpcClusterMover::proces else { // si clusters stay where they are - global_moved.emplace_back(ckey,global); + global_moved.emplace_back(ckey, global); } } @@ -158,7 +158,7 @@ std::vector> TpcClusterMover::proces return global_moved; } -int TpcClusterMover::get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y) +int TpcClusterMover::get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double& x, double& y) const { // finds the intersection of the fitted circle with the cylinder having radius = target_radius const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(target_radius, R, X0, Y0); diff --git a/offline/packages/tpc/TpcClusterMover.h b/offline/packages/tpc/TpcClusterMover.h index dc67312f7f..92a053e990 100644 --- a/offline/packages/tpc/TpcClusterMover.h +++ b/offline/packages/tpc/TpcClusterMover.h @@ -27,7 +27,7 @@ class TpcClusterMover void initialize_geometry(PHG4TpcGeomContainer *cellgeo); private: - int get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y); + int get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y) const; double _z_start = 0.0; double _y_start = 0.0; diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index bd5fc3c340..c0137613f5 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -25,7 +25,6 @@ #include #include #include -#include #include #include // for SubsysReco @@ -50,6 +49,7 @@ #include +#include #include #include // for sqrt, cos, sin #include @@ -64,7 +64,7 @@ namespace { template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -365,20 +365,14 @@ namespace int isosum = 0; int isophimin = iphi - 1; - if (isophimin < 0) - { - isophimin = 0; - } + isophimin = std::max(isophimin, 0); int isophimax = iphi + 1; if (!(isophimax < NPhiBinsMax)) { isophimax = NPhiBinsMax - 1; } int isotmin = it - 1; - if (isotmin < 0) - { - isotmin = 0; - } + isotmin = std::max(isotmin, 0); int isotmax = it + 1; if (!(isotmax < NTBinsMax)) { @@ -537,30 +531,11 @@ namespace continue; } - if (adc > max_adc) - { - max_adc = adc; - } - - if (iphi > phibinhi) - { - phibinhi = iphi; - } - - if (iphi < phibinlo) - { - phibinlo = iphi; - } - - if (it > tbinhi) - { - tbinhi = it; - } - - if (it < tbinlo) - { - tbinlo = it; - } + max_adc = std::max(max_adc, static_cast(std::round(adc))); // preserves rounding (0.5 -> 1) + phibinhi = std::max(iphi, phibinhi); + phibinlo = std::min(iphi, phibinlo); + tbinhi = std::max(it, tbinhi); + tbinlo = std::min(it, tbinlo); // if(it==it_center){ yg_sum += adc; } // update phi sums @@ -686,7 +661,7 @@ namespace // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; if (sqrt(phi_err_square) > my_data.min_err_squared) { - auto clus = new TrkrClusterv5; + auto *clus = new TrkrClusterv5; // auto clus = std::make_unique(); clus_base = clus; clus->setAdc(adc_sum); @@ -738,19 +713,19 @@ namespace if (my_data.fillClusHitsVerbose && b_made_cluster) { // push the data back to - my_data.phivec_ClusHitsVerbose.push_back(std::vector>{}); - my_data.zvec_ClusHitsVerbose.push_back(std::vector>{}); + my_data.phivec_ClusHitsVerbose.emplace_back(); + my_data.zvec_ClusHitsVerbose.emplace_back(); auto &vphi = my_data.phivec_ClusHitsVerbose.back(); auto &vz = my_data.zvec_ClusHitsVerbose.back(); for (auto &entry : m_phi) { - vphi.push_back({entry.first, entry.second}); + vphi.emplace_back(entry.first, entry.second); } for (auto &entry : m_z) { - vz.push_back({entry.first, entry.second}); + vz.emplace_back(entry.first, entry.second); } } @@ -875,7 +850,7 @@ namespace } if (adc > my_data->edge_threshold) { - adcval[phibin][tbin] = (unsigned short) adc; + adcval[phibin][tbin] = adc; } } } @@ -967,7 +942,7 @@ namespace } */ // std::cout << "done filling " << std::endl; - while (all_hit_map.size() > 0) + while (!all_hit_map.empty()) { // std::cout << "all hit map size: " << all_hit_map.size() << std::endl; auto iter = all_hit_map.rbegin(); @@ -1013,22 +988,10 @@ namespace { continue; } - if (wiphi > wphibinhi) - { - wphibinhi = wiphi; - } - if (wiphi < wphibinlo) - { - wphibinlo = wiphi; - } - if (wit > wtbinhi) - { - wtbinhi = wit; - } - if (wit < wtbinlo) - { - wtbinlo = wit; - } + wphibinhi = std::max(wiphi, wphibinhi); + wphibinlo = std::min(wiphi, wphibinlo); + wtbinhi = std::max(wit, wtbinhi); + wtbinlo = std::min(wit, wtbinlo); } char wtsize = wtbinhi - wtbinlo + 1; char wphisize = wphibinhi - wphibinlo + 1; @@ -1077,7 +1040,7 @@ namespace } void *ProcessSector(void *threadarg) { - auto my_data = static_cast(threadarg); + auto *my_data = static_cast(threadarg); ProcessSectorData(my_data); pthread_exit(nullptr); } @@ -1133,7 +1096,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -1151,7 +1114,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -1168,7 +1131,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(newNode); } - auto training_container = findNode::getClass(dstNode, "TRAINING_HITSET"); + auto *training_container = findNode::getClass(dstNode, "TRAINING_HITSET"); if (!training_container) { PHNodeIterator dstiter(dstNode); @@ -1217,18 +1180,18 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) if (!mClusHitsVerbose) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); dstNode->addNode(DetNode); } mClusHitsVerbose = new ClusHitsVerbosev1(); - auto newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); + auto *newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); DetNode->addNode(newNode); } } - auto geom = + auto *geom = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!geom) { @@ -1239,13 +1202,13 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) AdcClockPeriod = geom->GetFirstLayerCellGeom()->get_zstep(); std::cout << "FirstLayerCellGeomv1 streamer: " << std::endl; - auto *g1 = (PHG4TpcGeomv1*) geom->GetFirstLayerCellGeom(); // cast because << not in the base class + auto *g1 = static_cast (geom->GetFirstLayerCellGeom()); // cast because << not in the base class std::cout << *g1 << std::endl; std::cout << "LayerCellGeomv1 streamer for layer 24: " << std::endl; - auto *g2 = (PHG4TpcGeomv1*) geom->GetLayerCellGeom(24); // cast because << not in the base class + auto *g2 = static_cast (geom->GetLayerCellGeom(24)); // cast because << not in the base class std::cout << *g2 << std::endl; std::cout << "LayerCellGeomv1 streamer for layer 40: " << std::endl; - auto *g3 = (PHG4TpcGeomv1*) geom->GetLayerCellGeom(40); // cast because << not in the base class + auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; return Fun4AllReturnCodes::EVENT_OK; @@ -1489,18 +1452,18 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); if (mClusHitsVerbose) { - for (auto &hit : data.phivec_ClusHitsVerbose[index]) + for (const auto &hit : data.phivec_ClusHitsVerbose[index]) { mClusHitsVerbose->addPhiHit(hit.first, hit.second); } - for (auto &hit : data.zvec_ClusHitsVerbose[index]) + for (const auto &hit : data.zvec_ClusHitsVerbose[index]) { mClusHitsVerbose->addZHit(hit.first, hit.second); } @@ -1624,7 +1587,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); @@ -1668,7 +1631,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map // std::cout << "X: " << cluster->getLocalX() << "Y: " << cluster->getLocalY() << std::endl; @@ -1676,11 +1639,11 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) if (mClusHitsVerbose) { - for (auto &hit : data.phivec_ClusHitsVerbose[index]) + for (const auto &hit : data.phivec_ClusHitsVerbose[index]) { mClusHitsVerbose->addPhiHit(hit.first, (float) hit.second); } - for (auto &hit : data.zvec_ClusHitsVerbose[index]) + for (const auto &hit : data.zvec_ClusHitsVerbose[index]) { mClusHitsVerbose->addZHit(hit.first, (float) hit.second); } @@ -1698,7 +1661,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) m_clusterhitassoc->addAssoc(ckey, hkey); } - for (auto v_hit : thread_pair.data.v_hits) + for (auto *v_hit : thread_pair.data.v_hits) { if (_store_hits) { diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc index c194567d58..5f276c3c3a 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc @@ -57,7 +57,7 @@ void TpcCombinedRawDataUnpacker::ReadZeroSuppressedData() { m_do_zs_emulation = true; m_do_baseline_corr = false; - auto cdb = CDBInterface::instance(); + auto *cdb = CDBInterface::instance(); std::string dir = cdb->getUrl("TPC_ZS_THRESHOLDS"); auto cdbtree = std::make_unique(dir); @@ -75,7 +75,7 @@ void TpcCombinedRawDataUnpacker::ReadZeroSuppressedData() { name.str(""); name << "R"<GetSingleFloatValue(name.str().c_str()); + m_zs_threshold[i] = cdbtree->GetSingleFloatValue(name.str()); if(Verbosity() > 1) { std::cout << "Loading ADU threshold of " << m_zs_threshold[i] << " for region " << i << std::endl; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc index 0bb412197f..803a822aa9 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include // for exit #include // for exit @@ -234,14 +235,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) TpcRawHit* tpchit = tpccont->get_hit(i); uint64_t gtm_bco = tpchit->get_gtm_bco(); - if (gtm_bco < bco_min) - { - bco_min = gtm_bco; - } - if (gtm_bco > bco_max) - { - bco_max = gtm_bco; - } + bco_min = std::min(gtm_bco, bco_min); + bco_max = std::max(gtm_bco, bco_max); int fee = tpchit->get_fee(); int channel = tpchit->get_channel(); @@ -539,7 +534,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) for (int binx = 1; binx < hist2d->GetNbinsX(); binx++) { - double timebin = ((TAxis*) hist2d->GetXaxis())->GetBinCenter(binx); + double timebin = ( hist2d->GetXaxis())->GetBinCenter(binx); std::string histname1d = "h" + std::to_string(hiter.first) + "_" + std::to_string((int) timebin); TH1D* hist1d = hist2d->ProjectionY(histname1d.c_str(), binx, binx); float local_ped = 0; @@ -697,11 +692,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) if ((float(adc) - pedestal_offset - corr) > (hpedwidth2 * m_ped_sig_cut)) { float nuadc = (float(adc) - corr - pedestal_offset); - if (nuadc < 0) - { - nuadc = 0; - } - hitr->second->setAdc(float(nuadc)); + nuadc = std::max(nuadc, 0); + hitr->second->setAdc(nuadc); #ifdef DEBUG // hitr->second->setAdc(10); if (tbin == 383 && layer >= 7 + 32 && fee == 21) diff --git a/offline/packages/tpc/TpcDistortionCorrection.cc b/offline/packages/tpc/TpcDistortionCorrection.cc index b759331e77..71b9ea8b2f 100644 --- a/offline/packages/tpc/TpcDistortionCorrection.cc +++ b/offline/packages/tpc/TpcDistortionCorrection.cc @@ -15,7 +15,7 @@ namespace { template - inline constexpr T square(const T& x) + constexpr T square(const T x) { return x * x; } diff --git a/offline/packages/tpc/TpcLoadDistortionCorrection.cc b/offline/packages/tpc/TpcLoadDistortionCorrection.cc index 0ce2ffa4e1..65bf156a7a 100644 --- a/offline/packages/tpc/TpcLoadDistortionCorrection.cc +++ b/offline/packages/tpc/TpcLoadDistortionCorrection.cc @@ -58,7 +58,7 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) } /// Get the RUN node and check - auto runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + auto *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); if (!runNode) { std::cout << "TpcLoadDistortionCorrection::InitRun - RUN Node missing, quitting" << std::endl; @@ -74,17 +74,17 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) } // get distortion correction object and create if not found - auto distortion_correction_object = findNode::getClass(topNode, m_node_name[i]); + auto *distortion_correction_object = findNode::getClass(topNode, m_node_name[i]); if (!distortion_correction_object) { std::cout << "TpcLoadDistortionCorrection::InitRun - creating TpcDistortionCorrectionContainer in node " << m_node_name[i] << std::endl; distortion_correction_object = new TpcDistortionCorrectionContainer; - auto node = new PHDataNode(distortion_correction_object, m_node_name[i]); + auto *node = new PHDataNode(distortion_correction_object, m_node_name[i]); runNode->addNode(node); } std::cout << "TpcLoadDistortionCorrection::InitRun - reading corrections from " << m_correction_filename[i] << std::endl; - auto distortion_tfile = TFile::Open(m_correction_filename[i].c_str()); + auto *distortion_tfile = TFile::Open(m_correction_filename[i].c_str()); if (!distortion_tfile) { std::cout << "TpcLoadDistortionCorrection::InitRun - cannot open " << m_correction_filename[i] << std::endl; diff --git a/offline/packages/tpc/TpcRawDataTree.cc b/offline/packages/tpc/TpcRawDataTree.cc index 6199fb7425..1141b5de55 100644 --- a/offline/packages/tpc/TpcRawDataTree.cc +++ b/offline/packages/tpc/TpcRawDataTree.cc @@ -61,7 +61,7 @@ int TpcRawDataTree::InitRun(PHCompositeNode * /*unused*/) m_SampleTree->Branch("nWaveormInFrame", &m_nWaveormInFrame, "nWaveormInFrame/I"); m_SampleTree->Branch("maxFEECount", &m_maxFEECount, "maxFEECount/I"); m_SampleTree->Branch("nSamples", &m_nSamples, "nSamples/I"); - m_SampleTree->Branch("adcSamples", &m_adcSamples[0], "adcSamples[nSamples]/s"); + m_SampleTree->Branch("adcSamples", m_adcSamples.data(), "adcSamples[nSamples]/s"); m_SampleTree->Branch("fee", &m_fee, "fee/I"); m_SampleTree->Branch("sampaAddress", &m_sampaAddress, "sampaAddress/I"); m_SampleTree->Branch("sampaChannel", &m_sampaChannel, "sampaChannel/I"); diff --git a/offline/packages/tpc/TpcRawWriter.cc b/offline/packages/tpc/TpcRawWriter.cc index 5d7711e2bb..41c5f26df3 100644 --- a/offline/packages/tpc/TpcRawWriter.cc +++ b/offline/packages/tpc/TpcRawWriter.cc @@ -76,7 +76,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -94,7 +94,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -116,7 +116,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) if (!m_rawhits) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); @@ -124,7 +124,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) } m_rawhits = new RawHitSetContainerv1; - auto newNode = new PHIODataNode(m_rawhits, "TRKR_RAWHITSET", "PHObject"); + auto *newNode = new PHIODataNode(m_rawhits, "TRKR_RAWHITSET", "PHObject"); DetNode->addNode(newNode); } diff --git a/offline/packages/tpc/TpcSimpleClusterizer.cc b/offline/packages/tpc/TpcSimpleClusterizer.cc index f439d1d682..f1fb0d5b76 100644 --- a/offline/packages/tpc/TpcSimpleClusterizer.cc +++ b/offline/packages/tpc/TpcSimpleClusterizer.cc @@ -33,6 +33,7 @@ #include +#include #include #include // for sqrt, cos, sin #include @@ -46,7 +47,7 @@ namespace { template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -142,22 +143,10 @@ namespace int iphi = iter.second.first + my_data.phioffset; int iz = iter.second.second + my_data.zoffset; - if (iphi > phibinhi) - { - phibinhi = iphi; - } - if (iphi < phibinlo) - { - phibinlo = iphi; - } - if (iz > zbinhi) - { - zbinhi = iz; - } - if (iz < zbinlo) - { - zbinlo = iz; - } + phibinhi = std::max(iphi, phibinhi); + phibinlo = std::min(iphi, phibinlo); + zbinhi = std::max(iz, zbinhi); + zbinlo = std::min(iz, zbinlo); // update phi sums double phi_center = my_data.layergeom->get_phicenter(iphi, my_data.side); @@ -205,7 +194,7 @@ namespace clusz -= (clusz < 0) ? my_data.par0_neg : my_data.par0_pos; // create cluster and fill - auto clus = new TrkrClusterv3; + auto *clus = new TrkrClusterv3; clus->setAdc(adc_sum); /// Get the surface key to find the surface from the map @@ -280,7 +269,7 @@ namespace void *ProcessSector(void *threadarg) { - auto my_data = (struct thread_data *) threadarg; + auto *my_data = (struct thread_data *) threadarg; const auto &pedestal = my_data->pedestal; const auto &phibins = my_data->phibins; @@ -332,11 +321,11 @@ namespace all_hit_map.insert(std::make_pair(adc, thisHit)); } // adcval[phibin][zbin] = (unsigned short) adc; - adcval[phibin][zbin] = (unsigned short) adc; + adcval[phibin][zbin] = adc; } } - while (all_hit_map.size() > 0) + while (!all_hit_map.empty()) { auto iter = all_hit_map.rbegin(); if (iter == all_hit_map.rend()) @@ -413,7 +402,7 @@ int TpcSimpleClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -431,7 +420,7 @@ int TpcSimpleClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -614,7 +603,7 @@ int TpcSimpleClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); diff --git a/offline/packages/tpc/TrainingHits.cc b/offline/packages/tpc/TrainingHits.cc index 3a70db0854..20a810b225 100644 --- a/offline/packages/tpc/TrainingHits.cc +++ b/offline/packages/tpc/TrainingHits.cc @@ -1,17 +1,17 @@ #include "TrainingHits.h" TrainingHits::TrainingHits() + : radius(0.) + , phi(0.) + , z(0.) + , phistep(0.) + , zstep(0.) + , layer(0) + , ntouch(0) + , nedge(0) + , cluskey(0) { v_adc.fill(0); - radius = 0.; - phi = 0.; - z = 0.; - phistep = 0.; - zstep = 0.; - layer = 0; - ntouch = 0; - nedge = 0; - cluskey = 0; } void TrainingHits::Reset() diff --git a/offline/packages/trackbase/AlignmentTransformation.cc b/offline/packages/trackbase/AlignmentTransformation.cc index b3eb79fcb0..2e8647ab01 100644 --- a/offline/packages/trackbase/AlignmentTransformation.cc +++ b/offline/packages/trackbase/AlignmentTransformation.cc @@ -277,6 +277,7 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) surf = surfMaps.getTpcSurface(this_hitsetkey, (unsigned int) sskey); Eigen::Vector3d localFrameTranslation(0, 0, 0); + use_module_tilt = false; if (test_layer < 4 || use_module_tilt_always) { // get the local frame translation that puts the local surface center at the tilted position after the local rotations are applied @@ -285,6 +286,9 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) double this_radius = std::sqrt(this_center[0] * this_center[0] + this_center[1] * this_center[1]); float moduleRadius = TpcModuleRadii[side][sector][this_region]; // radius of the center of the module in cm localFrameTranslation = getTpcLocalFrameTranslation(moduleRadius, this_radius, sensorAngles) * 10; // cm to mm + + // set this flag for later use + use_module_tilt = true; } Acts::Transform3 transform; @@ -417,70 +421,83 @@ Acts::Transform3 AlignmentTransformation::newMakeTransform(const Surface& surf, Acts::Transform3 transform; //! If we read the survey parameters directly, that is the full transform if (survey) - { - //! The millepede affines will just be what was read in, which was the - //! survey information. This should (in principle) be equivalent to - //! the ideal position + any misalignment - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * mpLocalRotationAffine; - } - else - { - if (trkrid == TrkrDefs::tpcId) { - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + //! The millepede affines will just be what was read in, which was the + //! survey information. This should (in principle) be equivalent to + //! the ideal position + any misalignment + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * mpLocalRotationAffine; } - else + else { - if(use_new_silicon_rotation_order) + // not survey. this is the normal usage + + if (trkrid == TrkrDefs::tpcId) { - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + if(use_module_tilt) + { + // use module tilt transforms with local rotation followed by local translation + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + } + else + { + // backward compatibility for old alignment params sets + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + } } else { - // needed for backward compatibility to existing local rotations in MVTX - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + // silicon and TPOT + if(use_new_silicon_rotation_order) + { + // use new transform order for silicon as well as TPC + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + } + else + { + // needed for backward compatibility to existing local rotation parmeter sets in silicon + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + } } } - } - + if (localVerbosity) - { - Acts::Transform3 actstransform = actsTranslationAffine * actsRotationAffine; - - std::cout << "newMakeTransform" << std::endl; - std::cout << "Input sensorAngles: " << std::endl - << sensorAngles << std::endl; - std::cout << "Input sensorAnglesGlobal: " << std::endl - << sensorAnglesGlobal << std::endl; - std::cout << "Input translation: " << std::endl - << millepedeTranslation << std::endl; - std::cout << "mpLocalRotationAffine: " << std::endl - << mpLocalRotationAffine.matrix() << std::endl; - std::cout << "mpLocalTranslationAffine: " << std::endl - << mpLocalTranslationAffine.matrix() << std::endl; - std::cout << "actsRotationAffine: " << std::endl - << actsRotationAffine.matrix() << std::endl; - std::cout << "actsTranslationAffine: " << std::endl - << actsTranslationAffine.matrix() << std::endl; - std::cout << "mpRotationGlobalAffine: " << std::endl - << mpGlobalRotationAffine.matrix() << std::endl; - std::cout << "mpTranslationGlobalAffine: " << std::endl - << mpGlobalTranslationAffine.matrix() << std::endl; - std::cout << "Overall transform: " << std::endl - << transform.matrix() << std::endl; - std::cout << "overall * idealinv " << std::endl - << (transform * actstransform.inverse()).matrix() << std::endl; - std::cout << "overall - ideal " << std::endl; - for (int test = 0; test < transform.matrix().rows(); test++) { - for (int test2 = 0; test2 < transform.matrix().cols(); test2++) - { - std::cout << transform(test, test2) - actstransform(test, test2) << ", "; - } - std::cout << std::endl; + Acts::Transform3 actstransform = actsTranslationAffine * actsRotationAffine; + + std::cout << "newMakeTransform" << std::endl; + std::cout << "Input sensorAngles: " << std::endl + << sensorAngles << std::endl; + std::cout << "Input sensorAnglesGlobal: " << std::endl + << sensorAnglesGlobal << std::endl; + std::cout << "Input translation: " << std::endl + << millepedeTranslation << std::endl; + std::cout << "mpLocalRotationAffine: " << std::endl + << mpLocalRotationAffine.matrix() << std::endl; + std::cout << "mpLocalTranslationAffine: " << std::endl + << mpLocalTranslationAffine.matrix() << std::endl; + std::cout << "actsRotationAffine: " << std::endl + << actsRotationAffine.matrix() << std::endl; + std::cout << "actsTranslationAffine: " << std::endl + << actsTranslationAffine.matrix() << std::endl; + std::cout << "mpRotationGlobalAffine: " << std::endl + << mpGlobalRotationAffine.matrix() << std::endl; + std::cout << "mpTranslationGlobalAffine: " << std::endl + << mpGlobalTranslationAffine.matrix() << std::endl; + std::cout << "Overall transform: " << std::endl + << transform.matrix() << std::endl; + std::cout << "overall * idealinv " << std::endl + << (transform * actstransform.inverse()).matrix() << std::endl; + std::cout << "overall - ideal " << std::endl; + for (int test = 0; test < transform.matrix().rows(); test++) + { + for (int test2 = 0; test2 < transform.matrix().cols(); test2++) + { + std::cout << transform(test, test2) - actstransform(test, test2) << ", "; + } + std::cout << std::endl; + } } - } - + return transform; } diff --git a/offline/packages/trackbase/AlignmentTransformation.h b/offline/packages/trackbase/AlignmentTransformation.h index 7055d6c65a..e8eb3882d1 100644 --- a/offline/packages/trackbase/AlignmentTransformation.h +++ b/offline/packages/trackbase/AlignmentTransformation.h @@ -128,7 +128,8 @@ class AlignmentTransformation bool use_new_silicon_rotation_order = false; bool use_module_tilt_always = false; - + bool use_module_tilt = false; // starts at false in all cases + bool use_intt_survey_geometry = false; Acts::Transform3 newMakeTransform(const Surface& surf, Eigen::Vector3d& millepedeTranslation, Eigen::Vector3d& sensorAngles, Eigen::Vector3d& localFrameTranslation, Eigen::Vector3d& sensorAnglesGlobal, unsigned int trkrid, bool survey); diff --git a/offline/packages/trackbase_historic/TrackSeedHelper.cc b/offline/packages/trackbase_historic/TrackSeedHelper.cc index 99a9198811..0fba4fb80a 100644 --- a/offline/packages/trackbase_historic/TrackSeedHelper.cc +++ b/offline/packages/trackbase_historic/TrackSeedHelper.cc @@ -142,8 +142,8 @@ void TrackSeedHelper::circleFitByTaubin( float qOverR = 1./r; /// Set the charge - const auto& firstpos = positions_2d.at(0); - const auto& secondpos = positions_2d.at(1); + const auto& firstpos = *(positions_2d.begin()); + const auto& secondpos = *(positions_2d.rbegin()); const auto firstphi = atan2(firstpos.second, firstpos.first); const auto secondphi = atan2(secondpos.second, secondpos.first); diff --git a/offline/packages/trackreco/DSTClusterPruning.cc b/offline/packages/trackreco/DSTClusterPruning.cc index 15bfe547ca..36bbe4fd0f 100644 --- a/offline/packages/trackreco/DSTClusterPruning.cc +++ b/offline/packages/trackreco/DSTClusterPruning.cc @@ -177,6 +177,39 @@ void DSTClusterPruning::prune_clusters() } return; } + if(m_pruneAllSeeds) + { + for(const auto& container : {m_tpc_track_seed_container, m_silicon_track_seed_container}) + { + for (const auto& trackseed : *container) + { + if (!trackseed) + { + std::cout << "No TrackSeed" << std::endl; + continue; + } + + for (auto key_iter = trackseed->begin_cluster_keys(); key_iter != trackseed->end_cluster_keys(); ++key_iter) + { + const auto& cluster_key = *key_iter; + auto *cluster = m_cluster_map->findCluster(cluster_key); + if (!cluster) + { + std::cout << "DSTClusterPruning::evaluate_tracks - unable to find cluster for key " << cluster_key << std::endl; + continue; + } + if (!m_reduced_cluster_map->findCluster(cluster_key)) + { + m_cluster = new TrkrClusterv5(); + m_cluster->CopyFrom(cluster); + m_reduced_cluster_map->addClusterSpecifyKey(cluster_key, m_cluster); + } + } + } + } + return; + } + for (const auto& trackseed : *m_track_seed_container) { if (!trackseed) diff --git a/offline/packages/trackreco/DSTClusterPruning.h b/offline/packages/trackreco/DSTClusterPruning.h index c9ec35ea53..5fa2ff9b4f 100644 --- a/offline/packages/trackreco/DSTClusterPruning.h +++ b/offline/packages/trackreco/DSTClusterPruning.h @@ -52,6 +52,12 @@ class DSTClusterPruning : public SubsysReco //! end of processing //int End(PHCompositeNode*) override; + //! dump all clusters on all seeds out + void pruneAllSeeds() + { + m_pruneAllSeeds = true; + } + private: //! load nodes int load_nodes(PHCompositeNode*); @@ -68,6 +74,9 @@ class DSTClusterPruning : public SubsysReco TrackSeedContainer* m_tpc_track_seed_container = nullptr; TrackSeedContainer* m_silicon_track_seed_container = nullptr; +//! set to true if you want to dump out all clusters on all silicon +//! and all tpc seeds individually + bool m_pruneAllSeeds = false; //@} // debugging helpers diff --git a/offline/packages/trackreco/MakeSourceLinks.cc b/offline/packages/trackreco/MakeSourceLinks.cc index efbbe92853..f9038d182e 100644 --- a/offline/packages/trackreco/MakeSourceLinks.cc +++ b/offline/packages/trackreco/MakeSourceLinks.cc @@ -1,13 +1,12 @@ #include "MakeSourceLinks.h" -#include +#include +#include #include #include #include -#include #include #include -#include #include #include @@ -16,8 +15,8 @@ #include #include -#include #include +#include #include @@ -29,26 +28,25 @@ namespace { - template + template inline T square(const T& x) { return x * x; } - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector3& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v) { out << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"; return out; } - - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector2& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector2& v) { out << "(" << v.x() << ", " << v.y() << ")"; return out; } -} +} // namespace void MakeSourceLinks::initialize(PHG4TpcGeomContainer* cellgeo) { @@ -57,30 +55,33 @@ void MakeSourceLinks::initialize(PHG4TpcGeomContainer* cellgeo) { _clusterMover.initialize_geometry(cellgeo); } - } - //___________________________________________________________________________________ +//___________________________________________________________________________________ SourceLinkVec MakeSourceLinks::getSourceLinks( - TrackSeed* track, - ActsTrackFittingAlgorithm::MeasurementContainer& measurements, - TrkrClusterContainer* clusterContainer, - ActsGeometry* tGeometry, - const TpcGlobalPositionWrapper& globalPositionWrapper, - alignmentTransformationContainer* transformMapTransient, - std::set< Acts::GeometryIdentifier>& transient_id_set, - short int crossing - ) + TrackSeed* track, + ActsTrackFittingAlgorithm::MeasurementContainer& measurements, + TrkrClusterContainer* clusterContainer, + ActsGeometry* tGeometry, + const TpcGlobalPositionWrapper& globalPositionWrapper, + alignmentTransformationContainer* transformMapTransient, + std::set& transient_id_set, + short int crossing) { - if(m_verbosity > 1) { std::cout << "Entering MakeSourceLinks::getSourceLinks " << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Entering MakeSourceLinks::getSourceLinks " << std::endl; + } SourceLinkVec sourcelinks; if (m_pp_mode && crossing == SHRT_MAX) { // Need to skip this in the pp case, for AuAu it should not happen - if(m_verbosity > 1) - { std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; + } return sourcelinks; } @@ -96,84 +97,90 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( ++clusIter) { auto key = *clusIter; - auto cluster = clusterContainer->findCluster(key); + auto* cluster = clusterContainer->findCluster(key); if (!cluster) + { + if (m_verbosity > 0) { - if (m_verbosity > 0) - {std::cout << "MakeSourceLinks: Failed to get cluster with key " << key << " for track seed" << std::endl;} - continue; + std::cout << "MakeSourceLinks: Failed to get cluster with key " << key << " for track seed" << std::endl; } - else - if(m_verbosity > 0) - {std::cout << "MakeSourceLinks: Found cluster with key " << key << " for track seed " << std::endl;} - + continue; + } + if (m_verbosity > 0) + { + std::cout << "MakeSourceLinks: Found cluster with key " << key << " for track seed " << std::endl; + } + /// Make a safety check for clusters that couldn't be attached to a surface auto surf = tGeometry->maps().getSurface(key, cluster); if (!surf) - { - continue; - } - + { + continue; + } + const unsigned int trkrid = TrkrDefs::getTrkrId(key); const unsigned int clus_layer = TrkrDefs::getLayer(key); - if(m_verbosity > 1) { std::cout << " Cluster key " << key << " layer " << clus_layer << " trkrid " << trkrid << " crossing " << crossing << std::endl; } + if (m_verbosity > 1) + { + std::cout << " Cluster key " << key << " layer " << clus_layer << " trkrid " << trkrid << " crossing " << crossing << std::endl; + } // For the TPC, cluster z has to be corrected for the crossing z offset, distortion, and TOF z offset // we do this by modifying the fake surface transform, to move the cluster to the corrected position if (trkrid == TrkrDefs::tpcId) { - Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing ); + Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing); Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); // The wrapper returns the global position corrected for distortion and the cluster crossing z offset // The cluster z crossing correction has to be applied to the nominal global position (global_in) - double cluster_crossing_corrected_z= TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); - double crossing_correction = cluster_crossing_corrected_z - global_in.z(); + double cluster_crossing_corrected_z = TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); + double crossing_correction = cluster_crossing_corrected_z - global_in.z(); global_in.z() = cluster_crossing_corrected_z; - - if(m_verbosity > 2) + + if (m_verbosity > 2) { - unsigned int this_layer = TrkrDefs::getLayer(key); - unsigned int this_side = TpcDefs::getSide(key); - if(this_layer == 28) - { - std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl - << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) - << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) - << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl - << " distortion " << global(0)-global_in(0) << " " - << global(1) - global_in(1) << " " << global(2) - global_in(2) - << " cluster crossing z correction " << crossing_correction - << std::endl; - } + unsigned int this_layer = TrkrDefs::getLayer(key); + unsigned int this_side = TpcDefs::getSide(key); + if (this_layer == 28) + { + std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl + << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) + << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) + << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl + << " distortion " << global(0) - global_in(0) << " " + << global(1) - global_in(1) << " " << global(2) - global_in(2) + << " cluster crossing z correction " << crossing_correction + << std::endl; + } } - + // Make an afine transform that implements the distortion correction as a translation - auto correction_translation = (global - global_in)*Acts::UnitConstants::cm; - Acts::Vector3 correction_rotation(0,0,0); // null rotation + auto correction_translation = (global - global_in) * Acts::UnitConstants::cm; + Acts::Vector3 correction_rotation(0, 0, 0); // null rotation Acts::Transform3 tcorr = tGeometry->makeAffineTransform(correction_rotation, correction_translation); auto this_surf = tGeometry->maps().getSurface(key, cluster); Acts::GeometryIdentifier id = this_surf->geometryId(); - auto check_cluster = clusterContainer->findCluster(key); - Acts::Vector2 check_local2d = tGeometry->getLocalCoords(key, check_cluster) * Acts::UnitConstants::cm; // need mm - Acts::Vector3 check_local3d (check_local2d(0), check_local2d(1), 0); + auto* check_cluster = clusterContainer->findCluster(key); + Acts::Vector2 check_local2d = tGeometry->getLocalCoords(key, check_cluster) * Acts::UnitConstants::cm; // need mm + Acts::Vector3 check_local3d(check_local2d(0), check_local2d(1), 0); Acts::GeometryContext temp_transient_geocontext; - temp_transient_geocontext = transformMapTransient; - Acts::Vector3 check_before_pos_surf = this_surf->localToGlobal( temp_transient_geocontext, - check_local2d, - Acts::Vector3(1,1,1)); - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - std::cout << "Check global from transient transform BEFORE via surface method " << check_before_pos_surf(0)/10.0 << " " - << " " << check_before_pos_surf(1)/10.0 << " " << check_before_pos_surf(2)/10.0 << std::endl; - } - } - + temp_transient_geocontext = transformMapTransient; + Acts::Vector3 check_before_pos_surf = this_surf->localToGlobal(temp_transient_geocontext, + check_local2d, + Acts::Vector3(1, 1, 1)); + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + std::cout << "Check global from transient transform BEFORE via surface method " << check_before_pos_surf(0) / 10.0 << " " + << " " << check_before_pos_surf(1) / 10.0 << " " << check_before_pos_surf(2) / 10.0 << std::endl; + } + } + // replace the the default alignment transform with the corrected one auto ctxt = tGeometry->geometry().getGeoContext(); alignmentTransformationContainer* transformMap = ctxt.get(); @@ -181,18 +188,18 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( transformMapTransient->replaceTransform(id, corrected_transform); transient_id_set.insert(id); - Acts::Vector3 check_after_pos_surf = this_surf->localToGlobal( temp_transient_geocontext, - check_local2d, - Acts::Vector3(1,1,1)); - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - std::cout << "Check global from transient transform AFTER via surface method " << check_after_pos_surf(0)/10.0 << " " - << " " << check_after_pos_surf(1)/10.0 << " " << check_after_pos_surf(2)/10.0 << std::endl; - } - } + Acts::Vector3 check_after_pos_surf = this_surf->localToGlobal(temp_transient_geocontext, + check_local2d, + Acts::Vector3(1, 1, 1)); + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + std::cout << "Check global from transient transform AFTER via surface method " << check_after_pos_surf(0) / 10.0 << " " + << " " << check_after_pos_surf(1) / 10.0 << " " << check_after_pos_surf(2) / 10.0 << std::endl; + } + } } // end TPC specific treatment // corrected TPC transforms are installed, capture the cluster key @@ -201,128 +208,143 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( } // end loop over clusters here Acts::GeometryContext transient_geocontext; - transient_geocontext = transformMapTransient; + transient_geocontext = transformMapTransient; // loop over cluster_vec and make source links - for(auto& cluskey : cluster_vec) + for (auto& cluskey : cluster_vec) + { + if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) { - if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) - { - if (m_verbosity > 3) - { - std::cout << PHWHERE << "skipping cluster in layer " - << (unsigned int) TrkrDefs::getLayer(cluskey) << std::endl; - } - continue; - } - - // get local coordinates (TPC time needs conversion to cm) - auto cluster = clusterContainer->findCluster(cluskey); - Acts::Vector2 localPos = tGeometry->getLocalCoords(cluskey, cluster, crossing); // cm - - Surface surf = tGeometry->maps().getSurface(cluskey, cluster); - - Acts::ActsVector<2> loc; - loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; // mm - loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; - - std::array indices = - {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; - Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); - - // get errors - Acts::Vector3 global = tGeometry->getGlobalPosition(cluskey, cluster); - double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); - cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; - cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; - - ActsSourceLink::Index index = measurements.size(); - - SourceLink sl(surf->geometryId(), index, cluskey); - Acts::SourceLink actsSL{sl}; - Acts::Measurement meas(actsSL, indices, loc, cov); if (m_verbosity > 3) - { - unsigned int this_layer = TrkrDefs::getLayer(cluskey); - if (this_layer == 28) - { - std::cout << "source link in layer " << this_layer << " for cluskey " << cluskey << " is " << sl.index() << ", loc : " - << loc.transpose() << std::endl - << ", cov : " << cov.transpose() << std::endl - << " geo id " << sl.geometryId() << std::endl; - std::cout << "Surface original transform: " << std::endl; - surf.get()->toStream(tGeometry->geometry().getGeoContext(), std::cout); - std::cout << std::endl << "Surface transient transform: " << std::endl; - surf.get()->toStream(transient_geocontext, std::cout); - std::cout << std::endl; - std::cout << "Corrected surface transform:" << std::endl; - std::cout << transformMapTransient->getTransform(surf->geometryId()).matrix() << std::endl; - std::cout << "Cluster error " << cluster->getRPhiError() << " , " << cluster->getZError() << std::endl; - std::cout << "For key " << cluskey << " with local pos " << std::endl - << localPos(0) << ", " << localPos(1) - << std::endl << std::endl; - } + { + std::cout << PHWHERE << "skipping cluster in layer " + << (unsigned int) TrkrDefs::getLayer(cluskey) << std::endl; + } + continue; + } + + // get local coordinates (TPC time needs conversion to cm) + auto* cluster = clusterContainer->findCluster(cluskey); + if (TrkrDefs::getTrkrId(cluskey) == TrkrDefs::TrkrId::tpcId) + { + if (cluster->getEdge() > m_cluster_edge_rejection) + { + continue; + } } + Acts::Vector2 localPos = tGeometry->getLocalCoords(cluskey, cluster, crossing); // cm + + Surface surf = tGeometry->maps().getSurface(cluskey, cluster); + + Acts::ActsVector<2> loc; + loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; // mm + loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; + + std::array indices = + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; + Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); + + // get errors + Acts::Vector3 global = tGeometry->getGlobalPosition(cluskey, cluster); + double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); + auto para_errors = ClusterErrorPara::get_clusterv5_modified_error(cluster, clusRadius, cluskey); + cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; + cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; + cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; + cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; - sourcelinks.push_back(actsSL); - measurements.push_back(meas); + ActsSourceLink::Index index = measurements.size(); + + SourceLink sl(surf->geometryId(), index, cluskey); + Acts::SourceLink actsSL{sl}; + Acts::Measurement meas(actsSL, indices, loc, cov); + if (m_verbosity > 3) + { + unsigned int this_layer = TrkrDefs::getLayer(cluskey); + if (this_layer == 28) + { + std::cout << "source link in layer " << this_layer << " for cluskey " << cluskey << " is " << sl.index() << ", loc : " + << loc.transpose() << std::endl + << ", cov : " << cov.transpose() << std::endl + << " geo id " << sl.geometryId() << std::endl; + std::cout << "Surface original transform: " << std::endl; + surf.get()->toStream(tGeometry->geometry().getGeoContext(), std::cout); + std::cout << std::endl + << "Surface transient transform: " << std::endl; + surf.get()->toStream(transient_geocontext, std::cout); + std::cout << std::endl; + std::cout << "Corrected surface transform:" << std::endl; + std::cout << transformMapTransient->getTransform(surf->geometryId()).matrix() << std::endl; + std::cout << "Cluster error " << cluster->getRPhiError() << " , " << cluster->getZError() << std::endl; + std::cout << "For key " << cluskey << " with local pos " << std::endl + << localPos(0) << ", " << localPos(1) + << std::endl + << std::endl; + } } + sourcelinks.push_back(actsSL); + measurements.emplace_back(meas); + } + SLTrackTimer.stop(); auto SLTime = SLTrackTimer.get_accumulated_time(); if (m_verbosity > 1) - { - std::cout << "PHActsTrkFitter Source Links generation time: " + { + std::cout << "PHActsTrkFitter Source Links generation time: " << SLTime << std::endl; - } + } return sourcelinks; } void MakeSourceLinks::resetTransientTransformMap( - alignmentTransformationContainer* transformMapTransient, - std::set< Acts::GeometryIdentifier>& transient_id_set, - ActsGeometry* tGeometry ) + alignmentTransformationContainer* transformMapTransient, + std::set& transient_id_set, + ActsGeometry* tGeometry) const { - if(m_verbosity > 2) { std::cout << "Resetting TransientTransformMap with transient_id_set size " << transient_id_set.size() << std::endl; } + if (m_verbosity > 2) + { + std::cout << "Resetting TransientTransformMap with transient_id_set size " << transient_id_set.size() << std::endl; + } // loop over modifiedTransformSet and replace transient elements modified for the last track with the default transforms - for(auto& id : transient_id_set) - { - auto ctxt = tGeometry->geometry().getGeoContext(); - alignmentTransformationContainer* transformMap = ctxt.get(); - auto transform = transformMap->getTransform(id); - transformMapTransient->replaceTransform(id, transform); - // std::cout << "replaced transform for id " << id << std::endl; - } + for (const auto& id : transient_id_set) + { + auto ctxt = tGeometry->geometry().getGeoContext(); + alignmentTransformationContainer* transformMap = ctxt.get(); + auto transform = transformMap->getTransform(id); + transformMapTransient->replaceTransform(id, transform); + // std::cout << "replaced transform for id " << id << std::endl; + } transient_id_set.clear(); } - //___________________________________________________________________________________ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( - TrackSeed* track, - ActsTrackFittingAlgorithm::MeasurementContainer& measurements, - TrkrClusterContainer* clusterContainer, - ActsGeometry* tGeometry, - const TpcGlobalPositionWrapper& globalPositionWrapper, - short int crossing - ) + TrackSeed* track, + ActsTrackFittingAlgorithm::MeasurementContainer& measurements, + TrkrClusterContainer* clusterContainer, + ActsGeometry* tGeometry, + const TpcGlobalPositionWrapper& globalPositionWrapper, + short int crossing) { - if(m_verbosity > 1) { std::cout << "Entering MakeSourceLinks::getSourceLinksClusterMover for seed " - << " with crossing " << crossing - << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Entering MakeSourceLinks::getSourceLinksClusterMover for seed " + << " with crossing " << crossing + << std::endl; + } SourceLinkVec sourcelinks; if (m_pp_mode && crossing == SHRT_MAX) { // Need to skip this in the pp case, for AuAu it should not happen - if(m_verbosity > 1) - { std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; + } return sourcelinks; } @@ -339,13 +361,17 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( ++clusIter) { auto key = *clusIter; - auto cluster = clusterContainer->findCluster(key); + auto* cluster = clusterContainer->findCluster(key); if (!cluster) { if (m_verbosity > 0) - {std::cout << "Failed to get cluster with key " << key << " for track " << track << std::endl;} + { + std::cout << "Failed to get cluster with key " << key << " for track " << track << std::endl; + } else - {std::cout << "PHActsTrkFitter :: Key: " << key << " for track " << track << std::endl;} + { + std::cout << "PHActsTrkFitter :: Key: " << key << " for track " << track << std::endl; + } continue; } @@ -359,40 +385,43 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( const unsigned int trkrid = TrkrDefs::getTrkrId(key); - if(m_verbosity > 1) { std::cout << " Cluster key " << key << " trkrid " << trkrid << " crossing " << crossing << std::endl; } + if (m_verbosity > 1) + { + std::cout << " Cluster key " << key << " trkrid " << trkrid << " crossing " << crossing << std::endl; + } // For the TPC, cluster z has to be corrected for the crossing z offset, distortion, and TOF z offset // we do this locally here and do not modify the cluster, since the cluster may be associated with multiple silicon tracks - const Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing ); + const Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing); if (trkrid == TrkrDefs::tpcId) { - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - unsigned int this_side = TpcDefs::getSide(key); - Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); - Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); - double cluster_crossing_corrected_z= TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); - double crossing_correction = cluster_crossing_corrected_z - global_in.z(); - global_in.z() = cluster_crossing_corrected_z; - - std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl - << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) << std::endl - << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) << std::endl - << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl - << " distortion " << global(0)-global_in(0) << " " - << global(1) - global_in(1) << " " << global(2) - global_in(2) - << " cluster crossing z correction " << crossing_correction - << std::endl; - } - } + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + unsigned int this_side = TpcDefs::getSide(key); + Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); + Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); + double cluster_crossing_corrected_z = TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); + double crossing_correction = cluster_crossing_corrected_z - global_in.z(); + global_in.z() = cluster_crossing_corrected_z; + + std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl + << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) << std::endl + << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) << std::endl + << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl + << " distortion " << global(0) - global_in(0) << " " + << global(1) - global_in(1) << " " << global(2) - global_in(2) + << " cluster crossing z correction " << crossing_correction + << std::endl; + } + } } // add the global positions to a vector to give to the cluster mover - global_raw.emplace_back(std::make_pair(key, global)); + global_raw.emplace_back(key, global); } // end loop over clusters here @@ -405,10 +434,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } // loop over global positions returned by cluster mover - for(auto&& [cluskey, global] : global_moved) + for (auto&& [cluskey, global] : global_moved) { // std::cout << "Global moved: " << global.x() << " " << global.y() << " " << global.z() << std::endl; - + if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) { if (m_verbosity > 3) @@ -419,21 +448,26 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( continue; } - auto cluster = clusterContainer->findCluster(cluskey); + auto* cluster = clusterContainer->findCluster(cluskey); Surface surf = tGeometry->maps().getSurface(cluskey, cluster); - if(std::isnan(global.x()) || std::isnan(global.y())) + if (std::isnan(global.x()) || std::isnan(global.y())) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - invalid position" - << " key: " << cluskey - << " layer: " << (int)TrkrDefs::getLayer(cluskey) - << " position: " << global - << std::endl; + << " key: " << cluskey + << " layer: " << (int) TrkrDefs::getLayer(cluskey) + << " position: " << global + << std::endl; } // if this is a TPC cluster, the crossing correction may have moved it across the central membrane, check the surface auto trkrid = TrkrDefs::getTrkrId(cluskey); if (trkrid == TrkrDefs::tpcId) { + if (cluster->getEdge() > m_cluster_edge_rejection) + { + continue; + } + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluskey); TrkrDefs::subsurfkey new_subsurfkey = 0; surf = tGeometry->get_tpc_surface_from_coords(hitsetkey, global, new_subsurfkey); @@ -441,7 +475,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( if (!surf) { - if(m_verbosity > 2) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Failed to find surface for cluskey " << cluskey << std::endl; } + if (m_verbosity > 2) + { + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Failed to find surface for cluskey " << cluskey << std::endl; + } continue; } @@ -449,7 +486,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( Acts::Vector2 localPos; global *= Acts::UnitConstants::cm; // we want mm for transformations - Acts::Vector3 normal = surf->normal(tGeometry->geometry().getGeoContext(),Acts::Vector3(1,1,1), Acts::Vector3(1,1,1)); + Acts::Vector3 normal = surf->normal(tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1)); auto local = surf->globalToLocal(tGeometry->geometry().getGeoContext(), global, normal); if (local.ok()) @@ -458,11 +495,14 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } else { - if(m_verbosity > 2) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Taking manual calculation for global to local " << std::endl; } + if (m_verbosity > 2) + { + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Taking manual calculation for global to local " << std::endl; + } /// otherwise take the manual calculation for the TPC // doing it this way just avoids the bounds check that occurs in the surface class method - Acts::Vector3 loct = surf->transform(tGeometry->geometry().getGeoContext()).inverse() * global ; // global is in mm + Acts::Vector3 loct = surf->transform(tGeometry->geometry().getGeoContext()).inverse() * global; // global is in mm loct /= Acts::UnitConstants::cm; localPos(0) = loct(0); @@ -474,34 +514,34 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Cluster " << cluskey << " cluster global after mover: " << global << std::endl; std::cout << "MakeSourceLinks::getSourceLinksClusterMover - stored: cluster local X " << cluster->getLocalX() << " cluster local Y " << cluster->getLocalY() << std::endl; - const Acts::Vector2 localTest = tGeometry->getLocalCoords(cluskey, cluster); // cm + const Acts::Vector2 localTest = tGeometry->getLocalCoords(cluskey, cluster); // cm std::cout << "MakeSourceLinks::getSourceLinksClusterMover - localTest from getLocalCoords: " << localTest << std::endl; std::cout << "MakeSourceLinks::getSourceLinksClusterMover - new from inverse transform of cluster global after mover: " << std::endl; - const Acts::Vector3 globalTest = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localTest*Acts::UnitConstants::cm, normal); - std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from localTest: " << Acts::Vector3(globalTest/Acts::UnitConstants::cm) << std::endl; + const Acts::Vector3 globalTest = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localTest * Acts::UnitConstants::cm, normal); + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from localTest: " << Acts::Vector3(globalTest / Acts::UnitConstants::cm) << std::endl; - const Acts::Vector3 globalNew = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localPos*Acts::UnitConstants::cm, normal); - std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from new local: " << Acts::Vector3(globalNew/Acts::UnitConstants::cm) << std::endl; + const Acts::Vector3 globalNew = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localPos * Acts::UnitConstants::cm, normal); + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from new local: " << Acts::Vector3(globalNew / Acts::UnitConstants::cm) << std::endl; } Acts::ActsVector<2> loc; loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; std::array indices = - {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); + auto para_errors = ClusterErrorPara::get_clusterv5_modified_error(cluster, clusRadius, cluskey); cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; ActsSourceLink::Index index = measurements.size(); - + SourceLink sl(surf->geometryId(), index, cluskey); Acts::SourceLink actsSL{sl}; Acts::Measurement meas(actsSL, indices, loc, cov); @@ -521,16 +561,16 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } sourcelinks.push_back(actsSL); - measurements.push_back(meas); + measurements.emplace_back(meas); } SLTrackTimer.stop(); auto SLTime = SLTrackTimer.get_accumulated_time(); if (m_verbosity > 1) - { - std::cout << "PHMakeSourceLinks::getSourceLinksClusterMover - ActsTrkFitter Source Links generation time: " + { + std::cout << "PHMakeSourceLinks::getSourceLinksClusterMover - ActsTrkFitter Source Links generation time: " << SLTime << std::endl; - } + } return sourcelinks; } diff --git a/offline/packages/trackreco/MakeSourceLinks.h b/offline/packages/trackreco/MakeSourceLinks.h index 8acf4f8272..d22acc4881 100644 --- a/offline/packages/trackreco/MakeSourceLinks.h +++ b/offline/packages/trackreco/MakeSourceLinks.h @@ -1,17 +1,17 @@ #ifndef TRACKRECO_MAKESOURCELINKS_H #define TRACKRECO_MAKESOURCELINKS_H -#include #include #include -#include #include +#include +#include #include /// Acts includes to create all necessary definitions -#include #include +#include #include @@ -40,51 +40,47 @@ class TrackSeed; class MakeSourceLinks { public: - MakeSourceLinks() = default; + MakeSourceLinks() = default; - void initialize(PHG4TpcGeomContainer* cellgeo); + void initialize(PHG4TpcGeomContainer* cellgeo); - void setVerbosity(int verbosity) {m_verbosity = verbosity;} - - void set_pp_mode(bool ispp) { m_pp_mode = ispp; } + void setVerbosity(int verbosity) { m_verbosity = verbosity; } + void set_pp_mode(bool ispp) { m_pp_mode = ispp; } + void set_cluster_edge_rejection(int edge) { m_cluster_edge_rejection = edge; } void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } SourceLinkVec getSourceLinks( - TrackSeed* /*seed*/, - ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, - TrkrClusterContainer* /*clusters*/, - ActsGeometry* /*geometry*/, - const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, - alignmentTransformationContainer* /*transformMapTransient*/, - std::set< Acts::GeometryIdentifier>& /*transient_id_set*/, - short int /*crossing*/); + TrackSeed* /*seed*/, + ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, + TrkrClusterContainer* /*clusters*/, + ActsGeometry* /*geometry*/, + const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, + alignmentTransformationContainer* /*transformMapTransient*/, + std::set& /*transient_id_set*/, + short int /*crossing*/); void resetTransientTransformMap( - alignmentTransformationContainer* /*transformMapTransient*/, - std::set< Acts::GeometryIdentifier>& /*transient_id_set*/, - ActsGeometry* /*tGeometry*/ ); + alignmentTransformationContainer* /*transformMapTransient*/, + std::set& /*transient_id_set*/, + ActsGeometry* /*tGeometry*/) const; SourceLinkVec getSourceLinksClusterMover( - TrackSeed* /*seed*/, - ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, - TrkrClusterContainer* /*clusters*/, - ActsGeometry* /*geometry*/, - const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, - short int crossing - ); + TrackSeed* /*seed*/, + ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, + TrkrClusterContainer* /*clusters*/, + ActsGeometry* /*geometry*/, + const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, + short int crossing); private: int m_verbosity = 0; bool m_pp_mode = false; std::set m_ignoreLayer; - + int m_cluster_edge_rejection = 0; TpcClusterMover _clusterMover; ClusterErrorPara _ClusErrPara; - - }; - #endif diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index d4741a2ca9..8af74c701f 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -818,10 +818,13 @@ std::vector PHActsSiliconSeeding::findMatches( float avgtriplety = 0; for (auto& pos : clusters) { - avgtripletx += std::cos(std::atan2(pos(1), pos(0))); - avgtriplety += std::sin(std::atan2(pos(1), pos(0))); + + avgtripletx += std::cos(getPhiFromBeamSpot(pos(1), pos(0))); + avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } + float avgtripletphi = std::atan2(avgtriplety, avgtripletx); + std::vector dummykeys = keys; std::vector dummyclusters = clusters; @@ -889,6 +892,9 @@ std::vector PHActsSiliconSeeding::findMatches( // get an estimate of the phi of the track at this layer // to know which hitsetkeys to look at float layerradius = 0; + float x0 = 0.0; + float y0 = 0.0; + if (layer > 2) { layerradius = m_geomContainerIntt->GetLayerGeom(layer)->get_radius(); @@ -896,12 +902,21 @@ std::vector PHActsSiliconSeeding::findMatches( else { layerradius = m_geomContainerMvtx->GetLayerGeom(layer)->get_radius(); + x0 = m_mvtx_x0; + y0 = m_mvtx_y0; } + float xfitradius_moved = fitpars[1] - x0; + float yfitradius_moved = fitpars[2] - y0; const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], - fitpars[1], fitpars[2]); - - float approximate_phi1 = atan2(yplus, xplus); - float approximate_phi2 = atan2(yminus, xminus); + xfitradius_moved, yfitradius_moved); + float xp = xplus + x0; + float xm = xminus + x0; + float yp = yplus + y0; + float ym = yminus + y0; + + + float approximate_phi1 = getPhiFromBeamSpot(yp, xp); + float approximate_phi2 = getPhiFromBeamSpot(ym, xm); float approximatephi = approximate_phi1; if (std::fabs(normPhi2Pi(approximate_phi2 - avgtripletphi)) < std::fabs(normPhi2Pi(approximate_phi1 - avgtripletphi))) { @@ -911,7 +926,7 @@ std::vector PHActsSiliconSeeding::findMatches( { auto surf = m_tGeometry->maps().getSiliconSurface(hitsetkey); auto surfcenter = surf->center(m_tGeometry->geometry().geoContext); - float surfphi = atan2(surfcenter.y(), surfcenter.x()); + float surfphi = getPhiFromBeamSpot(surfcenter.y(), surfcenter.x()); float dphi = normPhi2Pi(approximatephi - surfphi); /// Check that the projection is within some reasonable amount of the segment @@ -1141,9 +1156,10 @@ std::vector> PHActsSiliconSeeding::iterateLayers( float avgtriplety = 0; for (const auto& pos : positions) { - avgtripletx += std::cos(std::atan2(pos(1), pos(0))); - avgtriplety += std::sin(std::atan2(pos(1), pos(0))); + avgtripletx += std::cos(getPhiFromBeamSpot(pos(1), pos(0))); + avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } + float avgtripletphi = std::atan2(avgtriplety, avgtripletx); int layer34timebucket = std::numeric_limits::max(); @@ -1155,13 +1171,29 @@ std::vector> PHActsSiliconSeeding::iterateLayers( } } + // move the fitted circle center the negative of the MVTX center position + float x0 = 0.0; // cm + float y0 = 0.0; for (int layer = startLayer; layer < endLayer; ++layer) { float layerradius = m_geomContainerIntt->GetLayerGeom(layer)->get_radius(); - const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], fitpars[1], fitpars[2]); + if(layer < 3) + { + x0 = m_mvtx_x0; + y0 = m_mvtx_y0; + } - float approximate_phi1 = atan2(yplus, xplus); - float approximate_phi2 = atan2(yminus, xminus); + float xfitradius_moved = fitpars[1] - x0; + float yfitradius_moved = fitpars[2] - y0; + + const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], xfitradius_moved, yfitradius_moved); + + float xp = xplus + x0; + float xm = xminus + x0; + float yp = yplus + y0; + float ym = yminus + y0; + float approximate_phi1 = getPhiFromBeamSpot(yp, xp); + float approximate_phi2 = getPhiFromBeamSpot(ym, xm); float approximatephi = approximate_phi1; if (std::fabs(normPhi2Pi(approximate_phi2 - avgtripletphi)) < std::fabs(normPhi2Pi(approximate_phi1 - avgtripletphi))) { @@ -1171,7 +1203,7 @@ std::vector> PHActsSiliconSeeding::iterateLayers( { auto surf = m_tGeometry->maps().getSiliconSurface(hitsetkey); auto surfcenter = surf->center(m_tGeometry->geometry().geoContext); - float surfphi = atan2(surfcenter.y(), surfcenter.x()); + float surfphi = getPhiFromBeamSpot(surfcenter.y(), surfcenter.x()); if(Verbosity() > 5) { std::cout << "approximate phis " << approximate_phi1 << " " << approximate_phi2 << " using " << approximatephi @@ -1404,7 +1436,8 @@ std::vector PHActsSiliconSeeding::getSiliconSpacePoints(Acts: if (det == TrkrDefs::TrkrId::mvtxId) { auto strobeId = MvtxDefs::getStrobeId(hitsetkey); - if (strobeId != strobe) + //if (strobeId != strobe) + if (abs(strobeId - strobe) > 1) { continue; } @@ -1713,6 +1746,15 @@ double PHActsSiliconSeeding::normPhi2Pi(const double phi) return returnPhi; } +float PHActsSiliconSeeding::getPhiFromBeamSpot(float clusy, float clusx) const +{ + // Calculate the phi value for (clusx, clusy) relative to the beam spot (x,y) position + + float phirel = std::atan2(clusy - m_beamSpoty, clusx - m_beamSpotx); + + return phirel; +} + void PHActsSiliconSeeding::largeGridSpacing(const bool spacing) { if (!spacing) diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.h b/offline/packages/trackreco/PHActsSiliconSeeding.h index ea3fe2c1ad..506f9c225c 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.h +++ b/offline/packages/trackreco/PHActsSiliconSeeding.h @@ -176,6 +176,16 @@ class PHActsSiliconSeeding : public SubsysReco { m_minSeedPt = pt; } + void set_mvtxCenterXY(const float X, const float Y) + { + m_mvtx_x0 = X; + m_mvtx_y0 = Y; + } + void set_beamSpotXY(const float X, const float Y) + { + m_beamSpotx = X; + m_beamSpoty = Y; + } /// A function to run the seeder with large (true) /// or small (false) grid spacing @@ -243,6 +253,8 @@ class PHActsSiliconSeeding : public SubsysReco short int getCrossingIntt(TrackSeed &si_track); std::vector getInttCrossings(TrackSeed &si_track); + float getPhiFromBeamSpot(float clusy, float clusx) const; + void createHistograms(); void writeHistograms(); double normPhi2Pi(const double phi); @@ -354,6 +366,15 @@ class PHActsSiliconSeeding : public SubsysReco float m_inttzSearchWin = 2.0; // default to one strip width double m_mvtxrPhiSearchWin = 0.2; float m_mvtxzSearchWin = 0.5; + + // collision point in sPHENIX coordinates, from vertex finder (pp run 3) + float m_beamSpotx = -0.072; // cm + float m_beamSpoty = 0.141; // cm + + // center of MVTX barrel in sPHENIX coordinates - default is for Run 3 pp + float m_mvtx_x0 = 0.6; // cm + float m_mvtx_y0 = -0.1; + /// Whether or not to use truth clusters in hit lookup bool m_useTruthClusters = false; diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index a26ee1fa0a..5a92307b81 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -5,7 +5,6 @@ * \author Tony Frawley */ - #include "PHActsTrkFitter.h" #include "ActsPropagator.h" @@ -25,7 +24,7 @@ #include #include #include -//#include +// #include #include #include #include @@ -134,8 +133,8 @@ int PHActsTrkFitter::InitRun(PHCompositeNode* topNode) MaterialSurfaceSelector selector; if (m_fitSiliconMMs || m_directNavigation) { - m_tGeometry->geometry().tGeometry->visitSurfaces(selector,false); - //std::cout<<"selector.surfaces.size() "<geometry().tGeometry->visitSurfaces(selector, false); + // std::cout<<"selector.surfaces.size() "<(m_evalname); m_evaluator->Init(topNode); - if(m_actsEvaluator && !m_simActsEvaluator) + if (m_actsEvaluator && !m_simActsEvaluator) { m_evaluator->isData(); } @@ -182,10 +182,10 @@ int PHActsTrkFitter::InitRun(PHCompositeNode* topNode) _tpccellgeo = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!_tpccellgeo) - { - std::cout << PHWHERE << " unable to find DST node TPCGEOMCONTAINER" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } + { + std::cout << PHWHERE << " unable to find DST node TPCGEOMCONTAINER" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } if (Verbosity() > 1) { @@ -287,7 +287,7 @@ int PHActsTrkFitter::End(PHCompositeNode* /*topNode*/) { m_evaluator->End(); } - if(m_useOutlierFinder) + if (m_useOutlierFinder) { m_outlierFinder.Write(); } @@ -314,47 +314,46 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) // capture the input crossing value, and set crossing parameters //============================== - short silicon_crossing = SHRT_MAX; - auto siseed = m_siliconSeeds->get(siid); - if(siseed) - { - silicon_crossing = siseed->get_crossing(); - } + short silicon_crossing = SHRT_MAX; + auto *siseed = m_siliconSeeds->get(siid); + if (siseed) + { + silicon_crossing = siseed->get_crossing(); + } short crossing = silicon_crossing; short int crossing_estimate = crossing; - if(m_enable_crossing_estimate) - { - crossing_estimate = track->get_crossing_estimate(); // geometric crossing estimate from matcher - } + if (m_enable_crossing_estimate) + { + crossing_estimate = track->get_crossing_estimate(); // geometric crossing estimate from matcher + } //=============================== - // must have silicon seed with valid crossing if we are doing a SC calibration fit if (m_fitSiliconMMs) + { + if ((siid == std::numeric_limits::max()) || (silicon_crossing == SHRT_MAX)) { - if( (siid == std::numeric_limits::max()) || (silicon_crossing == SHRT_MAX)) - { - continue; - } + continue; } + } // do not skip TPC only tracks, just set crossing to the nominal zero - if(!siseed) - { - crossing = 0; - } + if (!siseed) + { + crossing = 0; + } if (Verbosity() > 1) { - if(siseed) - { - std::cout << "tpc and si id " << tpcid << ", " << siid << " silicon_crossing " << silicon_crossing - << " crossing " << crossing << " crossing estimate " << crossing_estimate << std::endl; - } + if (siseed) + { + std::cout << "tpc and si id " << tpcid << ", " << siid << " silicon_crossing " << silicon_crossing + << " crossing " << crossing << " crossing estimate " << crossing_estimate << std::endl; + } } - auto tpcseed = m_tpcSeeds->get(tpcid); + auto *tpcseed = m_tpcSeeds->get(tpcid); /// Need to also check that the tpc seed wasn't removed by the ghost finder if (!tpcseed) @@ -381,7 +380,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (Verbosity() > 1 && siseed) { std::cout << " m_pp_mode " << m_pp_mode << " m_enable_crossing_estimate " << m_enable_crossing_estimate - << " INTT crossing " << crossing << " crossing_estimate " << crossing_estimate << std::endl; + << " INTT crossing " << crossing << " crossing_estimate " << crossing_estimate << std::endl; } short int this_crossing = crossing; @@ -390,35 +389,35 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) std::vector chisq_ndf; std::vector svtx_vec; - if(m_pp_mode) + if (m_pp_mode) + { + if (m_enable_crossing_estimate && crossing == SHRT_MAX) + { + // this only happens if there is a silicon seed but no assigned INTT crossing, and only in pp_mode + // If there is no INTT crossing, start with the crossing_estimate value, vary up and down, fit, and choose the best chisq/ndf + use_estimate = true; + nvary = max_bunch_search; + if (Verbosity() > 1) + { + std::cout << " No INTT crossing: use crossing_estimate " << crossing_estimate << " with nvary " << nvary << std::endl; + } + } + else { - if (m_enable_crossing_estimate && crossing == SHRT_MAX) - { - // this only happens if there is a silicon seed but no assigned INTT crossing, and only in pp_mode - // If there is no INTT crossing, start with the crossing_estimate value, vary up and down, fit, and choose the best chisq/ndf - use_estimate = true; - nvary = max_bunch_search; - if (Verbosity() > 1) - { - std::cout << " No INTT crossing: use crossing_estimate " << crossing_estimate << " with nvary " << nvary << std::endl; - } - } - else - { - // use INTT crossing - crossing_estimate = crossing; - } + // use INTT crossing + crossing_estimate = crossing; } + } else + { + // non pp mode, we want only crossing zero, veto others + if (siseed && silicon_crossing != 0) { - // non pp mode, we want only crossing zero, veto others - if(siseed && silicon_crossing != 0) - { - crossing = 0; - //continue; - } - crossing_estimate = crossing; + crossing = 0; + // continue; } + crossing_estimate = crossing; + } // Fit this track assuming either: // crossing = INTT value, if it exists (uses nvary = 0) @@ -441,16 +440,17 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) makeSourceLinks.initialize(_tpccellgeo); makeSourceLinks.setVerbosity(Verbosity()); makeSourceLinks.set_pp_mode(m_pp_mode); - for(const auto& layer : m_ignoreLayer) + makeSourceLinks.set_cluster_edge_rejection(m_cluster_edge_rejection); + for (const auto& layer : m_ignoreLayer) { makeSourceLinks.ignoreLayer(layer); } // loop over modifiedTransformSet and replace transient elements modified for the previous track with the default transforms // does nothing if m_transient_id_set is empty makeSourceLinks.resetTransientTransformMap( - m_alignmentTransformationMapTransient, - m_transient_id_set, - m_tGeometry); + m_alignmentTransformationMapTransient, + m_transient_id_set, + m_tGeometry); if (m_use_clustermover) { @@ -459,37 +459,56 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) { // silicon source links sourceLinks = makeSourceLinks.getSourceLinksClusterMover( - siseed, + siseed, + measurements, + m_clusterContainer, + m_tGeometry, + m_globalPositionWrapper, + this_crossing); + } + + // tpc source links + const auto tpcSourceLinks = makeSourceLinks.getSourceLinksClusterMover( + tpcseed, measurements, m_clusterContainer, m_tGeometry, m_globalPositionWrapper, this_crossing); - } - - // tpc source links - const auto tpcSourceLinks = makeSourceLinks.getSourceLinksClusterMover( - tpcseed, - measurements, - m_clusterContainer, - m_tGeometry, - m_globalPositionWrapper, - this_crossing); // add tpc sourcelinks to silicon source links sourceLinks.insert(sourceLinks.end(), tpcSourceLinks.begin(), tpcSourceLinks.end()); - - } else { - + } + else + { // make source links using transient transforms for distortion corrections - if(Verbosity() > 1) - { std::cout << "Calling getSourceLinks for si seed, siid " << siid << " and tpcid " << tpcid << std::endl; } + if (Verbosity() > 1) + { + std::cout << "Calling getSourceLinks for si seed, siid " << siid << " and tpcid " << tpcid << std::endl; + } if (siseed && !m_ignoreSilicon) { // silicon source links sourceLinks = makeSourceLinks.getSourceLinks( - siseed, + siseed, + measurements, + m_clusterContainer, + m_tGeometry, + m_globalPositionWrapper, + m_alignmentTransformationMapTransient, + m_transient_id_set, + this_crossing); + } + + if (Verbosity() > 1) + { + std::cout << "Calling getSourceLinks for tpc seed, siid " << siid << " and tpcid " << tpcid << std::endl; + } + + // tpc source links + const auto tpcSourceLinks = makeSourceLinks.getSourceLinks( + tpcseed, measurements, m_clusterContainer, m_tGeometry, @@ -497,21 +516,6 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) m_alignmentTransformationMapTransient, m_transient_id_set, this_crossing); - } - - if(Verbosity() > 1) - { std::cout << "Calling getSourceLinks for tpc seed, siid " << siid << " and tpcid " << tpcid << std::endl; } - - // tpc source links - const auto tpcSourceLinks = makeSourceLinks.getSourceLinks( - tpcseed, - measurements, - m_clusterContainer, - m_tGeometry, - m_globalPositionWrapper, - m_alignmentTransformationMapTransient, - m_transient_id_set, - this_crossing); // add tpc sourcelinks to silicon source links sourceLinks.insert(sourceLinks.end(), tpcSourceLinks.begin(), tpcSourceLinks.end()); @@ -524,15 +528,15 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) Acts::Vector3 position(0, 0, 0); if (siseed) { - position = TrackSeedHelper::get_xyz(siseed)*Acts::UnitConstants::cm; + position = TrackSeedHelper::get_xyz(siseed) * Acts::UnitConstants::cm; } - if(!siseed || !is_valid(position) || m_ignoreSilicon) + if (!siseed || !is_valid(position) || m_ignoreSilicon) { - position = TrackSeedHelper::get_xyz(tpcseed)*Acts::UnitConstants::cm; + position = TrackSeedHelper::get_xyz(tpcseed) * Acts::UnitConstants::cm; } if (!is_valid(position)) { - if(Verbosity() > 4) + if (Verbosity() > 4) { std::cout << "Invalid position of " << position.transpose() << std::endl; } @@ -559,26 +563,26 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) for (const auto& surface_apr : m_materialSurfaces) { - if(m_forceSiOnlyFit) + if (m_forceSiOnlyFit) { - if(surface_apr->geometryId().volume() >12) + if (surface_apr->geometryId().volume() > 12) { continue; } } bool pop_flag = false; - if(surface_apr->geometryId().approach() == 1) + if (surface_apr->geometryId().approach() == 1) { surfaces.push_back(surface_apr); } else { pop_flag = true; - for (const auto& surface_sns: surfaces_tmp) + for (const auto& surface_sns : surfaces_tmp) { if (surface_apr->geometryId().volume() == surface_sns->geometryId().volume()) { - if ( surface_apr->geometryId().layer()==surface_sns->geometryId().layer()) + if (surface_apr->geometryId().layer() == surface_sns->geometryId().layer()) { pop_flag = false; surfaces.push_back(surface_sns); @@ -594,9 +598,9 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) surfaces.pop_back(); pop_flag = false; } - if (surface_apr->geometryId().volume() == 12&& surface_apr->geometryId().layer()==8) + if (surface_apr->geometryId().volume() == 12 && surface_apr->geometryId().layer() == 8) { - for (const auto& surface_sns: surfaces_tmp) + for (const auto& surface_sns : surfaces_tmp) { if (14 == surface_sns->geometryId().volume()) { @@ -619,13 +623,13 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) { // make sure micromegas are in the tracks, if required if (m_useMicromegas && - std::none_of(surfaces.begin(), surfaces.end(), [this](const auto& surface) - { return m_tGeometry->maps().isMicromegasSurface(surface); })) - { - continue; + std::none_of(surfaces.begin(), surfaces.end(), [this](const auto& surface) + { return m_tGeometry->maps().isMicromegasSurface(surface); })) + { + continue; + } } } - } float px = std::numeric_limits::quiet_NaN(); float py = std::numeric_limits::quiet_NaN(); @@ -635,7 +639,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) float seedphi = 0; float seedtheta = 0; float seedeta = 0; - if(siseed) + if (siseed) { seedphi = siseed->get_phi(); seedtheta = siseed->get_theta(); @@ -659,7 +663,9 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) px = pt * std::cos(phi); py = pt * std::sin(phi); pz = pt * std::cosh(eta) * std::cos(theta); - } else { + } + else + { px = seedpt * std::cos(seedphi); py = seedpt * std::sin(seedphi); pz = seedpt * std::cosh(seedeta) * std::cos(seedtheta); @@ -668,14 +674,14 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) Acts::Vector3 momentum(px, py, pz); if (!is_valid(momentum)) { - if(Verbosity() > 4) + if (Verbosity() > 4) { std::cout << "Invalid momentum of " << momentum.transpose() << std::endl; } continue; } - auto pSurface = Acts::Surface::makeShared( position); + auto pSurface = Acts::Surface::makeShared(position); Acts::Vector4 actsFourPos(position(0), position(1), position(2), 10 * Acts::UnitConstants::ns); Acts::BoundSquareMatrix cov = setDefaultCovariance(); @@ -723,8 +729,10 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) auto trackStateContainer = std::make_shared(); ActsTrackFittingAlgorithm::TrackContainer tracks(trackContainer, trackStateContainer); - if(Verbosity() > 1) - { std::cout << "Calling fitTrack for track with siid " << siid << " tpcid " << tpcid << " crossing " << crossing << std::endl; } + if (Verbosity() > 1) + { + std::cout << "Calling fitTrack for track with siid " << siid << " tpcid " << tpcid << " crossing " << crossing << std::endl; + } auto result = fitTrack(sourceLinks, seed, kfOptions, surfaces, calibrator, tracks); fitTimer.stop(); @@ -761,7 +769,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (ivary != nvary) { - if(Verbosity() > 3) + if (Verbosity() > 3) { std::cout << "Skipping track fit for trial variation" << std::endl; } @@ -806,7 +814,6 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (getTrackFitResult(result, track, &newTrack, tracks, measurements)) { - // insert in dedicated map m_directedTrackMap->insertWithKey(&newTrack, trid); } @@ -822,11 +829,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) m_trackMap->insertWithKey(&newTrack, trid); } } // end insert track for normal fit - } // end case where INTT crossing is known - - - - + } // end case where INTT crossing is known } else if (!m_fitSiliconMMs) { @@ -840,7 +843,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) << std::endl; } } // end fit failed case - } // end ivary loop + } // end ivary loop trackTimer.stop(); auto trackTime = trackTimer.get_accumulated_time(); @@ -855,10 +858,10 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) } bool PHActsTrkFitter::getTrackFitResult( - const FitResult& fitOutput, - TrackSeed* seed, SvtxTrack* track, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) + const FitResult& fitOutput, + TrackSeed* seed, SvtxTrack* track, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) { /// Make a trajectory state for storage, which conforms to Acts track fit /// analysis tool @@ -872,12 +875,12 @@ bool PHActsTrkFitter::getTrackFitResult( // retrieve track parameters from fit result Acts::BoundTrackParameters parameters = ActsExamples::TrackParameters(outtrack.referenceSurface().getSharedPtr(), - outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()); + outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()); indexedParams.emplace( - outtrack.tipIndex(), - ActsExamples::TrackParameters{outtrack.referenceSurface().getSharedPtr(), - outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()}); + outtrack.tipIndex(), + ActsExamples::TrackParameters{outtrack.referenceSurface().getSharedPtr(), + outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()}); if (Verbosity() > 2) { @@ -948,7 +951,9 @@ ActsTrackFittingAlgorithm::TrackFitterResult PHActsTrkFitter::fitTrack( { // use direct fit for silicon MM gits or direct navigation if (m_fitSiliconMMs || m_directNavigation) - { return (*m_fitCfg.dFit)(sourceLinks, seed, kfOptions, surfSequence, calibrator, tracks); } + { + return (*m_fitCfg.dFit)(sourceLinks, seed, kfOptions, surfSequence, calibrator, tracks); + } // use full fit in all other cases return (*m_fitCfg.fit)(sourceLinks, seed, kfOptions, calibrator, tracks); @@ -986,9 +991,9 @@ SourceLinkVec PHActsTrkFitter::getSurfaceVector(const SourceLinkVec& sourceLinks } } - if(m_forceSiOnlyFit) + if (m_forceSiOnlyFit) { - if(m_tGeometry->maps().isMicromegasSurface(surf)||m_tGeometry->maps().isTpcSurface(surf)) + if (m_tGeometry->maps().isMicromegasSurface(surf) || m_tGeometry->maps().isTpcSurface(surf)) { continue; } @@ -1059,10 +1064,10 @@ void PHActsTrkFitter::checkSurfaceVec(SurfacePtrVec& surfaces) const } void PHActsTrkFitter::updateSvtxTrack( - const std::vector& tips, - const Trajectory::IndexedParameters& paramsMap, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - SvtxTrack* track) + const std::vector& tips, + const Trajectory::IndexedParameters& paramsMap, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + SvtxTrack* track) { const auto& mj = tracks.trackStateContainer(); @@ -1133,31 +1138,37 @@ void PHActsTrkFitter::updateSvtxTrack( trackStateTimer.restart(); if (m_fillSvtxTrackStates) - { transformer.fillSvtxTrackStates(mj, trackTip, track, m_transient_geocontext); } + { + transformer.fillSvtxTrackStates(mj, trackTip, track, m_transient_geocontext); + } // in using silicon mm fit also extrapolate track parameters to all TPC surfaces with clusters // get all tpc clusters auto* seed = track->get_tpc_seed(); - if( m_fitSiliconMMs && seed ) + if (m_fitSiliconMMs && seed) { - // acts propagator ActsPropagator propagator(m_tGeometry); // loop over cluster keys associated to TPC seed - for( auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter ) + for (auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter) { const auto& cluskey = *key_iter; // make sure cluster is from TPC const auto detId = TrkrDefs::getTrkrId(cluskey); if (detId != TrkrDefs::tpcId) - { continue; } + { + continue; + } // get layer, propagate const auto layer = TrkrDefs::getLayer(cluskey); auto result = propagator.propagateTrack(params, layer); - if( !result.ok() ) { continue; } + if (!result.ok()) + { + continue; + } // get path length and extrapolated parameters auto& [pathLength, trackStateParams] = result.value(); diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index c6e0afec35..09a8ab9d1d 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include @@ -130,20 +130,21 @@ class PHActsTrkFitter : public SubsysReco void set_track_map_name(const std::string& map_name) { _track_map_name = map_name; } void set_svtx_seed_map_name(const std::string& map_name) { _svtx_seed_map_name = map_name; } - void set_svtx_alignment_state_map_name(const std::string& map_name) { - _svtx_alignment_state_map_name = map_name; - m_alignStates.alignmentStateMap(map_name); + void set_svtx_alignment_state_map_name(const std::string& map_name) + { + _svtx_alignment_state_map_name = map_name; + m_alignStates.alignmentStateMap(map_name); } /// Set flag for pp running void set_pp_mode(bool ispp) { m_pp_mode = ispp; } - void set_enable_geometric_crossing_estimate(bool flag) { m_enable_crossing_estimate = flag ; } + void set_enable_geometric_crossing_estimate(bool flag) { m_enable_crossing_estimate = flag; } void set_use_clustermover(bool use) { m_use_clustermover = use; } void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } - void setTrkrClusterContainerName(std::string &name){ m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string& name) { m_clusterContainerName = name; } void setDirectNavigation(bool flag) { m_directNavigation = flag; } - + void setClusterEdgeRejection(int edge ) { m_cluster_edge_rejection = edge; } private: /// Get all the nodes int getNodes(PHCompositeNode* topNode); @@ -155,10 +156,10 @@ class PHActsTrkFitter : public SubsysReco /// Convert the acts track fit result to an svtx track void updateSvtxTrack( - const std::vector& tips, - const Trajectory::IndexedParameters& paramsMap, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - SvtxTrack* track); + const std::vector& tips, + const Trajectory::IndexedParameters& paramsMap, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + SvtxTrack* track); /// Helper function to call either the regular navigation or direct /// navigation, depending on m_fitSiliconMMs @@ -240,9 +241,10 @@ class PHActsTrkFitter : public SubsysReco // max variation of bunch crossing away from crossing_estimate short int max_bunch_search = 2; - //name of TRKR_CLUSTER container + // name of TRKR_CLUSTER container std::string m_clusterContainerName = "TRKR_CLUSTER"; + int m_cluster_edge_rejection = 0; //!@name evaluator //@{ bool m_actsEvaluator = false; @@ -253,7 +255,7 @@ class PHActsTrkFitter : public SubsysReco //@} //! tracks -// SvtxTrackMap* m_seedTracks = nullptr; + // SvtxTrackMap* m_seedTracks = nullptr; //! tpc global position wrapper TpcGlobalPositionWrapper m_globalPositionWrapper; @@ -268,7 +270,7 @@ class PHActsTrkFitter : public SubsysReco int _n_iteration = 0; std::string _track_map_name = "SvtxTrackMap"; std::string _svtx_seed_map_name = "SvtxTrackSeedContainer"; - std::string _svtx_alignment_state_map_name = "SvtxAlignmentStateMap"; + std::string _svtx_alignment_state_map_name = "SvtxAlignmentStateMap"; /// Default particle assumption to pion unsigned int m_pHypothesis = 211; @@ -292,14 +294,18 @@ class PHActsTrkFitter : public SubsysReco std::vector m_materialSurfaces = {}; - struct MaterialSurfaceSelector { + struct MaterialSurfaceSelector + { std::vector surfaces = {}; /// @param surface is the test surface - void operator()(const Acts::Surface* surface) { - if (surface->surfaceMaterial() != nullptr) { + void operator()(const Acts::Surface* surface) + { + if (surface->surfaceMaterial() != nullptr) + { if (std::find(surfaces.begin(), surfaces.end(), surface) == - surfaces.end()) { + surfaces.end()) + { surfaces.push_back(surface); } } diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 16c0848456..263fdd6b35 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -1,4 +1,3 @@ - #include "PHSiliconSeedMerger.h" #include @@ -14,34 +13,67 @@ #include #include -#include - -//____________________________________________________________________________.. +/** + * @brief Construct a PHSiliconSeedMerger with the given subsystem name. + * + * Initializes the PHSiliconSeedMerger and forwards the provided subsystem + * name to the base SubsysReco constructor. + * + * @param name Subsystem name used to register this module in the node tree. + */ PHSiliconSeedMerger::PHSiliconSeedMerger(const std::string& name) : SubsysReco(name) { } -//____________________________________________________________________________.. -PHSiliconSeedMerger::~PHSiliconSeedMerger() -{ -} +/** + * @brief Default destructor for PHSiliconSeedMerger. + * + * Performs default cleanup of the merger object and its owned resources. + */ +PHSiliconSeedMerger::~PHSiliconSeedMerger() = default; -//____________________________________________________________________________.. -int PHSiliconSeedMerger::Init(PHCompositeNode*) +/** + * @brief Perform module initialization (no operation required). + * + * This implementation does not perform any setup and always succeeds. + * + * @return int `EVENT_OK` indicating initialization succeeded. + */ +int PHSiliconSeedMerger::Init(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. +/** + * @brief Initializes run-time resources by retrieving required nodes. + * + * Calls getNodes(topNode) to locate and cache containers needed for processing this run. + * + * @param topNode Root of the node tree from which required nodes are retrieved. + * @return int `EVENT_OK` on success, `ABORTEVENT` or another non-zero code on failure. + */ int PHSiliconSeedMerger::InitRun(PHCompositeNode* topNode) { int ret = getNodes(topNode); return ret; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::process_event(PHCompositeNode*) +/** + * @brief Merge overlapping silicon seed tracks by consolidating MVTX cluster keys. + * + * Detects seeds whose MVTX cluster key sets fully overlap (one set equals the + * intersection) and treats one seed as a duplicate of the other. The merger + * preserves the seed with the larger MVTX key set; if both seeds share the + * same MVTX strobe and seed merging is enabled, the smaller seed's MVTX keys + * are merged into the preserved seed. After consolidation, duplicate seeds are + * erased from the silicon track container and preserved seeds are updated to + * include any newly merged MVTX cluster keys. + * + * @return Fun4AllReturnCodes::EVENT_OK on successful processing. + * + */ +int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { std::multimap> matches; std::set seedsToDelete; @@ -57,7 +89,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { TrackSeed* track1 = m_siliconTracks->get(track1ID); - if (seedsToDelete.find(track1ID) != seedsToDelete.end()) + if (seedsToDelete.contains(track1ID)) { continue; } @@ -74,7 +106,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { continue; } - track1Strobe = MvtxDefs::getStrobeId(ckey); + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { + track1Strobe = MvtxDefs::getStrobeId(ckey); + } mvtx1Keys.insert(ckey); } @@ -110,7 +145,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) continue; } mvtx2Keys.insert(ckey); - track2Strobe = MvtxDefs::getStrobeId(ckey); + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { + track2Strobe = MvtxDefs::getStrobeId(ckey); + } } std::vector intersection; @@ -120,19 +158,18 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) mvtx2Keys.end(), std::back_inserter(intersection)); - /// If we have two clusters in common in the triplet, it is likely - /// from the same track - if (intersection.size() > m_clusterOverlap && track1Strobe == track2Strobe) + /// If the intersection fully encompasses one of the tracks, it is completely duplicated + if (intersection.size() == mvtx1Keys.size() || intersection.size() == mvtx2Keys.size()) { if (Verbosity() > 2) { std::cout << "Track " << track1ID << " keys " << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " ckey: " << key << std::endl; } std::cout << "Track " << track2ID << " keys " << std::endl; - for (auto& key : mvtx2Keys) + for (const auto& key : mvtx2Keys) { std::cout << " ckey: " << key << std::endl; } @@ -143,15 +180,41 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) } } - for (auto& key : mvtx2Keys) + /// one of the tracks is encompassed in the other. Take the larger one + std::set keysToKeep; + if (mvtx1Keys.size() >= mvtx2Keys.size()) + { + keysToKeep = mvtx1Keys; + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); + } + matches.insert(std::make_pair(track1ID, mvtx1Keys)); + seedsToDelete.insert(track2ID); + if (Verbosity() > 2) + { + std::cout << " will delete seed " << track2ID << std::endl; + } + } + else { - mvtx1Keys.insert(key); + keysToKeep = mvtx2Keys; + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx1Keys.begin(), mvtx1Keys.end()); + } + matches.insert(std::make_pair(track2ID, mvtx2Keys)); + seedsToDelete.insert(track1ID); + if (Verbosity() > 2) + { + std::cout << " will delete seed " << track1ID << std::endl; + } } if (Verbosity() > 2) { std::cout << "Match IDed" << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " total track keys " << key << std::endl; } @@ -166,20 +229,22 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) for (const auto& [trackKey, mvtxKeys] : matches) { - auto track = m_siliconTracks->get(trackKey); + auto* track = m_siliconTracks->get(trackKey); if (Verbosity() > 2) { std::cout << "original track: " << std::endl; track->identify(); } - for (auto& key : mvtxKeys) + for (const auto& key : mvtxKeys) { if (track->find_cluster_key(key) == track->end_cluster_keys()) { track->insert_cluster_key(key); if (Verbosity() > 2) + { std::cout << "adding " << key << std::endl; + } } } } @@ -197,7 +262,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { for (const auto& seed : *m_siliconTracks) { - if (!seed) continue; + if (!seed) + { + continue; + } seed->identify(); } } @@ -205,21 +273,41 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::ResetEvent(PHCompositeNode*) +/** + * @brief Reset per-event state for the merger. + * + * This implementation performs no per-event cleanup and always reports success. + * + * @return Integer status code: `Fun4AllReturnCodes::EVENT_OK`. + */ +int PHSiliconSeedMerger::ResetEvent(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::End(PHCompositeNode*) +/** + * @brief Perform end-of-run shutdown for the silicon seed merger. + * + * @return int EVENT_OK on successful completion. + */ +int PHSiliconSeedMerger::End(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } +/** + * @brief Retrieve required nodes from the top-level node tree and validate availability. + * + * Locates the silicon TrackSeedContainer using m_trackMapName and stores it in + * m_siliconTracks. If the container is not found, the function logs an error + * message and signals an abort for the current event. + * + * @param topNode Root node used to search for the TrackSeedContainer. + * @return int Fun4AllReturnCodes::EVENT_OK on success, Fun4AllReturnCodes::ABORTEVENT if the silicon TrackSeedContainer is not present. + */ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) { - m_siliconTracks = findNode::getClass(topNode, m_trackMapName.c_str()); + m_siliconTracks = findNode::getClass(topNode, m_trackMapName); if (!m_siliconTracks) { std::cout << PHWHERE << "No silicon track container, can't merge seeds" @@ -229,3 +317,5 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } + + diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index b8227cd581..fcd741e688 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -25,17 +25,53 @@ class PHSiliconSeedMerger : public SubsysReco int ResetEvent(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void trackMapName(const std::string &name) { m_trackMapName = name; } - void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } - void searchIntt() { m_mvtxOnly = false; } + /** + * Set the name of the track seed container to use when retrieving silicon tracks. + * + * @param name Name of the TrackSeedContainer node (defaults to "SiliconTrackSeedContainer"). + */ +void trackMapName(const std::string &name) { m_trackMapName = name; } + /** + * Set the maximum number of overlapping clusters considered during seed merging. + * @param nclusters Maximum number of clusters that may overlap (overlap threshold). + */ +void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } + /** + * @brief Allow merging searches to include the INTT detector. + * + * Configure the merger to include INTT clusters in subsequent processing by disabling the MVTX-only restriction. + */ +void searchIntt() { m_mvtxOnly = false; } + /** + * Enable merging of silicon seed tracks during event processing. + * + * When enabled, the module will merge overlapping silicon seed tracks where applicable. + */ +void mergeSeeds() { m_mergeSeeds = true; } private: int getNodes(PHCompositeNode *topNode); TrackSeedContainer *m_siliconTracks{nullptr}; std::string m_trackMapName{"SiliconTrackSeedContainer"}; - unsigned int m_clusterOverlap{1}; - bool m_mvtxOnly{true}; + /** + * Minimum number of clusters that must be shared between two silicon track seeds + * for them to be considered overlapping. + * + * Defaults to 1. + */ +unsigned int m_clusterOverlap{1}; + bool m_mergeSeeds{false}; + /** + * Restrict seed processing to the MVTX detector only. + * + * When set to `true`, operations that iterate or merge silicon seed tracks + * will be limited to clusters originating from the MVTX vertex detector. + * When `false`, clusters from other silicon detectors are included. + */ +bool m_mvtxOnly{false}; }; #endif // PHSILICONSEEDMERGER_H + + diff --git a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc index 2e66a6df28..6aaae4bf93 100644 --- a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc +++ b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc @@ -445,10 +445,10 @@ int PHSiliconTpcTrackMatching::GetNodes(PHCompositeNode *topNode) svtxNode->addNode(node); } - _cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER"); + _cluster_map = findNode::getClass(topNode, _cluster_map_name); if (!_cluster_map) { - std::cout << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << std::endl; + std::cout << PHWHERE << " ERROR: Can't find node " <<_cluster_map_name << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } diff --git a/offline/packages/trackreco/PHSiliconTpcTrackMatching.h b/offline/packages/trackreco/PHSiliconTpcTrackMatching.h index acb157bd83..6de4a1dd3a 100644 --- a/offline/packages/trackreco/PHSiliconTpcTrackMatching.h +++ b/offline/packages/trackreco/PHSiliconTpcTrackMatching.h @@ -139,7 +139,10 @@ class PHSiliconTpcTrackMatching : public SubsysReco, public PHParameterInterface void set_file_name(const std::string &name) { _file_name = name; } void set_pp_mode(const bool flag) { _pp_mode = flag; } void set_use_intt_crossing(const bool flag) { _use_intt_crossing = flag; } - + void set_cluster_map_name(const std::string &name) + { + _cluster_map_name = name; + } int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *) override; @@ -210,6 +213,7 @@ class PHSiliconTpcTrackMatching : public SubsysReco, public PHParameterInterface int _n_iteration = 0; std::string _track_map_name = "TpcTrackSeedContainer"; std::string _silicon_track_map_name = "SiliconTrackSeedContainer"; + std::string _cluster_map_name = "TRKR_CLUSTER"; std::string m_fieldMap = "1.4"; std::vector getTrackletClusterList(TrackSeed* tracklet); }; diff --git a/offline/packages/trackreco/PHSimpleVertexFinder.cc b/offline/packages/trackreco/PHSimpleVertexFinder.cc index 3d3e4a9fda..5f9340d8f6 100644 --- a/offline/packages/trackreco/PHSimpleVertexFinder.cc +++ b/offline/packages/trackreco/PHSimpleVertexFinder.cc @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -263,7 +263,7 @@ int PHSimpleVertexFinder::process_event(PHCompositeNode * /*topNode*/) { unsigned int thisid = it + vertex_id; // the address of the vertex in the event - auto svtxVertex = std::make_unique(); + auto svtxVertex = std::make_unique(); svtxVertex->set_chisq(0.0); svtxVertex->set_ndof(0); diff --git a/offline/packages/trackreco/PHSimpleVertexFinder.h b/offline/packages/trackreco/PHSimpleVertexFinder.h index da0e36fabf..de5cff940b 100644 --- a/offline/packages/trackreco/PHSimpleVertexFinder.h +++ b/offline/packages/trackreco/PHSimpleVertexFinder.h @@ -54,7 +54,7 @@ class PHSimpleVertexFinder : public SubsysReco void setTrackMapName(const std::string &name) { _track_map_name = name; } void setVertexMapName(const std::string &name) { _vertex_map_name = name; } void zeroField(const bool flag) { _zero_field = flag; } - void setTrkrClusterContainerName(std::string &name){ m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string &name){ m_clusterContainerName = name; } void set_pp_mode(bool mode) { _pp_mode = mode; } private: @@ -91,7 +91,7 @@ class PHSimpleVertexFinder : public SubsysReco double _beamline_y_cut_hi = 0.2; double _qual_cut = 10.0; bool _require_mvtx = true; - unsigned int _nmvtx_required = 3; + unsigned int _nmvtx_required = 2; double _track_pt_cut = 0.0; double _outlier_cut = 0.015; diff --git a/offline/packages/trackreco/PHTpcDeltaZCorrection.h b/offline/packages/trackreco/PHTpcDeltaZCorrection.h index 46d099f587..4d383cc854 100644 --- a/offline/packages/trackreco/PHTpcDeltaZCorrection.h +++ b/offline/packages/trackreco/PHTpcDeltaZCorrection.h @@ -32,7 +32,7 @@ class PHTpcDeltaZCorrection : public SubsysReco, public PHParameterInterface int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; void SetDefaultParameters() override; - void setTrkrClusterContainerName(std::string &name) { m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string &name) { m_clusterContainerName = name; } private: /// load nodes diff --git a/offline/packages/trackreco/WeightedFitter.cc b/offline/packages/trackreco/WeightedFitter.cc index af7677f5b8..e35919c479 100644 --- a/offline/packages/trackreco/WeightedFitter.cc +++ b/offline/packages/trackreco/WeightedFitter.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc b/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc index 45458b9b49..97f801771c 100644 --- a/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc +++ b/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc @@ -2,7 +2,7 @@ #include "MbdVertexFastSimReco.h" #include -#include +#include #include #include @@ -95,7 +95,7 @@ int MbdVertexFastSimReco::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } - MbdVertex *vertex = new MbdVertexv2(); + MbdVertex *vertex = new MbdVertexv3(); if (m_T_Smear >= 0.0) { diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc index 4db6ecbd51..614712d4d3 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc @@ -305,28 +305,58 @@ PHG4Particle* PHG4TruthTrackingAction::AddParticle(PHG4TruthInfoContainer& truth return truth.AddParticle(trackid, ti)->second; } +/** + * @brief Create or retrieve a truth vertex for a Geant4 track keyed by position and production process. + * + * Uses the track vertex position combined with the mapped MC production process to look up an existing + * vertex or create a new PHG4VtxPoint and register it in the truth container. The vertex index is chosen + * positive for primary tracks and negative for secondaries. + * + * @param truth Container in which to find or register the vertex. + * @param track Geant4 track whose production vertex and creator process determine the vertex key. + * @return PHG4VtxPoint* Pointer to the vertex instance stored in the truth container. + */ PHG4VtxPoint* PHG4TruthTrackingAction::AddVertex(PHG4TruthInfoContainer& truth, const G4Track& track) { G4ThreeVector v = track.GetVertexPosition(); + + // Get G4Track creator process FIRST (needed for vertex map key) + const auto* const g4Process = track.GetCreatorProcess(); + // Convert G4 Process to MC process + const auto process = PHG4ProcessMapPhysics::Instance().GetMCProcess(g4Process); + int vtxindex = (track.GetParentID() == 0 ? truth.maxvtxindex() + 1 : truth.minvtxindex() - 1); - auto [iter, inserted] = m_VertexMap.insert(std::make_pair(v, vtxindex)); + // Use (position, process) as key to distinguish vertices at same location but different processes + // This is important for cases like K0 -> K0_S/K0_L mixing where particles are produced + // at the same position but by different physics processes + auto key = std::make_pair(v, process); + auto [iter, inserted] = m_VertexMap.insert(std::make_pair(key, vtxindex)); // If could not add a unique vertex => return the existing one if (!inserted) { return truth.GetVtxMap().find(iter->second)->second; } - // get G4Track creator process - const auto* const g4Process = track.GetCreatorProcess(); - // convert G4 Process to MC process - const auto process = PHG4ProcessMapPhysics::Instance().GetMCProcess(g4Process); - // otherwise, create and add a new one + + // Create and add a new vertex PHG4VtxPoint* vtxpt = new PHG4VtxPointv2(v[0] / cm, v[1] / cm, v[2] / cm, track.GetGlobalTime() / ns, vtxindex, process); return truth.AddVertex(vtxindex, vtxpt)->second; } +/** + * @brief Determine whether a PHG4Particle should be considered an sPHENIX primary. + * + * Evaluates the particle's production vertex, PDG id longevity, and ancestry to decide + * if it originates as an sPHENIX primary (produced as a primary or from a decay and + * having no long-lived ancestor produced by material interactions). + * + * @param truth Truth container used to look up particle parents and production vertices. + * @param particle Particle to evaluate. + * @return true if the particle is classified as an sPHENIX primary, `false` otherwise. + * + */ bool PHG4TruthTrackingAction::issPHENIXPrimary(PHG4TruthInfoContainer& truth, PHG4Particle* particle) const { PHG4VtxPoint* vtx = truth.GetVtx(particle->get_vtx_id()); @@ -346,13 +376,15 @@ bool PHG4TruthTrackingAction::issPHENIXPrimary(PHG4TruthInfoContainer& truth, PH // check the production process // if not decay or primary, then it is not a primary // debug print for pid, track id, parent id, and process - /* - std::cout << "PHG4TruthTrackingAction::issPHENIXPrimary - checking particle with track id " << particle->get_track_id() - << ", pid: " << pdgid - << ", parent id: " << particle->get_parent_id() - << ", process: " << process - << std::endl; - */ + // if (pdgid == 311 || pdgid == 130 || pdgid == 310) + //{ + // std::cout << "PHG4TruthTrackingAction::issPHENIXPrimary - checking particle with track id " << particle->get_track_id() + // << ", pid: " << pdgid + // << ", parent id: " << particle->get_parent_id() + // << ", process: " << process + // << std::endl; + //} + if (!(process == PHG4MCProcess::kPPrimary || process == PHG4MCProcess::kPDecay) && particle->get_parent_id()) // all primary particles seems to have unkown process id { return false; diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h index 5ad050c898..99e0c4669e 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h @@ -4,10 +4,12 @@ #define G4MAIN_PHG4TRUTHTRACKINGACTION_H #include "PHG4TrackingAction.h" +#include "PHG4MCProcessDefs.h" #include #include +#include #include class G4Track; @@ -17,6 +19,68 @@ class PHG4TruthEventAction; class PHG4Particle; class PHG4VtxPoint; +/** + * Construct a PHG4TruthTrackingAction associated with an event action. + * @param eventAction Pointer to the owning PHG4TruthEventAction used to record per-event truth information. + */ + +/** + * Destroy the PHG4TruthTrackingAction. + */ + +/** + * Handle actions to perform before Geant4 begins tracking a G4 track. + * @param track The Geant4 track about to be processed. + */ + +/** + * Handle actions to perform after Geant4 finishes tracking a G4 track. + * @param track The Geant4 track that has just been processed. + */ + +/** + * Set required node/interface pointers from the given top-level node. + * @param topNode Pointer to the PHCompositeNode root from which required I/O nodes are retrieved. + * @returns Zero on success, non-zero on failure. + */ + +/** + * Reset per-event state using nodes found under the given composite node. + * @param topNode Pointer to the PHCompositeNode for the current event. + * @returns Zero on success, non-zero on failure. + */ + +/** + * Create or update a truth particle entry corresponding to the provided Geant4 track. + * @param truth Container to which the particle entry will be added or updated. + * @param track Geant4 track from which particle information is derived. + * @returns Pointer to the created or updated PHG4Particle. + */ + +/** + * Create or update a truth vertex entry corresponding to the provided Geant4 track. + * @param truth Container to which the vertex entry will be added or updated. + * @param track Geant4 track whose production point will be recorded as a vertex. + * @returns Pointer to the created or updated PHG4VtxPoint. + */ + +/** + * Determine whether a particle type is considered long-lived for truth-building. + * @param pid Particle PDG identifier. + * @returns `true` if the particle with the given PDG id is treated as long-lived, `false` otherwise. + */ + +/** + * Determine whether a particle should be flagged as an sPHENIX primary. + * @param truth Truth information container used to evaluate primary status. + * @param particle Particle to evaluate. + * @returns `true` if the particle is considered an sPHENIX primary, `false` otherwise. + */ + +/** + * Update the internal upstream G4 particle stack when processing a new Geant4 track. + * @param track Geant4 track used to update parent/ancestor particle bookkeeping. + */ class PHG4TruthTrackingAction : public PHG4TrackingAction { public: @@ -37,7 +101,8 @@ class PHG4TruthTrackingAction : public PHG4TrackingAction int ResetEvent(PHCompositeNode*) override; private: - std::map m_VertexMap; + // Key is (position, process) to distinguish vertices at the same location but different processes + std::map, int> m_VertexMap; //! pointer to the "owning" event action PHG4TruthEventAction* m_EventAction;