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  // For tests
30 
31 public:
32  CrossSectionHandler(const std::vector<double>& crossSection, const std::vector<int>& resfind)
34  // The number of parameters is the number of fitted resonances minus 1
35  std::vector<int>::const_iterator it = resfind.begin();
36  for (; it != resfind.end(); ++it) {
37  if (*it != 0)
38  ++parNum_;
39  }
40  if (parNum_ > 0)
41  parNum_ = parNum_ - 1;
42 
43  vars_.resize(parNum_);
44 
47  }
48 
50  void addParameters(std::vector<double>& initpar) {
51  std::vector<double>::const_iterator it = vars_.begin();
52  for (; it != vars_.end(); ++it) {
53  initpar.push_back(*it);
54  }
55  }
56 
58  void setParameters(double* Start,
59  double* Step,
60  double* Mini,
61  double* Maxi,
62  int* ind,
63  TString* parname,
64  const std::vector<double>& parCrossSection,
65  const std::vector<int>& parCrossSectionOrder,
66  const std::vector<int>& resfind) {
67  computeRelativeCrossSections(parCrossSection, resfind);
69 
70  double thisStep[] = {0.001, 0.001, 0.001, 0.001, 0.001};
71  TString thisParName[] = {"cross section var 1",
72  "cross section var 2",
73  "cross section var 3",
74  "cross section var 4",
75  "cross section var 5"};
76  double thisMini[] = {0., 0., 0., 0., 0.};
77  double thisMaxi[] = {1000., 1000., 1000., 1000., 1000.};
78 
79  // This is used to unlock the parameters in a given order. It is not
80  // a TMinuit parameter, but a MuScleFit parameter.
81  for (unsigned int iPar = 0; iPar < numberOfResonances_; ++iPar) {
82  ind[iPar] = parCrossSectionOrder[iPar];
83  }
84 
85  if (parNum_ > 0) {
86  for (unsigned int iPar = 0; iPar < parNum_; ++iPar) {
87  Start[iPar] = vars_[iPar];
88  Step[iPar] = thisStep[iPar];
89  Mini[iPar] = thisMini[iPar];
90  Maxi[iPar] = thisMaxi[iPar];
91  parname[iPar] = thisParName[iPar];
92  }
93  }
94  }
95 
97  bool releaseParameters(TMinuit& rmin,
98  const std::vector<int>& resfind,
99  const std::vector<int>& parfix,
100  const int* ind,
101  const int iorder,
102  const unsigned int shift) {
103  // Find the number of free cross section parameters in this iteration
104  unsigned int freeParNum = 0;
105  for (unsigned int ipar = 0; ipar < numberOfResonances_; ++ipar) {
106  if ((parfix[shift + ipar] == 0) && (ind[shift + ipar] <= iorder) && (resfind[ipar] == 1)) {
107  ++freeParNum;
108  }
109  }
110  if (freeParNum > 0) {
111  freeParNum = freeParNum - 1;
112  // Free only the first (freeParNum-1) of the N-1 variables
113  for (unsigned int i = 0; i < freeParNum; ++i) {
114  rmin.Release(shift + i);
115  }
116  return true;
117  }
118  return false;
119  }
120 
121  inline unsigned int parNum() { return parNum_; }
122 
124  std::vector<double> relativeCrossSections(const double* variables, const std::vector<int>& resfind) {
125  // parNum_ is 0 in two cases:
126  // 1) if only one resonance is being fitted, in which case the relative cross section is
127  // fixed to one and there is no need to recompute it
128  // 2) if no resonance is being fitted, in which case all the relative cross sections will
129  // be set to 0.
130  // In both cases there is no need to make the transformation of variables.
131  if (parNum_ != 0) {
132  double* partialProduct = new double[numberOfResonances_];
133  double norm = 0.;
134  // Loop on all relative cross sections (that are parNum_+1)
135  for (unsigned int i = 0; i < parNum_ + 1; ++i) {
136  partialProduct[i] = std::accumulate(variables, variables + i, 1., std::multiplies<double>());
137  norm += partialProduct[i];
138  }
139  for (unsigned int i = 0; i < parNum_ + 1; ++i) {
140  relativeCrossSectionVec_[i] = partialProduct[i] / norm;
141  }
142  delete[] partialProduct;
143  }
144 
145  std::vector<double> allRelativeCrossSections;
146  std::vector<int>::const_iterator it = resfind.begin();
147  int smallerVectorIndex = 0;
148  for (; it != resfind.end(); ++it) {
149  if (*it == 0) {
150  allRelativeCrossSections.push_back(0.);
151  } else {
152  allRelativeCrossSections.push_back(relativeCrossSectionVec_[smallerVectorIndex]);
153  ++smallerVectorIndex;
154  }
155  }
156 
157  return allRelativeCrossSections;
158  }
159 
160 protected:
166  // void computeRelativeCrossSections(const double crossSection[], const std::vector<int> resfind, const unsigned int minRes, const unsigned int maxRes)
167  void computeRelativeCrossSections(const std::vector<double>& crossSection, const std::vector<int>& resfind) {
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]) {
179  }
180  }
181  }
182  }
183 
186  if (parNum_ > 0) {
187  for (unsigned int iVar = 0; iVar < parNum_; ++iVar) {
188  vars_[iVar] = relativeCrossSectionVec_[iVar + 1] / relativeCrossSectionVec_[iVar];
189  }
190  }
191  }
192 
193  // Data members
194  std::vector<double> relativeCrossSectionVec_;
195  std::vector<double> vars_;
196  unsigned int parNum_;
197  unsigned int numberOfResonances_;
198 };
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.
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)
static unsigned int const shift
void addParameters(std::vector< double > &initpar)
Inputs the vars in a vector.