1 #include <goofit/Error.h>
2 #include <goofit/Log.h>
3 #include <goofit/PDFs/combine/EventWeightedAddPdf.h>
7 __device__ fptype device_EventWeightedAddPdfs(fptype *evt, fptype *p, unsigned int *indices) {
8 int numParameters = RO_CACHE(indices[0]);
10 fptype totalWeight = 0;
12 for(int i = 0; i < numParameters / 2 - 1; ++i) {
13 fptype weight = RO_CACHE(evt[RO_CACHE(indices[2 + numParameters + i])]);
14 totalWeight += weight;
15 fptype curr = callFunction(evt, RO_CACHE(indices[2 * i + 1]), RO_CACHE(indices[2 * (i + 1)]));
16 ret += weight * curr * normalisationFactors[RO_CACHE(indices[2 * (i + 1)])];
19 // numParameters does not count itself. So the array structure for two functions is
20 // nP | F P | F P | nO | o1
21 // in which nP = 4. and nO = 1. Therefore the parameter index for the last function pointer is nP, and the function
23 // fptype last = (*(reinterpret_cast<device_function_ptr>(device_function_table[indices[numParameters-1]])))(evt, p,
24 // paramIndices + indices[numParameters]);
25 fptype last = callFunction(evt, RO_CACHE(indices[numParameters - 1]), RO_CACHE(indices[numParameters]));
26 ret += (1 - totalWeight) * last * normalisationFactors[RO_CACHE(indices[numParameters])];
31 __device__ fptype device_EventWeightedAddPdfsExt(fptype *evt, fptype *p, unsigned int *indices) {
32 // numParameters does not count itself. So the array structure for two functions is
33 // nP | F P | F P | nO | o1 o2
34 // in which nP = 4, nO = 2.
36 int numParameters = RO_CACHE(indices[0]);
38 fptype totalWeight = 0;
40 for(int i = 0; i < numParameters / 2; ++i) {
41 fptype curr = callFunction(evt, RO_CACHE(indices[2 * i + 1]), RO_CACHE(indices[2 * (i + 1)]));
42 // if ((0 == BLOCKIDX) && (THREADIDX < 5) && (isnan(curr))) printf("NaN component %i %i\n", i, THREADIDX);
43 fptype weight = RO_CACHE(evt[RO_CACHE(indices[2 + numParameters + i])]);
44 ret += weight * curr * normalisationFactors[RO_CACHE(indices[2 * (i + 1)])];
45 totalWeight += weight;
47 // if ((gpuDebug & 1) && (0 == THREADIDX))
48 // if ((gpuDebug & 1) && (1 > evt[8]))
49 // if ((gpuDebug & 1) && (0 == THREADIDX) && (0 == BLOCKIDX))
50 // printf("EventWeightedExt: %i %f %f | %f %f %f %f %f %f %f\n", i, curr, weight, evt[0], evt[1], evt[2],
51 // evt[3], evt[4], evt[5], evt[6]);
52 // printf("EventWeightedExt: %i %f %f | %f %f \n", i, curr, weight, normalisationFactors[indices[2*(i+1)]], curr
53 // * normalisationFactors[indices[2*(i+1)]]);
54 // printf("EventWeightedExt: %i : %i %.10f %.10f %.10f %f %f %f\n", (int) floor(0.5 + evt[8]), i, curr, weight,
55 // ret, normalisationFactors[indices[2*(i+1)]], evt[6], evt[7]);
60 // if (0 >= ret) printf("Zero sum %f %f %f %f %f %f %f %f %f %f\n", evt[0], evt[1], evt[2], evt[3], evt[4], evt[5],
61 // evt[6], evt[7], evt[8], evt[9]);
66 __device__ device_function_ptr ptr_to_EventWeightedAddPdfs = device_EventWeightedAddPdfs;
67 __device__ device_function_ptr ptr_to_EventWeightedAddPdfsExt = device_EventWeightedAddPdfsExt;
69 EventWeightedAddPdf::EventWeightedAddPdf(std::string n, std::vector<Observable> weights, std::vector<PdfBase *> comps)
71 if(weights.size() != comps.size() && (weights.size() + 1) != comps.size())
72 throw GooFit::GeneralError("Size of weights {} (+1) != comps {}", weights.size(), comps.size());
74 // Indices stores (function index)(function parameter index) doublet for each component.
75 // Last component has no weight index unless function is extended. Notice that in this case, unlike
76 // AddPdf, weight indices are into the event, not the parameter vector, hence they
77 // are not added to the pindices array at this stage, although 'initialize' will reserve space
79 for(PdfBase *p : comps) {
80 GOOFIT_TRACE("EventWeighted component: {}", p->getName());
81 components.push_back(p);
82 if(components.back() == nullptr)
83 throw GooFit::GeneralError("Invalid component");
87 std::vector<unsigned int> pindices;
89 for(unsigned int w = 0; w < weights.size(); ++w) {
90 if(components[w] == nullptr)
91 throw GooFit::GeneralError("Invalid component");
92 pindices.push_back(components[w]->getFunctionIndex());
93 pindices.push_back(components[w]->getParameterIndex());
94 registerObservable(weights[w]);
97 if(components.back() == nullptr)
98 throw GooFit::GeneralError("Invalid component");
100 if(weights.size() < components.size()) {
101 pindices.push_back(components.back()->getFunctionIndex());
102 pindices.push_back(components.back()->getParameterIndex());
106 // This must occur after registering weights, or the indices will be off - the device functions assume that the
107 // weights are first.
108 observables = getObservables();
111 GET_FUNCTION_ADDR(ptr_to_EventWeightedAddPdfsExt);
113 GET_FUNCTION_ADDR(ptr_to_EventWeightedAddPdfs);
116 initialize(pindices);
119 __host__ fptype EventWeightedAddPdf::normalize() const {
120 // if (cpuDebug & 1) std::cout << "Normalising EventWeightedAddPdf " << getName() << " " << components.size() <<
123 // Here the PDFs have per-event weights, so there is no per-PDF weight
124 // to keep track of. All we can do is normalize the components.
125 for(PdfBase *comp : components)
128 host_normalisation[parameters] = 1.0;
133 } // namespace GooFit