Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F19251207
JetSplitter.cc
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
JetSplitter.cc
View Options
/**
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2019
* \copyright GPLv2 or later
*/
#include
"HEJ/JetSplitter.hh"
#include
<array>
#include
<assert.h>
#include
<numeric>
#include
"fastjet/ClusterSequence.hh"
#include
"fastjet/PseudoJet.hh"
#include
"HEJ/Constants.hh"
#include
"HEJ/exceptions.hh"
namespace
HEJ
{
namespace
{
constexpr
double
ccut
=
HEJ
::
CMINPT
;
// min parton pt
template
<
class
Iterator
>
bool
same_pt_and_rapidity
(
Iterator
begin
,
Iterator
end
,
fastjet
::
PseudoJet
const
&
jet
){
constexpr
double
ep
=
1e-2
;
const
fastjet
::
PseudoJet
reconstructed_jet
=
std
::
accumulate
(
begin
,
end
,
fastjet
::
PseudoJet
{}
);
return
(
std
::
abs
(
reconstructed_jet
.
pt
()
-
jet
.
pt
())
<
ep
)
&&
(
std
::
abs
(
reconstructed_jet
.
rapidity
()
-
jet
.
rapidity
())
<
ep
)
;
}
bool
all_in_one_jet
(
std
::
vector
<
fastjet
::
PseudoJet
>
const
&
partons
,
fastjet
::
JetDefinition
jet_def
,
double
min_jet_pt
){
fastjet
::
ClusterSequence
ev
(
partons
,
jet_def
);
const
std
::
vector
<
fastjet
::
PseudoJet
>
testjet
=
ev
.
inclusive_jets
(
min_jet_pt
);
return
testjet
.
size
()
==
1u
&&
testjet
[
0
].
constituents
().
size
()
==
partons
.
size
();
}
}
using
SplitResult
=
JetSplitter
::
SplitResult
;
SplitResult
JetSplitter
::
split
(
fastjet
::
PseudoJet
const
&
j2split
,
int
ncons
)
const
{
if
(
ncons
<=
0
)
{
throw
std
::
invalid_argument
{
"number of requested jet constituents less than 1"
};
}
double
swt
=
1.
;
std
::
vector
<
fastjet
::
PseudoJet
>
jcons
;
if
(
ncons
==
1
){
jcons
.
emplace_back
(
j2split
);
jcons
.
back
().
set_user_index
(
0
);
return
{
jcons
,
swt
};
}
if
(
ncons
==
2
){
return
Split2
(
j2split
);
}
const
double
R_max
=
R_factor
*
R_
;
assert
(
R_max
<
M_PI
);
double
pt_remaining
=
j2split
.
pt
();
const
double
phi_jet
=
j2split
.
phi
();
const
double
y_jet
=
j2split
.
rapidity
();
for
(
int
i
=
0
;
i
<
ncons
-
1
;
++
i
){
/**
* Generate rapidity and azimuthal angle with a distance
* R = sqrt(delta_y^2 + delta_phi^2) < R_max
* from the jet centre
*/
const
double
R
=
R_max
*
ran_
.
get
().
flat
();
const
double
theta
=
2
*
M_PI
*
ran_
.
get
().
flat
();
const
double
delta_phi
=
R
*
cos
(
theta
);
const
double
delta_y
=
R
*
sin
(
theta
);
/**
* Generate pt such that the total contribution of all partons
* along the jet pt axis does not exceed the jet pt
*/
const
double
pt_max
=
pt_remaining
/
cos
(
delta_phi
);
assert
(
pt_max
>
0
);
if
(
pt_max
<
ccut
)
return
{};
// no pt remaining for this parton
const
double
pt
=
(
pt_max
-
ccut
)
*
ran_
.
get
().
flat
()
+
ccut
;
pt_remaining
-=
pt
*
cos
(
delta_phi
);
jcons
.
emplace_back
(
pt
*
cos
(
phi_jet
+
delta_phi
),
pt
*
sin
(
phi_jet
+
delta_phi
),
pt
*
sinh
(
y_jet
+
delta_y
),
pt
*
cosh
(
y_jet
+
delta_y
)
);
jcons
.
back
().
set_user_index
(
i
);
swt
*=
2
*
M_PI
*
R
*
R_max
*
pt
*
(
pt_max
-
ccut
);
}
const
fastjet
::
PseudoJet
p_total
=
std
::
accumulate
(
jcons
.
begin
(),
jcons
.
end
(),
fastjet
::
PseudoJet
{}
);
// Calculate the pt of the last parton
const
double
last_px
=
j2split
.
px
()
-
p_total
.
px
();
const
double
last_py
=
j2split
.
py
()
-
p_total
.
py
();
const
double
last_pt
=
sqrt
(
last_px
*
last_px
+
last_py
*
last_py
);
if
(
last_pt
<
ccut
)
return
{};
// Calculate the rapidity of the last parton using the requirement that the
// new jet must have the same rapidity as the LO jet.
const
double
exp_2y_jet
=
(
j2split
.
e
()
+
j2split
.
pz
())
/
(
j2split
.
e
()
-
j2split
.
pz
());
const
double
bb
=
(
p_total
.
e
()
+
p_total
.
pz
())
-
exp_2y_jet
*
(
p_total
.
e
()
-
p_total
.
pz
());
const
double
lasty
=
log
((
-
bb
+
sqrt
(
bb
*
bb
+
4.
*
exp_2y_jet
*
last_pt
*
last_pt
))
/
(
2.
*
last_pt
));
jcons
.
emplace_back
(
last_px
,
last_py
,
last_pt
*
sinh
(
lasty
),
last_pt
*
cosh
(
lasty
)
);
jcons
.
back
().
set_user_index
(
ncons
-
1
);
assert
(
same_pt_and_rapidity
(
begin
(
jcons
),
end
(
jcons
),
j2split
));
// Test that the last parton is not too far away from the jet centre.
if
(
jcons
.
back
().
delta_R
(
j2split
)
>
R_max
)
return
{};
if
(
!
all_in_one_jet
(
jcons
,
jet_def_
,
min_jet_pt_
))
return
{};
return
{
jcons
,
swt
};
}
double
JetSplitter
::
sample_distance_2p
(
double
&
wt
)
const
{
static
constexpr
double
x_small
=
0.1
;
static
constexpr
double
p_small
=
0.4
;
const
double
pR
=
ran_
.
get
().
flat
();
if
(
pR
<
p_small
){
wt
*=
x_small
/
p_small
;
return
x_small
/
p_small
*
pR
;
}
wt
*=
(
1
-
x_small
)
/
(
1
-
p_small
);
return
(
1
-
x_small
)
/
(
1
-
p_small
)
*
(
pR
-
p_small
)
+
x_small
;
}
SplitResult
JetSplitter
::
Split2
(
fastjet
::
PseudoJet
const
&
j2split
)
const
{
static
constexpr
size_t
ncons
=
2
;
std
::
vector
<
fastjet
::
PseudoJet
>
jcons
(
ncons
);
std
::
array
<
double
,
ncons
>
R
,
phi
,
y
,
pt
;
double
wt
=
1
;
const
double
theta
=
2
*
M_PI
*
ran_
.
get
().
flat
();
// angle in y-phi plane
// empiric observation: we are always within the jet radius
R
[
0
]
=
sample_distance_2p
(
wt
)
*
R_
;
R
[
1
]
=
-
sample_distance_2p
(
wt
)
*
R_
;
for
(
size_t
i
=
0
;
i
<=
1
;
++
i
){
phi
[
i
]
=
j2split
.
phi
()
+
R
[
i
]
*
cos
(
theta
);
y
[
i
]
=
j2split
.
rapidity
()
+
R
[
i
]
*
sin
(
theta
);
}
for
(
size_t
i
=
0
;
i
<=
1
;
++
i
){
pt
[
i
]
=
(
j2split
.
py
()
-
tan
(
phi
[
1
-
i
])
*
j2split
.
px
())
/
(
sin
(
phi
[
i
])
-
tan
(
phi
[
1
-
i
])
*
cos
(
phi
[
i
]));
if
(
pt
[
i
]
<
ccut
)
return
{};
jcons
[
i
].
reset_PtYPhiM
(
pt
[
i
],
y
[
i
],
phi
[
i
]);
jcons
[
i
].
set_user_index
(
i
);
}
assert
(
same_pt_and_rapidity
(
begin
(
jcons
),
end
(
jcons
),
j2split
));
if
(
!
all_in_one_jet
(
jcons
,
jet_def_
,
min_jet_pt_
))
return
{};
wt
*=
2
*
M_PI
*
pt
[
0
]
*
R
[
0
]
*
R_
*
R_
;
// from transformation of delta(R[1] - ...) to delta(pt[0] - ...)
const
double
dphi0
=
phi
[
0
]
-
j2split
.
phi
();
const
double
ptJ
=
j2split
.
pt
();
const
double
jacobian
=
cos
(
theta
)
*
pt
[
1
]
*
pt
[
1
]
/
(
ptJ
*
sin
(
dphi0
));
return
{
jcons
,
jacobian
*
wt
};
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Sep 30, 5:48 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6476752
Default Alt Text
JetSplitter.cc (5 KB)
Attached To
Mode
rHEJ HEJ
Attached
Detach File
Event Timeline
Log In to Comment