9#include <analysis/variables/ContinuumSuppressionVariables.h>
11#include <analysis/variables/ROEVariables.h>
12#include <analysis/VariableManager/Manager.h>
13#include <framework/dataobjects/EventExtraInfo.h>
14#include <analysis/dataobjects/Particle.h>
15#include <analysis/dataobjects/ContinuumSuppression.h>
16#include <analysis/utility/ReferenceFrame.h>
17#include <analysis/ClusterUtility/ClusterUtils.h>
18#include <analysis/ContinuumSuppression/FoxWolfram.h>
20#include <framework/logging/Logger.h>
21#include <framework/datastore/StoreArray.h>
22#include <framework/datastore/StoreObjPtr.h>
23#include <framework/utilities/Conversion.h>
25#include <mdst/dataobjects/PIDLikelihood.h>
26#include <mdst/dataobjects/Track.h>
27#include <mdst/dataobjects/ECLCluster.h>
41 if (arguments.size() != 1)
42 B2FATAL(
"An empty argument is not allowed for the variable R2."
43 "Either provide no argument or a valid mask name.");
44 std::string maskName = arguments[0];
45 auto func = [maskName](
const Particle * particle) ->
double {
46 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
55 double R2(
const Particle* particle)
57 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
58 if (continuumSuppressionRelations.size() == 1) {
59 const ContinuumSuppression* qq = continuumSuppressionRelations[0];
62 if (continuumSuppressionRelations.size() > 1) {
63 B2ERROR(
"The return value of R2 is ambiguous. Please provide the mask name as argument.");
71 if (arguments.size() != 1)
72 B2FATAL(
"An empty argument is not allowed for the variable thrustBm."
73 "Either provide no argument or a valid mask name.");
74 std::string maskName = arguments[0];
75 auto func = [maskName](
const Particle * particle) ->
double {
76 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
80 return qq->getThrustBm();
85 double thrustBm(
const Particle* particle)
87 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
88 if (continuumSuppressionRelations.size() == 1) {
89 const ContinuumSuppression* qq = continuumSuppressionRelations[0];
90 return qq->getThrustBm();
92 if (continuumSuppressionRelations.size() > 1) {
93 B2ERROR(
"The return value of thrustBm is ambiguous. Please provide the mask name as argument.");
101 if (arguments.size() != 1)
102 B2FATAL(
"An empty argument is not allowed for the variable thrustOm."
103 "Either provide no argument or a valid mask name.");
104 std::string maskName = arguments[0];
105 auto func = [maskName](
const Particle * particle) ->
double {
106 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
110 return qq->getThrustOm();
115 double thrustOm(
const Particle* particle)
117 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
118 if (continuumSuppressionRelations.size() == 1) {
119 const ContinuumSuppression* qq = continuumSuppressionRelations[0];
120 return qq->getThrustOm();
122 if (continuumSuppressionRelations.size() > 1) {
123 B2ERROR(
"The return value of thrustOm is ambiguous. Please provide the mask name as argument.");
131 if (arguments.size() != 1)
132 B2FATAL(
"An empty argument is not allowed for the variable cosTBTO."
133 "Either provide no argument or a valid mask name.");
134 std::string maskName = arguments[0];
135 auto func = [maskName](
const Particle * particle) ->
double {
136 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
140 return qq->getCosTBTO();
145 double cosTBTO(
const Particle* particle)
147 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
148 if (continuumSuppressionRelations.size() == 1) {
149 const ContinuumSuppression* qq = continuumSuppressionRelations[0];
150 return qq->getCosTBTO();
152 if (continuumSuppressionRelations.size() > 1) {
153 B2ERROR(
"The return value of cosTBTO is ambiguous. Please provide the mask name as argument.");
161 if (arguments.size() != 1)
162 B2FATAL(
"An empty argument is not allowed for the variable cosTBz."
163 "Either provide no argument or a valid mask name.");
164 std::string maskName = arguments[0];
165 auto func = [maskName](
const Particle * particle) ->
double {
166 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
170 return qq->getCosTBz();
175 double cosTBz(
const Particle* particle)
177 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
178 if (continuumSuppressionRelations.size() == 1) {
179 const ContinuumSuppression* qq = continuumSuppressionRelations[0];
180 return qq->getCosTBz();
182 if (continuumSuppressionRelations.size() > 1) {
183 B2ERROR(
"The return value of cosTBz is ambiguous. Please provide the mask name as argument.");
191 if (arguments.size() > 0 && arguments.size() < 4) {
193 auto variableName = arguments[0];
194 std::string maskName =
"";
195 if (arguments.size() >= 2) {
196 if (arguments[1] ==
"FS1") {
199 maskName = arguments[1];
201 if (arguments.size() == 3) {
202 maskName = arguments[2];
203 if (maskName ==
"FS1") {
204 B2ERROR(
"It looks like you provided the arguments for KSFWVariables in the wrong order."
205 "If you want to use the KSFW moments calculated from the B final state particles, the second argument has to be 'FS1'."
206 "The third argument would then have to be the ROE mask name.");
213 std::vector<std::string> names = {
"mm2",
"et",
214 "hso00",
"hso01",
"hso02",
"hso03",
"hso04",
215 "hso10",
"hso12",
"hso14",
216 "hso20",
"hso22",
"hso24",
217 "hoo0",
"hoo1",
"hoo2",
"hoo3",
"hoo4"
221 for (
unsigned i = 0; i < names.size(); ++i) {
222 if (variableName == names[i])
228 std::string allowed =
"";
231 B2FATAL(
"Variable name provided: " << variableName <<
" is not one of the allowed options. Please choose from one of:" << allowed);
234 auto func = [index, useFS1, maskName](
const Particle * particle) ->
double {
235 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
236 ContinuumSuppression* qq =
nullptr;
237 if (maskName.empty())
239 if (continuumSuppressionRelations.size() == 1) {
240 qq = continuumSuppressionRelations[0];
241 }
else if (continuumSuppressionRelations.size() > 1) {
242 B2ERROR(
"The return value of KSFWVariables is ambiguous. Please provide the mask name as argument.");
246 qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
251 std::vector<float> ksfw = qq->getKsfwFS0();
253 ksfw = qq->getKsfwFS1();
255 if (ksfw.size() == 0) B2FATAL(
"Could not find any KSFW moments");
256 return ksfw.at(index);
260 B2FATAL(
"Wrong number of arguments for meta function KSFWVariables. It only takes between one and three arguments."
261 " The first argument must be the variable. If you want to use the KSFW moments calculated from the B final state particles, set 'FS1' as second argument."
262 " You can also provide the ROE mask name as second or third argument.");
268 if (arguments.size() > 0 && arguments.size() < 4) {
272 coneNumber = Belle2::convertString<int>(arguments[0]);
273 }
catch (std::invalid_argument&) {
274 B2FATAL(
"The first argument of the CleoConeCS meta function must be an integer!");
278 std::string maskName =
"";
279 if (arguments.size() >= 2) {
280 if (arguments[1] ==
"ROE") {
283 maskName = arguments[1];
285 if (arguments.size() == 3) {
286 maskName = arguments[2];
287 if (maskName ==
"ROE") {
288 B2ERROR(
"It looks like you provided the arguments for CleoConeCS in the wrong order."
289 "If you want to use the CleoCones calculated from all final state particles, the second argument has to be 'ROE'."
290 "The third argument would then have to be the ROE mask name.");
295 auto func = [coneNumber, useROE, maskName](
const Particle * particle) ->
double {
296 RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
297 ContinuumSuppression* qq =
nullptr;
298 if (maskName.empty())
300 if (continuumSuppressionRelations.size() == 1) {
301 qq = continuumSuppressionRelations[0];
302 }
else if (continuumSuppressionRelations.size() > 1) {
303 B2ERROR(
"The return value of CleoConeCS is ambiguous. Please provide the mask name as argument.");
307 qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
312 std::vector<float> cleoCones = qq->getCleoConesALL();
314 cleoCones = qq->getCleoConesROE();
315 return cleoCones.at(coneNumber - 1);
319 B2FATAL(
"Wrong number of arguments for CleoConeCS function. It only takes between one and three arguments."
320 "The first argument must be the cone number. If you want to use the CleoCones calculated from all final state particles, set 'ROE' as second argument."
321 "You can also provide the ROE mask name as second or third argument.");
327 if (arguments.size() == 3) {
331 low = Belle2::convertString<double>(arguments[1]);
332 high = Belle2::convertString<double>(arguments[2]);
333 }
catch (std::invalid_argument&) {
334 B2FATAL(
"Second and third argument of transformedNetworkOutput meta function must be doubles!");
337 auto extraInfoName = arguments[0];
338 auto func = [extraInfoName, low, high](
const Particle * particle) ->
double {
339 if (particle ==
nullptr)
341 StoreObjPtr<EventExtraInfo> eventExtraInfo;
342 if (eventExtraInfo->hasExtraInfo(extraInfoName)) {
343 return eventExtraInfo->getExtraInfo(extraInfoName);
348 if (particle->hasExtraInfo(extraInfoName))
350 return std::log(((particle->getExtraInfo(extraInfoName)) - low) / (high - (particle->getExtraInfo(extraInfoName))));
358 B2FATAL(
"Wrong number of arguments for meta function transformedNetworkOutput");
364 if (arguments.size() == 2 || arguments.size() == 3) {
365 auto variableName = arguments[0];
366 std::string mode = arguments[1];
368 const bool modeisSignal = mode ==
"Signal";
369 const bool modeisAuto = mode ==
"Auto";
371 if (not modeisSignal and (mode !=
"ROE") and not modeisAuto)
372 B2FATAL(
"Second argument in useBThrustFrame can only be 'Signal', 'ROE' or 'Auto'. Your argument was " + mode);
376 std::string maskName = arguments.size() == 3 ? arguments[2] :
"";
378 auto func = [var, modeisSignal, modeisAuto, maskName](
const Particle * particle) ->
double {
379 StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
380 const Particle* Bparticle = roe->getRelatedFrom<Particle>();
381 RelationVector<ContinuumSuppression> continuumSuppressionRelations = Bparticle->getRelationsTo<ContinuumSuppression>(
"ALL");
382 ContinuumSuppression* qq =
nullptr;
383 if (maskName.empty())
385 if (continuumSuppressionRelations.size() == 1) {
386 qq = continuumSuppressionRelations[0];
387 }
else if (continuumSuppressionRelations.size() > 1) {
388 B2ERROR(
"The return value of useBThrustFrame is ambiguous. Please provide the mask name as argument.");
392 qq = Bparticle->getRelatedTo<ContinuumSuppression>(maskName);
397 bool isinROE = isInRestOfEvent(particle);
398 ROOT::Math::XYZVector newZ;
399 if (modeisSignal or (modeisAuto and isinROE))
400 newZ = qq->getThrustB();
402 newZ = qq->getThrustO();
404 ROOT::Math::XYZVector newY(0, 0, 0);
405 if (newZ.Z() == 0 and newZ.Y() == 0)
410 newY.SetZ(-newZ.Y());
412 ROOT::Math::XYZVector newX = newY.Cross(newZ);
414 UseReferenceFrame<CMSRotationFrame> signalframe(newX, newY, newZ);
416 return std::get<double>(var->function(particle));
420 B2FATAL(
"Wrong number of arguments for meta function useBThrustFrame. It only takes two or three arguments. The first argument must be the variable."
421 "The second can either be 'Signal', 'ROE', or 'Auto'."
422 "The third argument is optional (as long as the ContinuumSuppression was built only once) and can define a specific ROE mask name.");
427 VARIABLE_GROUP(
"Continuum Suppression");
428 REGISTER_METAVARIABLE(
"R2(maskname)", R2WithMask, R
"DOC(
429Returns reduced Fox-Wolfram R2, defined as ratio of the i-th to the 0-th order Fox Wolfram moments.
431.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
432.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
433)DOC", Manager::VariableDataType::c_double);
434 REGISTER_VARIABLE("R2", R2 , R
"DOC(
435Returns reduced Fox-Wolfram R2, defined as ratio of the i-th to the 0-th order Fox Wolfram moments.
437.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
438.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
441 REGISTER_METAVARIABLE("thrustBm(maskname)", thrustBmWithMask, R
"DOC(
442Returns magnitude of the signal B thrust axis.
444.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
445.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
446)DOC", Manager::VariableDataType::c_double);
447 REGISTER_VARIABLE("thrustBm", thrustBm, R
"DOC(
448Returns magnitude of the signal B thrust axis.
450.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
451.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
454 REGISTER_METAVARIABLE("thrustOm(maskname)", thrustOmWithMask, R
"DOC(
455Returns magnitude of the ROE thrust axis.
457.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
458.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
459)DOC", Manager::VariableDataType::c_double);
460 REGISTER_VARIABLE("thrustOm", thrustOm, R
"DOC(
461Returns magnitude of the ROE thrust axis.
463.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
464.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
467 REGISTER_METAVARIABLE("cosTBTO(maskname)", cosTBTOWithMask, R
"DOC(
468Returns cosine of angle between thrust axis of the signal B and thrust axis of ROE.
470.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
471.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
472)DOC", Manager::VariableDataType::c_double);
473 REGISTER_VARIABLE("cosTBTO", cosTBTO, R
"DOC(
474Returns cosine of angle between thrust axis of the signal B and thrust axis of ROE.
476.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
477.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
480 REGISTER_METAVARIABLE("cosTBz(maskname)", cosTBzWithMask, R
"DOC(
481Returns cosine of angle between thrust axis of the signal B and z-axis.
483.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
484.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
485)DOC", Manager::VariableDataType::c_double);
486 REGISTER_VARIABLE("cosTBz", cosTBz, R
"DOC(
487Returns cosine of angle between thrust axis of the signal B and z-axis.
489.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
490.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
493 REGISTER_METAVARIABLE("KSFWVariables(variable[, string, string])", KSFWVariables, R
"DOC(
494Returns variable et in ``GeV/c``, mm2 in (GeV/c^2)^2, or one of the 16 KSFW moments.
495The second and third arguments are optional unless you have created multiple instances of the ContinuumSuppression with different ROE masks.
496In that case the desired ROE mask name must be provided as well.
497If the second argument is set to 'FS1', the KSFW moment is calculated from the B final state daughters.
498Otherwise, the KSFW moment is calculated from the B primary daughters.
499The ROE mask name is then either the second or the third argument and must not be called 'FS1'.
500Allowed input values for ``variable`` argument are the following:
503* hso00, hso01, hso02, hso03, hso04
506* hoo0, hoo1, hoo2, hoo3, hoo4.
508.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
509.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
510)DOC", Manager::VariableDataType::c_double);
512 REGISTER_METAVARIABLE("CleoConeCS(integer[, string, string])", CleoConesCS, R
"DOC(
513Returns i-th cleo cones from the continuum suppression. The allowed inputs for the ``integer`` argument are integers from *1* to *9*.
514The second and third arguments are optional unless you have created multiple instances of the ContinuumSuppression with different ROE masks.
515In that case the desired ROE mask name must be provided as well.
516If the second argument is set to 'ROE', the CleoCones are calculated only from ROE particles.
517Otherwise, the CleoCones are calculated from all final state particles.
518The ROE mask name is then either the second or the third argument and must not be called 'ROE'. The unit of the CleoConeCS is ``GeV/c``.
520.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
521.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
522)DOC", Manager::VariableDataType::c_double);
524 REGISTER_METAVARIABLE("transformedNetworkOutput(name, low, high)", transformedNetworkOutput, R
"DOC(
525Transforms the network output :math:`C \to C'` via: :math:`C'=\operatorname{log}((C-\mathrm{low})/(\mathrm{high}-C))`.
526The arguments of the metavariable are the following:
528* ``name`` is the `extraInfo` name, where the network output :math:`C` has been stored. If particle is not specified, event `extraInfo` is used instead;
529* ``low``, ``high`` are floating point numbers.
531Returns NaN, if the `extraInfo` has not been found.
532)DOC", Manager::VariableDataType::c_double);
534 REGISTER_METAVARIABLE("useBThrustFrame(variable, mode)", useBThrustFrame, R
"DOC(
535Returns the variable with respect to rotated coordinates, in which z lies on the specified thrust axis.
536If mode is set to ``Signal`` it will use the thrust axis of the reconstructed B candidate, if mode is set to ROE it will use the ROE thrust axis.
537If mode is set to ``Auto`` the function use the thrust axis based on Rest Of Event (ROE) particles.
538Like :b2:var:`isInRestOfEvent`, one has to use this metavariable in ROE loop.
540.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful.
541.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`.
542)DOC", Manager::VariableDataType::c_double);
static const double doubleNaN
quiet_NaN
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
Abstract base class for different kinds of events.