vide_public/c_tools/hod/galaxy_prob_vz.c

484 lines
12 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* These are the parameters for creating the pdf table.
*/
int nv1,nr1,nphi1;
void create_pdf_table();
double ***ppp,*vvv,*rbin,*phibin,***yy2,FIRSTFLAG=1;
double BINSIZE;
double galaxy_prob_vz(double vel, double rad, double theta)
{
static int flag=0,prev_cosmo=0;
static double *y,*ya,*yb,*y2b,*xb,rv[21],rmin,rmax,dlogr;
int i,j,k,irad,iphi;
double vprob,m1,m2;
if(!flag || RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo)
{
rmin=1.7*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rmax=XI_MAX_RADIUS;
dlogr=log(rmax/rmin)/(nr1-1);
if((RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo) && !ThisTask)
{
printf("RESET: creating new table for:\n");
printf(" > OMEGA_M = %f\n",OMEGA_M);
printf(" > SIGMA_8 = %f\n",SIGMA_8);
printf(" > VBIAS = %f\n",VBIAS);
printf(" > VBIAS_C = %f\n",VBIAS_C);
fflush(stdout);
}
RESET_PVZ=0;
prev_cosmo=RESET_COSMOLOGY;
create_pdf_table();
if(!flag)
{
y=dvector(1,nphi1);
ya=dvector(1,nphi1);
yb=dvector(1,4);
y2b=dvector(1,4);
xb=dvector(1,4);
}
flag=1;
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
spline(vvv,ppp[i][j],nv1,1.0E+30,1.0E+30,yy2[i][j]);
}
if(fabs(vel)>MAXVEL)return(0);
if(theta<0)theta*=-1;
for(i=1;i<=nr1;++i)
if(rad<rbin[i])break;
if(i<3)i=3;
if(i>nr1-1)i=nr1-1;
irad=i;
while(rbin[irad-2]==0)irad++;
if(irad>nr1-1)
{
printf("ERROR CANNOT ITERPOLATE FOR r=%f\n",rad);
exit(0);
}
for(j=1,i=irad-2;i<=irad+1;++i,++j)
{
for(k=1;k<=nphi1;++k)
{
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[k]);
}
spline(phibin,y,nphi1,1.0E+30,1.0E+30,ya);
splint(phibin,y,ya,nphi1,theta,&yb[j]);
xb[j]=rbin[i];
}
spline(xb,yb,4,1.0E30,1.0E30,y2b);
splint(xb,yb,y2b,4,rad,&vprob);
if(vprob<0)vprob=0;
return(vprob);
irad=i;
if(irad<2)irad=2;
if(irad>nr1)irad=nr1;
iphi = (int)theta/(PI/18.0)+1;
if(iphi==nphi1)iphi=nphi1-1;
for(j=1,i=irad-1;i<=irad;++i)
{
for(k=iphi;k<=iphi+1;++k)
{
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[j++]);
}
}
m1 = (y[1]-y[2])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[1];
m2 = (y[3]-y[4])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[3];
vprob = (m2-m1)/(rbin[irad]-rbin[irad-1])*(rad-rbin[irad-1])+m1;
if(vprob<0)vprob=0;
return(vprob);
}
/* For consistency, the MAXVEL and BINSIZE variables will be scaled by
* OMEGA_M^0.6.
*
*/
void create_pdf_table()
{
#define NZMASS 19
int TEST=1;
FILE *fp;
double dlogr,vbias1,vbias2;
static int CNT=0;
double sgal[NZMASS][NZMASS],sgal_cs[NZMASS][NZMASS],sgal_cc[NZMASS][NZMASS],
*cf,fdat[10],s2gal[4],wgal[3],**mtemp,
***ptemp,*vtemp,*temp,*p1temp,*p2temp,*precv,*rvir,*ngal,**ngal2,**ngal2x,*mbin;
double binsize,ptot,vprob,p0,p1,p2,p3,s1,s2,s3,s4,v1,v,
mass,mlo,mhi,qromo(),midpnt(),sgal1[NZMASS][NZMASS],hmass[NZMASS],
sgal2[NZMASS][NZMASS],w1[NZMASS][NZMASS],w2[NZMASS][NZMASS],mass1,mass2,wsum,fac,
w3[NZMASS][NZMASS],t0,tsum=0,t1,tdiff,frac1,frac2,frac3,frac4,x1,x2,deltar,
haloweight,immax,mmax,rmax,rmin,exfac,xx1=0,weightsum;
int i,j,k,n,nzmass,imass=0,irad,im1,im2,istep=1,istart=1,jstart=1,jstep=1,
idat[10],nitems;
float f1;
CNT++;
#ifdef PARALLEL
istep = 1;
istart = 1;
jstart = ThisTask + 1;
jstep = NTask;
#endif
BINSIZE=20*pow(OMEGA_M/0.3,0.6);
rmin=R_MIN_2HALO;
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rmax=XI_MAX_RADIUS;
nr1=30;
nv1=301;
nphi1=9;
MAXVEL=BINSIZE*floor(nv1/2);
/* This assumes that even if the cosmology is changed, that
* the dimensions of these arrays won't change.
*/
if(FIRSTFLAG)
{
vvv=dvector(1,nv1);
rbin=dvector(1,nr1);
phibin=dvector(1,nphi1);
yy2=d3tensor(1,nr1,1,nphi1,1,nv1);
ppp=d3tensor(1,nr1,1,nphi1,1,nv1);
FIRSTFLAG=0;
}
if(TEST)
{
HOD.pdfs=0;
HOD.M_min = HOD.M_low = 4.4e11;
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
}
dlogr=log(rmax/rmin)/(nr1-1);
for(i=1;i<=nr1;++i)
rbin[i]=rmin*exp((i-1)*dlogr);
for(i=1;i<=nphi1;++i)
phibin[i]=(i-0.5)/nphi1*PI/2;
for(i=1;i<=nv1;++i)
vvv[i]=-MAXVEL+(i-1)*BINSIZE;
nzmass=NUM_POW2MASS_BINS-1;
ptemp=d3tensor(0,nzmass-1,0,nzmass-1,1,nv1);
vtemp=dvector(1,nv1);
temp=dvector(1,nv1);
p1temp=dvector(1,nv1);
p2temp=dvector(1,nv1);
precv=dvector(1,nv1);
rvir=dvector(0,nzmass);
mbin=dvector(0,nzmass);
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
for(k=1;k<=nv1;++k)
ppp[i][j][k]=0;
binsize=BINSIZE;
fac=sqrt(4.499E-48/2.0)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
fac=fac*fac;
/* w1 -> number of i_sat + j_cen pairs
* w2 -> number of j_sat + i_cen pairs
* w3 -> number of i_sat + j_sat pairs
*
* Okay, I know that all you have to do is switch the indices on
* w1 to get w2, but just to keep things really clear, I'll have three
* different matrices.
*/
for(i=0;i<nzmass;++i)
for(j=0;j<nzmass;++j)
{
mass1=1.5*pow(2.0,i)*HOD.M_low;
vbias1 = (VBIAS_SLOPE*(log(mass1)-34.5)+VBIAS);
if(vbias1<0.1)vbias1=0.1;
//vbias1 = 0.4/3*log(mass1)/LOGE_10 - 1;
//if(vbias1<0.6)vbias1=0.6;
/* TEMP-> mass threshold
*/
/*
vbias1=1;
if(mass1<VBIAS_MASS_THRESHOLD)
vbias1=VBIAS;
*/
vbias1 *= vbias1;
mass2=1.5*pow(2.0,j)*HOD.M_low;
vbias2 = (VBIAS_SLOPE*(log(mass2)-34.5)+VBIAS);
if(vbias2<0.1)vbias2=0.1;
//vbias2 = 0.4/3*log(mass2)/LOGE_10 - 1;
//if(vbias2<0.6)vbias2=0.6;
/* TEMP-> mass threshold
*/
/*
vbias2=1;
if(mass2<VBIAS_MASS_THRESHOLD)
vbias2=VBIAS;
*/
vbias2 *= vbias2;
mbin[i]=mass1;
s1=vbias1*fac*pow(mass1,0.66666666667);
s2=vbias2*fac*pow(mass2,0.66666666667);
sgal[i][j]=s1+s2;
s1=fac*pow(mass1,0.66666666667)*VBIAS_C*VBIAS_C;
sgal_cs[i][j]=s1+s2;
s2=fac*pow(mass2,0.66666666667)*VBIAS_C*VBIAS_C;
sgal_cc[i][j]=s1+s2;
wsum=N_avg(mass1)*dndM_interp(mass1)*N_avg(mass2)*dndM_interp(mass2);
w1[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_cen(mass2)*dndM_interp(mass2);
w2[i][j]=N_sat(mass2)*dndM_interp(mass2)*N_cen(mass1)*dndM_interp(mass1);
w3[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_sat(mass2)*dndM_interp(mass2);
// this is for testing sat-sat 2halo term
//w1[i][j] = w2[i][j] = 0;
//wsum = w3[i][j];
//w1[i][j] = w2[i][j] = w3[i][j] = 0;
//wsum = w3[i][j];
//w1[i][j] = w2[i][j] = 0;
w1[i][j]/=wsum;
w2[i][j]/=wsum;
w3[i][j]/=wsum;
}
/* Calculate the average number of galaxy
* pairs in each combination of halo mass bins.
*/
ngal=dvector(0,nzmass-1);
ngal2=dmatrix(0,nzmass-1,0,nzmass-1);
ngal2x=dmatrix(0,nzmass-1,0,nzmass-1);
for(i=0;i<nzmass;++i)
{
mlo=pow(2.0,i)*HOD.M_low;
mhi=mlo*2;
ngal[i]=qromo(func_galaxy_density,log(mlo),log(mhi),midpnt);
ngal2[i][i]=ngal[i]*ngal[i]*0.5;
}
for(i=0;i<nzmass;++i)
for(j=i+1;j<nzmass;++j)
ngal2[i][j]=ngal[i]*ngal[j];
/* Calculate the virial radius for each halo bin.
*/
for(i=0;i<nzmass;++i)
rvir[i]=pow(3*pow(2.0,i)*HOD.M_low*ROOT2/
(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
for(i=0;i<nzmass;++i)
hmass[i] = 1.5*pow(2.0,i)*HOD.M_low;
for(k=1;k<=nv1;++k)
vtemp[k]=vvv[k];
/* TEMP TEMP TEMP
*/
for(i=0;i<nzmass;++i)
for(j=i;j<nzmass;++j)
//ngal2x[i][j] = N_cen(hmass[i])*N_sat(hmass[j]) + N_cen(hmass[j])*N_sat(hmass[i]);
//ngal2x[i][j] = N_sat(hmass[i])*N_sat(hmass[j]);
ngal2x[i][j] = N_cen(hmass[i])*N_cen(hmass[j]);
for(i=0;i<nzmass;++i)
ngal2x[i][i]/=2;
/* For each r/phi combination, first calculate the pdf for all possible
* halo-halo pairs. Once the h-h pdf is calculates, convolve with the
* galaxy Gaussian pdf.
*/
j=jstart;
if(NTask==1 && OUTPUT)
{
printf("TASK %d starting: %d %d\n",ThisTask,istart,jstart);
fflush(stdout);
}
t0=second();
for(i=istart;i<=nr1;)
{
while(j>nphi1) { i++; j=j-nphi1; }
if(i>nr1)break;
jstart=j;
for(j=jstart;j<=nphi1;j+=jstep)
{
t1=second();
tdiff=timediff(t0,t1);
tsum+=tdiff;
t0=second();
if(NTask==1 && OUTPUT)
{
fprintf(stdout,"P(v_z) r[%d]= %5.2f phi[%d]=%4.1f [dt= %.2f T=%7.2f] (task= %d)\n",
i,rbin[i],j,phibin[j]*180/PI,tdiff,tsum,ThisTask);
fflush(stdout);
}
for(im1=0;im1<nzmass;++im1)
{
for(im2=im1;im2<nzmass;++im2)
{
/* NEW VERSION, with varying VBIAS_C
*/
s1=sgal_cs[im2][im1];
s2=sgal_cs[im1][im2];
s3=sgal[im1][im2];
s4=sgal_cc[im1][im2];
s2gal[0]=s1;
s2gal[1]=s2;
s2gal[2]=s3;
s2gal[3]=s4;
wgal[0]=w1[im1][im2];
wgal[1]=w2[im1][im2];
wgal[2]=w3[im1][im2];
vdelta_v4(mbin[im1],mbin[im2],rbin[i],phibin[j],BINSIZE,-MAXVEL,nv1,cf,
temp,p1temp,ptemp[im1][im2],wgal,s2gal);
}
}
/* Output some stuff for testing purposes
*/
if(TEST && (j==1 || j==9))
//if(j==1 || j==9)
{
for(im1=0;im1<nzmass;++im1)
{
p0=p1=p2=0;
for(k=1;k<=nv1;++k)
{
v = -MAXVEL + (k-1)*BINSIZE;
p0 += ptemp[im1][im1][k]*BINSIZE;
p1 += ptemp[im1][im1][k]*v*BINSIZE;
p2 += ptemp[im1][im1][k]*v*v*BINSIZE;
//printf("xTEST%d MASS%d %f %e\n",j,im1+1,ptemp[im1][im1][k]);
}
p1 = p1/p0;
p2 = sqrt(p2/p0 - p1*p1);
if(!isnan(p0+p1+p2))
printf("TEST%d MASS%d %e %f %f %f\n",j,im1+1,hmass[im1],rbin[i],-p1,p2);
}
}
/* Now calculate the galaxy-number-wieghted average
* of the v_z pdf by summing over all halo-halo pairs.
* (Using sum of virial radii for halo exclusion.)
*/
ptot=0;
weightsum=0;
for(k=1;k<=nv1;++k)
for(ppp[i][j][k]=0,im1=0;im1<nzmass;++im1)
for(im2=im1;im2<nzmass;++im2)
{
if(rbin[i]>rvir[im2]*0.75)
{
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
if(k==1)weightsum+=ngal2[im1][im2]*
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
}
continue;
if(rbin[i]/(rvir[im1]+rvir[im2])>0.5)
{
exfac=1;
if(rbin[i]/(rvir[im1]+rvir[im2])<1.5)
exfac=ellipsoidal_exclusion_probability(rvir[im2]/rvir[im1],
rbin[i]/(rvir[im1]+rvir[im2]));
/*
if(rbin[i]<(rvir[im1]+rvir[im2]))
exfac = 0;
if(rvir[im2]/rvir[im1]>pow(100.0,.333) && rbin[i]>(rvir[im1]+rvir[im2])*0.5)
exfac = 1;
*/
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*exfac*1*
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
if(k==1)weightsum+=ngal2[im1][im2]*exfac*1*
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
}
}
//printf("WEIGHTSUM %d %d %e %.0f\n",
// i,j,weightsum,weightsum*BOX_SIZE*BOX_SIZE*BOX_SIZE);
if(weightsum>0)
{
for(k=1;k<=nv1;++k)
ppp[i][j][k]/=weightsum;
// for(k=1;k<=nv1;++k)
//printf("yTEST %d %d %f %e\n",i,j,vvv[k],ppp[i][j][k]);
for(ptot=0,k=1;k<=nv1;++k)
ptot+=ppp[i][j][k]*binsize;
}
else
for(k=1;k<=nv1;++k)
ppp[i][j][k]=0;
}
}
#ifdef PARALLEL
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
{
for(k=1;k<=nv1;++k)
temp[k]=ppp[i][j][k];
MPI_Allreduce(&temp[1],&precv[1],nv1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
for(k=1;k<=nv1;++k)
ppp[i][j][k]=precv[k];
}
#endif
free_d3tensor(ptemp,0,nzmass-1,0,nzmass-1,1,nv1);
free_dvector(vtemp,1,nv1);
free_dvector(temp,1,nv1);
free_dvector(p1temp,1,nv1);
free_dvector(p2temp,1,nv1);
free_dvector(precv,1,nv1);
free_dvector(rvir,0,nzmass);
free_dvector(mbin,0,nzmass);
free_dvector(ngal,0,nzmass-1);
free_dmatrix(ngal2,0,nzmass-1,0,nzmass-1);
}