comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Error when calling ENVI_WRITE_ENVI_FILE
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Error when calling ENVI_WRITE_ENVI_FILE [message #86313] Fri, 25 October 2013 08:35 Go to next message
Simon Mitchell is currently offline  Simon Mitchell
Messages: 6
Registered: October 2013
Junior Member
Hi All,

I am getting an error when using the ENVI_WRITE_ENVI_FILE command. Note that I am a beginner with using IDL.

The error that I am getting is:
ERROR: "FLOAT: Struct expression not allowed in this context: DATA." The result may be invalid.

I have to add, that this error does not stop my code from creating a file, but the values are not what I am expecting.

A little background on what I am trying to do.
I want to be able to replicate in IDL (for batch script) opening multiple ASCII files (each representing a band of image data) and then saving them as an ENVI Standard file with multiple bands.
So essentially doing the "File->Open External File->Generic Formats->ASCII" for three files, then "Save File As->ENVI Standard" as one file with three bands in BSQ format.

My code is as follows, and I am just using a dummy test image of 11 samples and lines as my input, with 6 header lines.

PRO COMBINE_ASCII

opendir = 'D:\Directory'

redfile = opendir+'red_output_short.txt'
mirfile = opendir+'mir_template_short.txt'
tirfile = opendir+'tir_template_short.txt'
ofname = opendir+'random_image_1'
descrip = 'Random point image #1'
ns = 11
nl = 11
nc = 3*nl

rnd_data = FLTARR([ns], [nc]) ;float array of ns = 11, nl = 11 for 3 bands
;rnd_data = FLTARR([ns],[nl],3)

;Open the files

OPENR, lun_red, redfile, /GET_LUN
red_data = READ_ASCII(redfile, DATA_START = 6, DELIMITER = string(9B))

rnd_data = [red_data]

OPENR, lun_mir, mirfile, /GET_LUN
mir_data = READ_ASCII(mirfile, DATA_START = 6, DELIMITER = string(9B))

rnd_data = [[rnd_data], [mir_data]]

OPENR, lun_tir, tirfile, /GET_LUN
tir_data = READ_ASCII(tirfile, DATA_START = 6, DELIMITER = string(9B))

rnd_data = [[rnd_data], [tir_data]]

;rnd_data = [[red_data],[mir_data],[tir_data]]

;OPENW, lun_out, ofname, /GET_LUN

print, rnd_data

;reddata = READ_ASCII(redfile, DATA_START = 6)
;mirdata = READ_ASCII(mirfile, DATA_START = 6)
;tirdata = READ_ASCII(tirfile, DATA_START = 6)


ENVI_WRITE_ENVI_FILE, rnd_data, FILE_TYPE = 4, INTERLEAVE = 0, NB = 3, NS = ns, NL = nl, OUT_DT = 4, OUT_NAME = ofname

; FILE_TYPE = 4

ENVI_SETUP_HEAD, FNAME = ofname, NS = ns, NL = nl, NB = 3, $
XSTART = 0, YSTART = 0, DATA_TYPE = 1, INTERLEAVE = 0, $
file_type = 4, $
DESCRIP = descrip, /WRITE, /OPEN

CLOSE, /ALL

END

I am wondering if any one can tell me where I am going wrong, or could suggest a better way of doing this!!! As you can probably guess, I am not the best idl coder and have only been using it for a short time, but I think I may be doing something wrong with the array concatenation.

Many thanks in advance for your help.

Simon
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86315 is a reply to message #86313] Fri, 25 October 2013 09:02 Go to previous messageGo to next message
Phillip Bitzer is currently offline  Phillip Bitzer
Messages: 223
Registered: June 2006
Senior Member
Hi Simon-

Well, you're not getting what you think in the "data" variables. Check out this from the help for READ_ASCII:

The result is an IDL structure array containing the data

And this variable (ultimately) is what you're using in ENVI_WRITE_ENVI_FILE. Only problem is, according to the help, the parameter that you should pass is:

This is a 2D or 3D data array of type byte, integer, unsigned integer, long integer, unsigned long integer, long 64-bit integer, unsigned long 64-bit integer, floating-point, double-precision, complex, or double-precision complex.

You have to extract the pertinent data from the READ_ASCII function, and put it in the format ENVI_WRITE_ENVI_FILE expects. (I'll note there's probably better ways than using READ_ASCII here, but you can certainly get it to work.)

There's a couple of other things going on. Consider these lines:

rnd_data = FLTARR([ns], [nc]) ;float array of ns = 11, nl = 11 for 3 bands
...
red_data = READ_ASCII(redfile, DATA_START = 6, DELIMITER = string(9B))

rnd_data = [red_data]

Basically, the first line isn't doing anything for you, because you change the variable (more formally, dynamically cast the variable) from an array to a structure in the last line.

Hope this helps!
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86321 is a reply to message #86313] Fri, 25 October 2013 14:57 Go to previous messageGo to next message
Josh Sixsmith is currently offline  Josh Sixsmith
Messages: 13
Registered: December 2012
Junior Member
>
> OPENR, lun_red, redfile, /GET_LUN
>
> red_data = READ_ASCII(redfile, DATA_START = 6, DELIMITER = string(9B))

The READ_ASCII function doesn't need the file to be opened using openr. READ_ASCII will handle that itself. Just pass it the string containing the filename of the ascii file to read.

Use the openr command in conjunction with the read/readf/readu commands.

Cheers
Josh
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86335 is a reply to message #86321] Mon, 28 October 2013 08:55 Go to previous messageGo to next message
Simon Mitchell is currently offline  Simon Mitchell
Messages: 6
Registered: October 2013
Junior Member
Thanks for responding Phil and Josh.

I guess I'm just not understanding what is going on here.
What is the difference between a structure array and a data array?

When I use the code
red_data = READ_ASCII(redfile, DATA_START = 6, DELIMITER = string(9B))
rnd_data = [red_data]
print, red_data
print, rnd_data

I get the result (using a 3x3 image as an example)
{
1 1 1
1 1 1
1 1 1
}
{
1 1 1
1 1 1
1 1 1
}

I then want to add the second band to the data (to make it BSQ format)
mir_data = READ_ASCII(mirfile, DATA_START = 6, DELIMITER = string(9B))
rnd_data = [[rnd_data], [mir_data]]
print, rnd_data

I get
{
1 1 1
1 1 1
1 1 1
}{
2 2 2
2 2 2
2 2 2
}
when what I would expect would be
{
1 1 1
1 1 1
1 1 1
2 2 2
2 2 2
2 2 2
}
and so on for the third band. Am I correct in my assumption? I assume that what I'm actually getting is a [3,3,3] array, rather than my expected [3,9] array.

But I'm also not understanding is why the ENVI_WRITE_ENVI_FILE is not accepting this data?
Would you please be able to step me through my questions?

Or if someone has a better method for loading ASCII files into an ENVI standard image, could they please pass this on to me.

Many thanks in advance

Simon
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86337 is a reply to message #86335] Mon, 28 October 2013 09:34 Go to previous messageGo to next message
Phillip Bitzer is currently offline  Phillip Bitzer
Messages: 223
Registered: June 2006
Senior Member
Hi Simon-

First, some terminology. You can have an "array of structures". You can also have a "structure with tags that are arrays".

Before we jump into it, the use of help is much more, well, helpful, than print. You'll see this in action below.

Consider this variable:

IDL> str = {data:FLTARR(3, 3)}

Notice "str" is a structure, and "data" is a tag (or field) of "str". Try this:

IDL> help, str

So, "str" is in fact a structure. In order to access the tag data, we use:

IDL> help, str.data

So, str.data (again, the tag "data" in the structure "str") is a 3x3 float array.

Print it if you'd like:
IDL> print, str.data

This is how you deal with a "structure that has tags that are arrays".

-------

We can take this further. Consider:
arrOfStr = REPLICATE(str, 2)

Now, 'arrofStr' is an "array of structures". See for yourself:
IDL> help, arrOfStr

You can print this too:
IDL> print, arrOfStr

What you *really* want is the data tag from each structure:
IDL> help, arrOfStr.data
IDL> print, arrOfStr.data

-------
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86343 is a reply to message #86337] Mon, 28 October 2013 18:07 Go to previous messageGo to next message
Josh Sixsmith is currently offline  Josh Sixsmith
Messages: 13
Registered: December 2012
Junior Member
> What you *really* want is the data tag from each structure:
>
> IDL> help, arrOfStr.data
>
> IDL> print, arrOfStr.data
>
>
>
> -------

Exactly what Phillip has mentioned. Use the tag names to get at the actual data array contained within the structure. The "data" argument to "ENVI_WRITE_ENVI_FILE" is the array itself, not a structure that contains the arrays.

You could pre-allocate an array that will contain all the bands.
eg

red_data = READ_ASCII(redfile, DATA_START = 6, DELIMITER = string(9B))
columns = 4000 ; or whatever it may be
rows = 4000
bands = 7
all_bands = FLTARR(columns, rows, bands)
all_bands[*,*,0] = red_data.data_tag_name ;data_tag_name could be data as in the example provided by Phillip.

and so on for all the necessary bands.

bnames=['1','2','3','4','5','6','7']

Then
ENVI_WRITE_ENVI_FILE, all_bands, bnames=bnames, nb=bands, nl=rows, ns=columns, out_name='my_envi_file'

Hope that helps.

Cheers
Josh
Re: Error when calling ENVI_WRITE_ENVI_FILE [message #86372 is a reply to message #86343] Fri, 01 November 2013 04:17 Go to previous message
Simon Mitchell is currently offline  Simon Mitchell
Messages: 6
Registered: October 2013
Junior Member
Thank you for all your help Phil and Josh.

My code is working and I am getting good results, and I have learnt some more about IDL.

Thank you
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Airy function implementation?
Next Topic: New Coyote Store Up and Running

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 09:15:57 PDT 2025

Total time taken to generate the page: 0.00582 seconds