00001 #include <iostream>
00002 #include "TRadCor.h"
00003 #include "TRandom.h"
00004 #include "TGlobal.h"
00005 #include "TStopwatch.h"
00006 #include "TH1.h"
00007
00008 #ifdef HIST
00009 extern TH1 *gH[], *gH2[];
00010 #endif
00011
00012 TRadCor::TRadCor(TVCrossPart *m){
00013 fNEvents = 10000;
00014 fMatrix = m;
00015 fNPart = fMatrix->GetNPart();
00016 fMax = new double[fNPart];
00017 fMin = new double[fNPart];
00018 fSigma = new double[fNPart];
00019 fCross = new double[fNPart];
00020 fCross2 = new double[fNPart];
00021 fECross = new double[fNPart];
00022 fECross2 = new double[fNPart];
00023 fSM = new double[fNPart];
00024 fSM2 = new double[fNPart];
00025 fPart = new double[fNPart];
00026 fNSim = new unsigned int[fNPart];
00027 fN = new unsigned int[fNPart];
00028 fWN = new unsigned int[fNPart];
00029 fInList = new bool[fNPart];
00030 for(unsigned int i=0; i<fNPart; i++) fInList[i] = true;
00031
00032 fNew = true;
00033 fIsSmear = false;
00034 Init();
00035 }
00036
00037 TRadCor::TRadCor(){
00038 fMatrix = 0;
00039 fWN = 0;
00040 fN = 0;
00041 fNSim = 0;
00042 fPart = 0;
00043 fSM2 = 0;
00044 fSM = 0;
00045 fECross2 = 0;
00046 fECross = 0;
00047 fCross2 = 0;
00048 fCross = 0;
00049 fSigma = 0;
00050 fMin = 0;
00051 fMax = 0;
00052 fNPart = 0;
00053 fInList = 0;
00054 }
00055
00056 void TRadCor::Init(){
00057 fMatrix->Init();
00058 for(unsigned int i=0; i<fNPart; i++){
00059 fMax[i] =-1e20;
00060 fMin[i] = 1e20;
00061 fSigma[i] = 1e20;
00062 fNSim[i] = 0;
00063 fN[i] = 0;
00064 fWN[i] = 0;
00065 fSM[i] = 0;
00066 fSM2[i] = 0;
00067 fPart[i] = 0;
00068 fCross[i] = 0;
00069 fCross2[i] = 0;
00070 fECross[i] = 0;
00071 fECross2[i] = 0;
00072 }
00073
00074 fTheta_Aver_0 = gCut->AverageThetaMin() - 0.5*gGlobal->Get_de()/(gGlobal->Get_E()*cos(gCut->AverageThetaMin()));
00075 fTheta_Aver_0 = (fTheta_Aver_0<gGlobal->Get_ThetaMin()) ? gGlobal->Get_ThetaMin() : fTheta_Aver_0;
00076 }
00077
00078 TRadCor::~TRadCor(){
00079 delete [] fMax;
00080 delete [] fMin;
00081 delete [] fSigma;
00082 delete [] fCross;
00083 delete [] fCross2;
00084 delete [] fECross;
00085 delete [] fECross2;
00086 delete [] fSM;
00087 delete [] fSM2;
00088 delete [] fPart;
00089 delete [] fNSim;
00090 delete [] fN;
00091 delete [] fWN;
00092 delete [] fInList;
00093 }
00094
00095 void TRadCor::MakeMaximum(const unsigned int &ipart){
00096 SetSpecialCase(ipart);
00097 for(unsigned int i=0;i<fNEvents;i++){
00098 double m = fMatrix->GetValue(ipart);
00099 fSM[ipart] += m;
00100 fSM2[ipart] += m*m;
00101 fWN[ipart]++;
00102 if ( m != 0 && m > fMax[ipart] ) fMax[ipart] = m;
00103 if ( m != 0 && m < fMin[ipart] ) fMin[ipart] = m;
00104 #ifdef HIST
00105 double p0, t0, ph0, p1, t1, ph;
00106 fMatrix->GetEvent(p0, t0, ph0, p1, t1, ph);
00107 gH[ipart]->Fill(fabs(t0+t1-M_PI), m);
00108 #endif
00109 }
00110 fCross2[ipart] = gGlobal->Get_Norm()*fSM[ipart]/fWN[ipart];
00111 fECross2[ipart] = gGlobal->Get_Norm()*sqrt((fSM2[ipart]-1.*fSM[ipart]*fSM[ipart]/fWN[ipart]))/fWN[ipart];
00112 }
00113
00114 void TRadCor::MakeIntegral(const unsigned int &ipart){
00115 SetSpecialCase(ipart);
00116 for(unsigned int i=0;i<fNEvents;i++){
00117 double m = fMatrix->GetValue(ipart);
00118
00119 fSM[ipart] += m;
00120 fSM2[ipart] += m*m;
00121 fWN[ipart]++;
00122 fN[ipart]++;
00123 #ifdef HIST
00124 double p0, t0, ph0, p1, t1, ph;
00125 fMatrix->GetEvent(p0, t0, ph0, p1, t1, ph);
00126 gH[ipart]->Fill(fabs(t0+t1-M_PI), m);
00127 #endif
00128 if ( m != 0 && m > fMax[ipart]*gRandom->Rndm() ) {
00129 fNSim[ipart]++;
00130 #ifdef HIST
00131 gH2[ipart]->Fill(fabs(t0+t1-M_PI));
00132 #endif
00133
00134 }
00135 }
00136 fCross[ipart] = gGlobal->Get_Norm()*fNSim[ipart]*fMax[ipart]/fN[ipart];
00137 double r = (1.0*fNSim[ipart])/fN[ipart];
00138 fECross[ipart] = gGlobal->Get_Norm()*fMax[ipart]*sqrt(r*(1.-r)/fN[ipart]);
00139
00140 fCross2[ipart] = gGlobal->Get_Norm()*fSM[ipart]/fWN[ipart];
00141 fECross2[ipart] = gGlobal->Get_Norm()*sqrt((fSM2[ipart]-1.*fSM[ipart]*fSM[ipart]/fWN[ipart]))/fWN[ipart];
00142 }
00143
00144 double TRadCor::Norm(const unsigned int &ipart){
00145 return 1;
00146 }
00147
00148 void TRadCor::MakeAllMaximums(){
00149 for(unsigned int i=0; i<fNPart; i++){
00150 SetSpecialCase(i);
00151 MakeMaximum(i);
00152 }
00153 }
00154
00155 void TRadCor::MakeAllIntegrals(){
00156 for(unsigned int i=0; i<fNPart; i++){
00157 SetSpecialCase(i);
00158 MakeIntegral(i);
00159 }
00160 }
00161
00162 void TRadCor::MakePart(){
00163 fPart[0] = fCross2[0];
00164 for(unsigned int i=1; i<fNPart; i++)
00165 fPart[i] = fPart[i-1] + fCross2[i];
00166
00167 for(unsigned int i=0; i<fNPart; i++){
00168 fPart[i]/= fPart[fNPart-1];
00169 }
00170 }
00171
00172 unsigned int TRadCor::MakeEvent(){
00173 double r = gRandom->Rndm();
00174 unsigned int ipart = 0;
00175 while(r>fPart[ipart]) ipart++;
00176 SetSpecialCase(ipart);
00177 while (true){
00178 double m = fMatrix->GetValue(ipart);
00179 if ( m != 0 && m>fMax[ipart]*gRandom->Rndm() ) break;
00180 }
00181 return ipart;
00182 }
00183
00184 void TRadCor::MakeCrossSection(){
00185 using namespace std;
00186 bool *done = new bool[fNPart];
00187 TStopwatch *timer = new TStopwatch();
00188 timer->Start(kFALSE);
00189
00190
00191
00192
00193 for(unsigned int j=0;j<fNPart;j++) done[j] = false;
00194 int n = 0;
00195 for(unsigned int j=0;j<fNPart;j++) if(fInList[j]) n++;
00196 double te = gGlobal->Get_TotalError()/sqrt(n/2.);
00197 double tre = gGlobal->Get_RelativeError()*sqrt(2.);
00198 bool alldone = false;
00199 while(!alldone){
00200 alldone = true;
00201 for(unsigned int j=0;j<fNPart; j++){
00202 if(!fInList[j])continue;
00203 unsigned int i = j;
00204 if(!done[j]){
00205 MakeMaximum(i);
00206 double as = fabs(GetCross2(i));
00207 double es = fabs(GetECross2(i));
00208 if((es < te && es/as < tre) || ( es < 0.2*te )){
00209 cout<<"Part = "<<i<<", Min = "<<GetMin(i)<<", Max = "<<GetMax(i)<<", "
00210 <<"N = "<<GetWN(i)<<", "
00211 <<"sw = "<<GetCross2(i)<<" +- "<<es<<" nb"
00212 <<endl;
00213 done[j] = true;
00214 } else {
00215 alldone = false;
00216 }
00217 }
00218 }
00219 }
00220
00221 timer->Stop();
00222 cout<<"REALTIME = "<<timer->RealTime()<<", CPUTIME = "<<timer->CpuTime()<<endl<<flush;
00223 timer->Start(kFALSE);
00224 for(unsigned int j=0;j<fNPart;j++) done[j] = false;
00225
00226 double su = 0, sw = 0, esu=0, esw=0;
00227 alldone = false;
00228 while(!alldone){
00229 alldone = true;
00230 for(unsigned int j=0;j<fNPart;j++){
00231 if(!fInList[j])continue;
00232 unsigned int i = j;
00233 if(!done[j]){
00234 MakeIntegral(i);
00235 double as = fabs(GetCross2(i));
00236 double es = fabs(GetECross2(i));
00237 if ( (es < te/sqrt(2.) && es/as < tre/sqrt(2.) && (GetNSim(i) > 4000 || GetMax(i)<=0) ) ||
00238 (es < 0.2*te/sqrt(2.) && GetNSim(i) > 400 ) ||
00239 (es/as < 1e-5 && GetECross(i)/GetCross(i) < 1e-4)
00240 ){
00241 cout<<"Part = "<<i<<", "
00242 <<"N = "<<GetNSim(i)<<", "
00243 <<"s = "<<GetCross(i)<<" +- "<<GetECross(i)<<" nb"<<", "
00244 <<"N = "<<GetWN(i)<<", "
00245 <<"sw = "<<GetCross2(i)<<" +- "<<es<<" nb"
00246 <<endl;
00247 su += GetCross(i);
00248 esu += GetECross(i)*GetECross(i);
00249 sw += GetCross2(i);
00250 esw += es*es;
00251 done[j] = true;
00252 } else {
00253 alldone = false;
00254 }
00255 }
00256 }
00257 }
00258 esu = sqrt(esu);
00259 esw = sqrt(esw);
00260 cout<<"CrossSection = "<<su<<" +- "<<esu<<" nb, "
00261 <<"relative error is "<<esu/su*100<<"%"<<endl;
00262 cout<<"CrossSection2 = "<<sw<<" +- "<<esw<<" nb, "
00263 <<"relative error is "<<esw/sw*100<<"%"<<endl;
00264
00265 timer->Stop();
00266 cout<<"REALTIME = "<<timer->RealTime()<<", CPUTIME = "<<timer->CpuTime()<<endl<<flush;
00267 timer->Start(kFALSE);
00268
00269 MakePart();
00270
00271 delete [] done;
00272 delete timer;
00273 }