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