00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "DsG4GdCaptureGammas.h"
00011 #include "Randomize.hh"
00012 #include <TRandom.h>
00013 #include <vector>
00014 #include "G4Gamma.hh"
00015 #include "TROOT.h"
00016 #include "TFile.h"
00017 #include "TH1F.h"
00018 #include "TMath.h"
00019
00021
00022 using namespace std;
00023 using namespace CLHEP;
00024
00025 DsG4GdCaptureGammas::DsG4GdCaptureGammas ()
00026 {
00027
00028
00029
00030
00031 TDirectory *dirKeep = gDirectory;
00032
00033
00034
00035
00036
00037
00038
00039
00040 std::string specfilename = "gdcap_spec.root";
00041 const char* prefix = getenv("DAYA_DATA_DIR");
00042 if(prefix) {
00043 if(strlen(prefix)>0) {
00044 std::string newname = prefix;
00045 newname += "/";
00046 newname += specfilename;
00047 specfilename = newname;
00048 }
00049 }
00050
00051 specfile = TFile::Open(specfilename.c_str());
00052
00053 if(!specfile)
00054 G4cout << "Can not open gdcap_spec.root. "
00055 << "Make sure DAYA_DATA_DIR is set to it's location." << G4endl;
00056 if(!(specfile->IsOpen()))
00057 G4cout << "Can not open gdcap_spec.root. "
00058 << "Make sure DAYA_DATA_DIR is set to it's location." << G4endl;
00059
00060 capspec = (TH1F*)(specfile->Get("h1"));
00061
00062
00063 if (dirKeep) {
00064 dirKeep->cd();
00065 }
00066 }
00067
00068 DsG4GdCaptureGammas::~DsG4GdCaptureGammas ()
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078 }
00079
00080 G4ReactionProductVector* DsG4GdCaptureGammas::GetGammas ()
00081 {
00082 G4ReactionProductVector* theGammas = new G4ReactionProductVector;
00083 vector<double> energy = GetEnergy();
00084 for(unsigned int i=0; i<energy.size(); i++) {
00085
00086 G4ReactionProduct* theOne = new G4ReactionProduct;
00087 theOne->SetDefinition( G4Gamma::Gamma() );
00088
00089
00090
00091 G4double costheta = 2.*G4UniformRand()-1;
00092 G4double theta = acos(costheta);
00093 G4double phi = twopi*G4UniformRand();
00094 G4double sinth = sin(theta);
00095 theOne->SetTotalEnergy( energy[i] );
00096 G4ThreeVector temp(energy[i]*sinth*cos(phi),
00097 energy[i]*sinth*sin(phi),
00098 energy[i]*cos(theta) );
00099 theOne->SetMomentum( temp ) ;
00100 theGammas->push_back(theOne);
00101 }
00102 return theGammas;
00103 }
00104
00105 static double getRandomCLHEP(TH1* hh)
00106 {
00107
00108
00109
00110
00111
00112
00113
00114 if (hh->GetDimension()> 1) {
00115 G4cout << "Error in getRandomCLHEP: Function only valid for 1-d histograms"
00116 <<endl;
00117 return 0;
00118 }
00119 int nbinsx = hh->GetNbinsX();
00120 double integral;
00121
00122 double *myIntegral = 0;
00123 myIntegral = hh->GetIntegral();
00124
00125 if (myIntegral) {
00126 if (myIntegral[nbinsx+1] != hh->GetEntries()) {
00127 integral = hh->ComputeIntegral();
00128
00129 myIntegral = hh->GetIntegral();
00130 }
00131 } else {
00132 integral = hh->ComputeIntegral();
00133
00134 myIntegral = hh->GetIntegral();
00135 if (integral == 0 || myIntegral == 0) return 0;
00136 }
00137
00138
00139
00140 double r1 = HepRandom::getTheEngine()->flat();
00141
00142 int ibin = TMath::BinarySearch(nbinsx,myIntegral,r1);
00143 double x = hh->GetBinLowEdge(ibin+1);
00144 if (r1 > myIntegral[ibin])
00145 x +=
00146 hh->GetBinWidth(ibin+1)*(r1-myIntegral[ibin])
00147 /(myIntegral[ibin+1] - myIntegral[ibin]);
00148 return x;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 vector<double> DsG4GdCaptureGammas::GetEnergy ()
00158 {
00159 vector<double> Energy;
00160 G4double TotalEnergy;
00161 if (G4UniformRand()<0.815)
00162 TotalEnergy = 7.93;
00163 else
00164 TotalEnergy = 8.53;
00165 G4double energy_sum = 0.0;
00166 G4int gamma_num = 0;
00167 G4double gamma_energy[100]={0};
00168 G4double energy_tmp;
00169
00170 sample:
00171
00172
00173
00174
00175
00176 G4double energy = getRandomCLHEP(capspec);
00177
00178 energy_sum = energy_sum+energy;
00179 gamma_num = gamma_num+1;
00180 gamma_energy[gamma_num] = energy;
00181
00182 if(energy_sum>TotalEnergy) {
00183 if((energy_sum-TotalEnergy)<0.8) {
00184 energy_tmp = gamma_energy[gamma_num-1]+energy-(energy_sum-TotalEnergy);
00185 if(energy_tmp>7.4) {
00186 energy_sum = energy_sum-energy;
00187 gamma_num = gamma_num-1;
00188 goto sample;
00189 }
00190 gamma_num = gamma_num-1;
00191 gamma_energy[gamma_num]=energy_tmp;
00192 goto goon;
00193 }
00194 energy_sum = energy_sum-energy;
00195 gamma_num = gamma_num-1;
00196 goto sample;
00197 }
00198 goto sample;
00199
00200 goon:
00201
00202
00203 for(int i=gamma_num;i>1;i--) {
00204 for(int j=1;j<i;j++) {
00205 if(gamma_energy[j]<gamma_energy[j+1]) {
00206 energy_tmp = gamma_energy[j+1];
00207 gamma_energy[j+1] = gamma_energy[j];
00208 gamma_energy[j] = energy_tmp;
00209 }
00210 }
00211 }
00212 if(gamma_num<=3)
00213 goto ok;
00214
00215 if(gamma_energy[gamma_num]<0.8) {
00216 energy_tmp = gamma_energy[gamma_num]+gamma_energy[gamma_num-1];
00217 if(energy_tmp>7.4)
00218 goto ok;
00219 gamma_energy[gamma_num-1]=energy_tmp;
00220 gamma_num=gamma_num-1;
00221 }
00222
00223 ok:
00224
00225 for(int k=1;k<=gamma_num;k++)
00226 Energy.push_back(gamma_energy[k]);
00227
00228 return Energy;
00229 }