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