0

I have a very long lookup table (~40,000 lines) that I am using for my code. Currently, I have it set to grab 4 arrays from my lookup table in the subroutine that uses it, but I call that subroutine ~3,000 times. I would rather not waste processing time grabbing this table as arrays repeatedly. Is there a way to grab them in my main program, store them, and source them later in my subroutine?

My current code grabs the lookup table in 4 separate arrays of 39,760 lines, and I am currently calling it like this:

READCOL, 'LookupTable2.txt', F='D,D,D,D',Albedo, Inertia, NightT, DayT

EDIT: I should probably note I have IDL 6.2, but if there is a way to do it in a newer version, I would still appreciate knowing how.

EDIT 2: My current program has a function which saves 4 arrays and executes the main function. Can I call my function with arrays as an argument? That way I wouldn't have to keep creating the same array

Something like:

Pro
  FUNC(Array1, Array2, Var1, Var2, Var3)
END
DavidH
  • 415
  • 4
  • 21
Cam
  • 93
  • 1
  • 5

1 Answers1

0

There are several ways you can do this.

It looks like you have four columns and 40,000 lines, correct?

Then you can do the following. First, I will assume there is no header data in the ASCII file for the following commands.

FUNCTION read_my_file,file_name

;;  Assume FILE_NAME is full path to and including file name with extension
fname = file_name[0]
;;  One could also find the file with the following
;;    fname = FILE_SEARCH([path to file],[file name with extension])

;;  Define the number of lines in the file
nl = FILE_LINES(fname[0])
;;  Define empty arrays to fill
col1 = DBLARR(nl[0])
col2 = DBLARR(nl[0])
col3 = DBLARR(nl[0])
col4 = DBLARR(nl[0])
dumb = DBLARR(4)
;;  Open file
OPENR,gunit,fname[0],ERROR=err,/GET_LUN
IF (err NE 0) THEN PRINT, -2, !ERROR_STATE.MSG   ;;  Prints an error message
FOR n=0L, nl[0] - 1L DO BEGIN
  ;;  Read in file data
  READF,gunit,FORMAT='(4d)',dumb
  ;;  Fill arrays
  col1[n] = dumb[0]
  col2[n] = dumb[1]
  col3[n] = dumb[2]
  col4[n] = dumb[3]
ENDFOR
;;  Close file
FREE_LUN,gunit
;;  Define output
output = [[col1],[col2],[col3],[col4]]

;;  Return to calling routine
RETURN,output
END

Note that this will work better if you provide an explicit width for the format statement, e.g., '(4d15.5), which means a 15 character input with 5 decimal places.

This will return col1 through col4 to the user or calling routine as an [N,4]-element array, e.g., col1 = output[*,0]. You could use a structure where each tag contains one of the colj arrays or you could return them through keywords.

Then you can pass these arrays to another function/program in the following way:

PRO my_algorithm_wrapper,file_name,RESULTS=results
;;  Get data from files
columns = read_my_file(file_name)
;;  Pass data to [algorithm] function
results = my_algorithm(columns[*,0],columns[*,1],columns[*,2],columns[*,3])
;;  Return to user
RETURN
END

To call this from the command line (after making sure both routines are compiled), you would do something like the following:

IDL> my_algorithm_wrapper,file_name,RESULTS=results
IDL> HELP,results    ;;  see what the function my_algorithm.pro returned

The above code should work with IDL 6.2.

General Notes

  1. Try to avoid using uppercase letters in IDL routine names as it can cause issues when IDL searches for the routine during a call or compilation statement.
  2. You need to name the program/function in the line with the PRO/FUNCTION statement at the beginning of the file. The name must come immediately after the PRO/FUNCTION statement.
  3. It is generally wise to use explicit formatting statements to avoid ambiguities/errors when reading data files.
  4. You can pass any variable type (e.g., scalar integer, array, structure, object, etc.) to programs/functions so long as they are handled appropriately within the program/function.
honeste_vivere
  • 308
  • 5
  • 11
  • So, I'm a tad confused as I am new to IDL and coming from C++. This seems to be a great way to call my data into an array, but I think I have done that with my code above (It may not be the best however). In your last paragraph, are you saying I can include arrays in a fuction call? EDIT: I'll post it in my original post for formatting – Cam Jun 07 '16 at 17:48
  • @Cam - Yes, you can pass/return arrays to/from programs and functions in IDL. The syntax in your 2nd update is incorrect, however. You need to define the output of your arbitrary function, `FUNC`. – honeste_vivere Jun 07 '16 at 18:07
  • @Cam - IDL is in many ways similar (functionally) to Fortran and Python (except that FOR, WHILE, etc. loops are very slow since it is a vectorized language... well I know C++ is much much faster with loops than IDL but do not recall off hand if Fortran or Python care). – honeste_vivere Jun 07 '16 at 18:19