35 ProcRequirements::ProcRequirements() {
42 _dictionaries = dictionaries;
48 return _requiredAmplitudes.size();
53 pair<ParticleIndex, bool> ProcRequirements::getAncestorId(
ParticleIndex descendant)
const {
55 if (_requiredAmplitudes.find(parent) != _requiredAmplitudes.end()) {
56 return {parent,
false};
60 if(grandparent < _inputs->numParticles()) {
61 return {grandparent,
true};
63 return {_inputs->getFirstVertex(),
false};
67 void ProcRequirements::getAmplitudes() {
68 _requiredAmplitudes.clear();
69 _multPSFactors.clear();
70 _massPSFactors.clear();
71 _denominatorWilsonCoeffs.clear();
72 _specializedWilsonCoeffs.clear();
73 _requiredAmplitudes = _graph->selectedAmplitudes();
74 for(
auto& elem: _requiredAmplitudes) {
77 auto twcptr = _dictionaries->externalData().getWilsonCoefficients(ampl, WTerm::DENOMINATOR);
78 if (twcptr && twcptr->rank() > 0) {
79 Tensor twc{
"WC", {{twcptr,
false}, {twcptr,
true}}};
80 _denominatorWilsonCoeffs.push_back(move(twc));
84 if(ampln !=
nullptr && _dictionaries->externalData().isWCSpecialized(ampln)){
85 auto swcptr = _dictionaries->externalData().getSpecializedWilsonCoefficients(ampln);
86 if (swcptr && swcptr->rank() > 0) {
87 Tensor swc{
"WC", {{swcptr,
false}, {swcptr,
true}}};
88 _specializedWilsonCoeffs.push_back(move(swc));
92 if(_requiredAmplitudes.find(_inputs->getFirstVertex()) == _requiredAmplitudes.end()){
93 MSG_ERROR(
"An amplitude involving the parent particle is not implemented! 'Oh cock'...in Hungarian! (Check the PDG codes correspond to physical processes)");
96 for(
auto& elem : _requiredAmplitudes) {
97 auto amplNum = elem.second.amplitudes.numerator;
98 auto amplDen = elem.second.amplitudes.denominator;
100 if (elem.first == _inputs->getFirstVertex()){
104 multfact.
numerator = (amplNum.ptr !=
nullptr) ? 1./static_cast<double>(amplNum.ptr->multiplicityFactor()) : 1.;
105 multfact.denominator = (amplDen.ptr !=
nullptr) ? 1./static_cast<double>(amplDen.ptr->multiplicityFactor()) : 1.;
107 pair<ParticleIndex, bool> ancestor = getAncestorId(elem.first);
108 auto itAncestorAmpl = _requiredAmplitudes.find(get<0>(ancestor));
109 auto ancestorAmplNum = itAncestorAmpl->second.amplitudes.numerator;
110 auto ancestorAmplDen = itAncestorAmpl->second.amplitudes.denominator;
112 (amplNum.ptr !=
nullptr) ? _graph->getMultFactor(amplNum, ancestorAmplNum, get<1>(ancestor)) : 1.;
113 multfact.denominator =
114 (amplDen.ptr !=
nullptr) ? _graph->getMultFactor(amplDen, ancestorAmplDen, get<1>(ancestor)) : 1.;
116 _multPSFactors.insert({elem.first, multfact});
118 massfact.
numerator = _graph->getMassFactor(amplNum, elem.first, elem.second.daughterIdx);
119 massfact.denominator = _graph->getMassFactor(amplDen, elem.first, elem.second.daughterIdx);
120 _massPSFactors.insert({elem.first, massfact});
125 ProcRequirements::generatedAmplsMultsPS()
const {
126 vector<tuple<ParticleIndex, ParticleIndex, NumDenPair<AmplEntry>,
NumDenPair<double>, NumDenPair<double>>> res;
128 for(
auto& elem : _requiredAmplitudes){
129 auto corrmult = _multPSFactors.find(elem.first);
130 auto corrmass = _massPSFactors.find(elem.first);
131 tuple<ParticleIndex, ParticleIndex, NumDenPair<AmplEntry>, NumDenPair<double>, NumDenPair<double>> resTuple{elem.first, elem.second.daughterIdx, elem.second.amplitudes, corrmult->second, corrmass->second};
132 res.push_back(resTuple);
137 void ProcRequirements::getFormFactors() {
138 _requiredFormFactors.clear();
139 _denominatorFFEigenVectors.clear();
140 for(
auto& elem : _requiredAmplitudes) {
141 AmplitudeBase* ampNum = elem.second.amplitudes.numerator.ptr;
142 AmplitudeBase* ampDen = elem.second.amplitudes.denominator.ptr;
143 if (ampNum ==
nullptr && ampDen ==
nullptr)
continue;
145 auto ffs = _dictionaries->providers().getFormFactor(ffId);
147 auto res = _requiredFormFactors.insert({elem.first, map<FFIndex, FormFactorBase*>{}});
149 auto indices = _dictionaries->schemeDefs().getFormFactorIndices(ffId);
150 auto denidx = _dictionaries->schemeDefs().getDenominatorFormFactor(ffId);
151 for(
auto elem2: indices) {
152 res.first->second.insert({elem2, ffs[elem2]});
153 if(elem2 == denidx) {
156 auto tffeptr = _dictionaries->externalData().getFFEigenVectors(pff,
"Denominator");
157 if (tffeptr && tffeptr->rank() > 0) {
158 Tensor tfferr{
"", {{tffeptr,
false}, {tffeptr,
false}}};
159 _denominatorFFEigenVectors.push_back(move(tfferr));
169 void ProcRequirements::getRates() {
170 for (
auto& elem: _graph->assignedVertices()){
171 vector<PdgId> daughterPdgs;
172 auto daughters = _inputs->getDaughters(elem);
173 transform(daughters.begin(), daughters.end(), back_inserter(daughterPdgs), [](
Particle P){
return P.pdgId(); });
175 auto parentPdg = _inputs->getParticle(elem).pdgId();
177 auto rate = _dictionaries->providers().getRate(parentPdg, daughterPdgs);
178 if (rate !=
nullptr){
179 _requiredRates.insert({elem, rate});
180 _rateIds.insert({elem,
id});
182 auto pw = _dictionaries->providers().getPartialWidth(parentPdg, daughterPdgs);
184 _requiredPWs.insert({elem, pw});
185 _rateIds.insert({elem,
id});
187 MSG_WARNING(
"No rate or partial width found for vertex with parent pdg " +
188 to_string(parentPdg) +
189 ". Check rate classes, and/or widths and branching fractions are defined.");
196 return _requiredAmplitudes;
200 return _requiredRates;
204 return _requiredFormFactors;
207 const std::vector<Tensor>& ProcRequirements::denominatorWilsonCoeffs()
const {
208 return _denominatorWilsonCoeffs;
211 const std::vector<Tensor>& ProcRequirements::denominatorFFEigenVectors()
const {
212 return _denominatorFFEigenVectors;
215 const std::vector<Tensor>& ProcRequirements::specializedWilsonCoeffs()
const {
216 return _specializedWilsonCoeffs;
228 double ProcRequirements::calcCorrectionFactor(
WTerm what)
const {
230 for(
auto& elem: _multPSFactors) {
231 factor *= elem.second.get(what);
233 for(
auto& elem: _massPSFactors) {
234 factor *= elem.second.get(what);
239 Log& ProcRequirements::getLog()
const {
240 return Log::getLog(
"Hammer.ProcRequirements");
PDG codes to UID functions.
Base class for amplitudes.
std::vector< PdgId > combineDaughters(const std::vector< PdgId > &daughters, const std::vector< PdgId > &subDaughters)
combine list of codes of daughters and grandaughters (for processes which parameterise two subsequent...
Container class for values of WC and FF vectors.
Container class for required ingredients for the process weight calculation.
Interface class for amplitudes, rates, FFs dictionary container.
Message logging routines.
Hammer base amplitude class.
Container class for process tree structure and its amplitudes associations.
Interface class for tensor container data structure.
HashId hadronicId() const
returns the hadronic unique ID (parent + hadronic daughters) of the current decay signature ...
Multidimensional tensor class with complex numbers as elements.
std::map< ParticleIndex, T > VertexDict
Container class for Scheme Definitions.
HashId processID(PdgId parent, const std::vector< PdgId > &allDaughters)
compute a unique ID for a given process based on the PDG codes of the parent particle and the ordered...
Global container class for amplitudes, rates, FFs, data.