Go to the documentation of this file.00001
00018 #include <vector>
00019 #include <numeric>
00020
00021 #include "TString.h"
00022 #include "TMinuit.h"
00023
00024 class CrossSectionHandler
00025 {
00026 public:
00027 CrossSectionHandler(const std::vector<double> & crossSection, const std::vector<int> & resfind) :
00028 parNum_(0),
00029 numberOfResonances_(resfind.size())
00030 {
00031
00032 std::vector<int>::const_iterator it = resfind.begin();
00033 for( ; it != resfind.end(); ++it ) {
00034 if( *it != 0 ) ++parNum_;
00035 }
00036 if( parNum_ > 0 ) parNum_ = parNum_ - 1;
00037
00038 vars_.resize(parNum_);
00039
00040 computeRelativeCrossSections(crossSection, resfind);
00041 imposeConstraint();
00042 }
00043
00045 void addParameters(std::vector<double> & initpar)
00046 {
00047 std::vector<double>::const_iterator it = vars_.begin();
00048 for( ; it != vars_.end(); ++it ) {
00049 initpar.push_back(*it);
00050 }
00051 }
00052
00054 void setParameters( double* Start, double* Step, double* Mini, double* Maxi, int* ind, TString* parname,
00055 const std::vector<double> & parCrossSection, const std::vector<int> & parCrossSectionOrder,
00056 const std::vector<int> & resfind )
00057 {
00058 computeRelativeCrossSections(parCrossSection, resfind);
00059 imposeConstraint();
00060
00061 double thisStep[] = {0.001, 0.001, 0.001, 0.001, 0.001};
00062 TString thisParName[] = {"cross section var 1",
00063 "cross section var 2",
00064 "cross section var 3",
00065 "cross section var 4",
00066 "cross section var 5"};
00067 double thisMini[] = {0., 0., 0., 0., 0.};
00068 double thisMaxi[] = {1000., 1000., 1000., 1000., 1000.};
00069
00070
00071
00072 for( unsigned int iPar=0; iPar<numberOfResonances_; ++iPar ) {
00073 ind[iPar] = parCrossSectionOrder[iPar];
00074 }
00075
00076 if( parNum_ > 0 ) {
00077 for( unsigned int iPar=0; iPar<parNum_; ++iPar ) {
00078 Start[iPar] = vars_[iPar];
00079 Step[iPar] = thisStep[iPar];
00080 Mini[iPar] = thisMini[iPar];
00081 Maxi[iPar] = thisMaxi[iPar];
00082 parname[iPar] = thisParName[iPar];
00083 }
00084 }
00085 }
00086
00088 bool releaseParameters( TMinuit & rmin, const std::vector<int> & resfind, const std::vector<int> & parfix,
00089 const int * ind, const int iorder, const unsigned int shift )
00090 {
00091
00092 unsigned int freeParNum = 0;
00093 for( unsigned int ipar=0; ipar<numberOfResonances_; ++ipar ) {
00094 if( (parfix[shift+ipar]==0) && (ind[shift+ipar]<=iorder) && (resfind[ipar] == 1) ) {
00095 ++freeParNum;
00096 }
00097 }
00098 if( freeParNum > 0 ) {
00099 freeParNum = freeParNum - 1;
00100
00101 for( unsigned int i=0; i<freeParNum; ++i ) {
00102 rmin.Release( shift+i );
00103 }
00104 return true;
00105 }
00106 return false;
00107 }
00108
00109 inline unsigned int parNum()
00110 {
00111 return parNum_;
00112 }
00113
00115 std::vector<double> relativeCrossSections( const double * variables, const std::vector<int> & resfind )
00116 {
00117
00118
00119
00120
00121
00122
00123 if( parNum_ != 0 ) {
00124 double * partialProduct = new double[numberOfResonances_];
00125 double norm = 0.;
00126
00127 for( unsigned int i=0; i<parNum_+1; ++i ) {
00128 partialProduct[i] = std::accumulate(variables, variables + i, 1., std::multiplies<double>());
00129 norm += partialProduct[i];
00130 }
00131 for( unsigned int i=0; i<parNum_+1; ++i ) {
00132 relativeCrossSectionVec_[i] = partialProduct[i]/norm;
00133 }
00134 delete[] partialProduct;
00135 }
00136
00137 std::vector<double> allRelativeCrossSections;
00138 std::vector<int>::const_iterator it = resfind.begin();
00139 int smallerVectorIndex = 0;
00140 for( ; it != resfind.end(); ++it ) {
00141 if( *it == 0 ) {
00142 allRelativeCrossSections.push_back(0.);
00143 }
00144 else {
00145 allRelativeCrossSections.push_back(relativeCrossSectionVec_[smallerVectorIndex]);
00146 ++smallerVectorIndex;
00147 }
00148 }
00149
00150 return allRelativeCrossSections;
00151 }
00152
00153 protected:
00159
00160 void computeRelativeCrossSections(const std::vector<double> & crossSection, const std::vector<int> & resfind)
00161 {
00162 relativeCrossSectionVec_.clear();
00163 double normalization = 0.;
00164 for( unsigned int ires = 0; ires < resfind.size(); ++ires ) {
00165 if( resfind[ires] ) {
00166 normalization += crossSection[ires];
00167 }
00168 }
00169 if( normalization != 0. ) {
00170 for( unsigned int ires = 0; ires < resfind.size(); ++ires ) {
00171 if( resfind[ires] ) {
00172 relativeCrossSectionVec_.push_back(crossSection[ires]/normalization);
00173 }
00174 }
00175 }
00176 }
00177
00179 void imposeConstraint()
00180 {
00181 if( parNum_ > 0 ) {
00182 for( unsigned int iVar = 0; iVar < parNum_; ++iVar ) {
00183 vars_[iVar] = relativeCrossSectionVec_[iVar+1]/relativeCrossSectionVec_[iVar];
00184 }
00185 }
00186 }
00187
00188
00189 std::vector<double> relativeCrossSectionVec_;
00190 std::vector<double> vars_;
00191 unsigned int parNum_;
00192 unsigned int numberOfResonances_;
00193 };