laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauKMatrixPropagator.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2008 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
29 #include "LauKMatrixPropagator.hh"
30 
31 #include "LauComplex.hh"
32 #include "LauKinematics.hh"
33 #include "LauTextFileParser.hh"
34 
35 #include "TMath.h"
36 #include "TSystem.h"
37 
38 #include <cmath>
39 #include <cstdlib>
40 #include <fstream>
41 #include <iostream>
42 
43 using std::cerr;
44 using std::cout;
45 using std::endl;
46 
48  const TString& paramFile,
49  Int_t resPairAmpInt,
50  Int_t nChannels,
51  Int_t nPoles,
52  Int_t rowIndex ) :
53  name_( name ),
54  paramFileName_( paramFile ),
55  resPairAmpInt_( resPairAmpInt ),
56  index_( rowIndex - 1 ),
57  nChannels_( nChannels ),
58  nPoles_( nPoles )
59 {
60  // Constructor
61 
62  // Check that the index is OK
63  if ( index_ < 0 || index_ >= nChannels_ ) {
64  std::cerr << "ERROR in LauKMatrixPropagator constructor. The rowIndex, which is set to "
65  << rowIndex << ", must be between 1 and the number of channels " << nChannels_
66  << std::endl;
67  gSystem->Exit( EXIT_FAILURE );
68  }
69 
70  this->setParameters( paramFile );
71 }
72 
74 {
75  // Destructor
76  realProp_.Clear();
77  negImagProp_.Clear();
78  ScattKMatrix_.Clear();
79  ReRhoMatrix_.Clear();
80  ImRhoMatrix_.Clear();
81  GammaMatrix_.Clear();
82  ReTMatrix_.Clear();
83  ImTMatrix_.Clear();
84  IMatrix_.Clear();
85  zeroMatrix_.Clear();
86 }
87 
88 LauComplex LauKMatrixPropagator::getPropTerm( const Int_t channel ) const
89 {
90  // Get the (i,j) = (index_, channel) term of the propagator
91  // matrix. This allows us not to return the full propagator matrix.
92  Double_t realTerm = this->getRealPropTerm( channel );
93  Double_t imagTerm = this->getImagPropTerm( channel );
94 
95  LauComplex propTerm( realTerm, imagTerm );
96  return propTerm;
97 }
98 
99 Double_t LauKMatrixPropagator::getRealPropTerm( const Int_t channel ) const
100 {
101  // Get the real part of the (i,j) = (index_, channel) term of the propagator
102  // matrix. This allows us not to return the full propagator matrix.
103  if ( parametersSet_ == kFALSE ) {
104  return 0.0;
105  }
106 
107  Double_t propTerm = realProp_[index_][channel];
108  return propTerm;
109 }
110 
111 Double_t LauKMatrixPropagator::getImagPropTerm( const Int_t channel ) const
112 {
113  // Get the imaginary part of the (i,j) = (index_, channel) term of the propagator
114  // matrix. This allows us not to return the full propagator matrix.
115  if ( parametersSet_ == kFALSE ) {
116  return 0.0;
117  }
118 
119  Double_t imagTerm = -1.0 * negImagProp_[index_][channel];
120  return imagTerm;
121 }
122 
124 {
125  // Calculate the K-matrix propagator for the given s value.
126  // The K-matrix amplitude is given by
127  // T_i = sum_{ij} (I - iK*rho)^-1 * P_j, where P is the production K-matrix.
128  // i = index for the state (e.g. S-wave index = 0).
129  // Here, we only find the (I - iK*rho)^-1 matrix part.
130 
131  // Check if we have almost the same s value as before. If so, don't re-calculate
132  // the propagator nor any of the pole mass summation terms.
133  if ( TMath::Abs( s - previousS_ ) < 1e-6 * s ) {
134  //cout<<"Already got propagator for s = "<<s<<endl;
135  return;
136  }
137 
138  if ( parametersSet_ == kFALSE ) {
139  //cerr<<"ERROR in LauKMatrixPropagator::updatePropagator. Parameters have not been set."<<endl;
140  return;
141  }
142 
143  // Calculate the denominator pole mass terms and Adler zero factor
144  this->calcPoleDenomVect( s );
145  this->updateAdlerZeroFactor( s );
146 
147  // Calculate the scattering K-matrix (real and symmetric)
148  this->calcScattKMatrix( s );
149  // Calculate the phase space density matrix, which is diagonal, but can be complex
150  // if the quantity s is below various threshold values (analytic continuation).
151  this->calcRhoMatrix( s );
152 
153  // Calculate the angular momentum barrier matrix, which is real and diagonal
154  this->calcGammaMatrix( s );
155 
156  // Calculate K*rho*(gamma^2) (real and imaginary parts, since rho can be complex)
157  TMatrixD GammaMatrixSq = ( GammaMatrix_ * GammaMatrix_ );
158  TMatrixD K_realRhoGammaSq( ScattKMatrix_ );
159 
160  K_realRhoGammaSq *= ReRhoMatrix_;
161  K_realRhoGammaSq *= GammaMatrixSq;
162  TMatrixD K_imagRhoGammaSq( ScattKMatrix_ );
163 
164  K_imagRhoGammaSq *= ImRhoMatrix_;
165  K_imagRhoGammaSq *= GammaMatrixSq;
166 
167  // A = I + K*Imag(rho)Gamma^2, B = -K*Real(Rho)Gamma^2
168  // Calculate C and D matrices such that (A + iB)*(C + iD) = I,
169  // ie. C + iD = (I - i K*rhoGamma^2)^-1, separated into real and imaginary parts.
170  // realProp C = (A + B A^-1 B)^-1, imagProp D = -A^-1 B C
171  TMatrixD A( IMatrix_ );
172  A += K_imagRhoGammaSq;
173  TMatrixD B( zeroMatrix_ );
174  B -= K_realRhoGammaSq;
175 
176  TMatrixD invA( TMatrixD::kInverted, A );
177  TMatrixD invA_B( invA );
178  invA_B *= B;
179  TMatrixD B_invA_B( B );
180  B_invA_B *= invA_B;
181 
182  TMatrixD invC( A );
183  invC += B_invA_B;
184  // Set the real part of the propagator matrix ("C")
185  realProp_ = TMatrixD( TMatrixD::kInverted, invC );
186 
187  // Set the (negative) imaginary part of the propagator matrix ("-D")
188  TMatrixD BC( B );
189  BC *= realProp_;
190  negImagProp_ = TMatrixD( invA );
191  negImagProp_ *= BC;
192 
193  // Pre-multiply by the Gamma matrix:
196 
197  if ( verbose_ ) {
198  std::cout << "In LauKMatrixPropagator::updatePropagator(s). D[1-iKrhoD^2]^-1: " << std::endl;
199  TString realOutput( "Real part:" ), imagOutput( "Imag part:" );
200  for ( int iChannel = 0; iChannel < nChannels_; iChannel++ ) {
201  for ( int jChannel = 0; jChannel < nChannels_; jChannel++ ) {
202  realOutput += Form( "\t%.6f", realProp_[iChannel][jChannel] );
203  imagOutput += Form( "\t%.6f", -1 * negImagProp_[iChannel][jChannel] );
204  }
205  realOutput += "\n ";
206  imagOutput += "\n ";
207  }
208  std::cout << realOutput << std::endl;
209  std::cout << imagOutput << std::endl;
210  }
211 
212  // Also calculate the production SVP term, since this uses Adler-zero parameters
213  // defined in the parameter file.
214  this->updateProdSVPTerm( s );
215 
216  // Finally, keep track of the value of s we just used.
217  previousS_ = s;
218 }
219 
220 void LauKMatrixPropagator::setParameters( const TString& inputFile )
221 {
222 
223  // Read an input file that specifies the values of the coupling constants g_i for
224  // the given number of poles and their (bare) masses. Also provided are the f_{ab}
225  // slow-varying constants. The input file should also provide the Adler zero
226  // constants s_0, s_A and s_A0.
227 
228  parametersSet_ = kFALSE;
229 
230  cout << "Initialising K-matrix propagator " << name_ << " parameters from " << inputFile.Data()
231  << endl;
232 
233  cout << "nChannels = " << nChannels_ << ", nPoles = " << nPoles_ << endl;
234 
235  // Initialise various matrices
236  this->initialiseMatrices();
237  std::vector<Int_t> a( nChannels_, 0 );
238 
239  // The format of the input file contains lines starting with a keyword followed by the
240  // appropriate set of parameters. Keywords are case insensitive (treated as lower-case).
241  // 1) Indices (nChannels) of N phase space channel types (defined in KMatrixChannels enum)
242  // "Channels iChannel1 iChannel2 ... iChannelN"
243  // 2) Definition of poles: bare mass (GeV), pole index (1 to NPoles), N channel couplings g_j
244  // "Pole poleIndex mass g_1 g_2 ... g_N"
245  // 3) Definition of scattering f_{ij} constants: scattering index (1 to N), channel values
246  // "Scatt index f_{i1} f_{i2} ... f_{iN}", where i = index
247  // 4) Orbital angular momentu for each channel. If not set here, defaults to 0
248  // "AngularMomentum L[0] L[1] ... L[N]"
249  // 5) Barrier factor parameter, which appears in the denominator and multiplies the term involving
250  // the nominal radius. If not set here, defaults to 0 or values appropriate to non-zero angular
251  // momenta as set in in (4) above.
252  // "BarrierFactorParameter a[0] a[1] ... a[N]"
253  // 6) Characteristic radius for each channel. If not set here, defaults to 3.0 GeV^{-1}
254  // "Radii radChannel1 radChannel2 ... radChannelN"
255  // 7) Various Adler zero and scattering constants; each line is "name value".
256  // Possible names are mSq0, s0Scatt, s0Prod, sA, sA0
257  //
258  // By default, the scattering constants are symmetrised: f_{ji} = f_{ij}.
259  // To not assume this use "ScattSymmetry 0" on a line
260 
261  LauTextFileParser readFile( inputFile );
262  readFile.processFile();
263 
264  // Loop over the (non-commented) lines
265  UInt_t nTotLines = readFile.getTotalNumLines();
266 
267  if ( nTotLines == 0 ) {
268  std::cerr << "ERROR in LauKMatrixPropagator::setParameters : K-matrix parameter file not present - exiting."
269  << std::endl;
270 
271  gSystem->Exit( EXIT_FAILURE );
272  }
273 
274  UInt_t iLine( 0 );
275 
276  for ( iLine = 1; iLine <= nTotLines; iLine++ ) {
277 
278  // Get the line of strings
279  std::vector<std::string> theLine = readFile.getLine( iLine );
280 
281  // There should always be at least two strings: a keyword and at least 1 value
282  if ( theLine.size() < 2 ) {
283  continue;
284  }
285 
286  TString keyword( theLine[0].c_str() );
287  keyword.ToLower(); // Use lowercase
288 
289  if ( ! keyword.CompareTo( "channels" ) ) {
290 
291  // Channel indices for phase-space factors
292  this->storeChannels( theLine );
293 
294  } else if ( ! keyword.CompareTo( "pole" ) ) {
295 
296  // Pole terms
297  this->storePole( theLine );
298 
299  } else if ( ! keyword.CompareTo( "scatt" ) ) {
300 
301  // Scattering terms
302  this->storeScattering( theLine );
303 
304  } else if ( ! keyword.CompareTo( "angularmomentum" ) ) {
305 
306  // Orbital angular momentum state for each channel & set default a values if called before storeBarrierFactorParameter
307  this->storeOrbitalAngularMomenta( theLine, a );
308 
309  } else if ( ! keyword.CompareTo( "barrierfactorparameter" ) ) {
310 
311  // Value of parameter "a" in denominator of centrifugal barrier factor, gamma
312  this->storeBarrierFactorParameter( theLine, a );
313 
314  } else if ( ! keyword.CompareTo( "radii" ) ) {
315 
316  // Values of characteristic radius
317  this->storeRadii( theLine );
318 
319  } else {
320 
321  // Usually Adler-zero constants
322  TString parString( theLine[1].c_str() );
323  this->storeParameter( keyword, parString );
324  }
325  }
326 
328 
329  // Symmetrise scattering parameters if enabled
330  if ( scattSymmetry_ == kTRUE ) {
331 
332  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
333 
334  for ( Int_t jChannel = iChannel; jChannel < nChannels_; jChannel++ ) {
335 
336  LauParameter fPar = fScattering_[iChannel][jChannel];
337  fScattering_[jChannel][iChannel] = LauParameter( fPar );
338  }
339  }
340  }
341 
342  // Now that radii and barrier-factor-denominator parameters have been set, cache the value of "a/(R*R)"
343  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
344  gamAInvRadSq_[iChannel] = a[iChannel] / ( radii_[iChannel] * radii_[iChannel] );
345  }
346 
347  // All required parameters have been set
348  parametersSet_ = kTRUE;
349 
350  cout << "Finished initialising K-matrix propagator " << name_ << endl;
351 }
352 
354 {
355 
356  // Identity and null matrices
357  IMatrix_.Clear();
358  IMatrix_.ResizeTo( nChannels_, nChannels_ );
359  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
360  IMatrix_[iChannel][iChannel] = 1.0;
361  }
362 
363  zeroMatrix_.Clear();
364  zeroMatrix_.ResizeTo( nChannels_, nChannels_ );
365 
366  // Real K matrix
367  ScattKMatrix_.Clear();
368  ScattKMatrix_.ResizeTo( nChannels_, nChannels_ );
369 
370  // Real and imaginary propagator matrices
371  realProp_.Clear();
372  negImagProp_.Clear();
373  realProp_.ResizeTo( nChannels_, nChannels_ );
374  negImagProp_.ResizeTo( nChannels_, nChannels_ );
375 
376  // Phase space matrices
377  ReRhoMatrix_.Clear();
378  ImRhoMatrix_.Clear();
379  ReRhoMatrix_.ResizeTo( nChannels_, nChannels_ );
380  ImRhoMatrix_.ResizeTo( nChannels_, nChannels_ );
381 
382  // Gamma matrices
383  GammaMatrix_.Clear();
384  GammaMatrix_.ResizeTo( nChannels_, nChannels_ );
385 
386  // Vector of orbital angular momenta for the channels (default is S-wave everywhere)
387  L_.clear();
388  L_.assign( nChannels_, 0 );
389 
390  // Characteristic radius (diagonal) vector (default to 3.0)
391  radii_.clear();
392  radii_.assign( nChannels_, 3.0 );
393 
394  // Vector to cache ratio a/R^2
395  gamAInvRadSq_.clear();
396  gamAInvRadSq_.resize( nChannels_ );
397 
398  // Square-root phase space matrices
399  ReSqrtRhoMatrix_.Clear();
400  ImSqrtRhoMatrix_.Clear();
403 
404  // T matrices
405  ReTMatrix_.Clear();
406  ImTMatrix_.Clear();
407  ReTMatrix_.ResizeTo( nChannels_, nChannels_ );
408  ImTMatrix_.ResizeTo( nChannels_, nChannels_ );
409 
410  // For the coupling and scattering constants, use LauParArrays instead of TMatrices
411  // so that the quantities remain LauParameters instead of just doubles.
412  // Each array is an stl vector of another stl vector of LauParameters:
413  // std::vector< std::vector<LauParameter> >.
414  // Set their sizes using the number of poles and channels defined in the constructor
415  gCouplings_.clear();
416  gCouplings_.resize( nPoles_ );
417 
418  for ( Int_t iPole = 0; iPole < nPoles_; iPole++ ) {
419  gCouplings_[iPole].resize( nChannels_ );
420  }
421 
422  fScattering_.clear();
423  fScattering_.resize( nChannels_ );
424 
425  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
426  fScattering_[iChannel].resize( nChannels_ );
427  }
428 
429  // Clear other vectors
430  phaseSpaceTypes_.clear();
431  phaseSpaceTypes_.resize( nChannels_ );
432 
433  mSqPoles_.clear();
434  mSqPoles_.resize( nPoles_ );
435 
437 }
438 
439 void LauKMatrixPropagator::storeChannels( const std::vector<std::string>& theLine )
440 {
441 
442  // Get the list of channel indices to specify what phase space factors should be used
443  // e.g. pipi, Kpi, eta eta', 4pi etc..
444 
445  // Check that the line has nChannels_+1 strings
446  Int_t nTypes = static_cast<Int_t>( theLine.size() ) - 1;
447  if ( nTypes != nChannels_ ) {
448  cerr << "Error in LauKMatrixPropagator::storeChannels. The input file defines " << nTypes
449  << " channels when " << nChannels_ << " are expected" << endl;
450  return;
451  }
452 
453  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
454 
455  Int_t phaseSpaceInt = std::atoi( theLine[iChannel + 1].c_str() );
456  Bool_t checkChannel = this->checkPhaseSpaceType( phaseSpaceInt );
457 
458  if ( checkChannel == kTRUE ) {
459  cout << "Adding phase space channel index " << phaseSpaceInt
460  << " to K-matrix propagator " << name_ << endl;
462  phaseSpaceInt );
463  } else {
464  cerr << "Phase space channel index " << phaseSpaceInt << " should be between 1 and "
465  << static_cast<int>( LauKMatrixPropagator::KMatrixChannels::TotChannels ) - 1
466  << endl;
467  }
468  }
469 }
470 
471 void LauKMatrixPropagator::storePole( const std::vector<std::string>& theLine )
472 {
473 
474  // Store the pole mass and its coupling constants for each channel.
475  // Each line will contain: Pole poleNumber poleMass poleCouplingsPerChannel
476 
477  // Check that the line has nChannels_ + 3 strings
478  Int_t nWords = static_cast<Int_t>( theLine.size() );
479  Int_t nExpect = nChannels_ + 3;
480 
481  if ( nWords == nExpect ) {
482 
483  Int_t poleIndex = std::atoi( theLine[1].c_str() ) - 1;
484  if ( poleIndex >= 0 && poleIndex < nPoles_ ) {
485 
486  Double_t poleMass = std::atof( theLine[2].c_str() );
487  Double_t poleMassSq = poleMass * poleMass;
488  LauParameter mPoleParam( Form( "KM_%s_poleMassSq_%i", name_.Data(), poleIndex ),
489  poleMassSq );
490  mSqPoles_[poleIndex] = mPoleParam;
491 
492  cout << "Added bare pole mass " << poleMass << " GeV for pole number " << poleIndex + 1
493  << endl;
494 
495  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
496 
497  Double_t couplingConst = std::atof( theLine[iChannel + 3].c_str() );
498  LauParameter couplingParam(
499  Form( "KM_%s_gCoupling_%i_%i", name_.Data(), poleIndex, iChannel ),
500  couplingConst );
501  gCouplings_[poleIndex][iChannel] = couplingParam;
502 
503  cout << "Added coupling parameter g^{" << poleIndex + 1 << "}_" << iChannel + 1
504  << " = " << couplingConst << endl;
505  }
506  }
507 
508  } else {
509 
510  cerr << "Error in LauKMatrixPropagator::storePole. Expecting " << nExpect
511  << " numbers for pole definition but found " << nWords << " values instead" << endl;
512  }
513 }
514 
515 void LauKMatrixPropagator::storeScattering( const std::vector<std::string>& theLine )
516 {
517 
518  // Store the scattering constants (along one of the channel rows).
519  // Each line will contain: Scatt ScattIndex ScattConstantsPerChannel
520 
521  // Check that the line has nChannels_ + 2 strings
522  Int_t nWords = static_cast<Int_t>( theLine.size() );
523  Int_t nExpect = nChannels_ + 2;
524 
525  if ( nWords == nExpect ) {
526 
527  Int_t scattIndex = std::atoi( theLine[1].c_str() ) - 1;
528  if ( scattIndex >= 0 && scattIndex < nChannels_ ) {
529 
530  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
531 
532  Double_t scattConst = std::atof( theLine[iChannel + 2].c_str() );
533  LauParameter scattParam(
534  Form( "KM_%s_fScatteringConst_%i_%i", name_.Data(), scattIndex, iChannel ),
535  scattConst );
536  fScattering_[scattIndex][iChannel] = scattParam;
537 
538  cout << "Added scattering parameter f(" << scattIndex + 1 << "," << iChannel + 1
539  << ") = " << scattConst << endl;
540  }
541  }
542 
543  } else {
544 
545  cerr << "Error in LauKMatrixPropagator::storeScattering. Expecting " << nExpect
546  << " numbers for scattering constants definition but found " << nWords
547  << " values instead" << endl;
548  }
549 }
550 
551 void LauKMatrixPropagator::storeOrbitalAngularMomenta( const std::vector<std::string>& theLine,
552  std::vector<Int_t>& a )
553 {
554 
555  // Store the orbital angular momentum for each channel
556  // Each line will contain: angularmomentum OrbitalAngularMomentumPerChannel
557 
558  // Check that the line has nChannels_ + 1 strings
559  Int_t nWords = static_cast<Int_t>( theLine.size() );
560  Int_t nExpect = nChannels_ + 1;
561 
562  if ( nWords == nExpect ) {
563 
564  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
565 
566  Int_t angularMomentum = std::atoi( theLine[iChannel + 1].c_str() );
567  L_[iChannel] = angularMomentum;
568 
569  cout << "Defined K-matrix orbital angular momentum " << angularMomentum
570  << " for channel " << iChannel << endl;
571  }
572 
573  } else {
574 
575  cerr << "Error in LauKMatrixPropagator::storeOrbitalAngularMomenta. Expecting " << nExpect
576  << " numbers for orbital angular momenta definition but found " << nWords
577  << " values instead" << endl;
578  }
579 
581  // Set default value of spin-dependent centrifugal-barrier-factor parameter
582  for ( Int_t iCh = 0; iCh < nChannels_; iCh++ ) {
583  switch ( L_[iCh] ) {
584  case 0 :
585  a[iCh] = 0;
586  break;
587  case 1 :
588  a[iCh] = 1;
589  break;
590  case 2 :
591  a[iCh] = 3;
592  break;
593  default :
594  std::cerr << "ERROR in LauKMatrixPropagator constructor. Centrifugal barrier factor and angular-momentum terms of K-matrix are only defined for S-, P-, or D-wave."
595  << std::endl;
596  gSystem->Exit( EXIT_FAILURE );
597  }
598  }
599  }
600 }
601 
602 void LauKMatrixPropagator::storeRadii( const std::vector<std::string>& theLine )
603 {
604 
605  // Store the characteristic radii (measured in GeV^{-1})
606  // Each line will contain: Radii RadiusConstantsPerChannel
607 
608  // Check that the line has nChannels_ + 1 strings
609  Int_t nWords = static_cast<Int_t>( theLine.size() );
610  Int_t nExpect = nChannels_ + 1;
611 
612  if ( nWords == nExpect ) {
613 
614  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
615 
616  Double_t radiusConst = std::atof( theLine[iChannel + 1].c_str() );
617  radii_[iChannel] = radiusConst;
618 
619  cout << "Added K-matrix radius " << radiusConst << " for channel " << iChannel << endl;
620  }
621 
622  } else {
623 
624  cerr << "Error in LauKMatrixPropagator::storeRadii. Expecting " << nExpect
625  << " numbers for radii definition but found " << nWords << " values instead" << endl;
626  }
627 }
628 
629 void LauKMatrixPropagator::storeBarrierFactorParameter( const std::vector<std::string>& theLine,
630  std::vector<Int_t>& a )
631 {
632 
633  // Store the parameter of the barrier factor
634  // Each line will contain: barrierfactorparameter ParameterValuePerchannel
635 
636  // Check that the line has nChannels_ + 1 strings
637  Int_t nWords = static_cast<Int_t>( theLine.size() );
638  Int_t nExpect = nChannels_ + 1;
639 
640  if ( nWords == nExpect ) {
641 
642  for ( Int_t iChannel = 0; iChannel < nChannels_; iChannel++ ) {
643 
644  Double_t parameterValue = std::atof( theLine[iChannel + 1].c_str() );
645  a[iChannel] = parameterValue;
646 
647  cout << "Added K-matrix barrier factor parameter value " << parameterValue
648  << " for channel " << iChannel << endl;
649  }
650 
651  // Set flag to stop storeOrbitalAngularMomenta overriding these a values
653 
654  } else {
655 
656  cerr << "Error in LauKMatrixPropagator::storeBarrierFactorParameter. Expecting " << nExpect
657  << " numbers for barrier factor parameter definition but found " << nWords
658  << " values instead" << endl;
659  }
660 }
661 
662 void LauKMatrixPropagator::storeParameter( const TString& keyword, const TString& parString )
663 {
664 
665  if ( ! keyword.CompareTo( "msq0" ) ) {
666 
667  Double_t mSq0Value = std::atof( parString.Data() );
668  cout << "Adler zero constant m0Sq = " << mSq0Value << endl;
669  mSq0_ = LauParameter( Form( "KM_%s_mSq0", name_.Data() ), mSq0Value );
670 
671  } else if ( ! keyword.CompareTo( "s0scatt" ) ) {
672 
673  Double_t s0ScattValue = std::atof( parString.Data() );
674  cout << "Adler zero constant s0Scatt = " << s0ScattValue << endl;
675  s0Scatt_ = LauParameter( Form( "KM_%s_s0Scatt", name_.Data() ), s0ScattValue );
676 
677  } else if ( ! keyword.CompareTo( "s0prod" ) ) {
678 
679  Double_t s0ProdValue = std::atof( parString.Data() );
680  cout << "Adler zero constant s0Prod = " << s0ProdValue << endl;
681  s0Prod_ = LauParameter( Form( "KM_%s_s0Prod", name_.Data() ), s0ProdValue );
682 
683  } else if ( ! keyword.CompareTo( "sa0" ) ) {
684 
685  Double_t sA0Value = std::atof( parString.Data() );
686  cout << "Adler zero constant sA0 = " << sA0Value << endl;
687  sA0_ = LauParameter( Form( "KM_%s_sA0", name_.Data() ), sA0Value );
688 
689  } else if ( ! keyword.CompareTo( "sa" ) ) {
690 
691  Double_t sAValue = std::atof( parString.Data() );
692  cout << "Adler zero constant sA = " << sAValue << endl;
693  sA_ = LauParameter( Form( "KM_%s_sA", name_.Data() ), sAValue );
694 
695  } else if ( ! keyword.CompareTo( "scattsymmetry" ) ) {
696 
697  Int_t flag = std::atoi( parString.Data() );
698  if ( flag == 0 ) {
699  cout << "Turning off scattering parameter symmetry: f_ji = f_ij will not be assumed"
700  << endl;
701  scattSymmetry_ = kFALSE;
702  }
703  }
704 }
705 
707 {
708 
709  // Calculate the scattering K-matrix for the given value of s.
710  // We need to obtain the complete matrix (not just one row/column)
711  // to get the correct inverted (I - i K rho) terms for the propagator.
712 
713  if ( verbose_ ) {
714  cout << "Within calcScattKMatrix for s = " << s << endl;
715  }
716 
717  // Initialise the K matrix to zero
718  ScattKMatrix_.Zero();
719 
720  Int_t iChannel( 0 ), jChannel( 0 ), iPole( 0 );
721 
722  // The pole denominator 1/(m^2 - s) terms should already be calculated
723  // by the calcPoleDenomVect() function. These same terms are also
724  // used for calculating the production K-matrix elements.
725 
726  // Calculate the "slowly-varying part" (SVP), e.g. (1 GeV - s0)/(s - s0)
727  this->updateScattSVPTerm( s );
728 
729  // Now loop over iChannel, jChannel to calculate Kij = Kji.
730  for ( iChannel = 0; iChannel < nChannels_; iChannel++ ) {
731 
732  // Scattering matrix is real and symmetric. Start j loop from i.
733  for ( jChannel = iChannel; jChannel < nChannels_; jChannel++ ) {
734 
735  Double_t Kij( 0.0 );
736 
737  // Calculate pole mass summation term
738  for ( iPole = 0; iPole < nPoles_; iPole++ ) {
739 
740  Double_t g_i = this->getCouplingConstant( iPole, iChannel );
741  Double_t g_j = this->getCouplingConstant( iPole, jChannel );
742 
743  Kij += poleDenomVect_[iPole] * g_i * g_j;
744  if ( verbose_ ) {
745  cout << "1: Kij for i = " << iChannel << ", j = " << jChannel << " = " << Kij
746  << endl;
747  }
748  }
749 
750  Double_t fij = this->getScatteringConstant( iChannel, jChannel );
751  Kij += fij * scattSVP_;
752 
753  Kij *= adlerZeroFactor_;
754  if ( verbose_ ) {
755  cout << "2: Kij for i = " << iChannel << ", j = " << jChannel << " = " << Kij << endl;
756  }
757 
758  // Assign the TMatrix (i,j) element to the variable Kij and Kji (symmetry)
759  ScattKMatrix_( iChannel, jChannel ) = Kij;
760  ScattKMatrix_( jChannel, iChannel ) = Kij;
761 
762  } // j loop
763 
764  } // i loop
765 }
766 
768 {
769  // Calculate the 1/(m_pole^2 - s) terms for the scattering
770  // and production K-matrix formulae.
771  poleDenomVect_.clear();
772  Int_t iPole( 0 );
773  for ( iPole = 0; iPole < nPoles_; iPole++ ) {
774 
775  Double_t poleTerm = mSqPoles_[iPole].unblindValue() - s;
776  Double_t invPoleTerm( 0.0 );
777  if ( TMath::Abs( poleTerm ) > 1.0e-6 ) {
778  invPoleTerm = 1.0 / poleTerm;
779  }
780 
781  poleDenomVect_.push_back( invPoleTerm );
782  }
783 }
784 
785 Double_t LauKMatrixPropagator::getPoleDenomTerm( const Int_t poleIndex ) const
786 {
787 
788  if ( parametersSet_ == kFALSE ) {
789  return 0.0;
790  }
791 
792  Double_t poleDenom( 0.0 );
793  poleDenom = poleDenomVect_[poleIndex];
794  return poleDenom;
795 }
796 
798 {
799  if ( ( parametersSet_ == kFALSE ) || ( poleIndex < 0 || poleIndex >= nPoles_ ) ) {
800  std::cerr << "ERROR from LauKMatrixPropagator::getPoleMassSqParameter(). Invalid pole."
801  << std::endl;
802  gSystem->Exit( EXIT_FAILURE );
803  }
804 
805  return mSqPoles_[poleIndex];
806 }
807 
808 Double_t LauKMatrixPropagator::getCouplingConstant( const Int_t poleIndex,
809  const Int_t channelIndex ) const
810 {
811 
812  if ( parametersSet_ == kFALSE ) {
813  return 0.0;
814  }
815  if ( poleIndex < 0 || poleIndex >= nPoles_ ) {
816  return 0.0;
817  }
818  if ( channelIndex < 0 || channelIndex >= nChannels_ ) {
819  return 0.0;
820  }
821 
822  Double_t couplingConst = gCouplings_[poleIndex][channelIndex].unblindValue();
823  return couplingConst;
824 }
825 
827  const Int_t channelIndex )
828 {
829 
830  if ( ( parametersSet_ == kFALSE ) || ( poleIndex < 0 || poleIndex >= nPoles_ ) ||
831  ( channelIndex < 0 || channelIndex >= nChannels_ ) ) {
832  std::cerr << "ERROR from LauKMatrixPropagator::getCouplingParameter(). Invalid coupling."
833  << std::endl;
834  gSystem->Exit( EXIT_FAILURE );
835  }
836 
837  //std::cout << "Minvalue + range for " << poleIndex << ", " << channelIndex << ": " << gCouplings_[poleIndex][channelIndex].minValue() << " => + " << gCouplings_[poleIndex][channelIndex].range() <<
838  // " and init value: " << gCouplings_[poleIndex][channelIndex].initValue() << std::endl;
839  return gCouplings_[poleIndex][channelIndex];
840 }
841 
842 Double_t LauKMatrixPropagator::getScatteringConstant( const Int_t channel1Index,
843  const Int_t channel2Index ) const
844 {
845 
846  if ( parametersSet_ == kFALSE ) {
847  return 0.0;
848  }
849  if ( channel1Index < 0 || channel1Index >= nChannels_ ) {
850  return 0.0;
851  }
852  if ( channel2Index < 0 || channel2Index >= nChannels_ ) {
853  return 0.0;
854  }
855 
856  Double_t scatteringConst = fScattering_[channel1Index][channel2Index].unblindValue();
857  return scatteringConst;
858 }
859 
861  const Int_t channel2Index )
862 {
863 
864  if ( ( parametersSet_ == kFALSE ) || ( channel1Index < 0 || channel1Index >= nChannels_ ) ||
865  ( channel2Index < 0 || channel2Index >= nChannels_ ) ) {
866  std::cerr << "ERROR from LauKMatrixPropagator::getScatteringParameter(). Invalid chanel index."
867  << std::endl;
868  gSystem->Exit( EXIT_FAILURE );
869  }
870 
871  return fScattering_[channel1Index][channel2Index];
872 }
873 
874 Double_t LauKMatrixPropagator::calcSVPTerm( const Double_t s, const Double_t s0 ) const
875 {
876 
877  if ( parametersSet_ == kFALSE ) {
878  return 0.0;
879  }
880 
881  // Calculate the "slowly-varying part" (SVP)
882  Double_t result( 0.0 );
883  Double_t deltaS = s - s0;
884  if ( TMath::Abs( deltaS ) > 1.0e-6 ) {
885  result = ( mSq0_.unblindValue() - s0 ) / deltaS;
886  }
887 
888  return result;
889 }
890 
892 {
893  // Update the scattering "slowly-varying part" (SVP)
894  Double_t s0Scatt = s0Scatt_.unblindValue();
895  scattSVP_ = this->calcSVPTerm( s, s0Scatt );
896 }
897 
899 {
900  // Update the production "slowly-varying part" (SVP)
901  Double_t s0Prod = s0Prod_.unblindValue();
902  prodSVP_ = this->calcSVPTerm( s, s0Prod );
903 }
904 
906 {
907 
908  // Calculate the multiplicative factor containing various Adler zero
909  // constants.
910  adlerZeroFactor_ = 0.0;
911 
912  Double_t sA0Val = sA0_.unblindValue();
913  Double_t deltaS = s - sA0Val;
914  if ( TMath::Abs( deltaS ) > 1e-6 ) {
915  adlerZeroFactor_ = ( s - sAConst_ ) * ( 1.0 - sA0Val ) / deltaS;
916  }
917 }
918 
920 {
921  // Calculate the gamma angular momentum barrier matrix
922  // for the given invariant mass squared quantity, s.
923 
924  // Initialise all entries to zero
925  GammaMatrix_.Zero();
926 
927  Double_t gamma( 0.0 );
928 
929  for ( Int_t iChannel( 0 ); iChannel < nChannels_; ++iChannel ) {
930 
931  if ( L_[iChannel] != 0 ) {
932  gamma = this->calcGamma( iChannel, s );
933  } else {
934  gamma = 1.0; // S-wave
935  }
936 
937  if ( verbose_ ) {
938  cout << "GammaMatrix(" << iChannel << ", " << iChannel << ") = " << gamma << endl;
939  }
940 
941  GammaMatrix_( iChannel, iChannel ) = gamma;
942  }
943 }
944 
945 Double_t LauKMatrixPropagator::calcGamma( const Int_t iCh, const Double_t s ) const
946 {
947  // Calculate the barrier factor
948  Double_t gamma( 0.0 );
949 
951 
952  LauComplex rho = getRho( s, phaseSpaceIndex );
953  Double_t q = 0.5 * sqrt( s ) * rho.abs();
954 
955  gamma = pow( q, L_[iCh] );
956  if ( includeBWBarrierFactor_ ) {
957  gamma /= pow( q * q + gamAInvRadSq_[iCh], L_[iCh] / 2. );
958  }
959 
960  if ( verbose_ ) {
961  std::cout << "In LauKMatrixPropagator::calcGamma(iCh=" << iCh << ", s=" << s << ", prop). ";
962  std::cout << "|q(iCh=" << iCh << ")|: " << q << std::endl;
963  }
964 
965  return gamma;
966 }
967 
968 void LauKMatrixPropagator::calcRhoMatrix( const Double_t s )
969 {
970 
971  // Calculate the real and imaginary part of the phase space density
972  // diagonal matrix for the given invariant mass squared quantity, s.
973  // The matrix can be complex if s is below threshold (so that
974  // the amplitude continues analytically).
975 
976  // Initialise all entries to zero
977  ReRhoMatrix_.Zero();
978  ImRhoMatrix_.Zero();
979 
980  for ( Int_t iChannel( 0 ); iChannel < nChannels_; ++iChannel ) {
981 
982  LauKMatrixPropagator::KMatrixChannels phaseSpaceIndex = phaseSpaceTypes_[iChannel];
983 
984  LauComplex rho = getRho( s, phaseSpaceIndex );
985 
986  if ( verbose_ ) {
987  cout << "ReRhoMatrix(" << iChannel << ", " << iChannel << ") = " << rho.re() << endl;
988  cout << "ImRhoMatrix(" << iChannel << ", " << iChannel << ") = " << rho.im() << endl;
989  }
990 
991  ReRhoMatrix_( iChannel, iChannel ) = rho.re();
992  ImRhoMatrix_( iChannel, iChannel ) = rho.im();
993  }
994 }
995 
997  const LauKMatrixPropagator::KMatrixChannels phaseSpaceIndex ) const
998 {
999  LauComplex rho( 0.0, 0.0 );
1000  switch ( phaseSpaceIndex ) {
1001  case LauKMatrixPropagator::KMatrixChannels::PiPi :
1002  rho = this->calcPiPiRho( s );
1003  break;
1004  case LauKMatrixPropagator::KMatrixChannels::KK :
1005  rho = this->calcKKRho( s );
1006  break;
1007  case LauKMatrixPropagator::KMatrixChannels::FourPi :
1008  rho = this->calcFourPiRho( s );
1009  break;
1010  case LauKMatrixPropagator::KMatrixChannels::EtaEta :
1011  rho = this->calcEtaEtaRho( s );
1012  break;
1013  case LauKMatrixPropagator::KMatrixChannels::EtaEtaP :
1014  rho = this->calcEtaEtaPRho( s );
1015  break;
1016  case LauKMatrixPropagator::KMatrixChannels::KPi :
1017  rho = this->calcKPiRho( s );
1018  break;
1019  case LauKMatrixPropagator::KMatrixChannels::KEtaP :
1020  rho = this->calcKEtaPRho( s );
1021  break;
1022  case LauKMatrixPropagator::KMatrixChannels::KThreePi :
1023  rho = this->calcKThreePiRho( s );
1024  break;
1025  case LauKMatrixPropagator::KMatrixChannels::D0K :
1026  rho = this->calcD0KRho( s );
1027  break;
1028  case LauKMatrixPropagator::KMatrixChannels::Dstar0K :
1029  rho = this->calcDstar0KRho( s );
1030  break;
1031  default :
1032  std::cerr << "ERROR in LauKMatrixPropagator::getRho(...). Phase-space index not recognised for this channel"
1033  << std::endl;
1034  gSystem->Exit( EXIT_FAILURE );
1035  }
1036  return rho;
1037 }
1038 
1040 {
1041  // Calculate the D0K+ phase space factor
1042  LauComplex rho( 0.0, 0.0 );
1043  if ( TMath::Abs( s ) < 1e-10 ) {
1044  return rho;
1045  }
1046 
1047  Double_t sqrtTerm1 = ( -mD0KSumSq_ / s ) + 1.0;
1048  Double_t sqrtTerm2 = ( -mD0KDiffSq_ / s ) + 1.0;
1049  Double_t sqrtTerm = sqrtTerm1 * sqrtTerm2;
1050  if ( sqrtTerm < 0.0 ) {
1051  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1052  } else {
1053  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1054  }
1055 
1056  return rho;
1057 }
1058 
1060 {
1061  // Calculate the Dstar0K+ phase space factor
1062  LauComplex rho( 0.0, 0.0 );
1063  if ( TMath::Abs( s ) < 1e-10 ) {
1064  return rho;
1065  }
1066 
1067  Double_t sqrtTerm1 = ( -mDstar0KSumSq_ / s ) + 1.0;
1068  Double_t sqrtTerm2 = ( -mDstar0KDiffSq_ / s ) + 1.0;
1069  Double_t sqrtTerm = sqrtTerm1 * sqrtTerm2;
1070  if ( sqrtTerm < 0.0 ) {
1071  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1072  } else {
1073  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1074  }
1075 
1076  return rho;
1077 }
1078 
1080 {
1081  // Calculate the pipi phase space factor
1082  LauComplex rho( 0.0, 0.0 );
1083  if ( TMath::Abs( s ) < 1e-10 ) {
1084  return rho;
1085  }
1086 
1087  Double_t sqrtTerm = ( -m2piSq_ / s ) + 1.0;
1088  if ( sqrtTerm < 0.0 ) {
1089  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1090  } else {
1091  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1092  }
1093 
1094  return rho;
1095 }
1096 
1098 {
1099  // Calculate the KK phase space factor
1100  LauComplex rho( 0.0, 0.0 );
1101  if ( TMath::Abs( s ) < 1e-10 ) {
1102  return rho;
1103  }
1104 
1105  Double_t sqrtTerm = ( -m2KSq_ / s ) + 1.0;
1106  if ( sqrtTerm < 0.0 ) {
1107  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1108  } else {
1109  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1110  }
1111 
1112  return rho;
1113 }
1114 
1116 {
1117  // Calculate the 4pi phase space factor. This uses a 6th-order polynomial
1118  // parameterisation that approximates the multi-body phase space double integral
1119  // defined in Eq 4 of the A&S paper hep-ph/0204328. This form agrees with the
1120  // BaBar model (another 6th order polynomial from s^4 down to 1/s^2), but avoids the
1121  // exponential increase at small values of s (~< 0.1) arising from 1/s and 1/s^2.
1122  // Eq 4 is evaluated for each value of s by assuming incremental steps of 1e-3 GeV^2
1123  // for s1 and s2, the invariant energy squared of each of the di-pion states,
1124  // with the integration limits of s1 = (2*mpi)^2 to (sqrt(s) - 2*mpi)^2 and
1125  // s2 = (2*mpi)^2 to (sqrt(s) - sqrt(s1))^2. The mass M of the rho is taken to be
1126  // 0.775 GeV and the energy-dependent width of the 4pi system
1127  // Gamma(s) = gamma_0*rho1^3(s), where rho1 = sqrt(1.0 - 4*mpiSq/s) and gamma_0 is
1128  // the "width" of the 4pi state at s = 1, which is taken to be 0.3 GeV
1129  // (~75% of the total width from PDG estimates of the f0(1370) -> 4pi state).
1130  // The normalisation term rho_0 is found by ensuring that the phase space integral
1131  // at s = 1 is equal to sqrt(1.0 - 16*mpiSq/s). Note that the exponent for this
1132  // factor in hep-ph/0204328 is wrong; it should be 0.5, i.e. sqrt, not n = 1 to 5.
1133  // Plotting the value of this double integral as a function of s can then be fitted
1134  // to a 6th-order polynomial (for s < 1), which is the result used below
1135 
1136  LauComplex rho( 0.0, 0.0 );
1137  if ( TMath::Abs( s ) < 1e-10 ) {
1138  return rho;
1139  }
1140 
1141  if ( s <= 1.0 ) {
1142  Double_t rhoTerm = ( ( 1.07885 * s + 0.13655 ) * s - 0.29744 ) * s - 0.20840;
1143  rhoTerm = ( ( rhoTerm * s + 0.13851 ) * s - 0.01933 ) * s + 0.00051;
1144  // For some values of s (below 2*mpi), this term is a very small
1145  // negative number. Check for this and set the rho term to zero.
1146  if ( rhoTerm < 0.0 ) {
1147  rhoTerm = 0.0;
1148  }
1149  rho.setRealPart( rhoTerm );
1150  } else {
1151  rho.setRealPart( TMath::Sqrt( 1.0 - ( fourPiFactor1_ / s ) ) );
1152  }
1153 
1154  return rho;
1155 }
1156 
1158 {
1159  // Calculate the eta-eta phase space factor
1160  LauComplex rho( 0.0, 0.0 );
1161  if ( TMath::Abs( s ) < 1e-10 ) {
1162  return rho;
1163  }
1164 
1165  Double_t sqrtTerm = ( -m2EtaSq_ / s ) + 1.0;
1166  if ( sqrtTerm < 0.0 ) {
1167  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1168  } else {
1169  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1170  }
1171 
1172  return rho;
1173 }
1174 
1176 {
1177  // Calculate the eta-eta' phase space factor. Note that the
1178  // mass difference term m_eta - m_eta' is not included,
1179  // since this corresponds to a "t or u-channel crossing",
1180  // which means that we cannot simply analytically continue
1181  // this part of the phase space factor below threshold, which
1182  // we can do for s-channel contributions. This is actually an
1183  // unsolved problem, e.g. see Guo et al 1409.8652, and
1184  // Danilkin et al 1409.7708. Anisovich and Sarantsev in
1185  // hep-ph/0204328 "solve" this issue by setting the mass
1186  // difference term to unity, which is what we do here...
1187 
1188  LauComplex rho( 0.0, 0.0 );
1189  if ( TMath::Abs( s ) < 1e-10 ) {
1190  return rho;
1191  }
1192 
1193  Double_t sqrtTerm = ( -mEtaEtaPSumSq_ / s ) + 1.0;
1194  if ( sqrtTerm < 0.0 ) {
1195  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1196  } else {
1197  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1198  }
1199 
1200  return rho;
1201 }
1202 
1204 {
1205  // Calculate the K-pi phase space factor
1206  LauComplex rho( 0.0, 0.0 );
1207  if ( TMath::Abs( s ) < 1e-10 ) {
1208  return rho;
1209  }
1210 
1211  Double_t sqrtTerm1 = ( -mKpiSumSq_ / s ) + 1.0;
1212  Double_t sqrtTerm2 = ( -mKpiDiffSq_ / s ) + 1.0;
1213  Double_t sqrtTerm = sqrtTerm1 * sqrtTerm2;
1214  if ( sqrtTerm < 0.0 ) {
1215  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1216  } else {
1217  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1218  }
1219 
1220  return rho;
1221 }
1222 
1224 {
1225  // Calculate the K-eta' phase space factor
1226  LauComplex rho( 0.0, 0.0 );
1227  if ( TMath::Abs( s ) < 1e-10 ) {
1228  return rho;
1229  }
1230 
1231  Double_t sqrtTerm1 = ( -mKEtaPSumSq_ / s ) + 1.0;
1232  Double_t sqrtTerm2 = ( -mKEtaPDiffSq_ / s ) + 1.0;
1233  Double_t sqrtTerm = sqrtTerm1 * sqrtTerm2;
1234  if ( sqrtTerm < 0.0 ) {
1235  rho.setImagPart( TMath::Sqrt( -sqrtTerm ) );
1236  } else {
1237  rho.setRealPart( TMath::Sqrt( sqrtTerm ) );
1238  }
1239 
1240  return rho;
1241 }
1242 
1244 {
1245  // Calculate the Kpipipi + multimeson phase space factor.
1246  // Use the simplest definition in hep-ph/9705401 (Eq 14), which is the form
1247  // used for the rest of that paper (thankfully, the amplitude does not depend
1248  // significantly on the form used for the K3pi phase space factor).
1249  LauComplex rho( 0.0, 0.0 );
1250  if ( TMath::Abs( s ) < 1e-10 ) {
1251  return rho;
1252  }
1253 
1254  if ( s < 1.44 ) {
1255 
1256  Double_t powerTerm = ( -mK3piDiffSq_ / s ) + 1.0;
1257  if ( powerTerm < 0.0 ) {
1258  rho.setImagPart( k3piFactor_ * TMath::Power( -powerTerm, 2.5 ) );
1259  } else {
1260  rho.setRealPart( k3piFactor_ * TMath::Power( powerTerm, 2.5 ) );
1261  }
1262 
1263  } else {
1264  rho.setRealPart( 1.0 );
1265  }
1266 
1267  return rho;
1268 }
1269 
1270 Bool_t LauKMatrixPropagator::checkPhaseSpaceType( const Int_t phaseSpaceInt ) const
1271 {
1272  Bool_t passed( kFALSE );
1273 
1274  if ( phaseSpaceInt >= 1 &&
1275  phaseSpaceInt < static_cast<Int_t>( LauKMatrixPropagator::KMatrixChannels::TotChannels ) ) {
1276  passed = kTRUE;
1277  }
1278 
1279  return passed;
1280 }
1281 
1282 LauComplex LauKMatrixPropagator::getTransitionAmp( const Double_t s, const Int_t channel )
1283 {
1284 
1285  // Get the complex (unitary) transition amplitude T for the given channel
1286  LauComplex TAmp( 0.0, 0.0 );
1287 
1288  if ( channel <= 0 || channel > nChannels_ ) {
1289  return TAmp;
1290  }
1291 
1292  this->getTMatrix( s );
1293 
1294  TAmp.setRealPart( ReTMatrix_[index_][channel - 1] );
1295  TAmp.setImagPart( ImTMatrix_[index_][channel - 1] );
1296 
1297  return TAmp;
1298 }
1299 
1300 LauComplex LauKMatrixPropagator::getPhaseSpaceTerm( const Double_t s, const Int_t channel )
1301 {
1302 
1303  // Get the complex (unitary) transition amplitude T for the given channel
1304  LauComplex rho( 0.0, 0.0 );
1305 
1306  if ( channel <= 0 || channel > nChannels_ ) {
1307  return rho;
1308  }
1309 
1310  // If s has changed from the previous value, recalculate rho
1311  if ( TMath::Abs( s - previousS_ ) > 1e-6 * s ) {
1312  this->calcRhoMatrix( s );
1313  }
1314 
1315  rho.setRealPart( ReRhoMatrix_[channel][channel - 1] );
1316  rho.setImagPart( ImRhoMatrix_[channel][channel - 1] );
1317 
1318  return rho;
1319 }
1320 
1322 {
1323 
1324  // Find the unitary T matrix, where T = [sqrt(rho)]^{*} T_hat sqrt(rho),
1325  // and T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix,
1326  // which has phase-space factors included (rho). This function is not
1327  // needed to calculate the K-matrix amplitudes, but allows us
1328  // to check the variation of T as a function of s (kinematics)
1329 
1330  if ( ! kinematics ) {
1331  return;
1332  }
1333 
1334  // Get the invariant mass squared (s) from the kinematics object.
1335  // Use the resPairAmpInt to find which mass-squared combination to use.
1336  Double_t s( 0.0 );
1337 
1338  if ( resPairAmpInt_ == 1 ) {
1339  s = kinematics->getm23Sq();
1340  } else if ( resPairAmpInt_ == 2 ) {
1341  s = kinematics->getm13Sq();
1342  } else if ( resPairAmpInt_ == 3 ) {
1343  s = kinematics->getm12Sq();
1344  }
1345 
1346  this->getTMatrix( s );
1347 }
1348 
1349 void LauKMatrixPropagator::getTMatrix( const Double_t s )
1350 {
1351 
1352  // Find the unitary transition T matrix, where
1353  // T = [sqrt(rho)]^{*} T_hat sqrt(rho), and
1354  // T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix,
1355  // which has phase-space factors included (rho). Note that the first
1356  // sqrt of the rho matrix is complex conjugated.
1357 
1358  // This function is not needed to calculate the K-matrix amplitudes, but
1359  // allows us to check the variation of T as a function of s (kinematics)
1360 
1361  // Initialse the real and imaginary parts of the T matrix to zero
1362  ReTMatrix_.Zero();
1363  ImTMatrix_.Zero();
1364 
1365  if ( parametersSet_ == kFALSE ) {
1366  return;
1367  }
1368 
1369  // Update K, rho and the propagator (I - i K rho)^-1
1370  this->updatePropagator( s );
1371 
1372  // Find the real and imaginary T_hat matrices
1373  TMatrixD THatReal = realProp_ * ScattKMatrix_;
1374  TMatrixD THatImag( zeroMatrix_ );
1375  THatImag -= negImagProp_ * ScattKMatrix_;
1376 
1377  // Find the square-root of the phase space matrix
1378  this->getSqrtRhoMatrix();
1379 
1380  // Let sqrt(rho) = A + iB and T_hat = C + iD
1381  // => T = A(CA-DB) + B(DA+CB) + i[A(DA+CB) + B(DB-CA)]
1382  TMatrixD CA( THatReal );
1383  CA *= ReSqrtRhoMatrix_;
1384  TMatrixD DA( THatImag );
1385  DA *= ReSqrtRhoMatrix_;
1386  TMatrixD CB( THatReal );
1387  CB *= ImSqrtRhoMatrix_;
1388  TMatrixD DB( THatImag );
1389  DB *= ImSqrtRhoMatrix_;
1390 
1391  TMatrixD CAmDB( CA );
1392  CAmDB -= DB;
1393  TMatrixD DApCB( DA );
1394  DApCB += CB;
1395  TMatrixD DBmCA( DB );
1396  DBmCA -= CA;
1397 
1398  // Find the real and imaginary parts of the transition matrix T
1399  ReTMatrix_ = ReSqrtRhoMatrix_ * CAmDB + ImSqrtRhoMatrix_ * DApCB;
1400  ImTMatrix_ = ReSqrtRhoMatrix_ * DApCB + ImSqrtRhoMatrix_ * DBmCA;
1401 }
1402 
1404 {
1405 
1406  // Find the square root of the (current) phase space matrix so that
1407  // we can find T = [sqrt(rho)}^{*} T_hat sqrt(rho), where T_hat is the
1408  // Lorentz-invariant T matrix = (I - i K rho)^-1 * K; note that the first
1409  // sqrt of rho matrix is complex conjugated
1410 
1411  // If rho = rho_i + i rho_r = a + i b, then sqrt(rho) = c + i d, where
1412  // c = sqrt(0.5*(r+a)) and d = sqrt(0.5(r-a)), where r = sqrt(a^2 + b^2).
1413  // Since rho is diagonal, then the square root of rho will also be diagonal,
1414  // with its real and imaginary matrix elements equal to c and d, respectively
1415 
1416  // Initialise the real and imaginary parts of the square root of
1417  // the rho matrix to zero
1418  ReSqrtRhoMatrix_.Zero();
1419  ImSqrtRhoMatrix_.Zero();
1420 
1421  for ( Int_t iChannel( 0 ); iChannel < nChannels_; ++iChannel ) {
1422 
1423  Double_t realRho = ReRhoMatrix_[iChannel][iChannel];
1424  Double_t imagRho = ImRhoMatrix_[iChannel][iChannel];
1425 
1426  Double_t rhoMag = sqrt( realRho * realRho + imagRho * imagRho );
1427  Double_t rhoSum = rhoMag + realRho;
1428  Double_t rhoDiff = rhoMag - realRho;
1429 
1430  Double_t reSqrtRho( 0.0 ), imSqrtRho( 0.0 );
1431  if ( rhoSum > 0.0 ) {
1432  reSqrtRho = sqrt( 0.5 * rhoSum );
1433  }
1434  if ( rhoDiff > 0.0 ) {
1435  imSqrtRho = sqrt( 0.5 * rhoDiff );
1436  }
1437 
1438  ReSqrtRhoMatrix_[iChannel][iChannel] = reSqrtRho;
1439  ImSqrtRhoMatrix_[iChannel][iChannel] = imSqrtRho;
1440  }
1441 }
1442 
1443 LauComplex LauKMatrixPropagator::getTHat( const Double_t s, const Int_t channel )
1444 {
1445 
1446  LauComplex THat( 0.0, 0.0 );
1447 
1448  if ( channel <= 0 || channel > nChannels_ ) {
1449  return THat;
1450  }
1451 
1452  this->updatePropagator( s );
1453 
1454  // Find the real and imaginary T_hat matrices
1455  TMatrixD THatReal = realProp_ * ScattKMatrix_;
1456  TMatrixD THatImag( zeroMatrix_ );
1457  THatImag -= negImagProp_ * ScattKMatrix_;
1458 
1459  // Return the specific THat component
1460  THat.setRealPart( THatReal[index_][channel - 1] );
1461  THat.setImagPart( THatImag[index_][channel - 1] );
1462 
1463  return THat;
1464 }
Double_t getScatteringConstant(const Int_t channel1Index, const Int_t channel2Index) const
Get scattering constants that were loaded from the input file.
TMatrixD ImTMatrix_
Imaginary part of the unitary T matrix.
Double_t prodSVP_
"slowly-varying part" for the production K-matrix
LauComplex getTransitionAmp(const Double_t s, const Int_t channel)
Get the unitary transition amplitude for the given channel.
const Double_t mPiSq
Square of pi+- mass.
Definition: LauConstants.hh:80
Double_t sAConst_
Defined as 0.5*sA*mPi*mPi.
LauComplex calcPiPiRho(const Double_t s) const
Calculate the pipi phase space factor.
void setRealPart(Double_t realpart)
Set the real part.
Definition: LauComplex.hh:311
const Double_t mDstar0KDiffSq_
Defined as (mD*0-mK)^2.
const Double_t m2piSq_
Defined as 4*mPi*mPi.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:49
Double_t unblindValue() const
The unblinded value of the parameter.
Double_t scattSVP_
"slowly-varying part" for the scattering K-matrix
void storeScattering(const std::vector< std::string > &theLine)
Store the scattering coefficients from a line in the parameter file.
const Double_t mKEtaPSumSq_
Defined as (mK+mEta')^2.
Double_t getImagPropTerm(const Int_t channelIndex) const
Get the imaginary part of the term of the propagator.
Class for parsing text files.
Double_t calcSVPTerm(const Double_t s, const Double_t s0) const
Calculate the "slow-varying part".
Double_t getm12Sq() const
Get the m12 invariant mass square.
LauParameter sA0_
Constant from input file.
const Double_t m2KSq_
Defined as 4*mK*mK.
TMatrixD IMatrix_
Identity matrix.
LauParArray gCouplings_
Array of coupling constants.
KMatrixChannels
Integers to specify the allowed channels for the phase space calculations.
Int_t index_
Row index - 1.
Double_t getRealPropTerm(const Int_t channelIndex) const
Get the real part of the term of the propagator.
std::vector< Double_t > poleDenomVect_
Vector of 1/(m_pole^2 - s) terms for scattering and production K-matrix formulae.
LauComplex getTHat(const Double_t s, const Int_t channel)
Get the THat amplitude for the given s and channel number.
std::vector< LauParameter > mSqPoles_
Vector of squared pole masses.
Int_t nPoles_
Number of poles.
Int_t nChannels_
Number of channels.
void updateScattSVPTerm(const Double_t s)
Update the scattering "slowly-varying part".
const Double_t m2EtaSq_
Defined as 4*mEta*mEta.
UInt_t getTotalNumLines() const
Get the total number of lines that are not comments.
void setParameters(const TString &inputFile)
Read an input file to set parameters.
LauParArray fScattering_
Array of scattering SVP values.
TMatrixD realProp_
Real part of the propagator matrix.
void getSqrtRhoMatrix()
Get the square root of the phase space matrix.
LauParameter mSq0_
Constant from input file.
TMatrixD ReTMatrix_
Real part of the unitary T matrix.
TString name_
String to store the propagator name.
Bool_t haveCalled_storeBarrierFactorParameter
Boolean to indicate whether storeBarrierFactorParameter has been called.
Double_t adlerZeroFactor_
Multiplicative factor containing various Adler zero constants.
void storePole(const std::vector< std::string > &theLine)
Store the pole mass and couplings from a line in the parameter file.
const Double_t k3piFactor_
Factor used to calculate the Kpipipi phase space term.
TMatrixD ImRhoMatrix_
Imaginary part of the phase space density diagonal matrix.
std::vector< KMatrixChannels > phaseSpaceTypes_
Vector of phase space types.
TMatrixD ReRhoMatrix_
Real part of the phase space density diagonal matrix.
LauComplex calcFourPiRho(const Double_t s) const
Calculate the 4 pi phase space factor.
const Double_t fourPiFactor1_
Factor used to calculate the pipipipi phase space term.
Class for defining a complex number.
Definition: LauComplex.hh:61
void updateAdlerZeroFactor(const Double_t s)
Calculate the multiplicative factor containing severa Adler zero constants.
TMatrixD ReSqrtRhoMatrix_
Real part of the square root of the phase space density diagonal matrix.
void getTMatrix(const LauKinematics *kinematics)
Get the unitary transition amplitude matrix for the given kinematics.
const Double_t mKpiDiffSq_
Defined as (mK-mPi)^2.
Double_t getCouplingConstant(const Int_t poleIndex, const Int_t channelIndex) const
Get coupling constants that were loaded from the input file.
void calcGammaMatrix(const Double_t s)
Calculate the (real) gamma angular-momentum barrier matrix.
LauParameter s0Scatt_
Constant from input file.
Double_t getPoleDenomTerm(const Int_t poleIndex) const
Get the 1/(m_pole^2 -s) terms for the scattering and production K-matrix formulae.
void calcPoleDenomVect(const Double_t s)
Calulate the term 1/(m_pole^2 - s) for the scattering and production K-matrix formulae.
void storeRadii(const std::vector< std::string > &theLine)
Store the channels' characteristic radii from a line in the parameter file.
LauComplex calcKKRho(const Double_t s) const
Calculate the KK phase space factor.
LauParameter & getCouplingParameter(const Int_t poleIndex, const Int_t channelIndex)
Get coupling parameters, set according to the input file.
LauComplex calcDstar0KRho(const Double_t s) const
Calculate the D*0K+ phase space factor.
Bool_t parametersSet_
Tracks if all params have been set.
static constexpr Bool_t verbose_
Control the output of the functions.
LauComplex calcKEtaPRho(const Double_t s) const
Calculate the K-eta' phase space factor.
Double_t abs() const
Obtain the absolute value of the complex number.
Definition: LauComplex.hh:254
File containing declaration of LauComplex class.
TMatrixD GammaMatrix_
Gamma angular-momentum barrier matrix.
void storeOrbitalAngularMomenta(const std::vector< std::string > &theLine, std::vector< Int_t > &a)
Store the channels' angular momenta from a line in the parameter file.
void calcRhoMatrix(const Double_t s)
Calculate the real and imaginary part of the phase space density diagonal matrix.
void calcScattKMatrix(const Double_t s)
Calculate the scattering K-matrix for the given value of s.
const Double_t mK3piDiffSq_
Defined as (mK-3*mPi)^2.
void updatePropagator(const Double_t s)
Calculate the K-matrix propagator for the given s value.
const Double_t mKpiSumSq_
Defined as (mK+mPi)^2.
void storeParameter(const TString &keyword, const TString &parString)
Store miscelleanous parameters from a line in the parameter file.
const Double_t mD0KSumSq_
Defined as (mD0+mK)^2.
LauComplex calcKPiRho(const Double_t s) const
Calculate the Kpi phase space factor.
LauKMatrixPropagator(const TString &name, const TString &paramFileName, const Int_t resPairAmpInt, const Int_t nChannels, const Int_t nPoles, const Int_t rowIndex=1)
Constructor.
virtual ~LauKMatrixPropagator()
Destructor.
Double_t previousS_
s value of the previous pole
LauParameter & getScatteringParameter(const Int_t channel1Index, const Int_t channel2Index)
Get scattering parameters, set according to the input file.
LauParameter()
Default constructor.
Definition: LauParameter.cc:40
LauComplex getPhaseSpaceTerm(const Double_t s, const Int_t channel)
Get the complex phase space term for the given channel and invariant mass squared.
File containing declaration of LauTextFileParser class.
LauComplex getRho(const Double_t s, const LauKMatrixPropagator::KMatrixChannels) const
Retrieve the complex phasespace density for a given channel.
LauComplex calcEtaEtaPRho(const Double_t s) const
Calculate the eta-eta' phase space factor.
LauParameter sA_
Constant from input file.
Bool_t scattSymmetry_
Control if scattering constants are channel symmetric: f_ji = f_ij.
Double_t re() const
Get the real part.
Definition: LauComplex.hh:242
const TString & name() const
The parameter name.
void processFile()
Parse the file.
LauParameter & getPoleMassSqParameter(const Int_t poleIndex)
Get pole mass parameters, set according to the input file.
const Double_t mKEtaPDiffSq_
Defined as (mK-mEta')^2.
TMatrixD negImagProp_
Imaginary part of the propagator matrix.
void updateProdSVPTerm(const Double_t s)
Update the production "slowly-varying part".
const Double_t mEtaEtaPSumSq_
Defined as (mEta+mEta')^2.
void storeBarrierFactorParameter(const std::vector< std::string > &theLine, std::vector< Int_t > &a)
Store the barrier-factor parameter from a line in the parameter file.
const Double_t mD0KDiffSq_
Defined as (mD0-mK)^2.
void storeChannels(const std::vector< std::string > &theLine)
Store the (phase space) channel indices from a line in the parameter file.
std::vector< Double_t > radii_
Vector of characteristic radii.
const Double_t mDstar0KSumSq_
Defined as (mD*0+mK)^2.
TString name_
The parameter name.
Class for calculating 3-body kinematic quantities.
Bool_t includeBWBarrierFactor_
Boolean to dictate whether to include Blatt-Weisskopf-like denominator in K-matrix centrifugal barrie...
File containing declaration of LauKMatrixPropagator class.
LauComplex getPropTerm(const Int_t channelIndex) const
Get the full complex propagator term for a given channel.
std::vector< Double_t > gamAInvRadSq_
Vector of ratio a/R^2.
Int_t resPairAmpInt_
Number to identify the DP axis in question.
LauComplex calcEtaEtaRho(const Double_t s) const
Calculate the eta-eta phase space factor.
void initialiseMatrices()
Initialise and set the dimensions for the internal matrices and parameter arrays.
Double_t im() const
Get the imaginary part.
Definition: LauComplex.hh:248
void setImagPart(Double_t imagpart)
Set the imaginary part.
Definition: LauComplex.hh:317
std::vector< Int_t > L_
Vector of orbital angular momenta.
std::vector< std::string > getLine(UInt_t lineNo)
Retrieve the specified line.
Double_t calcGamma(const Int_t iCh, const Double_t s) const
Calculate the gamma angular-momentum barrier.
Bool_t checkPhaseSpaceType(const Int_t phaseSpaceInt) const
Check the phase space factors that need to be used.
Double_t getm23Sq() const
Get the m23 invariant mass square.
TMatrixD zeroMatrix_
Null matrix.
Double_t getm13Sq() const
Get the m13 invariant mass square.
TMatrixD ScattKMatrix_
Scattering K-matrix.
LauComplex calcKThreePiRho(const Double_t s) const
Calculate the Kpipipi phase space factor.
TMatrixD ImSqrtRhoMatrix_
Imaginary part of the square root of the phase space density diagonal matrix.
File containing declaration of LauKinematics class.
LauParameter s0Prod_
Constant from input file.
LauComplex calcD0KRho(const Double_t s) const
Calculate the D0K+ phase space factor.