11 #include <analysis/variables/ContinuumSuppressionVariables.h>
12 #include <analysis/variables/ROEVariables.h>
13 #include <analysis/VariableManager/Manager.h>
14 #include <analysis/dataobjects/EventExtraInfo.h>
15 #include <analysis/dataobjects/Particle.h>
16 #include <analysis/dataobjects/ContinuumSuppression.h>
17 #include <analysis/utility/ReferenceFrame.h>
18 #include <analysis/ClusterUtility/ClusterUtils.h>
19 #include <analysis/ContinuumSuppression/FoxWolfram.h>
21 #include <framework/logging/Logger.h>
22 #include <framework/datastore/StoreArray.h>
23 #include <framework/datastore/StoreObjPtr.h>
24 #include <framework/utilities/Conversion.h>
26 #include <mdst/dataobjects/PIDLikelihood.h>
27 #include <mdst/dataobjects/Track.h>
28 #include <mdst/dataobjects/ECLCluster.h>
30 #include <TLorentzVector.h>
43 double R2EventLevel(
const Particle*)
45 B2WARNING(
"The variable R2EventLevel is deprecated. Use `foxWolframR2` and ma.buildEventShape(inputListNames=[], default_cleanup=True, allMoments=False, cleoCones=True, collisionAxis=True, foxWolfram=True, harmonicMoments=True, jets=True, sphericity=True, thrust=True, checkForDuplicates=False, path=mypath)");
47 std::vector<TVector3> p3_all;
49 StoreArray<Track> tracks;
50 for (
int i = 0; i < tracks.getEntries(); ++i) {
54 Const::ParticleType mostLikely = tracks[i]->getRelated<PIDLikelihood>()->getMostLikely();
55 const TrackFitResult* iTrack = tracks[i]->getTrackFitResultWithClosestMass(mostLikely);
56 if (iTrack ==
nullptr)
continue;
57 if (iTrack->getChargeSign() != 0) {
58 Particle particle(tracks[i], iTrack->getParticleType());
60 TLorentzVector p_cms = T.rotateLabToCms() * particle.get4Vector();
61 p3_all.push_back(p_cms.Vect());
65 StoreArray<ECLCluster> eclClusters;
66 for (
int i = 0; i < eclClusters.getEntries(); ++i) {
73 if (momECLCluster == momECLCluster) {
74 if (eclClusters[i]->isNeutral()) {
75 Particle particle(eclClusters[i]);
77 TLorentzVector p_cms = T.rotateLabToCms() * particle.get4Vector();
78 p3_all.push_back(p_cms.Vect());
83 FoxWolfram FW(p3_all);
84 FW.calculateBasicMoments();
88 double R2(
const Particle* particle)
90 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
92 return std::numeric_limits<float>::quiet_NaN();
97 double thrustBm(
const Particle* particle)
99 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
101 return std::numeric_limits<float>::quiet_NaN();
103 return qq->getThrustBm();
106 double thrustOm(
const Particle* particle)
108 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
110 return std::numeric_limits<float>::quiet_NaN();
112 return qq->getThrustOm();
115 double cosTBTO(
const Particle* particle)
117 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
119 return std::numeric_limits<float>::quiet_NaN();
121 return qq->getCosTBTO();
124 double cosTBz(
const Particle* particle)
126 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
128 return std::numeric_limits<float>::quiet_NaN();
130 return qq->getCosTBz();
135 if (arguments.size() == 1 || arguments.size() == 2) {
137 auto variableName = arguments[0];
138 if (arguments.size() == 2) {
139 if (arguments[1] ==
"FS1") {
142 B2FATAL(
"Second argument in KSFWVariables can only be 'FS1' to use the KSFW moments calculated from the B final state particles! Do not include a second argument to use the default KSFW moments calculated from the B primary daughters.");
148 std::vector<std::string> names = {
"mm2",
"et",
149 "hso00",
"hso01",
"hso02",
"hso03",
"hso04",
150 "hso10",
"hso12",
"hso14",
151 "hso20",
"hso22",
"hso24",
152 "hoo0",
"hoo1",
"hoo2",
"hoo3",
"hoo4"
156 for (
unsigned i = 0; i < names.size(); ++i) {
157 if (variableName == names[i])
163 std::string allowed =
"";
166 B2FATAL(
"Variable name provided: " << variableName <<
" is not one of the allowed options. Please choose from one of:" << allowed);
169 auto func = [index, useFS1](
const Particle * particle) ->
double {
170 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
171 if (!qq)
return std::numeric_limits<double>::quiet_NaN();
174 std::vector<float> ksfw = qq->getKsfwFS0();
176 ksfw = qq->getKsfwFS1();
178 if (ksfw.size() == 0) B2FATAL(
"Could not find any KSFW moments");
179 return ksfw.at(index);
183 B2FATAL(
"Wrong number of arguments for meta function KSFWVariables. It only takes one or two arguments. The first argument must be the variable and the second can either be left blank or must be FS1 to use the KSFW moments calculated from the B final state particles.");
189 if (arguments.size() == 1 || arguments.size() == 2) {
193 coneNumber = Belle2::convertString<int>(arguments[0]);
194 }
catch (std::invalid_argument&) {
195 B2FATAL(
"The first argument of the CleoConeCS meta function must be an integer!");
199 if (arguments.size() == 2) {
200 if (arguments[1] ==
"ROE") {
203 B2FATAL(
"Second argument in CleoCones can only be 'ROE' to use the CleoCones calculated from the ROE only! Do not include a second argument to use the default CleoCones calculated from all final state particles.");
207 auto func = [coneNumber, useROE](
const Particle * particle) ->
double {
208 const ContinuumSuppression* qq = particle->getRelatedTo<ContinuumSuppression>();
210 return std::numeric_limits<double>::quiet_NaN();
211 std::vector<float> cleoCones = qq->getCleoConesALL();
213 cleoCones = qq->getCleoConesROE();
214 return cleoCones.at(coneNumber - 1);
218 B2FATAL(
"Wrong number of arguments for CleoCones function. It only takes one or two arguments. The first argument must be the cone number and the second can either be left blank or must 'ROE' to use the CleoCones calculated from all final state particles.");
224 if (arguments.size() == 3) {
228 low = Belle2::convertString<double>(arguments[1]);
229 high = Belle2::convertString<double>(arguments[2]);
230 }
catch (std::invalid_argument&) {
231 B2FATAL(
"Second and third argument of transformedNetworkOutput meta function must be doubles!");
234 auto extraInfoName = arguments[0];
235 auto func = [extraInfoName, low, high](
const Particle * particle) ->
double {
236 if (particle ==
nullptr)
238 StoreObjPtr<EventExtraInfo> eventExtraInfo;
239 if (eventExtraInfo->hasExtraInfo(extraInfoName)) {
240 return eventExtraInfo->getExtraInfo(extraInfoName);
242 return std::numeric_limits<double>::quiet_NaN();
245 if (particle->hasExtraInfo(extraInfoName))
247 return std::log(((particle->getExtraInfo(extraInfoName)) - low) / (high - (particle->getExtraInfo(extraInfoName))));
249 return std::numeric_limits<double>::quiet_NaN();
254 B2FATAL(
"Wrong number of arguments for meta function transformedNetworkOutput");
260 if (arguments.size() == 2) {
261 auto variableName = arguments[0];
262 std::string mode = arguments[1];
264 const bool modeisSignal = mode ==
"Signal";
265 const bool modeisAuto = mode ==
"Auto";
267 if (not modeisSignal and (mode !=
"ROE") and not modeisAuto)
268 B2FATAL(
"Second argument in useBThrustFrame can only be 'Signal', 'ROE' or 'Auto'. Your argument was " + mode);
272 auto func = [var, modeisSignal, modeisAuto](
const Particle * particle) ->
double {
273 StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
274 const Particle* Bparticle = roe->getRelated<Particle>();
275 const ContinuumSuppression* qq = Bparticle->getRelatedTo<ContinuumSuppression>();
277 return std::numeric_limits<double>::quiet_NaN();
278 double isinROE = isInRestOfEvent(particle);
280 if (modeisSignal or (modeisAuto and isinROE < 0.5))
281 newZ = qq->getThrustB();
283 newZ = qq->getThrustO();
285 TVector3 newY(0, 0, 0);
286 if (newZ(2) == 0 and newZ(1) == 0)
292 TVector3 newX = newY.Cross(newZ);
294 UseReferenceFrame<CMSRotationFrame> signalframe(newX, newY, newZ);
296 return var->function(particle);
300 B2FATAL(
"Wrong number of arguments for meta function useBThrustFrame. It only takes two arguments. The first argument must be the variable and the second can either be .");
305 VARIABLE_GROUP(
"Continuum Suppression");
306 REGISTER_VARIABLE(
"R2EventLevel", R2EventLevel,
"[Eventbased] Event-Level Reduced Fox-Wolfram moment R2");
307 REGISTER_VARIABLE(
"R2" , R2 ,
"Reduced Fox-Wolfram moment R2");
308 REGISTER_VARIABLE(
"thrustBm" , thrustBm ,
"Magnitude of the signal B thrust axis");
309 REGISTER_VARIABLE(
"thrustOm" , thrustOm ,
"Magnitude of the ROE thrust axis");
310 REGISTER_VARIABLE(
"cosTBTO" , cosTBTO ,
"Cosine of angle between thrust axis of the signal B and thrust axis of ROE");
311 REGISTER_VARIABLE(
"cosTBz" , cosTBz ,
"Cosine of angle between thrust axis of the signal B and z-axis");
312 REGISTER_VARIABLE(
"KSFWVariables(variable,string)", KSFWVariables,
313 "Returns variable et, mm2, or one of the 16 KSFW moments. If only the variable is specified, the KSFW moment calculated from the B primary daughters is returned. If string is set to ``FS1``, the KSFW moment calculated from the B final state daughters is returned.");
314 REGISTER_VARIABLE(
"CleoConeCS(integer,string)", CleoConesCS,
315 "Returns i-th cleo cones from the continuum suppression. If only the variable is specified, the CleoCones are calculated from all final state particles. If string is set to 'ROE', the CleoCones are calculated only from ROE particles.\n"
316 "Useful for ContinuumSuppression.\n"
317 "Given particle needs a related ContinuumSuppression object (built using the ContinuumSuppressionBuilder).\n"
318 "Returns NaN if particle has no related ContinuumSuppression object.");
319 REGISTER_VARIABLE(
"transformedNetworkOutput(name, low, high)", transformedNetworkOutput,
320 "Transforms the network output :math:`C\\to C`' via: :math:`C'=\\operatorname{log}((C-\\mathrm{low})/(\\mathrm{high}-C))`");
321 REGISTER_VARIABLE(
"useBThrustFrame(variable, mode)", useBThrustFrame,
322 "Returns the variable in respect to rotated coordinates, in which z lies on the specified thrust axis.\n"
323 "If 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.\n"
324 "If mode is set to Auto the function use the thrust axis based on isInRestOfEvent(particle).\n"
325 "Like isinRestofEvent, you have to use path.for_each( . . .) to use this MetaVariable.")