|
1 | 1 | function [Zlist, MergerRateByRedshiftByZ, SFRfractionZ]=... |
2 | | - CosmicHistoryIntegrator(filename,zlist,metallicitychoice, makeplots) |
| 2 | + CosmicHistoryIntegrator(filename, zlistformation, zlistdetection, Msimulated, makeplots) |
3 | 3 | % Integrator for the binary black hole merger rate over cosmic history |
4 | 4 | % COMPAS (Compact Object Mergers: Population Astrophysics and Statistics) |
5 | 5 | % software package |
6 | 6 | % |
7 | 7 | % USAGE: |
8 | 8 | % [Zlist, MergerRateByRedshiftByZ]=... |
9 | | -% CosmicHistoryIntegrator(filename, zlistformation, zlistmerger, zlistdetection, Msimulated, [,makeplots]) |
| 9 | +% CosmicHistoryIntegrator(filename, zlistformation, zlistmerger, [,makeplots]) |
10 | 10 | % |
11 | 11 | % INPUTS: |
12 | 12 | % filename: name of population synthesis input file |
13 | 13 | % should be in COMPAS output h5 format |
14 | 14 | % zlistformation: vector of redshifts at which the formation rate is |
15 | 15 | % computed |
16 | | -% zlistmerger: vector of redshifts at which the merger rate is computed |
17 | | -% zlistdetection: vector of redshifts at which the detection rate is |
18 | | -% computed |
| 16 | +% zlistdetection: vector of redshifts at which the detection rate is computed |
19 | 17 | % Msimulated: total star forming mass represented by the simulation (for |
20 | 18 | % normalisation) |
21 | 19 | % makeplots: if set to 1, generates a set of useful plots (default = 0) |
|
56 | 54 | Mpc=Mpcm/c; %Gpc in seconds |
57 | 55 | yr=3.15569e7; %year in seconds |
58 | 56 |
|
59 | | -if (nargin<2) |
| 57 | +if (nargin<4) |
60 | 58 | error('Not enough input arguments.'); |
61 | 59 | end; |
62 | | -if (nargin<4), makeplots=0; end; |
| 60 | +if (nargin<5), makeplots=0; end; |
63 | 61 |
|
64 | 62 | %cosmology calculator |
65 | | -[zvec,tL]=Cosmology(); |
| 63 | +[tL]=Cosmology(zlistformation); |
66 | 64 | %load COMPAS data |
67 | | -[M1,M2,Z,Tdelay]=DataRead(filename, max(tL)); |
| 65 | +[M1,M2,Z,Tdelay]=DataRead(filename); |
| 66 | +Zlist=unique(Z); |
68 | 67 | %metallicity-specific SFR |
69 | | -[Zlist,SFR,SFRfractionZ]=Metallicity(Z,zvec,metallicitychoice); |
| 68 | +[SFR,Zweight]=Metallicity(Zlist,zlistformation); |
70 | 69 |
|
71 | 70 |
|
72 | 71 | %Consider the contribution of every simulated binary to the merger rate |
73 | 72 | %in every redshift bin by considering when it would have to be formed to |
74 | 73 | %merge at that redshift and normalizing by the relevant |
75 | 74 | %metallicity-specific star formation rate |
76 | | -dz=zvec(2)-zvec(1); |
77 | | -tLmerge=tL(floor(zlist/(zvec(2)-zvec(1)))+1); |
78 | | -MergerRateByRedshiftByZ=zeros(length(zlist),length(Zlist)); |
| 75 | +dz=zlistformation(2)-zlistformation(1); |
| 76 | +tLmerge=tL(floor(zlistformation/dz)+1); |
| 77 | +MergerRateByRedshiftByZ=zeros(length(zlistformation),length(Zlist)); |
79 | 78 | for(i=1:length(M1)), |
80 | 79 | Zcounter=find(Zlist==Z(i)); |
81 | 80 | zformindex=find(tL>=Tdelay(i),1); |
82 | | - for(k=1:length(zlist)), |
| 81 | + for(k=1:length(zlistformation)), |
83 | 82 | zformindex=find(tL>=(Tdelay(i)+tLmerge(k)),1); |
84 | 83 | MergerRateByRedshiftByZ(k,Zcounter)=... |
85 | 84 | MergerRateByRedshiftByZ(k,Zcounter)+... |
86 | | - SFR(zformindex)*SFRfractionZ(zformindex,Zcounter)/Msimulated; |
| 85 | + SFR(zformindex)*Zweight(zformindex,Zcounter)/Msimulated; |
87 | 86 | end; |
88 | 87 | end; |
89 | 88 |
|
90 | 89 | if(makeplots==1), %make a set of default plots |
91 | | - MakePlots(M1,M2,Z,Tdelay,zvec,SFR,SFRfractionZ,... |
92 | | - zlist,Zlist,MergerRateByRedshiftByZ); |
| 90 | + MakePlots(M1,M2,Z,Tdelay,zlistformation,Zlist,SFR,Zweight,... |
| 91 | + MergerRateByRedshiftByZ); |
93 | 92 | end; |
94 | 93 |
|
95 | 94 | end %end of CosmicHistoryIntegrator |
96 | 95 |
|
97 | 96 |
|
98 | | -%Load the data stored in COMPAS output format from a file |
99 | | -%Select only binary black hole mergers of interest, and return the |
| 97 | +%Load the data stored in COMPAS .h5 output format from a file |
| 98 | +%Select only double compact object mergers of interest, and return the |
100 | 99 | %component masses, metallicities, and star formation to merger delay times |
101 | | -function [M1,M2,Z,Tdelay]=DataRead(filename, tHubble) |
102 | | - global BH |
103 | | - if(exist(filename, 'file')~=2), |
| 100 | +function [M1,M2,Z,Tdelay]=DataRead(file) |
| 101 | + if(exist(file, 'file')~=2), |
104 | 102 | error('Input file does not exist'); |
105 | | - end; |
106 | | - data = importdata(filename, '\t', 2); |
107 | | - |
108 | | - colnames=data.textdata(2,:); |
109 | | - Z1index=find(strcmp(colnames,'Metallicity1')); |
110 | | - M1index=find(strcmp(colnames,'M1')); |
111 | | - M2index=find(strcmp(colnames,'M2')); |
112 | | - tcindex=find(strcmp(colnames,'tc')); |
113 | | - tformindex=find(strcmp(colnames,'tform')); |
114 | | - type1index=find(strcmp(colnames,'stellarType1')); |
115 | | - type2index=find(strcmp(colnames,'stellarType2')); |
116 | | - nonRLOF=data.data(:,find(strcmp(colnames,'RLOFSecondaryAfterCEE')))==0; |
117 | | - Pessimistic=data.data(:,find(strcmp(colnames,'optimisticCEFlag')))==0; |
118 | | - tc=data.data(:,tcindex); |
119 | | - tform=data.data(:,tformindex); |
120 | | - Ttotal=(tc+tform)*1e6; %convert Megayears to years |
121 | | - %select only binaries where both members are black holes at the last |
122 | | - %step, the total delay time is less than the age of the Universe, there |
123 | | - %is no Roche-lobe overflow immediately after the common-envelope phase, |
124 | | - %and the Pessimistic common-envelope conditions are met |
125 | | - select=Ttotal<tHubble & nonRLOF & Pessimistic & ... |
126 | | - data.data(:,type1index)==14 & data.data(:,type2index)==14; |
127 | | - |
128 | | - M1=data.data(select,M1index); |
129 | | - M2=data.data(select,M2index); |
130 | | - Z=data.data(select,Z1index); |
131 | | - Tdelay=Ttotal(select); |
| 103 | + end; |
| 104 | + type1=h5read(file,'/BSE_Double_Compact_Objects/Stellar_Type(1)'); |
| 105 | + type2=h5read(file,'/BSE_Double_Compact_Objects/Stellar_Type(2)'); |
| 106 | + mass1=h5read(file,'/BSE_Double_Compact_Objects/Mass(1)'); |
| 107 | + mass2=h5read(file,'/BSE_Double_Compact_Objects/Mass(2)'); |
| 108 | + seedDCO=h5read(file,'/BSE_Double_Compact_Objects/SEED'); |
| 109 | + merges=h5read(file,'/BSE_Double_Compact_Objects/Merges_Hubble_Time'); |
| 110 | + a=h5read(file,'/BSE_Double_Compact_Objects/SemiMajorAxis@DCO'); |
| 111 | + e=h5read(file,'/BSE_Double_Compact_Objects/Eccentricity@DCO'); |
| 112 | + Ttotal=(h5read(file,'/BSE_Double_Compact_Objects/Time')+h5read(file,'/BSE_Double_Compact_Objects/Coalescence_Time'))*1e6; %to years |
| 113 | + %mergingBBH=(type1==14) & (type2==14) & merges; |
| 114 | + %BBH=(type1==14) & (type2==14); |
| 115 | + %mergingBNS=(type1==13) & (type2==13) & merges; |
| 116 | + %BNS=(type1==13) & (type2==13); |
| 117 | + %mergingNSBH=(((type1==13) & (type2==14)) | ((type1==14) & (type2==13))) & merges; |
| 118 | + %NSBH=(((type1==13) & (type2==14)) | ((type1==14) & (type2==13))); |
| 119 | + %mergingDCO=mergingBNS | mergingNSBH | mergingBBH; |
| 120 | + %BNScount=sum(mergingBNS); NSBHcount=sum(mergingNSBH); BBHcount=sum(mergingBBH); |
| 121 | + chirpmass=mass1.^0.6.*mass2.^0.6./(mass1+mass2).^0.2; |
| 122 | + q=mass2./mass1; |
| 123 | + seedCE=h5read(file,'/BSE_Common_Envelopes/SEED'); |
| 124 | + [isCE,CEIndex]=ismember(seedDCO,seedCE); |
| 125 | + optCE=h5read(file,'/BSE_Common_Envelopes/Optimistic_CE'); |
| 126 | + RLOFCE=h5read(file,'/BSE_Common_Envelopes/Immediate_RLOF>CE'); |
| 127 | + OKCE=zeros(size(seedDCO)); OKCE(CEIndex==0)=1; OKCE(CEIndex>0)=(~optCE(CEIndex(CEIndex>0))) & (~RLOFCE(CEIndex(CEIndex>0))); |
| 128 | + %BNSCE=sum(mergingBNS & isCE & OKCE); NSBHCE=sum(mergingNSBH & isCE & OKCE); BBHCE=sum(mergingBBH & isCE & OKCE); |
| 129 | + mergingDCO=merges & OKCE; |
| 130 | + Zsys=h5read(file,'/BSE_System_Parameters/Metallicity@ZAMS(1)'); |
| 131 | + seedsys=h5read(file,'/BSE_System_Parameters/SEED'); |
| 132 | + [blah,sysIndex]=ismember(seedDCO,seedsys); |
| 133 | + Zdco=Zsys(sysIndex); |
| 134 | + M1=mass1(mergingDCO); M2=mass2(mergingDCO); Z=Zdco(mergingDCO); Tdelay=Ttotal(mergingDCO); |
132 | 135 | end %end of DataRead |
133 | 136 |
|
134 | 137 | %Compute the star formation rate and lookback time (in years) |
135 | 138 | %for an array of redshifts |
136 | | -function [zvec,tL]=Cosmology() |
| 139 | +function [tL]=Cosmology(zvec) |
137 | 140 | global Mpcm |
138 | 141 | global Mpc |
139 | 142 | global yr |
140 | | - zmax=10; dz=0.001; zvec=0:dz:zmax; |
141 | | - Nz=length(zvec); |
| 143 | + %zmax=10; dz=0.001; zvec=0:dz:zmax; |
| 144 | + Nz=length(zvec); dz=zvec(2)-zvec(1); |
142 | 145 |
|
143 | 146 | %Planck cosmology |
144 | 147 | OmegaM=0.236+0.046; %2012arXiv1212.5226H |
|
157 | 160 | end %end of Cosmology |
158 | 161 |
|
159 | 162 |
|
160 | | -%Compute the fraction of star formation that happens in a given metallicity |
161 | | -%bin as a function of redshift |
162 | | -function [Zlist,SFR,SFRfractionZ]=Metallicity(zvec,Z) |
| 163 | +%Compute the weight of each star-forming metallicity as a function of redshift |
| 164 | +function [SFR,Zweight]=Metallicity(Zvec, zvec) |
163 | 165 | %M_/odot per Mpc^3 per year -- Neijssel+ 2019 preferred model |
164 | 166 | %would be SFR=0.015*(1+zvec).^2.7./(1+((1+zvec)/2.9).^5.6) in Madau & Dickinson, 2014, (15) |
165 | 167 | SFR=0.01*(1+zvec).^2.77./(1+((1+zvec)/2.9).^4.7); |
166 | | - Zmean=0.035.*10.^(-0.23*zvec); |
167 | | - Zmu=log(Zmean)-0.39^2/2; |
168 | | - dlogZ=0.01; |
169 | | - logZvec=-12:dlogZ:0; %natural log |
170 | | - dPdlogZ=1/0.39/sqrt(2*pi)*exp(-(logZvec'-Zmu).^2/2/0.39^2); |
171 | | - dPdlogZ=dPdlogZ./(sum(dPdlogZ,1)*dlogZ); %normalise |
172 | | - Zrange=log(max(Z))-log(min(Z)); %ugly correction for not including tails |
173 | | - PdrawZ=1/Zrange; |
174 | | - minlogZindex=find(exp(logZvec)>=min(Z),1, 'first'); |
175 | | - maxlogZindex=find(exp(logZvec)<=max(Z),1, 'last'); |
176 | | - dPdlogZ(minlogZindex,:)=dPdlogZ(minlogZindex,:)+sum(dPdlogZ(1:minlogZindex,:),1)*dlogZ/(sum(Z==min(Z))/length(Z))*PdrawZ; |
177 | | - dPdlogZ(maxlogZindex,:)=dPdlogZ(maxlogZindex,:)+sum(dPdlogZ(maxlogZindex:end,:),1)*dlogZ/(sum(Z==max(Z))/length(Z))*PdrawZ; |
178 | | - dPdlogZ=dPdlogZ./(sum(dPdlogZ,1)*dlogZ); %normalise |
| 168 | + if(length(Zvec)>1), |
| 169 | + Zmean=0.035.*10.^(-0.23*zvec); |
| 170 | + Zmu=log(Zmean)-0.39^2/2; |
| 171 | + dlogZ=0.01; |
| 172 | + logZvec=-12:dlogZ:0; %natural log |
| 173 | + dPdlogZ=1/0.39/sqrt(2*pi)*exp(-(logZvec'-Zmu).^2/2/0.39^2); |
| 174 | + dPdlogZ=dPdlogZ./(sum(dPdlogZ,1)*dlogZ); %normalise |
| 175 | + Zrange=log(max(Zvec))-log(min(Zvec)); %ugly correction for not including tails |
| 176 | + PdrawZ=1/Zrange; |
| 177 | + minlogZindex=find(exp(logZvec)>=min(Zvec),1, 'first'); |
| 178 | + maxlogZindex=find(exp(logZvec)>=max(Zvec),1, 'last'); |
| 179 | + dPdlogZ(minlogZindex,:)=dPdlogZ(minlogZindex,:)+sum(dPdlogZ(1:minlogZindex,:),1)*dlogZ/(sum(Zvec==min(Zvec))/length(Zvec))*PdrawZ; |
| 180 | + dPdlogZ(maxlogZindex,:)=dPdlogZ(maxlogZindex,:)+sum(dPdlogZ(maxlogZindex:end,:),1)*dlogZ/(sum(Zvec==max(Zvec))/length(Zvec))*PdrawZ; |
| 181 | + dPdlogZ(1:minlogZindex,:)=0; dPdlogZ(maxlogZindex:size(dPdlogZ,1),:)=0; |
| 182 | + dPdlogZ=dPdlogZ./(sum(dPdlogZ,1)*dlogZ); %normalise |
| 183 | + for(i=1:length(Zvec)) |
| 184 | + index=find(exp(logZvec)>=Zvec(i), 1, 'first'); |
| 185 | + Zweight(:,i)=dPdlogZ(index,:)*dlogZ; |
| 186 | + end; |
| 187 | + else %relevant for single-metallicity runs -- just give all binaries the same unit weight |
| 188 | + Zweight(1:length(zvec),1:length(Zvec))=1; |
| 189 | + end; |
179 | 190 | end %end of Metallicity |
180 | 191 |
|
181 | 192 |
|
182 | 193 | %Make a set of default plots |
183 | | -function MakePlots(M1,M2,Z,Tdelay,zvec,SFR,SFRfractionZ,... |
184 | | - zlist,Zlist,MergerRateByRedshiftByZ) |
| 194 | +function MakePlots(M1,M2,Z,Tdelay,zvec,Zlist,SFR,Zweight,... |
| 195 | + MergerRateByRedshiftByZ) |
185 | 196 |
|
186 | 197 | figure(1),colormap jet; |
187 | | - plot(zlist, MergerRateByRedshiftByZ, 'LineWidth', 2), |
| 198 | + plot(zvec, MergerRateByRedshiftByZ*1e9, 'LineWidth', 2), |
188 | 199 | legend(num2str(Zlist)), |
189 | 200 | set(gca, 'FontSize', 20); %for labels |
190 | 201 | xlabel('z'), |
191 | | - ylabel('Pessimistic non-RLOF BBH merger rate, per Gpc^3 per yr') |
192 | | - disp(['Total BBH merger rate at z=0: ', ... |
| 202 | + ylabel('DCO merger rate per Gpc^3 per yr') |
| 203 | + disp(['Total DCO merger rate at z=0: ', ... |
193 | 204 | num2str(sum(MergerRateByRedshiftByZ(:,1))),... |
194 | 205 | ' per Gpc^3 per year']); |
195 | 206 |
|
196 | | - |
197 | 207 | figure(2), colormap jet; |
198 | 208 | scatter(M1,M2,20,log(Z)/log(10),'filled'); |
199 | 209 | set(gca, 'FontSize', 20); %for labels |
200 | 210 | H=colorbar; H.Label.String='log_{10} metallicity'; |
201 | | - xlabel('Primary BH mass [M_o]'), ylabel('Secondary BH mass [M_o]'); |
| 211 | + xlabel('Primary mass [M_o]'), ylabel('Secondary mass [M_o]'); |
202 | 212 |
|
203 | 213 | figure(3), colormap jet; |
204 | | - scatter(M1+M2,log(Tdelay/1e6)/log(10),20,log(Z)/log(10),'filled'); |
| 214 | + scatter(M1+M2,log10(Tdelay/1e6),20,log10(Z),'filled'); |
205 | 215 | set(gca, 'FontSize', 20); %for labels |
206 | 216 | H=colorbar; H.Label.String='log_{10} metallicity'; |
207 | | - xlabel('Total BBH mass [M_o]'), ylabel('log(Tdelay/Myr)'); |
| 217 | + xlabel('Total DCO mass [M_o]'), ylabel('log_{10}(Tdelay/Myr)'); |
208 | 218 |
|
209 | 219 | figure(4), colormap jet; |
210 | | - plot(zvec, SFR) |
| 220 | + plot(zvec, SFR*1e9) |
211 | 221 | set(gca, 'FontSize', 20); %for labels |
212 | 222 | xlabel('z'), ylabel('Star-formation rate, M_o per Gpc^3 per yr'); |
213 | | - |
214 | 223 |
|
215 | 224 | figure(5), colormap jet; |
216 | | - plot(zvec, SFRfractionZ) |
| 225 | + plot(zvec, Zweight) |
217 | 226 | set(gca, 'FontSize', 20); %for labels |
218 | 227 | legend(num2str(Zlist)) |
219 | | - xlabel('z'), ylabel('Z-specific SFR fraction'); |
| 228 | + xlabel('z'), ylabel('Z-specific SFR weight'); |
220 | 229 |
|
221 | 230 | end %end of MakePlots |
222 | 231 |
|
|
0 commit comments