/* This program converts the output of MUSIC program into
   various types of muon distributions

   Alfred Tang
   Kansas State University

   Note:  Copy edist.dat to edistx.dat so that the root name is x.

   output files:
   1.  fdistx.dat -- energy distribution
   2.  gdistx.dat -- theta-phi distribution
   3.  tdistx.dat -- theta distribution
   4.  pdistx.dat -- phi distribution
   5.  cdistx.dat -- cos(theta) distribution
   6.  ddistx.dat -- cos(theta)-phi distribution
   7.  hdistx.dat -- energy-theta distribution
   8.  qdistx.dat -- energy-phi distribution

*/

#include <stdio.h>
#include <math.h>
#include <string.h>
#define NRANSI
#include "nrutil.h"
#include "nr.h"
#include "nrutil.c"
#define pi 3.1415926535897932384626433
#define m 100
#define n 200
#define lemin -0.974694134735
#define rho 2.65

int main()
{
  int i,j,ct=0,high,*count,icount,im;
  double *flux,dle,*the,*ph,**ang,lelow,lemax,dlem,km;
  double e,f,theta,phi,total_theta=0.,total_phi=0.,dth,dph,*tdist,*pdist;
  double ine=0.,in=0.,cz,r,nflux=0.,k,omega,twopi,dt,dp;
  double ia=0.,it=0.,ip=0.,iatemp,ittemp,iptemp,**hdist,**qdist;
  double *czdist,icz=0.,icztemp,**dzdist,idz=0.,idztemp,htemp,qtemp;
  double ih=0.,iq=0.;
  float e0,f0,theta0,phi0,cz0,r0,omega0,low,pos,emax;
  char infile[20]="edist",efile[20]="fdist",afile[20]="gdist",root[20];
  char tfile[20]="tdist",pfile[20]="pdist",cfile[20]="cdist",dfile[20]="ddist";
  char hfile[20]="hdist",qfile[20]="qdist";
  printf("Enter the root name of the input file: ");
  scanf("%s",root);
  FILE *fp1,*fp2,*fp3,*fp4,*fp5,*fp6,*fp7,*fp8,*fp9;
  fp1=fopen(strcat(strcat(infile,root),".dat"),"r");
  fp2=fopen(strcat(strcat(efile,root),".dat"),"w");
  fp3=fopen(strcat(strcat(afile,root),".dat"),"w");
  fp4=fopen(strcat(strcat(tfile,root),".dat"),"w");
  fp5=fopen(strcat(strcat(pfile,root),".dat"),"w");
  fp6=fopen(strcat(strcat(cfile,root),".dat"),"w");
  fp7=fopen(strcat(strcat(dfile,root),".dat"),"w");
  fp8=fopen(strcat(strcat(hfile,root),".dat"),"w");
  fp9=fopen(strcat(strcat(qfile,root),".dat"),"w");
  printf("lower bound of E_mu0: ");
  scanf("%f",&low);
  lelow=log10(low);
  printf("upper bound of E_mu0: (1) 5000 GeV, (2) 1 TeV, (3) other.\n");
  scanf("%d",&high);
  if(high==1) lemax=3.69897;
  else if(high==2) lemax=6.;
  else {
    printf("upper energy bound in GeV: ");
    scanf("%f",&emax);
    lemax=log10(emax);
  }
  printf("nthrows = ");
  scanf("%d",&icount);
  printf("phi offset (degrees) = ");
  scanf("%f",&pos);

  count=ivector(1,n);
  flux=dvector(1,n);
  the=dvector(1,n);
  ph=dvector(1,n);
  ang=dmatrix(1,m,1,m);
  tdist=dvector(1,n);
  pdist=dvector(1,n);
  czdist=dvector(1,n);
  dzdist=dmatrix(1,m,1,m);
  hdist=dmatrix(1,m,1,m);
  qdist=dmatrix(1,m,1,m);

  pos=pos*pi/180.;
  dle=(lemax-lemin)/n;
  dlem=(lemax-lemin)/m;

  for(i=1;i<=n;i++) {
    count[i]=0;
    flux[i]=the[i]=ph[i]=tdist[i]=pdist[i]=czdist[i]=0.;
  }

  for(i=1;i<=m;i++) {
    for(j=1;j<=m;j++) {
      ang[i][j]=dzdist[i][j]=hdist[i][j]=qdist[i][j]=0.;
    }
  }
  dth=pi/m;
  dph=2.*pi/m;
  dt=pi/n;
  dp=2.*pi/n;
  twopi=2.*pi;

  fscanf(fp1,"%f",&omega0);
  omega=(double)omega0;

  while(!feof(fp1)) {
    fscanf(fp1,"%f%f%f%f",&e0,&f0,&theta0,&phi0);
    e=(double)e0;
    f=((double)f0);
    theta=(double)theta0;
    phi=(double)phi0+pi+pos;
    if(phi>twopi)phi-=twopi;
    i=(int)((log10(e)-lemin)/dle+1.);
    im=(int)((log10(e)-lemin)/dlem+1.);
    flux[i]+=f/e;
    count[i]++;
    the[i]+=f*theta;
    ph[i]+=f*phi;
    ang[(int)(theta/dth+1.)][(int)(phi/dph+1.)]+=f;
    tdist[(int)(theta/dt+1.)]+=f;
    pdist[(int)(phi/dp+1.)]+=f;
    czdist[(int)((cos(theta)+1.)/2.*n+1.)]+=f;
    dzdist[(int)((cos(theta)+1.)/2.*m+1.)][(int)(phi/dph+1.)]+=f;
    hdist[im][(int)(theta/dth+1.)]+=f/e;
    qdist[im][(int)(phi/dph+1.)]+=f/e;
    ct++;
  };

  for(i=1;i<=n;i++){
    e=pow(10.,(i-1)*dle+lemin+.5*dle);
    if(count[i]==0) f=0.;
    else f=flux[i]*n/icount*(lemax-lelow)/(lemax-lemin)*omega;
    if (f>0.) {
      fprintf(fp2,"%e\t%e\n",e,f);
      in+=f*e;
      ine+=f*e*e;
      total_theta+=f*e*theta;
      total_phi+=f*e*phi;
    }
  }

  for(i=m/2+1;i<=m;i++){
    for(j=1;j<=m;j++){
      theta=pi-((i-1)*dth+.5*dth);
      phi=(j-1)*dph+.5*dph;
      iatemp=ang[i][j]*log(10.)*(lemax-lelow)/icount*m*m/2.*omega/pi/pi;
      ia+=iatemp;
      fprintf(fp3,"%f\t%f\t%e\n",phi*180/pi,theta*180/pi,iatemp);
    }
  }

  for(i=n/2+1;i<=n;i++){
    theta=pi-((i-1)*dt+.5*dt);
    ittemp=tdist[i]*log(10.)*(lemax-lelow)/icount*n*omega/pi;
    it+=ittemp;
    fprintf(fp4,"%f\t%e\n",theta*180./pi,ittemp);
  }

  for(i=1;i<=n;i++){
    phi=(i-1)*dp+.5*dp;
    iptemp=pdist[i]*log(10.)*(lemax-lelow)/icount*n*omega/2./pi;
    ip+=iptemp;
    fprintf(fp5,"%f\t%e\n",phi*180./pi,iptemp);
  }

  for(i=1;i<=n/2;i++){
    icztemp=czdist[i]*log(10.)*(lemax-lelow)/icount*n*omega/2.;
    icz+=icztemp;
    fprintf(fp6,"%f\t%e\n",1.-(i-.5)/n*2.,icztemp);
  }

  for(i=1;i<=m/2;i++){
    for(j=1;j<=m;j++){
      phi=pi+(j-1)*dph+.5*dph+pos;
      if(phi>twopi)phi-=twopi;
      idztemp=dzdist[i][j]*log(10.)*(lemax-lelow)/icount*m*m/4.*omega/pi;
      idz+=idztemp;
      fprintf(fp7,"%f\t%f\t%e\n",phi*180/pi,1.-(i-.5)/m*2.,idztemp);
    }
  }

  for(i=1;i<=m;i++){
    e=pow(10.,(i-1)*dlem+lemin+.5*dlem);
    for(j=m/2+1;j<=m;j++){
      theta=pi-((j-1)*dth+.5*dth);
      if(hdist[i][j]>0.) {
	htemp=hdist[i][j]*(lemax-lelow)/(lemax-lemin)/icount*m*m*omega/pi;
	ih+=htemp*e;
	fprintf(fp8,"%f\t%f\t%e\n",e,theta*180./pi,htemp);
      }
    }
  }

  for(i=1;i<=m;i++){
    e=pow(10.,(i-1)*dlem+lemin+.5*dlem);
    for(j=1;j<=m;j++){
      phi=(j-1)*dph+.5*dph;
      if(qdist[i][j]>0.) {
	qtemp=qdist[i][j]*(lemax-lelow)/(lemax-lemin)/icount*m*m*omega/pi/2.;
	iq+=qtemp*e;
	fprintf(fp9,"%f\t%f\t%e\n",e,phi*180./pi,qtemp);
      }
    }
  }

  k=(lemax-lemin)*log(10.)/n;
  km=(lemax-lemin)*log(10.)/m;
  nflux+=in*pow(ine/in,.74)*rho;
  printf("survival probability               %f\n",1.*ct/icount);
  printf("CHECK: energy (GeV) E              %f\n",ine/in);
  printf("CHECK: intensity (cm^-2 s^-1) J    %e\n",in*k);
  printf("CHECK: (cth-phi dist) J            %e\n",idz*dph/m*2.);
  printf("CHECK: (cth dist) J                %e\n",icz/n*2.);
  printf("CHECK: (phi dist) J                %e\n",ip*dp);
  printf("CHECK: (theta-phi dist) J          %e\n",ia*dth*dph);
  printf("CHECK: (theta dist) J              %e\n",it*dt);
  printf("CHECK: (enegy-theta dist) J        %e\n",ih*km*dth);
  printf("CHECK: (enegy-phi dist) J          %e\n",iq*km*dph);
  printf("neutron flux (cm^-3 s^-1)          %e\n",4.14e-6*nflux*k);
  printf("weighted theta                     %f\n",total_theta/in);
  printf("weighted phi                       %f\n\n",total_phi/in);
  fclose(fp1);
  fclose(fp2);
  fclose(fp3);
  fclose(fp4);
  fclose(fp5);
  fclose(fp6);
  fclose(fp7);
  fclose(fp8);
  fclose(fp9);
  free_ivector(count,1,n);
  free_dvector(flux,1,n);
  free_dvector(the,1,n);
  free_dvector(ph,1,n);
  free_dmatrix(ang,1,m,1,m);
  free_dvector(tdist,1,n);
  free_dvector(pdist,1,n);
  free_dvector(czdist,1,n);
  free_dmatrix(dzdist,1,m,1,m);
  free_dmatrix(hdist,1,m,1,m);
  free_dmatrix(qdist,1,m,1,m);
  return 0;
}
#undef NRANSI
