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> 
   18#include <framework/logging/Logger.h> 
   19#include <framework/datastore/StoreObjPtr.h> 
   20#include <framework/utilities/Conversion.h> 
   34      if (arguments.size() != 1)
 
   35        B2FATAL(
"An empty argument is not allowed for the variable R2." 
   36                "Either provide no argument or a valid mask name.");
 
   37      std::string maskName = arguments[0];
 
   38      auto func = [maskName](
const Particle * particle) -> 
double {
 
   39        const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
   48    double R2(
const Particle* particle)
 
   50      RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
   51      if (continuumSuppressionRelations.size() == 1) {
 
   52        const ContinuumSuppression* qq = continuumSuppressionRelations[0];
 
   55        if (continuumSuppressionRelations.size() > 1) {
 
   56          B2ERROR(
"The return value of R2 is ambiguous. Please provide the mask name as argument.");
 
   64      if (arguments.size() != 1)
 
   65        B2FATAL(
"An empty argument is not allowed for the variable thrustBm." 
   66                "Either provide no argument or a valid mask name.");
 
   67      std::string maskName = arguments[0];
 
   68      auto func = [maskName](
const Particle * particle) -> 
double {
 
   69        const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
   73        return qq->getThrustBm();
 
   78    double thrustBm(
const Particle* particle)
 
   80      RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
   81      if (continuumSuppressionRelations.size() == 1) {
 
   82        const ContinuumSuppression* qq = continuumSuppressionRelations[0];
 
   83        return qq->getThrustBm();
 
   85        if (continuumSuppressionRelations.size() > 1) {
 
   86          B2ERROR(
"The return value of thrustBm is ambiguous. Please provide the mask name as argument.");
 
   94      if (arguments.size() != 1)
 
   95        B2FATAL(
"An empty argument is not allowed for the variable thrustOm." 
   96                "Either provide no argument or a valid mask name.");
 
   97      std::string maskName = arguments[0];
 
   98      auto func = [maskName](
const Particle * particle) -> 
double {
 
   99        const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
  103        return qq->getThrustOm();
 
  108    double thrustOm(
const Particle* particle)
 
  110      RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  111      if (continuumSuppressionRelations.size() == 1) {
 
  112        const ContinuumSuppression* qq = continuumSuppressionRelations[0];
 
  113        return qq->getThrustOm();
 
  115        if (continuumSuppressionRelations.size() > 1) {
 
  116          B2ERROR(
"The return value of thrustOm is ambiguous. Please provide the mask name as argument.");
 
  124      if (arguments.size() != 1)
 
  125        B2FATAL(
"An empty argument is not allowed for the variable cosTBTO." 
  126                "Either provide no argument or a valid mask name.");
 
  127      std::string maskName = arguments[0];
 
  128      auto func = [maskName](
const Particle * particle) -> 
double {
 
  129        const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
  133        return qq->getCosTBTO();
 
  138    double cosTBTO(
const Particle* particle)
 
  140      RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  141      if (continuumSuppressionRelations.size() == 1) {
 
  142        const ContinuumSuppression* qq = continuumSuppressionRelations[0];
 
  143        return qq->getCosTBTO();
 
  145        if (continuumSuppressionRelations.size() > 1) {
 
  146          B2ERROR(
"The return value of cosTBTO is ambiguous. Please provide the mask name as argument.");
 
  154      if (arguments.size() != 1)
 
  155        B2FATAL(
"An empty argument is not allowed for the variable cosTBz." 
  156                "Either provide no argument or a valid mask name.");
 
  157      std::string maskName = arguments[0];
 
  158      auto func = [maskName](
const Particle * particle) -> 
double {
 
  159        const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
  163        return qq->getCosTBz();
 
  168    double cosTBz(
const Particle* particle)
 
  170      RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  171      if (continuumSuppressionRelations.size() == 1) {
 
  172        const ContinuumSuppression* qq = continuumSuppressionRelations[0];
 
  173        return qq->getCosTBz();
 
  175        if (continuumSuppressionRelations.size() > 1) {
 
  176          B2ERROR(
"The return value of cosTBz is ambiguous. Please provide the mask name as argument.");
 
  184      if (arguments.size() > 0 && arguments.size() < 4) {
 
  186        auto variableName = arguments[0];
 
  187        std::string maskName = 
"";
 
  188        if (arguments.size() >= 2) {
 
  189          if (arguments[1] == 
"FS1") {
 
  192            maskName = arguments[1];
 
  194          if (arguments.size() == 3) {
 
  195            maskName = arguments[2];
 
  196            if (maskName == 
"FS1") {
 
  197              B2ERROR(
"It looks like you provided the arguments for KSFWVariables in the wrong order." 
  198                      "If you want to use the KSFW moments calculated from the B final state particles, the second argument has to be 'FS1'." 
  199                      "The third argument would then have to be the ROE mask name.");
 
  206        std::vector<std::string> names = {
"mm2",   
"et",
 
  207                                          "hso00", 
"hso01", 
"hso02", 
"hso03", 
"hso04",
 
  208                                          "hso10", 
"hso12", 
"hso14",
 
  209                                          "hso20", 
"hso22", 
"hso24",
 
  210                                          "hoo0",  
"hoo1",  
"hoo2",  
"hoo3",  
"hoo4" 
  214        for (
unsigned i = 0; i < names.size(); ++i) {
 
  215          if (variableName == names[i])
 
  221          std::string allowed = 
"";
 
  224          B2FATAL(
"Variable name provided: " << variableName << 
" is not one of the allowed options. Please choose from one of:" << allowed);
 
  227        auto func = [index, useFS1, maskName](
const Particle * particle) -> 
double {
 
  228          RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  229          ContinuumSuppression* qq = 
nullptr;
 
  230          if (maskName.empty())
 
  232            if (continuumSuppressionRelations.size() == 1) {
 
  233              qq = continuumSuppressionRelations[0];
 
  234            } 
else if (continuumSuppressionRelations.size() > 1) {
 
  235              B2ERROR(
"The return value of KSFWVariables is ambiguous. Please provide the mask name as argument.");
 
  239            qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
  244          std::vector<float> ksfw = qq->getKsfwFS0();
 
  246            ksfw = qq->getKsfwFS1();
 
  248          if (ksfw.size() == 0) B2FATAL(
"Could not find any KSFW moments");
 
  249          return ksfw.at(index);
 
  253        B2FATAL(
"Wrong number of arguments for meta function KSFWVariables. It only takes between one and three arguments." 
  254                " 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." 
  255                " You can also provide the ROE mask name as second or third argument.");
 
  261      if (arguments.size() > 0 && arguments.size() < 4) {
 
  266        } 
catch (std::invalid_argument&) {
 
  267          B2FATAL(
"The first argument of the CleoConeCS meta function must be an integer!");
 
  271        std::string maskName = 
"";
 
  272        if (arguments.size() >= 2) {
 
  273          if (arguments[1] == 
"ROE") {
 
  276            maskName = arguments[1];
 
  278          if (arguments.size() == 3) {
 
  279            maskName = arguments[2];
 
  280            if (maskName == 
"ROE") {
 
  281              B2ERROR(
"It looks like you provided the arguments for CleoConeCS in the wrong order." 
  282                      "If you want to use the CleoCones calculated from all final state particles, the second argument has to be 'ROE'." 
  283                      "The third argument would then have to be the ROE mask name.");
 
  288        auto func = [coneNumber, useROE, maskName](
const Particle * particle) -> 
double {
 
  289          RelationVector<ContinuumSuppression> continuumSuppressionRelations = particle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  290          ContinuumSuppression* qq = 
nullptr;
 
  291          if (maskName.empty())
 
  293            if (continuumSuppressionRelations.size() == 1) {
 
  294              qq = continuumSuppressionRelations[0];
 
  295            } 
else if (continuumSuppressionRelations.size() > 1) {
 
  296              B2ERROR(
"The return value of CleoConeCS is ambiguous. Please provide the mask name as argument.");
 
  300            qq = particle->getRelatedTo<ContinuumSuppression>(maskName);
 
  305          std::vector<float> cleoCones = qq->getCleoConesALL();
 
  307            cleoCones = qq->getCleoConesROE();
 
  308          return cleoCones.at(coneNumber - 1);
 
  312        B2FATAL(
"Wrong number of arguments for CleoConeCS function. It only takes between one and three arguments." 
  313                "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." 
  314                "You can also provide the ROE mask name as second or third argument.");
 
  320      if (arguments.size() == 3) {
 
  326        } 
catch (std::invalid_argument&) {
 
  327          B2FATAL(
"Second and third argument of transformedNetworkOutput meta function must be doubles!");
 
  330        auto extraInfoName = arguments[0];
 
  331        auto func = [extraInfoName, low, high](
const Particle * particle) -> 
double {
 
  332          if (particle == 
nullptr)
 
  334            StoreObjPtr<EventExtraInfo> eventExtraInfo;
 
  335            if (eventExtraInfo->hasExtraInfo(extraInfoName)) {
 
  336              return eventExtraInfo->getExtraInfo(extraInfoName);
 
  341          if (particle->hasExtraInfo(extraInfoName))
 
  343            return std::log(((particle->getExtraInfo(extraInfoName)) - low) / (high - (particle->getExtraInfo(extraInfoName))));
 
  351        B2FATAL(
"Wrong number of arguments for meta function transformedNetworkOutput");
 
  357      if (arguments.size() == 2 || arguments.size() == 3) {
 
  358        auto variableName = arguments[0];
 
  359        std::string mode = arguments[1];
 
  361        const bool modeisSignal = mode == 
"Signal";
 
  362        const bool modeisAuto = mode == 
"Auto";
 
  364        if (not modeisSignal and (mode != 
"ROE") and not modeisAuto)
 
  365          B2FATAL(
"Second argument in useBThrustFrame can only be 'Signal', 'ROE' or 'Auto'. Your argument was " + mode);
 
  369        std::string maskName = arguments.size() == 3 ? arguments[2] : 
"";
 
  371        auto func = [var, modeisSignal, modeisAuto, maskName](
const Particle * particle) -> 
double {
 
  372          StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
 
  373          const Particle* Bparticle = roe->getRelatedFrom<Particle>();
 
  374          RelationVector<ContinuumSuppression> continuumSuppressionRelations = Bparticle->getRelationsTo<ContinuumSuppression>(
"ALL");
 
  375          ContinuumSuppression* qq = 
nullptr;
 
  376          if (maskName.empty())
 
  378            if (continuumSuppressionRelations.size() == 1) {
 
  379              qq = continuumSuppressionRelations[0];
 
  380            } 
else if (continuumSuppressionRelations.size() > 1) {
 
  381              B2ERROR(
"The return value of useBThrustFrame is ambiguous. Please provide the mask name as argument.");
 
  385            qq = Bparticle->getRelatedTo<ContinuumSuppression>(maskName);
 
  390          bool isinROE = isInRestOfEvent(particle);
 
  391          ROOT::Math::XYZVector newZ;
 
  392          if (modeisSignal or (modeisAuto and isinROE))
 
  393            newZ = qq->getThrustB();
 
  395            newZ = qq->getThrustO();
 
  397          ROOT::Math::XYZVector newY(0, 0, 0);
 
  398          if (newZ.Z() == 0 and newZ.Y() == 0)
 
  403            newY.SetZ(-newZ.Y());
 
  405          ROOT::Math::XYZVector newX = newY.Cross(newZ);
 
  407          UseReferenceFrame<CMSRotationFrame> signalframe(newX, newY, newZ);
 
  409          return std::get<double>(var->function(particle));
 
  413        B2FATAL(
"Wrong number of arguments for meta function useBThrustFrame. It only takes two or three arguments. The first argument must be the variable." 
  414                "The second can either be 'Signal', 'ROE', or 'Auto'." 
  415                "The third argument is optional (as long as the ContinuumSuppression was built only once) and can define a specific ROE mask name.");
 
  420    VARIABLE_GROUP(
"Continuum Suppression");
 
  421    REGISTER_METAVARIABLE(
"R2(maskname)", R2WithMask, R
"DOC( 
  422Returns reduced Fox-Wolfram R2, defined as ratio of the i-th to the 0-th order Fox Wolfram moments. 
  424.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  425.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  426)DOC", Manager::VariableDataType::c_double); 
  427    REGISTER_VARIABLE("R2", R2 , R
"DOC( 
  428Returns reduced Fox-Wolfram R2, defined as ratio of the i-th to the 0-th order Fox Wolfram moments. 
  430.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  431.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  434    REGISTER_METAVARIABLE("thrustBm(maskname)", thrustBmWithMask, R
"DOC( 
  435Returns magnitude of the signal B thrust axis. 
  437.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  438.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  439)DOC", Manager::VariableDataType::c_double); 
  440    REGISTER_VARIABLE("thrustBm", thrustBm, R
"DOC( 
  441Returns magnitude of the signal B thrust axis. 
  443.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  444.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  447    REGISTER_METAVARIABLE("thrustOm(maskname)", thrustOmWithMask, R
"DOC( 
  448Returns magnitude of the ROE 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`. 
  452)DOC", Manager::VariableDataType::c_double); 
  453    REGISTER_VARIABLE("thrustOm", thrustOm, R
"DOC( 
  454Returns magnitude of the ROE thrust axis. 
  456.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  457.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  460    REGISTER_METAVARIABLE("cosTBTO(maskname)", cosTBTOWithMask, R
"DOC( 
  461Returns cosine of angle between thrust axis of the signal B and thrust axis of ROE. 
  463.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  464.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  465)DOC", Manager::VariableDataType::c_double); 
  466    REGISTER_VARIABLE("cosTBTO", cosTBTO, R
"DOC( 
  467Returns cosine of angle between thrust axis of the signal B and thrust axis of ROE. 
  469.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  470.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  473    REGISTER_METAVARIABLE("cosTBz(maskname)", cosTBzWithMask, R
"DOC( 
  474Returns cosine of angle between thrust axis of the signal B and z-axis. 
  476.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  477.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  478)DOC", Manager::VariableDataType::c_double); 
  479    REGISTER_VARIABLE("cosTBz", cosTBz, R
"DOC( 
  480Returns cosine of angle between thrust axis of the signal B and z-axis. 
  482.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  483.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  486    REGISTER_METAVARIABLE("KSFWVariables(variable[, string, string])", KSFWVariables,  R
"DOC( 
  487Returns variable et in ``GeV/c``, mm2 in (GeV/c^2)^2, or one of the 16 KSFW moments. 
  488The second and third arguments are optional unless you have created multiple instances of the ContinuumSuppression with different ROE masks. 
  489In that case the desired ROE mask name must be provided as well. 
  490If the second argument is set to 'FS1', the KSFW moment is calculated from the B final state daughters. 
  491Otherwise, the KSFW moment is calculated from the B primary daughters. 
  492The ROE mask name is then either the second or the third argument and must not be called 'FS1'. 
  493Allowed input values for ``variable`` argument are the following: 
  496* hso00, hso01, hso02, hso03, hso04 
  499* hoo0,  hoo1,  hoo2,  hoo3,  hoo4. 
  501.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  502.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  503)DOC", Manager::VariableDataType::c_double); 
  505    REGISTER_METAVARIABLE("CleoConeCS(integer[, string, string])", CleoConesCS, R
"DOC( 
  506Returns i-th cleo cones from the continuum suppression. The allowed inputs for the ``integer`` argument are integers from *1* to *9*. 
  507The second and third arguments are optional unless you have created multiple instances of the ContinuumSuppression with different ROE masks. 
  508In that case the desired ROE mask name must be provided as well. 
  509If the second argument is set to 'ROE', the CleoCones are calculated only from ROE particles. 
  510Otherwise, the CleoCones are calculated from all final state particles. 
  511The 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``. 
  513.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  514.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  515)DOC", Manager::VariableDataType::c_double); 
  517    REGISTER_METAVARIABLE("transformedNetworkOutput(name, low, high)", transformedNetworkOutput, R
"DOC( 
  518Transforms the network output :math:`C \to C'` via: :math:`C'=\operatorname{log}((C-\mathrm{low})/(\mathrm{high}-C))`. 
  519The arguments of the metavariable are the following: 
  521* ``name`` is the `extraInfo` name, where the network output :math:`C` has been stored. If particle is not specified, event `extraInfo` is used instead; 
  522* ``low``, ``high`` are floating point numbers. 
  524Returns NaN, if the `extraInfo` has not been found. 
  525)DOC", Manager::VariableDataType::c_double); 
  527    REGISTER_METAVARIABLE("useBThrustFrame(variable, mode)", useBThrustFrame,  R
"DOC( 
  528Returns the variable with respect to rotated coordinates, in which z lies on the specified thrust axis. 
  529If 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. 
  530If mode is set to ``Auto`` the function use the thrust axis based on Rest Of Event (ROE) particles. 
  531Like :b2:var:`isInRestOfEvent`, one has to use this metavariable in ROE loop. 
  533.. warning:: You have to run the Continuum Suppression builder module for this variable to be meaningful. 
  534.. seealso:: :ref:`analysis_continuumsuppression` and `buildContinuumSuppression`. 
  535)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.
T convertString(const std::string &str)
Converts a string to type T (one of float, double, long double, int, long int, unsigned long int).
Abstract base class for different kinds of events.