/* If soft central cutoff, then put a lower limit on mass integrals * that begins at the mass where N_cen=0.001. */ double func_mlow(double m) { /* Have a check in case the passed mass is equal to M_min, but the value of * N_cen is < 0.001 (which might be the case for very small sigma_logM) */ if(fabs(exp(m)-HOD.M_min)<0.001*HOD.M_min) if(N_cen(exp(m))<0.001)return(0); // fprintf(stderr,"MLO %e %e %e %e %e\n",exp(m),N_cen(exp(m)),HOD.M_min,HOD.M_cen_max,HOD.M_low); return(N_cen(exp(m))-0.001); }
/* If soft central cutoff, then put a lower limit on mass integrals * that begins at the mass where N_cen=0.001. */ double func_mlow(double m) { /* Have a check in case the passed mass is equal to M_min, but the value of * N_cen is < 0.001 (which might be the case for very small sigma_logM) */ //fprintf(stdout,"MLOTOP %e %e %e\n",exp(m),HOD.M_min,N_cen(exp(m))); if(fabs(exp(m)-HOD.M_min)<0.001*HOD.M_min) if(N_cen(exp(m))<0.001*N_cen(HOD.M_min))return(0); //fprintf(stdout,"MLO %e %e %e %e %e\n",exp(m),N_cen(exp(m)),HOD.M_min,N_cen(HOD.M_min),HOD.M_low); //return(N_cen(exp(m))-0.001); //changing to 0.001 of the value at HOD.M_Min return(N_cen(exp(m))/N_cen(HOD.M_min)*1000 - 1); }
/* Same as above, only now we're calculating the number of pairs * in the cross-correlation. * * NB! -- We're assuming that the satellite galaxy profiles * of both HODs are the same. */ double func1_xcorr(double m) { double N,n,fac2,rvir,f_ss=0,f_cs=0,cvir,x,rfof,ncen1,nsat1,ncen2,nsat2; m=exp(m); cvir=halo_concentration(m)*CVIR_FAC; n=dndM_interp(m); nsat1=N_sat(m); ncen1=N_cen(m); nsat2=N_sat2(m); ncen2=N_cen2(m); rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0); /* Break up the contribution of pairs into * central-satellite (cs) and satellite-satellite (ss) pairs. * But for x-corr, we have c1-s2, c2-s1, s1-s2. */ f_ss=dFdx_ss(r_g2/rvir,cvir)*nsat1*nsat2; f_cs=dFdx_cs(r_g2/rvir,cvir)*(nsat1*ncen2 + nsat2*ncen1); x=n*(f_ss+f_cs)/rvir*m; return(x); }
double func1cs(double m) { double N,n,fac2,rvir,f_ss,f_cs,cvir,x,rfof,ncen,nsat; m=exp(m); cvir=halo_concentration(m)*CVIR_FAC; n=dndM_interp(m); nsat=N_sat(m); ncen=N_cen(m); rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0); /* Break up the contribution of pairs into * central-satellite (cs) and satellite-satellite (ss) pairs. */ f_cs=dFdx_cs(r_g2/rvir,cvir)*nsat*ncen; x=n*(f_cs)/rvir*m; // if(OUTPUT==3) // printf("%e %e %e %e %e\n",m,n,f_ss,f_cs,rvir); return(x); }
double func_central_bias(double m) { double n1,n2,m0; m=exp(m); n1=dndM_interp(m); n2=N_cen(m); return(n1*n2*m*bias_interp(m,-1)); }
void output_hod(char fname[]) { FILE *fp; double dlogm,sig,m; int i; fp=fopen(fname,"w"); dlogm=(log(HOD.M_max)-log(HOD.M_low))/99; for(i=1;i<=100;++i) { m=exp((i-1)*dlogm)*HOD.M_low; sig = N_sat(m)*N_sat(m) + N_cen(m)*(1-N_cen(m)); fprintf(fp,"%e %e %e %e %e %e\n", m,N_cen(m),N_sat(m),N_avg(m),sig,sig/(N_avg(m)*N_avg(m))); } fclose(fp); }
void analytic_sham() { int i,j,k,nlogm=400,imag,nmag,jmin; double dlogm,halocnt[401],magcnt[200],subcnt[401],m,msub,n1,mlow,dmag,magmin,nsub; double *hmass, *mag, *yy; dmag = 0.2; magmin = -18.0; nmag = 5/dmag; for(i=0;i<200;++i) magcnt[i] = 0; hmass = dvector(1,nlogm); mag = dvector(1,nlogm); yy = dvector(1,nlogm); mlow = HOD.M_low; for(i=1;i<=nlogm;++i) halocnt[i] = subcnt[i] = 0; // go through the mass function to find TOTAL number of halos dlogm = log(HOD.M_max/mlow)/nlogm; // get all HOD HOD.mass_shift = 0; HOD.fredc = 0.44; HOD.mass_shift = 0.6616; HOD.fredc = 1.00; HOD.mass_shift = 0.2; HOD.fredc = 0.66; for(i=1;i<=nlogm;++i) { m = exp(dlogm*(i-0.5))*mlow; halocnt[i] += dndM_interp(m)*m*dlogm; n1 = 0; for(j=1;j<=nlogm;++j) { msub = exp(dlogm*(j-0.5))*mlow; if(msub>m/3)continue; // no subhalo greater than half total mass //n1 = pow(m,0.5)/2.6*pow(msub,-1.5)*exp(-pow(msub/m/0.7,6))*dlogm*m/2; //original +2 //n1 = pow(m,0.7)/2.6*pow(msub,-1.7)*exp(-pow(msub/m/0.7,6))*dlogm*m/3.16; n1 = pow(msub,-2)*m*m*dlogm*15.7*HOD.M1; halocnt[0] += n1; subcnt[0] += N_cen(msub)*n1; } //printf("%e %e %e\n",m,N_sat(m),n1); } printf("%f\n",subcnt[0]/halocnt[0]); exit(0); }
double func2_m2n(double m) { double ncen,nsat,x; m = exp(m); ncen = N_cen(m); nsat = N_sat(m); x = poisson_prob(g31_number-1,nsat); if(isnan(x))x = 0; return ncen*x*m*dndM_interp(m); }
/* If modeling magnitude bin samples, then there will be a high mass * scale for central galaxies as well as a low mass scale. This finds * the mass at which N_cen(m)=0.001, where m>M_min. */ double set_high_central_mass() { double m,n; if(HOD.pdfc==7) return(HOD.M_cen_max); if(!(HOD.pdfc==6 || HOD.pdfc==8 || HOD.pdfc==9)) return(HOD.M_max); m = HOD.M_min; n = N_cen(m); while(n>0.001) { m*=2; n = N_cen(m); if(m>HOD.M_max)return(HOD.M_max); } m = exp(zbrent(func_mhi,log(m/2),log(m),1.0E-5)); return(m); }
/* This is the function passed to qromo in the above routine. * It is the number density of * galaxy pairs in halos of mass m at separation r_g2. * See Equation (11) from Berlind & Weinberg. */ double func1(double m) { double N,n,fac2,rvir,f_ss,f_cs,cvir,x,rfof,ncen,nsat,ss; m=exp(m); cvir=halo_concentration(m)*CVIR_FAC; n=dndM_interp(m); nsat=N_sat(m); ncen=N_cen(m); rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0); /* Break up the contribution of pairs into * central-satellite (cs) and satellite-satellite (ss) pairs. */ f_ss=dFdx_ss(r_g2/rvir,cvir)*moment_ss(m)*0.5; f_cs=dFdx_cs(r_g2/rvir,cvir)*nsat*ncen; x=n*(f_ss+f_cs)/rvir*m; // only send the cs term //x = n*f_cs/rvir*m; // only send the ss term //x = n*f_ss/rvir*m; // HAMANA /* ss = moment_ss(m); if(ss>1) return x; else return n*dFdx_cs(r_g2/rvir,cvir)*moment_ss(m)*0.5/rvir*m; */ // if(OUTPUT==3) // printf("%e %e %e %e %e\n",m,n,f_ss,f_cs,rvir); return(x); }
void populate_simulation_hod() { FILE *fp,*fpa[9],*fp2,*fpb[9],*fpc[9],*fps[9],*fpt; int i,j,k,n,imass,n1,j_start=0,i1,galcnt[1000],halocnt[1000],imag; double mass,xg[3],vg[3],nsat,nc[10],ncen,mlo,mag,err1,err2,r,fac,sigv; char aa[1000]; float x1,xh[3],vh[3],vgf[3]; long IDUM3 = -445; float **galarr; int *galid,id1=0,id2=0,j1; float dx,dy,dz,dr,drh,rv1,rv2,rmin,rmax; float **haloarr; int ngal,nsati[9],ALL_FILES=0,TRACK_GALAXIES=0,WARREN_MASS_CORRECTION=0,haloid; float *xt,*yt,*zt,*vxt,*vyt,*vzt; int SO_FILE = 1, JEANS_DISPERSION = 0; // if(RESOLUTION > 1.6) // WARREN_MASS_CORRECTION = 1; TRACK_GALAXIES=1; galarr = matrix(1,10000000,0,5); haloarr = matrix(1,10000000,0,6); galid = ivector(1,10000000); fp=openfile(Files.HaloFile); sprintf(aa,"%s.mock",Task.root_filename); fp2 = fopen(aa,"w"); sprintf(aa,"%s.mock_halo",Task.root_filename); fpt = fopen(aa,"w"); for(i=0;i<1000;++i) halocnt[i]=0; for(i=0;i<1000;++i) galcnt[i]=0; set_HOD_params(); mlo = HOD.M_low; printf("MLO %e %e %f\n",mlo,HOD.M_min,HOD.sigma_logM); printf("BOX_SIZE %f\n",BOX_SIZE); fflush(stdout); haloid = 0; while(!feof(fp)) { if(SO_FILE) { fscanf(fp,"%d %lf %f %f %f %f %f %f %f %f", &i,&mass,&x1,&x1,&xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2]); fgets(aa,1000,fp); /* fac=sqrt(4.499E-48)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19; sigv=fac*pow(mass,1.0/3.0)/sqrt(2.0); printf("%e %e %f\n",mass,sigv,VBIAS); if(i==2) one_halo(1,1); */ //haloid = i; } else { fscanf(fp,"%d %d %e %e %e %e %e %e %e", &i,&imass,&xh[0],&xh[1],&xh[2],&x1,&vh[0],&vh[1],&vh[2]); mass=imass*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0); } haloid++; //in case it's not iterated in the file if(mass>HOD.M_max)continue; if(WARREN_MASS_CORRECTION) mass = imass*(1-pow(imass,-0.6))*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0); if(mass<mlo)continue; for(i=0;i<3;++i) { if(xh[i]<0)xh[i]+=BOX_SIZE; if(xh[i]>BOX_SIZE)xh[i]-=BOX_SIZE; } i1 = (int)(log10(mass)/0.1); halocnt[i1]++; ncen=N_cen(mass); if(drand48()>ncen)goto SATELLITES; if(VBIAS_C>0) { NFW_central_velocity(mass,vg,mag); for(i=0;i<3;++i) vh[i]+=vg[i]; } fprintf(fp2,"%e %e %e %e %e %e\n",xh[0],xh[1],xh[2],vh[0],vh[1],vh[2]); fprintf(fpt,"%d\n",haloid); // THis mocks up the ~22 columns of the MR mocks // fprintf(fpt,"%d %d %d %e %e %e 0.0 0.0 0.0 %e %e %e 0.0 0.0 0.0 0.0 0.0 0.0 %e 0.0 0.0\n", // 0,0,0,xh[0],xh[1],xh[2],vh[0],vh[1],vh[2],log10(mass)); if(VBIAS_C>0) { for(i=0;i<3;++i) vh[i]-=vg[i]; } galcnt[i1]++; if(TRACK_GALAXIES) { id2++; galid[id2] = haloid; galarr[id2][0] = xh[0]; galarr[id2][1] = xh[1]; galarr[id2][2] = xh[2]; galarr[id2][3] = vh[0]; galarr[id2][4] = vh[1]; galarr[id2][5] = vh[2]; } if(TRACK_GALAXIES) { id1++; haloarr[id1][0] = xh[0]; haloarr[id1][1] = xh[1]; haloarr[id1][2] = xh[2]; haloarr[id1][3] = vh[0]; haloarr[id1][4] = vh[1]; haloarr[id1][5] = vh[2]; haloarr[id1][6] = mass; } SATELLITES: nsat = N_sat(mass); if(nsat>250) n1 = gasdev(&IDUM3)*sqrt(nsat) + nsat; else n1 = poisson_deviate(nsat); /* if(nsat>1) fprintf(stdout,"BUH %d %f %e %d %e %f\n",haloid,nsat,mass,n1,HOD.M1,pow(mass/HOD.M1,HOD.alpha)); */ for(i=1;i<=n1;++i) { r = NFW_position(mass,xg); if(JEANS_DISPERSION) jeans_dispersion(mass,r,vg); else NFW_velocity(mass,vg,mag); for(k=0;k<3;++k) { xg[k]+=xh[k]; if(xg[k]<0)xg[k]+=BOX_SIZE; if(xg[k]>BOX_SIZE)xg[k]-=BOX_SIZE; vg[k]+=vh[k]; /* vg[k] = vgf[k]; */ /* vg[k] = gasdev(&IDUM3)*500; vg[k] = non_gaussian_velocity(); */ } fprintf(fp2,"%e %e %e %e %e %e\n",xg[0],xg[1],xg[2],vg[0],vg[1],vg[2]); fprintf(fpt,"%d\n",haloid); // fprintf(fpt,"%d %d %d %e %e %e 0.0 0.0 0.0 %e %e %e 0.0 0.0 0.0 0.0 0.0 0.0 %e 0.0 0.0\n",1,1,1,xg[0],xg[1],xg[2],vg[0],vg[1],vg[2],log10(mass)); if(TRACK_GALAXIES) { id2++; galid[id2] = haloid; galarr[id2][0] = xg[0]; galarr[id2][1] = xg[1]; galarr[id2][2] = xg[2]; galarr[id2][3] = vg[0]; galarr[id2][4] = vg[1]; galarr[id2][5] = vg[2]; } /* Bin up the galaxies by halo mass to check the HOD */ galcnt[i1]++; } if(feof(fp))break; } fclose(fp2); fclose(fpt); /* output the binned HOD */ sprintf(aa,"%s.binned_HOD",Task.root_filename); fp2=fopen(aa,"w"); for(i=0;i<1000;++i) if(galcnt[i]>0) fprintf(fp2,"%d %f %f %d %d\n", i,(i+0.5)*0.1,(float)galcnt[i]/halocnt[i],galcnt[i],halocnt[i]); fclose(fp2); /* Calculate the two-halo term */ if(TRACK_GALAXIES) { fprintf(stderr,"Calling nbody_2halo...\n"); calc_nbody_two_halo(galarr,galid,id2); } return ; /* Track the close pairs - for Non-Tinkers, don't worry about this. */ rmin = 1.5; rmax = 2.5; for(i=1;i<=id2;++i) for(j=i+1;j<=id2;++j) { if(galid[i]==galid[j])continue; dx = galarr[i][0] - galarr[j][0]; if(dx>BOX_SIZE/2)dx = BOX_SIZE-dx; if(dx>rmax)continue; dy = galarr[i][1] - galarr[j][1]; if(dy>BOX_SIZE/2)dy = BOX_SIZE-dy; if(dy>rmax)continue; dz = galarr[i][2] - galarr[j][2]; if(dz>BOX_SIZE/2)dz = BOX_SIZE-dz; if(dz>rmax)continue; dr = sqrt(dx*dx+dy*dy+dz*dz); if(dr<rmin || dr>rmax)continue; i1 = galid[i]; j1 = galid[j]; dx = haloarr[i1][0] - haloarr[j1][0]; if(dx>BOX_SIZE/2)dx = BOX_SIZE-dx; dy = haloarr[i1][1] - haloarr[j1][1]; if(dy>BOX_SIZE/2)dy = BOX_SIZE-dy; dz = haloarr[i1][2] - haloarr[j1][2]; if(dz>BOX_SIZE/2)dz = BOX_SIZE-dz; drh = sqrt(dx*dx+dy*dy+dz*dz); rv1 = pow(3*haloarr[i1][6]/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0); rv2 = pow(3*haloarr[j1][6]/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0); if(dr < rv1+rv2) { dx = galarr[i][3] - galarr[j][3]; dy = galarr[i][4] - galarr[j][4]; dz = galarr[i][5] - galarr[j][5]; printf("%e %e %e %e %e %e %e\n",dr,rv1+rv2,haloarr[i1][6],haloarr[j1][6],dx,dy,dz); fflush(stdout); } } exit(0); }
void fit_color_samples() { int n,niter,i,j; double *a,**pp,*yy,FTOL=1.0E-3,chi2min,s1,dlogm,m; FILE *fp; char aa[1000]; mcmc_color_minimization(); fprintf(stderr,"\n\nCHI2 MINIMIZATION OF W_P(R_P) COLOR DATA..........\n"); fprintf(stderr, "--------------------------------------------\n\n"); HOD.blue_fraction = 0.5857; /* <- Millenium fraction (sloan);; SDSS fraction -> 0.565; */ HOD.blue_fraction = 0.6555; /* <- Millenium fraction (B-V>0.8) */ HOD.blue_fraction = 0.565; /* SDSS -19,-20 */ HOD.blue_fraction = 0.492; /* SDSS -20,-21 */ HOD.blue_fraction = 0.379; /* SDSS -21 */ wp_color.ON = 1; if(POWELL) FTOL=1.0E-3; else FTOL=1.0E-5; for(n=0,i=1;i<=7;++i) { n+=HOD.free[i]; if(!OUTPUT)continue; printf("wp_min> free[%i] = %d\n",i,HOD.free[i]); } /* The parameters that govern the blue fraction aren't * listed in the HOD.free array, so add them in. * NB: There are four parameters for these two functions, * one of which is fit by the number densities. */ n+=3; if(OUTPUT)printf("wp_min> Number of free parameters: %d\n",n); wp_color_input(); wp.ncf=n; a=dvector(1,n); if(POWELL) pp=dmatrix(1,n,1,n); else pp=dmatrix(1,n+1,1,n); yy=dvector(1,n+1); initial_color_values(a,pp,yy); if(POWELL) { if(OUTPUT)printf("wp_min> starting powell.\n"); powell(a,pp,n,FTOL,&niter,&chi2min,chi2_wp_color); chi2min = chi2_wp_color(a); } else { if(OUTPUT)printf("wp_min> starting amoeba.\n"); amoeba(pp,yy,n,FTOL,chi2_wp_color,&niter); for(i=1;i<=n;++i)a[i]=pp[1][i]; chi2min = chi2_wp_color(a); } s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt); GALAXY_BIAS=s1/GALAXY_DENSITY; printf("POWELL %e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen); if(HOD.pdfc==7) printf("%e ",HOD.M_cen_max); for(i=1;i<=n;++i)printf("%e ",a[i]); printf(" %f\n",GALAXY_BIAS); /* Output the fit and the HOD curve. */ sprintf(aa,"%s.fit",Task.root_filename); fp=fopen(aa,"w"); fprintf(fp,"%e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen); if(HOD.pdfc==7) fprintf(fp,"%e ",HOD.M_cen_max); for(i=1;i<=n;++i)fprintf(fp,"%e ",a[i]); fprintf(fp," %f\n",GALAXY_BIAS); fclose(fp); sprintf(aa,"%s.HOD",Task.root_filename); fp=fopen(aa,"w"); dlogm=(log(HOD.M_max)-log(HOD.M_low))/99; for(i=1;i<=100;++i) { m=exp((i-1)*dlogm)*HOD.M_low; fprintf(fp,"%e %e %e %e\n",m,N_cen(m),N_sat(m),N_avg(m)); } fclose(fp); }
// this is to calculate the numer-weighted mass of DRG galaxies double func_drg1(double m) { m = exp(m); return N_cen(m)*m*dndM_interp(m)*m; }
void output_drg_lf(int iout) { FILE *fp; char fname[100]; int i,j,k,nlogm=400,imag,nmag,jmin; double dlogm,halocnt[401],magcnt[200],m,msub,n1,mlow,dmag,magmin,nsub; double *hmass, *mag, *yy; dmag = 0.2; magmin = -18.0; nmag = 5/dmag; for(i=0;i<200;++i) magcnt[i] = 0; hmass = dvector(1,nlogm); mag = dvector(1,nlogm); yy = dvector(1,nlogm); mlow = HOD.M_low/5.0; for(i=1;i<=nlogm;++i) halocnt[i] = 0; // go through the mass function to find TOTAL number of halos dlogm = log(HOD.M_max/mlow)/nlogm; for(i=1;i<=nlogm;++i) { m = exp(dlogm*(i-0.5))*mlow; halocnt[i] += dndM_interp(m)*m*dlogm; for(j=1;j<=nlogm;++j) { msub = exp(dlogm*(j-0.5))*mlow; if(msub>m/2)continue; // no subhalo greater than half total mass // charlie's fit (with extra factor of log(10)?) halocnt[j] += 0.02*log(10)*pow(msub/m,-0.9)*exp(-msub/(2*m))*dlogm*dndM_interp(m)*m*dlogm; // gao et al 2004-- gives ~4% at M=1e12 z=0. //halocnt[i] += 6.3e-4*pow(msub,-1.9)*m*msub*dlogm*dndM_interp(m)*m*dlogm; } } // make it cumulative // and associate a magnitude at every mass. mag[nlogm] = mag_at_fixed_ngal(halocnt[nlogm]); hmass[nlogm] = exp(dlogm*(nlogm-0.5)*mlow); for(i=nlogm-1;i>=1;--i) { halocnt[i] += halocnt[i+1]; mag[i] = mag_at_fixed_ngal(halocnt[i]); hmass[i] = exp(dlogm*(i-0.5))*mlow; //printf("CNT %e %e %e\n",hmass[i],halocnt[i],lf_number_density(-27.9,-2.0)); } // prepare for spline interpolation spline(hmass,mag,nlogm,1.0E+30,1.0E+30,yy); // now go through HOD and create the DRG luminosity function for(i=1;i<=nlogm-1;++i) { m = hmass[i]; if(m<HOD.M_low)continue; imag = (magmin-mag[i])/dmag+1; //printf("%e\n",magcnt[i]); magcnt[imag] += N_cen(m)*dndM_interp(m)*dlogm*m; //printf("%e %f %d %e %e %e %e %e\n",m,mag[i],imag,magcnt[imag],N_cen(m),m,dlogm,dndM_interp(m)); //continue; // find the minimum subhalo mass nsub = 0; for(j=nlogm;j>=1;--j) { msub = hmass[j]; if(msub>m/2)continue; nsub += 0.02*log(10)*pow(msub/m,-0.9)*exp(msub/(2*m))*dlogm; if(nsub>N_sat(m)/HOD.freds) break; } if(j==nlogm)continue; jmin = j; if(jmin>=0) { printf("ERR %d %e %e %e %e %f\n",j,m,msub,nsub,N_sat(m)/HOD.freds,mag[jmin]); } // go through the satellites for(j=jmin;j<=nlogm;++j) { msub = hmass[j]; if(msub>m/2)break; imag = (magmin-mag[j])/dmag+1; magcnt[imag] += HOD.freds*0.02*log(10)*pow(msub/m,-0.9)*exp(msub/(2*m))*dlogm*dndM_interp(m)*m*dlogm; } } // print out the results sprintf(fname,"drg_lf.%d",iout); fp = fopen(fname,"w"); n1 = 0; for(i=0;i<200;++i) { if(-(i-0.5)*dmag+magmin >-21.6)continue; magcnt[i]/=dmag; if(magcnt[i]>0) fprintf(fp,"%f %e\n",-(i-0.5)*dmag + magmin,magcnt[i]); n1 += magcnt[i]*dmag; } printf("TOTAL ngal = %e\n",n1); fclose(fp); }
double funcxx2(double m) { m=exp(m); return(m*N_cen(m)*dndM_interp(m)*m); }
/* This function is to be passed to qromo to integrate the number density * of satellite galaxies. */ double func_central_density(double m) { m=exp(m); return(N_cen(m)*dndM_interp(m)*m); }
double func_mhi(double m) { m=exp(m); return(N_cen(m)-0.001); }
/* It is straightforward to calculate what M_low * should be given the other parameters on N_cen. */ double set_low_mass() { int i; double m,test_n; if(ERROR_FLAG) { fprintf(stdout,"uncaught ERROR at top of set low mass\n"); ERROR_FLAG = 0; } if(!SOFT_CENTRAL_CUTOFF)return(HOD.M_min); switch(HOD.pdfc){ case 8: case 6: m = log10(HOD.M_min) - sqrt(-2*HOD.sigma_logM*HOD.sigma_logM*log(0.001)); m = pow(10.0,m); return(m); case 9: m = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3, log(HOD.M_min),1.0E-5)); return(m); case 100: case 101: if(wpl.mlow_flag) return HOD.M_max*0.98; /* test_n=N_cen(HOD.M_min*1.0E-6); if(test_n > 0.001) return HOD.M_min*1.0E-7; // this is not ideal but should avoid getting some zbrent error here (notice returning 10^-7 here) */ m = exp(zbrent(func_mlow,log(HOD.M_min*1.0E-6), log(HOD.M_min),1.0E-5)); // changed to 1.0E-6. Could be a problem here is BOTH the data points are above 10^-3 if(m>HOD.M_max) { if(ERROR_FLAG) ERROR_FLAG = 0; return HOD.M_max*1.0E-3; } if(ERROR_FLAG && HOD.M_min > 1.0E+14) { ERROR_FLAG = 0; return HOD.M_min*1.0E-6; } if(ERROR_FLAG) { ERROR_FLAG = 0; return HOD.M_min*1.0E-3; } if(m>HOD.M_min) { return HOD.M_min*1.0E-3; } if(ERROR_FLAG) { fprintf(stdout," ERROR in set_low_mass: %e %e %e %d \n",HOD.M_min, HOD.sigma_logM, GALAXY_DENSITY,wpl.mlow_flag); fprintf(stdout,"n wpl.mlow_flag = %d \n",wpl.mlow_flag); test_n=N_cen(HOD.M_max); fprintf(stdout,"ncen at HOD max = %e \n",test_n); fprintf(stdout,"ncen at HOD.M_min*1.0E-6 = %e \n",N_cen(HOD.M_min*1.0E-6)); fprintf(stdout,"ncen at HOD.M_min and Mmin = %e %e \n",N_cen(HOD.M_min),HOD.M_min); for(i=1000;i<=1600;++i) printf("HODCEN %f %e\n",i/100.0,N_cen(pow(10.0,i/100.0))); exit(0); } return(m); default: m = exp(zbrent(func_mlow,log(HOD.M_min*1.0E-6), log(HOD.M_min),1.0E-5)); return(m); } return(0); }
/* This is a function to set the HOD parameters until * I get some input code or batch file set up. * */ void set_HOD_params() { int i,j=1; double m,error=1.0,tol=1.0E-4,prev,s1,mlo; /* If the mass function at M_max is undefined, reset M_max */ //LOCAL_DENSITY = -0.2; if(LOCAL_DENSITY!=0) { HOD.M_max = 1.0E16; while(dndM_interp(HOD.M_max)<=0) { HOD.M_max*=0.9; } fprintf(stderr,"NEW M_max= %e\n",HOD.M_max); } if(HOD.pdfc == 2 || HOD.pdfc == 3 || HOD.pdfc == 6 || HOD.pdfc == 8 || HOD.pdfc == 9 || HOD.pdfc == 12 || HOD.pdfc == 13) SOFT_CENTRAL_CUTOFF=1; /* Error trap both the galaxy density and M_min both left unspecified. */ if(HOD.M_min<=0 && GALAXY_DENSITY<=0 && HOD.free[0]==0) endrun("ERROR: Must specify either M_min or GALAXY_DENSITY"); /* If the user has specified M_min and M1, calculate the galaxy density. */ if(HOD.M_min>0 && HOD.M1>0) { HOD.M_low = -1; if (wp.ngal==0) wp.ngal = GALAXY_DENSITY; if(SOFT_CENTRAL_CUTOFF) HOD.M_low0 = HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min*1.0E-6),log(HOD.M_min*1.1),1.0E-5)); else HOD.M_low0 = HOD.M_low = HOD.M_min; if(HOD.M_low > HOD.M1 ) { while(N_cen(HOD.M_low) > 0.01) HOD.M_low /= 2.; } //if(HOD.M_low < HOD.M_min/100.) HOD.M_low = HOD.M_min/100.; GALAXY_DENSITY=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt); if(OUTPUT) { fprintf(stdout,"M_low= %e\n",HOD.M_low); fprintf(stdout,"ng= %e\n",GALAXY_DENSITY); } } /* If M_min<=0 then use the specified galaxy density to calculate M_min */ if(HOD.M_min<=0) { if(HOD.pdfc==7 && HOD.pdfc==8) HOD.M_min=pow(10.0,zbrent(fixfunc1,8.0,log10(HOD.M_cen_max*0.99),1.0E-5)); else HOD.M_min=pow(10.0,zbrent(fixfunc1,7.0,14.8,1.0E-5)); if(OUTPUT) fprintf(stderr,"SOFT_CENTRAL_CUTOFF Delta-n %d %e\n",SOFT_CENTRAL_CUTOFF, fixfunc1(log10(HOD.M_min))); HOD.M_low = -1; if(SOFT_CENTRAL_CUTOFF) { //HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3, // log(HOD.M_min),1.0E-5)); HOD.M_low = HOD.M_min/2.; while(N_cen(HOD.M_low) > 0.01) HOD.M_low /= 2.; } else HOD.M_low = HOD.M_min; if(HOD.M_low<1.0E7)HOD.M_low=1.0E+7; if(OUTPUT) { fprintf(stdout,"M_min %e [ng= %e]\n",HOD.M_min,GALAXY_DENSITY); fprintf(stdout,"M_low= %e\n",HOD.M_low); } } /* If M1<=0 then use the specified galaxy density to calculate M1 */ if(HOD.M1<=0) { HOD.M_low = -1; if(SOFT_CENTRAL_CUTOFF) HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3, log(HOD.M_min*1.1),1.0E-5)); else HOD.M_low = HOD.M_min; if(HOD.M_low<1.0E7)HOD.M_low=1.0E+7; HOD.M1=pow(10.0,zbrent(fixfunc2,log10(HOD.M_low),15.8,1.0E-5)); if(OUTPUT) { fprintf(stdout,"M1 %e [ng= %e]\n",HOD.M1,GALAXY_DENSITY); fprintf(stdout,"M_min = %e M_low= %e\n",HOD.M_min,HOD.M_low); } } /* Set the number of halo mass bins we've got. */ NUM_POW2MASS_BINS=log(HOD.M_max/HOD.M_low)/LN_2+1; if(HOD.pdfc==6) HOD.M_hi = set_high_central_mass(); HOD.M_low0 = set_low_mass(); return; }
/* If what is needed is the total number of galaxies in a halo. */ double N_avg(double m) { return(N_cen(m)+N_sat(m)); }
/***************** * DIFFERENT HOD PARAMETERIZATIONS: (1) Satellite galaxies * * This integer HOD.pdfs controls the parameterization of the satellite occupation. * * 0 = halos only, no galaxies (always returns zero) * 1 = power law: N_sat = pow(m/HOD.M1,HOD.alpha) [cut off at M_low] * 2 = power law with soft cutoff: N_sat = pow((m-HOD.M_cut)/HOD.M1,alpha) * 3 = power law with exp cutoff: N_sat = pow(m/HOD.M1,alpha)*exp(-M_cut/(m-M_min)) * 4 = broken power law with exp cutoff (alpha changes at some high mass value) * 5 = broken power law (m-mcut)/m1 parameterization * 6 = power with alternate exp cutoff: N_sat = pow(m/M1)*exp(-M_min/m) * 7 = from Zheng's new paper lognormal cutoff power law * 8 = power with Conroy exp cutoff: N_sat = pow(m/M1)*exp(-M_cut/m) * * 12 = Soft exp cutoff without dependence on centrals, as Reddick 2012 * 13 = Like 2, power law cutoff from Zehavi 2011, dep on centrals * 14 = Like 12, direct dependence on whatever N_cen is chosen * * The PDF is always assumed to be Poisson for satellite galaxies. */ double N_sat(double m) { double m1,f=1,n,nc; if(HOD.color) f = satellite_blue_fraction(m); f = HOD.freds; switch(HOD.pdfs) { case 0: return 0; case 1: if(m<HOD.M_min)return(0); return(f*pow(m/HOD.M1,HOD.alpha)); break; case 2: if(m<HOD.M_low || m<HOD.M_cut)return(0); return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha)); break; case 3: if(m<HOD.M_min)return(0); return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/HOD.M1,HOD.alpha)); break; case 4: if(m<HOD.M_min)return(0); if(m<HOD.M_sat_break) return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/HOD.M1,HOD.alpha)); else { m1 = exp(log(HOD.M_sat_break) - HOD.alpha/HOD.alpha1*log(HOD.M_sat_break/HOD.M1)); /* m1 = exp(log(HOD.M_sat_break) - 1/HOD.alpha1* (HOD.alpha*log(HOD.M_sat_break/HOD.M1) - HOD.M_cut/(HOD.M_sat_break-HOD.M_min))); */ return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/m1,HOD.alpha1)); } break; case 5: if(m<HOD.M_low || m<HOD.M_cut)return(0); if(m<HOD.M_sat_break) return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha)); else { m1 = HOD.M_sat_break*pow((HOD.M_sat_break-HOD.M_cut)/HOD.M1,-HOD.alpha/HOD.alpha1); return(f*pow(m/m1,HOD.alpha1)); } break; case 6: return(pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_min/m)); case 7: if(m<HOD.M_low || m<HOD.M_cut)return(0); return(0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)) *pow((m-HOD.M_cut)/HOD.M1,HOD.alpha)); break; case 8: n = (pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/m)); if(m<HOD.M_min) { nc = N_cen(m); if(n>nc)return(nc); } return(n); case 9: if(m<HOD.M_sat_break) { n = (pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/m)); if(m<HOD.M_min) { nc = N_cen(m); if(n>nc)return(nc); } return n; } m1 = (pow(HOD.M_sat_break/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/HOD.M_sat_break)); n = m1*pow(m/HOD.M_sat_break,HOD.alpha1); return n; break; case 10: if(m<HOD.M_low)return(0); return(0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)) *pow((m)/HOD.M1,HOD.alpha)); break; case 11: if(m<HOD.M_low)return(0); return(f*exp(-HOD.M_cut/m)*pow(m/HOD.M1,HOD.alpha)* 0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM))); break; case 12: if(m<HOD.M_low)return(0); return(f*exp(-HOD.M_cut/m)*pow(m/HOD.M1,HOD.alpha)); break; case 13: if(m<HOD.M_low || m<HOD.M_cut) return(0); return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha)* 0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM))); break; case 14: if(m<HOD.M_low) return(0); return(f*exp(-HOD.M_cut/m)*pow(m/HOD.M1,HOD.alpha)*N_cen(m)); break; case 101: if(m<HOD.M_min)return 0; n = pow(m/HOD.M1,HOD.alpha); if(n<1)return 0; return n-1; case 102: if(m<HOD.M_min)return 0; return pow(m/HOD.M1,HOD.alpha); default: endrun("Illegal value of HOD.pdfs."); } return 0; }