readf,1,format= ...... [message #57392] |
Sat, 08 December 2007 13:18  |
woopik
Messages: 18 Registered: September 2007
|
Junior Member |
|
|
hi
i have a question
i have in a txt file some data
48883 149.55579541 12.44483936
.... .... ....
when i read a entire line
line=''
readf,1,line
print,line
i get a good output
48883 149.55579541 12.44483936
but when i read data like this
ttab = MAKE_ARRAY(nlines,3,/DOUBLE)
...
FMTp='(I5,2X,D13.8,2X,D13.8)'
for i=1,nlines do begin
READF,1,FORMAT=FMT,l1,l2,l3
ttab[i-1,0]=l1 & ttab[i-1,1]=l2 & ttab[i-1,2]=l3
endfor
and i print them
print,FORMAT=FMTp,ttab[0,0], ttab[0,1],ttab[0,2]
i get
48883 149.55580139 12.44483948
and this is not the same it should be
48883 149.55579541 12.44483936
why ?
i use idl 6.1 6.2
Wojtek
|
|
|
Re: readf,1,format= ...... [message #57444 is a reply to message #57392] |
Mon, 10 December 2007 06:35   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
woopik@interia.pl writes:
> meaby, but its a big problem for me ;-)
>
> i try
> a=5.4195140971e-04
> print,a,FORMAT='(e17.10)'
>
> and i get
> 5.4195139091e-04
Oh, I thought we were talking about reading it from
a file. Yes, in this case, you want this:
IDL> a=5.4195140971d-04
IDL> print,a,FORMAT='(e17.10)'
5.4195140971e-004
Cheers,
David
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|
|
|
|
|
Re: readf,1,format= ...... [message #57468 is a reply to message #57392] |
Sun, 09 December 2007 08:07   |
David Fanning
Messages: 11724 Registered: August 2001
|
Senior Member |
|
|
woopik@interia.pl writes:
> sorry a type error but nothing change when i use FMTp for both
> (FMT is quite similar)
>
> function read_local ,file
> FMT=
> '(I5,2X,D13.8,2X,D13.8,3X,F8.2,3X,F8.2,3X,F7.2,3X,F7.2,3X,F6 .2,3X,F6.2,3X,F6.2,3X,F6.2,4X,F6.2,3X,F6.2,3X,F6.2,2X,F6.2)'
> spawn, ['wc', '-l', file], result, /noshell
> nlines = long(result(0))
> ttab = MAKE_ARRAY(nlines-5,15,/DOUBLE)
> OPENR,1,file
> line=''
> readf,1,line
> for i=1,nlines-5 do begin
> READF,1,FORMAT=FMT, n,ra,dec, l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12
> ttab[i-1,0]=n & ttab[i-1,1]=ra & ttab[i-1,2]=dec
> ttab[i-1,3]=l1 & ttab[i-1,4]=l2 & ttab[i-1,5]=l3
> ttab[i-1,6]=l4 & ttab[i-1,7]=l5 & ttab[i-1,8]=l6
> ttab[i-1,9]=l7 & ttab[i-1,10]=l8 & ttab[i-1,11]=l9
> ttab[i-1,12]=l10 & ttab[i-1,13]=l11 & ttab[i-1,14]=l12
> endfor
> CLOSE , 1
> print,FORMAT=FMT,ttab[0,*]
> RETURN,ttab
> end
Well, this is most interesting. There is a mismatch between
your variables (n, ra, dec, etc.) and your FORMAT statement.
In other words, ra and dec, since they are undeclared in the
program, are by default floats. Your format statement is going
to try to read them as doubles. The "rules" of input state that
IDL "tries to do what you want to do". Here, it thinks what you
are trying to do, is stuff a double into a float, and it does
this correctly. The variable ttab is a double, but it has been
stuffed with a floating value (from ra and dec).
The solution is to declare the variables on your READF
statement to be what you want to read into. That is, doubles.
However, I completely agree with Vince that what you REALLY
want to do is read this data in another way, rather than
line by line, practically the worst way to read data in IDL
(ala READ_ASCII). I think I would take his structure advice.
That will also solve your problem here.
Cheers,
David
P.S. Here is the program I used to test your program with the
data you sent yesterday:
function read_local ,file
FMT='(I5,2X,D13.8,2X,D13.8)'
nlines = File_lines(file)
ttab = MAKE_ARRAY(3,nlines,/DOUBLE)
n = 0L
ra = 0.0D0
dec = 0.0D0
OPENR,1,file
for I=0,nlines-1 do begin
READF,1,FORMAT=FMT, n,ra,dec
ttab[0,I]=n & ttab[1,I]=ra & ttab[2,I]=dec
endfor
CLOSE , 1
print,FORMAT=FMT,ttab
RETURN,ttab
end
--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
|
|
|
Re: readf,1,format= ...... [message #57469 is a reply to message #57392] |
Sun, 09 December 2007 07:49   |
Vince Hradil
Messages: 574 Registered: December 1999
|
Senior Member |
|
|
On Dec 9, 8:50 am, woo...@interia.pl wrote:
> sorry a type error but nothing change when i use FMTp for both
> (FMT is quite similar)
>
> function read_local ,file
> FMT=
> '(I5,2X,D13.8,2X,D13.8,3X,F8.2,3X,F8.2,3X,F7.2,3X,F7.2,3X,F6 .2,3X,F6.2,3X,F6.2,3X,F6.2,4X,F6.2,3X,F6.2,3X,F6.2,2X,F6.2)'
> spawn, ['wc', '-l', file], result, /noshell
> nlines = long(result(0))
> ttab = MAKE_ARRAY(nlines-5,15,/DOUBLE)
> OPENR,1,file
> line=''
> readf,1,line
> for i=1,nlines-5 do begin
> READF,1,FORMAT=FMT, n,ra,dec, l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12
> ttab[i-1,0]=n & ttab[i-1,1]=ra & ttab[i-1,2]=dec
> ttab[i-1,3]=l1 & ttab[i-1,4]=l2 & ttab[i-1,5]=l3
> ttab[i-1,6]=l4 & ttab[i-1,7]=l5 & ttab[i-1,8]=l6
> ttab[i-1,9]=l7 & ttab[i-1,10]=l8 & ttab[i-1,11]=l9
> ttab[i-1,12]=l10 & ttab[i-1,13]=l11 & ttab[i-1,14]=l12
> endfor
> CLOSE , 1
> print,FORMAT=FMT,ttab[0,*]
> RETURN,ttab
> end
1) I would avoid using l (el) in variable names - hard to read
2) I would use file_lines to count the number of lines
3) I would define a structure and read each line in separately:
ttab = replicate({n:0,ra:0.0D,dec:0.0D,array:fltarr(12)},nlines)
for i=0L, nlines-5 do readf, lun, ttab[i]
Hope this helps!
|
|
|
Re: readf,1,format= ...... [message #57471 is a reply to message #57392] |
Sun, 09 December 2007 06:50   |
woopik
Messages: 18 Registered: September 2007
|
Junior Member |
|
|
sorry a type error but nothing change when i use FMTp for both
(FMT is quite similar)
function read_local ,file
FMT=
'(I5,2X,D13.8,2X,D13.8,3X,F8.2,3X,F8.2,3X,F7.2,3X,F7.2,3X,F6 .2,3X,F6.2,3X,F6.2,3X,F6.2,4X,F6.2,3X,F6.2,3X,F6.2,2X,F6.2)'
spawn, ['wc', '-l', file], result, /noshell
nlines = long(result(0))
ttab = MAKE_ARRAY(nlines-5,15,/DOUBLE)
OPENR,1,file
line=''
readf,1,line
for i=1,nlines-5 do begin
READF,1,FORMAT=FMT, n,ra,dec, l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12
ttab[i-1,0]=n & ttab[i-1,1]=ra & ttab[i-1,2]=dec
ttab[i-1,3]=l1 & ttab[i-1,4]=l2 & ttab[i-1,5]=l3
ttab[i-1,6]=l4 & ttab[i-1,7]=l5 & ttab[i-1,8]=l6
ttab[i-1,9]=l7 & ttab[i-1,10]=l8 & ttab[i-1,11]=l9
ttab[i-1,12]=l10 & ttab[i-1,13]=l11 & ttab[i-1,14]=l12
endfor
CLOSE , 1
print,FORMAT=FMT,ttab[0,*]
RETURN,ttab
end
|
|
|
|
|
Re: Readf [message #70207 is a reply to message #57392] |
Fri, 19 March 2010 05:54  |
Maarten[1]
Messages: 176 Registered: November 2005
|
Senior Member |
|
|
On Mar 19, 12:51 pm, bing999 <thibaultga...@gmail.com> wrote:
> However, it is the same format I don't understand why it prints Inf
> for A ( even if i initialize A = 0.d0)
Sorry, missed that. I don't understand that. Having a d in the format
code doesn't help either. Are you sure that A is double presision when
the read statement is executed? It certainly worked for me.
Maarten
|
|
|
Re: Readf [message #70208 is a reply to message #57392] |
Fri, 19 March 2010 05:52  |
Gray
Messages: 253 Registered: February 2010
|
Senior Member |
|
|
On Mar 19, 7:51 am, bing999 <thibaultga...@gmail.com> wrote:
> Hi,
>
> i have written a file in fortran this way:
>
> write(444,'(e14.6,1x,e14.6,1x,e14.6)',advance='yes') A, B, C
>
> where A has a value of 2.10^60 and the other ones 0.0000000
>
> The file is printed correctly but when i want to read it with IDL:
>
> readf,11,format='(e14.6,1x,e14.6,1x,e14.6)', A, B, C
>
> It displays Inf for A and 0.0000000 for B and C.
>
> However, it is the same format I don't understand why it prints Inf
> for A ( even if i initialize A = 0.d0)
>
> If somebody could help, it would really help me !
> Thanks
The problem is that you're reading it in as a float, which has a
maximum value of 10^38. You need to read them in as type double.
|
|
|
Re: Readf [message #70209 is a reply to message #57392] |
Fri, 19 March 2010 05:51  |
Maarten[1]
Messages: 176 Registered: November 2005
|
Senior Member |
|
|
On Mar 19, 12:51 pm, bing999 <thibaultga...@gmail.com> wrote:
> i have written a file in fortran this way:
>
> write(444,'(e14.6,1x,e14.6,1x,e14.6)',advance='yes') A, B, C
>
> where A has a value of 2.10^60 and the other ones 0.0000000
>
> The file is printed correctly but when i want to read it with IDL:
>
> readf,11,format='(e14.6,1x,e14.6,1x,e14.6)', A, B, C
>
> It displays Inf for A and 0.0000000 for B and C.
>
> However, it is the same format I don't understand why it prints Inf
> for A ( even if i initialize A = 0.d0)
Make sure A is double precision. 2.10^60 is beyond the range of float.
IDL> a = 2D60
IDL> b = float(a)
% Program caused arithmetic error: Floating overflow
IDL> help
% At $MAIN$
A DOUBLE = 2.0000000e+60
B FLOAT = Inf
If you make sure that a, b, and c exist before the read statement (as
double precision floats), then all is well. I sure would like to have
a compile_opt to use doubles by default.
Maarten
|
|
|