00001
00006 #include <math.h>
00007 #include <iostream.h>
00008 #include <fstream.h>
00009 #include <iomanip.h>
00010 #include <string>
00011 #include <stdio.h>
00012 #include "ReactorConstants.hh"
00013 #include "ReactorFortran.hh"
00014 #include "MuonPropagator.hh"
00015 #include "MyHeSource.hh"
00016 #include "MyLiSource.hh"
00017
00018 MuonPropagator::MuonPropagator(int test, double newRmaxgen, double newEnergy,
00019 double newX, double newY, double newZ,
00020 double newVx, double newVy, double newVz){
00021
00022 Rmaxgen = newRmaxgen;
00023 energy = newEnergy;
00024
00025 double ri[3];
00026 ri[0] = newX;
00027 ri[1] = newY;
00028 ri[2] = newZ;
00029
00030 double pi[3];
00031 pi[0] = newVx;
00032 pi[1] = newVy;
00033 pi[2] = newVz;
00034
00035
00036
00037
00038
00039
00040
00041
00042 static double re = RELECTRON;
00043 static double me = MELECTRON;
00044 static double mmu = MMUON;
00045 static double Na = NAVOGADRO;
00046
00047
00048
00049 static double nel[2];
00050 static double A[2] = {A0,A1};
00051 static double Z[2] = {Z0,Z1};
00052 static double f[2] = {f0,f1};
00053 static double I[2] = {I0,I1};
00054
00055 static double ncar;
00056
00057
00058
00059 int static muonstop;
00060 bool static first = true;
00061 if(first){
00062
00063
00064 for(int i=0;i<2;i++) nel[i] = Na*density*f[i]*Z[i]/A[i];
00065
00066
00067
00068 ncar = Na*density*f[1]/A[1];
00069
00070
00071 Weight = 0.;
00072 muonstop = 0;
00073
00074 first = false;
00075 }
00076
00077
00078
00079 int inter = 0;
00080 double x[2],y[2],z[2];
00081
00082
00083
00084 double pdotp = sqrt(pi[0]*pi[0] + pi[1]*pi[1] + pi[2]*pi[2]);
00085 double t[3];
00086 for(int i=0;i<3;i++) t[i] = pi[i]/pdotp;
00087
00088
00089
00090
00091
00092
00093 double rf[3];
00094 for(int i=0;i<3;i++) rf[i] = ri[i]-t[i];
00095
00096
00097
00098
00099 double p[7];
00100 double* pptr = p;
00101 int num;
00102
00103 pptr = Intersection(ri[0], ri[1], ri[2],
00104 rf[0], rf[1], rf[2],
00105 0, 0, 0, Rmaxgen);
00106
00107 num = (int)*pptr++;
00108 if(num>1){
00109
00110 inter = 2;
00111 for(int i=0; i<inter; i++){
00112 x[i] = *pptr++;
00113 y[i] = *pptr++;
00114 z[i] = *pptr++;
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125 double L = sqrt((x[1]-x[0])*(x[1]-x[0])+
00126 (y[1]-y[0])*(y[1]-y[0])+
00127 (z[1]-z[0])*(z[1]-z[0]));
00128
00129
00130
00131
00132
00133
00134
00135
00136 double step=5.0;
00137 double Emin=0.01;
00138
00139 double range = 0.;
00140 double time = 0.;
00141
00142
00143
00144 int maxgammafromisotope = 5;
00145 int maxgamma = int(Rmaxgen*2/step)+maxgammafromisotope;
00146 double* egamma = new double[maxgamma];
00147 double* rgamma = new double[maxgamma*3];
00148 double* tgamma = new double[maxgamma];
00149
00150 double* egptr=egamma;
00151 double* rgptr=rgamma;
00152 double* tgptr=tgamma;
00153
00154
00155
00156 double dE=0;
00157 double eloss;
00158 int ngamma = 0;
00159
00160 bool done = false;
00161 while(!done){
00162
00163
00164 eloss = 0;
00165
00166
00167
00168 if(energy-dE > Emin){
00169
00170
00171
00172 if(range+step < L){
00173
00174
00175
00176 double gamma = 1+(energy-dE)/mmu;
00177 double beta = sqrt(1-1/gamma/gamma);
00178 range+=step;
00179 time+=step/beta/c;
00180
00181
00182
00183 double te = gamma-1;
00184 double tc = Emin/mmu;
00185 double tmax = te;
00186 double tup = tc;
00187 if(tc>tmax)tup=tmax;
00188
00189 for (int k=0;k<2;k++){
00190 eloss+=2*PI*re*re*me*nel[k]*step/beta/beta*
00191 (log(2*(gamma+1)/(I[k]*I[k]/me/me))
00192 +RadCorr(te,tup));
00193 }
00194
00195
00196
00197 if(dE+eloss > energy){
00198 *egptr++=energy-dE;
00199 dE=energy;
00200 }
00201 else{
00202 *egptr++=eloss;
00203 dE+=eloss;
00204 }
00205
00206
00207
00208 *rgptr++ = x[1] - (range-(step/2))*t[0];
00209 *rgptr++ = y[1] - (range-(step/2))*t[1];
00210 *rgptr++ = z[1] - (range-(step/2))*t[2];
00211
00212 *tgptr++ = time;
00213
00214
00215 ngamma++;
00216 }
00217 else{
00218
00219
00220
00221 double laststep = L-range;
00222
00223 double gamma = 1+(energy-dE)/mmu;
00224 double beta = sqrt(1-1/gamma/gamma);
00225 range+=laststep;
00226 time+=laststep/beta/c;
00227
00228
00229
00230 double te = gamma-1;
00231 double tc = Emin/mmu;
00232 double tmax = te;
00233 double tup = tc;
00234 if(tc>tmax)tup=tmax;
00235
00236 for (int k=0;k<2;k++){
00237 eloss+=2*PI*re*re*me*nel[k]*laststep/beta/beta*
00238 (log(2*(gamma+1)/(I[k]*I[k]/me/me))
00239 +RadCorr(te,tup));
00240 }
00241
00242
00243
00244 if(dE+eloss > energy){
00245 *egptr++=energy-dE;
00246 dE=energy;
00247 }
00248 else{
00249 *egptr++=eloss;
00250 dE+=eloss;
00251 }
00252
00253
00254
00255 *rgptr++ = x[1] - (range-(laststep/2))*t[0];
00256 *rgptr++ = y[1] - (range-(laststep/2))*t[1];
00257 *rgptr++ = z[1] - (range-(laststep/2))*t[2];
00258
00259 *tgptr++ = time;
00260
00261
00262 ngamma++;
00263
00264
00265 done = true;
00266 }
00267 }
00268 else{
00269
00270
00271
00272 muonstop++;
00273
00274
00275
00276 *egptr++=mmu;
00277
00278
00279
00280 *rgptr++ = x[1] - range*t[0];
00281 *rgptr++ = y[1] - range*t[1];
00282 *rgptr++ = z[1] - range*t[2];
00283
00284 *tgptr++ = time;
00285
00286
00287 ngamma++;
00288
00289
00290 done = true;
00291
00292
00293
00294
00295
00296
00297
00298
00299 }
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 Ngamma = ngamma;
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 Egamma = new double[ngamma];
00322 Rgamma = new double[ngamma*3];
00323 Tgamma = new double[ngamma];
00324
00325 double* ptr;
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 ptr = Egamma+ngamma;
00346 while(ptr>Egamma)*--ptr=*--egptr;
00347
00348 ptr = Rgamma+3*ngamma;
00349 while(ptr>Rgamma)*--ptr=*--rgptr;
00350
00351 ptr = Tgamma+ngamma;
00352 while(ptr>Tgamma)*--ptr=*--tgptr;
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 delete[] egamma;
00385 delete[] rgamma;
00386 delete[] tgamma;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 MuonPropagator::MuonPropagator(double newRmaxgen,
00403 double newDepth,
00404 double newEnergy,
00405 double newCosTheta){
00406
00407 Rmaxgen = newRmaxgen;
00408 Depth = newDepth;
00409 energy = newEnergy;
00410 cosg = newCosTheta;
00411
00412
00413
00414
00415 static double re = RELECTRON;
00416 static double me = MELECTRON;
00417 static double mmu = MMUON;
00418 static double Na = NAVOGADRO;
00419
00420
00421
00422 static double nel[2];
00423 static double A[2] = {A0,A1};
00424 static double Z[2] = {Z0,Z1};
00425 static double f[2] = {f0,f1};
00426 static double I[2] = {I0,I1};
00427
00428 static double ncar;
00429
00430
00431
00432 bool static first = true;
00433 double flux;
00434 int static muonstop;
00435 float static fspace[200];
00436
00437 if(first){
00438
00439
00440 if(Depth == 300.)
00441 flux = 0.374;
00442 else if(Depth == 450.)
00443 flux = 0.160;
00444 else if(Depth == 500.)
00445 flux = 0.145;
00446 else{
00447 cout << " ERROR: no muon flux for depth of " << Depth << " mwe" << endl;
00448 return;
00449 }
00450
00451
00452 for(int i=0;i<2;i++) nel[i] = Na*density*f[i]*Z[i]/A[i];
00453
00454
00455
00456 ncar = Na*density*f[1]/A[1];
00457
00458
00459
00460 float xlo = 0.;
00461 float xhi = 50.;
00462 funlxp_(IsotopeDistance,fspace,xlo,xhi);
00463
00464 Weight = 0.;
00465 muonstop = 0;
00466
00467 first = false;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 int inter = 0;
00479 double r[6],t[3];
00480 double x[2],y[2],z[2];
00481 double delta = Rmaxgen*20.;
00482 bool passed = false;
00483
00484 while(!passed){
00485
00486 const int len=3;
00487 float rv[len];
00488 ranlux_(rv,len);
00489 r[0] = (2*rv[0]-1)*delta;
00490 r[1] = (2*rv[1]-1)*delta;
00491 r[2] = Rmaxgen;
00492 phig = 2*PI*rv[2];
00493
00494
00495 t[0] = cos(phig)*sqrt(1-cosg*cosg);
00496 t[1] = sin(phig)*sqrt(1-cosg*cosg);
00497 t[2] = cosg;
00498
00499
00500
00501
00502
00503 for(int i=0;i<3;i++) r[i+3] = r[i]-t[i];
00504
00505
00506
00507
00508
00509 double p[7];
00510 double* ptr = p;
00511 int num;
00512
00513 ptr = Intersection(r[0], r[1], r[2],
00514 r[3], r[4], r[5],
00515 0, 0, 0, Rmaxgen);
00516
00517 num = (int)*ptr++;
00518 if(num>1){
00519
00520 inter = 2;
00521 for(int i=0; i<inter; i++){
00522 x[i] = *ptr++;
00523 y[i] = *ptr++;
00524 z[i] = *ptr++;
00525 }
00526 passed = true;
00527 }
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537 double L = sqrt((x[1]-x[0])*(x[1]-x[0])+
00538 (y[1]-y[0])*(y[1]-y[0])+
00539 (z[1]-z[0])*(z[1]-z[0]));
00540
00541
00542
00543
00544
00545
00546
00547
00548 double step=5.0;
00549 double Emin=0.01;
00550
00551 double range = 0.;
00552 double time = 0.;
00553
00554
00555
00556 int maxgammafromisotope = 5;
00557 int maxgamma = int(Rmaxgen*2/step)+maxgammafromisotope;
00558 double* egamma = new double[maxgamma];
00559 double* rgamma = new double[maxgamma*3];
00560 double* tgamma = new double[maxgamma];
00561
00562 double* egptr=egamma;
00563 double* rgptr=rgamma;
00564 double* tgptr=tgamma;
00565
00566
00567
00568 double dE=0;
00569 double eloss;
00570 int ngamma = 0;
00571
00572 bool done = false;
00573 while(!done){
00574
00575
00576 eloss = 0;
00577
00578
00579
00580 if(energy-dE > Emin){
00581
00582
00583
00584 if(range+step < L){
00585
00586
00587
00588 double gamma = 1+(energy-dE)/mmu;
00589 double beta = sqrt(1-1/gamma/gamma);
00590 range+=step;
00591 time+=step/beta/c;
00592
00593
00594
00595 double te = gamma-1;
00596 double tc = Emin/mmu;
00597 double tmax = te;
00598 double tup = tc;
00599 if(tc>tmax)tup=tmax;
00600
00601 for (int k=0;k<2;k++){
00602 eloss+=2*PI*re*re*me*nel[k]*step/beta/beta*
00603 (log(2*(gamma+1)/(I[k]*I[k]/me/me))
00604 +RadCorr(te,tup));
00605 }
00606
00607
00608
00609 if(dE+eloss > energy){
00610 *egptr++=energy-dE;
00611 dE=energy;
00612 }
00613 else{
00614 *egptr++=eloss;
00615 dE+=eloss;
00616 }
00617
00618
00619
00620 *rgptr++ = x[1] - (range-(step/2))*t[0];
00621 *rgptr++ = y[1] - (range-(step/2))*t[1];
00622 *rgptr++ = z[1] - (range-(step/2))*t[2];
00623
00624 *tgptr++ = time;
00625
00626
00627 ngamma++;
00628 }
00629 else{
00630
00631
00632
00633 double laststep = L-range;
00634
00635 double gamma = 1+(energy-dE)/mmu;
00636 double beta = sqrt(1-1/gamma/gamma);
00637 range+=laststep;
00638 time+=laststep/beta/c;
00639
00640
00641
00642 double te = gamma-1;
00643 double tc = Emin/mmu;
00644 double tmax = te;
00645 double tup = tc;
00646 if(tc>tmax)tup=tmax;
00647
00648 for (int k=0;k<2;k++){
00649 eloss+=2*PI*re*re*me*nel[k]*laststep/beta/beta*
00650 (log(2*(gamma+1)/(I[k]*I[k]/me/me))
00651 +RadCorr(te,tup));
00652 }
00653
00654
00655
00656 if(dE+eloss > energy){
00657 *egptr++=energy-dE;
00658 dE=energy;
00659 }
00660 else{
00661 *egptr++=eloss;
00662 dE+=eloss;
00663 }
00664
00665
00666
00667 *rgptr++ = x[1] - (range-(laststep/2))*t[0];
00668 *rgptr++ = y[1] - (range-(laststep/2))*t[1];
00669 *rgptr++ = z[1] - (range-(laststep/2))*t[2];
00670
00671 *tgptr++ = time;
00672
00673
00674 ngamma++;
00675
00676
00677 done = true;
00678 }
00679 }
00680 else{
00681
00682
00683
00684 muonstop++;
00685
00686
00687
00688 *egptr++=mmu;
00689
00690
00691
00692 *rgptr++ = x[1] - range*t[0];
00693 *rgptr++ = y[1] - range*t[1];
00694 *rgptr++ = z[1] - range*t[2];
00695
00696 *tgptr++ = time;
00697
00698
00699 ngamma++;
00700
00701
00702 done = true;
00703
00704
00705
00706
00707
00708
00709
00710
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 double XC;
00723 double mfp;
00724 double alpha = 0.73;
00725 double XCmeas = 2.12;
00726 double Emeas = 190000.;
00727 double ubarntocmsq = 1e-30;
00728
00729
00730 XC = (XCmeas/pow(Emeas,alpha))*pow(energy,alpha)*ubarntocmsq;
00731
00732
00733
00734
00735 int ntrial = 0;
00736 passed = false;
00737 while(!passed){
00738
00739 mfp = 1/ncar/XC;
00740
00741
00742
00743 double test = 1/pow(10.0,(range/mfp));
00744 if(test > 0.9999998){
00745 mfp = range/2.;
00746 ntrial = 0;
00747 }
00748 else{
00749 const int len=1;
00750 float rv[len];
00751 ranlux_(rv,len);
00752 mfp*=log(1/rv[0]);
00753 }
00754
00755
00756 if(mfp <= range) passed = true;
00757
00758
00759 ntrial++;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 double ri[3];
00775 ri[0] = x[1] - mfp*t[0];
00776 ri[1] = y[1] - mfp*t[1];
00777 ri[2] = z[1] - mfp*t[2];
00778
00779
00780
00781 const int len=2;
00782 float rw[len];
00783 ranlux_(rw,len);
00784
00785 double newphig = 2*PI*rw[0];
00786 double newcosg = 0.;
00787 double newt[3];
00788 newt[0] = cos(newphig)*sqrt(1-newcosg*newcosg);
00789 newt[1] = sin(newphig)*sqrt(1-newcosg*newcosg);
00790 newt[2] = newcosg;
00791
00792
00793
00794 float lateraldistance;
00795 int len2 = 1;
00796 funlux_(fspace,lateraldistance,len2);
00797
00798
00799
00800 double rt[3];
00801 rt[0] = lateraldistance*newt[0];
00802 rt[1] = lateraldistance*newt[1];
00803 rt[2] = lateraldistance*newt[2];
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 double angle = PI - acos(cosg);
00817 double qt[3];
00818 double* qtptr = qt;
00819 qtptr = Rotate('Y',angle,rt[0],rt[1],rt[2]);
00820 for(int i=0; i<3; i++) qt[i] = *qtptr++;
00821
00822
00823
00824 angle = PI - phig;
00825 double pt[3];
00826 double* ptptr = pt;
00827 ptptr = Rotate('Z',angle,qt[0],qt[1],qt[2]);
00828 for(int i=0; i<3; i++) pt[i] = *ptptr++;
00829
00830
00831
00832
00833 for(int i=0; i<3; i++)ri[i] += pt[i];
00834
00835
00836
00837
00838
00839 char* isotope;
00840 if(rw[1] <= 0.5)
00841 isotope = "9Li";
00842 else
00843 isotope = "8He";
00844
00845
00846
00847 int maxneutron = 1;
00848 double* eneutron = new double[maxneutron];
00849 double* rneutron = new double[maxneutron*3];
00850 double* tneutron = new double[maxneutron];
00851
00852 double* enptr = eneutron;
00853 double* rnptr = rneutron;
00854 double* tnptr = tneutron;
00855
00856 int maxelectron = 1;
00857 double* eelectron = new double[maxelectron];
00858 double* relectron = new double[maxelectron*3];
00859 double* telectron = new double[maxelectron];
00860
00861 double* eeptr = eelectron;
00862 double* reptr = relectron;
00863 double* teptr = telectron;
00864
00865
00866
00867 int nneutron = 0;
00868 int nelectron = 0;
00869
00870 if(isotope == "9Li"){
00871 MyLiSource LiSource(9,Rmaxgen);
00872
00873 nneutron = 1;
00874 *enptr++ = LiSource.GetLiNeutronEnergy();
00875 for(int i=0; i<3; i++) *rnptr++ = ri[i];
00876 *tnptr++ = LiSource.GetLiDecayTime();
00877
00878 nelectron = 1;
00879 *eeptr++ = LiSource.GetLiBetaEnergy();
00880 for(int i=0; i<3; i++) *reptr++ = ri[i];
00881 *teptr++ = LiSource.GetLiDecayTime();
00882
00883
00884 Weight = 1./float(ntrial);
00885 }
00886 else if(isotope == "8He"){
00887 MyHeSource HeSource(8,Rmaxgen);
00888
00889 nneutron = 1;
00890 *enptr++ = HeSource.GetHeNeutronEnergy();
00891 for(int i=0; i<3; i++) *rnptr++ = ri[i];
00892 *tnptr++ = HeSource.GetHeDecayTime();
00893
00894 nelectron = 1;
00895 *eeptr++ = HeSource.GetHeBetaEnergy();
00896 for(int i=0; i<3; i++) *reptr++ = ri[i];
00897 *teptr++ = HeSource.GetHeDecayTime();
00898
00899
00900 Weight = 1./float(ntrial);
00901 }
00902 else{
00903 cout << " ERROR: unknown isotope " << isotope
00904 << ". Options are '9Li' and '8He'." << endl;
00905 }
00906
00907
00908
00909 Nneutron = nneutron;
00910 Nelectron = nelectron;
00911 Ngamma = ngamma;
00912
00913 Eneutron = new double[nneutron];
00914 Rneutron = new double[nneutron*3];
00915 Tneutron = new double[nneutron];
00916
00917 Eelectron = new double[nelectron];
00918 Relectron = new double[nelectron*3];
00919 Telectron = new double[nelectron];
00920
00921 Egamma = new double[ngamma];
00922 Rgamma = new double[ngamma*3];
00923 Tgamma = new double[ngamma];
00924
00925 double* ptr;
00926
00927 ptr = Eneutron+nneutron;
00928 while(ptr>Eneutron)*--ptr=*--enptr;
00929
00930 ptr = Rneutron+3*nneutron;
00931 while(ptr>Rneutron)*--ptr=*--rnptr;
00932
00933 ptr = Tneutron+nneutron;
00934 while(ptr>Tneutron)*--ptr=*--tnptr;
00935
00936 ptr = Eelectron+nelectron;
00937 while(ptr>Eelectron)*--ptr=*--eeptr;
00938
00939 ptr = Relectron+3*nelectron;
00940 while(ptr>Relectron)*--ptr=*--reptr;
00941
00942 ptr = Telectron+nelectron;
00943 while(ptr>Telectron)*--ptr=*--teptr;
00944
00945 ptr = Egamma+ngamma;
00946 while(ptr>Egamma)*--ptr=*--egptr;
00947
00948 ptr = Rgamma+3*ngamma;
00949 while(ptr>Rgamma)*--ptr=*--rgptr;
00950
00951 ptr = Tgamma+ngamma;
00952 while(ptr>Tgamma)*--ptr=*--tgptr;
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 delete[] eneutron;
00979 delete[] rneutron;
00980 delete[] tneutron;
00981 delete[] eelectron;
00982 delete[] relectron;
00983 delete[] telectron;
00984 delete[] egamma;
00985 delete[] rgamma;
00986 delete[] tgamma;
00987 }
00988
00989 MuonPropagator::~MuonPropagator(){
00990 delete[] Eneutron;
00991 delete[] Rneutron;
00992 delete[] Tneutron;
00993 delete[] Eelectron;
00994 delete[] Relectron;
00995 delete[] Telectron;
00996 delete[] Egamma;
00997 delete[] Rgamma;
00998 delete[] Tgamma;
00999 }
01000
01001 MuonPropagator::MuonPropagator(const MuonPropagator& Muon){
01002
01003 Rmaxgen = Muon.Rmaxgen;
01004
01005 Nmuon = Muon.Nmuon;
01006 energy = Muon.energy;
01007 cosg = Muon.cosg;
01008 phig = Muon.phig;
01009
01010 Nneutron = Muon.Nneutron;
01011 Nelectron = Muon.Nelectron;
01012 Ngamma = Muon.Ngamma;
01013
01014 double* pold;
01015 double* pnew;
01016
01017 Eneutron = new double[Nneutron];
01018 pold = Muon.Eneutron+Nneutron;
01019 pnew = Eneutron+Nneutron;
01020 while(pnew>Eneutron)*--pnew=*--pold;
01021
01022 Rneutron = new double[3*Nneutron];
01023 pold = Muon.Rneutron+3*Nneutron;
01024 pnew = Rneutron+3*Nneutron;
01025 while(pnew>Rneutron)*--pnew=*--pold;
01026
01027 Tneutron = new double[Nneutron];
01028 pold = Muon.Tneutron+Nneutron;
01029 pnew = Tneutron+Nneutron;
01030 while(pnew>Tneutron)*--pnew=*--pold;
01031
01032 Eelectron = new double[Nelectron];
01033 pold = Muon.Eelectron+Nelectron;
01034 pnew = Eelectron+Nelectron;
01035 while(pnew>Eelectron)*--pnew=*--pold;
01036
01037 Relectron = new double[3*Nelectron];
01038 pold = Muon.Relectron+3*Nelectron;
01039 pnew = Relectron+3*Nelectron;
01040 while(pnew>Relectron)*--pnew=*--pold;
01041
01042 Telectron = new double[Nelectron];
01043 pold = Muon.Telectron+Nelectron;
01044 pnew = Telectron+Nelectron;
01045 while(pnew>Telectron)*--pnew=*--pold;
01046
01047 Egamma = new double[Ngamma];
01048 pold = Muon.Egamma+Ngamma;
01049 pnew = Egamma+Ngamma;
01050 while(pnew>Egamma)*--pnew=*--pold;
01051
01052 Rgamma = new double[3*Ngamma];
01053 pold = Muon.Rgamma+3*Ngamma;
01054 pnew = Rgamma+3*Ngamma;
01055 while(pnew>Rgamma)*--pnew=*--pold;
01056
01057 Tgamma = new double[Ngamma];
01058 pold = Muon.Tgamma+Ngamma;
01059 pnew = Tgamma+Ngamma;
01060 while(pnew>Tgamma)*--pnew=*--pold;
01061
01062 Weight = Muon.Weight;
01063 }
01064
01065 MuonPropagator& MuonPropagator::operator=(const MuonPropagator& rhs){
01066
01067 if(this == &rhs)return *this;
01068
01069 Rmaxgen = rhs.Rmaxgen;
01070
01071 Nmuon = rhs.Nmuon;
01072 energy = rhs.energy;
01073 cosg = rhs.cosg;
01074 phig = rhs.phig;
01075
01076 Nneutron = rhs.Nneutron;
01077 Nelectron = rhs.Nelectron;
01078 Ngamma = rhs.Ngamma;
01079
01080 double* pold;
01081 double* pnew;
01082
01083 delete[] Eneutron;
01084 Eneutron = new double[Nneutron];
01085 pold = rhs.Eneutron+Nneutron;
01086 pnew = Eneutron+Nneutron;
01087 while(pnew>Eneutron)*--pnew=*--pold;
01088
01089 delete[] Rneutron;
01090 Rneutron = new double[3*Nneutron];
01091 pold = rhs.Rneutron+3*Nneutron;
01092 pnew = Rneutron+3*Nneutron;
01093 while(pnew>Rneutron)*--pnew=*--pold;
01094
01095 delete[] Tneutron;
01096 Tneutron = new double[Nneutron];
01097 pold = rhs.Tneutron+Nneutron;
01098 pnew = Tneutron+Nneutron;
01099 while(pnew>Tneutron)*--pnew=*--pold;
01100
01101 delete[] Eelectron;
01102 Eelectron = new double[Nelectron];
01103 pold = rhs.Eelectron+Nelectron;
01104 pnew = Eelectron+Nelectron;
01105 while(pnew>Eelectron)*--pnew=*--pold;
01106
01107 delete[] Relectron;
01108 Relectron = new double[3*Nelectron];
01109 pold = rhs.Relectron+3*Nelectron;
01110 pnew = Relectron+3*Nelectron;
01111 while(pnew>Relectron)*--pnew=*--pold;
01112
01113 delete[] Telectron;
01114 Telectron = new double[Nelectron];
01115 pold = rhs.Telectron+Nelectron;
01116 pnew = Telectron+Nelectron;
01117 while(pnew>Telectron)*--pnew=*--pold;
01118
01119 delete[] Egamma;
01120 Egamma = new double[Ngamma];
01121 pold = rhs.Egamma+Ngamma;
01122 pnew = Egamma+Ngamma;
01123 while(pnew>Egamma)*--pnew=*--pold;
01124
01125 delete[] Rgamma;
01126 Rgamma = new double[3*Ngamma];
01127 pold = rhs.Rgamma+3*Ngamma;
01128 pnew = Rgamma+3*Ngamma;
01129 while(pnew>Rgamma)*--pnew=*--pold;
01130
01131 delete[] Tgamma;
01132 Tgamma = new double[Ngamma];
01133 pold = rhs.Tgamma+Ngamma;
01134 pnew = Tgamma+Ngamma;
01135 while(pnew>Tgamma)*--pnew=*--pold;
01136
01137 Weight = rhs.Weight;
01138
01139 return *this;
01140 }
01141
01142 double* MuonPropagator::Intersection(double x1, double y1, double z1,
01143 double x2, double y2, double z2,
01144 double x3, double y3, double z3, double r){
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 double a, b, c, mu, i ;
01155
01156 double point[7];
01157 double* p = point;
01158
01159 a = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
01160 b = 2*((x2-x1)*(x1-x3) + (y2-y1)*(y1-y3) + (z2-z1)*(z1-z3));
01161 c = (x3*x3 + y3*y3 + z3*z3 + x1*x1 + y1*y1 + z1*z1 -
01162 2*(x3*x1 + y3*y1 + z3*z1) - r*r);
01163 i = b*b - 4*a*c;
01164
01165
01166 if(i < 0.0){
01167
01168 p[0] = 0.0;
01169 }
01170 if(i ==0.0){
01171
01172 p[0] = 1.0;
01173
01174 mu = -b/(2*a) ;
01175 p[1] = x1 + mu*(x2-x1);
01176 p[2] = y1 + mu*(y2-y1);
01177 p[3] = z1 + mu*(z2-z1);
01178 }
01179 if(i>0.0){
01180
01181 p[0] = 2.0;
01182
01183
01184 mu = (-b + sqrt(b*b - 4*a*c))/(2*a);
01185 p[1] = x1 + mu*(x2-x1);
01186 p[2] = y1 + mu*(y2-y1);
01187 p[3] = z1 + mu*(z2-z1);
01188
01189
01190 mu = (-b - sqrt(b*b - 4*a*c))/(2*a);
01191 p[4] = x1 + mu*(x2-x1);
01192 p[5] = y1 + mu*(y2-y1);
01193 p[6] = z1 + mu*(z2-z1);
01194 }
01195 return(p);
01196 }
01197
01198 double* MuonPropagator::Rotate(char axis,double angle,
01199 double x1, double y1, double z1){
01200
01201
01202
01203
01204
01205 double x2,y2,z2;
01206 double p[3];
01207 double* ptr = p;
01208
01209 if(axis == 'X'){
01210 x2 = x1;
01211 y2 = cos(angle)*y1-sin(angle)*z1;
01212 z2 = sin(angle)*y1+cos(angle)*z1;
01213 }
01214 else if(axis == 'Y'){
01215 x2 = cos(angle)*x1+sin(angle)*z1;
01216 y2 = y1;
01217 z2 = -sin(angle)*x1+cos(angle)*z1;
01218 }
01219 else if(axis == 'Z'){
01220 x2 = cos(angle)*x1-sin(angle)*y1;
01221 y2 = sin(angle)*x1+cos(angle)*y1;
01222 z2 = z1;
01223 }
01224 else{
01225 cout << "ERROR: Unknown axis " << axis
01226 << ". Axis of rotation must be 'X', 'Y', or 'Z'." << endl;
01227 x2 = 0;
01228 y2 = 0;
01229 z2 = 0;
01230 }
01231
01232 p[0] = x2;
01233 p[1] = y2;
01234 p[2] = z2;
01235
01236 return(ptr);
01237 }
01238
01239 double MuonPropagator::RadCorr(double t,double tup){
01240
01241 if(t<=0 || tup<=0 || t<=tup) return 0;
01242
01243 double y = 1/(2+t);
01244
01245 return log(t*tup)
01246 -tup*tup*(t+2*tup-3*tup*tup*y/2
01247 -(tup-exp(3*log(tup))/3)*y*y
01248 -(tup*tup/2
01249 -t*exp(3*log(tup))/2
01250 +exp(4*log(tup))/4)*exp(3*log(y)));
01251 }
01252
01253 float MuonPropagator::IsotopeDistance(const float& r){
01254
01255
01256 float phi = 1/166.0*exp(-0.0403*r*r)+1/1223.0*exp(-0.098*r);
01257 return phi;
01258 }