Skip to content

Commit 6e0a214

Browse files
committed
Add support for fastjet library
1 parent 5a420db commit 6e0a214

File tree

10 files changed

+335
-0
lines changed

10 files changed

+335
-0
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ option(ACTS_BUILD_PLUGIN_DD4HEP "Build DD4hep plugin" OFF)
4747
option(ACTS_BUILD_PLUGIN_PODIO "Build Podio plugin" OFF)
4848
option(ACTS_BUILD_PLUGIN_EDM4HEP "Build EDM4hep plugin" OFF)
4949
option(ACTS_BUILD_PLUGIN_FPEMON "Build FPE monitoring plugin" OFF)
50+
option(ACTS_BUILD_PLUGIN_FASTJET "Build FastJet plugin" OFF)
5051
option(ACTS_BUILD_PLUGIN_GEOMODEL "Build GeoModel plugin" OFF)
5152
option(ACTS_BUILD_PLUGIN_TRACCC "Build Traccc plugin" OFF)
5253
option(ACTS_BUILD_PLUGIN_GEANT4 "Build Geant4 plugin" OFF)
@@ -369,6 +370,9 @@ if(ACTS_BUILD_PLUGIN_JSON)
369370
add_subdirectory(thirdparty/nlohmann_json)
370371
endif()
371372
endif()
373+
if(ACTS_BUILD_PLUGIN_FASTJET)
374+
find_package(FastJet REQUIRED)
375+
endif()
372376
if(ACTS_BUILD_PLUGIN_GEOMODEL)
373377
find_package(GeoModelCore ${_acts_geomodel_version} REQUIRED CONFIG)
374378
find_package(GeoModelIO ${_acts_geomodel_version} REQUIRED CONFIG)

Plugins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# independent plugins
44
add_component_if(ActSVG PluginActSVG ACTS_BUILD_PLUGIN_ACTSVG)
55
add_component_if(Cuda PluginCuda ACTS_BUILD_PLUGIN_CUDA)
6+
add_component_if(FastJet PluginFastJet ACTS_BUILD_PLUGIN_FASTJET)
67
add_component_if(FpeMonitoring PluginFpeMonitoring ACTS_BUILD_PLUGIN_FPEMON)
78
add_component_if(Geant4 PluginGeant4 ACTS_BUILD_PLUGIN_GEANT4)
89
add_component_if(GeoModel PluginGeoModel ACTS_BUILD_PLUGIN_GEOMODEL)

Plugins/FastJet/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
add_library(ActsPluginFastJet INTERFACE)
2+
3+
target_include_directories(
4+
ActsPluginFastJet
5+
INTERFACE
6+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
7+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
8+
)
9+
target_link_libraries(ActsPluginFastJet INTERFACE FastJet)
10+
11+
install(
12+
TARGETS ActsPluginFastJet
13+
EXPORT ActsPluginFastJetTargets
14+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
15+
)
16+
install(DIRECTORY include/Acts DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// This file is part of the Acts project.
2+
//
3+
// Copyright (C) 2024 CERN for the benefit of the Acts project
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
#pragma once
10+
11+
#include <Acts/Definitions/Units.hpp>
12+
13+
#include <optional>
14+
#include <vector>
15+
16+
#include <fastjet/JetDefinition.hh>
17+
#include <fastjet/PseudoJet.hh>
18+
19+
namespace Acts::FastJet {
20+
21+
template <typename TrackContainer>
22+
class TrackJetSequence {
23+
public:
24+
/// Get all the track jets passing the pT & eta cuts
25+
///
26+
/// @param ptMin the minimum jet pT in GeV
27+
/// @param etaMax the maximum jet absolute eta
28+
///
29+
/// @return a vector of fastjet::PseudoJet objects
30+
std::vector<fastjet::PseudoJet> jets(float ptMin = 20 *
31+
Acts::UnitConstants::GeV,
32+
float etaMax = 2.5);
33+
34+
/// Get the tracks making up a track-jet
35+
///
36+
/// @param jet the jet from which to get the constituent tracks
37+
/// @param coreR optional radius inside which to get the tracks
38+
///
39+
/// @return a vector of TrackProxy
40+
std::vector<typename TrackContainer::TrackProxy> tracksInJet(
41+
const fastjet::PseudoJet& jet, std::optional<float> coreR = {});
42+
43+
/// Main constructor, but using the "makeTrackJets" function is recommended
44+
///
45+
/// @param clusterSeq the fastjet::ClusterSequence object
46+
/// @param inputTracks the input tracks that make up the sequence
47+
TrackJetSequence(fastjet::ClusterSequence clusterSeq,
48+
TrackContainer& inputTracks)
49+
: m_clusterSeq{std::move(clusterSeq)}, m_inputTracks{inputTracks} {}
50+
51+
private:
52+
fastjet::ClusterSequence m_clusterSeq;
53+
TrackContainer& m_inputTracks;
54+
};
55+
56+
/// Default jet definition: Anti-kt with a radius of 0.4
57+
const fastjet::JetDefinition DefaultJetDefinition =
58+
fastjet::JetDefinition(fastjet::antikt_algorithm, 0.4);
59+
60+
/// Create a sequence of track jets
61+
///
62+
/// @param tracks the input tracks
63+
/// @jetDef the jet definition to use, defaults to "DefaultJetDefinition"
64+
template <typename TrackContainer>
65+
TrackJetSequence<TrackContainer> makeTrackJets(
66+
TrackContainer& tracks,
67+
fastjet::JetDefinition jetDef = DefaultJetDefinition);
68+
69+
} // namespace Acts::FastJet
70+
71+
#include "TrackJets.ipp"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// This file is part of the Acts project.
2+
//
3+
// Copyright (C) 2024 CERN for the benefit of the Acts project
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
#include <Acts/Definitions/Algebra.hpp>
10+
#include <Acts/Definitions/Common.hpp>
11+
12+
template <typename TrackContainer>
13+
Acts::FastJet::TrackJetSequence<TrackContainer> Acts::FastJet::makeTrackJets(
14+
TrackContainer& tracks, fastjet::JetDefinition jetDef) {
15+
std::vector<fastjet::PseudoJet> inputs;
16+
17+
for (std::size_t i = 0; i < tracks.size(); i++) {
18+
typename TrackContainer::ConstTrackProxy track = tracks.getTrack(i);
19+
Acts::Vector3 p = track.momentum();
20+
float m = track.particleHypothesis().mass();
21+
22+
float px = p[Acts::eMom0];
23+
float py = p[Acts::eMom1];
24+
float pz = p[Acts::eMom2];
25+
float e = std::sqrt(m * m + px * px + py * py + pz * pz);
26+
27+
inputs.emplace_back(px, py, pz, e);
28+
inputs.back().set_user_index(i);
29+
}
30+
31+
fastjet::ClusterSequence cs(inputs, jetDef);
32+
33+
return TrackJetSequence(std::move(cs), tracks);
34+
}
35+
36+
template <typename TrackContainer>
37+
std::vector<fastjet::PseudoJet>
38+
Acts::FastJet::TrackJetSequence<TrackContainer>::jets(float ptMin,
39+
float etaMax) {
40+
fastjet::Selector sel_eta = fastjet::SelectorAbsEtaMax(etaMax);
41+
return sel_eta(m_clusterSeq.inclusive_jets(ptMin));
42+
}
43+
44+
template <typename TrackContainer>
45+
std::vector<typename TrackContainer::TrackProxy>
46+
Acts::FastJet::TrackJetSequence<TrackContainer>::tracksInJet(
47+
const fastjet::PseudoJet& jet, std::optional<float> coreR) {
48+
fastjet::Selector sel = fastjet::SelectorIdentity();
49+
if (coreR.has_value()) {
50+
sel = fastjet::SelectorCircle(coreR.value());
51+
sel.set_reference(jet);
52+
}
53+
54+
std::vector<typename TrackContainer::TrackProxy> tracks;
55+
for (fastjet::PseudoJet& cst : sel(jet.constituents())) {
56+
tracks.push_back(m_inputTracks.getTrack(cst.user_index()));
57+
}
58+
59+
return tracks;
60+
}

Tests/UnitTests/Plugins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_subdirectory_if(Cuda ACTS_BUILD_PLUGIN_CUDA)
33
add_subdirectory_if(Detray ACTS_BUILD_PLUGIN_TRACCC)
44
add_subdirectory_if(DD4hep ACTS_BUILD_PLUGIN_DD4HEP)
55
add_subdirectory_if(ExaTrkX ACTS_BUILD_PLUGIN_EXATRKX)
6+
add_subdirectory_if(FastJet ACTS_BUILD_PLUGIN_FASTJET)
67
add_subdirectory_if(Geant4 ACTS_BUILD_PLUGIN_GEANT4)
78
add_subdirectory_if(GeoModel ACTS_BUILD_PLUGIN_GEOMODEL)
89
add_subdirectory_if(Json ACTS_BUILD_PLUGIN_JSON)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
set(unittest_extra_libraries ActsPluginFastJet)
2+
add_unittest(TrackJetsTests TrackJetsTests.cpp)
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// This file is part of the Acts project.
2+
//
3+
// Copyright (C) 2024 CERN for the benefit of the Acts project
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
#include <boost/test/unit_test.hpp>
10+
11+
#include <Acts/Plugins/FastJet/TrackJets.hpp>
12+
13+
class ParticleHypothesis {
14+
public:
15+
float mass() { return 139.57061 * Acts::UnitConstants::MeV; }
16+
};
17+
18+
class Track {
19+
public:
20+
Track(float pt, float eta, float phi) {
21+
m_momentum[0] = pt * std::cos(phi);
22+
m_momentum[1] = pt * std::sin(phi);
23+
m_momentum[1] = pt * std::sinh(eta);
24+
}
25+
Acts::Vector3 momentum() const { return m_momentum; }
26+
ParticleHypothesis particleHypothesis() const { return ParticleHypothesis(); }
27+
28+
private:
29+
Acts::Vector3 m_momentum;
30+
};
31+
32+
bool operator==(Track const& lhs, Track const& rhs) {
33+
return lhs.momentum() == rhs.momentum();
34+
}
35+
36+
class TrackContainer {
37+
public:
38+
using TrackProxy = Track;
39+
40+
TrackContainer() {}
41+
void insert(Track track) { m_vec.push_back(std::move(track)); }
42+
std::size_t size() { return m_vec.size(); }
43+
44+
using ConstTrackProxy = const Track&;
45+
ConstTrackProxy getTrack(std::size_t i) {
46+
if (i < size()) {
47+
return m_vec[i];
48+
}
49+
throw std::runtime_error("Too few tracks");
50+
}
51+
52+
private:
53+
std::vector<Track> m_vec;
54+
};
55+
56+
BOOST_AUTO_TEST_CASE(SingleTrack) {
57+
TrackContainer tracks;
58+
tracks.insert(Track(100, 0, 0));
59+
60+
Acts::FastJet::TrackJetSequence jetSeq = Acts::FastJet::makeTrackJets(tracks);
61+
std::vector<fastjet::PseudoJet> jets = jetSeq.jets();
62+
63+
BOOST_CHECK_EQUAL(jets.size(), 1);
64+
BOOST_CHECK_EQUAL(jets[0].constituents().size(), 1);
65+
BOOST_CHECK_EQUAL(jets[0].constituents()[0].user_index(), 0);
66+
BOOST_CHECK_CLOSE(jets[0].pt(), 100, 1e-3);
67+
BOOST_CHECK_CLOSE(jets[0].eta(), 0, 1e-3);
68+
BOOST_CHECK_CLOSE(jets[0].phi(), 0, 1e-3);
69+
BOOST_CHECK_CLOSE(jets[0].m(), ParticleHypothesis().mass(), 1);
70+
}
71+
72+
BOOST_AUTO_TEST_CASE(TwoTracksTwoJets) {
73+
TrackContainer tracks;
74+
tracks.insert(Track(100, 0, 0.0));
75+
tracks.insert(Track(100, 0, M_PI));
76+
77+
Acts::FastJet::TrackJetSequence jetSeq = Acts::FastJet::makeTrackJets(tracks);
78+
std::vector<fastjet::PseudoJet> jets = jetSeq.jets();
79+
80+
BOOST_CHECK_EQUAL(jets.size(), 2);
81+
82+
std::vector<Track> trks_0 = jetSeq.tracksInJet(jets[0]);
83+
BOOST_CHECK_EQUAL(trks_0.size(), 1);
84+
BOOST_CHECK(trks_0[0] == tracks.getTrack(0) ||
85+
trks_0[0] == tracks.getTrack(1));
86+
87+
std::vector<Track> trks_1 = jetSeq.tracksInJet(jets[1]);
88+
BOOST_CHECK_EQUAL(trks_1.size(), 1);
89+
BOOST_CHECK(trks_1[0] == tracks.getTrack(0) ||
90+
trks_1[0] == tracks.getTrack(1));
91+
BOOST_CHECK(trks_0[0] != trks_1[0]);
92+
}
93+
94+
BOOST_AUTO_TEST_CASE(TwoTracksOneJet) {
95+
TrackContainer tracks;
96+
tracks.insert(Track(100, 0, 0.0));
97+
tracks.insert(Track(100, 0, 0.2));
98+
99+
Acts::FastJet::TrackJetSequence jetSeq = Acts::FastJet::makeTrackJets(tracks);
100+
std::vector<fastjet::PseudoJet> jets = jetSeq.jets();
101+
102+
BOOST_CHECK_EQUAL(jets.size(), 1);
103+
104+
std::vector<Track> trks_0 = jetSeq.tracksInJet(jets[0]);
105+
BOOST_CHECK_EQUAL(trks_0.size(), 2);
106+
BOOST_CHECK(trks_0[0] == tracks.getTrack(0) ||
107+
trks_0[0] == tracks.getTrack(1));
108+
BOOST_CHECK(trks_0[1] == tracks.getTrack(0) ||
109+
trks_0[1] == tracks.getTrack(1));
110+
BOOST_CHECK(trks_0[0] != trks_0[1]);
111+
}
112+
113+
BOOST_AUTO_TEST_CASE(TracksInJetCore) {
114+
TrackContainer tracks;
115+
tracks.insert(Track(100, 0, 0));
116+
tracks.insert(Track(10, 0.05, 0));
117+
tracks.insert(Track(10, -0.05, 0));
118+
tracks.insert(Track(10, 0.2, 0));
119+
tracks.insert(Track(10, -0.2, 0));
120+
121+
Acts::FastJet::TrackJetSequence jetSeq = Acts::FastJet::makeTrackJets(tracks);
122+
std::vector<fastjet::PseudoJet> jets = jetSeq.jets();
123+
124+
BOOST_REQUIRE_EQUAL(jets.size(), 1);
125+
126+
std::vector<Track> trks = jetSeq.tracksInJet(jets[0], 0.1);
127+
BOOST_CHECK_EQUAL(trks.size(), 3);
128+
129+
BOOST_CHECK(std::find(trks.begin(), trks.end(), tracks.getTrack(0)) !=
130+
trks.end());
131+
BOOST_CHECK(std::find(trks.begin(), trks.end(), tracks.getTrack(1)) !=
132+
trks.end());
133+
BOOST_CHECK(std::find(trks.begin(), trks.end(), tracks.getTrack(2)) !=
134+
trks.end());
135+
BOOST_CHECK(std::find(trks.begin(), trks.end(), tracks.getTrack(3)) ==
136+
trks.end());
137+
BOOST_CHECK(std::find(trks.begin(), trks.end(), tracks.getTrack(4)) ==
138+
trks.end());
139+
}

cmake/FindFastJet.cmake

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Find the FastJet includes and libraries.
2+
3+
find_library(FastJet_LIBRARY NAMES FastJet fastjet DOC "The FastJet library")
4+
5+
find_path(
6+
FastJet_INCLUDE_DIR
7+
fastjet/version.hh
8+
DOC "The FastJet include directory"
9+
)
10+
11+
file(READ "${FastJet_INCLUDE_DIR}/fastjet/config_auto.h" FastJet_VERSION_FILE)
12+
string(
13+
REGEX MATCH
14+
"#define FASTJET_PACKAGE_VERSION \"([0-9]+\.[0-9]+\.[0-9]+)\""
15+
_
16+
${FastJet_VERSION_FILE}
17+
)
18+
19+
set(FastJet_VERSION ${CMAKE_MATCH_1})
20+
21+
find_package_handle_standard_args(
22+
FastJet
23+
REQUIRED_VARS FastJet_LIBRARY FastJet_INCLUDE_DIR
24+
VERSION_VAR FastJet_VERSION
25+
)
26+
27+
add_library(FastJet SHARED IMPORTED)
28+
set_property(TARGET FastJet PROPERTY IMPORTED_LOCATION ${FastJet_LIBRARY})
29+
set_property(
30+
TARGET FastJet
31+
PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FastJet_INCLUDE_DIR}
32+
)
33+
34+
mark_as_advanced(FastJet_FOUND FastJet_INCLUDE_DIR FastJet_LIBRARY)
35+
36+
if(FastJet_FOUND)
37+
message(STATUS "Found FastJet ${FastJet_VERSION} at ${FastJet_LIBRARY}")
38+
else()
39+
message(FATAL_ERROR "FastJet not found")
40+
endif()

docs/getting_started.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ components.
279279
| ACTS_BUILD_PLUGIN_PODIO | Build Podio plugin<br> type: `bool`, default: `OFF` |
280280
| ACTS_BUILD_PLUGIN_EDM4HEP | Build EDM4hep plugin<br> type: `bool`, default: `OFF` |
281281
| ACTS_BUILD_PLUGIN_FPEMON | Build FPE monitoring plugin<br> type: `bool`, default: `OFF` |
282+
| ACTS_BUILD_PLUGIN_FASTJET | Build FastJet plugin<br> type: `bool`, default: `OFF` |
282283
| ACTS_BUILD_PLUGIN_GEOMODEL | Build GeoModel plugin<br> type: `bool`, default: `OFF` |
283284
| ACTS_BUILD_PLUGIN_TRACCC | Build Traccc plugin<br> type: `bool`, default: `OFF` |
284285
| ACTS_BUILD_PLUGIN_GEANT4 | Build Geant4 plugin<br> type: `bool`, default: `OFF` |

0 commit comments

Comments
 (0)