CosmicFish  Reference documentation for version 1.0
Looking into future Cosmology
011_Fisher_calculator_RD.f90
Go to the documentation of this file.
1 !----------------------------------------------------------------------------------------
2 !
3 ! This file is part of CosmicFish.
4 !
5 ! Copyright (C) 2015-2016 by the CosmicFish authors
6 !
7 ! The CosmicFish code is free software;
8 ! You can use it, redistribute it, and/or modify it under the terms
9 ! of the GNU General Public License as published by the Free Software Foundation;
10 ! either version 3 of the License, or (at your option) any later version.
11 ! The full text of the license can be found in the file LICENSE at
12 ! the top level of the CosmicFish distribution.
13 !
14 !----------------------------------------------------------------------------------------
15 
19 
20 !----------------------------------------------------------------------------------------
22 
24 
26 
27  use precision
28  use modelparams
30  use cambmain
31  use camb
32  use constants
34  use lensnoise
35  use omp_lib
38 
39 #ifdef COSMICFISH_EFTCAMB
40  use eftinitialization
41 #endif
42 
43  implicit none
44 
45  private
46 
48 
49 contains
50 
51  ! ---------------------------------------------------------------------------------------------
54  subroutine rd_theo_calc( P, FP, redrift, err )
55  implicit none
56 
57  Type(cambparams) , intent(in) :: P
58  Type(cosmicfish_params), intent(in) :: FP
59  real(dl), dimension(FP%fisher_RD%number_RD_redshifts), intent(out) :: redrift
60  integer, intent(out) :: err
66 
67  ! other definitions:
68  integer :: i
69  logical :: EFTsuccess
70  real(dl), parameter :: conv_time=3.15e7, conv_mpc=1/(3.09e19) !years to seconds and 1/Mpc to 1/km
71  real(dl) ::deltaT
72  ! initialization:
73  redrift = 0._dl
74  err = 0
75 
76  call cambparams_set(p)
77 
78 
79 #ifdef COSMICFISH_EFTCAMB
80  ! check stability if EFTCAMB is used
81  if (p%EFTflag /= 0) then
82  call eftcamb_initialization(eftsuccess)
83  if (.not. eftsuccess) then
84  write(*,*) 'EFTCAMB: unstable model'
85  err = 4
86  return
87  end if
88  end if
89 #endif
90 
91  deltat = fp%fisher_RD%obs_time*conv_time
92 
93 
94 
95  ! compute the supernova magnitude array:
96  do i=1, fp%fisher_RD%number_RD_redshifts
97  redrift(i) =(c*100)*(p%H0*conv_mpc)*deltat*(1.-(hofz(fp%fisher_RD%RD_redshift(i))/(p%H0*1.e+03/c))/(1+fp%fisher_RD%RD_redshift(i)))
98  end do
99 
100  end subroutine rd_theo_calc
101 
102 
103 
104  subroutine rd_error_calc(P, FP, RDsigma, err)
105  !This subroutine computes the error on redshift drift observations (units are cm/s).
106  !Depending on the value of FP%fisher_RD%exptype different experiments can be used.
107 
108  !TO DO:
109  !1) calculation of source number per bin can be automatized
110  !2) implement SKA
111  implicit none
112 
113  Type(cambparams) , intent(in) :: P
114  Type(cosmicfish_params), intent(in) :: FP
115  real(dl), dimension(FP%fisher_RD%number_RD_redshifts), intent(out) :: RDsigma
116  integer, intent(out) :: err
122  integer i
123  real(dl) pow
124 
125  err = 0
126 
127  if (fp%fisher_RD%exptype.eq.1) then
128  if ( fp%cosmicfish_feedback >= 1 ) then
129  write(*,'(a)') '**************************************************************'
130  write(*,'(a)') 'Computing E-ELT errors:'
131  write(*,'(a)') '**************************************************************'
132  end if
133  do i=1, fp%fisher_RD%number_RD_redshifts
134  if (fp%fisher_RD%RD_redshift(i).le.4) then
135  pow = 1.7
136  else
137  pow = 0.9
138  end if
139  rdsigma(i) = 1.35*(2370./fp%fisher_RD%signoise)*sqrt(30./fp%fisher_RD%RD_number(i))*(5./(1+fp%fisher_RD%RD_redshift(i)))**pow
140  end do
141  else if (fp%fisher_RD%exptype.eq.2) then
142  write(*,*) 'not implemented yet'
143  stop
144  else if (fp%fisher_RD%exptype.eq.3) then
145  write(*,*) 'not implemented yet'
146  stop
147  else
148  write(*,*) 'invalid experiment choice'
149  stop
150  end if
151 
152  if ( fp%cosmicfish_feedback >= 1 ) then
153  write(*,'(a)') '**************************************************************'
154  write(*,'(a)') 'errors computed'
155  write(*,'(a)') '**************************************************************'
156  end if
157 
158  end subroutine rd_error_calc
159 
160 
161  ! ---------------------------------------------------------------------------------------------
163  subroutine save_rd_mock_to_file(FP, mock_size, RD_theory, RD_error, filename)
164  implicit none
165 
166  Type(cosmicfish_params), intent(in) :: FP
167  integer, intent(in) :: mock_size
168  real(dl), dimension(mock_size), intent(in) :: RD_theory
169  real(dl), dimension(mock_size), intent(in) :: RD_error
170  character(len=*), intent(in) :: filename
171  integer :: i
172 
173  open(unit=42, file=filename, action="write", status="replace")
174 
175  write(42,'(a)') "# redshift, Delta v [cm/s], sigma(Delta v) [cm/s] "
176  do i = 1, mock_size
177  write(42,'(5E15.5)') fp%fisher_RD%RD_redshift(i), rd_theory(i), rd_error(i)
178  end do
179 
180  close(42)
181 
182 
183 
184  end subroutine save_rd_mock_to_file
185 
186 
187  ! ---------------------------------------------------------------------------------------------
191  subroutine rd_derivativecalc( P, FP, param_num, deltav_derivative, deltav_der_error, deltav_initial, initial_step, num_param, error_code)
192  implicit none
193 
194  Type(cambparams) , intent(in) :: P
195  Type(cosmicfish_params) , intent(in) :: FP
196 
197  integer , intent(in) :: param_num
198  integer , intent(in) :: num_param
199 
200  real(dl), dimension(:), intent(in) :: deltav_initial
201  real(dl), dimension(:), intent(out) :: deltav_derivative
202  real(dl), dimension(:), intent(out) :: deltav_der_error
203 
204  !real(dl), dimension(:,:), intent(in) :: RD_mock !< Input supernovae mock. Three columns with SN redshift, color and stretch
205 
206  real(dl), intent(in) :: initial_step
207  integer , intent(out) :: error_code
212 
213 
214  integer :: mock_RD_size
215  real(dl), dimension(:), allocatable :: rd_temp_1, rd_temp_2, errt
216  integer , dimension(:), allocatable :: accept_mask
217  real(dl), dimension(:,:,:), allocatable :: a
218  real(dl), dimension(num_param) :: param_vector, fiducial_param_vector, temp_param_vector
219  ! parameters of the algorithm:
220  real(dl), parameter :: con = 1.4_dl ! parameter that decides the decrease in the stepsize h
221  real(dl), parameter :: big = 1.d+30 ! a big number used to fill the error array initially
222  real(dl), parameter :: safe = 2._dl ! parameter used to define the stopping cryterium
223  integer , parameter :: ntab = 30 ! maximum number of Cls computation
224  real(dl) :: con2 = con*con
225  integer :: i, j, k, l, m, side, err, AllocateStatus
226  real(dl) :: fac, hh
227  real(dl) :: temp1, temp2, temp3
228  Type(cambparams) :: P_temp
229  Type(cosmicfish_params) :: FP_temp
230  integer :: accepted
231  real(dl) :: acceptance
232  real(dl), dimension(:), allocatable :: redshift, deltav
233 
234 
235 
236  ! initialize output variables:
237  error_code = 0
238  deltav_derivative = 0._dl
239  deltav_der_error = 0._dl
240 
241  ! check input values are correct
242  if ( initial_step == 0._dl ) then
243  stop 'RD_derivative initial stepsize is zero'
244  end if
245 
246  mock_rd_size = fp%fisher_RD%number_RD_redshifts
247 
248  ! allocate the arrays:
249  if ( fp%adaptivity ) then
250  !THIS IS FOR MARCO TO ENJOY
251  ! allocate( sn_temp_1(mock_sn_size), &
252  ! & sn_temp_2(mock_sn_size), &
253  ! & errt(mock_sn_size), &
254  ! & accept_mask(mock_sn_size),&
255  ! & stat = AllocateStatus )
256  ! if (AllocateStatus /= 0) stop "Observed_SN_Magnitude_derivative: Allocation failed. Not enough memory"
257  ! allocate( a(ntab, ntab, mock_sn_size) , stat = AllocateStatus )
258  ! if (AllocateStatus /= 0) stop "Observed_SN_Magnitude_derivative: Allocation failed. Not enough memory for the derivative array"
259  else
260  allocate( rd_temp_1(mock_rd_size), &
261  & rd_temp_2(mock_rd_size), &
262  & stat = allocatestatus )
263  if (allocatestatus /= 0) stop "RD_Magnitude_derivative: Allocation failed. Not enough memory"
264  allocate( a(1,1, mock_rd_size) , stat = allocatestatus )
265  if (allocatestatus /= 0) stop "RD_derivative: Allocation failed. Not enough memory for the derivative array"
266  end if
267 
268  allocate( redshift(mock_rd_size), &
269  & deltav(mock_rd_size), &
270  & stat = allocatestatus )
271 
272  ! copy the data from the sn mock:
273  redshift(:) = fp%fisher_RD%RD_redshift(:)!sn_mock(1,:)
274  ! deltav(:) = sn_mock(2,:)
275 
276  ! initialize the parameter array:
277  p_temp = p
278  fp_temp = fp
279 
280  call camb_params_to_params_array( p_temp, fp, num_param, param_vector )
281 
282  fiducial_param_vector = param_vector
283  temp_param_vector = param_vector
284 
285  ! initialize the computation:
286  hh = initial_step
287  deltav_der_error = big
288  side = 0 ! both sides
289  if ( fp%adaptivity ) accept_mask = 0
290 
291  ! do the initial step on the right:
292  param_vector(param_num) = fiducial_param_vector(param_num) + hh
293  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
294  call rd_theo_calc(p_temp, fp_temp, rd_temp_1, err)
295  ! if on the right we cannot go we go to the left:
296  if ( err /= 0 ) side = 1
297  ! do the initial step on the left:
298  temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
299  call params_array_to_camb_param( p_temp, fp_temp, num_param, temp_param_vector )
300  call rd_theo_calc(p_temp, fp_temp, rd_temp_2, err)
301 
302  ! if on the left we cannot go decide what to do:
303  if ( err /= 0 ) then
304  if ( side == 1 ) then ! we cannot go to the left nor to the right. Return derivative zero with error code.
305  error_code = 4
306  deltav_der_error = 0.0_dl
307  deltav_derivative = 0.0_dl
308  return
309  else if ( side == 0 ) then ! we cannot go to the left but we can go to the right:
310  side = 2
311  end if
312  end if
313 
314  ! store the results based on the side we decided to go:
315  if (side == 0) then ! both sides
316  a(1,1,:) = (rd_temp_1(:) - rd_temp_2(:))/(2.0_dl*hh)
317  else if (side == 1) then ! left side: increment negative
318  a(1,1,:) = (rd_temp_2(:) - deltav_initial(:))/(-hh)
319  else if (side == 2) then ! right side: increment positive
320  a(1,1,:) = (rd_temp_1(:) - deltav_initial(:))/(hh) !mag initial deve essere il fiduciale
321  end if
322 
323  ! fixed stepsize derivative if adaptivity is not wanted:
324  if ( .not. fp%adaptivity ) then
325  deltav_derivative(:) = a(1,1,:)
326  deltav_der_error = 0.0_dl
327  deallocate( rd_temp_1, rd_temp_2, a )
328  return
329  end if
330 
331  ! start the derivative computation:
332  do i = 2, ntab
333 
334  ! feedback for the adaptive derivative:
335  if ( fp%cosmicfish_feedback >= 2 ) then
336  accepted = sum(accept_mask)
337  acceptance = REAL(accepted)/REAL(mock_rd_size)
338  print*, 'iteration:', i
339  print*, ' stepsize:', hh
340  print*, ' accepted elements', accepted, 'accepted ratio', acceptance
341  end if
342 
343  ! decrease the stepsize:
344  hh = hh/con
345 
346  ! compute the finite difference:
347  if (side == 0) then
348  param_vector(param_num) = fiducial_param_vector(param_num) + hh
349  temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
350  ! compute for + hh
351  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
352  call rd_theo_calc(p_temp, fp_temp, rd_temp_1, err)
353  if ( err /= 0 ) then
354  error_code = 4
355  deltav_der_error = 0.0_dl
356  deltav_derivative = 0.0_dl
357  return
358  end if
359  ! compute for - hh
360  call params_array_to_camb_param( p_temp, fp_temp, num_param, temp_param_vector )
361  call rd_theo_calc(p_temp, fp_temp, rd_temp_2, err)
362  if ( err /= 0 ) then
363  error_code = 4
364  deltav_der_error = 0.0_dl
365  deltav_derivative = 0.0_dl
366  return
367  end if
368  ! store the result
369  a(1,i,:) = (rd_temp_1(:) - rd_temp_2(:))/(2.0_dl*hh)
370  else if (side==1) then
371  param_vector(param_num) = fiducial_param_vector(param_num) - hh
372  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
373  call rd_theo_calc(p_temp, fp_temp, rd_temp_1, err)
374  if ( err /= 0 ) then
375  error_code = 4
376  deltav_der_error = 0.0_dl
377  deltav_derivative = 0.0_dl
378  return
379  end if
380  ! store the result
381  a(1,i,:) = (rd_temp_1(:) - deltav_initial(:))/(-hh)
382  else if (side==2) then
383  param_vector(param_num) = fiducial_param_vector(param_num) + hh
384  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
385  call rd_theo_calc(p_temp, fp_temp, rd_temp_1, err)
386  if ( err /= 0 ) then
387  error_code = 4
388  deltav_der_error = 0.0_dl
389  deltav_derivative = 0.0_dl
390  return
391  end if
392  ! store the result
393  a(1,i,:) = (rd_temp_1(:) - deltav_initial(:))/(hh)
394  end if
395 
396  ! now do the extrapolation table:
397  fac=con2
398  do j = 2, i
399 
400  forall ( k = 1:mock_rd_size, accept_mask(k) == 0 )
401  ! compute the interpolation table:
402  a(j,i,k) = (a(j-1,i,k)*fac-a(j-1,i-1,k))/(fac-1._dl)
403  ! estimate the error:
404  errt(k) = max( abs(a(j,i,k)-a(j-1,i,k)), &
405  & abs(a(j,i,k)-a(j-1,i-1,k)))
406  end forall
407 
408  fac=con2*fac
409 
410  ! if there is an improvement save the result:
411 
412  forall ( k = 1:mock_rd_size, &
413  & errt(k) .le. deltav_der_error(k) .and. accept_mask(k) == 0 )
414 
415  deltav_der_error(k) = errt(k)
416  deltav_derivative(k) = a(j,i,k)
417  end forall
418 
419  ! accept a value of the derivative if the value of the extrapolation is stable
420  ! Store this information into the mask matrix
421  ! so that the value contained in rd_error and rd_derivative is not overwritten.
422  forall ( k = 1:mock_rd_size, &
423  & accept_mask(k) == 0 .and. &
424  & (a(i,i,k) - a(i-1,i-1,k)) .ge. safe*deltav_der_error(k) )
425 
426  accept_mask(k) = 1
427  end forall
428 
429  ! if all the entries match the required accuracy exit the loop
430  if ( sum(accept_mask) == mock_rd_size ) exit
431 
432  end do
433 
434  ! quality check on the results:
435  if ( sum(accept_mask) /= mock_rd_size ) then
436  error_code = 3
437  end if
438 
439  ! deallocate the arrays:
440  if ( fp%adaptivity ) then
441  !MARCO!
442  ! deallocate( sn_temp_1, sn_temp_2, errt, accept_mask, a )
443  end if
444 
445  return
446 
447  end do
448 
449  end subroutine rd_derivativecalc
450 
451 
452 
453 
454  ! ---------------------------------------------------------------------------------------------
456  subroutine fisher_rd(P, FP, num_param, Fisher_Matrix, outroot)
457  implicit none
458 
459  Type(cambparams) , intent(in) :: P
460  Type(cosmicfish_params), intent(in) :: FP
461  real(dl), allocatable, dimension(:) :: redrift,RDsigma
462 
463  integer , intent(in) :: num_param
464  real(dl), dimension(num_param,num_param), intent(out) :: Fisher_Matrix
465  character(len=*), intent(in), optional :: outroot
466 
467  real(dl) :: time_1, time_2
468  real(dl) :: initial_step, temp, temp1, temp2
469  integer :: err, AllocateStatus, ind, ind2
470  integer :: i, j, k, l
471  real(dl), allocatable :: param_array(:)
472  real(dl), dimension(:), allocatable :: rd_fiducial, rd_derivative, rd_temp, rd_error
473  real(dl), dimension(:,:), allocatable :: rd_derivative_array
474 
475 
476  ! allocate a parameter array:
477  allocate( param_array(num_param) )
478  ! write the parameters in the parameter array:
479  call camb_params_to_params_array( p, fp, num_param, param_array )
480 
481 
482 
483  ! allocation:
484  allocate(rd_fiducial(fp%fisher_RD%number_RD_redshifts), stat = allocatestatus)
485  if (allocatestatus /= 0) stop "Allocation failed. Not enough memory to allocate rd_fiducial"
486  allocate(rd_temp(fp%fisher_RD%number_RD_redshifts), stat = allocatestatus)
487  if (allocatestatus /= 0) stop "Allocation failed. Not enough memory to allocate rd_temp"
488  allocate(rd_derivative(fp%fisher_RD%number_RD_redshifts), stat = allocatestatus)
489  if (allocatestatus /= 0) stop "Allocation failed. Not enough memory to allocate rd_derivative"
490  allocate(rd_error(fp%fisher_RD%number_RD_redshifts), stat = allocatestatus)
491  if (allocatestatus /= 0) stop "Allocation failed. Not enough memory to allocate rd_derivative"
492 
493  ! computation of the fiducial model:
494  time_1 = omp_get_wtime()
495  call rd_theo_calc(p, fp, rd_fiducial, err)
496  call rd_error_calc(p, fp, rd_error, err)
497  time_2 = omp_get_wtime() - time_1
498 
499  if ( present(outroot) ) call save_rd_mock_to_file(fp, fp%fisher_RD%number_RD_redshifts, rd_fiducial, rd_error, filename=trim(outroot)//'fiducial.dat')
500 
501  if ( err == 0 ) then
502  else if ( err == 4 ) then
503  write(*,*) 'Fiducial model unstable. Calculation cannot proceed.'
504  stop
505  else
506  write(*,*) 'Error in computing the fiducial. Calculation cannot proceed.'
507  stop
508  end if
509 
510  ! print some feedback
511  if ( fp%cosmicfish_feedback >= 1 ) then
512  write(*,'(a)') '**************************************************************'
513  write(*,'(a,i10)') 'Some more feedback to be added '
514  write(*,'(a,i10)') 'Number of parameters : ', num_param
515  write(*,'(a,f10.3,a)') 'Time taken for RD calculation: ', time_2, ' (s)'
516  write(*,'(a,i10)') 'Number of omp processes : ', omp_get_max_threads()
517  if ( fp%adaptivity ) then
518  write(*,'(a,f10.3,a)') 'Estimated completion time : ', time_2*20._dl*num_param, ' (s)'
519  else
520  write(*,'(a,f10.3,a)') 'Estimated completion time : ', time_2*2._dl*num_param, ' (s)'
521  end if
522  write(*,'(a)') '**************************************************************'
523  end if
524 
525  ! compute the derivatives of the Cls:
526  if ( fp%cosmicfish_feedback >= 1 ) then
527  write(*,'(a)') '**************************************************************'
528  write(*,'(a)') 'Computation of the delta v derivatives'
529  write(*,'(a)') '**************************************************************'
530  end if
531 
532  allocate(rd_derivative_array(num_param,fp%fisher_RD%number_RD_redshifts), stat = allocatestatus)
533  if (allocatestatus /= 0) stop "Allocation failed. Not enough memory to allocate rd_derivative_array"
534 
535  time_1 = omp_get_wtime()
536  do ind = 1, num_param
537 
538  if ( fp%cosmicfish_feedback >= 1 ) then
539  write(*,'(a,i5,a,E15.5)') 'Doing parameter number: ', ind, ' value: ', param_array(ind)
540  end if
541 
542  if ( param_array(ind) /= 0._dl ) then
543  initial_step = param_array(ind)*3.0_dl/100._dl !MM: shouldn't this be a user defined quantity
544  else
545  initial_step = 3.0_dl/100._dl
546  end if
547 
548  call rd_derivativecalc( p, fp, ind, rd_derivative, rd_temp, rd_fiducial, initial_step, num_param, err)
549 
550  if (err /= 0) print*, 'WARNING: something went wrong with the delta v derivative of parameter:', ind
551 
552  if ( present(outroot) .and. fp%cosmicfish_feedback >= 2 ) then
553  call save_rd_mock_to_file(fp, fp%fisher_RD%number_RD_redshifts, rd_derivative, rd_temp, filename=trim(outroot)//'RD_derivative_'//trim(adjustl(integer_to_string(ind)))//'.dat')
554  end if
555 
556  rd_derivative_array(ind,:) = rd_derivative(:)
557 
558  end do
559  time_2 = omp_get_wtime() - time_1
560 
561  if ( fp%cosmicfish_feedback >= 1 ) then
562  write(*,*)
563  write(*,'(a,f8.3,a)') 'Time to compute all the derivatives:', time_2, ' (s)'
564  end if
565 
566 
567  ! compute the Fisher matrix:
568  do ind = 1, num_param
569  do ind2 = 1, num_param
570 
571  temp2 = 0._dl
572 
573  do i = 1, fp%fisher_RD%number_RD_redshifts
574  temp = (1./rd_error(i)**2.)*rd_derivative_array(ind,i)*rd_derivative_array(ind2,i)
575  temp2 = temp2 + temp
576  end do
577 
578  fisher_matrix(ind, ind2) = temp2
579 
580  end do
581  end do
582  time_2 = omp_get_wtime() - time_1
583 
584  if ( fp%cosmicfish_feedback >= 1 ) then
585  write(*,'(a,f8.3,a)') 'Time to compute the Fisher matrix:', time_2, ' (s)'
586  end if
587 
588 
589  end subroutine fisher_rd
590 
591 end module fisher_calculator_rd
592 
subroutine, public rd_error_calc(P, FP, RDsigma, err)
subroutine, public rd_theo_calc(P, FP, redrift, err)
This subroutine returns the theoretical prediction of redshift drift given the input cosmological par...
subroutine, public params_array_to_camb_param(P, FP, num_param, params_array)
This subroutine updates the values of the parameters P and FP based on the values contained in the pa...
subroutine, public fisher_rd(P, FP, num_param, Fisher_Matrix, outroot)
This subroutine computes the Fisher matrix for redshift drift.
subroutine, public camb_params_to_params_array(P, FP, num_param, params_array)
This subroutine updates the values of the parameters array based on the values of P and FP...
This module contains the definitions of derived data types used to store the informations about the f...
This module contains the subroutine and functions to manipulate and modify matrices.
This module contains the interface layer between CosmicFish and CAMB.
This module contains several general purpose utilities.
subroutine, public save_rd_mock_to_file(FP, mock_size, RD_theory, RD_error, filename)
This subroutine outputs to file a SN covariance.
This module contains the code to compute the noise for CMB lensing.
character(10) function, public integer_to_string(number)
This function converts an integer to a string. Usefull for numbered files output. ...
This module contains the code that computes the Fisher matrix for Redshift Drift. ...
subroutine, public rd_derivativecalc(P, FP, param_num, deltav_derivative, deltav_der_error, deltav_initial, initial_step, num_param, error_code)
This subroutine computes the derivative of the observed redshift drift signal. The calculation is car...
This derived data type contains all the informations that the cosmicfish code needs to run...