32 namespace MD = MultiDimensional;
34 ProcManager::ProcManager(
const Process& inputs)
37 _reqs{
new ProcRequirements{}},
38 _results{
new ProcResults{}},
39 _processRates{
nullptr},
40 _dictionaries{
nullptr} {
48 read(msgreader,
false);
53 _graph{other._graph.release()},
54 _reqs{other._reqs.release()},
55 _results{other._results.release()},
56 _processRates{other._processRates},
57 _dictionaries{other._dictionaries} {
89 for(
auto&
id :
_reqs->rateIds()){
106 if(
isOn(
"Amplitudes")) {
107 pair<bool, bool> first{
true,
true};
110 for (
auto& elem :
_reqs->amplitudes()) {
111 auto amplNum = elem.second.amplitudes.numerator;
112 auto amplDen = elem.second.amplitudes.denominator;
113 auto numamp = amplNum.ptr;
114 auto denamp = amplDen.ptr;
115 if (numamp !=
nullptr) {
116 auto particles =
_graph->getParticleVectors(amplNum.type, elem.first, elem.second.daughterIdx);
117 numamp->eval(get<0>(particles), get<1>(particles), get<2>(particles));
127 if (denamp !=
nullptr) {
128 if (numamp != denamp) {
129 auto particles =
_graph->getParticleVectors(amplDen.type, elem.first, elem.second.daughterIdx);
130 denamp->eval(get<0>(particles), get<1>(particles), get<2>(particles));
134 first.second =
false;
143 if (
isOn(
"SquaredAmplitudes")) {
148 if(
isOn(
"SquaredAmplitudes")){
153 if (
isOn(
"FormFactors")) {
158 for(
auto& elem:
_reqs->amplitudes()){
159 auto itFF =
_reqs->formFactors().find(elem.first);
160 if(itFF !=
_reqs->formFactors().end()){
161 AmplitudeBase* ampNum = elem.second.amplitudes.numerator.ptr;
162 AmplitudeBase* ampDen = elem.second.amplitudes.denominator.ptr;
164 auto it =
_inputs->find(elem.first);
166 MSG_ERROR(
"Something really stinky just happened in CalcFormFactors. Can you smell it?");
169 auto daughters =
_inputs->getDaughters(it->first,
true);
170 auto& parent =
_inputs->getParticle(it->first);
171 auto siblings =
_inputs->getSiblings(it->first,
true);
172 for(
auto& elemCh: dict) {
173 auto itCh = elemCh.second.find(
id);
174 if(itCh != elemCh.second.end()) {
175 auto iFF = itFF->second.find(itCh->second);
176 if(iFF != itFF->second.end()) {
177 if ((elemCh.first ==
"Denominator" && ampDen ==
nullptr) || (elemCh.first !=
"Denominator" && ampNum ==
nullptr)){
178 _results->appendFormFactor(elemCh.first, noFF);
181 iFF->second->eval(parent, daughters, siblings);
182 _results->appendFormFactor(elemCh.first, iFF->second->getTensor());
183 iFF->second->addRefs();
188 for(
auto& elemCh: dict) {
189 _results->appendFormFactor(elemCh.first, noFF);
194 if (
isOn(
"Weights")) {
199 auto ffdens =
_results->processFormFactors(
"Denominator");
200 for(
auto& elem: ffdens) {
208 for(
auto& elem:
_reqs->denominatorFFEigenVectors()) {
209 denominator.
dot(elem);
213 for(
auto& elem:
_reqs->denominatorWilsonCoeffs()) {
214 denominator.
dot(elem);
217 if(denominator.
rank() > 0) {
218 MSG_ERROR(
"Denominator has uncontracted indices, with rank " + to_string(denominator.
rank()) +
". There's a monster in the basement! Check FF input scheme has been correctly set.");
221 double denValue = denominator.
element().real();
224 for (
auto& elem :
_results->availableSchemes()) {
228 for(
auto& elem2:
_reqs->specializedWilsonCoeffs()) {
234 for (
auto& elem2 :
_results->processFormFactors(elem)) {
240 tbase *= 1. / denValue;
241 _results->setProcessWeight(elem, tbase);
256 addSetting<bool>(
"FormFactors",
true);
257 addSetting<bool>(
"SquaredAmplitudes",
true);
258 addSetting<bool>(
"Amplitudes",
true);
259 addSetting<bool>(
"Rates",
true);
260 addSetting<bool>(
"Weights",
true);
266 _inputs->write(msgwriter, &serialids);
268 _results->write(msgwriter, &serialdata);
269 Serial::FBProcessBuilder serialprocess{*msgwriter};
270 serialprocess.add_ids(serialids);
271 serialprocess.add_data(serialdata);
272 *msg = serialprocess.Finish();
276 if (msgreader !=
nullptr) {
279 _inputs->read(msgreader->ids());
282 res &=
_results->read(msgreader->data(), merge);
290 if (!
_inputs->isParent(parent)) {
291 MSG_ERROR(
"Something really stinky just happened in calcPSTensor. Can you smell it?");
295 auto pmassPDG = pdg.
getMass(
_inputs->getParticle(parent).pdgId());
296 auto daughters =
_inputs->getDaughters(parent);
297 vector<double> dmassesPDG;
298 for(
auto& elem: daughters){
299 dmassesPDG.push_back(pdg.
getMass(elem.pdgId()));
301 res.element({}) = 0.5*
phaseSpaceNBody(pmassPDG, dmassesPDG)*pow(pmassPDG, static_cast<double>(5-2*daughters.size()));
306 const string& scheme)
const {
307 auto itr =
_reqs->rates().find(parent);
308 if (itr !=
_reqs->rates().end()){
312 auto itf =
_reqs->formFactors().find(parent);
313 auto itidx = ffmaps.find(rateptr->
hadronicId());
314 if(itf !=
_reqs->formFactors().end() && itidx != ffmaps.end()){
315 auto itFF = itf->second.find(itidx->second);
317 Tensor rateFF = itFF->second->getFFPSIntegrand(points);
321 MSG_ERROR(
"Unable to contract rate tensor for vertex with parent " + to_string(
_inputs->getParticle(parent).pdgId()) +
" with scheme " + scheme +
". Eject! Eject!");
326 auto itpw =
_reqs->partialWidths().find(parent);
327 if (itpw !=
_reqs->partialWidths().end()){
329 pw.element({}) = *(itpw->second);
333 MSG_ERROR(
"Unable to compute rate tensor for vertex with parent " + to_string(
_inputs->getParticle(parent).pdgId()) +
" and scheme "
334 + scheme +
". Pull up! Pull up!");
339 if(!
isOn(
"Rates")) {
return; }
340 auto it =
_reqs->amplitudes().find(parent);
341 if (it ==
_reqs->amplitudes().end()) {
return; }
342 auto amplNum = (it->second).amplitudes.numerator;
343 auto amplDen = (it->second).amplitudes.denominator;
344 auto daughter = (it->second).daughterIdx;
346 for(
auto& scheme : schemes){
347 auto ampl = (scheme.first ==
"Denominator") ? amplDen : amplNum;
350 if(ampl.ptr ==
nullptr){
359 if (ampl.ptr ==
nullptr) {
361 dprocessRates->insert({scheme.first,
calcPSTensor(daughter)});
364 dprocessRates->insert({scheme.first,
calcRateTensor(daughter, scheme.second, scheme.first)});
371 dprocessRates->insert({scheme.first,
calcPSTensor(daughter)});
377 dprocessRates->insert({scheme.first,
calcRateTensor(daughter, scheme.second, scheme.first)});
virtual void defineSettings()
purely virtual function for a class to define new settings
Tensor & outerSquare()
creates a tensor with twice the rank by multiplying the tensor with its hermitean conjugate ...
DictionaryManager * _dictionaries
std::complex< double > & element(const IndexList &indices={})
access an element given its indices
virtual void forbidProcess(ProcessUID processId) const
Base class for amplitudes.
SchemeDict< Tensor > * _processRates
TensorData read(const Serial::FBTensor *msgreader)
Tensor calcPSTensor(const ParticleIndex &parent) const
virtual void initialize(DictionaryManager *dictionaries)
Tensor outerSquare(const Tensor &first)
creates a tensor with twice the rank by multiplying the tensor with it's hermitean conjugate ...
void write(flatbuffers::FlatBufferBuilder *msgwriter, flatbuffers::Offset< Serial::FBProcess > *msg) const
void calcRates(const ParticleIndex &parent) const
void setPath(const std::string &path)
provide the basic path for the settings defined by this class, as in "<path>:<setting>" ...
Container class for storing included/forbidden process info.
virtual const SchemeDict< ProcIdDict< FFIndex > > & getSchemeDefs() const
double phaseSpaceNBody(const double parentMass, const vector< double > &daughterMasses)
std::unique_ptr< ProcResults > _results
Hammer base amplitude class.
bool hasFFLabels() const
checks if Tensor has indices in the FF range
std::unique_ptr< ProcRequirements > _reqs
void calcTensor()
evaluates the rate by computing the (rank N) rate tensor at different points using evalAtPSPoint on ...
virtual void setSettingsHandler(SettingsHandler &sh)
set link to settings repository handler.
Base class to access the settings repository.
std::unique_ptr< Process > _inputs
virtual bool isProcessIncluded(std::set< HashId > subamplitudes, ProcessUID processId) const
size_t rank() const
rank of the tensor
static Log & getLog(const std::string &name)
Get a logger with the given name.
virtual void setSettingsHandler(SettingsHandler &sh)
set link to settings repository handler.
Tensor calcRateTensor(const ParticleIndex &parent, const ProcIdDict< FFIndex > &ffmaps, const std::string &schemeName) const
HashId hadronicId() const
returns the hadronic unique ID (parent + hadronic daughters) of the current decay signature ...
void setDictionary(DictionaryManager *dict)
Order-0 tensor data container.
const Process & inputs() const
Log & getLog() const
logging facility
Hammer class for dealing with particle data.
Multidimensional tensor class with complex numbers as elements.
Tensor & getTensor()
returns a reference to itself as a Tensor
Container class for all process related data structures.
TensorData makeScalar(complex< double > value)
std::unique_ptr< ProcGraph > _graph
virtual const ProcRates & rates() const
const ProcResults & results() const
Hammer particle data class.
bool read(const Serial::FBProcess *msgreader, bool merge)
Hammer numerical integration classes.
TensorData makeEmptyScalar()
Container class for Scheme Definitions.
Hammer settings manager class.
std::map< SchemeName, T > SchemeDict
Tensor & dot(const Tensor &other, const UniqueLabelsList &indices={})
contract this tensor with another and stores the result in this tensor
const EvaluationGrid & getEvaluationPoints() const
virtual const SchemeDefinitions & schemeDefs() const
bool isOn(const std::string &name) const
method to check a boolean setting defined by this class
Container class for process rate tensors.
virtual SchemeDict< Tensor > * getProcessRates(ProcessUID id)
Serialization related typedefs and includes.
bool hasFFVarLabels() const
checks if Tensor has indices in the FF Var range
virtual const ProcessDefinitions & processDefs() const
double getMass(PdgId id) const
particle mass from a PDG code
Global container class for amplitudes, rates, FFs, data.
bool hasWCLabels() const
checks if Tensor has indices in the WC range