CMS 3D CMS Logo

CrossSectionHandler.h
Go to the documentation of this file.
1 
18 #include <vector>
19 #include <numeric>
20 
21 #include "TString.h"
22 #include "TMinuit.h"
23 
24 // Unit test for testing CrossSectionHandler
25 class TestCrossSectionHandler;
26 
28 {
29  // For tests
31 
32 public:
33  CrossSectionHandler(const std::vector<double> & crossSection, const std::vector<int> & resfind) :
34  parNum_(0),
35  numberOfResonances_(resfind.size())
36  {
37  // The number of parameters is the number of fitted resonances minus 1
38  std::vector<int>::const_iterator it = resfind.begin();
39  for( ; it != resfind.end(); ++it ) {
40  if( *it != 0 ) ++parNum_;
41  }
42  if( parNum_ > 0 ) parNum_ = parNum_ - 1;
43 
44  vars_.resize(parNum_);
45 
46  computeRelativeCrossSections(crossSection, resfind);
48  }
49 
51  void addParameters(std::vector<double> & initpar)
52  {
53  std::vector<double>::const_iterator it = vars_.begin();
54  for( ; it != vars_.end(); ++it ) {
55  initpar.push_back(*it);
56  }
57  }
58 
60  void setParameters( double* Start, double* Step, double* Mini, double* Maxi, int* ind, TString* parname,
61  const std::vector<double> & parCrossSection, const std::vector<int> & parCrossSectionOrder,
62  const std::vector<int> & resfind )
63  {
64  computeRelativeCrossSections(parCrossSection, resfind);
66 
67  double thisStep[] = {0.001, 0.001, 0.001, 0.001, 0.001};
68  TString thisParName[] = {"cross section var 1",
69  "cross section var 2",
70  "cross section var 3",
71  "cross section var 4",
72  "cross section var 5"};
73  double thisMini[] = {0., 0., 0., 0., 0.};
74  double thisMaxi[] = {1000., 1000., 1000., 1000., 1000.};
75 
76  // This is used to unlock the parameters in a given order. It is not
77  // a TMinuit parameter, but a MuScleFit parameter.
78  for( unsigned int iPar=0; iPar<numberOfResonances_; ++iPar ) {
79  ind[iPar] = parCrossSectionOrder[iPar];
80  }
81 
82  if( parNum_ > 0 ) {
83  for( unsigned int iPar=0; iPar<parNum_; ++iPar ) {
84  Start[iPar] = vars_[iPar];
85  Step[iPar] = thisStep[iPar];
86  Mini[iPar] = thisMini[iPar];
87  Maxi[iPar] = thisMaxi[iPar];
88  parname[iPar] = thisParName[iPar];
89  }
90  }
91  }
92 
94  bool releaseParameters( TMinuit & rmin, const std::vector<int> & resfind, const std::vector<int> & parfix,
95  const int * ind, const int iorder, const unsigned int shift )
96  {
97  // Find the number of free cross section parameters in this iteration
98  unsigned int freeParNum = 0;
99  for( unsigned int ipar=0; ipar<numberOfResonances_; ++ipar ) {
100  if( (parfix[shift+ipar]==0) && (ind[shift+ipar]<=iorder) && (resfind[ipar] == 1) ) {
101  ++freeParNum;
102  }
103  }
104  if( freeParNum > 0 ) {
105  freeParNum = freeParNum - 1;
106  // Free only the first (freeParNum-1) of the N-1 variables
107  for( unsigned int i=0; i<freeParNum; ++i ) {
108  rmin.Release( shift+i );
109  }
110  return true;
111  }
112  return false;
113  }
114 
115  inline unsigned int parNum()
116  {
117  return parNum_;
118  }
119 
121  std::vector<double> relativeCrossSections( const double * variables, const std::vector<int> & resfind )
122  {
123  // parNum_ is 0 in two cases:
124  // 1) if only one resonance is being fitted, in which case the relative cross section is
125  // fixed to one and there is no need to recompute it
126  // 2) if no resonance is being fitted, in which case all the relative cross sections will
127  // be set to 0.
128  // In both cases there is no need to make the transformation of variables.
129  if( parNum_ != 0 ) {
130  double * partialProduct = new double[numberOfResonances_];
131  double norm = 0.;
132  // Loop on all relative cross sections (that are parNum_+1)
133  for( unsigned int i=0; i<parNum_+1; ++i ) {
134  partialProduct[i] = std::accumulate(variables, variables + i, 1., std::multiplies<double>());
135  norm += partialProduct[i];
136  }
137  for( unsigned int i=0; i<parNum_+1; ++i ) {
138  relativeCrossSectionVec_[i] = partialProduct[i]/norm;
139  }
140  delete[] partialProduct;
141  }
142 
143  std::vector<double> allRelativeCrossSections;
144  std::vector<int>::const_iterator it = resfind.begin();
145  int smallerVectorIndex = 0;
146  for( ; it != resfind.end(); ++it ) {
147  if( *it == 0 ) {
148  allRelativeCrossSections.push_back(0.);
149  }
150  else {
151  allRelativeCrossSections.push_back(relativeCrossSectionVec_[smallerVectorIndex]);
152  ++smallerVectorIndex;
153  }
154  }
155 
156  return allRelativeCrossSections;
157  }
158 
159 protected:
165  // void computeRelativeCrossSections(const double crossSection[], const std::vector<int> resfind, const unsigned int minRes, const unsigned int maxRes)
166  void computeRelativeCrossSections(const std::vector<double> & crossSection, const std::vector<int> & resfind)
167  {
168  relativeCrossSectionVec_.clear();
169  double normalization = 0.;
170  for( unsigned int ires = 0; ires < resfind.size(); ++ires ) {
171  if( resfind[ires] ) {
172  normalization += crossSection[ires];
173  }
174  }
175  if( normalization != 0. ) {
176  for( unsigned int ires = 0; ires < resfind.size(); ++ires ) {
177  if( resfind[ires] ) {
178  relativeCrossSectionVec_.push_back(crossSection[ires]/normalization);
179  }
180  }
181  }
182  }
183 
186  {
187  if( parNum_ > 0 ) {
188  for( unsigned int iVar = 0; iVar < parNum_; ++iVar ) {
190  }
191  }
192  }
193 
194  // Data members
195  std::vector<double> relativeCrossSectionVec_;
196  std::vector<double> vars_;
197  unsigned int parNum_;
198  unsigned int numberOfResonances_;
199 };
size
Write out results.
void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const std::vector< double > &parCrossSection, const std::vector< int > &parCrossSectionOrder, const std::vector< int > &resfind)
Initializes the arrays needed by Minuit.
int ires[2]
void computeRelativeCrossSections(const std::vector< double > &crossSection, const std::vector< int > &resfind)
friend class TestCrossSectionHandler
std::vector< double > vars_
std::vector< double > relativeCrossSectionVec_
bool releaseParameters(TMinuit &rmin, const std::vector< int > &resfind, const std::vector< int > &parfix, const int *ind, const int iorder, const unsigned int shift)
Use the information in resfind, parorder and parfix to release the N-1 variables. ...
unsigned int numberOfResonances_
void imposeConstraint()
Change of variables so that we move from N to N-1 variables using the constraint that Sum(x_i) = 1...
std::vector< double > relativeCrossSections(const double *variables, const std::vector< int > &resfind)
Perform a variable transformation from N-1 to relative cross sections.
CrossSectionHandler(const std::vector< double > &crossSection, const std::vector< int > &resfind)
int iorder
static unsigned int const shift
void addParameters(std::vector< double > &initpar)
Inputs the vars in a vector.