00001
00011 #include <math.h>
00012 #include <iostream.h>
00013 #include <string.h>
00014 #include "ReactorEvent.hh"
00015 #include "ReactorFortran.hh"
00016 #include "ReactorConstants.hh"
00017 #include "ReactorXC.hh"
00018 #include "ReactorDetector.hh"
00019 #include "MyTlSource.hh"
00020 #include "MyBiSource.hh"
00021
00022
00023
00024 ReactorDetector::ReactorDetector(){
00025
00026
00027
00028 Xpmt = new double[0];
00029 Ypmt = new double[0];
00030 Zpmt = new double[0];
00031 PMTdata = new PMT[0];
00032 PMTpositron = new PMT[0];
00033 PMTneutron = new PMT[0];
00034
00035
00036
00037 SetNominalParameters();
00038 SetPMT();
00039 SetNeutronPropStuff();
00040
00041
00042
00043 Ngamma = 0;
00044 Rgamma = new double[Ngamma];
00045 Egamma = new double[Ngamma];
00046 Tgamma = new double[Ngamma];
00047 Ogamma = new std::string[Ngamma];
00048
00049 Nneutron = 0;
00050 Absorber = new double[Nneutron];
00051 NeutronSteps = new double[Nneutron];
00052
00053 pmtRadCount = 0;
00054 }
00055
00056
00057
00058 ReactorDetector::~ReactorDetector(){
00059 delete[] Xpmt;
00060 delete[] Ypmt;
00061 delete[] Zpmt;
00062 delete[] PMTdata;
00063 delete[] PMTpositron;
00064 delete[] PMTneutron;
00065 delete[] Rgamma;
00066 delete[] Egamma;
00067 delete[] Tgamma;
00068 delete[] Ogamma;
00069 delete[] Absorber;
00070 delete[] NeutronSteps;
00071 }
00072
00073
00074
00075 ReactorDetector::ReactorDetector(const ReactorDetector& Detector){
00076
00077 R0=Detector.R0;
00078 R1=Detector.R1;
00079 R2=Detector.R2;
00080 GdConcentration=Detector.GdConcentration;
00081 refracGd=Detector.refracGd;
00082 refracSc=Detector.refracSc;
00083 mfpGd=Detector.mfpGd;
00084 mfpSc=Detector.mfpSc;
00085 MeanNeuDispl = Detector.MeanNeuDispl;
00086 FastNeutronOption = Detector.FastNeutronOption;
00087 Temperature = Detector.Temperature;
00088 tGd=Detector.tGd;
00089 tSc=Detector.tSc;
00090 GdCaptureFraction=Detector.GdCaptureFraction;
00091 GammasPerGd=Detector.GammasPerGd;
00092 attenlGd=Detector.attenlGd;
00093 attenlSc=Detector.attenlSc;
00094 PhotonsPerMeV=Detector.PhotonsPerMeV;
00095 ShortPosFrac0=Detector.ShortPosFrac0;
00096 ShortPosFrac1=Detector.ShortPosFrac1;
00097 LongPosFrac=Detector.LongPosFrac;
00098 ShortPosTime0=Detector.ShortPosTime0;
00099 ShortPosTime1=Detector.ShortPosTime1;
00100 LongPosTime=Detector.LongPosTime;
00101 PMTcoverage=Detector.PMTcoverage;
00102 PMTdiameter=Detector.PMTdiameter;
00103 PMTqe=Detector.PMTqe;
00104 ScintDecayTime=Detector.ScintDecayTime;
00105 for(int i=0;i<4;i++){
00106 a[i] = Detector.a[i];
00107 z[i] = Detector.z[i];
00108 nn[i] = Detector.nn[i];
00109 }
00110
00111 Npmt = Detector.Npmt;
00112 Ncosbins = Detector.Ncosbins;
00113 Nphibins = Detector.Nphibins;
00114
00115 Xpmt = new double[Npmt];
00116 Ypmt = new double[Npmt];
00117 Zpmt = new double[Npmt];
00118
00119 double* pold = Detector.Xpmt+Npmt;
00120 double* pnew = Xpmt+Npmt;
00121 while(pnew>Ypmt)*--pnew=*--pold;
00122
00123 pold = Detector.Ypmt+Npmt;
00124 pnew = Ypmt+Npmt;
00125 while(pnew>Ypmt)*--pnew=*--pold;
00126
00127 pold = Detector.Zpmt+Npmt;
00128 pnew = Zpmt+Npmt;
00129 while(pnew>Zpmt)*--pnew=*--pold;
00130
00131 PHelectron = Detector.PHelectron;
00132 PHpositron = Detector.PHpositron;
00133 PHneutron = Detector.PHneutron;
00134 PHthallium = Detector.PHthallium;
00135 PHbismuth = Detector.PHbismuth;
00136 PHcalifornium = Detector.PHcalifornium;
00137 PHmuon = Detector.PHmuon;
00138
00139 PHeleReco = Detector.PHeleReco;
00140 PHposReco = Detector.PHposReco;
00141 PHneuReco = Detector.PHneuReco;
00142 PHthaReco = Detector.PHthaReco;
00143 PHbisReco = Detector.PHbisReco;
00144 PHcalReco = Detector.PHcalReco;
00145 PHmuoReco = Detector.PHmuoReco;
00146
00147 TimePositron = Detector.TimePositron;
00148 TimeNeutron = Detector.TimeNeutron;
00149
00150 for(int i=0;i<3;i++){
00151 DipolePositron[i] = Detector.DipolePositron[i];
00152 DipoleNeutron[i] = Detector.DipoleNeutron[i];
00153 }
00154
00155 for(int i=0;i<7;i++){
00156 MeanNpe[i]=Detector.MeanNpe[i];
00157 MeanAtten[i] = Detector.MeanAtten[i];
00158 MeanSfactor[i] = Detector.MeanSfactor[i];
00159 }
00160
00161 Nneutron = Detector.Nneutron;
00162 Absorber = new double[Nneutron];
00163 pold = Detector.Absorber+Nneutron;
00164 pnew = Absorber+Nneutron;
00165 while(pnew>Absorber)*--pnew=*--pold;
00166
00167 NeutronSteps = new double[Nneutron];
00168 pold = Detector.NeutronSteps+Nneutron;
00169 pnew = NeutronSteps+Nneutron;
00170 while(pnew>NeutronSteps)*--pnew=*--pold;
00171
00172 Ngamma = Detector.Ngamma;
00173 Rgamma = new double[Ngamma];
00174 pold = Detector.Rgamma+3*Ngamma;
00175 pnew = Rgamma+3*Ngamma;
00176 while(pnew>Rgamma)*--pnew=*--pold;
00177
00178 Egamma = new double[Ngamma];
00179 pold = Detector.Egamma+Ngamma;
00180 pnew = Egamma+Ngamma;
00181 while(pnew>Egamma)*--pnew=*--pold;
00182
00183 Tgamma = new double[Ngamma];
00184 pold = Detector.Tgamma+Ngamma;
00185 pnew = Tgamma+Ngamma;
00186 while(pnew>Tgamma)*--pnew=*--pold;
00187
00188 Ogamma = new std::string[Ngamma];
00189 std::string* rold = Detector.Ogamma+Ngamma;
00190 std::string* rnew = Ogamma+Ngamma;
00191 while(rnew>Ogamma)*--rnew=*--rold;
00192
00193 PMTsize = Detector.PMTsize;
00194 PMTlen = Detector.PMTlen;
00195 PMTdata = new PMT[PMTsize];
00196 PMT* qold = Detector.PMTdata+PMTsize;
00197 PMT* qnew = PMTdata+PMTsize;
00198 while(qnew>PMTdata)*--qnew=*--qold;
00199
00200 PMTpositron = new PMT[Npmt];
00201 qold = Detector.PMTpositron+Npmt;
00202 qnew = PMTpositron+Npmt;
00203 while(qnew>PMTpositron)*--qnew=*--qold;
00204
00205 PMTneutron = new PMT[Npmt];
00206 qold = Detector.PMTneutron+Npmt;
00207 qnew = PMTneutron+Npmt;
00208 while(qnew>PMTneutron)*--qnew=*--qold;
00209
00210 }
00211
00212
00213
00214 ReactorDetector& ReactorDetector::operator=(const ReactorDetector& rhs){
00215
00216 if(this == &rhs)return *this;
00217
00218 R0=rhs.R0;
00219 R1=rhs.R1;
00220 R2=rhs.R2;
00221 GdConcentration=rhs.GdConcentration;
00222 refracGd=rhs.refracGd;
00223 refracSc=rhs.refracSc;
00224 mfpGd=rhs.mfpGd;
00225 mfpSc=rhs.mfpSc;
00226 MeanNeuDispl = rhs.MeanNeuDispl;
00227 FastNeutronOption = rhs.FastNeutronOption;
00228 Temperature = rhs.Temperature;
00229 tGd=rhs.tGd;
00230 tSc=rhs.tSc;
00231 GdCaptureFraction=rhs.GdCaptureFraction;
00232 GammasPerGd=rhs.GammasPerGd;
00233 attenlGd=rhs.attenlGd;
00234 attenlSc=rhs.attenlSc;
00235 PhotonsPerMeV=rhs.PhotonsPerMeV;
00236 ShortPosFrac0=rhs.ShortPosFrac0;
00237 ShortPosFrac1=rhs.ShortPosFrac1;
00238 LongPosFrac=rhs.LongPosFrac;
00239 ShortPosTime0=rhs.ShortPosTime0;
00240 ShortPosTime1=rhs.ShortPosTime1;
00241 LongPosTime=rhs.LongPosTime;
00242 PMTcoverage=rhs.PMTcoverage;
00243 PMTdiameter=rhs.PMTdiameter;
00244 PMTqe=rhs.PMTqe;
00245 ScintDecayTime=rhs.ScintDecayTime;
00246 for(int i=0;i<4;i++){
00247 a[i] = rhs.a[i];
00248 z[i] = rhs.z[i];
00249 nn[i] = rhs.nn[i];
00250 }
00251
00252 Npmt = rhs.Npmt;
00253 Ncosbins = rhs.Ncosbins;
00254 Nphibins = rhs.Nphibins;
00255
00256 delete[] Xpmt;
00257 delete[] Ypmt;
00258 delete[] Zpmt;
00259
00260 Xpmt = new double[Npmt];
00261 Ypmt = new double[Npmt];
00262 Zpmt = new double[Npmt];
00263
00264 double* pold = rhs.Xpmt+Npmt;
00265 double* pnew = Xpmt+Npmt;
00266 while(pnew>Ypmt)*--pnew=*--pold;
00267
00268 pold = rhs.Ypmt+Npmt;
00269 pnew = Ypmt+Npmt;
00270 while(pnew>Ypmt)*--pnew=*--pold;
00271
00272 pold = rhs.Zpmt+Npmt;
00273 pnew = Zpmt+Npmt;
00274 while(pnew>Zpmt)*--pnew=*--pold;
00275
00276 PHelectron = rhs.PHelectron;
00277 PHpositron = rhs.PHpositron;
00278 PHneutron = rhs.PHneutron;
00279 PHthallium = rhs.PHthallium;
00280 PHbismuth = rhs.PHbismuth;
00281 PHcalifornium = rhs.PHcalifornium;
00282 PHmuon = rhs.PHmuon;
00283
00284 PHeleReco = rhs.PHeleReco;
00285 PHposReco = rhs.PHposReco;
00286 PHneuReco = rhs.PHneuReco;
00287 PHthaReco = rhs.PHthaReco;
00288 PHbisReco = rhs.PHbisReco;
00289 PHcalReco = rhs.PHcalReco;
00290 PHmuoReco = rhs.PHmuoReco;
00291
00292 TimePositron = rhs.TimePositron;
00293 TimeNeutron = rhs.TimeNeutron;
00294
00295 for(int i=0;i<3;i++){
00296 DipolePositron[i] = rhs.DipolePositron[i];
00297 DipoleNeutron[i] = rhs.DipoleNeutron[i];
00298 }
00299
00300 for (int i=0;i<7;i++){
00301 MeanNpe[i] = rhs.MeanNpe[i];
00302 MeanAtten[i] = rhs.MeanAtten[i];
00303 MeanSfactor[i] = rhs.MeanSfactor[i];
00304 }
00305
00306 Nneutron = rhs.Nneutron;
00307
00308 delete[] Absorber;
00309 Absorber = new double[Nneutron];
00310 pold = rhs.Absorber+Nneutron;
00311 pnew = Absorber+Nneutron;
00312 while(pnew>Absorber)*--pnew=*--pold;
00313
00314 delete[] NeutronSteps;
00315 NeutronSteps = new double[Nneutron];
00316 pold = rhs.NeutronSteps+Nneutron;
00317 pnew = NeutronSteps+Nneutron;
00318 while(pnew>NeutronSteps)*--pnew=*--pold;
00319
00320 Ngamma = rhs.Ngamma;
00321
00322 delete[] Rgamma;
00323 Rgamma = new double[Ngamma];
00324 pold = rhs.Rgamma+3*Ngamma;
00325 pnew = Rgamma+3*Ngamma;
00326 while(pnew>Rgamma)*--pnew=*--pold;
00327
00328 delete[] Egamma;
00329 Egamma = new double[Ngamma];
00330 pold = rhs.Egamma+Ngamma;
00331 pnew = Egamma+Ngamma;
00332 while(pnew>Egamma)*--pnew=*--pold;
00333
00334 delete[] Tgamma;
00335 Tgamma = new double[Ngamma];
00336 pold = rhs.Tgamma+Ngamma;
00337 pnew = Tgamma+Ngamma;
00338 while(pnew>Tgamma)*--pnew=*--pold;
00339
00340 delete[] Ogamma;
00341 Ogamma = new std::string[Ngamma];
00342 std::string* rold = rhs.Ogamma+Ngamma;
00343 std::string* rnew = Ogamma+Ngamma;
00344 while(rnew>Ogamma)*--rnew=*--rold;
00345
00346 PMTsize = rhs.PMTsize;
00347 PMTlen = rhs.PMTlen;
00348 delete[] PMTdata;
00349 PMTdata = new PMT[PMTsize];
00350 PMT* qold = rhs.PMTdata+PMTsize;
00351 PMT* qnew = PMTdata+PMTsize;
00352 while(qnew>PMTdata)*--qnew=*--qold;
00353
00354 delete[] PMTpositron;
00355 PMTpositron = new PMT[Npmt];
00356 qold = rhs.PMTpositron+Npmt;
00357 qnew = PMTpositron+Npmt;
00358 while(qnew>PMTpositron)*--qnew=*--qold;
00359
00360 delete[] PMTneutron;
00361 PMTneutron = new PMT[Npmt];
00362 qold = rhs.PMTneutron+Npmt;
00363 qnew = PMTneutron+Npmt;
00364 while(qnew>PMTneutron)*--qnew=*--qold;
00365
00366 return *this;
00367
00368 }
00369
00370
00371
00372 ReactorDetector::PMT::PMT(){
00373 npmt=0;
00374 for (int i=0;i<3;i++)xyz[i]=0;
00375 TimeGen=0;
00376 TimeSmr=0;
00377 PHgen=0;
00378 PHsmr=0;
00379 PathGd=0;
00380 PathSc=0;
00381 Sfactor=0;
00382 Atten=0;
00383 Npe=0;
00384 Xpe=0;
00385 Parent="U";
00386
00387 SubHits=0;
00388 SubHitsPtr = new PMT*[0];
00389 }
00390
00391 ReactorDetector::PMT::~PMT(){
00392 delete[] SubHitsPtr;
00393 }
00394
00395 ReactorDetector::PMT::PMT(const ReactorDetector::PMT& p){
00396
00397 npmt=p.npmt;
00398 for (int i=0;i<3;i++)xyz[i]=p.xyz[i];
00399 TimeGen=p.TimeGen;
00400 TimeSmr=p.TimeSmr;
00401 PHgen=p.PHgen;
00402 PHsmr=p.PHsmr;
00403 PathGd=p.PathGd;
00404 PathSc=p.PathSc;
00405 Sfactor=p.Sfactor;
00406 Atten=p.Atten;
00407 Npe=p.Npe;
00408 Xpe=p.Xpe;
00409 Parent=p.Parent;
00410
00411 SubHits=p.SubHits;
00412 SubHitsPtr = new PMT*[SubHits];
00413 PMT** pold = p.SubHitsPtr+SubHits;
00414 PMT** pnew = SubHitsPtr+SubHits;
00415 while(pnew>SubHitsPtr)*--pnew=*--pold;
00416 }
00417
00418
00419
00420 ReactorDetector::PMT&
00421 ReactorDetector::PMT::operator=(const ReactorDetector::PMT& rhs){
00422
00423 if(this == &rhs)return *this;
00424
00425 npmt=rhs.npmt;
00426 for (int i=0;i<3;i++)xyz[i]=rhs.xyz[i];
00427 TimeGen=rhs.TimeGen;
00428 TimeSmr=rhs.TimeSmr;
00429 PHgen=rhs.PHgen;
00430 PHsmr=rhs.PHsmr;
00431 PathGd=rhs.PathGd;
00432 PathSc=rhs.PathSc;
00433 Sfactor=rhs.Sfactor;
00434 Atten=rhs.Atten;
00435 Npe=rhs.Npe;
00436 Xpe=rhs.Xpe;
00437 Parent=rhs.Parent;
00438
00439 SubHits=rhs.SubHits;
00440 delete[] SubHitsPtr;
00441 SubHitsPtr = new PMT*[SubHits];
00442 PMT** pold = rhs.SubHitsPtr+SubHits;
00443 PMT** pnew = SubHitsPtr+SubHits;
00444 while(pnew>SubHitsPtr)*--pnew=*--pold;
00445
00446 return *this;
00447 }
00448 ReactorDetector::PMT
00449 ReactorDetector::PMT::operator+(const ReactorDetector::PMT& rhs){
00450
00451 PMT sum(*this);
00452 if(npmt!=rhs.npmt)return sum;
00453 sum.npmt = npmt;
00454
00455 double w1=Xpe/(Xpe+rhs.Xpe);
00456 double w2=1-w1;
00457
00458 for (int i=0;i<3;i++)sum.xyz[i]=w1*xyz[i]+w2*rhs.xyz[i];
00459 sum.TimeGen=w1*TimeGen+w2*rhs.TimeGen;
00460 sum.TimeSmr=w1*TimeSmr+w2*rhs.TimeSmr;
00461 sum.PHgen=w1*PHgen+w2*rhs.PHgen;
00462 sum.PHsmr=w1*PHsmr+w2*rhs.PHsmr;
00463 sum.PathGd=w1*PathGd+w2*rhs.PathGd;
00464 sum.PathSc=w1*PathSc+w2*rhs.PathSc;
00465 sum.Sfactor=w1*Sfactor+w1*rhs.Sfactor;
00466 sum.Atten=w1*Atten+w2*rhs.Atten;
00467 sum.Npe=Npe+rhs.Npe;
00468 sum.Xpe=Xpe+rhs.Xpe;
00469 if(Parent==rhs.Parent)sum.Parent=rhs.Parent;
00470 else sum.Parent="U";
00471
00472 sum.SubHits = SubHits+rhs.SubHits;
00473 delete[] sum.SubHitsPtr;
00474 sum.SubHitsPtr = new PMT*[sum.SubHits];
00475 PMT** p = sum.SubHitsPtr+sum.SubHits;
00476 PMT** q = SubHitsPtr+SubHits;
00477 PMT** r = rhs.SubHitsPtr+rhs.SubHits;
00478 while(p>sum.SubHitsPtr+SubHits)*--p=*--r;
00479 while(p>sum.SubHitsPtr)*--p=*--q;
00480
00481 return sum;
00482 }
00483 ReactorDetector::PMT&
00484 ReactorDetector::PMT::operator+=(const ReactorDetector::PMT& rhs){
00485
00486 if(npmt!=rhs.npmt)return *this;
00487
00488 double w1=Xpe/(Xpe+rhs.Xpe);
00489 double w2=1-w1;
00490
00491 for (int i=0;i<3;i++)xyz[i]=w1*xyz[i]+w2*rhs.xyz[i];
00492 TimeGen=w1*TimeGen+w2*rhs.TimeGen;
00493 TimeSmr=w1*TimeSmr+w2*rhs.TimeSmr;
00494 PHgen=w1*PHgen+w2*rhs.PHgen;
00495 PHsmr=w1*PHsmr+w2*rhs.PHsmr;
00496 PathGd=w1*PathGd+w2*rhs.PathGd;
00497 PathSc=w1*PathSc+w2*rhs.PathSc;
00498 Sfactor=w1*Sfactor+w1*rhs.Sfactor;
00499 Atten=w1*Atten+w2*rhs.Atten;
00500 Npe+=rhs.Npe;
00501 Xpe+=rhs.Xpe;
00502 if(Parent!=rhs.Parent)Parent="U";
00503
00504 PMT** SubHitsTmp = new PMT*[SubHits];
00505 PMT** p = SubHitsTmp+SubHits;
00506 PMT** q = SubHitsPtr+SubHits;
00507 while(p>SubHitsTmp)*--p=*--q;
00508 delete[] SubHitsPtr;
00509 SubHitsPtr = new PMT*[SubHits+rhs.SubHits];
00510 p = SubHitsPtr+SubHits+rhs.SubHits;
00511 q = SubHitsTmp+SubHits;
00512 PMT** r = rhs.SubHitsPtr+rhs.SubHits;
00513 while(p>SubHitsPtr+SubHits)*--p=*--r;
00514 while(p>SubHitsPtr)*--p=*--q;
00515 SubHits += rhs.SubHits;
00516 delete[] SubHitsTmp;
00517
00518 return *this;
00519 }
00520 void ReactorDetector::PMT::SetSubHitsPtr(int subhits){
00521 delete[] SubHitsPtr;
00522 SubHits = subhits;
00523 SubHitsPtr = new PMT*[subhits];
00524 return;
00525 }
00526
00527
00528
00529
00530
00531 void ReactorDetector::LightsOut(ReactorEvent& Event){
00532
00533 PMTlen=0;
00534 delete[] PMTdata;
00535 PMTdata = new PMT[PMTsize];
00536
00537 GenerateSecondaries(Event);
00538 GenerateGammas(Event);
00539 GenerateResponse(Event);
00540
00541 ConsolidatePMT();
00542
00543 CalculateDipoleMoment("P");
00544 CalculateDipoleMoment("N");
00545
00546 ImproveDipoleMoment("P");
00547 ImproveDipoleMoment("N");
00548 }
00549
00550
00551
00552 void ReactorDetector::GetPMTdata(int npmt,double* XYZpmt,
00553 int& nele,double* PHele,double* Tele,
00554 int& npos,double* PHpos,double* Tpos,
00555 int& nneu,double* PHneu,double* Tneu,
00556 int& ntha,double* PHtha,double* Ttha,
00557 int& nbis,double* PHbis,double* Tbis,
00558 int& ncal,double* PHcal,double* Tcal,
00559 int& nmuo,double* PHmuo,double* Tmuo){
00560
00561 *(XYZpmt+0) = *(Xpmt+npmt);
00562 *(XYZpmt+1) = *(Ypmt+npmt);
00563 *(XYZpmt+2) = *(Zpmt+npmt);
00564
00565 nele=0;
00566 npos=0;
00567 nneu=0;
00568 ntha=0;
00569 nbis=0;
00570 ncal=0;
00571 nmuo=0;
00572
00573 for(PMT* PMTptr=PMTdata;PMTptr<PMTdata+PMTlen;PMTptr++){
00574 if(npmt==(*PMTptr).npmt){
00575 if((*PMTptr).Parent=="E"){
00576 *(PHele+nele) = (*PMTptr).PHsmr;
00577 *(Tele+nele) = (*PMTptr).TimeSmr;
00578 nele++;
00579 }
00580 if((*PMTptr).Parent=="P"){
00581 *(PHpos+npos) = (*PMTptr).PHsmr;
00582 *(Tpos+npos) = (*PMTptr).TimeSmr;
00583 npos++;
00584 }
00585 if((*PMTptr).Parent=="N"){
00586 *(PHneu+nneu) = (*PMTptr).PHsmr;
00587 *(Tneu+nneu) = (*PMTptr).TimeSmr;
00588 nneu++;
00589 }
00590 if((*PMTptr).Parent=="Tl"){
00591 *(PHtha+ntha) = (*PMTptr).PHsmr;
00592 *(Ttha+ntha) = (*PMTptr).TimeSmr;
00593 ntha++;
00594 }
00595 if((*PMTptr).Parent=="Bi"){
00596 *(PHbis+nbis) = (*PMTptr).PHsmr;
00597 *(Tbis+nbis) = (*PMTptr).TimeSmr;
00598 nbis++;
00599 }
00600 if((*PMTptr).Parent=="Cf"){
00601 *(PHcal+ncal) = (*PMTptr).PHsmr;
00602 *(Tcal+ncal) = (*PMTptr).TimeSmr;
00603 ncal++;
00604 }
00605 if((*PMTptr).Parent=="muon"){
00606 *(PHmuo+nmuo) = (*PMTptr).PHsmr;
00607 *(Tmuo+nmuo) = (*PMTptr).TimeSmr;
00608 nmuo++;
00609 }
00610 }
00611 }
00612 return;
00613 }
00614 void ReactorDetector::GenerateSecondaries(ReactorEvent& Event){
00615
00616
00617
00618
00619
00620 int Npositron = Event.GetNumPositron();
00621
00622
00623 double Rpos[Event.Rdim*Npositron];
00624
00625
00626 for(int n=0;n<Npositron;n++){
00627
00628 double kepos = Event.GetPositronKE(n);
00629 double tpos = 0.;
00630 double rangepos = 0.;
00631 PositronRange(kepos,rangepos,tpos);
00632 tpos+=Event.GetPositronTime(n);
00633
00634 double cospos = Event.GetPositronCosTheta(n);
00635 double phipos = Event.GetPositronPhi(n);
00636
00637 double rint[3];
00638 for(int i=0;i<3;i++){
00639 rint[i] = *(Event.GetPositronVertexXYZ()+(i+n*Event.Rdim));
00640 }
00641
00642 double rpos[3];
00643 rpos[0]=rint[0]+rangepos*sqrt(1-cospos*cospos)*cos(phipos);
00644 rpos[1]=rint[1]+rangepos*sqrt(1-cospos*cospos)*sin(phipos);
00645 rpos[2]=rint[2]+rangepos*cospos;
00646 double rrpos = sqrt(rpos[0]*rpos[0]+rpos[1]*rpos[1]+rpos[2]*rpos[2]);
00647
00648
00649
00650 Rpos[0+n*Event.Rdim] = tpos;
00651 for(int i=1;i<4;i++)Rpos[i+n*Event.Rdim]=rpos[i-1];
00652 Rpos[4+n*Event.Rdim] = rrpos;
00653 Rpos[5+n*Event.Rdim] = rpos[2]/rrpos;
00654 Rpos[6+n*Event.Rdim] = atan2(rpos[1],rpos[0]);
00655 if(Rpos[6+n*Event.Rdim]<0)Rpos[6+n*Event.Rdim]+=2*RC.pi;
00656 Event.SetPositronVertex(n,Rpos);
00657 }
00658
00659
00660
00661
00662
00663 int Nneutron = Event.GetNumNeutron();
00664
00665
00666 delete[] Absorber;
00667 delete[] NeutronSteps;
00668
00669 Absorber = new double[Nneutron];
00670 NeutronSteps = new double[Nneutron];
00671
00672 double Rneu[Event.Rdim*Nneutron];
00673
00674
00675 for(int n=0;n<Nneutron;n++){
00676
00677 double rneu[3];
00678 double tneu = 0.;
00679 if(FastNeutronOption){
00680
00681
00682
00683 float rn[3];
00684 int len=3;
00685 rnormx_(rn,len,ranlux_);
00686
00687
00688
00689 len=1;
00690 float rv[1];
00691 ranlux_(rv,len);
00692
00693
00694
00695
00696
00697 double rint[3];
00698 for(int i=0;i<3;i++){
00699 rint[i] = *(Event.GetNeutronVertexXYZ()+(i+n*Event.Rdim));
00700 }
00701
00702 double rrint = sqrt(rint[0]*rint[0]+rint[1]*rint[1]+rint[2]*rint[2]);
00703 double path = 0.;
00704 if(rrint<=R0){
00705 for (int i=0;i<3;i++)rneu[i]=rint[i]+mfpGd*rn[i]/sqrt(3.);
00706 path = mfpGd*sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00707 tneu = tGd*sqrt(path/mfpGd)*log(1/rv[0]);
00708 }
00709 else if(rrint<R2){
00710 for (int i=0;i<3;i++)rneu[i]=rint[i]+mfpSc*rn[i]/sqrt(3.);
00711 path = mfpSc*sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00712 tneu = tSc*sqrt(path/mfpSc)*log(1/rv[0]);
00713 }
00714 else{
00715 for (int i=0;i<3;i++)rneu[i]=999999;
00716 tneu = 999999.;
00717 }
00718
00719
00720
00721 rneu[2]+=MeanNeuDispl;
00722 }
00723 else{
00724 double pneu[3];
00725 for(int i=0;i<3;i++){
00726 pneu[i]=*(Event.GetNeutronPxyz()+(i+n*Event.Pdim));
00727
00728 }
00729 for(int i=0;i<3;i++){
00730 rneu[i]=*(Event.GetNeutronVertexXYZ()+(i+n*Event.Rdim));
00731
00732 }
00733 double keneu = Event.GetNeutronKE(n);
00734 NeutronSteps[n]=0.;
00735 Absorber[n]=0.;
00736 NeutronPropagator(R0,R2,keneu,Absorber[n],NeutronSteps[n],
00737 pneu,rneu,tneu,Temperature,a,z,nn);
00738
00739
00740 tneu+=Event.GetNeutronTime(n);
00741
00742 }
00743
00744
00745
00746 Rneu[0+n*Event.Rdim] = tneu;
00747 for(int i=1;i<4;i++)Rneu[i+n*Event.Rdim]=rneu[i-1];
00748 double rrneu = sqrt(rneu[0]*rneu[0]+rneu[1]*rneu[1]+rneu[2]*rneu[2]);
00749 Rneu[4+n*Event.Rdim] = rrneu;
00750 Rneu[5+n*Event.Rdim] = rneu[2]/rrneu;
00751 Rneu[6+n*Event.Rdim] = atan2(rneu[1],rneu[0]);
00752 if(Rneu[6+n*Event.Rdim]<0)Rneu[6+n*Event.Rdim]+=2*RC.pi;
00753 Event.SetNeutronVertex(n,Rneu);
00754 }
00755
00756
00757
00758
00759 }
00760
00761 void ReactorDetector::GenerateResponse(ReactorEvent& Event){
00762
00763
00764
00765 PHelectron = 0;
00766 PHpositron = 0;
00767 PHneutron = 0;
00768 PHthallium = 0;
00769 PHbismuth = 0;
00770 PHcalifornium = 0;
00771 PHmuon = 0;
00772
00773 PHeleReco = 0;
00774 PHposReco = 0;
00775 PHneuReco = 0;
00776 PHthaReco = 0;
00777 PHbisReco = 0;
00778 PHcalReco = 0;
00779 PHmuoReco = 0;
00780
00781 for(int i=0;i<7;i++){
00782 MeanSfactor[i] = 0;
00783 MeanAtten[i] = 0;
00784 MeanNpe[i] = 0;
00785 }
00786
00787
00788
00789 int pmtindex=0;
00790 double* xpmt=Xpmt;
00791 double* ypmt=Ypmt;
00792 double* zpmt=Zpmt;
00793
00794 PMT* PMTptr = PMTdata;
00795
00796
00797 for(int i=0;i<Ncosbins;i++){
00798 for(int j=0;j<Nphibins;j++){
00799 double rpmt[3];
00800 rpmt[0] = *xpmt++;
00801 rpmt[1] = *ypmt++;
00802 rpmt[2] = *zpmt++;
00803
00804 double r[3];
00805 double dr[3];
00806 double tr[3];
00807
00808 double sumele[6]={0,0,0,0,0,0};
00809 double sumpos[6]={0,0,0,0,0,0};
00810 double sumneu[6]={0,0,0,0,0,0};
00811 double sumtha[6]={0,0,0,0,0,0};
00812 double sumbis[6]={0,0,0,0,0,0};
00813 double sumcal[6]={0,0,0,0,0,0};
00814 double summuo[6]={0,0,0,0,0,0};
00815
00816 double* rgptr=Rgamma;
00817 double* egptr=Egamma;
00818 double* tgptr=Tgamma;
00819 std::string* ogptr=Ogamma;
00820
00821 int nelegt0=0;
00822 int nposgt0=0;
00823 int nneugt0=0;
00824 int nthagt0=0;
00825 int nbisgt0=0;
00826 int ncalgt0=0;
00827 int nmuogt0=0;
00828
00829 for(int k=0;k<Ngamma;k++){
00830
00831 for (int l=0;l<3;l++)r[l]=*rgptr++;
00832 double rdotr = r[0]*r[0]+r[1]*r[1]+r[2]*r[2];
00833
00834
00835
00836
00837 if(sqrt(rdotr)>R1){
00838 double dummy = *egptr++;
00839 dummy = *tgptr++;
00840 std::string sdummy = *ogptr++;
00841 continue;
00842 }
00843
00844 for (int l=0;l<3;l++)dr[l]=rpmt[l]-r[l];
00845 double ddr = sqrt(dr[0]*dr[0]+dr[1]*dr[1]+dr[2]*dr[2]);
00846
00847 for (int l=0;l<3;l++)tr[l]=dr[l]/ddr;
00848 double tdotr = r[0]*tr[0]+r[1]*tr[1]+r[2]*tr[2];
00849
00850
00851
00852
00853 double sGd;
00854 double sSc;
00855
00856
00857
00858 double test = R0*R0+tdotr*tdotr-rdotr;
00859 bool inter = (test>=0);
00860
00861
00862
00863
00864
00865
00866 if(inter){
00867 double sint1 = -tdotr+sqrt(test);
00868 double sint2 = -tdotr-sqrt(test);
00869 if(sint1>0&&sint2<0){
00870 sGd = sint1;
00871 }
00872 else if(sint2>0&&sint1<0){
00873 sGd = sint2;
00874 }
00875 else if(sint2>0&&sint1>0){
00876 sGd = sint1-sint2;
00877 if(sGd<0)sGd*=-1;
00878 }
00879 else{
00880 sGd = 0;
00881 }
00882 sSc = ddr-sGd;
00883 }
00884
00885
00886
00887 else{
00888 sGd = 0;
00889 sSc = ddr;
00890 }
00891
00892
00893
00894
00895 double dsGd = sGd-R0;
00896 double dsSc = sSc-R2+R0;
00897 double atten0 = exp(-sGd/attenlGd-sSc/attenlSc);
00898 double atten = exp(-dsGd/attenlGd-dsSc/attenlSc);
00899
00900
00901
00902 double sfactor=0;
00903 for (int l=0;l<3;l++){sfactor+=tr[l]*rpmt[l]/R2;}
00904 sfactor *= R2*R2/ddr/ddr;
00905
00906
00907
00908 double phgen = *egptr++;
00909
00910
00911 float xpe = (phgen*PhotonsPerMeV);
00912 xpe *= (atten0*sfactor);
00913 xpe *= (PMTcoverage/Npmt*PMTqe);
00914
00915
00916 int npe;
00917 int error;
00918 rnpssn_(xpe,npe,error);
00919
00920
00921 double phsmr = npe/PMTqe/PMTcoverage/PhotonsPerMeV;
00922
00923
00924 double tgen = *tgptr++;
00925
00926 double tsmr = refracGd*sGd/RC.c+refracSc*sSc/RC.c + tgen;
00927
00928
00929 std::string type = *ogptr++;
00930
00931 if(type == "E"){
00932 nelegt0++;
00933 sumele[0]+=phsmr;
00934 sumele[1]+=phgen;
00935 sumele[2]+=phgen*atten0*sfactor;
00936 sumele[3]+=npe;
00937 sumele[4]+=sfactor;
00938 sumele[5]+=atten;
00939
00940 PHelectron+=phsmr;
00941 }
00942 else if(type == "P"){
00943 nposgt0++;
00944 sumpos[0]+=phsmr;
00945 sumpos[1]+=phgen;
00946 sumpos[2]+=phgen*atten0*sfactor;
00947 sumpos[3]+=npe;
00948 sumpos[4]+=sfactor;
00949 sumpos[5]+=atten;
00950
00951 PHpositron+=phsmr;
00952 }
00953 else if(type == "N"){
00954 nneugt0++;
00955 sumneu[0]+=phsmr;
00956 sumneu[1]+=phgen;
00957 sumneu[2]+=phgen*atten0*sfactor;
00958 sumneu[3]+=npe;
00959 sumneu[4]+=sfactor;
00960 sumneu[5]+=atten;
00961
00962 PHneutron+=phsmr;
00963 }
00964 else if(type == "Tl"){
00965 nthagt0++;
00966 sumtha[0]+=phsmr;
00967 sumtha[1]+=phgen;
00968 sumtha[2]+=phgen*atten0*sfactor;
00969 sumtha[3]+=npe;
00970 sumtha[4]+=sfactor;
00971 sumtha[5]+=atten;
00972
00973 PHthallium+=phsmr;
00974 }
00975 else if(type == "Bi"){
00976 nbisgt0++;
00977 sumbis[0]+=phsmr;
00978 sumbis[1]+=phgen;
00979 sumbis[2]+=phgen*atten0*sfactor;
00980 sumbis[3]+=npe;
00981 sumbis[4]+=sfactor;
00982 sumbis[5]+=atten;
00983
00984 PHbismuth+=phsmr;
00985 }
00986 else if(type == "Cf"){
00987 ncalgt0++;
00988 sumcal[0]+=phsmr;
00989 sumcal[1]+=phgen;
00990 sumcal[2]+=phgen*atten0*sfactor;
00991 sumcal[3]+=npe;
00992 sumcal[4]+=sfactor;
00993 sumcal[5]+=atten;
00994
00995 PHcalifornium+=phsmr;
00996 }
00997 else if(type == "muon"){
00998 nmuogt0++;
00999 summuo[0]+=phsmr;
01000 summuo[1]+=phgen;
01001 summuo[2]+=phgen*atten0*sfactor;
01002 summuo[3]+=npe;
01003 summuo[4]+=sfactor;
01004 summuo[5]+=atten;
01005
01006 PHmuon+=phsmr;
01007 }
01008 else{
01009 cout << " ERROR: GenerateResponse has unrecognized type "
01010 << type << endl;
01011 }
01012
01013 PMT PMTtmp;
01014 PMTtmp.npmt = pmtindex;
01015 for(int l=0;l<3;l++)PMTtmp.xyz[l] = rpmt[l];
01016 PMTtmp.PHgen = phgen;
01017 PMTtmp.PHsmr = phsmr;
01018 PMTtmp.PathGd = sGd;
01019 PMTtmp.PathSc = sSc;
01020 PMTtmp.Atten = atten;
01021 PMTtmp.Sfactor = sfactor;
01022 PMTtmp.TimeGen = tgen;
01023 PMTtmp.TimeSmr = tsmr;
01024 PMTtmp.Xpe = xpe;
01025 PMTtmp.Npe = npe;
01026 PMTtmp.Parent = type;
01027
01028 if(PMTptr<PMTdata+PMTsize){
01029 *PMTptr++=PMTtmp;
01030 PMTlen++;
01031 }
01032 else{
01033
01034
01035
01036 PMTptr = ResizePMT();
01037 *PMTptr++=PMTtmp;
01038 PMTlen++;
01039 }
01040 }
01041
01042
01043
01044
01045
01046
01047 if(sumpos[2]>0){
01048 PHposReco+=sumpos[0]*sumpos[1]/sumpos[2];
01049 MeanNpe[0]+=sumpos[3]/Npmt;
01050 MeanSfactor[0]+=sumpos[4]/Npmt/nposgt0;
01051 MeanAtten[0]+=sumpos[5]/Npmt/nposgt0;
01052 }
01053 if(sumneu[2]>0){
01054 PHneuReco+=sumneu[0]*sumneu[1]/sumneu[2];
01055 MeanNpe[1]+=sumneu[3]/Npmt;
01056 MeanSfactor[1]+=sumneu[4]/Npmt/nneugt0;
01057 MeanAtten[1]+=sumneu[5]/Npmt/nneugt0;
01058 }
01059 if(sumtha[2]>0){
01060 PHthaReco+=sumtha[0]*sumtha[1]/sumtha[2];
01061 MeanNpe[2]+=sumtha[3]/Npmt;
01062 MeanSfactor[2]+=sumtha[4]/Npmt/nthagt0;
01063 MeanAtten[2]+=sumtha[5]/Npmt/nthagt0;
01064 }
01065 if(sumbis[2]>0){
01066 PHbisReco+=sumbis[0]*sumbis[1]/sumbis[2];
01067 MeanNpe[3]+=sumbis[3]/Npmt;
01068 MeanSfactor[3]+=sumbis[4]/Npmt/nbisgt0;
01069 MeanAtten[3]+=sumbis[5]/Npmt/nbisgt0;
01070 }
01071 if(sumcal[2]>0){
01072 PHcalReco+=sumcal[0]*sumcal[1]/sumcal[2];
01073 MeanNpe[4]+=sumcal[3]/Npmt;
01074 MeanSfactor[4]+=sumcal[4]/Npmt/ncalgt0;
01075 MeanAtten[4]+=sumcal[5]/Npmt/ncalgt0;
01076 }
01077 if(summuo[2]>0){
01078 PHmuoReco+=summuo[0]*summuo[1]/summuo[2];
01079 MeanNpe[5]+=summuo[3]/Npmt;
01080 MeanSfactor[5]+=summuo[4]/Npmt/nmuogt0;
01081 MeanAtten[5]+=summuo[5]/Npmt/nmuogt0;
01082 }
01083 if(sumele[2]>0){
01084 PHeleReco+=sumele[0]*sumele[1]/sumele[2];
01085 MeanNpe[6]+=sumele[3]/Npmt;
01086 MeanSfactor[6]+=sumele[4]/Npmt/nelegt0;
01087 MeanAtten[6]+=sumele[5]/Npmt/nelegt0;
01088 }
01089
01090
01091
01092 pmtindex++;
01093 }
01094 }
01095 }
01096
01097 void ReactorDetector::GenerateGammas(ReactorEvent& Event){
01098
01099
01100
01101
01102 int ngamma = Event.GetNumGamma();
01103
01104
01105 int maxgamma = 100+ngamma;
01106 double* egamma = new double[maxgamma];
01107 double* tgamma = new double[maxgamma];
01108 double* rgamma = new double[3*maxgamma];
01109 std::string* ogamma = new std::string[maxgamma];
01110
01111 double* egptr=egamma;
01112 double* rgptr=rgamma;
01113 double* tgptr=tgamma;
01114 std::string* ogptr=ogamma;
01115
01116
01117
01118 for(int n=0;n<ngamma;n++){
01119
01120 *egptr++ = Event.GetGammaKE(n);
01121
01122 for(int i=0;i<3;i++)
01123 *rgptr++ = *(Event.GetGammaVertexXYZ()+(i+n*Event.Rdim));
01124
01125 *tgptr++ = Event.GetGammaTime(n);
01126
01127 if(Event.GetGammaParentProcess(n) == 1){
01128 cout << "ERROR: gammas are not produced by inverse-beta decay" << endl;
01129 }
01130 else if(Event.GetGammaParentProcess(n) == 2){
01131 *ogptr++ = "Cf";
01132 }
01133 else if(Event.GetGammaParentProcess(n) == 3){
01134 *ogptr++ = "muon";
01135 }
01136 else{
01137 cout << "Process Id " << Event.GetGammaParentProcess(n) << " is unknown"
01138 << endl;
01139 }
01140 }
01141
01142
01143
01144 if(Event.GetPmtRad() == "on"){
01145
01146
01147 int len = 2;
01148 float r[len];
01149 ranlux_(r,len);
01150 int pmtId = r[0]*Npmt;
01151
01152
01153 std::string Stuff; int Isotope;
01154
01155
01156
01157 if(r[1] < 0.25){
01158 Stuff = "thallium"; Isotope = 208;
01159 }
01160 else if(0.25 <= r[1] && r[1] < 0.5){
01161 Stuff = "thallium"; Isotope = 210;
01162 }
01163 else if(0.5 <= r[1] && r[1] < 0.75){
01164 Stuff = "bismuth"; Isotope = 212;
01165 }
01166 else{
01167 Stuff = "bismuth"; Isotope = 214;
01168 }
01169
01170
01171
01172
01173 if(Stuff == "thallium"){
01174 MyTlSource Thallium(Isotope);
01175
01176
01177 float PMTWeight[Thallium.GetNumTlGammas()];
01178
01179
01180 for(int n=0;n<Thallium.GetNumTlGammas();n++){
01181
01182
01183 float e = Thallium.GetTlGammaEnergy(n);
01184 *egptr++ = e;
01185
01186
01187 PMTWeight[n] = 1.;
01188 int attempts = 1;
01189 double r[3];
01190 double time;
01191
01192
01193 int len=4;
01194 float rv[len];
01195 ranlux_(rv,len);
01196 double cosg = -1+2*rv[0];
01197 double phig = 2*RC.pi*rv[1];
01198 double t[3];
01199 t[0] = cos(phig)*sqrt(1-cosg*cosg);
01200 t[1] = sin(phig)*sqrt(1-cosg*cosg);
01201 t[2] = cosg;
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 double range;
01212 std::string material = "oil";
01213 range = GammaComptonRange(material,e);
01214 range*=log(1/rv[2]);
01215
01216
01217 r[0] = Xpmt[pmtId]+range*t[0];
01218 r[1] = Ypmt[pmtId]+range*t[1];
01219 r[2] = Zpmt[pmtId]+range*t[2];
01220
01221 double rdotr = r[0]*r[0]+r[1]*r[1]+r[2]*r[2];
01222 if(sqrt(rdotr)<R1){
01223 pmtRadCount++;
01224 cout << "PMTrad Tl " << pmtRadCount << " radius " << sqrt(rdotr)
01225 << ", energy " << e << endl;
01226 }
01227
01228
01229 for(int i=0;i<3;i++) *rgptr++ = r[i];
01230
01231
01232 time = rv[3]*1000000.;
01233
01234 *tgptr++ = time;
01235 *ogptr++ = "Tl";
01236
01237 PMTWeight[n] = 1./float(attempts);
01238
01239
01240 ngamma++;
01241 }
01242 }
01243
01244
01245
01246 else if(Stuff == "bismuth"){
01247 MyBiSource Bismuth(Isotope);
01248
01249
01250 float PMTWeight[Bismuth.GetNumBiGammas()];
01251
01252
01253 for(int n=0;n<Bismuth.GetNumBiGammas();n++){
01254
01255
01256 float e = Bismuth.GetBiGammaEnergy(n);
01257 *egptr++ = e;
01258
01259
01260 PMTWeight[n] = 1.;
01261 int attempts = 1;
01262 double r[3];
01263 double time;
01264
01265
01266 int len=4;
01267 float rv[len];
01268 ranlux_(rv,len);
01269 double cosg = -1+2*rv[0];
01270 double phig = 2*RC.pi*rv[1];
01271 double t[3];
01272 t[0] = cos(phig)*sqrt(1-cosg*cosg);
01273 t[1] = sin(phig)*sqrt(1-cosg*cosg);
01274 t[2] = cosg;
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 double range;
01285 std::string material = "oil";
01286 range = GammaComptonRange(material,e);
01287 range*=log(1/rv[2]);
01288
01289
01290 r[0] = Xpmt[pmtId]+range*t[0];
01291 r[1] = Ypmt[pmtId]+range*t[1];
01292 r[2] = Zpmt[pmtId]+range*t[2];
01293
01294 double rdotr = r[0]*r[0]+r[1]*r[1]+r[2]*r[2];
01295 if(sqrt(rdotr)<R1){
01296 pmtRadCount++;
01297 cout << "PMTrad Bi " << pmtRadCount << " radius " << sqrt(rdotr)
01298 << ", energy " << e << endl;
01299 }
01300
01301
01302 for(int i=0;i<3;i++) *rgptr++ = r[i];
01303
01304
01305 time = rv[3]*1000000.;
01306
01307 *tgptr++ = time;
01308 *ogptr++ = "Bi";
01309
01310 PMTWeight[n] = 1./float(attempts);
01311
01312
01313 ngamma++;
01314 }
01315 }
01316 }
01317
01318
01319
01320 int Nelectron = Event.GetNumElectron();
01321
01322
01323
01324 for(int n=0;n<Nelectron;n++){
01325
01326 double rele[3];
01327 for(int i=0;i<3;i++){
01328 rele[i] = *(Event.GetElectronVertexXYZ()+(i+n*Event.Rdim));
01329
01330 }
01331 double tele = Event.GetElectronTime(n);
01332
01333 double keele = Event.GetElectronKE(n);
01334
01335
01336
01337
01338 for(int i=0;i<3;i++)*rgptr++=rele[i];
01339 *tgptr++ = tele;
01340 *egptr++ = keele;
01341 *ogptr++ = "E";
01342 ngamma++;
01343 }
01344
01345
01346
01347
01348 int Npositron = Event.GetNumPositron();
01349
01350
01351
01352 for(int n=0;n<Npositron;n++){
01353
01354 double rpos[3];
01355 for(int i=0;i<3;i++){
01356 rpos[i] = *(Event.GetPositronVertexXYZ()+(i+n*Event.Rdim));
01357
01358 }
01359 double tpos = Event.GetPositronTime(n);
01360
01361 double kepos = Event.GetPositronKE(n);
01362
01363
01364
01365
01366
01367 for(int i=0;i<3;i++)*rgptr++=rpos[i];
01368 *tgptr++ = tpos;
01369 *egptr++ = kepos;
01370 *ogptr++ = "P";
01371 ngamma++;
01372
01373
01374
01375 int len=4;
01376 float rv[4];
01377 ranlux_(rv,len);
01378 double cosg = -1+2*rv[0];
01379 double phig = 2*RC.pi*rv[1];
01380 double t[3];
01381 t[0] = cos(phig)*sqrt(1-cosg*cosg);
01382 t[1] = sin(phig)*sqrt(1-cosg*cosg);
01383 t[2] = cosg;
01384 double range;
01385 for (int i=0;i<2;i++){
01386 std::string material = "scintillator";
01387 range = GammaComptonRange(material,RC.Melectron);
01388 range*=log(1/rv[i+2]);
01389 if(i==0){
01390 for(int j=0;j<3;j++) *rgptr++ = rpos[j]+range*t[j];
01391 }
01392 if(i==1){
01393 for(int j=0;j<3;j++)*rgptr++ = rpos[j]-range*t[j];
01394 }
01395 *egptr++=RC.Melectron;
01396 *tgptr++=tpos+range/RC.c*refracSc;
01397 *ogptr++ = "P";
01398 ngamma++;
01399 }
01400 }
01401
01402
01403
01404
01405 Nneutron = Event.GetNumNeutron();
01406
01407
01408
01409 for(int n=0;n<Nneutron;n++){
01410
01411 double rneu[3];
01412 for(int i=0;i<3;i++){
01413 rneu[i] = *(Event.GetNeutronVertexXYZ()+(i+n*Event.Rdim));
01414
01415 }
01416 double tneu = Event.GetNeutronTime(n);
01417
01418
01419
01420
01421 double emax=RC.Hpeak;
01422 if(FastNeutronOption){
01423
01424 Absorber[n]=1;
01425 double rrneu = sqrt(rneu[0]*rneu[0]+rneu[1]*rneu[1]+rneu[2]*rneu[2]);
01426 if(rrneu<R0){
01427 int len=2;
01428 float rv[2];
01429 ranlux_(rv,len);
01430 if(rv[0]<=GdCaptureFraction){
01431
01432
01433
01434 if(rv[1]<=RC.Gd155frac){
01435 emax = RC.Gd155peak;
01436 Absorber[n]=155;
01437 }
01438 else{
01439 emax = RC.Gd157peak;
01440 Absorber[n]=157;
01441 }
01442 }
01443 }
01444 }
01445 else{
01446
01447 if(Absorber[n]==1)emax=RC.Hpeak;
01448 if(Absorber[n]==12)emax=RC.Cpeak;
01449 if(Absorber[n]==155)emax=RC.Gd155peak;
01450 if(Absorber[n]==157)emax=RC.Gd157peak;
01451 }
01452
01453
01454
01455 if(emax==RC.Hpeak || emax==RC.Cpeak){
01456
01457 int len=3;
01458 float rv[3];
01459 ranlux_(rv,len);
01460 std::string material = "scintillator";
01461 double range = GammaComptonRange(material,emax);
01462 range*=log(1/rv[0]);
01463 double cosg = -1+2*rv[1];
01464 double phig = 2*RC.pi*rv[2];
01465 double t[3];
01466 t[0] = cos(phig)*sqrt(1-cosg*cosg);
01467 t[1] = sin(phig)*sqrt(1-cosg*cosg);
01468 t[2] = cosg;
01469 for(int j=0;j<3;j++)*rgptr++ = rneu[j]+range*t[j];
01470 *egptr++ = emax;
01471 *tgptr++ = tneu+range/RC.c*refracSc;
01472 *ogptr++ = "N";
01473 ngamma++;
01474
01475 }
01476
01477
01478
01479 else{
01480
01481 int ngd;
01482 double pgd[3*maxgamma];
01483 MyGdDecayModel(emax,ngd,pgd);
01484 float rv2[ngd];
01485 ranlux_(rv2,ngd);
01486 double* qgd=pgd;
01487 double check[4]={0,0,0,0};
01488 for(int i=0;i<ngd;i++){
01489 double p[3];
01490 for(int j=0;j<3;j++)p[j]=*qgd++;
01491 double e = sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
01492 std::string material = "scintillator";
01493 double range = GammaComptonRange(material,e);
01494 range*=log(1/rv2[i]);
01495 for(int j=0;j<3;j++)*rgptr++ = rneu[j]+range*p[j]/e;
01496
01497 for(int j=0;j<3;j++)check[j]+=p[j];
01498 check[3]+=e;
01499
01500 *egptr++ = e;
01501 *tgptr++ = tneu+range/RC.c*refracGd;
01502 *ogptr++ = "N";
01503 ngamma++;
01504
01505 }
01506 }
01507 }
01508
01509
01510
01511
01512 delete[] Rgamma;
01513 delete[] Egamma;
01514 delete[] Tgamma;
01515 delete[] Ogamma;
01516
01517 Ngamma = ngamma;
01518 Rgamma = new double[3*ngamma];
01519 Egamma = new double[ngamma];
01520 Tgamma = new double[ngamma];
01521 Ogamma = new std::string[ngamma];
01522
01523 double* ptr;
01524
01525 ptr = Rgamma+3*ngamma;
01526 while(ptr>Rgamma)*--ptr=*--rgptr;
01527
01528 ptr = Egamma+ngamma;
01529 while(ptr>Egamma)*--ptr=*--egptr;
01530
01531 ptr = Tgamma+ngamma;
01532 while(ptr>Tgamma)*--ptr=*--tgptr;
01533
01534 std::string* qtr = Ogamma+ngamma;
01535 while(qtr>Ogamma)*--qtr=*--ogptr;
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 delete[] rgamma;
01551 delete[] egamma;
01552 delete[] tgamma;
01553 delete[] ogamma;
01554 }
01555
01556
01557 ReactorDetector::PMT* ReactorDetector::ResizePMT(){
01558
01559 int oldsize = PMTsize;
01560 int newsize = 2*oldsize;
01561 PMT* PMThold = new PMT[newsize];
01562 PMT* PMTold = PMTdata+oldsize;
01563 PMT* PMTnew = PMThold+oldsize;
01564 while(PMTnew>PMThold)*--PMTnew=*--PMTold;
01565 delete[] PMTdata;
01566 PMTdata = new PMT[newsize];
01567 PMTold = PMThold+newsize;
01568 PMTnew = PMTdata+newsize;
01569 while(PMTnew>PMTdata)*--PMTnew=*--PMTold;
01570 delete[] PMThold;
01571 PMTsize = newsize;
01572 return PMTdata+oldsize;
01573 }
01574
01575
01576
01577 int ReactorDetector::GetNgamma(std::string parent){
01578 int gamma=0;
01579 for(std::string* optr=Ogamma;optr<Ogamma+Ngamma;optr++){
01580 if (*optr==parent)gamma++;
01581 }
01582 return gamma;
01583 }
01584
01585
01586
01587 void ReactorDetector::GetGamma(std::string parent,double* xyz){
01588
01589 double* Rptr=Rgamma;
01590 double* rptr=xyz;
01591
01592 for(std::string* optr=Ogamma;optr<Ogamma+Ngamma;optr++){
01593 if (*optr==parent){
01594 for(int i=0;i<3;i++)*rptr++ = *Rptr++;
01595 }
01596 }
01597 }
01598 void ReactorDetector::GetGamma(std::string parent,double* e,
01599 double* t,double* r,
01600 double* c,double* f){
01601
01602
01603 double* Eptr=Egamma;
01604 double* Rptr=Rgamma;
01605 double* Tptr=Tgamma;
01606 double* eptr=e;
01607 double* rptr=r;
01608 double* tptr=t;
01609 double* cptr=c;
01610 double* fptr=f;
01611
01612 for(std::string* optr=Ogamma;optr<Ogamma+Ngamma;optr++){
01613 if (*optr==parent){
01614 *e++=*Eptr;
01615 *t++=*Tptr;
01616 double x=*(Rptr+0);
01617 double y=*(Rptr+1);
01618 double z=*(Rptr+2);
01619 *r++=sqrt(x*x+y*y+z*z);
01620 *c++=z/sqrt(x*x+y*y+z*z);
01621 *f++=atan2(y,x);
01622 if((*f)<0)*f+=2*RC.pi;
01623 }
01624 Eptr++;
01625 Tptr++;
01626 Rptr+=3;
01627 }
01628 }
01629 void ReactorDetector::SetNominalParameters(){
01630
01631
01632
01633 R0 = RC.R0;
01634 R1 = RC.R1;
01635 R2 = RC.R2;
01636
01637 GdConcentration=RC.GdConcentration;
01638
01639 refracGd = RC.refracGd;
01640 refracSc = RC.refracSc;
01641
01642 mfpGd = RC.mfpGd;
01643 mfpSc = RC.mfpSc;
01644
01645 MeanNeuDispl = RC.MeanNeuDispl;
01646
01647 FastNeutronOption = RC.FastNeutronOption;
01648 Temperature = RC.Temperature;
01649
01650 tGd = RC.tGd;
01651 tSc = RC.tSc;
01652
01653 GdCaptureFraction = RC.GdCaptureFraction;
01654
01655
01656
01657
01658
01659 GammasPerGd = RC.GammasPerGd;
01660
01661 attenlGd = RC.attenlGd;
01662 attenlSc = RC.attenlSc;
01663
01664 PhotonsPerMeV = RC.PhotonsPerMeV;
01665
01666 ShortPosFrac0 = RC.ShortPosFrac0;
01667 ShortPosFrac1 = RC.ShortPosFrac1;
01668 LongPosFrac = RC.LongPosFrac;
01669 ShortPosTime0 = RC.ShortPosTime0;
01670 ShortPosTime1 = RC.ShortPosTime1;
01671 LongPosTime = RC.LongPosTime;
01672
01673 PMTcoverage = RC.PMTcoverage;
01674 PMTdiameter = RC.PMTdiameter;
01675
01676 PMTqe = RC.PMTqe;
01677 }
01678 void ReactorDetector::SetPMT(){
01679
01680
01681
01682
01683 Npmt = 16*R2*R2*PMTcoverage/PMTdiameter/PMTdiameter;
01684 Ncosbins = sqrt(Npmt/RC.pi);
01685 Nphibins = sqrt(Npmt*RC.pi);
01686 Npmt = Ncosbins*Nphibins;
01687
01688
01689 delete[] Xpmt;
01690 delete[] Ypmt;
01691 delete[] Zpmt;
01692
01693 Xpmt = new double[Npmt];
01694 Ypmt = new double[Npmt];
01695 Zpmt = new double[Npmt];
01696
01697
01698
01699
01700 delete[] PMTdata;
01701 PMTlen = 0;
01702 PMTsize = 10*Npmt;
01703 PMTdata = new PMT[PMTsize];
01704
01705
01706
01707 double* xpmt=Xpmt;
01708 double* ypmt=Ypmt;
01709 double* zpmt=Zpmt;
01710
01711 double dphi = 2*RC.pi/Nphibins;
01712 double dz = 2.0/Ncosbins;
01713
01714 for(int i=0;i<Ncosbins;i++){
01715 double z = -1+i*dz+dz/2;
01716 for(int j=0;j<Nphibins;j++){
01717 double phi = j*dphi+dphi/2;
01718 *xpmt++ = R2*sqrt(1-z*z)*cos(phi);
01719 *ypmt++ = R2*sqrt(1-z*z)*sin(phi);
01720 *zpmt++ = R2*z;
01721
01722 }
01723 }
01724 }
01725 void ReactorDetector::SetParam_GdConcentration(double x){
01726 GdConcentration =x;
01727 double y =(GdConcentration/RC.GdConcentrationRef);
01728 double z = GdCaptureFraction/(1-GdCaptureFraction);
01729
01730 GdCaptureFraction = y*z/(1+y*z);
01731
01732 mfpGd*=(1+z)/(1+y*z);
01733 tGd*=(1+z)/(1+y*z);
01734 SetNeutronPropStuff();
01735 }
01736 void ReactorDetector::SetNeutronPropStuff(){
01737
01738 a[0] = RC.A0;
01739 a[1] = RC.A1;
01740 a[2] = RC.A2;
01741 a[3] = RC.A3;
01742
01743 z[0] = RC.Z0;
01744 z[1] = RC.Z1;
01745 z[2] = RC.Z2;
01746 z[3] = RC.Z3;
01747
01748 nn[0]=RC.Navogadro*RC.f0*RC.density/RC.A0;
01749 nn[1]=RC.Navogadro*RC.f1*RC.density/RC.A1;
01750 nn[2]=RC.Navogadro*GdConcentration/100*RC.f2*RC.density/RC.A2;
01751 nn[3]=RC.Navogadro*GdConcentration/100*RC.f3*RC.density/RC.A3;
01752
01753 }
01754 double ReactorDetector::GetHitFrac(std::string parent){
01755 bool hit[Npmt];
01756 for(int i=0;i<Npmt;i++)hit[i]=0;
01757 for(PMT* pPMT=PMTdata;pPMT<PMTdata+PMTlen;pPMT++){
01758 if(pPMT->Parent==parent&&pPMT->Npe>0)hit[pPMT->npmt]=1;
01759 }
01760 int nhit=0;
01761 for(int i=0;i<Npmt;i++)nhit+=hit[i];
01762 return 1.0*nhit/Npmt;
01763 }
01764 void ReactorDetector::CalculateDipoleMoment(std::string parent){
01765
01766 double d[3] = {0,0,0};
01767 double q=0;
01768 for(PMT* pPMT=PMTdata;pPMT<PMTdata+PMTlen;pPMT++){
01769 if(pPMT->Parent==parent&&pPMT->Npe>0){
01770 q+=pPMT->PHsmr;
01771 for(int i=0;i<3;i++)d[i]+=(pPMT->PHsmr)*(pPMT->xyz[i]);
01772 }
01773 }
01774 if(q>0)for(int i=0;i<3;i++)d[i]/=q;
01775
01776 if(parent=="P"){
01777 for(int i=0;i<3;i++)DipolePositron[i] = d[i];
01778 }
01779 if(parent=="N"){
01780 for(int i=0;i<3;i++)DipoleNeutron[i] = d[i];
01781 }
01782 }
01783 void ReactorDetector::ImproveDipoleMoment(std::string parent){
01784
01785 double d[3];
01786 double k;
01787 PMT* qPMT;
01788 if(parent=="P"){
01789 for(int i=0;i<3;i++)d[i]=DipolePositron[i];
01790 k = PHpositron;
01791 qPMT=PMTpositron;
01792 }
01793 if(parent=="N"){
01794 for(int i=0;i<3;i++)d[i]=DipoleNeutron[i];
01795 k = PHneutron;
01796 qPMT=PMTneutron;
01797 }
01798
01799 double C= RC.PMTqe*RC.PMTdiameter*RC.PMTdiameter/16*RC.PhotonsPerMeV;
01800
01801 double sumlast = 999999;
01802 double test=999999;
01803 double tol=0.01;
01804 int sign=1;
01805 bool first=1;
01806 double dev=0.1;
01807 while(test>tol){
01808
01809 double dlast[3];
01810 for(int i=0;i<3;i++)dlast[i]=d[i];
01811 double klast=k;
01812 double sum[3]={0,0,0};
01813 for(PMT* pPMT=qPMT;pPMT<qPMT+Npmt;pPMT++){
01814 if(pPMT->Parent!=parent)continue;
01815 double r[3];
01816 double rn[3];
01817 double t[3];
01818 for(int i=0;i<3;i++)rn[i]=pPMT->xyz[i];
01819 for(int i=0;i<3;i++)r[i]=rn[i]-d[i];
01820 double rdotr = r[0]*r[0]+r[1]*r[1]+r[2]*r[2];
01821 double rdotrn = r[0]*rn[0]+r[1]*rn[1]+r[2]*rn[2];
01822 for(int i=0;i<3;i++)t[i]=r[i]/sqrt(rdotr);
01823
01824 double tdotd=d[0]*t[0]+d[1]*t[1]+d[2]*t[2];
01825 double ddotd=d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
01826 double test2=tdotd*tdotd-ddotd+R0*R0;
01827 double sSc;
01828 double sGd;
01829
01830 if(test2<0){
01831 sSc=sqrt(rdotr);
01832 sGd=0;
01833 }
01834 else{
01835 double s1=-tdotd+sqrt(test2);
01836 double s2=-tdotd-sqrt(test2);
01837 if(s1>0&&s2>0){
01838 sSc=sqrt(rdotr)-s1+s2;
01839 sGd=s1-s2;
01840 }
01841 else if(s1>0&&s2<0){
01842 sSc=sqrt(rdotr)-s1;
01843 sGd=s1;
01844 }
01845 else {
01846 sSc=sqrt(rdotr);
01847 sGd=0;
01848 }
01849 }
01850
01851 double mn=pPMT->Npe;
01852 double w0=C*rdotrn/R2/sqrt(rdotr)/rdotr*
01853 exp(-sGd/RC.attenlGd-sSc/RC.attenlSc);
01854 sum[0]+=mn;
01855 sum[1]+=w0;
01856 sum[2]+=w0*klast-mn*log(w0*klast);
01857 }
01858 if(first){
01859 k = sum[0]/sum[1];
01860 for(int i=0;i<3;i++)d[i]*=(1+dev);
01861 first=0;
01862 }
01863 else{
01864 k = sum[0]/sum[1];
01865 if(sum[2]<sumlast){
01866 for(int i=0;i<3;i++)d[i]*=(1+sign*dev);
01867 }
01868 else{
01869 sign*=-1;
01870 dev/=2;
01871 for(int i=0;i<3;i++)d[i]*=(1+sign*dev);
01872 }
01873 }
01874 test=1-sum[2]/sumlast;
01875 if(test<0)test*=-1;
01876 sumlast=sum[2];
01877 }
01878 if(parent=="P")for(int i=0;i<3;i++)DipolePositron[i]=d[i];
01879 if(parent=="N")for(int i=0;i<3;i++)DipoleNeutron[i]=d[i];
01880 }
01881
01882
01883
01884 void ReactorDetector::ConsolidatePMT(){
01885
01886
01887
01888 double xpepos[Npmt];
01889 double xpeneu[Npmt];
01890 int subhitspos[Npmt];
01891 int subhitsneu[Npmt];
01892
01893 for(int i=0;i<Npmt;i++)xpepos[i]=0;
01894 for(int i=0;i<Npmt;i++)xpeneu[i]=0;
01895 for(int i=0;i<Npmt;i++)subhitspos[i]=0;
01896 for(int i=0;i<Npmt;i++)subhitsneu[i]=0;
01897
01898 for(PMT* pPMT=PMTdata;pPMT<PMTdata+PMTlen;pPMT++){
01899 int n=pPMT->npmt;
01900 if(pPMT->Parent=="P"){
01901 xpepos[n]+=pPMT->Npe;
01902 subhitspos[n]++;
01903 }
01904 if(pPMT->Parent=="N"){
01905 xpeneu[n]+=pPMT->Npe;
01906 subhitsneu[n]++;
01907 }
01908 }
01909
01910 delete[] PMTpositron;
01911 PMTpositron = new PMT[Npmt];
01912 delete[] PMTneutron;
01913 PMTneutron = new PMT[Npmt];
01914
01915 for(int i=0;i<Npmt;i++){
01916 (*(PMTpositron+i)).npmt=i;
01917 (*(PMTpositron+i)).Parent="P";
01918 (PMTpositron+i)->SetSubHitsPtr(subhitspos[i]);
01919
01920 (*(PMTneutron+i)).npmt=i;
01921 (*(PMTneutron+i)).Parent="N";
01922 (PMTneutron+i)->SetSubHitsPtr(subhitsneu[i]);
01923 }
01924
01925 for(PMT* pPMT=PMTdata;pPMT<PMTdata+PMTlen;pPMT++){
01926 int n=pPMT->npmt;
01927 PMT* qPMT;
01928 if(pPMT->Parent=="P"){
01929 qPMT = PMTpositron+n;
01930 *qPMT+=*pPMT;
01931 }
01932 if(pPMT->Parent=="N"){
01933 qPMT = PMTneutron+n;
01934 *qPMT+=*pPMT;
01935 }
01936 }
01937 cout;
01938 }