Codebase list healpix-fortran / f71e89b
Import upstream version 3.81 Debian Janitor 2 years ago
15 changed file(s) with 3293 addition(s) and 2513 deletion(s). Raw diff Collapse all Expand all
Binary diff not shown
221221 subroutine gifstr(x,nx,ny,sx,sy,nc,r,g,b,or_,fn) bind(C, name="gifstr")
222222 use iso_c_binding
223223 implicit none
224 integer (c_int), intent(out) :: x(*)
224 integer (c_int), intent(inout) :: x(*) ! 2020-08-25
225225 integer (c_int), intent(in) :: nx, ny, sx, sy, nc, r(*), g(*), b(*), or_
226226 character(c_char), intent(in) :: fn(*)
227227 end subroutine
484484 end subroutine addttl
485485
486486 ! ------------------------------------------------------------------
487 ! addstr: used exclusively by addbar to add labels to the ends of
488 ! color bar; [a] is the image array, [i] and [j] are the
487 ! addstr: used by addbar to add labels to the ends of color bar
488 ! and by addttl to add title;
489 ! [a] is the (modified) image array, [i] and [j] are the
489490 ! array positions where the string [s] should end if [or]
490491 ! is negative, or start if [or] is positive
491492 ! ------------------------------------------------------------------
493494 subroutine addstr(a,i,j,or,s)
494495 use healpix_types
495496 implicit none
496 integer(i4b) :: nx,ny,i,j
497 integer(i4b), intent(inout), dimension(:,:) :: a
498 integer(i4b), intent(in) :: i,j
497499 integer(i4b), intent(in) :: or
498 integer(i4b), dimension(:,:) :: a
499500 character(len=*), intent(in) :: s
501 integer(i4b) :: nx,ny
500502
501503 nx = size(a,1)
502504 ny = size(a,2)
1212 apply_mask_inc.f90 \
1313 pixel_routines.F90
1414
15 incfits = fits_s_inc.f90 fits_d_inc.f90
15 incfits = fits_s_inc.F90 fits_d_inc.F90
1616
1717 incudgrade = udgrade_s_inc.f90 udgrade_d_inc.f90
1818
108108
109109 $(OD)/fitstools.o: fitstools.F90 $(incfits)
110110
111 $(OD)/udgrade_nr.o: udgrade_nr.f90 $(incudgrade)
111 $(OD)/udgrade_nr.o: udgrade_nr.F90 $(incudgrade)
112112
113113 $(OD)/num_rec.o: num_rec.F90 $(incnumrec)
114114
122122 alm_map_dd_inc.F90: alm_map_template.F90 gen_alm_code alm_map_ss_inc.F90
123123 @./gen_alm_code
124124
125 fits_s_inc.f90: fits_template.f90 gen_fits_code
125 fits_s_inc.F90: fits_template.F90 gen_fits_code
126126 @./gen_fits_code
127127
128 fits_d_inc.f90: fits_template.f90 gen_fits_code fits_s_inc.f90
128 fits_d_inc.F90: fits_template.F90 gen_fits_code fits_s_inc.F90
129129 @./gen_fits_code
130130
131131 udgrade_s_inc.f90: udgrade_template.f90 gen_udgrade_code
326326
327327 real(DP), dimension(1:2) :: zbounds_in
328328 integer(I4B) :: l, m, ith ! alm related
329 integer(I8B) :: istart_south, istart_north, npix ! map related
329 integer(I8B) :: istart_south, istart_north, npix, p! map related
330330 integer(I4B) :: nrings, nphmx
331331
332332 real(DP), dimension(1:4) :: b_even, b_odd
353353 #ifdef USE_SHARP
354354 zbounds_in = (/-1.d0 , 1.d0/)
355355 if (present(zbounds)) zbounds_in = zbounds
356
356 ! aspin = abs(spin)
357 ! if ((aspin>0).and.(aspin<=100)) then
358 ! call sharp_hp_alm2map_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
359 ! alm(1:2,0:nlmax,0:nmmax),map(0:12*nsmax*nsmax-1,1:2), zbounds_in)
360 ! return
361 ! endif
362 ! 2021-06-15: use scalar routine when s=0
357363 aspin = abs(spin)
358 if ((aspin>0).and.(aspin<=100)) then
359 call sharp_hp_alm2map_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
360 alm(1:2,0:nlmax,0:nmmax),map(0:12*nsmax*nsmax-1,1:2), zbounds_in)
361 return
362 endif
364 npix = (12_I8B*nsmax)*nsmax
365 if (aspin > 0) then
366 call sharp_hp_alm2map_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
367 alm(1:2,0:nlmax,0:nmmax),map(0:npix-1,1:2), zbounds_in)
368 else
369 call sharp_hp_alm2map_x_KLOAD(nsmax,nlmax,nmmax,&
370 alm(1:1,0:nlmax,0:nmmax),map(0:npix-1,1), zbounds_in)
371 do p = 0_I8B, npix - 1_I8B
372 map(p,1) = -map(p,1) ! mimic alm sign convention of alm2map_spin
373 map(p,2) = 0.0_KMAP ! unused for s=0
374 enddo
375 endif
376 return
363377 #endif
364378 !=======================================================================
365379
24192433 if (present(zbounds)) zbounds_in = zbounds
24202434 w8ring_in = 1.d0
24212435 if (present(w8ring)) w8ring_in = w8ring
2422
24232436 call sharp_hp_map2alm_x_KLOAD(nsmax,nlmax,nmmax,map,alm,zbounds_in,w8ring_in)
24242437 #else
24252438
26952708 if (present(w8ring)) w8ring_in = w8ring
26962709
26972710 #ifdef USE_SHARP
2711 ! aspin = abs(spin)
2712 ! if ((aspin>0).and.(aspin<=100)) then
2713 ! call sharp_hp_map2alm_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
2714 ! map(0:12*nsmax*nsmax-1,1:2),alm(1:2,0:nlmax,0:nmmax),zbounds_in,w8ring_in)
2715 ! return
2716 ! endif
2717 ! 2021-06-15: use scalar routine when s=0
26982718 aspin = abs(spin)
2699 if ((aspin>0).and.(aspin<=100)) then
2700 call sharp_hp_map2alm_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
2701 map(0:12*nsmax*nsmax-1,1:2),alm(1:2,0:nlmax,0:nmmax),zbounds_in,w8ring_in)
2702 return
2703 endif
2719 npix = (12_I8B*nsmax)*nsmax
2720 if (aspin > 0) then
2721 call sharp_hp_map2alm_spin_x_KLOAD(nsmax,nlmax,nmmax,aspin, &
2722 map(0:npix-1,1:2),alm(1:2,0:nlmax,0:nmmax),zbounds_in,w8ring_in)
2723 else
2724 call sharp_hp_map2alm_x_KLOAD(nsmax,nlmax,nmmax, &
2725 map(0:npix-1,1),alm(1:1,0:nlmax,0:nmmax),zbounds_in,w8ring_in)
2726 do l=0,nlmax
2727 do m=l,nmmax
2728 alm(1,l,m) = -alm(1,l,m) ! implement alm sign convention of map2alm_spin
2729 alm(2,l,m) = 0.0_DPC ! unused for s=0
2730 enddo
2731 enddo
2732 endif
2733 return
27042734 #endif
27052735
27062736 ! Healpix definitions
0 !-----------------------------------------------------------------------------
1 !
2 ! Copyright (C) 1997-2013 Krzysztof M. Gorski, Eric Hivon,
3 ! Benjamin D. Wandelt, Anthony J. Banday,
4 ! Matthias Bartelmann, Hans K. Eriksen,
5 ! Frode K. Hansen, Martin Reinecke
6 !
7 !
8 ! This file is part of HEALPix.
9 !
10 ! HEALPix is free software; you can redistribute it and/or modify
11 ! it under the terms of the GNU General Public License as published by
12 ! the Free Software Foundation; either version 2 of the License, or
13 ! (at your option) any later version.
14 !
15 ! HEALPix is distributed in the hope that it will be useful,
16 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ! GNU General Public License for more details.
19 !
20 ! You should have received a copy of the GNU General Public License
21 ! along with HEALPix; if not, write to the Free Software
22 ! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 !
24 ! For more information about HEALPix see http://healpix.sourceforge.net
25 !
26 !-----------------------------------------------------------------------------
27 ! template for routine SP/DP overloading for module fitstools
28 !
29 ! subroutine input_map_KLOAD (4/8)
30 ! subroutine read_bintab_KLOAD (4/8)
31 ! subroutine read_conbintab_KLOAD NotYet
32 ! subroutine write_bintab_KLOAD (4/8)
33 ! subroutine write_asctab_KLOAD NA
34 ! subroutine dump_alms_KLOAD NotYet
35 ! subroutine write_alms_KLOAD NotYet
36 ! subroutine read_alms_KLOAD NotYet
37 ! subroutine read_bintod_KLOAD (8)
38 ! subroutine write_bintabh_KLOAD (8)
39 ! subroutine unfold_weights_KLOAD
40 ! subroutine unfold_weightslist_KLOAD
41 ! subroutine read_fits_partial_KLOAD (4/8)
42 ! subroutine write_fits_partial_KLOAD (4)
43 !
44 !
45 ! K M A P : map kind either SP or DP
46 !
47 ! K L O A D : suffixe of routine name, to be replaced by either s (SP) or d (DP)
48 !
49 ! edited Jan 11, 2006 to deal correctly with polarised alms in write_alms and alms2fits
50 ! edited Apr 04, 2006 to avoid concatenation problem in TFORMs (write_plm and write_bintabh with Ifort 9)
51 ! edited Dec 20, 2006 to accept alm file with less elements than expected (in particular if vanishing ones are not included)
52 ! 2007-05-10 : increased maxdim (max number of columns per extension) from 20 to 40
53 ! 2008-08-27 : in dump_alms and write_alms and write_*tab*:
54 ! do not write TTYPE# and TFORM# in excess of # of fields in the file
55 ! 2008-10-14: corrected bug introduced in write_asctab
56 ! 2012-02-23: correction of a possible bug with index writing in dump_alms and write_alms
57 ! 2013-12-13: increased MAXDIM from 40 to MAXDIM_TOP
58 ! 2018-05-22: added unfold_weights, unfold_weightslist
59 ! 2019-10-14: can write TTYPE??? (ie with up to 3 digits) in write_* and dump_alms
60 !
61
62 !=======================================================================
63 ! map_bad_pixels(map, fin, fout, nbads, verbose)
64 ! map: input data (2D)
65 ! fin: input value of 'bad' pixels
66 ! fout: output value of same 'bad' pixels
67 ! nbads: number of bad pixels found
68 ! verbose: OPTIONAL, if set, be verbose
69 !=======================================================================
70
71 subroutine map_bad_pixels_KLOAD(map, fin, fout, nbads, verbose)
72 use long_intrinsic, only: long_size
73 real(KMAP), dimension(0:,1:), intent(inout) :: map
74 real(KMAP), intent(in) :: fin, fout
75 integer(I8B), intent(out) :: nbads
76 logical(LGT), optional, intent(in) :: verbose
77 integer(I8B) :: i, npix
78 integer(I8B), dimension(1:100) :: imiss
79 integer(I4B) :: imap, nmaps
80 logical(LGT) :: be_verbose
81 real(KMAP) :: threshold
82 !-----------------------------------------
83
84 npix = long_size(map, 1)
85 nmaps = long_size(map, 2)
86 threshold = abs(fin * 1.e-5_KMAP)
87
88 imiss(:) = 0
89 do imap = 1, nmaps
90 do i=0,npix-1
91 if ( abs( map(i,imap) - fin ) < threshold ) then
92 map(i,imap) = fout
93 imiss(imap) = imiss(imap)+1
94 endif
95 enddo
96 enddo
97 nbads = sum(imiss)
98
99 be_verbose = .false.
100 if (present(verbose)) be_verbose=verbose
101 if (be_verbose) then
102 write(*,'(a,1pe11.4)') 'blank value : ' ,fin
103 do imap = 1, nmaps
104 if (imiss(imap) > 0) then
105 write(*,'(i12,a,f7.3,a,1pe11.4)') &
106 & imiss(imap),' missing pixels (', &
107 & (100.0_KMAP*imiss(imap))/npix,' %),'// &
108 & ' have been set to : ',fout
109 endif
110 enddo
111 endif
112
113 return
114 end subroutine map_bad_pixels_KLOAD
115 !=======================================================================
116 ! input_map
117 ! reads fits file
118 ! filename = fits file (input)
119 ! map = data read from the file (ouput) = real*4 array of size (npixtot,nmaps)
120 ! npixtot = length of the map (input)
121 ! nmaps = number of maps
122 ! fmissval = OPTIONAL argument (input) with the value to be given to missing
123 ! pixels, its default value is 0
124 ! header = OPTIONAL (output) contains extension header
125 ! units = OPTIONAL (output) contains the maps units
126 ! extno = OPTIONAL (input) contains the unit number to read from (0 based)
127 ! ignore_polcconv = OPTIONAL (input), LGT, default=.false.
128 ! take into account or not the POLCCONV FITS keyword
129 !
130 ! modified Feb 03 for units argument to run with Sun compiler
131 ! 2017-02-15: deals with POLCCONV
132 !=======================================================================
133 #ifndef NO64BITS
134 subroutine input_map4_KLOAD(filename, map, npixtot, nmaps, &
135 & fmissval, header, units, extno, ignore_polcconv)
136 !=======================================================================
137
138 INTEGER(I4B), INTENT(IN) :: npixtot
139 INTEGER(I4B), INTENT(IN) :: nmaps
140 REAL(KMAP), INTENT(OUT), dimension(0:,1:) :: map
141 CHARACTER(LEN=*), INTENT(IN) :: filename
142 REAL(KMAP), INTENT(IN), OPTIONAL :: fmissval
143 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: header
144 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: units
145 INTEGER(I4B), INTENT(IN) , optional :: extno
146 logical(LGT), intent(IN) , optional :: ignore_polcconv
147 integer(i8b) :: npixtot8
148
149 npixtot8 = npixtot
150 call input_map8_KLOAD(filename, map, npixtot8, nmaps, &
151 fmissval, header, units, extno, ignore_polcconv)
152
153 return
154 end subroutine input_map4_KLOAD
155 #endif
156
157 !=======================================================================
158 subroutine input_map8_KLOAD(filename, map, npixtot, nmaps, &
159 fmissval, header, units, extno, ignore_polcconv)
160 !=======================================================================
161 use head_fits, only: get_card, add_card
162 use pix_tools, only: nside2npix
163 INTEGER(I8B), INTENT(IN) :: npixtot
164 INTEGER(I4B), INTENT(IN) :: nmaps
165 REAL(KMAP), INTENT(OUT), dimension(0:,1:) :: map
166 CHARACTER(LEN=*), INTENT(IN) :: filename
167 REAL(KMAP), INTENT(IN), OPTIONAL :: fmissval
168 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: header
169 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: units
170 INTEGER(I4B), INTENT(IN) , optional :: extno
171 logical(LGT), intent(IN) , optional :: ignore_polcconv
172
173 INTEGER(I8B) :: i, imissing, obs_npix, maxpix, minpix
174 REAL(KMAP) :: fmissing, fmiss_effct
175 integer(I4B) :: imap, nlheader
176
177 LOGICAL(LGT) :: anynull, do_polcconv
178 ! Note : read_fits_cut4 still SP and I4B only
179 integer(I4B), dimension(:), allocatable :: pixel4
180 real(SP), dimension(:), allocatable :: signal
181 ! while read_fits_partial is SP/DP and I4B/I8B
182 integer(I8B), dimension(:), allocatable :: pixel8
183 real(KMAP), dimension(:,:), allocatable :: iqu
184 integer(I4B) :: status
185 integer(I4B) :: type_fits, nmaps_fits
186 CHARACTER(LEN=80) :: units1
187 CHARACTER(LEN=80),dimension(1:30) :: unitsm
188 character(len=80), dimension(:), allocatable :: hbuffer
189 ! CHARACTER(LEN=80),dimension(:), allocatable :: unitsm
190 integer(I4B) :: extno_i, extno_f, n_ext
191 CHARACTER(LEN=80) :: polcconv
192 integer(I4B) :: ipolcconv, polar, nside_fits
193 character(len=*), parameter :: primer_url = 'http://healpix.sf.net/pdf/intro.pdf'
194 character(len=*), parameter :: code = 'input_map'
195
196 !-----------------------------------------------------------------------
197
198 units1 = ' '
199 unitsm(:) = ' '
200 fmiss_effct = 0.
201 imissing = 0
202 if (PRESENT(fmissval)) fmiss_effct = fmissval
203 if (PRESENT(header)) then
204 nlheader = size(header)
205 else
206 nlheader = 36*100
207 endif
208 extno_i = 0
209 if (present(extno)) extno_i = extno
210 allocate(hbuffer(1:nlheader))
211 do_polcconv = .true.
212 if (present(ignore_polcconv)) then
213 do_polcconv = .not. ignore_polcconv
214 endif
215
216 n_ext = getnumext_fits(filename)
217 obs_npix = getsize_fits(filename, nmaps = nmaps_fits, type=type_fits, extno=extno_i, &
218 polcconv=ipolcconv, polarisation=polar, nside=nside_fits)
219
220 ! if (nmaps_fits > nmaps) then
221 ! print*,trim(filename)//' only contains ',nmaps_fits,' maps'
222 ! print*,' You try to read ',nmaps
223 ! endif
224 if (type_fits == 0 .or. type_fits == 2) then ! full sky map (in image or binary table)
225 call read_bintab(filename, map(0:,1:), &
226 & npixtot, nmaps, fmissing, anynull, header=hbuffer(1:), &
227 & units=unitsm(1:), extno=extno_i)
228 if (present(header)) then
229 do i=1,nlheader
230 header(i) = hbuffer(i)
231 enddo
232 endif
233 if (present(units)) then
234 units(1:size(units)) = unitsm(1:size(units))
235 endif
236 call map_bad_pixels(map, fmissing, fmiss_effct, imissing, verbose=.false.)
237 if (imissing > 0) write(*,'(a,1pe11.4)') 'blank value : ' ,fmissing
238 else if (type_fits == 3 .and. (nmaps == 1 .or. nmaps == 3) &
239 & .and. (nmaps_fits > nmaps) .and. n_ext == 1) then
240 ! partial FITS file, reading 1 map (I) or 3 maps (I,Q,U) from the same extension
241 obs_npix = getsize_fits(filename)
242 allocate(pixel8(0:obs_npix-1), stat = status)
243 call assert_alloc(status, code, "pixel8")
244 allocate(iqu (0:obs_npix-1, 1:nmaps), stat = status)
245 call assert_alloc(status, code, "iqu")
246 call read_fits_partial(filename, pixel8, iqu, header=hbuffer)
247 if (present(header)) then
248 do i=1,nlheader
249 header(i) = hbuffer(i)
250 enddo
251 endif
252 if (present(units)) then
253 do imap=1,min(size(units),nmaps-1)
254 call get_card(hbuffer,'TUNIT'//string(imap+1,format='(i0.0)'), units(imap))
255 enddo
256 endif
257 maxpix = maxval(pixel8)
258 minpix = maxval(pixel8)
259 if (maxpix > (npixtot-1) .or. minpix < 0) then
260 print*,'map constructed from file '//trim(filename)//', with pixels in ',minpix,maxpix
261 print*,' wont fit in array with ',npixtot,' elements'
262 call fatal_error
263 endif
264 map(:,:) = fmiss_effct
265 do imap=1,nmaps
266 map(pixel8(:),imap) = iqu(:,imap)
267 enddo
268 imissing = npixtot - obs_npix
269 deallocate(iqu)
270 deallocate(pixel8)
271 ! else if (type_fits == 3 .and. (nmaps == 1 .or. nmaps == 3) .and. n_ext == nmaps) then
272 ! ! cut sky FITS file, reading 1 map (I) or 3 maps (I,Q,U), each from a different extension
273 else if (type_fits == 3 .and. (nmaps == 3) .and. n_ext == nmaps) then
274 ! cut sky FITS file, reading 3 maps (I,Q,U), each from a different extension
275 do imap = 1, nmaps
276 extno_f = extno_i + imap - 1 ! 2016-08-16
277 obs_npix = getsize_fits(filename, extno = extno_f)
278 ! one partial map (in binary table with explicit pixel indexing)
279 allocate(pixel4(0:obs_npix-1), stat = status)
280 allocate(signal(0:obs_npix-1), stat = status)
281 call read_fits_cut4(filename, int(obs_npix,kind=i4b), &
282 & pixel4, signal, header=hbuffer, units=units1, extno=extno_f)
283 if (present(header) .and. imap == 1) then
284 do i=1,nlheader
285 header(i) = hbuffer(i)
286 enddo
287 endif
288 if (present(units)) units(imap) = trim(units1)
289 maxpix = maxval(pixel4)
290 minpix = maxval(pixel4)
291 if (maxpix > (npixtot-1) .or. minpix < 0) then
292 print*,'map constructed from file '//trim(filename)//', with pixels in ',minpix,maxpix
293 print*,' wont fit in array with ',npixtot,' elements'
294 call fatal_error
295 endif
296 map(:,imap) = fmiss_effct
297 map(pixel4(:),imap) = signal(:)
298 imissing = npixtot - obs_npix
299 deallocate(signal)
300 deallocate(pixel4)
301 enddo
302 else
303 print*,'Unable to read the ',nmaps,' required map(s) from file '//trim(filename)
304 print*,'file type = ',type_fits
305 call fatal_error
306 endif
307 !-----------------------------------------------------------------------
308 if (imissing > 0) then
309 write(*,'(i12,a,f7.3,a,1pe11.4)') &
310 & imissing,' missing pixels (', &
311 & (100.*imissing)/npixtot,' %),'// &
312 & ' have been set to : ',fmiss_effct
313 endif
314
315 ! deallocate(unitsm)
316
317 !-----------------------------------------------------------------------
318 ! deal with polcconv
319 ! print*,'******* in input_map ',nmaps, polar, type_fits, nside_fits
320
321 if ( do_polcconv .and. ( &
322 & (nmaps >= 3 .and. type_fits == 3) & ! cut-sky, multiple maps
323 & .or. &
324 & (nmaps >=3 .and. polar==1 .and. type_fits ==2 .and. &
325 & obs_npix==nside2npix(nside_fits)) & ! full-sky, polarized map
326 & ) ) then
327 if (ipolcconv == 0) then
328 print 9000,' The POLCCONV keyword was not found in '//trim(filename)
329 print 9000,' COSMO (HEALPix default) will be assumed, and map is unchanged.'
330 print 9000,' See HEALPix primer ('//primer_url//') for details.'
331 endif
332 ! if (ipolcconv == 1) then
333 ! print 9000,' POLCCONV=COSMO found in '//trim(filename)//'. Map is unchanged.'
334 ! endif
335 if (ipolcconv == 2) then
336 print 9000,' POLCCONV=IAU found in '//trim(filename)
337 map(:,3) = - map(:,3)
338 if (present(header)) then
339 print 9000,' The sign of the U polarisation is changed in memory,'&
340 & //' and the header is updated.'
341 call add_card(header, 'POLCCONV', 'COSMO', &
342 comment='Changed by input_map', update=.true.)
343 else
344 print 9000,' The sign of the U polarisation is changed in memory.'
345 endif
346 print 9000,' See HEALPix primer ('//primer_url//') for details.'
347 endif
348 if (ipolcconv == 3) then
349 call get_card(hbuffer,'POLCCONV',polcconv)
350 print 9000,' POLCCONV='//trim(polcconv)//' found in '//trim(filename)
351 print 9000,' It is neither COSMO nor IAU. Aborting!'
352 print 9000,' See HEALPix primer ('//primer_url//') for details.'
353 call fatal_error
354 endif
355 endif
356 9000 format(a)
357 if (allocated(hbuffer)) deallocate(hbuffer)
358
359 RETURN
360 END subroutine input_map8_KLOAD
361 !=======================================================================
362 ! Read a FITS file
363 ! This routine is used for reading MAPS by anafast.
364 ! modified Feb 03 for units argument to run with Sun compiler
365 ! Jan 2005, EH, improved for faster writing
366 !=======================================================================
367 #ifndef NO64BITS
368 subroutine read_bintab4_KLOAD(filename, map, npixtot, nmaps, nullval, anynull, header, units, extno)
369 character(len=*), intent(IN) :: filename
370 integer(I4B), intent(IN) :: npixtot
371 integer(I4B), intent(IN) :: nmaps
372 real(KMAP), dimension(0:,1:), intent(OUT) :: map
373 real(KMAP), intent(OUT) :: nullval
374 logical(LGT), intent(OUT) :: anynull
375 character(LEN=*), dimension(1:), optional, intent(OUT) :: header
376 character(LEN=*), dimension(1:), optional, intent(OUT) :: units
377 integer(I4B) , optional, intent(IN) :: extno
378
379 integer(i8b):: npixtot8
380
381 npixtot8 = int(npixtot,kind=i8b)
382 call read_bintab8_KLOAD(filename, map, npixtot8, nmaps, nullval, anynull, header, units, extno)
383 return
384
385 end subroutine read_bintab4_KLOAD
386 #endif
387 subroutine read_bintab8_KLOAD(filename, map, npixtot, nmaps, nullval, anynull, header, units, extno)
388 !=======================================================================
389 character(len=*), intent(IN) :: filename
390 integer(I8B), intent(IN) :: npixtot
391 integer(I4B), intent(IN) :: nmaps
392 real(KMAP), dimension(0:,1:), intent(OUT) :: map
393 real(KMAP), intent(OUT) :: nullval
394 logical(LGT), intent(OUT) :: anynull
395 character(LEN=*), dimension(1:), optional, intent(OUT) :: header
396 character(LEN=*), dimension(1:), optional, intent(OUT) :: units
397 integer(I4B) , optional, intent(IN) :: extno
398
399 integer(I4B) :: nl_header, len_header, nl_units, len_units
400 integer(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
401 integer(I4B) :: group, firstpix, i, npix32
402 real(KMAP) :: blank, testval
403 real(DP) :: bscale,bzero
404 character(len=80) :: comment
405 logical(LGT) :: extend
406 integer(I4B) :: nmove, hdutype, hdunum
407 integer(I4B) :: frow, imap
408 integer(I4B) :: datacode, width
409 LOGICAL(LGT) :: anynull_i
410
411 integer(I4B), parameter :: MAXDIM = MAXDIM_TOP !number of columns in the extension
412 integer(i8b) :: npix_old
413 integer(i8b), dimension(1:MAXDIM) :: npix
414 integer(i8b), dimension(1:MAXDIM) :: i0, i1
415 integer(i4b), dimension(1:MAXDIM) :: repeat
416 integer(i4b) :: nrow2read, nelem
417
418 integer(I4B) :: nrows, tfields, varidat
419 character(len=20), dimension(1:MAXDIM) :: ttype, tform, tunit
420 character(len=20) :: extname
421 character(len=*), parameter :: code='read_bintab'
422 !-----------------------------------------------------------------------
423 status=0
424
425 unit = 146
426 naxes(1) = 1
427 naxes(2) = 1
428 nfound = -1
429 anynull = .false.
430 bscale = 1.0d0
431 bzero = 0.0d0
432 blank = -2.e25
433 nullval = bscale*blank + bzero
434 comment=''
435 ttype=''
436 tform=''
437 tunit=''
438 extname=''
439
440 nl_header = 0
441 if (present(header)) then
442 nl_header = size(header)
443 len_header = 80
444 endif
445
446 nl_units = 0
447 if (present(units)) then
448 nl_units = size(units)
449 len_units = min(80,len(units(1))) ! due to SUN compiler bug
450 endif
451
452 readwrite=0
453 !call ftopen(unit,filename,readwrite,blocksize,status)
454 call ftnopn(unit,filename,readwrite, status) !open primary HDU or specified HDU
455 if (status > 0) call printerror(status)
456 ! -----------------------------------------
457 call ftghdn(unit, hdunum)
458
459 if (hdunum == 1) then ! in primary HDU
460 ! determines the presence of image
461 call ftgkyj(unit,'NAXIS', naxis, comment, status)
462 if (status > 0) call printerror(status)
463
464 ! determines the presence of an extension
465 call ftgkyl(unit,'EXTEND', extend, comment, status)
466 if (status > 0) then
467 extend = .false.
468 status = 0 ! no extension :
469 ! to be compatible with first version of the code
470 endif
471 endif
472
473 if (naxis > 0 .and. .not.extend .and. hdunum==1) then ! there is an image
474 ! determine the size of the image (look naxis1 and naxis2)
475 call ftgknj(unit,'NAXIS',1_i4b,2_i4b,naxes,nfound,status)
476
477 ! check that it found only NAXIS1
478 if (nfound == 2 .and. naxes(2) > 1) then
479 print *,'multi-dimensional image'
480 print *,'expected 1-D data.'
481 call fatal_error
482 end if
483
484 if (nfound < 1) then
485 call printerror(status)
486 print *,'can not find NAXIS1.'
487 call fatal_error
488 endif
489
490 npix(1)=naxes(1)
491 if (npix(1) /= npixtot) then
492 print *,'WARNING: found ',npix(1),' pixels in '//trim(filename)
493 print *,' expected ',npixtot
494 npix(1) = min(npix(1), npixtot)
495 print *,' only ',npix(1),' will be read'
496 endif
497
498 call ftgkyd(unit,'BSCALE',bscale,comment,status)
499 if (status == 202) then ! BSCALE not found
500 bscale = 1.0d0
501 status = 0
502 endif
503 call ftgkyd(unit,'BZERO', bzero, comment,status)
504 if (status == 202) then ! BZERO not found
505 bzero = 0.0d0
506 status = 0
507 endif
508 call f90ftgky_(unit, 'BLANK', blank, comment, status)
509 if (status == 202) then ! BLANK not found
510 ! (according to fitsio BLANK is integer)
511 blank = -2.e25
512 status = 0
513 endif
514 nullval = bscale*blank + bzero
515
516 ! -----------------------------------------
517
518 group=1
519 firstpix = 1
520 npix32 = npix(1)
521 call f90ftgpv_(unit, group, firstpix, npix32, nullval, map(0:npix(1)-1,1), anynull, status)
522 ! if there are any NaN pixels, (real data)
523 ! or BLANK pixels (integer data) they will take nullval value
524 ! and anynull will switch to .true.
525 ! otherwise, switch it by hand if necessary
526 testval = 1.e-6 * ABS(nullval)
527 do i=0, npix(1)-1
528 if (ABS(map(i,1)-nullval) < testval) then
529 anynull = .true.
530 goto 111
531 endif
532 enddo
533 111 continue
534
535 else if (extend .or. hdunum>1) then
536 if (hdunum == 1) then
537 nmove = +1
538 if (present(extno)) nmove = +1 + extno
539 call ftmrhd(unit, nmove, hdutype, status)
540 else
541 call ftghdt(unit, hdutype, status)
542 endif
543
544 call assert (hdutype==2, 'this is not a binary table')
545
546 ! reads all the keywords
547 call ftghbn(unit, MAXDIM, &
548 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
549 & status)
550
551 if (tfields < nmaps) then
552 print *,'found ',tfields,' maps in file '//trim(filename)
553 print *,'expected ',nmaps
554 call fatal_error
555 endif
556
557 ! finds the bad data value
558 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
559 if (status == 202) then ! bad_data not found
560 if (KMAP == SP) nullval = s_bad_value ! default value
561 if (KMAP == DP) nullval = d_bad_value ! default value
562 status = 0
563 endif
564
565 if (nl_header > 0) then
566 do i=1,nl_header
567 header(i)(1:len_header) = ""
568 enddo
569 call get_clean_header(unit, header, filename, status)
570 status = 0
571 endif
572
573 if (nl_units > 0) then
574 do i=1,nl_units
575 units(i)(1:len_units) = 'unknown' ! default
576 enddo
577 do imap = 1, min(nmaps, nl_units)
578 units(imap)(1:len_units) = adjustl(tunit(imap))
579 enddo
580 endif
581
582 npix_old = npixtot
583 do imap = 1, nmaps
584 !parse TFORM keyword to find out the length of the column vector
585 call ftbnfm(tform(imap), datacode, repeat(imap), width, status)
586 npix(imap) = int(nrows,i8b) * repeat(imap)
587 if (npix(imap) /= npixtot .and. npix_old /= npix(imap)) then
588 print *,'WARNING: found ',npix(imap),' pixels in '//trim(filename)//', column ',imap
589 print *,' expected ',npixtot,' or ',npix_old
590 npix_old = npix(imap)
591 npix(imap) = min(npix(imap), npixtot)
592 print *,' only ',npix(imap),' will be read'
593 endif
594 enddo
595
596
597 call ftgrsz(unit, nrow2read, status)
598 nrow2read = max(nrow2read, 1)
599 firstpix = 1 ! starting position in FITS within row, 1 based
600 i0(:) = 0_i8b ! starting element in array, 0 based
601 do frow = 1, nrows, nrow2read
602 do imap = 1, nmaps
603 i1(imap) = min(i0(imap) + int(nrow2read,i8b) * repeat(imap), npix(imap)) - 1_i8b
604 nelem = i1(imap) - i0(imap) + 1
605 call f90ftgcv_(unit, imap, frow, firstpix, nelem, &
606 & nullval, map(i0(imap):i1(imap),imap), anynull_i, status)
607 anynull = anynull .or. anynull_i
608 i0(imap) = i1(imap) + 1_i8b
609 enddo
610 enddo
611 ! sanity check
612 do imap = 1, nmaps
613 if (i0(imap) /= npix(imap)) then
614 call fatal_error('something wrong during piece wise reading')
615 endif
616 enddo
617
618 else ! no image no extension, you are dead, man
619 call fatal_error(' No image, no extension in '//trim(filename))
620 endif
621 ! close the file
622 call ftclos(unit, status)
623
624 ! check for any error, and if so print out error messages
625 if (status > 0) call printerror(status)
626
627 return
628 end subroutine read_bintab8_KLOAD
629
630 !=======================================================================
631 subroutine read_conbintab_KLOAD(filename, alms, nalms, units, extno)
632 !=======================================================================
633 ! Read a FITS file containing alms values
634 !
635 ! slightly modified to deal with vector column
636 ! in binary table EH/IAP/Jan-98
637 !
638 ! Used by synfast when reading a binary file with alms for cons.real.
639 ! FKH/Apr-99
640 !
641 ! extno : optional, number of extension to be read, default=0: first extension
642 ! Jan 2005, EH, improved for faster reading
643 !=======================================================================
644 CHARACTER(LEN=*), INTENT(IN) :: filename
645 INTEGER(I4B), INTENT(IN) :: nalms !, nlheader
646 REAL(KMAP), DIMENSION(0:nalms-1,1:6), INTENT(OUT) :: alms
647 CHARACTER(LEN=*), dimension(1:), optional, INTENT(OUT) :: units
648 INTEGER(I4B) , optional, INTENT(IN) :: extno
649
650 REAL(KMAP) :: nullval
651 LOGICAL(LGT) :: anynull
652
653 INTEGER(I4B), DIMENSION(:), allocatable :: lm
654 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
655 INTEGER(I4B) :: npix
656 CHARACTER(LEN=80) :: comment
657 LOGICAL(LGT) :: extend
658 INTEGER(I4B) :: nmove, hdutype
659 INTEGER(I4B) :: frow, imap
660 INTEGER(I4B) :: datacode, repeat, width
661 integer(I4B) :: i, l, m
662 integer(i4b) :: nrow2read, nelem
663 integer(i8b) :: i0, i1
664
665 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
666 INTEGER(I4B) :: nrows, tfields, varidat
667 CHARACTER(LEN=20), dimension(1:MAXDIM) :: ttype, tform, tunit
668 CHARACTER(LEN=20) :: extname
669 character(len=*), parameter :: code="read_conbintab"
670
671 !-----------------------------------------------------------------------
672 status=0
673
674 unit = 145
675 naxes(1) = 1
676 naxes(2) = 1
677 nfound = -1
678 anynull = .false.
679 alms=0. ! set output to 0.
680 readwrite=0
681 comment=''
682 ttype=''
683 tform=''
684 tunit=''
685 extname=''
686 call ftopen(unit,filename,readwrite,blocksize,status)
687 if (status > 0) call printerror(status)
688 ! -----------------------------------------
689
690 ! determines the presence of image
691 call ftgkyj(unit,'NAXIS', naxis, comment, status)
692 if (status > 0) call printerror(status)
693
694 ! determines the presence of an extension
695 call ftgkyl(unit,'EXTEND', extend, comment, status)
696 if (status > 0) status = 0 ! no extension :
697 ! to be compatible with first version of the code
698
699 if (.not.extend) then
700 print*,'No extension!'
701 call fatal_error
702 endif
703
704 ! go to assigned extension (if it exists)
705 nmove = +1
706 if (present(extno)) nmove = +1 + extno
707 call ftmrhd(unit, nmove, hdutype, status)
708 if (status > 0) then
709 ! if required extension not found:
710 ! print a warning, fill with dummy values, return to calling routine
711 print*,code//' WARNING: the extension ',extno,' was not found in ',trim(filename)
712 alms(0:nalms-1,1)=0. ! l = 0
713 alms(0:nalms-1,2)=1. ! m = 1
714 alms(0:nalms-1,3:6)=0.
715 status = 0
716 call ftclos(unit, status) ! close the file
717 return
718 endif
719
720 if (hdutype /= 2) then ! not a binary table
721 print*, 'this is not a binary table'
722 call fatal_error
723 endif
724
725 ! reads all the keywords
726 call ftghbn(unit, MAXDIM, &
727 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
728 & status)
729
730 if ((tfields/=3).and.(tfields/=5)) then
731 print *,'found ',tfields,' columns in the file'
732 print *,'expected 3 or 5'
733 call fatal_error
734 endif
735 ! finds the bad data value
736 ! if (KMAP == SP) call ftgkye(unit,'BAD_DATA',nullval,comment,status)
737 ! if (KMAP == DP) call ftgkyd(unit,'BAD_DATA',nullval,comment,status)
738 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
739 if (status == 202) then ! bad_data not found
740 if (KMAP == SP) nullval = s_bad_value ! default value
741 if (KMAP == DP) nullval = d_bad_value ! default value
742 status = 0
743 endif
744
745 ! if (nlheader > 0) then
746 ! header = ""
747 ! status = 0
748 ! call get_clean_header(unit, header, filename, status)
749 ! endif
750
751 if (present(units)) then
752 units(1) = tunit(2)
753 endif
754
755 !parse TFORM keyword to find out the length of the column vector
756 call ftbnfm(tform(1), datacode, repeat, width, status)
757 npix = nrows * repeat
758 if (npix /= nalms) then
759 print *,'found ',npix,' alms'
760 print *,'expected ',nalms
761 call fatal_error
762 endif
763
764 call ftgrsz(unit, nrow2read, status)
765 nrow2read = max(nrow2read, 1)
766 nelem = nrow2read * repeat
767 i0 = 0_i8b
768 allocate(lm(0:nelem-1))
769 do frow = 1, nrows, nrow2read
770 i1 = min(i0 + nrow2read * repeat, int(npix,i8b)) - 1_i8b
771 nelem = i1 - i0 + 1
772 ! first column -> index
773 call ftgcvj(unit, 1_i4b, frow, 1_i4b, nelem, i_bad_value, &
774 & lm(0), anynull, status)
775 call assert(.not. anynull, 'There are undefined values in the table!')
776 ! other columns -> a(l,m)
777 do imap = 2, tfields
778 call f90ftgcv_(unit, imap, frow, 1_i4b, nelem, nullval, &
779 & alms(i0:i1,imap+1), anynull, status)
780 call assert (.not. anynull, 'There are undefined values in the table!')
781 enddo
782 ! recoding of the mapping, EH, 2002-08-08
783 ! lm = l*l + l + m + 1
784 do i = i0, i1
785 l = int(sqrt( real(lm(i-i0)-1, kind = DP) ) )
786 m = lm(i-i0) - l*(l+1) - 1
787 ! check that round-off did not screw up mapping
788 if (abs(m) > l) then
789 print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
790 print*,l, m, l*(l+1)+m+1, lm(i-i0)
791 call fatal_error
792 endif
793 alms(i,1) = real( l, kind=KMAP)
794 alms(i,2) = real( m, kind=KMAP)
795 enddo
796 i0 = i1 + 1_i8b
797 enddo
798 deallocate(lm)
799 ! sanity check
800 if (i0 /= npix) then
801 print*,'something wrong during piece-wise reading'
802 call fatal_error
803 endif
804
805 ! !reads the columns
806 ! ! first column : index -> (l,m)
807 ! allocate(lm(0:nalms-1))
808 ! column = 1
809 ! frow = 1
810 ! firstpix = 1
811 ! npix = nrows * repeat
812 ! if (npix /= nalms) then
813 ! print *,'found ',npix,' alms'
814 ! print *,'expected ',nalms
815 ! call fatal_error
816 ! endif
817 ! call ftgcvj(unit, column, frow, firstpix, npix, i_bad_value, &
818 ! & lm(0), anynull, status)
819 ! call assert (.not. anynull, 'There are undefined values in the table!')
820 ! ! recoding of the mapping, EH, 2002-08-08
821 ! ! lm = l*l + l + m + 1
822 ! do i = 0, nalms - 1
823 ! l = int(sqrt( real(lm(i)-1, kind = DP) ) )
824 ! m = lm(i) - l*(l+1) - 1
825 ! ! check that round-off did not screw up mapping
826 ! if (abs(m) > l) then
827 ! print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
828 ! print*,l, m, l*(l+1)+m+1, lm(i)
829 ! call fatal_error
830 ! endif
831 ! alms(i,1) = real( l, kind=KMAP )
832 ! alms(i,2) = real( m, kind=KMAP )
833 ! enddo
834 ! deallocate(lm)
835 !
836 ! do imap = 2, tfields
837 ! !parse TFORM keyword to find out the length of the column vector
838 ! call ftbnfm(tform(imap), datacode, repeat, width, status)
839 !
840 ! !reads the columns
841 ! column = imap
842 ! frow = 1
843 ! firstpix = 1
844 ! npix = nrows * repeat
845 ! if (npix /= nalms) then
846 ! print *,'found ',npix,' alms'
847 ! print *,'expected ',nalms
848 ! call fatal_error
849 ! endif
850 ! call f90ftgcv_(unit, column, frow, firstpix, npix, nullval, &
851 ! & alms(0:npix-1,imap+1), anynull, status)
852 ! call assert (.not. anynull, 'There are undefined values in the table!')
853 ! enddo
854 ! close the file
855 call ftclos(unit, status)
856
857
858 ! check for any error, and if so print out error messages
859 if (status > 0) call printerror(status)
860 return
861 end subroutine read_conbintab_KLOAD
862
863 #ifndef NO64BITS
864 subroutine write_bintab4_KLOAD(map, npix, nmap, header, nlheader, filename, extno)
865 !=======================================================================
866 INTEGER(I4B), INTENT(IN) :: npix, nmap, nlheader
867 REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap) :: map
868 CHARACTER(LEN=*), INTENT(IN), DIMENSION(1:nlheader) :: header
869 CHARACTER(LEN=*), INTENT(IN) :: filename
870 INTEGER(I4B) , INTENT(IN), optional :: extno
871
872 integer(i8b) :: npix8
873
874 npix8 = npix
875 if (present(extno)) then
876 call write_bintab8_KLOAD(map, npix8, nmap, header, nlheader, filename, extno)
877 else
878 call write_bintab8_KLOAD(map, npix8, nmap, header, nlheader, filename)
879 endif
880 return
881 end subroutine write_bintab4_KLOAD
882 #endif
883
884 subroutine write_bintab8_KLOAD(map, npix, nmap, header, nlheader, filename, extno)
885 !=======================================================================
886 ! Create a FITS file containing a binary table extension with
887 ! the temperature map in the first column
888 ! written by EH from writeimage and writebintable
889 ! (fitsio cookbook package)
890 !
891 ! slightly modified to deal with vector column (ie TFORMi = '1024E')
892 ! in binary table EH/IAP/Jan-98
893 !
894 ! simplified the calling sequence, the header sould be filled in
895 ! before calling the routine
896 !
897 ! July 21, 2004: SP version
898 ! Jan 2005, EH, improved for faster writing
899 ! 2009-02-25: EH, accepts I4B and I8B npix
900 !=======================================================================
901 use pix_tools, only: npix2nside
902 INTEGER(I8B), INTENT(IN) :: npix
903 INTEGER(I4B), INTENT(IN) :: nmap, nlheader
904 ! REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap), target :: map
905 REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap) :: map
906 CHARACTER(LEN=*), INTENT(IN), DIMENSION(1:nlheader) :: header
907 CHARACTER(LEN=*), INTENT(IN) :: filename
908 INTEGER(I4B) , INTENT(IN), optional :: extno
909
910 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
911 INTEGER(I4B) :: i, nside
912 LOGICAL(LGT) :: simple,extend
913 CHARACTER(LEN=80) :: comment, ch
914
915 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
916 INTEGER(I4B) :: nrows, tfields, varidat
917 integer(i4b) :: repeat, nrow2write, nelem
918 integer(i8b) :: i0, i1
919 INTEGER(I4B) :: frow, felem, colnum, hdutype
920 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
921 CHARACTER(LEN=10) :: card
922 CHARACTER(LEN=2) :: stn
923 INTEGER(I4B) :: itn, extno_i
924 character(len=filenamelen) sfilename
925 character(len=1) :: pform
926 ! character(len=80) :: junk_k, junk_v, junk_c
927 !-----------------------------------------------------------------------
928
929 if (KMAP == SP) pform = 'E'
930 if (KMAP == DP) pform = 'D'
931 status=0
932 unit = 144
933 blocksize=1
934
935 extno_i = 0
936 if (present(extno)) extno_i = extno
937
938 if (extno_i == 0) then
939 !*************************************
940 ! create the new empty FITS file
941 !*************************************
942 call ftinit(unit,filename,blocksize,status)
943 if (status > 0) call fatal_error("Error while creating file " &
944 & //trim(filename) &
945 & //". Check path and/or access rights.")
946
947 ! -----------------------------------------------------
948 ! initialize parameters about the FITS image
949 simple=.true.
950 bitpix=32 ! integer*4
951 naxis=0 ! no image
952 naxes(1)=0
953 extend=.true. ! there is an extension
954
955 ! ----------------------
956 ! primary header
957 ! ----------------------
958 ! write the required header keywords
959 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
960
961 ! writes supplementary keywords : none
962
963 ! write the current date
964 call ftpdat(unit,status) ! format (yyyy-mm-dd)
965
966 ! ----------------------
967 ! image : none
968 ! ----------------------
969
970 ! ----------------------
971 ! extension
972 ! ----------------------
973 else
974
975 !*********************************************
976 ! reopen an existing file and go to the end
977 !*********************************************
978 ! remove the leading '!' (if any) when reopening the same file
979 sfilename = adjustl(filename)
980 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
981 call ftopen(unit,sfilename,1_i4b,blocksize,status)
982 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
983
984 endif
985
986 ! creates an extension
987 call ftcrhd(unit, status)
988
989 ! writes required keywords
990 tfields = nmap
991 repeat = 1024
992 if (npix < 1024) repeat = 1 ! for nside <= 8
993 ! for large npix increase repeat so that nrows < 2^31-1
994 nside = npix2nside(npix)
995 if (nside > 1024*256) repeat = nside/256
996 nrows = npix / repeat ! naxis1
997 ch = string(repeat, format='(i8)')
998 ch = trim(adjustl(ch))//pform
999 tform(1:nmap) = ch
1000 ttype(1:nmap) = 'simulation' ! will be updated
1001 tunit(1:nmap) = '' ! optional, will not appear
1002 extname = '' ! optional, will not appear
1003 varidat = 0
1004 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
1005 & extname, varidat, status)
1006
1007 ! write the header literally, putting TFORM1 and TUNIT1 at the desired place
1008 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
1009 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
1010 do i=1,nlheader
1011 card = header(i)
1012 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
1013 stn = card(6:8)
1014 read(stn,'(i3)') itn
1015 ! discard at their original location:
1016 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and
1017 status = 0
1018 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1019 status = 0
1020 if (itn <= tfields) then ! only put relevant information 2008-08-27
1021 call putrec(unit,header(i), status) ! write new TTYPE1
1022 status = 0
1023 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
1024 endif
1025 elseif (header(i)/=' ') then
1026 call putrec(unit,header(i), status)
1027 endif
1028 status = 0
1029 enddo
1030
1031 ! write the extension buffer by buffer
1032 call ftgrsz(unit, nrow2write, status)
1033 nrow2write = max(nrow2write, 1)
1034 felem = 1 ! starting position in FITS (element), 1 based
1035 i0 = 0_i8b ! starting element in array, 0 based
1036 do frow = 1, nrows, nrow2write
1037 i1 = min(i0 + nrow2write * repeat, npix) - 1_i8b
1038 nelem = i1 - i0 + 1
1039 do colnum = 1, nmap
1040 call f90ftpcl_(unit, colnum, frow, felem, nelem, map(i0:i1, colnum), status)
1041 enddo
1042 i0 = i1 + 1_i8b
1043 enddo
1044 ! sanity check
1045 if (i0 /= npix) then
1046 call fatal_error("something wrong during piece wise writing")
1047 endif
1048
1049 ! ----------------------
1050 ! close and exit
1051 ! ----------------------
1052
1053 ! close the file and free the unit number
1054 call ftclos(unit, status)
1055
1056 ! check for any error, and if so print out error messages
1057 if (status > 0) call printerror(status)
1058
1059 return
1060 end subroutine write_bintab8_KLOAD
1061 !=======================================================================
1062 subroutine write_asctab_KLOAD &
1063 & (clout, lmax, ncl, header, nlheader, filename, extno)
1064 !=======================================================================
1065 ! Create a FITS file containing an ASCII table extension with
1066 ! the measured power spectra
1067 ! written by EH from writeimage and writeascii
1068 ! (fitsio cookbook package)
1069 !
1070 ! clout = power spectra with l in (0:lmax)
1071 ! ncl = number of spectra
1072 ! header = FITS header to be put on top of the file
1073 ! nlheader = number of lines of the header
1074 ! filename = FITS output file name
1075 !
1076 ! 2015-09-10: EH, added extno
1077 !=======================================================================
1078 !
1079 INTEGER(I4B), INTENT(IN) :: lmax, ncl,nlheader
1080 REAL(KMAP), INTENT(IN) :: clout(0:lmax,1:ncl)
1081 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1082 CHARACTER(LEN=*), INTENT(IN) :: filename
1083 INTEGER(I4B) , INTENT(IN), optional :: extno
1084
1085 INTEGER(I4B) :: bitpix,naxis,naxes(1)
1086 LOGICAL(LGT) :: simple,extend
1087 CHARACTER(LEN=10) :: card
1088
1089 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP
1090 INTEGER(I4B) :: status,unit,blocksize,tfields,nrows,rowlen
1091 INTEGER(I4B) :: nspace,tbcol(MAXDIM),colnum,frow,felem,hdutype
1092 CHARACTER(LEN=16) :: ttype(MAXDIM),tform(MAXDIM),tunit(MAXDIM),extname
1093 CHARACTER(LEN=80) :: comment, card_tbcol
1094 CHARACTER(LEN=2) :: stn
1095 INTEGER(I4B) :: itn, i, extno_i
1096 character(len=filenamelen) sfilename
1097 character(len=6) :: form
1098 !=======================================================================
1099 if (KMAP == SP) form = 'E15.7'
1100 if (KMAP == DP) form = 'D24.15'
1101 status=0
1102 unit = 109
1103 blocksize=1
1104
1105 extno_i = 0
1106 if (present(extno)) extno_i = extno
1107
1108 if (extno_i == 0) then
1109 call ftinit(unit,filename,blocksize,status)
1110 if (status > 0) call fatal_error("Error while creating file " &
1111 & //trim(filename) &
1112 & //". Check path and/or access rights.")
1113
1114 ! -----------------------------------------------------
1115 ! initialize parameters about the FITS image
1116 simple=.true.
1117 bitpix=32 ! integer*4
1118 naxis=0 ! no image
1119 naxes(1)=0
1120 extend=.true. ! there is an extension
1121
1122 ! ----------------------
1123 ! primary header
1124 ! ----------------------
1125 ! write the required header keywords
1126 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1127
1128 ! writes supplementary keywords : none
1129
1130 ! write the current date
1131 call ftpdat(unit,status) ! (format ccyy-mm-dd)
1132
1133 ! ----------------------
1134 ! image : none
1135 ! ----------------------
1136
1137 ! ----------------------
1138 ! extension
1139 ! ----------------------
1140 else
1141 !*********************************************
1142 ! reopen an existing file and go to the end
1143 !*********************************************
1144 ! remove the leading '!' (if any) when reopening the same file
1145 sfilename = adjustl(filename)
1146 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1147 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1148 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
1149
1150 endif
1151
1152 ! append a new empty extension onto the end of the primary array
1153 call ftcrhd(unit,status)
1154
1155 ! define parameters for the ASCII table
1156 nrows = lmax+1
1157 tfields = ncl
1158 tform(1:ncl) = form
1159 ttype(1:ncl) = 'power spectrum' ! is updated by the value given in the header
1160 tunit(1:ncl) = '' ! optional, will not appear
1161 extname = '' ! optional, will not appear
1162
1163 ! calculate the starting position of each column, and the total row length
1164 nspace=1
1165 call ftgabc(tfields,tform,nspace,rowlen,tbcol,status)
1166
1167 ! write the required header parameters for the ASCII table
1168 call ftphtb(unit,rowlen,nrows,tfields,ttype,tbcol,tform,tunit, &
1169 & extname,status)
1170
1171 ! write the header literally, putting TFORM1 at the desired place
1172 comment = ''
1173 card_tbcol=''
1174 do i=1,nlheader
1175 card = header(i)
1176 if (card(1:5) == 'TTYPE') then ! if TTYPE1 is explicitely given
1177 stn = card(6:8)
1178 read(stn,'(i3)') itn
1179 ! discard at their original location:
1180 !!!!!!!call ftdkey(unit,card(1:6),status) ! old TTYPEi 2019-10-14
1181 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi
1182 status = 0
1183 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1184 status = 0
1185 call ftgcrd(unit,'TBCOL'//stn,card_tbcol,status)
1186 status = 0
1187 call ftdkey(unit,'TBCOL'//stn,status) ! TBCOLi
1188 status = 0
1189 ! and rewrite
1190 if (itn <= tfields) then
1191 call putrec(unit,card_tbcol,status) ! TBCOLi
1192 status = 0
1193 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! TFORMi right after
1194 status = 0
1195 call putrec(unit,header(i), status) ! TTYPEi
1196 endif
1197 elseif (header(i)/=' ') then
1198 call putrec(unit,header(i), status)
1199 endif
1200 status = 0
1201 enddo
1202
1203 frow=1
1204 felem=1
1205 do colnum = 1, ncl
1206 call f90ftpcl_(unit, colnum, frow, felem, nrows, clout(0:nrows-1,colnum), status)
1207 enddo
1208
1209 ! close the FITS file
1210 call ftclos(unit, status)
1211
1212 ! check for any error, and if so print out error messages
1213 if (status > 0) call printerror(status)
1214
1215 return
1216 end subroutine write_asctab_KLOAD
1217 !=======================================================================
1218 ! DUMP_ALMS
1219 !
1220 ! Create/extend a FITS file containing a binary table extension with
1221 ! the a_lm coefficients in each extension.
1222 !
1223 ! Format of alm FITS file: in each extension, 3 columns:
1224 ! index=l*l+l+m+1, real(a_lm), imag(a_lm)
1225 ! the a_lm are obtained using the complex Y_lm
1226 ! only the modes with m>=0 are stored (because the map is assumed real)
1227 !
1228 ! The extensions contain, in general, T, E (= G) and B (= C) in that order
1229 ! First extension has extno = 0
1230 !
1231 ! Adapted from write_bintab, FKH/Apr-99
1232 ! SP/DP overloaded, 2004-12, EH
1233 ! reduced size of intermediate arrays (alms_out, lm)
1234 !
1235 subroutine dump_alms_KLOAD(filename, alms, nlmax, header, nlheader, extno)
1236 !=======================================================================
1237 INTEGER(I4B), INTENT(IN) :: nlmax, nlheader, extno
1238 COMPLEX(KMAPC), INTENT(IN), DIMENSION(0:,0:) :: alms
1239 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1240 CHARACTER(LEN=*), INTENT(IN) :: filename
1241 ! local variables
1242 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1243 REAL(KMAP), DIMENSION(:,:), allocatable :: alms_out
1244 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
1245 INTEGER(I4B) :: i,l,m,cnt,hdutype, nmmax
1246 LOGICAL(LGT) :: simple,extend, found_lmax, found_mmax
1247 CHARACTER(LEN=80) :: comment
1248
1249 integer(i8b) :: npix
1250 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1251 INTEGER(I4B) :: nrows, tfields, varidat
1252 INTEGER(I4B) :: frow, felem
1253 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1254 CHARACTER(LEN=10) :: card
1255 CHARACTER(LEN=2) :: stn
1256 INTEGER(I4B) :: itn
1257 character(len=filenamelen) sfilename
1258 character(len=1) :: pform
1259 character(len=*), parameter :: code = 'dump_alms'
1260 !-----------------------------------------------------------------------
1261
1262 if (KMAP == SP) pform = 'E'
1263 if (KMAP == DP) pform = 'D'
1264
1265 nmmax = size(alms,2) - 1
1266 if (nmmax < 0 .or. nmmax > nlmax) call fatal_error('inconsistent Lmax and Mmax in dump_alms')
1267 !! npix=((nlmax+1)*(nlmax+2))/2
1268 npix = ((nmmax+1_i8b)*(2_i8b*nlmax-nmmax+2))/2
1269 if (npix > MAX_I4B .or. nlmax >= int(sqrt(real(MAX_I4B,kind=dp)))) then
1270 print*,code//'> Index of a_lm too large for current file format,'
1271 print*,code//'> '//trim(filename)//' not written.'
1272 call fatal_error
1273 endif
1274
1275 status=0
1276 unit = 141
1277 blocksize=1
1278
1279 if (extno==0) then
1280 !*********************************************
1281 ! create the new empty FITS file
1282 !*********************************************
1283 call ftinit(unit,filename,blocksize,status)
1284 if (status > 0) call fatal_error("Error while creating file " &
1285 & //trim(filename) &
1286 & //". Check path and/or access rights.")
1287
1288 ! -----------------------------------------------------
1289 ! initialize parameters about the FITS image
1290 simple=.true.
1291 bitpix=32 ! integer*4
1292 naxis=0 ! no image
1293 naxes(1)=0
1294 extend=.true. ! there is an extension
1295
1296 ! ----------------------
1297 ! primary header
1298 ! ----------------------
1299 ! write the required header keywords
1300 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1301
1302 ! writes supplementary keywords : none
1303
1304 ! write the current date
1305 call ftpdat(unit,status) ! format (yyyy-mm-dd)
1306
1307 ! ----------------------
1308 ! image : none
1309 ! extension
1310 ! ----------------------
1311 else
1312
1313 !*********************************************
1314 ! reopen an existing file and go to the end
1315 !*********************************************
1316 ! remove the leading '!' (if any) when reopening the same file
1317 sfilename = adjustl(filename)
1318 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1319 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1320 call ftmahd(unit,1_i4b+extno,hdutype,status)
1321
1322 endif
1323
1324 ! creates an extension
1325 call ftcrhd(unit, status)
1326
1327 ! writes required keywords
1328 nrows = npix ! naxis1
1329 tfields = 3
1330 tform = '' ; ttype = '' ; tunit = ''
1331 tform(1)(1:2)= '1J' ! necessary with ifort 11.1.076
1332 tform(2)(1:2) = '1'//pform
1333 tform(3)(1:2) = '1'//pform
1334 ttype(1)(1:15) = 'index=l^2+l+m+1'
1335 ttype(2)(1:15) = 'alm (real) '
1336 ttype(3)(1:15) = 'alm (imaginary)'
1337 tunit(1:3) = '' ! optional, will not appear
1338 extname = '' ! optional, will not appear
1339 varidat = 0
1340 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
1341 & extname, varidat, status)
1342
1343 ! write the header literally, putting TFORM1 at the desired place
1344 do i=1,nlheader
1345 card = header(i)
1346 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
1347 stn = card(6:8)
1348 read(stn,'(i3)') itn
1349 ! discard at their original location:
1350 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and ! remove
1351 status = 0
1352 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1353 status = 0
1354 if (itn <= tfields) then ! only put relevant information 2008-08-27
1355 call putrec(unit,header(i), status) ! write new TTYPEi
1356 status = 0
1357 if (itn==1) then
1358 comment = 'data format of field: 4-byte INTEGER'
1359 else
1360 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
1361 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
1362 endif
1363 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
1364 endif
1365 elseif (header(i)/=' ') then
1366 call putrec(unit,header(i), status)
1367 endif
1368 status = 0
1369 enddo
1370
1371 call ftukyj(unit, 'MIN-LPOL', 0_i4b, 'Minimum L multipole order', status)
1372 call ftukyj(unit, 'MAX-LPOL', nlmax, 'Maximum L multipole order', status)
1373 call ftukyj(unit, 'MAX-MPOL', nmmax, 'Maximum M multipole degree', status)
1374
1375 allocate(lm (0:nmmax))
1376 allocate(alms_out(0:nmmax,1:2))
1377 ! write the extension one column by one column
1378 frow = 1 ! starting position (row)
1379 felem = 1 ! starting position (element)
1380 do l = 0, nlmax
1381 cnt = 0
1382 do m = 0, min(l,nmmax)
1383 lm(cnt) = l**2 + l + m + 1
1384 alms_out(cnt,1)=REAL( alms(l,m))
1385 alms_out(cnt,2)=AIMAG(alms(l,m))
1386 cnt = cnt + 1
1387 enddo
1388 call ftpclj( unit, 1_i4b, frow, felem, cnt, lm, status)
1389 call f90ftpcl_(unit, 2_i4b, frow, felem, cnt, alms_out(0:cnt-1,1), status)
1390 call f90ftpcl_(unit, 3_i4b, frow, felem, cnt, alms_out(0:cnt-1,2), status)
1391 frow = frow + cnt
1392 enddo
1393 deallocate(lm)
1394 deallocate(alms_out)
1395
1396 ! ----------------------
1397 ! close and exit
1398 ! ----------------------
1399
1400 ! close the file and free the unit number
1401 call ftclos(unit, status)
1402
1403 ! check for any error, and if so print out error messages
1404 if (status > 0) call printerror(status)
1405
1406
1407 return
1408 end subroutine dump_alms_KLOAD
1409 !=======================================================================
1410 subroutine write_alms_KLOAD(filename, nalms, alms, ncl, header, nlheader, extno)
1411 !=======================================================================
1412 ! Writes alms from to binary FITS file, FKH/Apr-99
1413 ! ncl is the number of columns, in the output fits file,
1414 ! either 3 or 5 (with or without errors respectively)
1415 !
1416 ! input array (real) FITS file
1417 ! alms(:,1) = l )
1418 ! alms(:,2) = m )---> col 1: l*l+l+m+1
1419 ! alms(:,3) = real(a_lm) ---> col 2
1420 ! alms(:,4) = imag(a_lm) ---> col 3
1421 ! alms(:,5) = real(delta a_lm) ---> col 4
1422 ! alms(:,6) = imag(delta a_lm) ---> col 5
1423 !
1424 !=======================================================================
1425
1426 INTEGER(I4B), INTENT(IN) :: nalms, nlheader, ncl, extno
1427 REAL(KMAP), INTENT(IN), DIMENSION(0:nalms-1,1:(ncl+1)) :: alms
1428 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1429 CHARACTER(LEN=*), INTENT(IN) :: filename
1430
1431 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1432 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
1433 INTEGER(I4B) :: i,hdutype, lmax, mmax, lmin
1434 LOGICAL(LGT) :: simple,extend
1435 CHARACTER(LEN=80) :: comment
1436
1437 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1438 INTEGER(I4B) :: nrows, npix, tfields, varidat, repeat
1439 INTEGER(I4B) :: frow, felem, colnum, stride, istart, iend, k
1440 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1441 CHARACTER(LEN=10) :: card
1442 CHARACTER(LEN=2) :: stn
1443 INTEGER(I4B) :: itn
1444 integer(I4B) :: l, m
1445 character(len=filenamelen) sfilename
1446 character(len=1) :: pform
1447 !-----------------------------------------------------------------------
1448
1449 if (KMAP == SP) pform = 'E'
1450 if (KMAP == DP) pform = 'D'
1451
1452 status=0
1453 unit = 140
1454
1455 ! create the new empty FITS file
1456 blocksize=1
1457
1458 if (extno==1) then
1459
1460 call ftinit(unit,filename,blocksize,status)
1461 if (status > 0) call fatal_error("Error while creating file " &
1462 & //trim(filename) &
1463 & //". Check path and/or access rights.")
1464
1465 ! -----------------------------------------------------
1466 ! initialize parameters about the FITS image
1467 simple=.true.
1468 bitpix=32 ! integer*4
1469 naxis=0 ! no image
1470 naxes(1)=0
1471 extend=.true. ! there is an extension
1472
1473 ! ----------------------
1474 ! primary header
1475 ! ----------------------
1476 ! write the required header keywords
1477 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1478
1479 ! writes supplementary keywords : none
1480
1481 ! write the current date
1482 call ftpdat(unit,status) ! format ccyy-mm-dd
1483
1484 ! ----------------------
1485 ! image : none
1486 ! ----------------------
1487
1488 ! ----------------------
1489 ! extension
1490 ! ----------------------
1491
1492 else
1493
1494 !*********************************************
1495 ! reopen an existing file and go to the end
1496 !*********************************************
1497 ! remove the leading '!' (if any) when reopening the same file
1498 sfilename = adjustl(filename)
1499 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1500 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1501 call ftmahd(unit,extno,hdutype,status)
1502
1503 endif
1504
1505 ! creates an extension
1506 call ftcrhd(unit, status)
1507
1508 ! writes required keywords
1509 nrows = nalms ! naxis1
1510 tfields = ncl
1511 repeat = 1
1512 tform(1)(1:2)='1J' ! necessary with ifort 11.1.076
1513 do i=2, ncl
1514 tform(i)(1:2) = '1'//pform
1515 enddo
1516 ttype(1)(1:15) = 'index=l^2+l+m+1'
1517 ttype(2)(1:15) = 'alm (real) '
1518 ttype(3)(1:15) = 'alm (imaginary)'
1519 if (ncl>3) then
1520 ttype(4)(1:17) = 'error (real) '
1521 ttype(5)(1:17) = 'error (imaginary)'
1522 endif
1523 tunit(1:ncl) = '' ! optional, will not appear
1524 extname = '' ! optional, will not appear
1525 varidat = 0
1526 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
1527 & extname, varidat, status)
1528
1529 ! write the header literally, putting TFORMi at the desired place
1530 do i=1,nlheader
1531 card = header(i)
1532 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
1533 stn = card(6:8)
1534 read(stn,'(i3)') itn
1535 ! discard at their original location:
1536 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and ! remove
1537 status = 0
1538 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1539 status = 0
1540 if (itn <= tfields) then ! only put relevant information 2008-08-27
1541 call putrec(unit,header(i), status) ! write new TTYPE1
1542 status = 0
1543 if (itn==1) then
1544 comment = 'data format of field: 4-byte INTEGER'
1545 else
1546 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
1547 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
1548 endif
1549 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
1550 endif
1551 elseif (header(i)/=' ') then
1552 call putrec(unit,header(i), status)
1553 endif
1554 status = 0
1555 enddo
1556
1557 lmax = nint(maxval(alms(:,1)))
1558 lmin = nint(minval(alms(:,1)))
1559 mmax = nint(maxval(alms(:,2)))
1560 call ftukyj(unit, 'MIN-LPOL', lmin, 'Minimum L multipole order', status)
1561 call ftukyj(unit, 'MAX-LPOL', lmax, 'Maximum L multipole order', status)
1562 call ftukyj(unit, 'MAX-MPOL', mmax, 'Maximum M multipole degree', status)
1563
1564 ! write the extension by blocks of rows ! EH, Dec 2004
1565 felem = 1 ! starting position (element)
1566 !!! stride = 1000 ! 1000 rows at a time
1567 call ftgrsz(unit, stride, status) ! find optimal stride in rows
1568 stride = max( stride, 1)
1569 allocate(lm(0:stride-1))
1570 do k = 0, (nalms-1)/(stride * repeat)
1571 istart = k * (stride * repeat)
1572 iend = min(nalms, istart + stride * repeat) - 1
1573 do i = istart, iend ! recode the (l,m) -> lm mapping, EH, 2002-08-08
1574 l = nint(alms(i,1))
1575 m = nint(alms(i,2))
1576 lm(i-istart) = (l+1)*l + m + 1
1577 enddo
1578
1579 frow = istart/repeat + 1
1580 npix = iend - istart + 1
1581 call ftpclj( unit, 1_i4b, frow, felem, npix, lm, status)
1582 do colnum = 2, ncl
1583 call f90ftpcl_(unit, colnum, frow, felem, npix, alms(istart:iend,colnum+1), status)
1584 enddo
1585 enddo
1586 deallocate(lm)
1587
1588 ! ----------------------
1589 ! close and exit
1590 ! ----------------------
1591
1592 ! close the file and free the unit number
1593 call ftclos(unit, status)
1594
1595 ! check for any error, and if so print out error messages
1596 if (status > 0) call printerror(status)
1597
1598 return
1599 end subroutine write_alms_KLOAD
1600 !=======================================================================
1601 subroutine read_alms_KLOAD(filename, nalms, alms, ncl, header, nlheader, extno)
1602 !=======================================================================
1603 ! Read a FITS file
1604 !
1605 ! slightly modified to deal with vector column
1606 ! in binary table EH/IAP/Jan-98
1607 !
1608 ! Used by synfast when reading a binary file with alms for cons.real.
1609 ! FKH/Apr-99
1610 !
1611 ! called by fits2alms
1612 ! Jan 2005, EH, improved for faster reading
1613 !=======================================================================
1614 CHARACTER(LEN=*), INTENT(IN) :: filename
1615 INTEGER(I4B), INTENT(IN) :: nalms, ncl,nlheader,extno
1616 REAL(KMAP), DIMENSION(0:nalms-1,1:(ncl+1)), INTENT(OUT) :: alms
1617 CHARACTER(LEN=80), INTENT(OUT), DIMENSION(1:nlheader) :: header
1618 REAL(KMAP) :: nullval
1619 LOGICAL(LGT) :: anynull
1620
1621 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1622 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
1623 INTEGER(I4B) :: npix
1624 CHARACTER(LEN=80) :: comment ! , record
1625 LOGICAL(LGT) :: extend
1626 INTEGER(I4B) :: nmove, hdutype ! , nkeys , nspace
1627 INTEGER(I4B) :: frow, imap
1628 INTEGER(I4B) :: datacode, repeat, width
1629 integer(I4B) :: i, l, m
1630 integer(i4b) :: nrow2read, nelem
1631 integer(i8b) :: i0, i1
1632
1633 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1634 INTEGER(I4B) :: nrows, tfields, varidat
1635 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1636
1637 !-----------------------------------------------------------------------
1638 status=0
1639 header=''
1640 comment=''
1641 ttype=''
1642 tform=''
1643 tunit=''
1644 extname=''
1645 unit = 139
1646 naxes(1) = 1
1647 naxes(2) = 1
1648 nfound = -1
1649 anynull = .false.
1650 alms=0.
1651 readwrite=0
1652 call ftopen(unit,filename,readwrite,blocksize,status)
1653 if (status > 0) then
1654 call printerror(status)
1655 call fatal_error("Aborting.")
1656 endif
1657 ! -----------------------------------------
1658
1659 ! determines the presence of image
1660 call ftgkyj(unit,'NAXIS', naxis, comment, status)
1661 if (status > 0) call printerror(status)
1662
1663 ! determines the presence of an extension
1664 call ftgkyl(unit,'EXTEND', extend, comment, status)
1665 if (status > 0) status = 0 ! no extension :
1666 ! to be compatible with first version of the code
1667
1668 call assert (extend, 'No extension!')
1669 nmove = +extno
1670 call ftmrhd(unit, nmove, hdutype, status)
1671 !cc write(*,*) hdutype
1672
1673 call assert(hdutype==2, 'this is not a binary table')
1674
1675 header = ""
1676 call get_clean_header( unit, header, filename, status)
1677
1678 ! reads all the keywords
1679 call ftghbn(unit, MAXDIM, &
1680 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
1681 & status)
1682
1683 if (tfields<ncl) then
1684 print *,'found ',tfields,' columns in the file'
1685 print *,'expected ',ncl
1686 call fatal_error
1687 endif
1688 ! finds the bad data value
1689 ! if (KMAP == SP) call ftgkye(unit,'BAD_DATA',nullval,comment,status)
1690 ! if (KMAP == DP) call ftgkyd(unit,'BAD_DATA',nullval,comment,status)
1691 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
1692 if (status == 202) then ! bad_data not found
1693 if (KMAP == SP) nullval = s_bad_value ! default value
1694 if (KMAP == DP) nullval = d_bad_value ! default value
1695 status = 0
1696 endif
1697 !parse TFORM keyword to find out the length of the column vector
1698 call ftbnfm(tform(1), datacode, repeat, width, status)
1699 npix = nrows * repeat
1700 ! if (npix /= nalms) then
1701 if (npix > nalms) then
1702 print *,'found ',npix,' alms'
1703 ! print *,'expected ',nalms
1704 print *,'expected ',nalms,' or less'
1705 call fatal_error
1706 endif
1707
1708 call ftgrsz(unit, nrow2read, status)
1709 nrow2read = max(nrow2read, 1)
1710 nelem = nrow2read * repeat
1711 i0 = 0_i8b
1712 allocate(lm(0:nelem-1))
1713 do frow = 1, nrows, nrow2read
1714 i1 = min(i0 + nrow2read * repeat, int(npix,i8b)) - 1_i8b
1715 nelem = i1 - i0 + 1
1716 ! first column -> index
1717 call ftgcvj(unit, 1_i4b, frow, 1_i4b, nelem, i_bad_value, &
1718 & lm(0), anynull, status)
1719 call assert(.not. anynull, 'There are undefined values in the table!')
1720 ! other columns -> a(l,m)
1721 do imap = 2, ncl
1722 call f90ftgcv_(unit, imap, frow, 1_i4b, nelem, nullval, &
1723 & alms(i0:i1,imap+1), anynull, status)
1724 call assert (.not. anynull, 'There are undefined values in the table!')
1725 enddo
1726 ! recoding of the mapping, EH, 2002-08-08
1727 ! lm = l*l + l + m + 1
1728 do i = i0, i1
1729 l = int(sqrt( real(lm(i-i0)-1, kind = DP) ) )
1730 m = lm(i-i0) - l*(l+1) - 1
1731 ! check that round-off did not screw up mapping
1732 if (abs(m) > l) then
1733 print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
1734 print*,l, m, l*(l+1)+m+1, lm(i-i0)
1735 call fatal_error
1736 endif
1737 alms(i,1) = real( l, kind=KMAP)
1738 alms(i,2) = real( m, kind=KMAP)
1739 enddo
1740 i0 = i1 + 1_i8b
1741 enddo
1742 deallocate(lm)
1743 ! sanity check
1744 if (i0 /= npix) then
1745 print*,'something wrong during piece-wise reading'
1746 call fatal_error
1747 endif
1748
1749 ! close the file
1750 call ftclos(unit, status)
1751
1752
1753 ! check for any error, and if so print out error messages
1754 if (status > 0) call printerror(status)
1755 return
1756 end subroutine read_alms_KLOAD
1757 !**************************************************************************
1758 SUBROUTINE read_bintod_KLOAD(filename, tod, npixtot, ntods, firstpix, nullval, anynull, &
1759 header, extno, units)
1760 !**************************************************************************
1761 !=======================================================================
1762 ! Read a FITS file
1763 !
1764 ! slightly modified to deal with vector column (ie TFORMi = '1024E')
1765 ! in binary table EH/IAP/Jan-98
1766 !
1767 ! This routine is used for reading TODS by anafast.
1768 ! Modified to start at a given pix numb OD & RT 02/02
1769 ! Modified to handle huge array (npix_tot > 2^32) OD & EH 07/02
1770 ! 2002-07-08 : bugs correction by E.H.
1771 ! 2007-01-31 : added units optional output
1772 !=======================================================================
1773
1774 IMPLICIT NONE
1775
1776 CHARACTER(LEN=*), INTENT(IN) :: filename
1777 INTEGER(I8B) , INTENT(IN) :: npixtot,firstpix
1778 INTEGER(I4B), INTENT(IN) :: ntods
1779 REAL(KMAP), DIMENSION(0:,1:), INTENT(OUT) :: tod
1780 REAL(KMAP), INTENT(OUT) :: nullval
1781 LOGICAL(LGT), INTENT(OUT) :: anynull
1782 character(len=*), dimension(1:),intent(out), optional :: header
1783 INTEGER(I4B), INTENT(IN), OPTIONAL :: extno
1784 character(LEN=*), dimension(1:),intent(OUT), optional :: units
1785
1786
1787 integer(I4B) :: i, nl_header, len_header, nl_units, len_units
1788 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
1789 INTEGER(I4B) :: npix_32 !,firstpix_32
1790 CHARACTER(LEN=80) :: comment
1791 LOGICAL(LGT) :: extend
1792 INTEGER(I4B) :: nmove, hdutype
1793 INTEGER(I4B) :: column, frow, itod
1794 INTEGER(I4B) :: datacode, repeat, width
1795
1796 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1797 INTEGER(I4B) :: nrows, tfields, varidat,felem
1798 CHARACTER(LEN=20), dimension(1:MAXDIM) :: ttype, tform,tunit
1799 CHARACTER(LEN=20) :: extname
1800
1801 INTEGER(I8B) :: q,iq,npix_tmp,firstpix_tmp, i0, i1
1802
1803 !-----------------------------------------------------------------------
1804 status=0
1805
1806 unit = 138
1807 naxes(1) = 1
1808 naxes(2) = 1
1809 nfound = -1
1810 anynull = .FALSE.
1811
1812 nl_header = 0
1813 if (present(header)) then
1814 nl_header = size(header)
1815 len_header = 80
1816 endif
1817
1818 nl_units = 0
1819 if (present(units)) then
1820 nl_units = size(units)
1821 len_units = min(80,len(units(1))) ! due to SUN compiler bug
1822 endif
1823
1824 readwrite=0
1825 CALL ftopen(unit,filename,readwrite,blocksize,status)
1826 IF (status .GT. 0) CALL printerror(status)
1827 ! -----------------------------------------
1828
1829 ! determines the presence of image
1830 CALL ftgkyj(unit,'NAXIS', naxis, comment, status)
1831 IF (status .GT. 0) CALL printerror(status)
1832
1833 ! determines the presence of an extension
1834 CALL ftgkyl(unit,'EXTEND', extend, comment, status)
1835 IF (status .GT. 0) status = 0 ! no extension :
1836 ! to be compatible with first version of the code
1837
1838 IF (naxis .GT. 0) THEN ! there is an image
1839 print*,'WARNING : Image is ignored in '//trim(filename)
1840 ENDIF
1841 IF (extend) THEN ! there is an extension
1842
1843 nmove = +1
1844 if (present(extno)) nmove = +1 + extno
1845 CALL ftmrhd(unit, nmove, hdutype, status)
1846 !cc write(*,*) hdutype
1847
1848 call assert(hdutype==2, 'this is not a binary table')
1849
1850 ! reads all the keywords
1851 CALL ftghbn(unit, MAXDIM, &
1852 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
1853 & status)
1854
1855 IF (tfields .LT. ntods) THEN
1856 PRINT *,'found ',tfields,' tods in the file'
1857 PRINT *,'expected ',ntods
1858 call fatal_error
1859 ENDIF
1860
1861 if (nl_header > 0) then
1862 header = ""
1863 status = 0
1864 call get_clean_header(unit, header, filename, status)
1865 endif
1866
1867 if (nl_units > 0) then
1868 do i=1,nl_units
1869 units(i)(1:len_units) = 'unknown' ! default
1870 enddo
1871 do itod = 1, min(ntods, nl_units)
1872 units(itod)(1:len_units) = adjustl(tunit(itod))
1873 enddo
1874 endif
1875
1876 ! finds the bad data value
1877 ! if (KMAP == SP) CALL ftgkye(unit,'BAD_DATA',nullval,comment,status)
1878 ! if (KMAP == DP) CALL ftgkyd(unit,'BAD_DATA',nullval,comment,status)
1879 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
1880 IF (status .EQ. 202) THEN ! bad_data not found
1881 if (KMAP == SP) nullval = s_bad_value ! default value
1882 if (KMAP == DP) nullval = d_bad_value ! default value
1883 status = 0
1884 ENDIF
1885
1886 IF (npixtot .LT. nchunk_max) THEN
1887
1888 DO itod = 1, ntods
1889
1890 !parse TFORM keyword to find out the length of the column vector (repeat)
1891 CALL ftbnfm(tform(itod), datacode, repeat, width, status)
1892 frow = (firstpix)/repeat+1 ! 1 based
1893 felem = firstpix-(frow-1)*repeat+1 ! 1 based
1894 npix_32 = npixtot
1895
1896 !reads the columns
1897 column = itod
1898 CALL f90ftgcv_(unit, column, frow, felem, npix_32, nullval, &
1899 & tod(0:npix_32-1,itod), anynull, status)
1900 END DO
1901
1902 ELSE
1903
1904 q = (npixtot-1)/nchunk_max
1905 DO iq = 0,q
1906 IF (iq .LT. q) THEN
1907 npix_tmp = nchunk_max
1908 ELSE
1909 npix_tmp = npixtot - iq*nchunk_max
1910 ENDIF
1911 firstpix_tmp = firstpix + iq*nchunk_max
1912 npix_32 = npix_tmp
1913 i0 = firstpix_tmp-firstpix
1914 i1 = i0 + npix_tmp - 1_i8b
1915
1916 DO itod = 1, ntods
1917 ! parse TFORM keyword to find out the length of the column vector
1918 CALL ftbnfm(tform(itod), datacode, repeat, width, status)
1919 frow = (firstpix_tmp)/repeat+1 ! 1 based
1920 felem = firstpix_tmp-(frow-1)*repeat+1 ! 1 based
1921 CALL f90ftgcv_(unit, itod, frow, felem, npix_32, nullval, &
1922 & tod(i0:i1,itod), anynull, status)
1923 END DO
1924
1925 ENDDO
1926
1927 ENDIF
1928
1929 ELSE ! no image no extension, you are dead, man
1930 call fatal_error(' No image, no extension')
1931 ENDIF
1932
1933 ! close the file
1934 CALL ftclos(unit, status)
1935
1936 ! check for any error, and if so print out error messages
1937 IF (status .GT. 0) CALL printerror(status)
1938
1939 RETURN
1940
1941 END SUBROUTINE read_bintod_KLOAD
1942 !=======================================================================
1943
1944 !======================================================================================
1945 SUBROUTINE write_bintabh_KLOAD(tod, npix, ntod, header, nlheader, filename, extno, firstpix, repeat)
1946 !======================================================================================
1947
1948 ! =================================================================================
1949 ! Create a FITS file containing a binary table extension in the first extension
1950 !
1951 ! Designed to deal with Huge file, (n_elements > 2^31)
1952 !
1953 ! OPTIONAL NEW PARAMETERS:
1954 ! firstpix : position in the file of the first element to be written (starts at 0)
1955 ! default value =0
1956 ! 8-byte integer
1957 ! if NE 0 then suppose that the file already exists
1958 !
1959 ! repeat : length of vector per unit rows and columns of the first binary extension
1960 ! default value = 12000 (\equiv 1 mn of PLANCK/HFI data)
1961 ! 4-byte integer
1962 !
1963 ! OTHER PARAMETERS
1964 ! unchanged with respect to the standard write_bintab of the HEALPIX package except
1965 ! npix which is an 8-byte integer
1966 !
1967 ! Adapted from write_bintab
1968 ! E.H. & O.D. @ IAP 07/02
1969 !
1970 ! Requires a compilation in 64 bits of the CFITSIO
1971 ! Note that the flag -D_FILE_OFFSETS_BITS=64 has to be added
1972 ! (cf page CFITIO 2.2 User's guide Chap 4, section 4-13)
1973 !
1974 ! 2002-07-08 : bugs correction by E.H.
1975 ! (uniform use of firstpix_tmp, introduction of firstpix_chunk)
1976 ! 2015-04-28: better handling of repeat (suggested by R. Keskitalo)
1977 !==========================================================================================
1978
1979 USE healpix_types
1980 IMPLICIT NONE
1981
1982 INTEGER(I8B) , INTENT(IN) :: npix
1983 INTEGER(I8B) , INTENT(IN), OPTIONAL :: firstpix
1984 INTEGER(I4B) , INTENT(IN), OPTIONAL :: repeat
1985 INTEGER(I4B) , INTENT(IN) :: ntod,nlheader
1986 REAL(KMAP) , INTENT(IN), DIMENSION(0:npix-1,1:ntod) :: tod
1987 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1988 CHARACTER(LEN=*), INTENT(IN) :: filename
1989 INTEGER(I4B) , INTENT(IN) , OPTIONAL :: extno
1990
1991 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1),repeat_fits
1992 INTEGER(I4B) :: i,npix_32
1993 LOGICAL(LGT) :: simple,extend
1994 CHARACTER(LEN=80) :: comment, ch
1995 integer(I8B) :: repeat_tmp
1996
1997 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1998 INTEGER(I4B) :: nrows,tfields,varidat
1999 INTEGER(I4B) :: frow,felem,colnum,readwrite,width,datacode,hdutype
2000 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
2001 CHARACTER(LEN=10) :: card
2002 CHARACTER(LEN=2) :: stn
2003 INTEGER(I4B) :: itn
2004
2005 real(KMAP), dimension(:), allocatable :: padding
2006 integer(I8B) :: lastpix
2007 integer(I4B) :: lengap
2008
2009 INTEGER(I4B) :: extno_i
2010 character(len=filenamelen) :: sfilename
2011 INTEGER(I8B) :: q,iq,npix_tmp,firstpix_tmp,firstpix_chunk, i0, i1
2012 character(len=1) :: pform
2013 character(len=*), parameter :: code='write_bintabh'
2014 !-----------------------------------------------------------------------
2015
2016 if (KMAP == SP) pform = 'E'
2017 if (KMAP == DP) pform = 'D'
2018
2019 IF (.NOT. PRESENT(repeat) ) THEN
2020 repeat_tmp = 1
2021 if (mod(npix,1024_i8b) == 0) then
2022 repeat_tmp = 1024
2023 elseif (npix >= 12000) then
2024 repeat_tmp = 12000
2025 endif
2026 ELSE
2027 repeat_tmp = repeat
2028 ENDIF
2029 IF (.NOT. PRESENT(firstpix) ) THEN
2030 firstpix_tmp = 0
2031 ELSE
2032 firstpix_tmp = firstpix
2033 ENDIF
2034
2035 extno_i = 0
2036 if (present(extno)) extno_i = extno
2037
2038 status=0
2039 unit = 137
2040 blocksize=1
2041
2042 ! remove the leading '!' (if any) when reopening the same file
2043 sfilename = adjustl(filename)
2044 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
2045
2046 ! create the new empty FITS file
2047
2048 IF (firstpix_tmp .EQ. 0) THEN
2049
2050 if (extno_i == 0) then
2051 CALL ftinit(unit,filename,blocksize,status)
2052 if (status > 0) call fatal_error("Error while creating file " &
2053 & //trim(filename) &
2054 & //". Check path and/or access rights.")
2055
2056 ! -----------------------------------------------------
2057 ! Initialize parameters about the FITS image
2058 simple=.TRUE.
2059 bitpix=32 ! integer*4
2060 naxis=0 ! no image
2061 naxes(1)=0
2062 extend=.TRUE. ! there is an extension
2063
2064 ! ----------------------
2065 ! primary header
2066 ! ----------------------
2067 ! write the required header keywords
2068 CALL ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
2069
2070 ! writes supplementary keywords : none
2071
2072 ! write the current date
2073 CALL ftpdat(unit,status) ! format ccyy-mm-dd
2074
2075 ! ----------------------
2076 ! image : none
2077 ! ----------------------
2078
2079 ! ----------------------
2080 ! extension
2081 ! ----------------------
2082 else
2083
2084 !*********************************************
2085 ! reopen an existing file and go to the end
2086 !*********************************************
2087 call ftopen(unit,sfilename,1_i4b,blocksize,status)
2088 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
2089
2090 endif
2091
2092 ! creates an extension
2093 CALL ftcrhd(unit, status)
2094
2095 ! writes required keywords
2096 ! if (npix < repeat_tmp) repeat_tmp = npix ! 2015-04-28
2097
2098 ! nrows = npix / repeat_tmp + 1 ! naxis1
2099 nrows = (npix - 1_i8b) / repeat_tmp + 1_i4b ! 2015-04-28
2100 tfields = ntod
2101 WRITE(ch,'(i8)') repeat_tmp
2102 ! tform(1:ntod) = TRIM(ADJUSTL(ch))//pform ! does not work with Ifort, EH, 2006-04-04
2103 ch = TRIM(ADJUSTL(ch))//pform
2104 tform(1:ntod) = ch
2105
2106 ! IF (npix .LT. repeat_tmp) THEN ! 2015-04-28
2107 ! nrows = npix
2108 ! ch = '1'//pform
2109 ! tform(1:ntod) = ch
2110 ! ENDIF
2111 ttype(1:ntod) = 'simulation' ! will be updated
2112 tunit(1:ntod) = '' ! optional, will not appear
2113
2114 extname = '' ! optional, will not appear
2115 varidat = 0
2116
2117 CALL ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
2118 & extname, varidat, status)
2119
2120 ! write the header literally, putting TFORM1 at the desired place
2121 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
2122 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
2123 DO i=1,nlheader
2124 card = header(i)
2125 IF (card(1:5) == 'TTYPE') THEN ! if TTYPE1 is explicitely given
2126 stn = card(6:8)
2127 READ(stn,'(i3)') itn
2128 ! discard at their original location:
2129 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and
2130 status = 0
2131 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
2132 status = 0
2133 if (itn <= tfields) then ! only put relevant information 2008-08-27
2134 call putrec(unit,header(i), status) ! write new TTYPE1
2135 status = 0
2136 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
2137 !CALL ftmcrd(unit,'TTYPE'//stn,'COMMENT',status) ! old TTYPEi and
2138 !CALL ftmcrd(unit,'TFORM'//stn,'COMMENT',status) ! TFORMi
2139 !CALL ftprec(unit,header(i), status) ! write new TTYPE1
2140 !CALL ftpkys(unit,'TFORM'//stn,tform(1),comment,status) ! and write new TFORM1 right after
2141 endif
2142 ELSEIF (header(i).NE.' ') THEN
2143 call putrec(unit,header(i), status)
2144 ! CALL ftprec(unit,header(i), status)
2145 ENDIF
2146 status = 0
2147 ENDDO
2148
2149 ELSE
2150 ! The file already exists
2151 readwrite=1
2152 CALL ftopen(unit,sfilename,readwrite,blocksize,status)
2153 CALL ftmahd(unit,2_i4b+extno_i,hdutype,status)
2154
2155 CALL ftgkys(unit,'TFORM1',tform(1),comment,status)
2156 CALL ftbnfm(tform(1),datacode,repeat_fits,width,status)
2157
2158 IF (repeat_tmp .NE. repeat_fits) THEN
2159 if (present(repeat)) then
2160 write(*,'(a)') code//'> WARNING: In file '//trim(sfilename)
2161 write(*,'(a)') &
2162 & code//'> user provided REPEAT value (' // &
2163 & trim(adjustl(string(repeat_tmp))) // &
2164 & ') differs from value read from file (' // &
2165 & trim(adjustl(string(repeat_fits))) // &
2166 & ').'
2167 write(*,'(a)') code//'> The latter will be used.'
2168 ! else
2169 ! write(*,'(a,i0.0,a)') &
2170 ! & code//'> WARNING: REPEAT value read from file (', &
2171 ! & repeat_fits, &
2172 ! & ') will be used.'
2173 endif
2174 repeat_tmp = repeat_fits
2175 ENDIF
2176
2177 ENDIF
2178
2179
2180 IF (npix .LT. nchunk_max) THEN ! data is small enough to be written in one chunk
2181
2182 frow = (firstpix_tmp)/repeat_tmp + 1
2183 felem = firstpix_tmp-(frow-1)*repeat_tmp + 1
2184 npix_32 = npix
2185
2186 DO colnum = 1, ntod
2187 call f90ftpcl_(unit, colnum, frow, felem, npix_32, tod(0:npix_32-1,colnum), status)
2188 END DO
2189
2190 ELSE ! data has to be written in several chunks
2191
2192 q = (npix-1)/nchunk_max
2193 DO iq = 0,q
2194 IF (iq .LT. q) THEN
2195 npix_tmp = nchunk_max
2196 ELSE
2197 npix_tmp = npix - iq*nchunk_max
2198 ENDIF
2199 i0 = iq*nchunk_max
2200 i1 = i0 + npix_tmp - 1_i8b
2201 firstpix_chunk = firstpix_tmp + i0
2202 frow = (firstpix_chunk)/repeat_tmp + 1
2203 felem = firstpix_chunk-(frow-1)*repeat_tmp + 1
2204 npix_32 = npix_tmp
2205 DO colnum = 1, ntod
2206 call f90ftpcl_(unit, colnum, frow, felem, npix_32, &
2207 & tod(i0:i1, colnum), status)
2208 END DO
2209 ENDDO
2210
2211 ENDIF
2212
2213 ! pad entry if necessary ! 2015-04-28
2214 lastpix = firstpix_tmp + npix ! number of pixels written above
2215 lengap = modulo(lastpix, repeat_tmp) ! remaining gap
2216 if (lengap > 0) then
2217 firstpix_tmp = lastpix
2218 npix_32 = repeat_tmp - lengap
2219 frow = (firstpix_tmp)/repeat_tmp + 1
2220 felem = firstpix_tmp-(frow-1)*repeat_tmp + 1
2221 allocate(padding(0:npix_32-1))
2222 if (KMAP == SP) padding(:) = HPX_SBADVAL
2223 if (KMAP == DP) padding(:) = HPX_DBADVAL
2224 do colnum = 1, ntod
2225 call f90ftpcl_(unit, colnum, frow, felem, npix_32, padding, status)
2226 enddo
2227 deallocate(padding)
2228 endif
2229
2230 ! ----------------------
2231 ! close and exit
2232 ! ----------------------
2233
2234 ! close the file and free the unit number
2235 CALL ftclos(unit, status)
2236
2237 ! check for any error, and if so print out error messages
2238 IF (status .GT. 0) CALL printerror(status)
2239
2240 RETURN
2241
2242 END SUBROUTINE write_bintabh_KLOAD
2243 ! ==============================================================================
2244
2245 !******************************************************************************
2246 !---------------------------------------
2247 ! reads a FITS file containing a list of
2248 ! ring-based or pixel-based quadrature weights
2249 ! and turns it into a (ring-ordered) full sky map
2250 !
2251 ! adapted from unfold_weights.pro
2252 ! 2018-05-25
2253 !---------------------------------------
2254 subroutine unfold_weightsfile_KLOAD(w8file, w8map)
2255
2256 USE pix_tools, only: nside2npix, nside2npweights
2257
2258 character(len=*), intent(in) :: w8file
2259 real(KMAP), intent(out), dimension(0:) :: w8map
2260 real(KMAP), allocatable, dimension(:,:) :: w8list
2261 integer(i4b) :: nside, status, won
2262 integer(i8b) :: nfw8, npw8, nrw8
2263 character(len=*), parameter :: code = 'unfold_weightsfile'
2264
2265 nfw8 = getsize_fits(w8file, nside=nside)
2266 npw8 = nside2npweights(nside)
2267 nrw8 = 2*nside
2268
2269 won = 0
2270 if (nfw8 == nrw8) won = 1
2271 if (nfw8 == npw8) won = 2
2272 if (won == 0) then
2273 print*,'Weights file = '//trim(w8file)
2274 print*,'contains ',nfw8,' weights'
2275 print*,'for Nside = ',nside
2276 print*,'Expected either ',nrw8,' or ',npw8
2277 call fatal_error
2278 endif
2279
2280 allocate(w8list(0:nfw8-1,1:1), stat=status)
2281 call assert_alloc(status,code,"w8list")
2282 call input_map(w8file, w8list, nfw8, 1)
2283 call unfold_weightslist(nside, won, w8list(:,1), w8map)
2284 deallocate(w8list)
2285
2286 return
2287 end subroutine unfold_weightsfile_KLOAD
2288 !---------------------------------------
2289 ! turns a list of ring-based or pixel-based quadrature weights
2290 ! into a (ring-ordered) full sky map
2291 !
2292 ! adapted from unfold_weights.pro
2293 ! 2018-05-18
2294 ! 2018-09-12: promoted qpix to I8B to avoid consistency problems during compilation with g95
2295 !---------------------------------------
2296 subroutine unfold_weightslist_KLOAD(nside, won, w8list, w8map)
2297
2298 USE pix_tools, only: nside2npix, nside2npweights
2299 USE long_intrinsic, only: long_size
2300
2301 integer(i4b), intent(in) :: nside, won
2302 real(KMAP), dimension(0:), intent(in) :: w8list
2303 real(KMAP), dimension(0:), intent(out) :: w8map
2304
2305 integer(i8b) :: np, npix
2306 integer(i8b) :: nf, nw8, pnorth, psouth, vpix, qp4, p, qpix
2307 integer(i4b) :: ring, odd, shifted, rpix, wpix, j4, n4, it
2308
2309 ! test nside
2310 npix = nside2npix(nside)
2311 if (npix <= 0) then
2312 print*,'Unvalid Nside = ',nside
2313 call fatal_error
2314 endif
2315
2316 ! test won
2317 if (won < 1 .or. won > 2) then
2318 print*,'Expected either 1 or 2, got ',won
2319 call fatal_error
2320 endif
2321
2322 ! test input list size
2323 nf = long_size(w8list)
2324 if (won == 1) then
2325 nw8 = 2 * nside
2326 else
2327 nw8 = nside2npweights(nside)
2328 endif
2329 if (nf /= nw8) then
2330 print*,'Expected in input weight list',nw8
2331 print*,'got ',nf
2332 call fatal_error
2333 endif
2334
2335 ! test output map size
2336 np = long_size(w8map)
2337 if (np /= npix) then
2338 print*,'Expected in output weight map',npix
2339 print*,'got ',np
2340 call fatal_error
2341 endif
2342
2343 ! do actual unfolding
2344 if (won == 1) then
2345
2346 pnorth = 0_i8b
2347 n4 = 4 * nside
2348 do ring=1,n4-1 ! loop on all rings
2349 it = min(ring, n4 - ring) ! ring index, counting from closest pole
2350 qp4= 4_i8b * min(it, nside) ! pixels / ring
2351 w8map(pnorth:pnorth+qp4-1) = w8list(it-1)
2352 pnorth = pnorth + qp4
2353 enddo
2354
2355 else
2356
2357 pnorth = 0_i8b ! position in expanded weights
2358 vpix = 0_i8b ! position in compress list
2359 do ring=0, 2*nside-1
2360 qpix = min(ring+1, nside) ! 1/4 of number of pixels per ring
2361 shifted = 0
2362 if (ring < (nside-1) .or. iand(ring+nside,1_i4b) == 1_i4b) shifted = 1
2363 odd = iand(qpix,1_i8b)
2364 qp4 = 4_i8b*qpix ! number of pixels per ring
2365 ! fill the weight map
2366 do p=0,qp4-1
2367 j4 = mod(p, qpix) ! g95: p and qpix must be of same type
2368 rpix = min(j4, qpix - shifted - j4) ! seesaw
2369 w8map(pnorth+p) = w8list(vpix + rpix)
2370 enddo
2371
2372 if (ring < 2*nside-1) then ! south part (except equator)
2373 psouth = npix - pnorth - qp4
2374 w8map(psouth:psouth+qp4-1) = w8map(pnorth:pnorth+qp4-1)
2375 endif
2376 ! locations on next ring
2377 pnorth = pnorth + qp4
2378 wpix = (qpix+1)/2 + 1 - ior(odd, shifted)
2379 vpix = vpix + wpix
2380 enddo
2381 endif
2382
2383 ! add 1 to get final weight
2384 w8map = w8map + 1.0_KMAP
2385
2386 return
2387 end subroutine unfold_weightslist_KLOAD
2388
2389 !=======================================================================
2390 ! read_fits_partial(filename, pixel, cutmap, [header, extno])
2391 ! routine to read FITS file with cut sky data : PIXEL, ?, ?, ?, ?, ...
2392 !=======================================================================
2393 #ifndef NO64BITS
2394 !=======================================================================
2395 subroutine read_fits_partial4_KLOAD(filename, pixel, cutmap, header, extno)
2396 !=======================================================================
2397 use long_intrinsic, only: long_size
2398 character(len=*), intent(in) :: filename
2399 integer(I4B), dimension(0:), intent(out) :: pixel
2400 real(KMAP), dimension(0:,1:), intent(out) :: cutmap
2401 character(len=*), dimension(1:), intent(out), optional :: header
2402 integer(I4B), intent(in), optional :: extno
2403 !
2404 integer(i8b), dimension(:), allocatable :: pixel8
2405 integer(i8b) :: npix
2406 character(len=*), parameter :: code = 'read_fits_partial'
2407 !---------------------------------------------------------------------
2408 npix = long_size(pixel)
2409 if (npix > MAX_I4b) then
2410 call fatal_error(code//': PIXEL must be of type I8B to read '//trim(filename))
2411 endif
2412 allocate(pixel8(0:npix-1))
2413 call read_fits_partial8_KLOAD(filename, pixel8, cutmap, header, extno)
2414 if (maxval(pixel8) > MAX_I4B) then
2415 call fatal_error(code//': PIXEL must be of type I8B to read '//trim(filename))
2416 endif
2417 pixel(0:npix-1) = pixel8(0:npix-1)
2418 deallocate(pixel8)
2419 return
2420
2421 end subroutine read_fits_partial4_KLOAD
2422 #endif
2423 !=======================================================================
2424 subroutine read_fits_partial8_KLOAD(filename, pixel, cutmap, header, extno)
2425 !=======================================================================
2426 use long_intrinsic, only: long_size
2427 character(len=*), intent(in) :: filename
2428 integer(I8B), dimension(0:), intent(out) :: pixel
2429 real(KMAP), dimension(0:,1:), intent(out) :: cutmap
2430 character(len=*), dimension(1:), intent(out), optional :: header
2431 integer(I4B), intent(in), optional :: extno
2432
2433 integer(I8B) :: obs_npix, npixtot, npix
2434
2435 integer(I4B), parameter :: MAXDIM = MAXDIM_TOP !number of columns in the extension
2436 integer(I4B) :: blocksize, datacode
2437 integer(I4B) :: firstpix, frow, hdutype
2438 integer(I4B) :: naxis, nfound, nmove, nrows, nmaps, nmr, i, npix_4
2439 integer(I4B) :: readwrite, status, tfields, unit, varidat, width
2440 integer(I4B) :: repeat, repeat1, repeat2
2441 logical(LGT) :: anynull, extend
2442 character(len=20), dimension(MAXDIM) :: ttype, tform, tunit
2443 character(len=20) :: extname
2444 character(len=80) :: comment
2445 real(KMAP) :: nullval
2446 !=======================================================================
2447
2448 npixtot = min(long_size(pixel),long_size(cutmap,1))
2449 nmaps = size(cutmap,2)
2450 status=0
2451
2452 unit = 150
2453 nfound = -1
2454 anynull = .false.
2455
2456 readwrite=0
2457 call ftopen(unit,filename,readwrite,blocksize,status)
2458 if (status > 0) call printerror(status)
2459
2460 ! determines the presence of image
2461 call ftgkyj(unit,'NAXIS', naxis, comment, status)
2462 if (status > 0) call printerror(status)
2463 if (naxis > 0) then ! there is an image
2464 print*,'an image was found in the FITS file '//filename
2465 print*,'... it is ignored.'
2466 endif
2467
2468 ! determines the presence of an extension
2469 call ftgkyl(unit,'EXTEND', extend, comment, status)
2470 if (status > 0) then
2471 print*,'extension expected and not found in FITS file '//filename
2472 print*,'abort code'
2473 call fatal_error
2474 endif
2475
2476 nmove = +1
2477 if (present(extno)) nmove = +1 + extno
2478 call ftmrhd(unit, nmove, hdutype, status)
2479
2480 call assert (hdutype==2, 'this is not a binary table')
2481
2482 ! reads all the FITS related keywords
2483 call ftghbn(unit, MAXDIM, &
2484 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
2485 & status)
2486
2487 if (.not. (trim(ttype(1)) == 'PIXEL' &
2488 & .or. trim(ttype(1)) == 'PIX' ) ) call fatal_error('did not find PIXEL column in '//filename)
2489
2490
2491 if (present(header)) then
2492 header = ""
2493 status = 0
2494 !call fitstools_mp_get_clean_header(unit, header, filename, status)
2495 call get_clean_header(unit, header, filename, status)
2496 endif
2497
2498 ! if (present(units)) then
2499 ! ! the second column contains the SIGNAL, for which we
2500 ! ! already read the units from the header
2501 ! units = adjustl(tunit(2))
2502 ! endif
2503
2504 ! finds the bad data value
2505 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
2506 if (status == 202) then ! bad_data not found
2507 if (KMAP == SP) nullval = s_bad_value ! default value
2508 if (KMAP == DP) nullval = d_bad_value ! default value
2509 status = 0
2510 endif
2511
2512 frow = 1
2513 firstpix = 1
2514 ! parse TFORM keyword to find out the length of the column vector
2515 repeat1 = 1
2516 repeat2 = 1
2517 call ftbnfm(tform(1), datacode, repeat1, width, status)
2518 if (tfields > 1) call ftbnfm(tform(2), datacode, repeat2, width, status)
2519 repeat = max(repeat1, repeat2)
2520
2521 !call ftgkyj(unit,'OBS_NPIX',obs_npix,comment,status) ! I4B
2522 !call ftgkyk(unit,'OBS_NPIX',obs_npix,comment,status) ! I8B
2523 call f90ftgky_(unit,'OBS_NPIX',obs_npix,comment,status) ! generic
2524 if (status == 202) then ! obs_npix not found
2525 obs_npix = int(nrows, kind=i8b) * repeat
2526 status = 0
2527 endif
2528
2529 npix = min(npixtot, obs_npix)
2530 npix_4 = npix
2531 nmr = min(nmaps, tfields-1)
2532 !call ftgcvj (unit, 1_i4b, frow, firstpix, npix_4, i_bad_value, pixel(0), anynull, status) ! I4B
2533 !call ftgcvk (unit, 1_i4b, frow, firstpix, npix_4, l_bad_value, pixel(0), anynull, status) ! I8B
2534 call f90ftgcv_(unit, 1_i4b, frow, firstpix, npix_4, l_bad_value, pixel, anynull, status) ! generic
2535 do i=1,nmr
2536 call f90ftgcv_(unit, i+1_i4b, frow, firstpix, npix_4, nullval, cutmap(0:npix-1,i), anynull, status)
2537 enddo
2538
2539 ! close the file
2540 call ftclos(unit, status)
2541
2542 ! check for any error, and if so print out error messages
2543 if (status > 0) call printerror(status)
2544
2545 return
2546 end subroutine read_fits_partial8_KLOAD
2547
2548
2549 !=======================================================================
2550 ! writes a fits file for (polarized) sky data set with columns:
2551 ! PIXEL, TEMPERATURE, [Q_POLARISATION, U_POLARISATION]
2552 !
2553 ! write_fits_partial(filename, pixel, cutmap, &
2554 ! [, header, coord, nside, order, units, extno])
2555 !=======================================================================
2556 subroutine write_fits_partial4_KLOAD(filename, pixel, cutmap, &
2557 & header, coord, nside, order, units, extno)
2558 !=======================================================================
2559 character(len=*), intent(in) :: filename
2560 integer(I4B), dimension(0:), intent(in) :: pixel
2561 real(KMAP), dimension(0:,1:), intent(in) :: cutmap
2562 character(len=*), dimension(1:), intent(in), optional :: header
2563 integer(I4B), intent(in), optional :: nside, order
2564 character(len=*), intent(in), optional :: coord, units
2565 integer(I4B), intent(in), optional :: extno !, polarisation
2566 character(len=*), parameter :: routine = 'write_fits_partial'
2567 call sub_write_fits_partial_KLOAD(filename, cutmap, pixel4=pixel, &
2568 header=header, coord=coord, nside=nside, order=order, units=units, extno=extno)
2569 end subroutine write_fits_partial4_KLOAD
2570 !=======================================================================
2571 #ifndef NO64BITS
2572 subroutine write_fits_partial8_KLOAD(filename, pixel, cutmap, &
2573 & header, coord, nside, order, units, extno)
2574 !=======================================================================
2575 character(len=*), intent(in) :: filename
2576 integer(I8B), dimension(0:), intent(in) :: pixel
2577 real(KMAP), dimension(0:,1:), intent(in) :: cutmap
2578 character(len=*), dimension(1:), intent(in), optional :: header
2579 integer(I4B), intent(in), optional :: nside, order
2580 character(len=*), intent(in), optional :: coord, units
2581 integer(I4B), intent(in), optional :: extno !, polarisation
2582 character(len=*), parameter :: routine = 'write_fits_partial'
2583 call sub_write_fits_partial_KLOAD(filename, cutmap, pixel8=pixel, &
2584 header=header, coord=coord, nside=nside, order=order, units=units, extno=extno)
2585 end subroutine write_fits_partial8_KLOAD
2586 #endif
2587 !=======================================================================
2588 subroutine sub_write_fits_partial_KLOAD(filename, cutmap, &
2589 & pixel4, pixel8, &
2590 & header, coord, nside, order, units, extno)
2591 !=======================================================================
2592 use long_intrinsic, only: long_size
2593 use pix_tools, only: nside2npix
2594 use misc_utils, only: assert
2595
2596 character(len=*), intent(in) :: filename
2597 real(KMAP), dimension(0:,1:), intent(in) :: cutmap
2598 integer(I4B), dimension(0:), intent(in), optional :: pixel4
2599 integer(I8B), dimension(0:), intent(in), optional :: pixel8
2600 character(len=*), dimension(1:), intent(in), optional :: header
2601 integer(I4B), intent(in), optional :: nside, order
2602 character(len=*), intent(in), optional :: coord, units
2603 integer(I4B), intent(in), optional :: extno !, polarisation
2604
2605 character(len=*), parameter :: routine = 'write_fits_partial'
2606 ! --- healpix/fits related variables ----
2607 integer(I4B) :: ncol, grain, nd2
2608 integer(I4B) :: npix_hd, nside_hd, i
2609 integer(I4B) :: maxpix, minpix
2610 character(len=1) :: char1, coord_usr
2611 ! character(len=8) :: char8
2612 character(len=20) :: units_usr
2613 logical(LGT) :: done_nside, done_order, done_coord, done_polar, polar_flag
2614 integer(I4B) :: nlheader, extno_i
2615
2616 ! --- cfitsio related variables ----
2617 integer(I4B) :: status, unit, blocksize, bitpix, naxis, naxes(1)
2618 logical(LGT) :: simple, extend
2619 character(LEN=80) :: svalue, comment
2620
2621 integer(I4B), parameter :: MAXDIM = MAXDIM_TOP !number of columns in the extension
2622 integer(I4B) :: nrows, tfields, varidat
2623 integer(I4B) :: frow, felem, repeat, repeatg, hdutype
2624 character(len=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
2625 character(len=20), dimension(1:3) :: extnames
2626 character(len=80) :: card
2627 character(len=4) :: srepeat, srepeatg
2628 character(len=1) :: pform1, pform2
2629 character(len=filenamelen) sfilename
2630 integer(I8B) :: obs_npix8, npix_final, obs_npp
2631 integer(I4B) :: obs_npix4, kpix, nside_final
2632
2633 integer(I4B), save :: nside_old
2634 !=======================================================================
2635 if (KMAP == SP) pform2='E'
2636 if (KMAP == DP) pform2='D'
2637 if (present(pixel4) .eqv. present(pixel8)) then
2638 call fatal_error(routine//': choose either PIXEL4 or PIXEL8')
2639 endif
2640 if (present(pixel4)) then
2641 kpix = I4B
2642 pform1='J'
2643 obs_npp = long_size(pixel4)
2644 elseif (present(pixel8)) then
2645 kpix = I8B
2646 pform1='K'
2647 obs_npp = long_size(pixel8)
2648 endif
2649 obs_npix8 = long_size(cutmap, 1)
2650 nd2 = size(cutmap, 2)
2651 obs_npix4 = int(obs_npix8, kind=I4B)
2652 call assert( obs_npix8 == obs_npp, routine//': mismatched size for PIXEL and DATA')
2653 ncol = 1 + nd2
2654 grain = 1
2655 status=0
2656 unit = 149
2657 blocksize=1
2658
2659 nlheader = 0
2660 if (present(header)) nlheader = size(header)
2661 units_usr = ' '
2662 if (present(units)) units_usr = units
2663 extno_i = 0
2664 if (present(extno)) extno_i = extno
2665 polar_flag = .false.
2666 done_polar = .false.
2667 ! if (present(polarisation)) then
2668 ! polar_flag = (polarisation /= 0)
2669 ! done_polar = .true. ! will ignore the header provided value of POLAR
2670 ! endif
2671
2672 if (extno_i == 0) then
2673 !*************************************
2674 ! create the new empty FITS file
2675 !*************************************
2676 call ftinit(unit,filename,blocksize,status)
2677 if (status > 0) call fatal_error("Error while creating file " &
2678 & //trim(filename) &
2679 & //". Check path and/or access rights.")
2680
2681 ! -----------------------------------------------------
2682 ! initialize parameters about the FITS image
2683 simple=.true.
2684 bitpix=32 ! integer*4
2685 naxis=0 ! no image
2686 naxes(1)=0
2687 extend=.true. ! there is an extension
2688
2689 ! ----------------------
2690 ! primary header
2691 ! ----------------------
2692 ! write the required header keywords
2693 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
2694
2695 ! write the current date
2696 call ftpdat(unit,status) ! format ccyy-mm-dd
2697
2698 else
2699 !*********************************************
2700 ! reopen an existing file and go to the end
2701 !*********************************************
2702 ! remove the leading '!' (if any) when reopening the same file
2703 sfilename = adjustl(filename)
2704 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
2705 call ftopen(unit,sfilename,1_i4b,blocksize,status)
2706 ! move to last extension written
2707 call ftmahd(unit, 1_i4b+ extno_i, hdutype, status)
2708
2709 endif
2710
2711
2712 ! ----------------------
2713 ! new extension
2714 ! ----------------------
2715 call ftcrhd(unit, status)
2716
2717 ! writes required keywords
2718 ! repeat = 1024
2719 repeat = 1
2720 if (obs_npix8 < repeat) repeat = 1
2721 nrows = (obs_npix8 + repeat - 1)/ repeat ! naxis1
2722 write(srepeat,'(i4)') repeat
2723 srepeat = adjustl(srepeat)
2724
2725 repeatg = repeat * grain
2726 write(srepeatg,'(i4)') repeatg
2727 srepeatg = adjustl(srepeatg)
2728
2729 tfields = ncol
2730 ttype(1) = 'PIXEL'
2731 if (nd2 == 1) then
2732 done_polar = .true.
2733 polar_flag = .false.
2734 ttype(2) = 'TEMPERATURE '
2735 elseif (nd2 == 3) then
2736 done_polar = .true.
2737 polar_flag = .true.
2738 ttype(2:4) = (/'TEMPERATURE ' , &
2739 & 'Q_POLARISATION' , &
2740 & 'U_POLARISATION' /)
2741 else
2742 do i=2,ncol
2743 ttype(i) = 'C'//string(i-1, format='(i2.2)') ! C01, C02, ...
2744 enddo
2745 endif
2746
2747 tform(1) = trim(srepeat) //pform1
2748 tform(2:ncol) = trim(srepeatg)//pform2
2749
2750 tunit = ' ' ! optional, will not appear
2751 tunit(2:ncol) = units_usr
2752
2753 extname = 'SKY_OBSERVATION' ! default, will be overridden by user provided one if any
2754 ! if (polar_flag) extname = extnames(1+extno_i)
2755 varidat = 0
2756 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
2757 & extname, varidat, status)
2758
2759 call ftpcom(unit,'------------------------------------------',status)
2760 call ftpcom(unit,' Pixelisation Specific Keywords ',status)
2761 call ftpcom(unit,'------------------------------------------',status)
2762 call ftpkys(unit,'PIXTYPE','HEALPIX ',' HEALPIX Pixelisation',status)
2763 call ftpkyu(unit,'NSIDE', ' ',status) ! place holder, will be updated later on
2764 call ftpkyu(unit,'ORDERING',' ',status)
2765 call ftpkys(unit,'COORDSYS',' ',' ',status)
2766 call ftpcom(unit,' G = Galactic, E = ecliptic, C = celestial = equatorial', status)
2767 call ftpkyl(unit,'POLAR',polar_flag,'Polarisation included in file (T/F)',status)
2768 call ftpcom(unit,'------------------------------------------',status)
2769 call ftpcom(unit,' Data Specific Keywords ',status)
2770 call ftpcom(unit,'------------------------------------------',status)
2771 call ftpkys(unit,'INDXSCHM','EXPLICIT',' Indexing : IMPLICIT or EXPLICIT', status)
2772 ! call ftpkyj(unit,'GRAIN', grain, ' Grain of pixel indexing',status)
2773 ! call ftpcom(unit,'GRAIN=0 : no indexing of pixel data (IMPLICIT)',status)
2774 ! call ftpcom(unit,'GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT)',status)
2775 ! call ftpcom(unit,'GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT)',status)
2776 call ftpkys(unit,'OBJECT','PARTIAL ',' Sky coverage represented by data',status)
2777 if (KPIX == I4B) then
2778 call ftpkyj(unit,'OBS_NPIX',obs_npix4, ' Number of pixels observed and recorded',status)
2779 else
2780 call ftpkyk(unit,'OBS_NPIX',obs_npix8, ' Number of pixels observed and recorded',status)
2781 endif
2782
2783 ! add required Healpix keywords (NSIDE, ORDER) if provided by user
2784 done_order = .false.
2785 if (present(order)) then
2786 ! char8 = order
2787 ! call ftupch(char8)
2788 ! if (char8(1:4) == 'RING') then
2789 if (order == 1) then
2790 call ftukys(unit, 'ORDERING','RING',' Pixel ordering scheme, either RING or NESTED',status)
2791 done_order = .true.
2792 ! elseif (char8(1:4) == 'NEST') then
2793 elseif (order == 2) then
2794 call ftukys(unit, 'ORDERING','NESTED',' Pixel ordering scheme, either RING or NESTED ',status)
2795 done_order = .true.
2796 else
2797 print*,'Invalid ORDER given : ',order, ' instead of 1 (RING) or 2 (NESTED)'
2798 endif
2799 endif
2800
2801 done_nside = .false.
2802 if (present(nside)) then
2803 if (nside2npix(nside) > 0) then ! valid nside
2804 call ftukyj(unit,'NSIDE',nside,' Resolution parameter for HEALPIX', status)
2805 done_nside = .true.
2806 nside_final = nside
2807 else
2808 print*,'Invalid NSIDE given : ',nside
2809 endif
2810 endif
2811
2812 ! add non required Healpix keyword (COORD)
2813 done_coord = .false.
2814 if (present(coord)) then
2815 coord_usr = adjustl(coord)
2816 char1 = coord_usr(1:1)
2817 call ftupch(char1) ! uppercase
2818 if (char1 == 'C' .or. char1 == 'Q') then
2819 coord_usr = 'C'
2820 done_coord = .true.
2821 elseif (char1 == 'G') then
2822 coord_usr = 'G'
2823 done_coord = .true.
2824 elseif (char1 == 'E' ) then
2825 coord_usr='E'
2826 done_coord = .true.
2827 else
2828 print*,'Unrecognised COORD given : ',coord,' instead of C, G, or E'
2829 print*,'Proceed at you own risks '
2830 coord_usr = char1
2831 done_coord = .true.
2832 endif
2833 if (done_coord) then
2834 call ftukys(unit, 'COORDSYS',coord_usr,' Pixelisation coordinate system',status)
2835 endif
2836 endif
2837
2838
2839 ! write the user provided header literally, except for PIXTYPE, TFORM*, TTYPE*, TUNIT*, INDXSCHM and GRAIN
2840 ! copy NSIDE, ORDERING and COORDSYS and POLAR if they are valid and not already given
2841 do i=1,nlheader
2842 card = header(i)
2843 if (card(1:5) == 'TTYPE' .or. card(1:5) == 'TFORM' .or. card(1:7) == 'PIXTYPE') then
2844 continue ! don't keep them
2845 else if (card(1:8) == 'INDXSCHM') then
2846 continue
2847 else if (card(1:5) == 'GRAIN') then ! already written above
2848 continue
2849 else if (card(1:13) == 'COMMENT GRAIN' .or. card(1:14) == 'COMMENT GRAIN') then ! already written above
2850 continue
2851 else if (card(1:5) == 'TUNIT') then
2852 if (trim(units_usr) == '') then
2853 call ftucrd(unit,'TUNIT'//card(6:7),card, status) !update TUNIT2 and above
2854 endif
2855 else if (card(1:5) == 'NSIDE') then
2856 call ftpsvc(card, svalue, comment, status)
2857 read(svalue,*) nside_hd
2858 npix_hd = nside2npix(nside_hd)
2859 if (.not. done_nside .and. npix_hd > 0) then
2860 call ftucrd(unit,'NSIDE',card, status) !update NSIDE
2861 done_nside = .true.
2862 nside_final = nside_hd
2863 endif
2864 else if (card(1:8) == 'ORDERING') then
2865 call ftpsvc(card, svalue, comment, status)
2866 svalue = adjustl(svalue)
2867 svalue = svalue(2:8) ! remove leading quote
2868 call ftupch(svalue)
2869 if (.not. done_order .and. (svalue(1:4)=='RING' .or. svalue(1:6) == 'NESTED')) then
2870 call ftucrd(unit,'ORDERING',card, status) !update ORDERING
2871 done_order = .true.
2872 endif
2873 else if (card(1:8) == 'COORDSYS') then
2874 if (.not. done_coord) call putrec(unit,card, status)
2875 done_coord = .true.
2876 else if (card(1:5) == 'POLAR') then
2877 if (.not. done_polar) then
2878 call ftucrd(unit,'POLAR', card, status) ! update POLAR
2879 done_polar = .true.
2880 endif
2881 else if (card(1:7) == 'EXTNAME') then
2882 call ftucrd(unit, 'EXTNAME', card, status)
2883 else if (card(1:1) /= ' ') then ! if none of the above, copy to FITS file
2884 call putrec(unit, card, status)
2885 endif
2886 10 continue
2887 enddo
2888
2889
2890 ! test that required keywords have been provided in some way
2891 if (.not. done_nside) then
2892 print*,routine//'> NSIDE is a Healpix required keyword, '
2893 print*,routine//'> it was NOT provided either as routine argument or in the input header'
2894 print*,routine//'> abort execution, file not written'
2895 call fatal_error
2896 endif
2897 if (.not. done_order) then
2898 print*,routine//'> ORDER is a Healpix required keyword, '
2899 print*,routine//'> it was NOT provided either as routine argument or in the input header'
2900 print*,routine//'> abort execution, file not written'
2901 call fatal_error
2902 endif
2903 ! if ((.not. done_polar) .and. extno_i >=2) then
2904 ! print*,routine//'> Warning: POLAR keyword not set while 3 extensions have been written'
2905 ! endif
2906
2907 ! check that NSIDE is the same for all extensions
2908 if (extno_i == 0) then
2909 nside_old = nside_final
2910 else
2911 if (nside_final /= nside_old) then
2912 print*,routine//'> Inconsistent NSIDE: ',nside_final, nside_old
2913 print*,routine//'> Should use same NSIDE for all extensions'
2914 endif
2915 endif
2916
2917 ! check validity of PIXEL
2918 npix_final = nside2npix(nside_final)
2919 if (kpix == I4B) then
2920 minpix = minval(pixel4(0:obs_npix8-1))
2921 maxpix = maxval(pixel4(0:obs_npix8-1))
2922 else
2923 minpix = minval(pixel8(0:obs_npix8-1))
2924 maxpix = maxval(pixel8(0:obs_npix8-1))
2925 endif
2926 if (minpix < 0 .or. maxpix > npix_final-1) then
2927 print*,routine//'> Actual pixel range = ',minpix,maxpix
2928 print*,routine//'> expected range (for Nside =',nside_final,') : 0, ',npix_final-1
2929 print*,routine//'> ABORT execution, file not written.'
2930 call fatal_error
2931 endif
2932 if (obs_npix8 > npix_final) then
2933 print*,routine//'> The actual number of pixels ',obs_npix8
2934 print*,routine//'> is larger than the number of pixels over the whole sky : ',npix_final
2935 print*,routine//'> for Nside = ',nside_final
2936 print*,routine//'> ABORT execution, file not written.'
2937 call fatal_error
2938 endif
2939
2940 ! write the extension one column by one column
2941 frow = 1 ! starting position (row)
2942 felem = 1 ! starting position (element)
2943 if (kpix == I4B) then
2944 call f90ftpcl_(unit, 1_i4b, frow, felem, obs_npix4, pixel4, status)
2945 else
2946 call f90ftpcl_(unit, 1_i4b, frow, felem, obs_npix4, pixel8, status)
2947 endif
2948 do i=1, nd2
2949 call f90ftpcl_(unit, i+1_i4b, frow, felem, obs_npix4, cutmap(0:,i), status)
2950 enddo
2951
2952 ! ----------------------
2953 ! close and exit
2954 ! ----------------------
2955
2956 ! close the file and free the unit number
2957 call ftclos(unit, status)
2958
2959 ! check for any error, and if so print out error messages
2960 if (status > 0) call printerror(status)
2961
2962 return
2963 end subroutine sub_write_fits_partial_KLOAD
+0
-2359
src/f90/mod/fits_template.f90 less more
0 !-----------------------------------------------------------------------------
1 !
2 ! Copyright (C) 1997-2013 Krzysztof M. Gorski, Eric Hivon,
3 ! Benjamin D. Wandelt, Anthony J. Banday,
4 ! Matthias Bartelmann, Hans K. Eriksen,
5 ! Frode K. Hansen, Martin Reinecke
6 !
7 !
8 ! This file is part of HEALPix.
9 !
10 ! HEALPix is free software; you can redistribute it and/or modify
11 ! it under the terms of the GNU General Public License as published by
12 ! the Free Software Foundation; either version 2 of the License, or
13 ! (at your option) any later version.
14 !
15 ! HEALPix is distributed in the hope that it will be useful,
16 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ! GNU General Public License for more details.
19 !
20 ! You should have received a copy of the GNU General Public License
21 ! along with HEALPix; if not, write to the Free Software
22 ! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 !
24 ! For more information about HEALPix see http://healpix.sourceforge.net
25 !
26 !-----------------------------------------------------------------------------
27 ! template for routine SP/DP overloading for module fitstools
28 !
29 ! subroutine input_map_KLOAD (4/8)
30 ! subroutine read_bintab_KLOAD (4/8)
31 ! subroutine read_conbintab_KLOAD NotYet
32 ! subroutine write_bintab_KLOAD (4/8)
33 ! subroutine write_asctab_KLOAD NA
34 ! subroutine dump_alms_KLOAD NotYet
35 ! subroutine write_alms_KLOAD NotYet
36 ! subroutine read_alms_KLOAD NotYet
37 ! subroutine read_bintod_KLOAD (8)
38 ! subroutine write_bintabh_KLOAD (8)
39 ! subroutine unfold_weights_KLOAD
40 ! subroutine unfold_weightslist_KLOAD
41 !
42 !
43 ! K M A P : map kind either SP or DP
44 !
45 ! K L O A D : suffixe of routine name, to be replaced by either s (SP) or d (DP)
46 !
47 ! edited Jan 11, 2006 to deal correctly with polarised alms in write_alms and alms2fits
48 ! edited Apr 04, 2006 to avoid concatenation problem in TFORMs (write_plm and write_bintabh with Ifort 9)
49 ! edited Dec 20, 2006 to accept alm file with less elements than expected (in particular if vanishing ones are not included)
50 ! 2007-05-10 : increased maxdim (max number of columns per extension) from 20 to 40
51 ! 2008-08-27 : in dump_alms and write_alms and write_*tab*:
52 ! do not write TTYPE# and TFORM# in excess of # of fields in the file
53 ! 2008-10-14: corrected bug introduced in write_asctab
54 ! 2012-02-23: correction of a possible bug with index writing in dump_alms and write_alms
55 ! 2013-12-13: increased MAXDIM from 40 to MAXDIM_TOP
56 ! 2018-05-22: added unfold_weights, unfold_weightslist
57 ! 2019-10-14: can write TTYPE??? (ie with up to 3 digits) in write_* and dump_alms
58 !
59
60 !=======================================================================
61 ! map_bad_pixels(map, fin, fout, nbads, verbose)
62 ! map: input data (2D)
63 ! fin: input value of 'bad' pixels
64 ! fout: output value of same 'bad' pixels
65 ! nbads: number of bad pixels found
66 ! verbose: OPTIONAL, if set, be verbose
67 !=======================================================================
68
69 subroutine map_bad_pixels_KLOAD(map, fin, fout, nbads, verbose)
70 use long_intrinsic, only: long_size
71 real(KMAP), dimension(0:,1:), intent(inout) :: map
72 real(KMAP), intent(in) :: fin, fout
73 integer(I8B), intent(out) :: nbads
74 logical(LGT), optional, intent(in) :: verbose
75 integer(I8B) :: i, npix
76 integer(I8B), dimension(1:100) :: imiss
77 integer(I4B) :: imap, nmaps
78 logical(LGT) :: be_verbose
79 real(KMAP) :: threshold
80 !-----------------------------------------
81
82 npix = long_size(map, 1)
83 nmaps = long_size(map, 2)
84 threshold = abs(fin * 1.e-5_KMAP)
85
86 imiss(:) = 0
87 do imap = 1, nmaps
88 do i=0,npix-1
89 if ( abs( map(i,imap) - fin ) < threshold ) then
90 map(i,imap) = fout
91 imiss(imap) = imiss(imap)+1
92 endif
93 enddo
94 enddo
95 nbads = sum(imiss)
96
97 be_verbose = .false.
98 if (present(verbose)) be_verbose=verbose
99 if (be_verbose) then
100 write(*,'(a,1pe11.4)') 'blank value : ' ,fin
101 do imap = 1, nmaps
102 if (imiss(imap) > 0) then
103 write(*,'(i12,a,f7.3,a,1pe11.4)') &
104 & imiss(imap),' missing pixels (', &
105 & (100.0_KMAP*imiss(imap))/npix,' %),'// &
106 & ' have been set to : ',fout
107 endif
108 enddo
109 endif
110
111 return
112 end subroutine map_bad_pixels_KLOAD
113 !=======================================================================
114 ! input_map
115 ! reads fits file
116 ! filename = fits file (input)
117 ! map = data read from the file (ouput) = real*4 array of size (npixtot,nmaps)
118 ! npixtot = length of the map (input)
119 ! nmaps = number of maps
120 ! fmissval = OPTIONAL argument (input) with the value to be given to missing
121 ! pixels, its default value is 0
122 ! header = OPTIONAL (output) contains extension header
123 ! units = OPTIONAL (output) contains the maps units
124 ! extno = OPTIONAL (input) contains the unit number to read from (0 based)
125 ! ignore_polcconv = OPTIONAL (input), LGT, default=.false.
126 ! take into account or not the POLCCONV FITS keyword
127 !
128 ! modified Feb 03 for units argument to run with Sun compiler
129 ! 2017-02-15: deals with POLCCONV
130 !=======================================================================
131 #ifndef NO64BITS
132 subroutine input_map4_KLOAD(filename, map, npixtot, nmaps, &
133 & fmissval, header, units, extno, ignore_polcconv)
134 !=======================================================================
135
136 INTEGER(I4B), INTENT(IN) :: npixtot
137 INTEGER(I4B), INTENT(IN) :: nmaps
138 REAL(KMAP), INTENT(OUT), dimension(0:,1:) :: map
139 CHARACTER(LEN=*), INTENT(IN) :: filename
140 REAL(KMAP), INTENT(IN), OPTIONAL :: fmissval
141 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: header
142 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: units
143 INTEGER(I4B), INTENT(IN) , optional :: extno
144 logical(LGT), intent(IN) , optional :: ignore_polcconv
145 integer(i8b) :: npixtot8
146
147 npixtot8 = npixtot
148 call input_map8_KLOAD(filename, map, npixtot8, nmaps, &
149 fmissval, header, units, extno, ignore_polcconv)
150
151 return
152 end subroutine input_map4_KLOAD
153 #endif
154
155 !=======================================================================
156 subroutine input_map8_KLOAD(filename, map, npixtot, nmaps, &
157 fmissval, header, units, extno, ignore_polcconv)
158 !=======================================================================
159 use head_fits, only: get_card, add_card
160 use pix_tools, only: nside2npix
161 INTEGER(I8B), INTENT(IN) :: npixtot
162 INTEGER(I4B), INTENT(IN) :: nmaps
163 REAL(KMAP), INTENT(OUT), dimension(0:,1:) :: map
164 CHARACTER(LEN=*), INTENT(IN) :: filename
165 REAL(KMAP), INTENT(IN), OPTIONAL :: fmissval
166 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: header
167 CHARACTER(LEN=*), INTENT(OUT), dimension(1:), OPTIONAL :: units
168 INTEGER(I4B), INTENT(IN) , optional :: extno
169 logical(LGT), intent(IN) , optional :: ignore_polcconv
170
171 INTEGER(I8B) :: i, imissing, obs_npix, maxpix, minpix
172 REAL(KMAP) :: fmissing, fmiss_effct
173 integer(I4B) :: imap, nlheader
174
175 LOGICAL(LGT) :: anynull, do_polcconv
176 ! Note : read_fits_cut4 still SP and I4B only
177 integer(I4B), dimension(:), allocatable :: pixel
178 ! real(KMAP), dimension(:), allocatable :: signal
179 real(SP), dimension(:), allocatable :: signal
180 integer(I4B) :: status
181 integer(I4B) :: type_fits, nmaps_fits
182 CHARACTER(LEN=80) :: units1
183 CHARACTER(LEN=80),dimension(1:30) :: unitsm
184 character(len=80), dimension(:), allocatable :: hbuffer
185 ! CHARACTER(LEN=80),dimension(:), allocatable :: unitsm
186 integer(I4B) :: extno_i, extno_f
187 CHARACTER(LEN=80) :: polcconv
188 integer(I4B) :: ipolcconv, polar, nside_fits
189 character(len=*), parameter :: primer_url = 'http://healpix.sf.net/pdf/intro.pdf'
190 !-----------------------------------------------------------------------
191
192 units1 = ' '
193 unitsm(:) = ' '
194 fmiss_effct = 0.
195 imissing = 0
196 if (PRESENT(fmissval)) fmiss_effct = fmissval
197 if (PRESENT(header)) then
198 nlheader = size(header)
199 else
200 nlheader = 36*100
201 endif
202 extno_i = 0
203 if (present(extno)) extno_i = extno
204 allocate(hbuffer(1:nlheader))
205 do_polcconv = .true.
206 if (present(ignore_polcconv)) then
207 do_polcconv = .not. ignore_polcconv
208 endif
209
210 obs_npix = getsize_fits(filename, nmaps = nmaps_fits, type=type_fits, extno=extno_i, &
211 polcconv=ipolcconv, polarisation=polar, nside=nside_fits)
212
213 ! if (nmaps_fits > nmaps) then
214 ! print*,trim(filename)//' only contains ',nmaps_fits,' maps'
215 ! print*,' You try to read ',nmaps
216 ! endif
217 if (type_fits == 0 .or. type_fits == 2) then ! full sky map (in image or binary table)
218 call read_bintab(filename, map(0:,1:), &
219 & npixtot, nmaps, fmissing, anynull, header=hbuffer(1:), &
220 & units=unitsm(1:), extno=extno_i)
221 if (present(header)) then
222 do i=1,nlheader
223 header(i) = hbuffer(i)
224 enddo
225 endif
226 if (present(units)) then
227 units(1:size(units)) = unitsm(1:size(units))
228 endif
229 call map_bad_pixels(map, fmissing, fmiss_effct, imissing, verbose=.false.)
230 ! do imap = 1, nmaps
231 ! anynull = .true.
232 ! if (anynull) then
233 ! imissing = 0
234 ! do i=0,npixtot-1
235 ! if ( ABS(map(i,imap)/fmissing -1.) < 1.e-5 ) then
236 ! map(i,imap) = fmiss_effct
237 ! imissing = imissing + 1
238 ! endif
239 ! enddo
240 ! endif
241 ! enddo
242 if (imissing > 0) write(*,'(a,1pe11.4)') 'blank value : ' ,fmissing
243 else if (type_fits == 3 .and. (nmaps == 1 .or. nmaps == 3)) then
244 ! cut sky FITS file, reading 1 map (I) or 3 maps (I,Q,U), each from a different extension
245 do imap = 1, nmaps
246 extno_f = extno_i + imap - 1 ! 2016-08-16
247 obs_npix = getsize_fits(filename, extno = extno_f)
248 ! one partial map (in binary table with explicit pixel indexing)
249 allocate(pixel(0:obs_npix-1), stat = status)
250 allocate(signal(0:obs_npix-1), stat = status)
251 call read_fits_cut4(filename, int(obs_npix,kind=i4b), &
252 & pixel, signal, header=hbuffer, units=units1, extno=extno_f)
253 if (present(header) .and. imap == 1) then
254 do i=1,nlheader
255 header(i) = hbuffer(i)
256 enddo
257 endif
258 if (present(units)) units(imap) = trim(units1)
259 maxpix = maxval(pixel)
260 minpix = maxval(pixel)
261 if (maxpix > (npixtot-1) .or. minpix < 0) then
262 print*,'map constructed from file '//trim(filename)//', with pixels in ',minpix,maxpix
263 print*,' wont fit in array with ',npixtot,' elements'
264 call fatal_error
265 endif
266 map(:,imap) = fmiss_effct
267 map(pixel(:),imap) = signal(:)
268 imissing = npixtot - obs_npix
269 deallocate(signal)
270 deallocate(pixel)
271 enddo
272 else
273 print*,'Unable to read the ',nmaps,' required map(s) from file '//trim(filename)
274 print*,'file type = ',type_fits
275 call fatal_error
276 endif
277 !-----------------------------------------------------------------------
278 if (imissing > 0) then
279 write(*,'(i12,a,f7.3,a,1pe11.4)') &
280 & imissing,' missing pixels (', &
281 & (100.*imissing)/npixtot,' %),'// &
282 & ' have been set to : ',fmiss_effct
283 endif
284
285 ! deallocate(unitsm)
286
287 !-----------------------------------------------------------------------
288 ! deal with polcconv
289 ! print*,'******* in input_map ',nmaps, polar, type_fits, nside_fits
290
291 if ( do_polcconv .and. ( &
292 & (nmaps >= 3 .and. type_fits == 3) & ! cut-sky, multiple maps
293 & .or. &
294 & (nmaps >=3 .and. polar==1 .and. type_fits ==2 .and. &
295 & obs_npix==nside2npix(nside_fits)) & ! full-sky, polarized map
296 & ) ) then
297 if (ipolcconv == 0) then
298 print 9000,' The POLCCONV keyword was not found in '//trim(filename)
299 print 9000,' COSMO (HEALPix default) will be assumed, and map is unchanged.'
300 print 9000,' See HEALPix primer ('//primer_url//') for details.'
301 endif
302 ! if (ipolcconv == 1) then
303 ! print 9000,' POLCCONV=COSMO found in '//trim(filename)//'. Map is unchanged.'
304 ! endif
305 if (ipolcconv == 2) then
306 print 9000,' POLCCONV=IAU found in '//trim(filename)
307 map(:,3) = - map(:,3)
308 if (present(header)) then
309 print 9000,' The sign of the U polarisation is changed in memory,'&
310 & //' and the header is updated.'
311 call add_card(header, 'POLCCONV', 'COSMO', &
312 comment='Changed by input_map', update=.true.)
313 else
314 print 9000,' The sign of the U polarisation is changed in memory.'
315 endif
316 print 9000,' See HEALPix primer ('//primer_url//') for details.'
317 endif
318 if (ipolcconv == 3) then
319 call get_card(hbuffer,'POLCCONV',polcconv)
320 print 9000,' POLCCONV='//trim(polcconv)//' found in '//trim(filename)
321 print 9000,' It is neither COSMO nor IAU. Aborting!'
322 print 9000,' See HEALPix primer ('//primer_url//') for details.'
323 call fatal_error
324 endif
325 endif
326 9000 format(a)
327 if (allocated(hbuffer)) deallocate(hbuffer)
328
329 RETURN
330 END subroutine input_map8_KLOAD
331 !=======================================================================
332 ! Read a FITS file
333 ! This routine is used for reading MAPS by anafast.
334 ! modified Feb 03 for units argument to run with Sun compiler
335 ! Jan 2005, EH, improved for faster writing
336 !=======================================================================
337 #ifndef NO64BITS
338 subroutine read_bintab4_KLOAD(filename, map, npixtot, nmaps, nullval, anynull, header, units, extno)
339 character(len=*), intent(IN) :: filename
340 integer(I4B), intent(IN) :: npixtot
341 integer(I4B), intent(IN) :: nmaps
342 real(KMAP), dimension(0:,1:), intent(OUT) :: map
343 real(KMAP), intent(OUT) :: nullval
344 logical(LGT), intent(OUT) :: anynull
345 character(LEN=*), dimension(1:), optional, intent(OUT) :: header
346 character(LEN=*), dimension(1:), optional, intent(OUT) :: units
347 integer(I4B) , optional, intent(IN) :: extno
348
349 integer(i8b):: npixtot8
350
351 npixtot8 = int(npixtot,kind=i8b)
352 call read_bintab8_KLOAD(filename, map, npixtot8, nmaps, nullval, anynull, header, units, extno)
353 return
354
355 end subroutine read_bintab4_KLOAD
356 #endif
357 subroutine read_bintab8_KLOAD(filename, map, npixtot, nmaps, nullval, anynull, header, units, extno)
358 !=======================================================================
359 character(len=*), intent(IN) :: filename
360 integer(I8B), intent(IN) :: npixtot
361 integer(I4B), intent(IN) :: nmaps
362 real(KMAP), dimension(0:,1:), intent(OUT) :: map
363 real(KMAP), intent(OUT) :: nullval
364 logical(LGT), intent(OUT) :: anynull
365 character(LEN=*), dimension(1:), optional, intent(OUT) :: header
366 character(LEN=*), dimension(1:), optional, intent(OUT) :: units
367 integer(I4B) , optional, intent(IN) :: extno
368
369 integer(I4B) :: nl_header, len_header, nl_units, len_units
370 integer(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
371 integer(I4B) :: group, firstpix, i, npix32
372 real(KMAP) :: blank, testval
373 real(DP) :: bscale,bzero
374 character(len=80) :: comment
375 logical(LGT) :: extend
376 integer(I4B) :: nmove, hdutype, hdunum
377 integer(I4B) :: frow, imap
378 integer(I4B) :: datacode, width
379 LOGICAL(LGT) :: anynull_i
380
381 integer(I4B), parameter :: MAXDIM = MAXDIM_TOP !number of columns in the extension
382 integer(i8b) :: npix_old
383 integer(i8b), dimension(1:MAXDIM) :: npix
384 integer(i8b), dimension(1:MAXDIM) :: i0, i1
385 integer(i4b), dimension(1:MAXDIM) :: repeat
386 integer(i4b) :: nrow2read, nelem
387
388 integer(I4B) :: nrows, tfields, varidat
389 character(len=20), dimension(1:MAXDIM) :: ttype, tform, tunit
390 character(len=20) :: extname
391 character(len=*), parameter :: code='read_bintab'
392 !-----------------------------------------------------------------------
393 status=0
394
395 unit = 146
396 naxes(1) = 1
397 naxes(2) = 1
398 nfound = -1
399 anynull = .false.
400 bscale = 1.0d0
401 bzero = 0.0d0
402 blank = -2.e25
403 nullval = bscale*blank + bzero
404 comment=''
405 ttype=''
406 tform=''
407 tunit=''
408 extname=''
409
410 nl_header = 0
411 if (present(header)) then
412 nl_header = size(header)
413 len_header = 80
414 endif
415
416 nl_units = 0
417 if (present(units)) then
418 nl_units = size(units)
419 len_units = min(80,len(units(1))) ! due to SUN compiler bug
420 endif
421
422 readwrite=0
423 !call ftopen(unit,filename,readwrite,blocksize,status)
424 call ftnopn(unit,filename,readwrite, status) !open primary HDU or specified HDU
425 if (status > 0) call printerror(status)
426 ! -----------------------------------------
427 call ftghdn(unit, hdunum)
428
429 if (hdunum == 1) then ! in primary HDU
430 ! determines the presence of image
431 call ftgkyj(unit,'NAXIS', naxis, comment, status)
432 if (status > 0) call printerror(status)
433
434 ! determines the presence of an extension
435 call ftgkyl(unit,'EXTEND', extend, comment, status)
436 if (status > 0) then
437 extend = .false.
438 status = 0 ! no extension :
439 ! to be compatible with first version of the code
440 endif
441 endif
442
443 if (naxis > 0 .and. .not.extend .and. hdunum==1) then ! there is an image
444 ! determine the size of the image (look naxis1 and naxis2)
445 call ftgknj(unit,'NAXIS',1_i4b,2_i4b,naxes,nfound,status)
446
447 ! check that it found only NAXIS1
448 if (nfound == 2 .and. naxes(2) > 1) then
449 print *,'multi-dimensional image'
450 print *,'expected 1-D data.'
451 call fatal_error
452 end if
453
454 if (nfound < 1) then
455 call printerror(status)
456 print *,'can not find NAXIS1.'
457 call fatal_error
458 endif
459
460 npix(1)=naxes(1)
461 if (npix(1) /= npixtot) then
462 print *,'WARNING: found ',npix(1),' pixels in '//trim(filename)
463 print *,' expected ',npixtot
464 npix(1) = min(npix(1), npixtot)
465 print *,' only ',npix(1),' will be read'
466 endif
467
468 call ftgkyd(unit,'BSCALE',bscale,comment,status)
469 if (status == 202) then ! BSCALE not found
470 bscale = 1.0d0
471 status = 0
472 endif
473 call ftgkyd(unit,'BZERO', bzero, comment,status)
474 if (status == 202) then ! BZERO not found
475 bzero = 0.0d0
476 status = 0
477 endif
478 call f90ftgky_(unit, 'BLANK', blank, comment, status)
479 if (status == 202) then ! BLANK not found
480 ! (according to fitsio BLANK is integer)
481 blank = -2.e25
482 status = 0
483 endif
484 nullval = bscale*blank + bzero
485
486 ! -----------------------------------------
487
488 group=1
489 firstpix = 1
490 npix32 = npix(1)
491 call f90ftgpv_(unit, group, firstpix, npix32, nullval, map(0:npix(1)-1,1), anynull, status)
492 ! if there are any NaN pixels, (real data)
493 ! or BLANK pixels (integer data) they will take nullval value
494 ! and anynull will switch to .true.
495 ! otherwise, switch it by hand if necessary
496 testval = 1.e-6 * ABS(nullval)
497 do i=0, npix(1)-1
498 if (ABS(map(i,1)-nullval) < testval) then
499 anynull = .true.
500 goto 111
501 endif
502 enddo
503 111 continue
504
505 else if (extend .or. hdunum>1) then
506 if (hdunum == 1) then
507 nmove = +1
508 if (present(extno)) nmove = +1 + extno
509 call ftmrhd(unit, nmove, hdutype, status)
510 else
511 call ftghdt(unit, hdutype, status)
512 endif
513
514 call assert (hdutype==2, 'this is not a binary table')
515
516 ! reads all the keywords
517 call ftghbn(unit, MAXDIM, &
518 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
519 & status)
520
521 if (tfields < nmaps) then
522 print *,'found ',tfields,' maps in file '//trim(filename)
523 print *,'expected ',nmaps
524 call fatal_error
525 endif
526
527 ! finds the bad data value
528 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
529 if (status == 202) then ! bad_data not found
530 if (KMAP == SP) nullval = s_bad_value ! default value
531 if (KMAP == DP) nullval = d_bad_value ! default value
532 status = 0
533 endif
534
535 if (nl_header > 0) then
536 do i=1,nl_header
537 header(i)(1:len_header) = ""
538 enddo
539 call get_clean_header(unit, header, filename, status)
540 status = 0
541 endif
542
543 if (nl_units > 0) then
544 do i=1,nl_units
545 units(i)(1:len_units) = 'unknown' ! default
546 enddo
547 do imap = 1, min(nmaps, nl_units)
548 units(imap)(1:len_units) = adjustl(tunit(imap))
549 enddo
550 endif
551
552 npix_old = npixtot
553 do imap = 1, nmaps
554 !parse TFORM keyword to find out the length of the column vector
555 call ftbnfm(tform(imap), datacode, repeat(imap), width, status)
556 npix(imap) = int(nrows,i8b) * repeat(imap)
557 if (npix(imap) /= npixtot .and. npix_old /= npix(imap)) then
558 print *,'WARNING: found ',npix(imap),' pixels in '//trim(filename)//', column ',imap
559 print *,' expected ',npixtot,' or ',npix_old
560 npix_old = npix(imap)
561 npix(imap) = min(npix(imap), npixtot)
562 print *,' only ',npix(imap),' will be read'
563 endif
564 enddo
565
566
567 call ftgrsz(unit, nrow2read, status)
568 nrow2read = max(nrow2read, 1)
569 firstpix = 1 ! starting position in FITS within row, 1 based
570 i0(:) = 0_i8b ! starting element in array, 0 based
571 do frow = 1, nrows, nrow2read
572 do imap = 1, nmaps
573 i1(imap) = min(i0(imap) + int(nrow2read,i8b) * repeat(imap), npix(imap)) - 1_i8b
574 nelem = i1(imap) - i0(imap) + 1
575 call f90ftgcv_(unit, imap, frow, firstpix, nelem, &
576 & nullval, map(i0(imap):i1(imap),imap), anynull_i, status)
577 anynull = anynull .or. anynull_i
578 i0(imap) = i1(imap) + 1_i8b
579 enddo
580 enddo
581 ! sanity check
582 do imap = 1, nmaps
583 if (i0(imap) /= npix(imap)) then
584 call fatal_error('something wrong during piece wise reading')
585 endif
586 enddo
587
588 else ! no image no extension, you are dead, man
589 call fatal_error(' No image, no extension in '//trim(filename))
590 endif
591 ! close the file
592 call ftclos(unit, status)
593
594 ! check for any error, and if so print out error messages
595 if (status > 0) call printerror(status)
596
597 return
598 end subroutine read_bintab8_KLOAD
599
600 !=======================================================================
601 subroutine read_conbintab_KLOAD(filename, alms, nalms, units, extno)
602 !=======================================================================
603 ! Read a FITS file containing alms values
604 !
605 ! slightly modified to deal with vector column
606 ! in binary table EH/IAP/Jan-98
607 !
608 ! Used by synfast when reading a binary file with alms for cons.real.
609 ! FKH/Apr-99
610 !
611 ! extno : optional, number of extension to be read, default=0: first extension
612 ! Jan 2005, EH, improved for faster reading
613 !=======================================================================
614 CHARACTER(LEN=*), INTENT(IN) :: filename
615 INTEGER(I4B), INTENT(IN) :: nalms !, nlheader
616 REAL(KMAP), DIMENSION(0:nalms-1,1:6), INTENT(OUT) :: alms
617 CHARACTER(LEN=*), dimension(1:), optional, INTENT(OUT) :: units
618 INTEGER(I4B) , optional, INTENT(IN) :: extno
619
620 REAL(KMAP) :: nullval
621 LOGICAL(LGT) :: anynull
622
623 INTEGER(I4B), DIMENSION(:), allocatable :: lm
624 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
625 INTEGER(I4B) :: npix
626 CHARACTER(LEN=80) :: comment
627 LOGICAL(LGT) :: extend
628 INTEGER(I4B) :: nmove, hdutype
629 INTEGER(I4B) :: frow, imap
630 INTEGER(I4B) :: datacode, repeat, width
631 integer(I4B) :: i, l, m
632 integer(i4b) :: nrow2read, nelem
633 integer(i8b) :: i0, i1
634
635 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
636 INTEGER(I4B) :: nrows, tfields, varidat
637 CHARACTER(LEN=20), dimension(1:MAXDIM) :: ttype, tform, tunit
638 CHARACTER(LEN=20) :: extname
639 character(len=*), parameter :: code="read_conbintab"
640
641 !-----------------------------------------------------------------------
642 status=0
643
644 unit = 145
645 naxes(1) = 1
646 naxes(2) = 1
647 nfound = -1
648 anynull = .false.
649 alms=0. ! set output to 0.
650 readwrite=0
651 comment=''
652 ttype=''
653 tform=''
654 tunit=''
655 extname=''
656 call ftopen(unit,filename,readwrite,blocksize,status)
657 if (status > 0) call printerror(status)
658 ! -----------------------------------------
659
660 ! determines the presence of image
661 call ftgkyj(unit,'NAXIS', naxis, comment, status)
662 if (status > 0) call printerror(status)
663
664 ! determines the presence of an extension
665 call ftgkyl(unit,'EXTEND', extend, comment, status)
666 if (status > 0) status = 0 ! no extension :
667 ! to be compatible with first version of the code
668
669 if (.not.extend) then
670 print*,'No extension!'
671 call fatal_error
672 endif
673
674 ! go to assigned extension (if it exists)
675 nmove = +1
676 if (present(extno)) nmove = +1 + extno
677 call ftmrhd(unit, nmove, hdutype, status)
678 if (status > 0) then
679 ! if required extension not found:
680 ! print a warning, fill with dummy values, return to calling routine
681 print*,code//' WARNING: the extension ',extno,' was not found in ',trim(filename)
682 alms(0:nalms-1,1)=0. ! l = 0
683 alms(0:nalms-1,2)=1. ! m = 1
684 alms(0:nalms-1,3:6)=0.
685 status = 0
686 call ftclos(unit, status) ! close the file
687 return
688 endif
689
690 if (hdutype /= 2) then ! not a binary table
691 print*, 'this is not a binary table'
692 call fatal_error
693 endif
694
695 ! reads all the keywords
696 call ftghbn(unit, MAXDIM, &
697 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
698 & status)
699
700 if ((tfields/=3).and.(tfields/=5)) then
701 print *,'found ',tfields,' columns in the file'
702 print *,'expected 3 or 5'
703 call fatal_error
704 endif
705 ! finds the bad data value
706 ! if (KMAP == SP) call ftgkye(unit,'BAD_DATA',nullval,comment,status)
707 ! if (KMAP == DP) call ftgkyd(unit,'BAD_DATA',nullval,comment,status)
708 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
709 if (status == 202) then ! bad_data not found
710 if (KMAP == SP) nullval = s_bad_value ! default value
711 if (KMAP == DP) nullval = d_bad_value ! default value
712 status = 0
713 endif
714
715 ! if (nlheader > 0) then
716 ! header = ""
717 ! status = 0
718 ! call get_clean_header(unit, header, filename, status)
719 ! endif
720
721 if (present(units)) then
722 units(1) = tunit(2)
723 endif
724
725 !parse TFORM keyword to find out the length of the column vector
726 call ftbnfm(tform(1), datacode, repeat, width, status)
727 npix = nrows * repeat
728 if (npix /= nalms) then
729 print *,'found ',npix,' alms'
730 print *,'expected ',nalms
731 call fatal_error
732 endif
733
734 call ftgrsz(unit, nrow2read, status)
735 nrow2read = max(nrow2read, 1)
736 nelem = nrow2read * repeat
737 i0 = 0_i8b
738 allocate(lm(0:nelem-1))
739 do frow = 1, nrows, nrow2read
740 i1 = min(i0 + nrow2read * repeat, int(npix,i8b)) - 1_i8b
741 nelem = i1 - i0 + 1
742 ! first column -> index
743 call ftgcvj(unit, 1_i4b, frow, 1_i4b, nelem, i_bad_value, &
744 & lm(0), anynull, status)
745 call assert(.not. anynull, 'There are undefined values in the table!')
746 ! other columns -> a(l,m)
747 do imap = 2, tfields
748 call f90ftgcv_(unit, imap, frow, 1_i4b, nelem, nullval, &
749 & alms(i0:i1,imap+1), anynull, status)
750 call assert (.not. anynull, 'There are undefined values in the table!')
751 enddo
752 ! recoding of the mapping, EH, 2002-08-08
753 ! lm = l*l + l + m + 1
754 do i = i0, i1
755 l = int(sqrt( real(lm(i-i0)-1, kind = DP) ) )
756 m = lm(i-i0) - l*(l+1) - 1
757 ! check that round-off did not screw up mapping
758 if (abs(m) > l) then
759 print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
760 print*,l, m, l*(l+1)+m+1, lm(i-i0)
761 call fatal_error
762 endif
763 alms(i,1) = real( l, kind=KMAP)
764 alms(i,2) = real( m, kind=KMAP)
765 enddo
766 i0 = i1 + 1_i8b
767 enddo
768 deallocate(lm)
769 ! sanity check
770 if (i0 /= npix) then
771 print*,'something wrong during piece-wise reading'
772 call fatal_error
773 endif
774
775 ! !reads the columns
776 ! ! first column : index -> (l,m)
777 ! allocate(lm(0:nalms-1))
778 ! column = 1
779 ! frow = 1
780 ! firstpix = 1
781 ! npix = nrows * repeat
782 ! if (npix /= nalms) then
783 ! print *,'found ',npix,' alms'
784 ! print *,'expected ',nalms
785 ! call fatal_error
786 ! endif
787 ! call ftgcvj(unit, column, frow, firstpix, npix, i_bad_value, &
788 ! & lm(0), anynull, status)
789 ! call assert (.not. anynull, 'There are undefined values in the table!')
790 ! ! recoding of the mapping, EH, 2002-08-08
791 ! ! lm = l*l + l + m + 1
792 ! do i = 0, nalms - 1
793 ! l = int(sqrt( real(lm(i)-1, kind = DP) ) )
794 ! m = lm(i) - l*(l+1) - 1
795 ! ! check that round-off did not screw up mapping
796 ! if (abs(m) > l) then
797 ! print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
798 ! print*,l, m, l*(l+1)+m+1, lm(i)
799 ! call fatal_error
800 ! endif
801 ! alms(i,1) = real( l, kind=KMAP )
802 ! alms(i,2) = real( m, kind=KMAP )
803 ! enddo
804 ! deallocate(lm)
805 !
806 ! do imap = 2, tfields
807 ! !parse TFORM keyword to find out the length of the column vector
808 ! call ftbnfm(tform(imap), datacode, repeat, width, status)
809 !
810 ! !reads the columns
811 ! column = imap
812 ! frow = 1
813 ! firstpix = 1
814 ! npix = nrows * repeat
815 ! if (npix /= nalms) then
816 ! print *,'found ',npix,' alms'
817 ! print *,'expected ',nalms
818 ! call fatal_error
819 ! endif
820 ! call f90ftgcv_(unit, column, frow, firstpix, npix, nullval, &
821 ! & alms(0:npix-1,imap+1), anynull, status)
822 ! call assert (.not. anynull, 'There are undefined values in the table!')
823 ! enddo
824 ! close the file
825 call ftclos(unit, status)
826
827
828 ! check for any error, and if so print out error messages
829 if (status > 0) call printerror(status)
830 return
831 end subroutine read_conbintab_KLOAD
832
833 #ifndef NO64BITS
834 subroutine write_bintab4_KLOAD(map, npix, nmap, header, nlheader, filename, extno)
835 !=======================================================================
836 INTEGER(I4B), INTENT(IN) :: npix, nmap, nlheader
837 REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap) :: map
838 CHARACTER(LEN=*), INTENT(IN), DIMENSION(1:nlheader) :: header
839 CHARACTER(LEN=*), INTENT(IN) :: filename
840 INTEGER(I4B) , INTENT(IN), optional :: extno
841
842 integer(i8b) :: npix8
843
844 npix8 = npix
845 if (present(extno)) then
846 call write_bintab8_KLOAD(map, npix8, nmap, header, nlheader, filename, extno)
847 else
848 call write_bintab8_KLOAD(map, npix8, nmap, header, nlheader, filename)
849 endif
850 return
851 end subroutine write_bintab4_KLOAD
852 #endif
853
854 subroutine write_bintab8_KLOAD(map, npix, nmap, header, nlheader, filename, extno)
855 !=======================================================================
856 ! Create a FITS file containing a binary table extension with
857 ! the temperature map in the first column
858 ! written by EH from writeimage and writebintable
859 ! (fitsio cookbook package)
860 !
861 ! slightly modified to deal with vector column (ie TFORMi = '1024E')
862 ! in binary table EH/IAP/Jan-98
863 !
864 ! simplified the calling sequence, the header sould be filled in
865 ! before calling the routine
866 !
867 ! July 21, 2004: SP version
868 ! Jan 2005, EH, improved for faster writing
869 ! 2009-02-25: EH, accepts I4B and I8B npix
870 !=======================================================================
871 use pix_tools, only: npix2nside
872 INTEGER(I8B), INTENT(IN) :: npix
873 INTEGER(I4B), INTENT(IN) :: nmap, nlheader
874 ! REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap), target :: map
875 REAL(KMAP), INTENT(IN), DIMENSION(0:npix-1,1:nmap) :: map
876 CHARACTER(LEN=*), INTENT(IN), DIMENSION(1:nlheader) :: header
877 CHARACTER(LEN=*), INTENT(IN) :: filename
878 INTEGER(I4B) , INTENT(IN), optional :: extno
879
880 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
881 INTEGER(I4B) :: i, nside
882 LOGICAL(LGT) :: simple,extend
883 CHARACTER(LEN=80) :: comment, ch
884
885 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
886 INTEGER(I4B) :: nrows, tfields, varidat
887 integer(i4b) :: repeat, nrow2write, nelem
888 integer(i8b) :: i0, i1
889 INTEGER(I4B) :: frow, felem, colnum, hdutype
890 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
891 CHARACTER(LEN=10) :: card
892 CHARACTER(LEN=2) :: stn
893 INTEGER(I4B) :: itn, extno_i
894 character(len=filenamelen) sfilename
895 character(len=1) :: pform
896 ! character(len=80) :: junk_k, junk_v, junk_c
897 !-----------------------------------------------------------------------
898
899 if (KMAP == SP) pform = 'E'
900 if (KMAP == DP) pform = 'D'
901 status=0
902 unit = 144
903 blocksize=1
904
905 extno_i = 0
906 if (present(extno)) extno_i = extno
907
908 if (extno_i == 0) then
909 !*************************************
910 ! create the new empty FITS file
911 !*************************************
912 call ftinit(unit,filename,blocksize,status)
913 if (status > 0) call fatal_error("Error while creating file " &
914 & //trim(filename) &
915 & //". Check path and/or access rights.")
916
917 ! -----------------------------------------------------
918 ! initialize parameters about the FITS image
919 simple=.true.
920 bitpix=32 ! integer*4
921 naxis=0 ! no image
922 naxes(1)=0
923 extend=.true. ! there is an extension
924
925 ! ----------------------
926 ! primary header
927 ! ----------------------
928 ! write the required header keywords
929 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
930
931 ! writes supplementary keywords : none
932
933 ! write the current date
934 call ftpdat(unit,status) ! format (yyyy-mm-dd)
935
936 ! ----------------------
937 ! image : none
938 ! ----------------------
939
940 ! ----------------------
941 ! extension
942 ! ----------------------
943 else
944
945 !*********************************************
946 ! reopen an existing file and go to the end
947 !*********************************************
948 ! remove the leading '!' (if any) when reopening the same file
949 sfilename = adjustl(filename)
950 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
951 call ftopen(unit,sfilename,1_i4b,blocksize,status)
952 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
953
954 endif
955
956 ! creates an extension
957 call ftcrhd(unit, status)
958
959 ! writes required keywords
960 tfields = nmap
961 repeat = 1024
962 if (npix < 1024) repeat = 1 ! for nside <= 8
963 ! for large npix increase repeat so that nrows < 2^31-1
964 nside = npix2nside(npix)
965 if (nside > 1024*256) repeat = nside/256
966 nrows = npix / repeat ! naxis1
967 ch = string(repeat, format='(i8)')
968 ch = trim(adjustl(ch))//pform
969 tform(1:nmap) = ch
970 ttype(1:nmap) = 'simulation' ! will be updated
971 tunit(1:nmap) = '' ! optional, will not appear
972 extname = '' ! optional, will not appear
973 varidat = 0
974 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
975 & extname, varidat, status)
976
977 ! write the header literally, putting TFORM1 and TUNIT1 at the desired place
978 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
979 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
980 do i=1,nlheader
981 card = header(i)
982 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
983 stn = card(6:8)
984 read(stn,'(i3)') itn
985 ! discard at their original location:
986 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and
987 status = 0
988 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
989 status = 0
990 if (itn <= tfields) then ! only put relevant information 2008-08-27
991 call putrec(unit,header(i), status) ! write new TTYPE1
992 status = 0
993 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
994 endif
995 elseif (header(i)/=' ') then
996 call putrec(unit,header(i), status)
997 endif
998 status = 0
999 enddo
1000
1001 ! write the extension buffer by buffer
1002 call ftgrsz(unit, nrow2write, status)
1003 nrow2write = max(nrow2write, 1)
1004 felem = 1 ! starting position in FITS (element), 1 based
1005 i0 = 0_i8b ! starting element in array, 0 based
1006 do frow = 1, nrows, nrow2write
1007 i1 = min(i0 + nrow2write * repeat, npix) - 1_i8b
1008 nelem = i1 - i0 + 1
1009 do colnum = 1, nmap
1010 call f90ftpcl_(unit, colnum, frow, felem, nelem, map(i0:i1, colnum), status)
1011 enddo
1012 i0 = i1 + 1_i8b
1013 enddo
1014 ! sanity check
1015 if (i0 /= npix) then
1016 call fatal_error("something wrong during piece wise writing")
1017 endif
1018
1019 ! ----------------------
1020 ! close and exit
1021 ! ----------------------
1022
1023 ! close the file and free the unit number
1024 call ftclos(unit, status)
1025
1026 ! check for any error, and if so print out error messages
1027 if (status > 0) call printerror(status)
1028
1029 return
1030 end subroutine write_bintab8_KLOAD
1031 !=======================================================================
1032 subroutine write_asctab_KLOAD &
1033 & (clout, lmax, ncl, header, nlheader, filename, extno)
1034 !=======================================================================
1035 ! Create a FITS file containing an ASCII table extension with
1036 ! the measured power spectra
1037 ! written by EH from writeimage and writeascii
1038 ! (fitsio cookbook package)
1039 !
1040 ! clout = power spectra with l in (0:lmax)
1041 ! ncl = number of spectra
1042 ! header = FITS header to be put on top of the file
1043 ! nlheader = number of lines of the header
1044 ! filename = FITS output file name
1045 !
1046 ! 2015-09-10: EH, added extno
1047 !=======================================================================
1048 !
1049 INTEGER(I4B), INTENT(IN) :: lmax, ncl,nlheader
1050 REAL(KMAP), INTENT(IN) :: clout(0:lmax,1:ncl)
1051 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1052 CHARACTER(LEN=*), INTENT(IN) :: filename
1053 INTEGER(I4B) , INTENT(IN), optional :: extno
1054
1055 INTEGER(I4B) :: bitpix,naxis,naxes(1)
1056 LOGICAL(LGT) :: simple,extend
1057 CHARACTER(LEN=10) :: card
1058
1059 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP
1060 INTEGER(I4B) :: status,unit,blocksize,tfields,nrows,rowlen
1061 INTEGER(I4B) :: nspace,tbcol(MAXDIM),colnum,frow,felem,hdutype
1062 CHARACTER(LEN=16) :: ttype(MAXDIM),tform(MAXDIM),tunit(MAXDIM),extname
1063 CHARACTER(LEN=80) :: comment, card_tbcol
1064 CHARACTER(LEN=2) :: stn
1065 INTEGER(I4B) :: itn, i, extno_i
1066 character(len=filenamelen) sfilename
1067 character(len=6) :: form
1068 !=======================================================================
1069 if (KMAP == SP) form = 'E15.7'
1070 if (KMAP == DP) form = 'D24.15'
1071 status=0
1072 unit = 109
1073 blocksize=1
1074
1075 extno_i = 0
1076 if (present(extno)) extno_i = extno
1077
1078 if (extno_i == 0) then
1079 call ftinit(unit,filename,blocksize,status)
1080 if (status > 0) call fatal_error("Error while creating file " &
1081 & //trim(filename) &
1082 & //". Check path and/or access rights.")
1083
1084 ! -----------------------------------------------------
1085 ! initialize parameters about the FITS image
1086 simple=.true.
1087 bitpix=32 ! integer*4
1088 naxis=0 ! no image
1089 naxes(1)=0
1090 extend=.true. ! there is an extension
1091
1092 ! ----------------------
1093 ! primary header
1094 ! ----------------------
1095 ! write the required header keywords
1096 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1097
1098 ! writes supplementary keywords : none
1099
1100 ! write the current date
1101 call ftpdat(unit,status) ! (format ccyy-mm-dd)
1102
1103 ! ----------------------
1104 ! image : none
1105 ! ----------------------
1106
1107 ! ----------------------
1108 ! extension
1109 ! ----------------------
1110 else
1111 !*********************************************
1112 ! reopen an existing file and go to the end
1113 !*********************************************
1114 ! remove the leading '!' (if any) when reopening the same file
1115 sfilename = adjustl(filename)
1116 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1117 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1118 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
1119
1120 endif
1121
1122 ! append a new empty extension onto the end of the primary array
1123 call ftcrhd(unit,status)
1124
1125 ! define parameters for the ASCII table
1126 nrows = lmax+1
1127 tfields = ncl
1128 tform(1:ncl) = form
1129 ttype(1:ncl) = 'power spectrum' ! is updated by the value given in the header
1130 tunit(1:ncl) = '' ! optional, will not appear
1131 extname = '' ! optional, will not appear
1132
1133 ! calculate the starting position of each column, and the total row length
1134 nspace=1
1135 call ftgabc(tfields,tform,nspace,rowlen,tbcol,status)
1136
1137 ! write the required header parameters for the ASCII table
1138 call ftphtb(unit,rowlen,nrows,tfields,ttype,tbcol,tform,tunit, &
1139 & extname,status)
1140
1141 ! write the header literally, putting TFORM1 at the desired place
1142 comment = ''
1143 card_tbcol=''
1144 do i=1,nlheader
1145 card = header(i)
1146 if (card(1:5) == 'TTYPE') then ! if TTYPE1 is explicitely given
1147 stn = card(6:8)
1148 read(stn,'(i3)') itn
1149 ! discard at their original location:
1150 !!!!!!!call ftdkey(unit,card(1:6),status) ! old TTYPEi 2019-10-14
1151 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi
1152 status = 0
1153 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1154 status = 0
1155 call ftgcrd(unit,'TBCOL'//stn,card_tbcol,status)
1156 status = 0
1157 call ftdkey(unit,'TBCOL'//stn,status) ! TBCOLi
1158 status = 0
1159 ! and rewrite
1160 if (itn <= tfields) then
1161 call putrec(unit,card_tbcol,status) ! TBCOLi
1162 status = 0
1163 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! TFORMi right after
1164 status = 0
1165 call putrec(unit,header(i), status) ! TTYPEi
1166 endif
1167 elseif (header(i)/=' ') then
1168 call putrec(unit,header(i), status)
1169 endif
1170 status = 0
1171 enddo
1172
1173 frow=1
1174 felem=1
1175 do colnum = 1, ncl
1176 call f90ftpcl_(unit, colnum, frow, felem, nrows, clout(0:nrows-1,colnum), status)
1177 enddo
1178
1179 ! close the FITS file
1180 call ftclos(unit, status)
1181
1182 ! check for any error, and if so print out error messages
1183 if (status > 0) call printerror(status)
1184
1185 return
1186 end subroutine write_asctab_KLOAD
1187 !=======================================================================
1188 ! DUMP_ALMS
1189 !
1190 ! Create/extend a FITS file containing a binary table extension with
1191 ! the a_lm coefficients in each extension.
1192 !
1193 ! Format of alm FITS file: in each extension, 3 columns:
1194 ! index=l*l+l+m+1, real(a_lm), imag(a_lm)
1195 ! the a_lm are obtained using the complex Y_lm
1196 ! only the modes with m>=0 are stored (because the map is assumed real)
1197 !
1198 ! The extensions contain, in general, T, E (= G) and B (= C) in that order
1199 ! First extension has extno = 0
1200 !
1201 ! Adapted from write_bintab, FKH/Apr-99
1202 ! SP/DP overloaded, 2004-12, EH
1203 ! reduced size of intermediate arrays (alms_out, lm)
1204 !
1205 subroutine dump_alms_KLOAD(filename, alms, nlmax, header, nlheader, extno)
1206 !=======================================================================
1207 INTEGER(I4B), INTENT(IN) :: nlmax, nlheader, extno
1208 COMPLEX(KMAPC), INTENT(IN), DIMENSION(0:,0:) :: alms
1209 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1210 CHARACTER(LEN=*), INTENT(IN) :: filename
1211 ! local variables
1212 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1213 REAL(KMAP), DIMENSION(:,:), allocatable :: alms_out
1214 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
1215 INTEGER(I4B) :: i,l,m,cnt,hdutype, nmmax
1216 LOGICAL(LGT) :: simple,extend, found_lmax, found_mmax
1217 CHARACTER(LEN=80) :: comment
1218
1219 integer(i8b) :: npix
1220 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1221 INTEGER(I4B) :: nrows, tfields, varidat
1222 INTEGER(I4B) :: frow, felem
1223 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1224 CHARACTER(LEN=10) :: card
1225 CHARACTER(LEN=2) :: stn
1226 INTEGER(I4B) :: itn
1227 character(len=filenamelen) sfilename
1228 character(len=1) :: pform
1229 character(len=*), parameter :: code = 'dump_alms'
1230 !-----------------------------------------------------------------------
1231
1232 if (KMAP == SP) pform = 'E'
1233 if (KMAP == DP) pform = 'D'
1234
1235 nmmax = size(alms,2) - 1
1236 if (nmmax < 0 .or. nmmax > nlmax) call fatal_error('inconsistent Lmax and Mmax in dump_alms')
1237 !! npix=((nlmax+1)*(nlmax+2))/2
1238 npix = ((nmmax+1_i8b)*(2_i8b*nlmax-nmmax+2))/2
1239 if (npix > MAX_I4B .or. nlmax >= int(sqrt(real(MAX_I4B,kind=dp)))) then
1240 print*,code//'> Index of a_lm too large for current file format,'
1241 print*,code//'> '//trim(filename)//' not written.'
1242 call fatal_error
1243 endif
1244
1245 status=0
1246 unit = 141
1247 blocksize=1
1248
1249 if (extno==0) then
1250 !*********************************************
1251 ! create the new empty FITS file
1252 !*********************************************
1253 call ftinit(unit,filename,blocksize,status)
1254 if (status > 0) call fatal_error("Error while creating file " &
1255 & //trim(filename) &
1256 & //". Check path and/or access rights.")
1257
1258 ! -----------------------------------------------------
1259 ! initialize parameters about the FITS image
1260 simple=.true.
1261 bitpix=32 ! integer*4
1262 naxis=0 ! no image
1263 naxes(1)=0
1264 extend=.true. ! there is an extension
1265
1266 ! ----------------------
1267 ! primary header
1268 ! ----------------------
1269 ! write the required header keywords
1270 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1271
1272 ! writes supplementary keywords : none
1273
1274 ! write the current date
1275 call ftpdat(unit,status) ! format (yyyy-mm-dd)
1276
1277 ! ----------------------
1278 ! image : none
1279 ! extension
1280 ! ----------------------
1281 else
1282
1283 !*********************************************
1284 ! reopen an existing file and go to the end
1285 !*********************************************
1286 ! remove the leading '!' (if any) when reopening the same file
1287 sfilename = adjustl(filename)
1288 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1289 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1290 call ftmahd(unit,1_i4b+extno,hdutype,status)
1291
1292 endif
1293
1294 ! creates an extension
1295 call ftcrhd(unit, status)
1296
1297 ! writes required keywords
1298 nrows = npix ! naxis1
1299 tfields = 3
1300 tform = '' ; ttype = '' ; tunit = ''
1301 tform(1)(1:2)= '1J' ! necessary with ifort 11.1.076
1302 tform(2)(1:2) = '1'//pform
1303 tform(3)(1:2) = '1'//pform
1304 ttype(1)(1:15) = 'index=l^2+l+m+1'
1305 ttype(2)(1:15) = 'alm (real) '
1306 ttype(3)(1:15) = 'alm (imaginary)'
1307 tunit(1:3) = '' ! optional, will not appear
1308 extname = '' ! optional, will not appear
1309 varidat = 0
1310 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
1311 & extname, varidat, status)
1312
1313 ! write the header literally, putting TFORM1 at the desired place
1314 do i=1,nlheader
1315 card = header(i)
1316 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
1317 stn = card(6:8)
1318 read(stn,'(i3)') itn
1319 ! discard at their original location:
1320 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and ! remove
1321 status = 0
1322 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1323 status = 0
1324 if (itn <= tfields) then ! only put relevant information 2008-08-27
1325 call putrec(unit,header(i), status) ! write new TTYPEi
1326 status = 0
1327 if (itn==1) then
1328 comment = 'data format of field: 4-byte INTEGER'
1329 else
1330 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
1331 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
1332 endif
1333 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
1334 endif
1335 elseif (header(i)/=' ') then
1336 call putrec(unit,header(i), status)
1337 endif
1338 status = 0
1339 enddo
1340
1341 call ftukyj(unit, 'MIN-LPOL', 0_i4b, 'Minimum L multipole order', status)
1342 call ftukyj(unit, 'MAX-LPOL', nlmax, 'Maximum L multipole order', status)
1343 call ftukyj(unit, 'MAX-MPOL', nmmax, 'Maximum M multipole degree', status)
1344
1345 allocate(lm (0:nmmax))
1346 allocate(alms_out(0:nmmax,1:2))
1347 ! write the extension one column by one column
1348 frow = 1 ! starting position (row)
1349 felem = 1 ! starting position (element)
1350 do l = 0, nlmax
1351 cnt = 0
1352 do m = 0, min(l,nmmax)
1353 lm(cnt) = l**2 + l + m + 1
1354 alms_out(cnt,1)=REAL( alms(l,m))
1355 alms_out(cnt,2)=AIMAG(alms(l,m))
1356 cnt = cnt + 1
1357 enddo
1358 call ftpclj( unit, 1_i4b, frow, felem, cnt, lm, status)
1359 call f90ftpcl_(unit, 2_i4b, frow, felem, cnt, alms_out(0:cnt-1,1), status)
1360 call f90ftpcl_(unit, 3_i4b, frow, felem, cnt, alms_out(0:cnt-1,2), status)
1361 frow = frow + cnt
1362 enddo
1363 deallocate(lm)
1364 deallocate(alms_out)
1365
1366 ! ----------------------
1367 ! close and exit
1368 ! ----------------------
1369
1370 ! close the file and free the unit number
1371 call ftclos(unit, status)
1372
1373 ! check for any error, and if so print out error messages
1374 if (status > 0) call printerror(status)
1375
1376
1377 return
1378 end subroutine dump_alms_KLOAD
1379 !=======================================================================
1380 subroutine write_alms_KLOAD(filename, nalms, alms, ncl, header, nlheader, extno)
1381 !=======================================================================
1382 ! Writes alms from to binary FITS file, FKH/Apr-99
1383 ! ncl is the number of columns, in the output fits file,
1384 ! either 3 or 5 (with or without errors respectively)
1385 !
1386 ! input array (real) FITS file
1387 ! alms(:,1) = l )
1388 ! alms(:,2) = m )---> col 1: l*l+l+m+1
1389 ! alms(:,3) = real(a_lm) ---> col 2
1390 ! alms(:,4) = imag(a_lm) ---> col 3
1391 ! alms(:,5) = real(delta a_lm) ---> col 4
1392 ! alms(:,6) = imag(delta a_lm) ---> col 5
1393 !
1394 !=======================================================================
1395
1396 INTEGER(I4B), INTENT(IN) :: nalms, nlheader, ncl, extno
1397 REAL(KMAP), INTENT(IN), DIMENSION(0:nalms-1,1:(ncl+1)) :: alms
1398 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1399 CHARACTER(LEN=*), INTENT(IN) :: filename
1400
1401 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1402 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1)
1403 INTEGER(I4B) :: i,hdutype, lmax, mmax, lmin
1404 LOGICAL(LGT) :: simple,extend
1405 CHARACTER(LEN=80) :: comment
1406
1407 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1408 INTEGER(I4B) :: nrows, npix, tfields, varidat, repeat
1409 INTEGER(I4B) :: frow, felem, colnum, stride, istart, iend, k
1410 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1411 CHARACTER(LEN=10) :: card
1412 CHARACTER(LEN=2) :: stn
1413 INTEGER(I4B) :: itn
1414 integer(I4B) :: l, m
1415 character(len=filenamelen) sfilename
1416 character(len=1) :: pform
1417 !-----------------------------------------------------------------------
1418
1419 if (KMAP == SP) pform = 'E'
1420 if (KMAP == DP) pform = 'D'
1421
1422 status=0
1423 unit = 140
1424
1425 ! create the new empty FITS file
1426 blocksize=1
1427
1428 if (extno==1) then
1429
1430 call ftinit(unit,filename,blocksize,status)
1431 if (status > 0) call fatal_error("Error while creating file " &
1432 & //trim(filename) &
1433 & //". Check path and/or access rights.")
1434
1435 ! -----------------------------------------------------
1436 ! initialize parameters about the FITS image
1437 simple=.true.
1438 bitpix=32 ! integer*4
1439 naxis=0 ! no image
1440 naxes(1)=0
1441 extend=.true. ! there is an extension
1442
1443 ! ----------------------
1444 ! primary header
1445 ! ----------------------
1446 ! write the required header keywords
1447 call ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
1448
1449 ! writes supplementary keywords : none
1450
1451 ! write the current date
1452 call ftpdat(unit,status) ! format ccyy-mm-dd
1453
1454 ! ----------------------
1455 ! image : none
1456 ! ----------------------
1457
1458 ! ----------------------
1459 ! extension
1460 ! ----------------------
1461
1462 else
1463
1464 !*********************************************
1465 ! reopen an existing file and go to the end
1466 !*********************************************
1467 ! remove the leading '!' (if any) when reopening the same file
1468 sfilename = adjustl(filename)
1469 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
1470 call ftopen(unit,sfilename,1_i4b,blocksize,status)
1471 call ftmahd(unit,extno,hdutype,status)
1472
1473 endif
1474
1475 ! creates an extension
1476 call ftcrhd(unit, status)
1477
1478 ! writes required keywords
1479 nrows = nalms ! naxis1
1480 tfields = ncl
1481 repeat = 1
1482 tform(1)(1:2)='1J' ! necessary with ifort 11.1.076
1483 do i=2, ncl
1484 tform(i)(1:2) = '1'//pform
1485 enddo
1486 ttype(1)(1:15) = 'index=l^2+l+m+1'
1487 ttype(2)(1:15) = 'alm (real) '
1488 ttype(3)(1:15) = 'alm (imaginary)'
1489 if (ncl>3) then
1490 ttype(4)(1:17) = 'error (real) '
1491 ttype(5)(1:17) = 'error (imaginary)'
1492 endif
1493 tunit(1:ncl) = '' ! optional, will not appear
1494 extname = '' ! optional, will not appear
1495 varidat = 0
1496 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
1497 & extname, varidat, status)
1498
1499 ! write the header literally, putting TFORMi at the desired place
1500 do i=1,nlheader
1501 card = header(i)
1502 if (card(1:5) == 'TTYPE') then ! if TTYPEi is explicitely given
1503 stn = card(6:8)
1504 read(stn,'(i3)') itn
1505 ! discard at their original location:
1506 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and ! remove
1507 status = 0
1508 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
1509 status = 0
1510 if (itn <= tfields) then ! only put relevant information 2008-08-27
1511 call putrec(unit,header(i), status) ! write new TTYPE1
1512 status = 0
1513 if (itn==1) then
1514 comment = 'data format of field: 4-byte INTEGER'
1515 else
1516 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
1517 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
1518 endif
1519 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
1520 endif
1521 elseif (header(i)/=' ') then
1522 call putrec(unit,header(i), status)
1523 endif
1524 status = 0
1525 enddo
1526
1527 lmax = nint(maxval(alms(:,1)))
1528 lmin = nint(minval(alms(:,1)))
1529 mmax = nint(maxval(alms(:,2)))
1530 call ftukyj(unit, 'MIN-LPOL', lmin, 'Minimum L multipole order', status)
1531 call ftukyj(unit, 'MAX-LPOL', lmax, 'Maximum L multipole order', status)
1532 call ftukyj(unit, 'MAX-MPOL', mmax, 'Maximum M multipole degree', status)
1533
1534 ! write the extension by blocks of rows ! EH, Dec 2004
1535 felem = 1 ! starting position (element)
1536 !!! stride = 1000 ! 1000 rows at a time
1537 call ftgrsz(unit, stride, status) ! find optimal stride in rows
1538 stride = max( stride, 1)
1539 allocate(lm(0:stride-1))
1540 do k = 0, (nalms-1)/(stride * repeat)
1541 istart = k * (stride * repeat)
1542 iend = min(nalms, istart + stride * repeat) - 1
1543 do i = istart, iend ! recode the (l,m) -> lm mapping, EH, 2002-08-08
1544 l = nint(alms(i,1))
1545 m = nint(alms(i,2))
1546 lm(i-istart) = (l+1)*l + m + 1
1547 enddo
1548
1549 frow = istart/repeat + 1
1550 npix = iend - istart + 1
1551 call ftpclj( unit, 1_i4b, frow, felem, npix, lm, status)
1552 do colnum = 2, ncl
1553 call f90ftpcl_(unit, colnum, frow, felem, npix, alms(istart:iend,colnum+1), status)
1554 enddo
1555 enddo
1556 deallocate(lm)
1557
1558 ! ----------------------
1559 ! close and exit
1560 ! ----------------------
1561
1562 ! close the file and free the unit number
1563 call ftclos(unit, status)
1564
1565 ! check for any error, and if so print out error messages
1566 if (status > 0) call printerror(status)
1567
1568 return
1569 end subroutine write_alms_KLOAD
1570 !=======================================================================
1571 subroutine read_alms_KLOAD(filename, nalms, alms, ncl, header, nlheader, extno)
1572 !=======================================================================
1573 ! Read a FITS file
1574 !
1575 ! slightly modified to deal with vector column
1576 ! in binary table EH/IAP/Jan-98
1577 !
1578 ! Used by synfast when reading a binary file with alms for cons.real.
1579 ! FKH/Apr-99
1580 !
1581 ! called by fits2alms
1582 ! Jan 2005, EH, improved for faster reading
1583 !=======================================================================
1584 CHARACTER(LEN=*), INTENT(IN) :: filename
1585 INTEGER(I4B), INTENT(IN) :: nalms, ncl,nlheader,extno
1586 REAL(KMAP), DIMENSION(0:nalms-1,1:(ncl+1)), INTENT(OUT) :: alms
1587 CHARACTER(LEN=80), INTENT(OUT), DIMENSION(1:nlheader) :: header
1588 REAL(KMAP) :: nullval
1589 LOGICAL(LGT) :: anynull
1590
1591 INTEGER(I4B), DIMENSION(:), allocatable :: lm
1592 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
1593 INTEGER(I4B) :: npix
1594 CHARACTER(LEN=80) :: comment ! , record
1595 LOGICAL(LGT) :: extend
1596 INTEGER(I4B) :: nmove, hdutype ! , nkeys , nspace
1597 INTEGER(I4B) :: frow, imap
1598 INTEGER(I4B) :: datacode, repeat, width
1599 integer(I4B) :: i, l, m
1600 integer(i4b) :: nrow2read, nelem
1601 integer(i8b) :: i0, i1
1602
1603 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1604 INTEGER(I4B) :: nrows, tfields, varidat
1605 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1606
1607 !-----------------------------------------------------------------------
1608 status=0
1609 header=''
1610 comment=''
1611 ttype=''
1612 tform=''
1613 tunit=''
1614 extname=''
1615 unit = 139
1616 naxes(1) = 1
1617 naxes(2) = 1
1618 nfound = -1
1619 anynull = .false.
1620 alms=0.
1621 readwrite=0
1622 call ftopen(unit,filename,readwrite,blocksize,status)
1623 if (status > 0) then
1624 call printerror(status)
1625 call fatal_error("Aborting.")
1626 endif
1627 ! -----------------------------------------
1628
1629 ! determines the presence of image
1630 call ftgkyj(unit,'NAXIS', naxis, comment, status)
1631 if (status > 0) call printerror(status)
1632
1633 ! determines the presence of an extension
1634 call ftgkyl(unit,'EXTEND', extend, comment, status)
1635 if (status > 0) status = 0 ! no extension :
1636 ! to be compatible with first version of the code
1637
1638 call assert (extend, 'No extension!')
1639 nmove = +extno
1640 call ftmrhd(unit, nmove, hdutype, status)
1641 !cc write(*,*) hdutype
1642
1643 call assert(hdutype==2, 'this is not a binary table')
1644
1645 header = ""
1646 call get_clean_header( unit, header, filename, status)
1647
1648 ! reads all the keywords
1649 call ftghbn(unit, MAXDIM, &
1650 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
1651 & status)
1652
1653 if (tfields<ncl) then
1654 print *,'found ',tfields,' columns in the file'
1655 print *,'expected ',ncl
1656 call fatal_error
1657 endif
1658 ! finds the bad data value
1659 ! if (KMAP == SP) call ftgkye(unit,'BAD_DATA',nullval,comment,status)
1660 ! if (KMAP == DP) call ftgkyd(unit,'BAD_DATA',nullval,comment,status)
1661 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
1662 if (status == 202) then ! bad_data not found
1663 if (KMAP == SP) nullval = s_bad_value ! default value
1664 if (KMAP == DP) nullval = d_bad_value ! default value
1665 status = 0
1666 endif
1667 !parse TFORM keyword to find out the length of the column vector
1668 call ftbnfm(tform(1), datacode, repeat, width, status)
1669 npix = nrows * repeat
1670 ! if (npix /= nalms) then
1671 if (npix > nalms) then
1672 print *,'found ',npix,' alms'
1673 ! print *,'expected ',nalms
1674 print *,'expected ',nalms,' or less'
1675 call fatal_error
1676 endif
1677
1678 call ftgrsz(unit, nrow2read, status)
1679 nrow2read = max(nrow2read, 1)
1680 nelem = nrow2read * repeat
1681 i0 = 0_i8b
1682 allocate(lm(0:nelem-1))
1683 do frow = 1, nrows, nrow2read
1684 i1 = min(i0 + nrow2read * repeat, int(npix,i8b)) - 1_i8b
1685 nelem = i1 - i0 + 1
1686 ! first column -> index
1687 call ftgcvj(unit, 1_i4b, frow, 1_i4b, nelem, i_bad_value, &
1688 & lm(0), anynull, status)
1689 call assert(.not. anynull, 'There are undefined values in the table!')
1690 ! other columns -> a(l,m)
1691 do imap = 2, ncl
1692 call f90ftgcv_(unit, imap, frow, 1_i4b, nelem, nullval, &
1693 & alms(i0:i1,imap+1), anynull, status)
1694 call assert (.not. anynull, 'There are undefined values in the table!')
1695 enddo
1696 ! recoding of the mapping, EH, 2002-08-08
1697 ! lm = l*l + l + m + 1
1698 do i = i0, i1
1699 l = int(sqrt( real(lm(i-i0)-1, kind = DP) ) )
1700 m = lm(i-i0) - l*(l+1) - 1
1701 ! check that round-off did not screw up mapping
1702 if (abs(m) > l) then
1703 print*,'Inconsistent l^2+l+m+1 -> l,m mapping'
1704 print*,l, m, l*(l+1)+m+1, lm(i-i0)
1705 call fatal_error
1706 endif
1707 alms(i,1) = real( l, kind=KMAP)
1708 alms(i,2) = real( m, kind=KMAP)
1709 enddo
1710 i0 = i1 + 1_i8b
1711 enddo
1712 deallocate(lm)
1713 ! sanity check
1714 if (i0 /= npix) then
1715 print*,'something wrong during piece-wise reading'
1716 call fatal_error
1717 endif
1718
1719 ! close the file
1720 call ftclos(unit, status)
1721
1722
1723 ! check for any error, and if so print out error messages
1724 if (status > 0) call printerror(status)
1725 return
1726 end subroutine read_alms_KLOAD
1727 !**************************************************************************
1728 SUBROUTINE read_bintod_KLOAD(filename, tod, npixtot, ntods, firstpix, nullval, anynull, &
1729 header, extno, units)
1730 !**************************************************************************
1731 !=======================================================================
1732 ! Read a FITS file
1733 !
1734 ! slightly modified to deal with vector column (ie TFORMi = '1024E')
1735 ! in binary table EH/IAP/Jan-98
1736 !
1737 ! This routine is used for reading TODS by anafast.
1738 ! Modified to start at a given pix numb OD & RT 02/02
1739 ! Modified to handle huge array (npix_tot > 2^32) OD & EH 07/02
1740 ! 2002-07-08 : bugs correction by E.H.
1741 ! 2007-01-31 : added units optional output
1742 !=======================================================================
1743
1744 IMPLICIT NONE
1745
1746 CHARACTER(LEN=*), INTENT(IN) :: filename
1747 INTEGER(I8B) , INTENT(IN) :: npixtot,firstpix
1748 INTEGER(I4B), INTENT(IN) :: ntods
1749 REAL(KMAP), DIMENSION(0:,1:), INTENT(OUT) :: tod
1750 REAL(KMAP), INTENT(OUT) :: nullval
1751 LOGICAL(LGT), INTENT(OUT) :: anynull
1752 character(len=*), dimension(1:),intent(out), optional :: header
1753 INTEGER(I4B), INTENT(IN), OPTIONAL :: extno
1754 character(LEN=*), dimension(1:),intent(OUT), optional :: units
1755
1756
1757 integer(I4B) :: i, nl_header, len_header, nl_units, len_units
1758 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxes(2),nfound, naxis
1759 INTEGER(I4B) :: npix_32 !,firstpix_32
1760 CHARACTER(LEN=80) :: comment
1761 LOGICAL(LGT) :: extend
1762 INTEGER(I4B) :: nmove, hdutype
1763 INTEGER(I4B) :: column, frow, itod
1764 INTEGER(I4B) :: datacode, repeat, width
1765
1766 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1767 INTEGER(I4B) :: nrows, tfields, varidat,felem
1768 CHARACTER(LEN=20), dimension(1:MAXDIM) :: ttype, tform,tunit
1769 CHARACTER(LEN=20) :: extname
1770
1771 INTEGER(I8B) :: q,iq,npix_tmp,firstpix_tmp, i0, i1
1772
1773 !-----------------------------------------------------------------------
1774 status=0
1775
1776 unit = 138
1777 naxes(1) = 1
1778 naxes(2) = 1
1779 nfound = -1
1780 anynull = .FALSE.
1781
1782 nl_header = 0
1783 if (present(header)) then
1784 nl_header = size(header)
1785 len_header = 80
1786 endif
1787
1788 nl_units = 0
1789 if (present(units)) then
1790 nl_units = size(units)
1791 len_units = min(80,len(units(1))) ! due to SUN compiler bug
1792 endif
1793
1794 readwrite=0
1795 CALL ftopen(unit,filename,readwrite,blocksize,status)
1796 IF (status .GT. 0) CALL printerror(status)
1797 ! -----------------------------------------
1798
1799 ! determines the presence of image
1800 CALL ftgkyj(unit,'NAXIS', naxis, comment, status)
1801 IF (status .GT. 0) CALL printerror(status)
1802
1803 ! determines the presence of an extension
1804 CALL ftgkyl(unit,'EXTEND', extend, comment, status)
1805 IF (status .GT. 0) status = 0 ! no extension :
1806 ! to be compatible with first version of the code
1807
1808 IF (naxis .GT. 0) THEN ! there is an image
1809 print*,'WARNING : Image is ignored in '//trim(filename)
1810 ENDIF
1811 IF (extend) THEN ! there is an extension
1812
1813 nmove = +1
1814 if (present(extno)) nmove = +1 + extno
1815 CALL ftmrhd(unit, nmove, hdutype, status)
1816 !cc write(*,*) hdutype
1817
1818 call assert(hdutype==2, 'this is not a binary table')
1819
1820 ! reads all the keywords
1821 CALL ftghbn(unit, MAXDIM, &
1822 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
1823 & status)
1824
1825 IF (tfields .LT. ntods) THEN
1826 PRINT *,'found ',tfields,' tods in the file'
1827 PRINT *,'expected ',ntods
1828 call fatal_error
1829 ENDIF
1830
1831 if (nl_header > 0) then
1832 header = ""
1833 status = 0
1834 call get_clean_header(unit, header, filename, status)
1835 endif
1836
1837 if (nl_units > 0) then
1838 do i=1,nl_units
1839 units(i)(1:len_units) = 'unknown' ! default
1840 enddo
1841 do itod = 1, min(ntods, nl_units)
1842 units(itod)(1:len_units) = adjustl(tunit(itod))
1843 enddo
1844 endif
1845
1846 ! finds the bad data value
1847 ! if (KMAP == SP) CALL ftgkye(unit,'BAD_DATA',nullval,comment,status)
1848 ! if (KMAP == DP) CALL ftgkyd(unit,'BAD_DATA',nullval,comment,status)
1849 call f90ftgky_(unit, 'BAD_DATA', nullval, comment, status)
1850 IF (status .EQ. 202) THEN ! bad_data not found
1851 if (KMAP == SP) nullval = s_bad_value ! default value
1852 if (KMAP == DP) nullval = d_bad_value ! default value
1853 status = 0
1854 ENDIF
1855
1856 IF (npixtot .LT. nchunk_max) THEN
1857
1858 DO itod = 1, ntods
1859
1860 !parse TFORM keyword to find out the length of the column vector (repeat)
1861 CALL ftbnfm(tform(itod), datacode, repeat, width, status)
1862 frow = (firstpix)/repeat+1 ! 1 based
1863 felem = firstpix-(frow-1)*repeat+1 ! 1 based
1864 npix_32 = npixtot
1865
1866 !reads the columns
1867 column = itod
1868 CALL f90ftgcv_(unit, column, frow, felem, npix_32, nullval, &
1869 & tod(0:npix_32-1,itod), anynull, status)
1870 END DO
1871
1872 ELSE
1873
1874 q = (npixtot-1)/nchunk_max
1875 DO iq = 0,q
1876 IF (iq .LT. q) THEN
1877 npix_tmp = nchunk_max
1878 ELSE
1879 npix_tmp = npixtot - iq*nchunk_max
1880 ENDIF
1881 firstpix_tmp = firstpix + iq*nchunk_max
1882 npix_32 = npix_tmp
1883 i0 = firstpix_tmp-firstpix
1884 i1 = i0 + npix_tmp - 1_i8b
1885
1886 DO itod = 1, ntods
1887 ! parse TFORM keyword to find out the length of the column vector
1888 CALL ftbnfm(tform(itod), datacode, repeat, width, status)
1889 frow = (firstpix_tmp)/repeat+1 ! 1 based
1890 felem = firstpix_tmp-(frow-1)*repeat+1 ! 1 based
1891 CALL f90ftgcv_(unit, itod, frow, felem, npix_32, nullval, &
1892 & tod(i0:i1,itod), anynull, status)
1893 END DO
1894
1895 ENDDO
1896
1897 ENDIF
1898
1899 ELSE ! no image no extension, you are dead, man
1900 call fatal_error(' No image, no extension')
1901 ENDIF
1902
1903 ! close the file
1904 CALL ftclos(unit, status)
1905
1906 ! check for any error, and if so print out error messages
1907 IF (status .GT. 0) CALL printerror(status)
1908
1909 RETURN
1910
1911 END SUBROUTINE read_bintod_KLOAD
1912 !=======================================================================
1913
1914 !======================================================================================
1915 SUBROUTINE write_bintabh_KLOAD(tod, npix, ntod, header, nlheader, filename, extno, firstpix, repeat)
1916 !======================================================================================
1917
1918 ! =================================================================================
1919 ! Create a FITS file containing a binary table extension in the first extension
1920 !
1921 ! Designed to deal with Huge file, (n_elements > 2^31)
1922 !
1923 ! OPTIONAL NEW PARAMETERS:
1924 ! firstpix : position in the file of the first element to be written (starts at 0)
1925 ! default value =0
1926 ! 8-byte integer
1927 ! if NE 0 then suppose that the file already exists
1928 !
1929 ! repeat : length of vector per unit rows and columns of the first binary extension
1930 ! default value = 12000 (\equiv 1 mn of PLANCK/HFI data)
1931 ! 4-byte integer
1932 !
1933 ! OTHER PARAMETERS
1934 ! unchanged with respect to the standard write_bintab of the HEALPIX package except
1935 ! npix which is an 8-byte integer
1936 !
1937 ! Adapted from write_bintab
1938 ! E.H. & O.D. @ IAP 07/02
1939 !
1940 ! Requires a compilation in 64 bits of the CFITSIO
1941 ! Note that the flag -D_FILE_OFFSETS_BITS=64 has to be added
1942 ! (cf page CFITIO 2.2 User's guide Chap 4, section 4-13)
1943 !
1944 ! 2002-07-08 : bugs correction by E.H.
1945 ! (uniform use of firstpix_tmp, introduction of firstpix_chunk)
1946 ! 2015-04-28: better handling of repeat (suggested by R. Keskitalo)
1947 !==========================================================================================
1948
1949 USE healpix_types
1950 IMPLICIT NONE
1951
1952 INTEGER(I8B) , INTENT(IN) :: npix
1953 INTEGER(I8B) , INTENT(IN), OPTIONAL :: firstpix
1954 INTEGER(I4B) , INTENT(IN), OPTIONAL :: repeat
1955 INTEGER(I4B) , INTENT(IN) :: ntod,nlheader
1956 REAL(KMAP) , INTENT(IN), DIMENSION(0:npix-1,1:ntod) :: tod
1957 CHARACTER(LEN=80), INTENT(IN), DIMENSION(1:nlheader) :: header
1958 CHARACTER(LEN=*), INTENT(IN) :: filename
1959 INTEGER(I4B) , INTENT(IN) , OPTIONAL :: extno
1960
1961 INTEGER(I4B) :: status,unit,blocksize,bitpix,naxis,naxes(1),repeat_fits
1962 INTEGER(I4B) :: i,npix_32
1963 LOGICAL(LGT) :: simple,extend
1964 CHARACTER(LEN=80) :: comment, ch
1965 integer(I8B) :: repeat_tmp
1966
1967 INTEGER(I4B), PARAMETER :: MAXDIM = MAXDIM_TOP !number of columns in the extension
1968 INTEGER(I4B) :: nrows,tfields,varidat
1969 INTEGER(I4B) :: frow,felem,colnum,readwrite,width,datacode,hdutype
1970 CHARACTER(LEN=20) :: ttype(MAXDIM), tform(MAXDIM), tunit(MAXDIM), extname
1971 CHARACTER(LEN=10) :: card
1972 CHARACTER(LEN=2) :: stn
1973 INTEGER(I4B) :: itn
1974
1975 real(KMAP), dimension(:), allocatable :: padding
1976 integer(I8B) :: lastpix
1977 integer(I4B) :: lengap
1978
1979 INTEGER(I4B) :: extno_i
1980 character(len=filenamelen) :: sfilename
1981 INTEGER(I8B) :: q,iq,npix_tmp,firstpix_tmp,firstpix_chunk, i0, i1
1982 character(len=1) :: pform
1983 character(len=*), parameter :: code='write_bintabh'
1984 !-----------------------------------------------------------------------
1985
1986 if (KMAP == SP) pform = 'E'
1987 if (KMAP == DP) pform = 'D'
1988
1989 IF (.NOT. PRESENT(repeat) ) THEN
1990 repeat_tmp = 1
1991 if (mod(npix,1024_i8b) == 0) then
1992 repeat_tmp = 1024
1993 elseif (npix >= 12000) then
1994 repeat_tmp = 12000
1995 endif
1996 ELSE
1997 repeat_tmp = repeat
1998 ENDIF
1999 IF (.NOT. PRESENT(firstpix) ) THEN
2000 firstpix_tmp = 0
2001 ELSE
2002 firstpix_tmp = firstpix
2003 ENDIF
2004
2005 extno_i = 0
2006 if (present(extno)) extno_i = extno
2007
2008 status=0
2009 unit = 137
2010 blocksize=1
2011
2012 ! remove the leading '!' (if any) when reopening the same file
2013 sfilename = adjustl(filename)
2014 if (sfilename(1:1) == '!') sfilename = sfilename(2:filenamelen)
2015
2016 ! create the new empty FITS file
2017
2018 IF (firstpix_tmp .EQ. 0) THEN
2019
2020 if (extno_i == 0) then
2021 CALL ftinit(unit,filename,blocksize,status)
2022 if (status > 0) call fatal_error("Error while creating file " &
2023 & //trim(filename) &
2024 & //". Check path and/or access rights.")
2025
2026 ! -----------------------------------------------------
2027 ! Initialize parameters about the FITS image
2028 simple=.TRUE.
2029 bitpix=32 ! integer*4
2030 naxis=0 ! no image
2031 naxes(1)=0
2032 extend=.TRUE. ! there is an extension
2033
2034 ! ----------------------
2035 ! primary header
2036 ! ----------------------
2037 ! write the required header keywords
2038 CALL ftphpr(unit,simple,bitpix,naxis,naxes,0_i4b,1_i4b,extend,status)
2039
2040 ! writes supplementary keywords : none
2041
2042 ! write the current date
2043 CALL ftpdat(unit,status) ! format ccyy-mm-dd
2044
2045 ! ----------------------
2046 ! image : none
2047 ! ----------------------
2048
2049 ! ----------------------
2050 ! extension
2051 ! ----------------------
2052 else
2053
2054 !*********************************************
2055 ! reopen an existing file and go to the end
2056 !*********************************************
2057 call ftopen(unit,sfilename,1_i4b,blocksize,status)
2058 call ftmahd(unit,1_i4b+extno_i,hdutype,status)
2059
2060 endif
2061
2062 ! creates an extension
2063 CALL ftcrhd(unit, status)
2064
2065 ! writes required keywords
2066 ! if (npix < repeat_tmp) repeat_tmp = npix ! 2015-04-28
2067
2068 ! nrows = npix / repeat_tmp + 1 ! naxis1
2069 nrows = (npix - 1_i8b) / repeat_tmp + 1_i4b ! 2015-04-28
2070 tfields = ntod
2071 WRITE(ch,'(i8)') repeat_tmp
2072 ! tform(1:ntod) = TRIM(ADJUSTL(ch))//pform ! does not work with Ifort, EH, 2006-04-04
2073 ch = TRIM(ADJUSTL(ch))//pform
2074 tform(1:ntod) = ch
2075
2076 ! IF (npix .LT. repeat_tmp) THEN ! 2015-04-28
2077 ! nrows = npix
2078 ! ch = '1'//pform
2079 ! tform(1:ntod) = ch
2080 ! ENDIF
2081 ttype(1:ntod) = 'simulation' ! will be updated
2082 tunit(1:ntod) = '' ! optional, will not appear
2083
2084 extname = '' ! optional, will not appear
2085 varidat = 0
2086
2087 CALL ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
2088 & extname, varidat, status)
2089
2090 ! write the header literally, putting TFORM1 at the desired place
2091 if (KMAP == SP) comment = 'data format of field: 4-byte REAL'
2092 if (KMAP == DP) comment = 'data format of field: 8-byte REAL'
2093 DO i=1,nlheader
2094 card = header(i)
2095 IF (card(1:5) == 'TTYPE') THEN ! if TTYPE1 is explicitely given
2096 stn = card(6:8)
2097 READ(stn,'(i3)') itn
2098 ! discard at their original location:
2099 call ftdkey(unit,'TTYPE'//stn,status) ! old TTYPEi and
2100 status = 0
2101 call ftdkey(unit,'TFORM'//stn,status) ! TFORMi
2102 status = 0
2103 if (itn <= tfields) then ! only put relevant information 2008-08-27
2104 call putrec(unit,header(i), status) ! write new TTYPE1
2105 status = 0
2106 call ftpkys(unit,'TFORM'//stn,tform(itn),comment,status) ! and write new TFORM1 right after
2107 !CALL ftmcrd(unit,'TTYPE'//stn,'COMMENT',status) ! old TTYPEi and
2108 !CALL ftmcrd(unit,'TFORM'//stn,'COMMENT',status) ! TFORMi
2109 !CALL ftprec(unit,header(i), status) ! write new TTYPE1
2110 !CALL ftpkys(unit,'TFORM'//stn,tform(1),comment,status) ! and write new TFORM1 right after
2111 endif
2112 ELSEIF (header(i).NE.' ') THEN
2113 call putrec(unit,header(i), status)
2114 ! CALL ftprec(unit,header(i), status)
2115 ENDIF
2116 status = 0
2117 ENDDO
2118
2119 ELSE
2120 ! The file already exists
2121 readwrite=1
2122 CALL ftopen(unit,sfilename,readwrite,blocksize,status)
2123 CALL ftmahd(unit,2_i4b+extno_i,hdutype,status)
2124
2125 CALL ftgkys(unit,'TFORM1',tform(1),comment,status)
2126 CALL ftbnfm(tform(1),datacode,repeat_fits,width,status)
2127
2128 IF (repeat_tmp .NE. repeat_fits) THEN
2129 if (present(repeat)) then
2130 write(*,'(a)') code//'> WARNING: In file '//trim(sfilename)
2131 write(*,'(a)') &
2132 & code//'> user provided REPEAT value (' // &
2133 & trim(adjustl(string(repeat_tmp))) // &
2134 & ') differs from value read from file (' // &
2135 & trim(adjustl(string(repeat_fits))) // &
2136 & ').'
2137 write(*,'(a)') code//'> The latter will be used.'
2138 ! else
2139 ! write(*,'(a,i0.0,a)') &
2140 ! & code//'> WARNING: REPEAT value read from file (', &
2141 ! & repeat_fits, &
2142 ! & ') will be used.'
2143 endif
2144 repeat_tmp = repeat_fits
2145 ENDIF
2146
2147 ENDIF
2148
2149
2150 IF (npix .LT. nchunk_max) THEN ! data is small enough to be written in one chunk
2151
2152 frow = (firstpix_tmp)/repeat_tmp + 1
2153 felem = firstpix_tmp-(frow-1)*repeat_tmp + 1
2154 npix_32 = npix
2155
2156 DO colnum = 1, ntod
2157 call f90ftpcl_(unit, colnum, frow, felem, npix_32, tod(0:npix_32-1,colnum), status)
2158 END DO
2159
2160 ELSE ! data has to be written in several chunks
2161
2162 q = (npix-1)/nchunk_max
2163 DO iq = 0,q
2164 IF (iq .LT. q) THEN
2165 npix_tmp = nchunk_max
2166 ELSE
2167 npix_tmp = npix - iq*nchunk_max
2168 ENDIF
2169 i0 = iq*nchunk_max
2170 i1 = i0 + npix_tmp - 1_i8b
2171 firstpix_chunk = firstpix_tmp + i0
2172 frow = (firstpix_chunk)/repeat_tmp + 1
2173 felem = firstpix_chunk-(frow-1)*repeat_tmp + 1
2174 npix_32 = npix_tmp
2175 DO colnum = 1, ntod
2176 call f90ftpcl_(unit, colnum, frow, felem, npix_32, &
2177 & tod(i0:i1, colnum), status)
2178 END DO
2179 ENDDO
2180
2181 ENDIF
2182
2183 ! pad entry if necessary ! 2015-04-28
2184 lastpix = firstpix_tmp + npix ! number of pixels written above
2185 lengap = modulo(lastpix, repeat_tmp) ! remaining gap
2186 if (lengap > 0) then
2187 firstpix_tmp = lastpix
2188 npix_32 = repeat_tmp - lengap
2189 frow = (firstpix_tmp)/repeat_tmp + 1
2190 felem = firstpix_tmp-(frow-1)*repeat_tmp + 1
2191 allocate(padding(0:npix_32-1))
2192 if (KMAP == SP) padding(:) = HPX_SBADVAL
2193 if (KMAP == DP) padding(:) = HPX_DBADVAL
2194 do colnum = 1, ntod
2195 call f90ftpcl_(unit, colnum, frow, felem, npix_32, padding, status)
2196 enddo
2197 deallocate(padding)
2198 endif
2199
2200 ! ----------------------
2201 ! close and exit
2202 ! ----------------------
2203
2204 ! close the file and free the unit number
2205 CALL ftclos(unit, status)
2206
2207 ! check for any error, and if so print out error messages
2208 IF (status .GT. 0) CALL printerror(status)
2209
2210 RETURN
2211
2212 END SUBROUTINE write_bintabh_KLOAD
2213 ! ==============================================================================
2214
2215 !******************************************************************************
2216 !---------------------------------------
2217 ! reads a FITS file containing a list of
2218 ! ring-based or pixel-based quadrature weights
2219 ! and turns it into a (ring-ordered) full sky map
2220 !
2221 ! adapted from unfold_weights.pro
2222 ! 2018-05-25
2223 !---------------------------------------
2224 subroutine unfold_weightsfile_KLOAD(w8file, w8map)
2225
2226 USE pix_tools, only: nside2npix, nside2npweights
2227
2228 character(len=*), intent(in) :: w8file
2229 real(KMAP), intent(out), dimension(0:) :: w8map
2230 real(KMAP), allocatable, dimension(:,:) :: w8list
2231 integer(i4b) :: nside, status, won
2232 integer(i8b) :: nfw8, npw8, nrw8
2233 character(len=*), parameter :: code = 'unfold_weightsfile'
2234
2235 nfw8 = getsize_fits(w8file, nside=nside)
2236 npw8 = nside2npweights(nside)
2237 nrw8 = 2*nside
2238
2239 won = 0
2240 if (nfw8 == nrw8) won = 1
2241 if (nfw8 == npw8) won = 2
2242 if (won == 0) then
2243 print*,'Weights file = '//trim(w8file)
2244 print*,'contains ',nfw8,' weights'
2245 print*,'for Nside = ',nside
2246 print*,'Expected either ',nrw8,' or ',npw8
2247 call fatal_error
2248 endif
2249
2250 allocate(w8list(0:nfw8-1,1:1), stat=status)
2251 call assert_alloc(status,code,"w8list")
2252 call input_map(w8file, w8list, nfw8, 1)
2253 call unfold_weightslist(nside, won, w8list(:,1), w8map)
2254 deallocate(w8list)
2255
2256 return
2257 end subroutine unfold_weightsfile_KLOAD
2258 !---------------------------------------
2259 ! turns a list of ring-based or pixel-based quadrature weights
2260 ! into a (ring-ordered) full sky map
2261 !
2262 ! adapted from unfold_weights.pro
2263 ! 2018-05-18
2264 ! 2018-09-12: promoted qpix to I8B to avoid consistency problems during compilation with g95
2265 !---------------------------------------
2266 subroutine unfold_weightslist_KLOAD(nside, won, w8list, w8map)
2267
2268 USE pix_tools, only: nside2npix, nside2npweights
2269 USE long_intrinsic, only: long_size
2270
2271 integer(i4b), intent(in) :: nside, won
2272 real(KMAP), dimension(0:), intent(in) :: w8list
2273 real(KMAP), dimension(0:), intent(out) :: w8map
2274
2275 integer(i8b) :: np, npix
2276 integer(i8b) :: nf, nw8, pnorth, psouth, vpix, qp4, p, qpix
2277 integer(i4b) :: ring, odd, shifted, rpix, wpix, j4, n4, it
2278
2279 ! test nside
2280 npix = nside2npix(nside)
2281 if (npix <= 0) then
2282 print*,'Unvalid Nside = ',nside
2283 call fatal_error
2284 endif
2285
2286 ! test won
2287 if (won < 1 .or. won > 2) then
2288 print*,'Expected either 1 or 2, got ',won
2289 call fatal_error
2290 endif
2291
2292 ! test input list size
2293 nf = long_size(w8list)
2294 if (won == 1) then
2295 nw8 = 2 * nside
2296 else
2297 nw8 = nside2npweights(nside)
2298 endif
2299 if (nf /= nw8) then
2300 print*,'Expected in input weight list',nw8
2301 print*,'got ',nf
2302 call fatal_error
2303 endif
2304
2305 ! test output map size
2306 np = long_size(w8map)
2307 if (np /= npix) then
2308 print*,'Expected in output weight map',npix
2309 print*,'got ',np
2310 call fatal_error
2311 endif
2312
2313 ! do actual unfolding
2314 if (won == 1) then
2315
2316 pnorth = 0_i8b
2317 n4 = 4 * nside
2318 do ring=1,n4-1 ! loop on all rings
2319 it = min(ring, n4 - ring) ! ring index, counting from closest pole
2320 qp4= 4_i8b * min(it, nside) ! pixels / ring
2321 w8map(pnorth:pnorth+qp4-1) = w8list(it-1)
2322 pnorth = pnorth + qp4
2323 enddo
2324
2325 else
2326
2327 pnorth = 0_i8b ! position in expanded weights
2328 vpix = 0_i8b ! position in compress list
2329 do ring=0, 2*nside-1
2330 qpix = min(ring+1, nside) ! 1/4 of number of pixels per ring
2331 shifted = 0
2332 if (ring < (nside-1) .or. iand(ring+nside,1_i4b) == 1_i4b) shifted = 1
2333 odd = iand(qpix,1_i8b)
2334 qp4 = 4_i8b*qpix ! number of pixels per ring
2335 ! fill the weight map
2336 do p=0,qp4-1
2337 j4 = mod(p, qpix) ! g95: p and qpix must be of same type
2338 rpix = min(j4, qpix - shifted - j4) ! seesaw
2339 w8map(pnorth+p) = w8list(vpix + rpix)
2340 enddo
2341
2342 if (ring < 2*nside-1) then ! south part (except equator)
2343 psouth = npix - pnorth - qp4
2344 w8map(psouth:psouth+qp4-1) = w8map(pnorth:pnorth+qp4-1)
2345 endif
2346 ! locations on next ring
2347 pnorth = pnorth + qp4
2348 wpix = (qpix+1)/2 + 1 - ior(odd, shifted)
2349 vpix = vpix + wpix
2350 enddo
2351 endif
2352
2353 ! add 1 to get final weight
2354 w8map = w8map + 1.0_KMAP
2355
2356 return
2357 end subroutine unfold_weightslist_KLOAD
2358
8383 ! subroutine read_bintod
8484 ! subroutine write_bintabh
8585 ! subroutine unfold_weights
86 ! subroutine read_fits_partial
87 ! subroutine write_fits_partial
8688 ! ----------------------------------
8789 !
8890 ! subroutine read_fits_cut4 ?
118120 real(kind=SP), private, parameter :: s_bad_value = HPX_SBADVAL
119121 real(kind=DP), private, parameter :: d_bad_value = HPX_DBADVAL
120122 integer(kind=I4B), private, parameter :: i_bad_value = -1637500000
123 integer(kind=I8B), private, parameter :: l_bad_value = -1637500000_I8B
121124 integer(I4B) , private, parameter :: nchunk_max = 12000
122125 integer(I4B), private, parameter :: MAXDIM_TOP = 199 ! < 999
123126
166169 #endif
167170 end interface
168171
172 interface read_fits_partial
173 #ifdef NO64BITS
174 module procedure read_fits_partial8_s, read_fits_partial8_d
175 #else
176 module procedure read_fits_partial8_s, read_fits_partial8_d, &
177 & read_fits_partial4_s, read_fits_partial4_d
178 #endif
179 end interface
180
181 interface write_fits_partial
182 #ifdef NO64BITS
183 module procedure write_fits_partial4_s, write_fits_partial4_d
184 #else
185 module procedure write_fits_partial8_s, write_fits_partial8_d, &
186 & write_fits_partial4_s, write_fits_partial4_d
187 #endif
188 end interface
189
169190 !
170191 interface input_tod
171192 module procedure input_tod_s,input_tod_d
216237 end interface
217238
218239 interface f90ftpcl_
219 module procedure f90ftpcle, f90ftpcld
240 #ifdef NO64BITS
241 module procedure f90ftpcle, f90ftpcld, f90ftpclj
242 #else
243 module procedure f90ftpcle, f90ftpcld, f90ftpclj, f90ftpclk
244 #endif
220245 end interface
221246
222247 interface f90ftgcv_
223 module procedure f90ftgcve, f90ftgcvd
248 #ifdef NO64BITS
249 module procedure f90ftgcve, f90ftgcvd, f90ftgcvj
250 #else
251 module procedure f90ftgcve, f90ftgcvd, f90ftgcvj, f90ftgcvk
252 #endif
224253 end interface
225254
226255 interface f90ftgpv_
228257 end interface
229258
230259 interface f90ftgky_
231 module procedure f90ftgkye, f90ftgkyd
260 #ifdef NO64BITS
261 module procedure f90ftgkye, f90ftgkyd, f90ftgkyj
262 #else
263 module procedure f90ftgkye, f90ftgkyd, f90ftgkyj, f90ftgkyk
264 #endif
232265 end interface
233266
234267 interface map_bad_pixels
248281 public :: read_fits_cut4, write_fits_cut4, &
249282 & input_map, read_bintab, &
250283 & output_map, write_bintab
284 public :: read_fits_partial, write_fits_partial
251285 public :: write_plm
252286 public :: fits2cl, read_asctab, write_asctab
253287 public :: read_dbintab, write_dbintab
261295 contains
262296
263297 !-------------------------------------------------------------------------------
264 ! generic interface F90FTPCL_ for FITSIO's FTPCLE and FTPCLD
298 ! generic interface F90FTPCL_ for FITSIO's FTPCL[E,D,J,K]
265299 ! writes data in ASCTAB or BINTAB
266300 subroutine f90ftpcle(unit, colnum, frow, felem, np, data, status)
267301 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
277311 call ftpcld(unit, colnum, frow, felem, np, data, status)
278312 return
279313 end subroutine f90ftpcld
314 subroutine f90ftpclj(unit, colnum, frow, felem, np, data, status)
315 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
316 integer(I4B), intent(out) :: status
317 integer(I4B), intent(in), dimension(0:) :: data
318 call ftpclj(unit, colnum, frow, felem, np, data, status)
319 return
320 end subroutine f90ftpclj
321 #ifndef NO64BITS
322 subroutine f90ftpclk(unit, colnum, frow, felem, np, data, status)
323 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
324 integer(I4B), intent(out) :: status
325 integer(I8B), intent(in), dimension(0:) :: data
326 call ftpclk(unit, colnum, frow, felem, np, data, status)
327 return
328 end subroutine f90ftpclk
329 #endif
280330 !-------------------------------------------------------------------------------
281 ! generic interface F90FTGCV_ for FITSIO's FTGCVE and FTGCVD
331 ! generic interface F90FTGCV_ for FITSIO's FTGCV[E,D,J,K]
282332 ! reads data from BINTAB
283333 subroutine f90ftgcve(unit, colnum, frow, felem, np, nullval, data, anynull, status)
284334 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
298348 call ftgcvd(unit, colnum, frow, felem, np, nullval, data, anynull, status)
299349 return
300350 end subroutine f90ftgcvd
351 subroutine f90ftgcvj(unit, colnum, frow, felem, np, nullval, data, anynull, status)
352 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
353 integer(I4B), intent(out) :: status
354 logical(LGT), intent(out) :: anynull
355 integer(I4B), intent(out), dimension(0:) :: data
356 integer(I4B), intent(in) :: nullval
357 call ftgcvj(unit, colnum, frow, felem, np, nullval, data, anynull, status)
358 return
359 end subroutine f90ftgcvj
360 #ifndef NO64BITS
361 subroutine f90ftgcvk(unit, colnum, frow, felem, np, nullval, data, anynull, status)
362 integer(I4B), intent(in) :: unit, colnum, frow, felem, np
363 integer(I4B), intent(out) :: status
364 logical(LGT), intent(out) :: anynull
365 integer(I8B), intent(out), dimension(0:) :: data
366 integer(I8B), intent(in) :: nullval
367 call ftgcvk(unit, colnum, frow, felem, np, nullval, data, anynull, status)
368 return
369 end subroutine f90ftgcvk
370 #endif
301371 !-------------------------------------------------------------------------------
302372 ! generic interface F90FTGPV_ for FITSIO's FTGPVE and FTGPVD
303373 ! reads data from IMAGE
320390 return
321391 end subroutine f90ftgpvd
322392 !-------------------------------------------------------------------------------
323 ! generic interface F90FTGKY_ for FITSIO's FTGKYE and FTGKYD
393 ! generic interface F90FTGKY_ for FITSIO's FTGKY[E,D,J,K]
324394 ! reads a keyword
325395 subroutine f90ftgkye(unit, keyword, value, comment, status)
326396 integer(I4B), intent(in) :: unit
340410 call ftgkyd(unit, keyword, value, comment, status)
341411 return
342412 end subroutine f90ftgkyd
413 subroutine f90ftgkyj(unit, keyword, value, comment, status)
414 integer(I4B), intent(in) :: unit
415 character(len=*), intent(in) :: keyword
416 integer(I4B), intent(out) :: status
417 character(len=*), intent(out) :: comment
418 integer(I4B), intent(out) :: value
419 call ftgkyj(unit, keyword, value, comment, status)
420 return
421 end subroutine f90ftgkyj
422 #ifndef NO64BITS
423 subroutine f90ftgkyk(unit, keyword, value, comment, status)
424 integer(I4B), intent(in) :: unit
425 character(len=*), intent(in) :: keyword
426 integer(I4B), intent(out) :: status
427 character(len=*), intent(out) :: comment
428 integer(I8B), intent(out) :: value
429 call ftgkyk(unit, keyword, value, comment, status)
430 return
431 end subroutine f90ftgkyk
432 #endif
343433 !-------------------------------------------------------------------------------
344434
345435
346436 ! define routine with SP I/O
347 #include "fits_s_inc.f90"
437 #include "fits_s_inc.F90"
348438
349439 ! define routine with DP I/O
350 #include "fits_d_inc.f90"
440 #include "fits_d_inc.F90"
351441
352442
353443
401491 call ftgkyj(unit,'NAXIS', naxis, comment, status)
402492 if (status > 0) call printerror(status)
403493 if (naxis > 0) then ! there is an image
404 print*,'an image was found in the FITS file '//filename
494 print*,'an image was found in the FITS file '//trim(filename)
405495 print*,'... it is ignored.'
406496 endif
407497
408498 ! determines the presence of an extension
409499 call ftgkyl(unit,'EXTEND', extend, comment, status)
410500 if (status > 0) then
411 print*,'extension expected and not found in FITS file '//filename
501 print*,'extension expected and not found in FITS file '//trim(filename)
412502 print*,'abort code'
413503 call fatal_error
414504 endif
424514 & nrows, tfields, ttype, tform, tunit, extname, varidat, &
425515 & status)
426516 if (tfields < 4) then
427 print*,'Expected 4 columns in FITS file '//filename
517 print*,'Expected 4 columns in FITS file '//trim(filename)
428518 print*,'found ',tfields
429519 if (tfields < 2) call fatal_error
430520 if (.not. (trim(ttype(1)) == 'PIXEL' &
613703 ! writes required keywords
614704 ! repeat = 1024
615705 repeat = 1
706 if (obs_npix < repeat) repeat = 1
616707 nrows = (obs_npix + repeat - 1)/ repeat ! naxis1
617 if (obs_npix < repeat) repeat = 1
618708 write(srepeat,'(i4)') repeat
619709 srepeat = adjustl(srepeat)
620710
632722 tunit = ' ' ! optional, will not appear
633723 tunit(2) = units_usr
634724 tunit(4) = units_usr
635 extname = 'SKY_OBSERVATION' ! default, will be overide by user provided one if any
725 extname = 'SKY_OBSERVATION' ! default, will be overridden by user provided one if any
636726 if (polar_flag) extname = extnames(1+extno_i)
637727 varidat = 0
638728 call ftphbn(unit, nrows, tfields, ttype, tform, tunit, &
651741 call ftpcom(unit,' Data Specific Keywords ',status)
652742 call ftpcom(unit,'------------------------------------------',status)
653743 call ftpkys(unit,'INDXSCHM','EXPLICIT',' Indexing : IMPLICIT or EXPLICIT', status)
654 call ftpkyj(unit,'GRAIN', grain, ' Grain of pixel indexing',status)
655 call ftpcom(unit,'GRAIN=0 : no indexing of pixel data (IMPLICIT) ',status)
656 call ftpcom(unit,'GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT)',status)
657 call ftpcom(unit,'GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT)',status)
744 ! call ftpkyj(unit,'GRAIN', grain, ' Grain of pixel indexing',status)
745 ! call ftpcom(unit,'GRAIN=0 : no indexing of pixel data (IMPLICIT)',status)
746 ! call ftpcom(unit,'GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT)',status)
747 ! call ftpcom(unit,'GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT)',status)
658748 call ftpkys(unit,'OBJECT','PARTIAL ',' Sky coverage represented by data',status)
659749 call ftpkyj(unit,'OBS_NPIX',obs_npix, ' Number of pixels observed and recorded',status)
660750
715805 endif
716806
717807
718 ! write the user provided header literally, except for PIXTYPE, TFORM*, TTYPE*, TUNIT* and INDXSCHM
808 ! write the user provided header literally, except for PIXTYPE, TFORM*, TTYPE*, TUNIT*, INDXSCHM and GRAIN
719809 ! copy NSIDE, ORDERING and COORDSYS and POLAR if they are valid and not already given
720810 do i=1,nlheader
721811 card = header(i)
722812 if (card(1:5) == 'TTYPE' .or. card(1:5) == 'TFORM' .or. card(1:7) == 'PIXTYPE') then
723813 continue ! don't keep them
724814 else if (card(1:8) == 'INDXSCHM') then
815 continue
816 else if (card(1:5) == 'GRAIN') then ! already written above
817 continue
818 else if (card(1:13) == 'COMMENT GRAIN' .or. card(1:14) == 'COMMENT GRAIN') then ! already written above
725819 continue
726820 else if (card(1:5) == 'TUNIT') then
727821 if ((card(6:6) == '2' .or. card(6:6) == '4') .and. trim(units_usr) == '') then
19672061 INTEGER(I4B) :: status,unit,readwrite,blocksize,naxis
19682062 CHARACTER(LEN=80) :: comment, ttype1
19692063 LOGICAL(LGT) :: extend, anyf
1970 INTEGER(I4B):: nmove, hdutype, idmax, nrows
2064 INTEGER(I4B):: nmove, hdutype, nrows
2065 integer(I4B), dimension(1) :: idmax ! because ftgcvj expects an array (2020-08-24)
19712066
19722067 !-----------------------------------------------------------------------
19732068 status=0
20142109 ttype1 = trim(strupcase(adjustl(ttype1)))
20152110 if (trim(ttype1(1:5)) == 'INDEX') then
20162111 call ftgkyj(unit, 'NAXIS2', nrows, comment, status) ! find number of rows
2017 call ftgcvj(unit, 1_i4b, nrows, 1_i4b, 1_i4b, 0_i4b, idmax, anyf, status) ! read element on last row of first column
2112 call ftgcvj(unit, 1_i4b, nrows, 1_i4b, 1_i4b, 0_i4b, idmax(1), anyf, status) ! read element on last row of first column
20182113 if (status == 0) then
2019 lmax = int(sqrt( real(idmax-1, kind = DP) ) )
2114 lmax = int(sqrt( real(idmax(1)-1, kind = DP) ) )
20202115 if (lmax > 0) goto 1000
20212116 endif
20222117 endif
27582853 character(len=*), parameter :: primer_url = 'http://healpix.sf.net/pdf/intro.pdf'
27592854 !====================================================================
27602855
2856 !n_ext = getnumext_fits(mapfile)
27612857 npixtot = getsize_fits(mapfile, nmaps = nmaps, ordering=order_map, nside=nsmax,&
27622858 & mlpol=mlpol, type = type, polarisation = polar_fits, &
27632859 & coordsys=coordsys, polcconv=polcconv)
27642860
27652861 if (nsmax<=0) then
2766 print*,"Keyword NSIDE not found in FITS header!"
2862 print*,"Keyword NSIDE not found in FITS header of "//trim(mapfile)//" !"
27672863 call fatal_error(code)
27682864 endif
27692865 if (type == 3) npixtot = nside2npix(nsmax) ! cut sky input data set
27702866 if (nsmax/=npix2nside(npixtot)) then
27712867 print 9000,"FITS header keyword NSIDE does not correspond"
2772 print 9000,"to the size of the map!"
2868 print 9000,"to the size of the map in "//trim(mapfile)//" !"
27732869 call fatal_error(code)
27742870 endif
27752871
27762872 if (polarisation .and. (nmaps >=3) .and. polar_fits == -1) then
2777 print 9000,"The input fits file MAY NOT contain polarisation data."
2873 print 9000,"The input FITS file "//trim(mapfile)//" MAY NOT contain polarisation data."
27782874 print 9000,"Proceed at your own risk"
27792875 endif
27802876
27812877 if (polarisation .and. (nmaps<3 .or. polar_fits ==0)) then
2782 print 9000,"The file does NOT contain polarisation maps"
2878 print 9000,"The FITS file "//trim(mapfile)//" does NOT contain polarisation maps"
27832879 print 9000,"only the temperature field will be analyzed"
27842880 polarisation = .false.
27852881 endif
28082904 ! --- check ordering scheme ---
28092905 if ((order_map/=1).and.(order_map/=2)) then
28102906 print 9000,"The ordering scheme of the map must be RING or NESTED."
2811 print 9000,"No ordering specification is given in the FITS-header!"
2907 print 9000,"No ordering specification is given in the FITS-header of "//trim(mapfile)//" !"
28122908 call fatal_error(code)
28132909 endif
28142910
22 # EH, Dec 2004 -- Jan 2005
33
44 SetDef(){
5 template_file=fits_template.f90
6 outfile_s=fits_s_inc.f90
7 outfile_d=fits_d_inc.f90
5 template_file=fits_template.F90
6 outfile_s=fits_s_inc.F90
7 outfile_d=fits_d_inc.F90
88 }
99
1010 #--------
523523 endif
524524 endif
525525 enddo
526 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
526 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
527527 if (present(comment)) comment = ' '
528528 if (present(count)) count = count_in
529529 return
562562 endif
563563 endif
564564 enddo
565 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
565 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
566566 if (present(comment)) comment = ' '
567567 if (present(count)) count = count_in
568568 return
672672 return
673673 endif
674674 enddo
675 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
675 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
676676 if (present(comment)) comment = ' '
677677 if (present(count)) count = count_in
678678 return
711711 endif
712712 endif
713713 enddo
714 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
714 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
715715 if (present(comment)) comment = ' '
716716 if (present(count)) count = count_in
717717 return
752752 endif
753753 endif
754754 enddo
755 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
755 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
756756 if (present(comment)) comment = ' '
757757 if (present(count)) count = count_in
758758 return
791791 endif
792792 endif
793793 enddo
794 if (verbose) print*,' >>>>> keyword '//kwd//' not found <<<<< '
794 if (verbose) print*,' >>>>> keyword '//trim(kwd)//' not found <<<<< '
795795 if (present(comment)) comment = ' '
796796 if (present(count)) count = count_in
797797 return
877877 character(len=80), dimension(1:20) :: my_units
878878 character(len=8) :: my_ordering
879879 character(len=FILENAMELEN) :: udtype, my_beam_leg
880 logical(LGT) :: do_full, do_alm, do_cl, do_cut, do_polar, &
881 & do_bcross, do_reset, do_asym
880 logical(LGT) :: do_full, do_alm, do_cl, do_cut, do_partial, &
881 & do_polar, do_bcross, do_reset, do_asym, do_map
882882
883883 character(len=*), parameter :: code = 'write_minimal_header'
884884 !--------------------------------------------------------------------------------
885885 ! find out type of data to be contained in FITS file
886886 udtype = strupcase(dtype)
887 do_alm = .false. ; do_cl = .false. ; do_full = .false. ; do_cut = .false.
887 do_alm = .false. ; do_cl = .false. ; do_full = .false.
888 do_cut = .false. ; do_partial = .false.
888889 select case (trim(udtype))
889890 case ('ALM')
890891 do_alm = .true.
894895 do_full = .true.
895896 case ('CUTMAP')
896897 do_cut = .true.
898 ! case ('PARTIAL')
899 do_partial = .true.
897900 case default
898901 print*,'Invalid choice of datatype:'//trim(dtype)
899902 print*,'Should be one of: ALM, alm, CL, cl, CUTMAP, cutmap, MAP, map'
900903 call fatal_error(code)
901904 end select
905 do_map = (do_cut .or. do_full .or. do_partial)
902906
903907 !
904908 if (present(order) .and. present(ordering)) then
907911 endif
908912
909913 ! check for required keywords for map
910 if (do_cut .or. do_full) then
914 if (do_map) then
911915 if (.not. present(nside)) then
912916 print*,'NSIDE required for maps in '//code
913917 call fatal_error(code)
11071111
11081112 endif ! cl
11091113
1110 if (do_full .or. do_cut) then
1114 if (do_map) then
11111115 !--------------------------------------------------------------------------------------------
11121116 ! minimal header for FULL SKY MAP and CUT SKY MAP
11131117 !--------------------------------------------------------------------------------------------
11551159 call add_card(header,"COMMENT","Full sky data")
11561160 call add_card(header,"OBJECT","FULLSKY")
11571161 call add_card(header,"INDXSCHM","IMPLICIT"," Indexing : IMPLICIT or EXPLICIT")
1158 call add_card(header,"GRAIN", 0, " Grain of pixel indexing")
1159 endif
1160 if (do_cut) then
1162 ! call add_card(header,"GRAIN", 0, " Grain of pixel indexing")
1163 endif
1164 if (do_cut .or. do_partial) then
11611165 call add_card(header,"EXTNAME","'CUT SKY MAP'",update=.true.)
11621166 call add_card(header,"COMMENT","Cut sky data")
11631167 call add_card(header,"OBJECT","PARTIAL")
11641168 call add_card(header,"INDXSCHM","EXPLICIT"," Indexing : IMPLICIT or EXPLICIT")
1165 call add_card(header,"GRAIN", 1, " Grain of pixel indexing")
1166 endif
1167 call add_card(header,"COMMENT","GRAIN=0 : no indexing of pixel data (IMPLICIT)")
1168 call add_card(header,"COMMENT","GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT)")
1169 call add_card(header,"COMMENT","GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT)")
1169 ! call add_card(header,"GRAIN", 1, " Grain of pixel indexing")
1170 endif
1171 ! call add_card(header,"COMMENT","GRAIN=0 : no indexing of pixel data (IMPLICIT)")
1172 ! call add_card(header,"COMMENT","GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT)")
1173 ! call add_card(header,"COMMENT","GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT)")
11701174 call add_card(header) ! blank line
11711175 call add_card(header,"POLAR",do_polar," Polarisation included (True/False)")
11721176 if (do_cut) then
1177 call add_card(header) ! blank line
1178 call add_card(header,"TTYPE1", "PIXEL","pixel index")
1179 call add_card(header,"TUNIT1", "", "")
1180 call add_card(header)
11731181 if (present(units)) then
11741182 my_units = units
1175 call add_card(header,"TUNIT2", my_units(1),"physical unit of signal map")
1176 call add_card(header,"TUNIT4", my_units(1),"physical unit of error map")
1183 call add_card(header,"TUNIT2", my_units(1),"physical units of map")
1184 call add_card(header,"TUNIT4", my_units(1),"physical units of map")
11771185 endif
11781186 endif
1187 ! if (do_partial) then
1188 ! if (present(units)) my_units = units
1189 ! it = 1 ; iq = 1 ; iu = 1
1190 ! call add_card(header) ! blank line
1191 ! call add_card(header,"TTYPE1", "PIXEL","pixel index")
1192 ! call add_card(header,"TUNIT1", "", "")
1193 ! call add_card(header)
1194
1195 ! call add_card(header) ! blank line
1196 ! call add_card(header,"TTYPE2", "TEMPERATURE","Temperature map")
1197 ! call add_card(header,"TUNIT2", my_units(it), "physical units of map")
1198 ! call add_card(header)
1199
1200 ! if (do_polar) then
1201 ! call add_card(header,"TTYPE3", "Q_POLARISATION","Q Polarisation map")
1202 ! call add_card(header,"TUNIT3", my_units(iq), "physical units of map")
1203 ! call add_card(header)
1204
1205 ! call add_card(header,"TTYPE4", "U_POLARISATION","U Polarisation map")
1206 ! call add_card(header,"TUNIT4", my_units(iu), "physical units unit")
1207 ! call add_card(header)
1208 ! endif
1209 ! endif
11791210 if (do_full) then
11801211 call add_card(header,"DERIV",my_deriv," Derivative included (0, 1 or 2)")
11811212
11981229 call add_card(header)
11991230
12001231 if (do_polar) then
1201 !call add_card(header,"TTYPE2", "Q-POLARISATION","Q Polarisation map")
12021232 call add_card(header,"TTYPE2", "Q_POLARISATION","Q Polarisation map")
12031233 call add_card(header,"TUNIT2", my_units(iq),"map unit")
12041234 call add_card(header)
12051235
1206 !call add_card(header,"TTYPE3", "U-POLARISATION","U Polarisation map")
12071236 call add_card(header,"TTYPE3", "U_POLARISATION","U Polarisation map")
12081237 call add_card(header,"TUNIT3", my_units(iu),"map unit")
12091238 call add_card(header)
3838 ! Mars 2008: i8b same as i4b on machines not supporting 64 bits (NO64BITS flag set)
3939 ! Feb 2009: introduce healpix_version
4040 !
41 character(len=*), PARAMETER, public :: healpix_version = '3.60'
41 character(len=*), PARAMETER, public :: healpix_version = '3.81'
4242 INTEGER, PARAMETER, public :: i4b = SELECTED_INT_KIND(9)
4343 #ifdef NO64BITS
4444 INTEGER, PARAMETER, public :: i8b = i4b
870870 integer(i4b), dimension(1:,1:), intent(inout) :: ringphi
871871 integer(i4b), intent(inout) :: ngr
872872
873 integer(i4b) :: i, j, k, kk, ngr_out, diff, iphi, i0, nrh
873 !integer(i4b) :: i, j, k, kk, ngr_out, diff, iphi, i0, nrh
874 integer(i4b) :: i, j, k, kk, ngr_out, iphi, i0, nrh, nshrink, np
874875 real(dp), dimension(1:2*nsboost+1) :: phiw, phie
875876 real(dp) :: dd, dph, phic
877 ! 2020-08-31: bug correction
876878
877879 !=======================================================================
878880 if (nsboost <= 1) return
881883 do i=1, ngr ! loop on low-res rings
882884 i0 = ringphi(1,i) * nsboost - nsboost - irmin
883885 do k=-1,1,2 ! West and East side of disc
886 nshrink = 0
884887 kk = (k+5)/2 ! 2 or 3
885888 222 continue
886889 iphi = ringphi(kk, i)
887 if (ringphi(2,i) <= ringphi(3,i) .and. iphi >= 0) then
888 call find_pixel_bounds(nside, nsboost, ringphi(1,i), iphi, phiw, phie)
890 !if (ringphi(2,i) <= ringphi(3,i) .and. iphi >= 0) then
891 if (iphi >= 0) then ! corrected 2020-08-31
892 call find_pixel_bounds(nside, nsboost, ringphi(1,i), iphi, phiw, phie, np=np)
889893 do j=1, 2*nsboost+1
890894 if (i0+j >= 1 .and. i0+j <= nrh) then
891895 phic = (phie(j)+phiw(j))*0.5_dp ! pixel center
895899 if (dd <= dph) goto 1000 ! pixel touched by disc, move to next one
896900 endif
897901 enddo
898 ringphi(kk, i)= iphi - k ! pixel not in disc, move edge pixel inwards
899 goto 222 ! try next pixel inward
902 !ringphi(kk, i)= iphi - k ! pixel not in disc, move edge pixel inwards
903 ringphi(kk, i) = mod(iphi + np - k, np) ! pixel not in disc, move edge pixel inwards in [0,np-1]
904 nshrink = nshrink + 1
905 if (nshrink <= 2) then
906 goto 222 ! try next pixel inward
907 else
908 ringphi(kk,i) = -999
909 endif
900910 1000 continue
901911 endif
902 enddo ! loop on side
912 enddo ! loop on k East-West sides
903913 enddo ! loop on low-res rings
904914
905915 ! remove empty rings
906916 ngr_out = 0
907917 do i=1,ngr
908 diff = ringphi(3,i) - ringphi(2,i)
909 if (ringphi(2,i) >=0 .and. ringphi(3,i) >=0 .and. diff /= -2 .and. diff /= -1) then
918 ! diff = ringphi(3,i) - ringphi(2,i)
919 ! if (ringphi(2,i) >=0 .and. ringphi(3,i) >=0 .and. diff /= -2 .and. diff /= -1) then
920 if (ringphi(2,i) >=0 .and. ringphi(3,i) >=0) then ! 2020-08-31
910921 ngr_out = ngr_out + 1
911922 ringphi(1:3, ngr_out) = ringphi(1:3, i)
912923 endif
920931 return
921932 end subroutine check_edge_pixels
922933 !=======================================================================
923 subroutine find_pixel_bounds (nside, nsboost, iring, iphi, phiw, phie)
934 subroutine find_pixel_bounds (nside, nsboost, iring, iphi, phiw, phie, np)
924935 !=======================================================================
925936 integer(i4b), intent(in) :: nside, nsboost, iring, iphi
926937 real(dp), dimension(1:2*nsboost+1), intent(out) :: phiw, phie
938 integer(i4b), optional, intent(out) :: np
927939
928940 real(dp), dimension(1:2*nsboost+1) :: f, f1, phiw_t, phie_t
929941 real(dp) :: c0, quad, phie1, phie2, phiw1, phiw2, cv
935947 !f = ((/ (i,i=0,2*nsboost) /) - nsboost) / nsboost
936948 f = ((/ (i*1.d0,i=0,2*nsboost) /) - nsboost*1.d0) / nsboost
937949
950 if (present(np)) np = npr
938951 nq = npr/4 ! number of pixels on current ring in [0,Pi/2] (quadrant)
939952 transition = (iring == nside .or. iring == nside*3)
940953
19191919 ! New algorithm for Inclusive case: test boundary of edge pixels on each ring
19201920 ! 2013-04-02: bug correction in query_disc in inclusive mode
19211921 ! 2014-07-07: bug correction in discedge2fulldisc
1922 ! 2020-08-31: bug correction in check_edge_pixels (reported by R. de Belsunce)
19221923 !=======================================================================
19231924 #ifdef DOI8B
19241925 subroutine query_disc_8( nside, vector0, radius, listpix, nlist, nest, inclusive)
20152016 call pixels_on_edge(nside, irmin, irmax, phi0, dphitab, ringphi, ngr)
20162017 if (do_inclusive) then
20172018 ! sample edge pixels at larger Nside
2018 nsboost = 16
2019 nsideh = min(NS_MAX8, nside * int(nsboost,i8b))
2019 nsboost = 2**ceiling( log(1.1_DP/(radius*nside))/log(2.0_DP) ) ! make pixel smaller than disc (2020-08-31)
2020 nsboost = max(nsboost,16)
2021 nsideh = min(NS_MAX8, nside * int(nsboost,i8b))
20202022 radiush = fudge_query_radius(nsideh, radius, quadratic=.true.)
20212023
20222024 irmin = ring_num(nsideh, zmax, shift=+1) ! shifted South
20272029 zlist(iz-irmin+1) = ring2z(nsideh, iz)
20282030 enddo
20292031 call discphirange_at_z(vector0, radiush, zlist, nrh, dphilist, phi0)
2032 phi0 = mod(phi0 + TWOPI, TWOPI) ! [-Pi,Pi] -> [0,2Pi]
20302033 call check_edge_pixels(nside, nsboost, irmin, irmax, phi0, dphilist, ringphi, ngr)
20312034 deallocate(zlist, dphilist)
20322035 endif
4343 void *mapptr[2], *almptr[2];
4444
4545 CHECK_STACK_ALIGN(8);
46 UTIL_ASSERT(spin>0, "spin must not be zero");
4647 sharp_make_healpix_geom_info_2 (nside, wgt, zbounds[0], zbounds[1], &ginfo);
4748 sharp_make_rectangular_alm_info (lmax,mmax,2,&ainfo);
4849
108109 void *mapptr[2], *almptr[2];
109110
110111 CHECK_STACK_ALIGN(8);
112 UTIL_ASSERT(spin>0, "spin must not be zero");
111113 // sharp_make_healpix_geom_info (nside, 1, &ginfo);
112114 int i,nrings=4*nside-1;
113115 double *wgt=RALLOC(double,nrings);
0 !-----------------------------------------------------------------------------
1 !
2 ! Copyright (C) 1997-2013 Krzysztof M. Gorski, Eric Hivon,
3 ! Benjamin D. Wandelt, Anthony J. Banday,
4 ! Matthias Bartelmann, Hans K. Eriksen,
5 ! Frode K. Hansen, Martin Reinecke
6 !
7 !
8 ! This file is part of HEALPix.
9 !
10 ! HEALPix is free software; you can redistribute it and/or modify
11 ! it under the terms of the GNU General Public License as published by
12 ! the Free Software Foundation; either version 2 of the License, or
13 ! (at your option) any later version.
14 !
15 ! HEALPix is distributed in the hope that it will be useful,
16 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ! GNU General Public License for more details.
19 !
20 ! You should have received a copy of the GNU General Public License
21 ! along with HEALPix; if not, write to the Free Software
22 ! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 !
24 ! For more information about HEALPix see http://healpix.sourceforge.net
25 !
26 !-----------------------------------------------------------------------------
27 module udgrade_nr
28
29 ! --- in udgrade_template.f90 ---
30 ! subroutine sub_udgrade_nest
31 ! subroutine udgrade_ring
32 ! subroutine udgrade_nest
33
34 use healpix_types
35 use misc_utils
36
37 IMPLICIT none
38
39 private
40
41 public :: sub_udgrade_nest, udgrade_ring, udgrade_nest
42
43 ! SP and DP interface
44 interface sub_udgrade_nest
45 module procedure sub_udgrade_nest_s, sub_udgrade_nest_d
46 end interface
47
48 ! SP and DP, 1-dim and N-dim interface
49 interface udgrade_ring
50 module procedure udgrade_ring_1d_s, udgrade_ring_1d_d, udgrade_ring_nd_s, udgrade_ring_nd_d
51 end interface
52
53 interface udgrade_nest
54 module procedure udgrade_nest_1d_s, udgrade_nest_1d_d, udgrade_nest_nd_s, udgrade_nest_nd_d
55 end interface
56 !---------------------
57
58 contains
59
60 ! include SP implementation of routines
61 #include "udgrade_s_inc.f90"
62
63 ! include DP implementation of routines
64 #include "udgrade_d_inc.f90"
65
66
67 end module udgrade_nr
+0
-68
src/f90/mod/udgrade_nr.f90 less more
0 !-----------------------------------------------------------------------------
1 !
2 ! Copyright (C) 1997-2013 Krzysztof M. Gorski, Eric Hivon,
3 ! Benjamin D. Wandelt, Anthony J. Banday,
4 ! Matthias Bartelmann, Hans K. Eriksen,
5 ! Frode K. Hansen, Martin Reinecke
6 !
7 !
8 ! This file is part of HEALPix.
9 !
10 ! HEALPix is free software; you can redistribute it and/or modify
11 ! it under the terms of the GNU General Public License as published by
12 ! the Free Software Foundation; either version 2 of the License, or
13 ! (at your option) any later version.
14 !
15 ! HEALPix is distributed in the hope that it will be useful,
16 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ! GNU General Public License for more details.
19 !
20 ! You should have received a copy of the GNU General Public License
21 ! along with HEALPix; if not, write to the Free Software
22 ! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 !
24 ! For more information about HEALPix see http://healpix.sourceforge.net
25 !
26 !-----------------------------------------------------------------------------
27 module udgrade_nr
28
29 ! --- in udgrade_template.f90 ---
30 ! subroutine sub_udgrade_nest
31 ! subroutine udgrade_ring
32 ! subroutine udgrade_nest
33
34 use healpix_types
35 use misc_utils
36
37 IMPLICIT none
38
39 private
40
41 public :: sub_udgrade_nest, udgrade_ring, udgrade_nest
42
43 ! SP and DP interface
44 interface sub_udgrade_nest
45 module procedure sub_udgrade_nest_s, sub_udgrade_nest_d
46 end interface
47
48 ! SP and DP, 1-dim and N-dim interface
49 interface udgrade_ring
50 module procedure udgrade_ring_1d_s, udgrade_ring_1d_d, udgrade_ring_nd_s, udgrade_ring_nd_d
51 end interface
52
53 interface udgrade_nest
54 module procedure udgrade_nest_1d_s, udgrade_nest_1d_d, udgrade_nest_nd_s, udgrade_nest_nd_d
55 end interface
56 !---------------------
57
58 contains
59
60 ! include SP implementation of routines
61 include 'udgrade_s_inc.f90'
62
63 ! include DP implementation of routines
64 include 'udgrade_d_inc.f90'
65
66
67 end module udgrade_nr