read ascii file

166 views
Skip to first unread message

AG

unread,
Sep 8, 2021, 4:24:13 PM9/8/21
to idl-pvwave
Hello,

I want to read a file contains hundreds of rows like the attached sample.

I try to use readcol and read_ascII but not work.

Ali


sample

markus.sc...@gmail.com

unread,
Sep 9, 2021, 10:09:40 AM9/9/21
to idl-pvwave
this is a fixed width file, with empty fields. Load first all the content:
nl=file_lines(filename)
lines=strarr(nl)
openr,lun,/get_lun,filename
readf,lun,lines
close,lun
Then use strmid to extract and float and long to convert the string to numbers and strtrim(field,2) to trim white spaces.

Message has been deleted

markus.sc...@gmail.com

unread,
Sep 9, 2021, 10:13:54 AM9/9/21
to idl-pvwave
Instead of strmid you can also use strsplit(lines[1:-1],'|',/extract)
[typo corrected, older post deleted]

markus.sc...@gmail.com schrieb am Donnerstag, 9. September 2021 um 16:12:14 UTC+2:
Instead of strmid you can also use strsplot(lines[1:-1],'|',/extract)

AG

unread,
Sep 9, 2021, 1:22:36 PM9/9/21
to idl-pvwave
Thanks very much.

When I try to extract columns the following error appears

> STRTOK: Expression must be a scalar or 1 element array in this context: <STRING    Array[8]>

code as

**********************************************************************
  filename='txx'
  nl=file_lines(filename)
  print,nl
  lines=strarr(nl)
  openr,lun,/get_lun,filename
  readf,lun,lines
  close,lun
  free_lun,lun
  data=strsplit(lines[1:-1],'|',/extract)

  fields = list()
  For i = 0, nl - 1 do fields.add, strtok( data[ i ] )
  fields = fields.toArray()

end
**********************************************************************

markus.sc...@gmail.com

unread,
Sep 10, 2021, 8:33:27 AM9/10/21
to idl-pvwave
Your problem is specific to IDL<8.0.  The following hopefully works:
pos=strsplit(lines[1],'|')
start=pos+1
width=[pos[1:-1],strlen(lines[1])+2]-pos-2
nf=n_elements(pos)
fields=strarr(nf,nl)
for i=0,nf-1 do fields[i,*]=strtrim(strmid(lines,pos[i],width[i]),2)

header=fields[*,1]
w=(where(strlen(fields[2,*]) eq 1))[1:-1]
config      =      reform(fields[0,w])
term        =      reform(fields[1,w])
J           = long(reform(fields[2,w]))
Level       =float(reform(fields[3,w]))
Uncertainty =float(reform(fields[4,w]))
Lande       =float(reform(fields[5,w]))
;...

AG

unread,
Sep 11, 2021, 9:31:01 AM9/11/21
to idl-pvwave

Thanks very much, I want to ask about two things

1- when I print 60563.614 it will 60563.613, I want to print the same input number
IDL> print,double(60563.614)
       60563.613

2- I sort data according to column 2, but if data in column 2 as the same I want to sort these rows only according to column1 as the following example


  29   2          1.202e-07
  17   3          9.772e-08
  19   4          1.000e-07
  19   5         1.000e-07
  40   6          1.549e-07
  25   6         1.175e-07
  28   8         1.202e-07
  93  20        1.072e-06
  66  20         3.802e-07
  60  20         3.020e-07
  61  21         3.311e-07

I want it to become

  29   2          1.202e-07
  17   3          9.772e-08
  19   4          1.000e-07
  19   5         1.000e-07
  25   6         1.175e-07
  40   6          1.549e-07
  28   8         1.202e-07
  60  20         3.020e-07
  66  20         3.802e-07
  93  20        1.072e-06
  61  21         3.311e-07

Wayne Landsman

unread,
Sep 11, 2021, 11:25:20 PM9/11/21
to idl-pvwave
1.  Once you create a variable as Float (the default), you can't improve the precision by casting it as Double()
You should read/create the variable as double in the beginning

IDL> print,double(60563.614)

       60563.613

IDL> print,double(60563.614d)

       60563.614

2.   Craig Markwardt wrote a program multisort.pro to sort on multiple keys:

https://cow.physics.wisc.edu/~craigm/idl/down/multisort.pro

Wayne

AG

unread,
Sep 13, 2021, 2:09:07 PM9/13/21
to idl-pvwave
Thanks very much

AG

unread,
Dec 23, 2021, 5:29:45 AM12/23/21
to idl-pvwave
Hello,
Now I have another file but the  length of (fields[2,*]) can be equal 1 or 3 or 5, how I can modify it to read any length of (1, 3 , and 5)
w=(where(strlen(fields[2,*]) eq 1))[1:-1]

Thanks

AG

unread,
Dec 28, 2021, 1:30:56 AM12/28/21
to idl-pvwave
Hello,
Now I have another file but the  length of (fields[2,*]) can be equal 1 or 3 or 5, how I can modify it to read any length of (1, 3 , and 5)
w=(where(strlen(fields[2,*]) eq 1))[1:-1]

Thanks

Reply all
Reply to author
Forward
0 new messages