File indexing completed on 2024-04-06 12:22:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <vector>
0019 #include <numeric>
0020
0021 #include "TString.h"
0022 #include "TMinuit.h"
0023
0024
0025 class TestCrossSectionHandler;
0026
0027 class CrossSectionHandler {
0028
0029 friend class TestCrossSectionHandler;
0030
0031 public:
0032 CrossSectionHandler(const std::vector<double>& crossSection, const std::vector<int>& resfind)
0033 : parNum_(0), numberOfResonances_(resfind.size()) {
0034
0035 std::vector<int>::const_iterator it = resfind.begin();
0036 for (; it != resfind.end(); ++it) {
0037 if (*it != 0)
0038 ++parNum_;
0039 }
0040 if (parNum_ > 0)
0041 parNum_ = parNum_ - 1;
0042
0043 vars_.resize(parNum_);
0044
0045 computeRelativeCrossSections(crossSection, resfind);
0046 imposeConstraint();
0047 }
0048
0049
0050 void addParameters(std::vector<double>& initpar) {
0051 std::vector<double>::const_iterator it = vars_.begin();
0052 for (; it != vars_.end(); ++it) {
0053 initpar.push_back(*it);
0054 }
0055 }
0056
0057
0058 void setParameters(double* Start,
0059 double* Step,
0060 double* Mini,
0061 double* Maxi,
0062 int* ind,
0063 TString* parname,
0064 const std::vector<double>& parCrossSection,
0065 const std::vector<int>& parCrossSectionOrder,
0066 const std::vector<int>& resfind) {
0067 computeRelativeCrossSections(parCrossSection, resfind);
0068 imposeConstraint();
0069
0070 double thisStep[] = {0.001, 0.001, 0.001, 0.001, 0.001};
0071 TString thisParName[] = {"cross section var 1",
0072 "cross section var 2",
0073 "cross section var 3",
0074 "cross section var 4",
0075 "cross section var 5"};
0076 double thisMini[] = {0., 0., 0., 0., 0.};
0077 double thisMaxi[] = {1000., 1000., 1000., 1000., 1000.};
0078
0079
0080
0081 for (unsigned int iPar = 0; iPar < numberOfResonances_; ++iPar) {
0082 ind[iPar] = parCrossSectionOrder[iPar];
0083 }
0084
0085 if (parNum_ > 0) {
0086 for (unsigned int iPar = 0; iPar < parNum_; ++iPar) {
0087 Start[iPar] = vars_[iPar];
0088 Step[iPar] = thisStep[iPar];
0089 Mini[iPar] = thisMini[iPar];
0090 Maxi[iPar] = thisMaxi[iPar];
0091 parname[iPar] = thisParName[iPar];
0092 }
0093 }
0094 }
0095
0096
0097 bool releaseParameters(TMinuit& rmin,
0098 const std::vector<int>& resfind,
0099 const std::vector<int>& parfix,
0100 const int* ind,
0101 const int iorder,
0102 const unsigned int shift) {
0103
0104 unsigned int freeParNum = 0;
0105 for (unsigned int ipar = 0; ipar < numberOfResonances_; ++ipar) {
0106 if ((parfix[shift + ipar] == 0) && (ind[shift + ipar] <= iorder) && (resfind[ipar] == 1)) {
0107 ++freeParNum;
0108 }
0109 }
0110 if (freeParNum > 0) {
0111 freeParNum = freeParNum - 1;
0112
0113 for (unsigned int i = 0; i < freeParNum; ++i) {
0114 rmin.Release(shift + i);
0115 }
0116 return true;
0117 }
0118 return false;
0119 }
0120
0121 inline unsigned int parNum() { return parNum_; }
0122
0123
0124 std::vector<double> relativeCrossSections(const double* variables, const std::vector<int>& resfind) {
0125
0126
0127
0128
0129
0130
0131 if (parNum_ != 0) {
0132 double* partialProduct = new double[numberOfResonances_];
0133 double norm = 0.;
0134
0135 for (unsigned int i = 0; i < parNum_ + 1; ++i) {
0136 partialProduct[i] = std::accumulate(variables, variables + i, 1., std::multiplies<double>());
0137 norm += partialProduct[i];
0138 }
0139 for (unsigned int i = 0; i < parNum_ + 1; ++i) {
0140 relativeCrossSectionVec_[i] = partialProduct[i] / norm;
0141 }
0142 delete[] partialProduct;
0143 }
0144
0145 std::vector<double> allRelativeCrossSections;
0146 std::vector<int>::const_iterator it = resfind.begin();
0147 int smallerVectorIndex = 0;
0148 for (; it != resfind.end(); ++it) {
0149 if (*it == 0) {
0150 allRelativeCrossSections.push_back(0.);
0151 } else {
0152 allRelativeCrossSections.push_back(relativeCrossSectionVec_[smallerVectorIndex]);
0153 ++smallerVectorIndex;
0154 }
0155 }
0156
0157 return allRelativeCrossSections;
0158 }
0159
0160 protected:
0161
0162
0163
0164
0165
0166
0167 void computeRelativeCrossSections(const std::vector<double>& crossSection, const std::vector<int>& resfind) {
0168 relativeCrossSectionVec_.clear();
0169 double normalization = 0.;
0170 for (unsigned int ires = 0; ires < resfind.size(); ++ires) {
0171 if (resfind[ires]) {
0172 normalization += crossSection[ires];
0173 }
0174 }
0175 if (normalization != 0.) {
0176 for (unsigned int ires = 0; ires < resfind.size(); ++ires) {
0177 if (resfind[ires]) {
0178 relativeCrossSectionVec_.push_back(crossSection[ires] / normalization);
0179 }
0180 }
0181 }
0182 }
0183
0184
0185 void imposeConstraint() {
0186 if (parNum_ > 0) {
0187 for (unsigned int iVar = 0; iVar < parNum_; ++iVar) {
0188 vars_[iVar] = relativeCrossSectionVec_[iVar + 1] / relativeCrossSectionVec_[iVar];
0189 }
0190 }
0191 }
0192
0193
0194 std::vector<double> relativeCrossSectionVec_;
0195 std::vector<double> vars_;
0196 unsigned int parNum_;
0197 unsigned int numberOfResonances_;
0198 };