AmpTools
LikelihoodCalculator.cc
Go to the documentation of this file.
1 //******************************************************************************
2 // This file is part of AmpTools, a package for performing Amplitude Analysis
3 //
4 // Copyright Trustees of Indiana University 2010, all rights reserved
5 //
6 // This software written by Matthew Shepherd, Ryan Mitchell, and
7 // Hrayr Matevosyan at Indiana University, Bloomington
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 // 1. Redistributions of source code must retain the above copyright
13 // notice and author attribution, this list of conditions and the
14 // following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright
16 // notice and author attribution, this list of conditions and the
17 // following disclaimer in the documentation and/or other materials
18 // provided with the distribution.
19 // 3. Neither the name of the University nor the names of its contributors
20 // may be used to endorse or promote products derived from this software
21 // without specific prior written permission.
22 //
23 // Creation of derivative forms of this software for commercial
24 // utilization may be subject to restriction; written permission may be
25 // obtained from the Trustees of Indiana University.
26 //
27 // INDIANA UNIVERSITY AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES,
28 // EXPRESS OR IMPLIED. By way of example, but not limitation, INDIANA
29 // UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCANTABILITY OR
30 // FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THIS SOFTWARE OR
31 // DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS,
32 // OR OTHER RIGHTS. Neither Indiana University nor the authors shall be
33 // held liable for any liability with respect to any claim by the user or
34 // any other party arising from use of the program.
35 //******************************************************************************
36 
37 #include <sys/time.h>
38 #include <cassert>
39 #include <string>
40 
43 #include "IUAmpTools/DataReader.h"
44 #include "IUAmpTools/Kinematics.h"
47 
51 
52 #ifdef VTRACE
53 #include "vt_user.h"
54 #endif
55 
57  const NormIntInterface& normInt,
58  DataReader* dataReaderSignal,
59  DataReader* dataReaderBkgnd,
60  const ParameterManager& parManager ) :
61 MIFunctionContribution( parManager.fitManager() ),
62 m_intenManager( intenManager ),
63 m_normInt( normInt ),
64 m_dataReaderSignal( dataReaderSignal ),
65 m_dataReaderBkgnd( dataReaderBkgnd ),
66 m_firstDataCalc( true ),
67 m_firstNormIntCalc( true ),
68 m_sumBkgWeights( 0 ),
69 m_numBkgEvents( 0 ),
70 m_numDataEvents( 0 )
71 {
72 
73  m_hasBackground = ( dataReaderBkgnd != NULL );
74 
75 // avoid caching data here in the constructor so that MPI-based classes that
76 // inherit from this class can have better control of what triggers the
77 // caching of data
78 
79  m_prodFactorArray = new double[2*intenManager.getTermNames().size()];
80  m_normIntArray = normInt.normIntMatrix();
81  m_ampIntArray = normInt.ampIntMatrix();
82 }
83 
85 
86  delete[] m_prodFactorArray;
87 }
88 
89 double
91 
92  // split the compuation of likelihood into data and normalization
93  // integral sums -- this provides parallel implementations with the
94  // methods they need to compute these terms individually
95 
96  return -2 * ( dataTerm() - normIntTerm() );
97 }
98 
99 
100 double
102 
103 #ifdef VTRACE
104  VT_TRACER( "LikelihoodCalculator::normIntTerm" );
105 #endif
106 
107  // check to be sure we can actually perform a computation of the
108  // normalization integrals in case we have floating parameters
109 
110  if( m_intenManager.hasTermWithFreeParam() && !m_normInt.hasAccessToMC() ){
111 
112  cout << "ERROR: IntensityManager has terms with floating parameters\n"
113  << " but NormIntInterface has not been provided with MC." << endl;
114 
115  assert( false );
116  }
117 
118  if( ( m_firstNormIntCalc && m_normInt.hasAccessToMC() ) ||
119  ( m_intenManager.hasTermWithFreeParam() && !m_firstNormIntCalc ) ){
120 
121  m_normInt.forceCacheUpdate( true );
122  }
123 
124  int n = m_intenManager.getTermNames().size();
125  m_intenManager.prodFactorArray( m_prodFactorArray );
126 
127  double normTerm = 0;
128  bool renormalize = m_intenManager.termsAreRenormalized();
129 
130  switch( m_intenManager.type() ){
131 
133 
134  for( int a = 0; a < n; ++a ){
135  for( int b = 0; b <= a; ++b ){
136 
137  double thisTerm = 0;
138 
139  // we only need to compute the real part since the
140  // imaginary part will sum to zero in the end
141  // want: Re( V_a conj( V_b ) NI_a,b )
142 
143  double reVa = m_prodFactorArray[2*a];
144  double imVa = m_prodFactorArray[2*a+1];
145  double reVb = m_prodFactorArray[2*b];
146  double imVb = m_prodFactorArray[2*b+1];
147  double reNI = m_normIntArray[2*a*n+2*b];
148  double imNI = m_normIntArray[2*a*n+2*b+1];
149 
150  thisTerm = ( reVa*reVb + imVa*imVb ) * reNI;
151  thisTerm -= ( imVa*reVb - reVa*imVb ) * imNI;
152 
153  if( a != b ) thisTerm *= 2;
154 
155  if( renormalize ){
156  thisTerm /= sqrt( m_ampIntArray[2*a*n+2*a] *
157  m_ampIntArray[2*b*n+2*b] );
158  }
159 
160  normTerm += thisTerm;
161  }
162  }
163  break;
164 
166 
167  break;
168 
169  default:
170 
171  cout << "LikelihoodCalculator ERROR: unkown IntensityManager type" << endl;
172  assert( false );
173  break;
174  }
175 
176  m_firstNormIntCalc = false;
177 
178  if( m_hasBackground ){
179 
180  // in this case let's match the number of observed events to sum of the
181  // predicted signal and the provided background
182 
183  // this is the number of predicted signal and background events
184  double nPred = normTerm + m_sumBkgWeights;
185 
186  normTerm = ( m_numDataEvents - m_sumBkgWeights ) * log( normTerm );
187  normTerm += nPred - ( m_numDataEvents * log( nPred ) );
188 
189  return normTerm;
190  }
191  else{
192 
193  // this is the standard extended maximum likelihood technique that uses
194  // a Poisson distribution of the predicted signal and the number of
195  // observed events to normalize the fit components
196 
197  return normTerm;
198  }
199 }
200 
201 double
203 
204 #ifdef VTRACE
205  VT_TRACER( "LikelihoodCalculator::dataTerm" );
206 #endif
207 
208  if( m_firstDataCalc ) {
209 
210  // first calculation -- need to load the data
211 
212  cout << "Allocating Data and Amplitude Array in LikelihoodCalculator for "
213  << m_intenManager.reactionName() << "..." << endl;
214 
215  m_ampVecsSignal.loadData( m_dataReaderSignal );
216  m_ampVecsSignal.allocateTerms( m_intenManager, true );
217 
218  m_numDataEvents = m_ampVecsSignal.m_iNTrueEvents;
219 
220  if( m_hasBackground ){
221 
222  m_ampVecsBkgnd.loadData( m_dataReaderBkgnd, true );
223  m_ampVecsBkgnd.allocateTerms( m_intenManager, true );
224 
225  m_sumBkgWeights = m_ampVecsBkgnd.m_dAbsSumWeights;
226  m_numBkgEvents = m_ampVecsBkgnd.m_iNTrueEvents;
227  }
228 
229  cout << "\tDone." << endl;
230  }
231 
232  double sumLnI = m_intenManager.calcSumLogIntensity( m_ampVecsSignal );
233 
234  if( m_hasBackground ){
235 
236  sumLnI += m_intenManager.calcSumLogIntensity( m_ampVecsBkgnd );
237  }
238 
239  m_firstDataCalc = false;
240 
241  return sumLnI;
242 }
string reactionName() const
void allocateTerms(const IntensityManager &intenMan, bool bAllocIntensity=false)
Definition: AmpVecs.cc:235
void prodFactorArray(double *array) const
virtual void forceCacheUpdate(bool normIntOnly=false) const
virtual bool hasTermWithFreeParam() const =0
const vector< string > & getTermNames() const
#define NULL
Definition: URtypes.h:72
unsigned long long m_iNTrueEvents
Definition: AmpVecs.h:75
double sqrt(double)
bool hasAccessToMC() const
bool termsAreRenormalized() const
virtual Type type() const =0
const GDouble * normIntMatrix() const
double m_dAbsSumWeights
Definition: AmpVecs.h:83
virtual double calcSumLogIntensity(AmpVecs &ampVecs) const =0
LikelihoodCalculator(const IntensityManager &intenManager, const NormIntInterface &normInt, DataReader *dataReaderSignal, DataReader *dataReaderBkgnd, const ParameterManager &parManager)
const GDouble * ampIntMatrix() const
void loadData(DataReader *pDataReader, bool bForceNegativeWeight=false)
Definition: AmpVecs.cc:193
double log(double)