1 #include <goofit/PDFs/detail/ComplexUtils.h>
2 #include <goofit/PDFs/physics/DalitzPlotHelpers.h>
3 #include <goofit/PDFs/physics/ResonancePdf.h>
7 __device__ fptype cDeriatives[2 * MAXNKNOBS];
9 __device__ fptype twoBodyCMmom(double rMassSq, fptype d1m, fptype d2m) {
10 // For A -> B + C, calculate momentum of B and C in rest frame of A.
13 fptype kin1 = 1 - POW2(d1m + d2m) / rMassSq;
15 kin1 = kin1 >= 0 ? sqrt(kin1) : 1;
17 fptype kin2 = 1 - POW2(d1m - d2m) / rMassSq;
18 kin2 = kin2 >= 0 ? sqrt(kin2) : 1;
20 return 0.5 * sqrt(rMassSq) * kin1 * kin2;
23 __device__ fptype dampingFactorSquare(const fptype &cmmom, const int &spin, const fptype &mRadius) {
24 fptype square = mRadius * mRadius * cmmom * cmmom;
25 fptype dfsq = 1 + square; // This accounts for spin 1
26 // if (2 == spin) dfsq += 8 + 2*square + square*square; // Coefficients are 9, 3, 1.
27 fptype dfsqres = dfsq + 8 + 2 * square + square * square;
29 // Spin 3 and up not accounted for.
31 return (spin == 2) ? dfsqres : dfsq;
34 __device__ fptype spinFactor(unsigned int spin,
42 unsigned int cyclic_index) {
44 return 1; // Should not cause branching since every thread evaluates the same resonance at the same time.
47 // Copied from BdkDMixDalitzAmp
49 fptype _mA = (PAIR_12 == cyclic_index ? daug1Mass : (PAIR_13 == cyclic_index ? daug1Mass : daug3Mass));
50 fptype _mB = (PAIR_12 == cyclic_index ? daug2Mass : (PAIR_13 == cyclic_index ? daug3Mass : daug3Mass));
51 fptype _mC = (PAIR_12 == cyclic_index ? daug3Mass : (PAIR_13 == cyclic_index ? daug2Mass : daug1Mass));
53 fptype _mAC = (PAIR_12 == cyclic_index ? m13 : (PAIR_13 == cyclic_index ? m12 : m12));
54 fptype _mBC = (PAIR_12 == cyclic_index ? m23 : (PAIR_13 == cyclic_index ? m23 : m13));
55 fptype _mAB = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
57 // The above, collapsed into single tests where possible.
58 fptype _mA = (PAIR_13 == cyclic_index ? daug3Mass : daug2Mass);
59 fptype _mB = (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass);
60 fptype _mC = (PAIR_12 == cyclic_index ? daug3Mass : (PAIR_13 == cyclic_index ? daug2Mass : daug1Mass));
62 fptype _mAC = (PAIR_23 == cyclic_index ? m13 : m23);
63 fptype _mBC = (PAIR_12 == cyclic_index ? m13 : m12);
64 fptype _mAB = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
67 // Copied from EvtDalitzReso, with assumption that pairAng convention matches pipipi0 from EvtD0mixDalitz.
68 // Again, all threads should get the same branch.
69 fptype _mA = (PAIR_12 == cyclic_index ? daug1Mass : (PAIR_13 == cyclic_index ? daug3Mass : daug2Mass));
70 fptype _mB = (PAIR_12 == cyclic_index ? daug2Mass : (PAIR_13 == cyclic_index ? daug1Mass : daug3Mass));
71 fptype _mC = (PAIR_12 == cyclic_index ? daug3Mass : (PAIR_13 == cyclic_index ? daug2Mass : daug1Mass));
72 fptype _mAC = (PAIR_12 == cyclic_index ? m13 : (PAIR_13 == cyclic_index ? m23 : m12));
73 fptype _mBC = (PAIR_12 == cyclic_index ? m23 : (PAIR_13 == cyclic_index ? m12 : m13));
74 fptype _mAB = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
76 fptype massFactor = 1.0 / _mAB;
78 sFactor *= ((_mBC - _mAC) + (massFactor * (motherMass * motherMass - _mC * _mC) * (_mA * _mA - _mB * _mB)));
82 fptype extraterm = ((_mAB - (2 * motherMass * motherMass) - (2 * _mC * _mC))
83 + massFactor * POW2(motherMass * motherMass - _mC * _mC));
84 extraterm *= ((_mAB - (2 * _mA * _mA) - (2 * _mB * _mB)) + massFactor * POW2(_mA * _mA - _mB * _mB));
93 __device__ fpcomplex plainBW(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
94 fptype motherMass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 0]);
95 fptype daug1Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 1]);
96 fptype daug2Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 2]);
97 fptype daug3Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 3]);
98 fptype meson_radius = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 4]);
100 fptype resmass = RO_CACHE(cudaArray[RO_CACHE(indices[2])]);
101 fptype reswidth = RO_CACHE(cudaArray[RO_CACHE(indices[3])]);
102 unsigned int spin = RO_CACHE(indices[4]);
103 unsigned int cyclic_index = RO_CACHE(indices[5]);
105 fpcomplex result{0.0, 0.0};
106 fptype resmass2 = POW2(resmass);
109 for(size_t i = 0; i < I; i++) {
110 fptype rMassSq = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
111 fptype mass_daug1 = (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass);
112 fptype mass_daug2 = (PAIR_12 == cyclic_index ? daug2Mass : daug3Mass);
116 // Calculate momentum of the two daughters in the resonance rest frame
117 // Note symmetry under interchange (dm1 <-> dm2)
119 fptype measureDaughterMoms = twoBodyCMmom(rMassSq, mass_daug1, mass_daug2);
120 fptype nominalDaughterMoms = twoBodyCMmom(resmass2, mass_daug1, mass_daug2);
123 frFactor = dampingFactorSquare(nominalDaughterMoms, spin, meson_radius)
124 / dampingFactorSquare(measureDaughterMoms, spin, meson_radius);
128 fptype A = (resmass2 - rMassSq);
129 fptype B = resmass2 * reswidth * pow(measureDaughterMoms / nominalDaughterMoms, 2.0 * spin + 1) * frFactor
131 fptype C = 1.0 / (POW2(A) + POW2(B));
133 fpcomplex ret(A * C, B * C); // Dropping F_D=1
135 ret *= sqrt(frFactor);
136 ret *= spinFactor(spin, motherMass, daug1Mass, daug2Mass, daug3Mass, m12, m13, m23, cyclic_index);
141 cyclic_index = cyclic_index + 1 % 3;
147 __device__ fpcomplex gaussian(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
148 // indices[1] is unused constant index, for consistency with other function types.
149 fptype resmass = RO_CACHE(cudaArray[RO_CACHE(indices[2])]);
150 fptype reswidth = RO_CACHE(cudaArray[RO_CACHE(indices[3])]);
151 unsigned int cyclic_index = indices[4];
153 // Notice sqrt - this function uses mass, not mass-squared like the other resonance types.
154 fptype massToUse = sqrt(PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
155 massToUse -= resmass;
156 massToUse /= reswidth;
157 massToUse *= massToUse;
158 fptype ret = exp(-0.5 * massToUse);
160 // Ignore factor 1/sqrt(2pi).
166 __device__ fptype hFun(double s, double daug2Mass, double daug3Mass) {
167 // Last helper function
168 const fptype _pi = 3.14159265359;
169 double sm = daug2Mass + daug3Mass;
170 double sqrt_s = sqrt(s);
171 double k_s = twoBodyCMmom(s, daug2Mass, daug3Mass);
173 return ((2 / _pi) * (k_s / sqrt_s) * log((sqrt_s + 2 * k_s) / (sm)));
176 __device__ fptype dh_dsFun(double s, double daug2Mass, double daug3Mass) {
177 // Yet another helper function
178 const fptype _pi = 3.14159265359;
179 double k_s = twoBodyCMmom(s, daug2Mass, daug3Mass);
181 return hFun(s, daug2Mass, daug3Mass) * (1.0 / (8.0 * POW2(k_s)) - 1.0 / (2.0 * s)) + 1.0 / (2.0 * _pi * s);
184 __device__ fptype dFun(double s, double daug2Mass, double daug3Mass) {
185 // Helper function used in Gronau-Sakurai
186 const fptype _pi = 3.14159265359;
187 double sm = daug2Mass + daug3Mass;
188 double sm24 = sm * sm / 4.0;
190 double k_m2 = twoBodyCMmom(s, daug2Mass, daug3Mass);
192 return 3.0 / _pi * sm24 / POW2(k_m2) * log((m + 2 * k_m2) / sm) + m / (2 * _pi * k_m2)
193 - sm24 * m / (_pi * POW3(k_m2));
196 __device__ fptype fsFun(double s, double m2, double gam, double daug2Mass, double daug3Mass) {
197 // Another G-S helper function
199 double k_s = twoBodyCMmom(s, daug2Mass, daug3Mass);
200 double k_Am2 = twoBodyCMmom(m2, daug2Mass, daug3Mass);
202 double f = gam * m2 / POW3(k_Am2);
203 f *= (POW2(k_s) * (hFun(s, daug2Mass, daug3Mass) - hFun(m2, daug2Mass, daug3Mass))
204 + (m2 - s) * POW2(k_Am2) * dh_dsFun(m2, daug2Mass, daug3Mass));
209 __device__ fpcomplex gouSak(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
210 fptype motherMass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 0]);
211 fptype daug1Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 1]);
212 fptype daug2Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 2]);
213 fptype daug3Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 3]);
214 fptype meson_radius = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 4]);
216 fptype resmass = RO_CACHE(cudaArray[RO_CACHE(indices[2])]);
217 fptype reswidth = RO_CACHE(cudaArray[RO_CACHE(indices[3])]);
218 unsigned int spin = RO_CACHE(indices[4]);
219 unsigned int cyclic_index = RO_CACHE(indices[5]);
221 fptype rMassSq = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
225 // Calculate momentum of the two daughters in the resonance rest frame; note symmetry under interchange (dm1 <->
227 fptype measureDaughterMoms = twoBodyCMmom(
228 rMassSq, (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass), (PAIR_12 == cyclic_index ? daug2Mass : daug3Mass));
229 fptype nominalDaughterMoms = twoBodyCMmom(
230 resmass, (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass), (PAIR_12 == cyclic_index ? daug2Mass : daug3Mass));
233 frFactor = dampingFactorSquare(nominalDaughterMoms, spin, meson_radius);
234 frFactor /= dampingFactorSquare(measureDaughterMoms, spin, meson_radius);
237 // Implement Gou-Sak:
239 fptype D = (1.0 + dFun(resmass, daug2Mass, daug3Mass) * reswidth / sqrt(resmass));
240 fptype E = resmass - rMassSq + fsFun(rMassSq, resmass, reswidth, daug2Mass, daug3Mass);
241 fptype F = sqrt(resmass) * reswidth * pow(measureDaughterMoms / nominalDaughterMoms, 2.0 * spin + 1) * frFactor;
243 D /= (E * E + F * F);
244 fpcomplex retur(D * E, D * F); // Dropping F_D=1
245 retur *= sqrt(frFactor);
246 retur *= spinFactor(spin, motherMass, daug1Mass, daug2Mass, daug3Mass, m12, m13, m23, cyclic_index);
251 __device__ fpcomplex lass(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
252 fptype motherMass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 0]);
253 fptype daug1Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 1]);
254 fptype daug2Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 2]);
255 fptype daug3Mass = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 3]);
256 fptype meson_radius = RO_CACHE(functorConstants[RO_CACHE(indices[1]) + 4]);
258 fptype resmass = RO_CACHE(cudaArray[RO_CACHE(indices[2])]);
259 fptype reswidth = RO_CACHE(cudaArray[RO_CACHE(indices[3])]);
260 unsigned int spin = RO_CACHE(indices[4]);
261 unsigned int cyclic_index = RO_CACHE(indices[5]);
263 fptype rMassSq = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
267 // Calculate momentum of the two daughters in the resonance rest frame; note symmetry under interchange (dm1 <->
270 fptype measureDaughterMoms = twoBodyCMmom(
271 rMassSq, (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass), (PAIR_23 == cyclic_index ? daug3Mass : daug2Mass));
272 fptype nominalDaughterMoms = twoBodyCMmom(
273 resmass, (PAIR_23 == cyclic_index ? daug2Mass : daug1Mass), (PAIR_23 == cyclic_index ? daug3Mass : daug2Mass));
276 frFactor = dampingFactorSquare(nominalDaughterMoms, spin, meson_radius);
277 frFactor /= dampingFactorSquare(measureDaughterMoms, spin, meson_radius);
282 fptype s = kinematics(m12, m13, _trackinfo[i]);
283 fptype q = twoBodyCMmom(s, _trackinfo[i]);
284 fptype m0 = _massRes[i]->getValFast();
285 fptype _g0 = _gammaRes[i]->getValFast();
286 int spin = _spinRes[i];
287 fptype g = runningWidthFast(s, m0, _g0, spin, _trackinfo[i], FrEval(s, m0, _trackinfo[i], spin));
290 fptype q = measureDaughterMoms;
291 fptype g = reswidth * pow(measureDaughterMoms / nominalDaughterMoms, 2.0 * spin + 1) * frFactor / sqrt(rMassSq);
296 fptype _phiR = 1.10644;
297 fptype _B = 0.614463;
298 fptype _phiB = -0.0981907;
300 // background phase motion
301 fptype cot_deltaB = (1.0 / (_a * q)) + 0.5 * _r * q;
302 fptype qcot_deltaB = (1.0 / _a) + 0.5 * _r * q * q;
304 // calculate resonant part
305 fpcomplex expi2deltaB = fpcomplex(qcot_deltaB, q) / fpcomplex(qcot_deltaB, -q);
306 fpcomplex resT = fpcomplex(cos(_phiR + 2 * _phiB), sin(_phiR + 2 * _phiB)) * _R;
308 fpcomplex prop = fpcomplex(1, 0) / fpcomplex(resmass - rMassSq, sqrt(resmass) * g);
309 // resT *= prop*m0*_g0*m0/twoBodyCMmom(m0*m0, _trackinfo[i])*expi2deltaB;
310 resT *= prop * (resmass * reswidth / nominalDaughterMoms) * expi2deltaB;
312 // calculate bkg part
313 resT += fpcomplex(cos(_phiB), sin(_phiB)) * _B * (cos(_phiB) + cot_deltaB * sin(_phiB)) * sqrt(rMassSq)
314 / fpcomplex(qcot_deltaB, -q);
316 resT *= sqrt(frFactor);
317 resT *= spinFactor(spin, motherMass, daug1Mass, daug2Mass, daug3Mass, m12, m13, m23, cyclic_index);
322 __device__ fpcomplex nonres(fptype m12, fptype m13, fptype m23, unsigned int *indices) { return {1., 0.}; }
325 getAmplitudeCoefficients(fpcomplex a1, fpcomplex a2, fptype &a1sq, fptype &a2sq, fptype &a1a2real, fptype &a1a2imag) {
326 // Returns A_1^2, A_2^2, real and imaginary parts of A_1A_2^*
327 a1sq = thrust::norm(a1);
328 a2sq = thrust::norm(a2);
330 a1a2real = a1.real();
331 a1a2imag = a1.imag();
334 __device__ fpcomplex flatte(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
335 // indices[1] is unused constant index, for consistency with other function types.
336 fptype resmass = cudaArray[indices[2]];
337 fptype g1 = cudaArray[indices[3]];
338 fptype g2 = cudaArray[indices[4]] * g1;
339 unsigned int cyclic_index = indices[5];
340 unsigned int doSwap = indices[6];
342 fptype pipmass = 0.13957018;
343 fptype pi0mass = 0.1349766;
344 fptype kpmass = 0.493677;
345 fptype k0mass = 0.497614;
347 fptype twopimasssq = 4 * pipmass * pipmass;
348 fptype twopi0masssq = 4 * pi0mass * pi0mass;
349 fptype twokmasssq = 4 * kpmass * kpmass;
350 fptype twok0masssq = 4 * k0mass * k0mass;
352 fpcomplex ret(0., 0.);
353 for(int i = 0; i < 1 + doSwap; i++) {
354 fptype rhopipi_real = 0, rhopipi_imag = 0;
355 fptype rhokk_real = 0, rhokk_imag = 0;
357 fptype s = (PAIR_12 == cyclic_index ? m12 : (PAIR_13 == cyclic_index ? m13 : m23));
360 rhopipi_real += (2. / 3) * sqrt(1 - twopimasssq / s); // Above pi+pi- threshold
362 rhopipi_imag += (2. / 3) * sqrt(-1 + twopimasssq / s);
363 if(s >= twopi0masssq)
364 rhopipi_real += (1. / 3) * sqrt(1 - twopi0masssq / s); // Above pi0pi0 threshold
366 rhopipi_imag += (1. / 3) * sqrt(-1 + twopi0masssq / s);
368 rhokk_real += 0.5 * sqrt(1 - twokmasssq / s); // Above K+K- threshold
370 rhokk_imag += 0.5 * sqrt(-1 + twokmasssq / s);
372 rhokk_real += 0.5 * sqrt(1 - twok0masssq / s); // Above K0K0 threshold
374 rhokk_imag += 0.5 * sqrt(-1 + twok0masssq / s);
375 fptype A = (resmass * resmass - s) + resmass * (rhopipi_imag * g1 + rhokk_imag * g2);
376 fptype B = resmass * (rhopipi_real * g1 + rhokk_real * g2);
377 fptype C = 1.0 / (A * A + B * B);
378 fpcomplex retur(A * C, B * C);
381 fptype swpmass = m12;
390 __device__ fpcomplex cubicspline(fptype m12, fptype m13, fptype m23, unsigned int *indices) {
392 unsigned int cyclic_index = indices[2];
393 unsigned int doSwap = indices[3];
394 const unsigned int nKnobs = indices[4];
395 unsigned int idx = 5; // Next index
397 const unsigned int pwa_coefs_idx = idx;
399 const fptype *mKKlimits = &(functorConstants[indices[idx]]);
400 fptype mAB = m12, mAC = m13;
401 switch(cyclic_index) {
412 int khiAB = 0, khiAC = 0;
413 fptype dmKK, aa, bb, aa3, bb3;
414 unsigned int timestorun = 1 + doSwap;
415 while(khiAB < nKnobs) {
416 if(mAB < mKKlimits[khiAB])
421 if(khiAB <= 0 || khiAB == nKnobs)
423 while(khiAC < nKnobs) {
424 if(mAC < mKKlimits[khiAC])
429 if(khiAC <= 0 || khiAC == nKnobs)
432 for(i = 0; i < timestorun; i++) {
433 unsigned int kloAB = khiAB - 1; //, kloAC = khiAC -1;
434 unsigned int twokloAB = kloAB + kloAB;
435 unsigned int twokhiAB = khiAB + khiAB;
436 fptype pwa_coefs_real_kloAB = cudaArray[indices[pwa_coefs_idx + twokloAB]];
437 fptype pwa_coefs_real_khiAB = cudaArray[indices[pwa_coefs_idx + twokhiAB]];
438 fptype pwa_coefs_imag_kloAB = cudaArray[indices[pwa_coefs_idx + twokloAB + 1]];
439 fptype pwa_coefs_imag_khiAB = cudaArray[indices[pwa_coefs_idx + twokhiAB + 1]];
440 fptype pwa_coefs_prime_real_kloAB = cDeriatives[twokloAB];
441 fptype pwa_coefs_prime_real_khiAB = cDeriatives[twokhiAB];
442 fptype pwa_coefs_prime_imag_kloAB = cDeriatives[twokloAB + 1];
443 fptype pwa_coefs_prime_imag_khiAB = cDeriatives[twokhiAB + 1];
444 // printf("m12: %f: %f %f %f %f %f %f %d %d %d\n", mAB, mKKlimits[0], mKKlimits[nKnobs-1],
445 // pwa_coefs_real_khiAB, pwa_coefs_imag_khiAB, pwa_coefs_prime_real_khiAB, pwa_coefs_prime_imag_khiAB, khiAB,
446 // khiAC, timestorun );
448 dmKK = mKKlimits[khiAB] - mKKlimits[kloAB];
449 aa = (mKKlimits[khiAB] - mAB) / dmKK;
453 // ret += aa * pwa_coefs[kloAB] + bb * pwa_coefs[khiAB] + ((aa3 - aa)*pwa_coefs_prime[kloAB] + (bb3 - bb) *
454 // pwa_coefs_prime[khiAB]) * (dmKK*dmKK)/6.0;
455 ret.real(ret.real() + aa * pwa_coefs_real_kloAB + bb * pwa_coefs_real_khiAB
456 + ((aa3 - aa) * pwa_coefs_prime_real_kloAB + (bb3 - bb) * pwa_coefs_prime_real_khiAB) * (dmKK * dmKK)
458 ret.imag(ret.imag() + aa * pwa_coefs_imag_kloAB + bb * pwa_coefs_imag_khiAB
459 + ((aa3 - aa) * pwa_coefs_prime_imag_kloAB + (bb3 - bb) * pwa_coefs_prime_imag_khiAB) * (dmKK * dmKK)
467 __device__ resonance_function_ptr ptr_to_RBW = plainBW<1>;
468 __device__ resonance_function_ptr ptr_to_RBW_Sym = plainBW<2>;
469 __device__ resonance_function_ptr ptr_to_GOUSAK = gouSak;
470 __device__ resonance_function_ptr ptr_to_GAUSSIAN = gaussian;
471 __device__ resonance_function_ptr ptr_to_NONRES = nonres;
472 __device__ resonance_function_ptr ptr_to_LASS = lass;
473 __device__ resonance_function_ptr ptr_to_FLATTE = flatte;
474 __device__ resonance_function_ptr ptr_to_SPLINE = cubicspline;
476 namespace Resonances {
478 RBW::RBW(std::string name,
486 : ResonancePdf(name, ar, ai) {
487 pindices.push_back(registerParameter(mass));
488 pindices.push_back(registerParameter(width));
489 pindices.push_back(sp);
490 pindices.push_back(cyc);
493 GET_FUNCTION_ADDR(ptr_to_RBW_Sym);
495 GET_FUNCTION_ADDR(ptr_to_RBW);
498 initialize(pindices);
501 GS::GS(std::string name, Variable ar, Variable ai, Variable mass, Variable width, unsigned int sp, unsigned int cyc)
502 : ResonancePdf(name, ar, ai) {
503 pindices.push_back(registerParameter(mass));
504 pindices.push_back(registerParameter(width));
505 pindices.push_back(sp);
506 pindices.push_back(cyc);
508 GET_FUNCTION_ADDR(ptr_to_GOUSAK);
510 initialize(pindices);
513 LASS::LASS(std::string name, Variable ar, Variable ai, Variable mass, Variable width, unsigned int sp, unsigned int cyc)
514 : ResonancePdf(name, ar, ai) {
515 pindices.push_back(registerParameter(mass));
516 pindices.push_back(registerParameter(width));
517 pindices.push_back(sp);
518 pindices.push_back(cyc);
520 GET_FUNCTION_ADDR(ptr_to_LASS);
522 initialize(pindices);
525 // Constructor for regular BW,Gounaris-Sakurai,LASS
526 Gauss::Gauss(std::string name, Variable ar, Variable ai, Variable mass, Variable width, unsigned int cyc)
527 : ResonancePdf(name, ar, ai) {
528 // Making room for index of decay-related constants. Assumption:
529 // These are mother mass and three daughter masses in that order.
530 // They will be registered by the object that uses this resonance,
531 // which will tell this object where to find them by calling setConstantIndex.
533 std::vector<unsigned int> pindices;
534 pindices.push_back(0);
535 pindices.push_back(registerParameter(mass));
536 pindices.push_back(registerParameter(width));
537 pindices.push_back(cyc);
539 GET_FUNCTION_ADDR(ptr_to_GAUSSIAN);
541 initialize(pindices);
544 NonRes::NonRes(std::string name, Variable ar, Variable ai)
545 : ResonancePdf(name, ar, ai) {
546 GET_FUNCTION_ADDR(ptr_to_NONRES);
548 initialize(pindices);
551 FLATTE::FLATTE(std::string name,
559 : ResonancePdf(name, ar, ai) {
560 pindices.push_back(registerParameter(mean));
561 pindices.push_back(registerParameter(g1));
562 pindices.push_back(registerParameter(rg2og1));
563 pindices.push_back(cyc);
564 pindices.push_back((unsigned int)symmDP);
566 GET_FUNCTION_ADDR(ptr_to_FLATTE);
568 initialize(pindices);
571 Spline::Spline(std::string name,
574 std::vector<fptype> &HH_bin_limits,
575 std::vector<Variable> &pwa_coefs_reals,
576 std::vector<Variable> &pwa_coefs_imags,
579 : ResonancePdf(name, ar, ai) {
580 std::vector<unsigned int> pindices;
581 const unsigned int nKnobs = HH_bin_limits.size();
582 host_constants.resize(nKnobs);
584 pindices.push_back(0);
585 pindices.push_back(cyc);
586 pindices.push_back((unsigned int)symmDP);
587 pindices.push_back(nKnobs);
589 for(int i = 0; i < pwa_coefs_reals.size(); i++) {
590 host_constants[i] = HH_bin_limits[i];
591 pindices.push_back(registerParameter(pwa_coefs_reals[i]));
592 pindices.push_back(registerParameter(pwa_coefs_imags[i]));
594 pindices.push_back(registerConstants(nKnobs));
596 MEMCPY_TO_SYMBOL(functorConstants,
597 host_constants.data(),
598 nKnobs * sizeof(fptype),
599 cIndex * sizeof(fptype),
600 cudaMemcpyHostToDevice);
602 GET_FUNCTION_ADDR(ptr_to_SPLINE);
604 initialize(pindices);
607 __host__ void Spline::recalculateCache() const {
608 auto params = getParameters();
609 const unsigned nKnobs = params.size() / 2;
610 std::vector<fpcomplex> y(nKnobs);
612 for(auto v = params.begin(); v != params.end(); ++v, ++i) {
613 unsigned int idx = i / 2;
614 fptype value = host_params[v->getIndex()];
620 std::vector<fptype> y2_flat = flatten(complex_derivative(host_constants, y));
622 MEMCPY_TO_SYMBOL(cDeriatives, y2_flat.data(), 2 * nKnobs * sizeof(fptype), 0, cudaMemcpyHostToDevice);
625 } // namespace Resonances
627 } // namespace GooFit