; ;+ ; NAME: ; ; READ_PARAMETERS ; ; PURPOSE: ; ; Reads keyword values from an ASCII file. ; ; DESCRIPTION: ; ; Reads a tagged list of parameters into a structure from an ASCII file of the form: ; ; # Comment ; ... ; ; TAG1 = value ; TAG2 = value ; ... ; ; CATEGORY: ; ; Input/Output. ; ; CALLING SEQUENCE: ; ; READ_PARAMETERS, filename [, structure] ; ; ; INPUTS: ; ; Filename: name of the text file to read. ; ; Structure: structure, with the tag names identical to the tags in the parameter file, ; in which the read parameters are stored. ; The routine is not case sensitive. ; If Structure is not a structure-type variable or it's undefined, then it is replaced ; by a structure created by the program which will contain all the tags found ; in the text file. In this case all the tags will be string type. ; ; ; OUTPUTS: ; ; Structure: The function returns Structure with the tags values equal to the values read in the file. ; If Structure is not a structure-type variable or it's undefined, then it is replaced ; by a structure created by the program which will contain all the tags found ; in the text file. In this case all the tags will be string type. ; ; If the number of elements assigned to a tag in the parameters file is different from ; the number of elements defined, for that tag, in the input structure, then the ; structure will be re-defined. This make possible to read array tags even if their ; number of elements is unknown. ; ; ; PROCEDURE: ; ; The file is searched for any tag in the input structure. ; If the tag is not found its value remains unchanged. ; The file can contain more tags than the structure: in this case they are ignored. ; Once found a tag, its value is supposed to be all that is found after the equal sign; ; array elements must be separated by commas. ; Any byte type tag in the input structure is interpreted as boolean type: ; 0 -> FALSE, other values -> TRUE, and correspondingly the file is searched for ; the strings "NO" or "YES", case insensitive. ; ; ; CALLS: ; ; The procedure READ_PARAMETERS_NUMBER is called. ; ; ; See Also: ; ; WRITE_PARAMETERS ; ; EXAMPLE: ; ; Suppose we have an ASCII file named 'Parameters_Example.cfg' with the the following content: ; ; ############################# ; # Parmeters file # ; ############################# ; ; # Parameter 1: ; Message = "text" ; ; # Parameter 2: ; Value = 100. ; ; # Parameter 3: ; Vector = 1., 2., 3., 4. ; ; we can read it in a structure by first defining the structure and then using READ_PARAMETERS: ; ; Parameters = {Message: "", Value: 0., Vector: fltarr(4)} ; Read_Parameters, 'Parameters_Example.cfg', Parameters ; ; ; ; MODIFICATION HISTORY: ; ; Feb 2004 - Gianluca Li Causi, INAF - Rome Astronomical Observatory ; Apr 2004 - Added possibility to use undefined Structure. ; June 2004 - Added possibility to read vector data. ; Gianluca Li Causi, INAF - Rome Astronomical Observatory ; licausi@mporzio.astro.it ; http://www.mporzio.astro.it/~licausi/ ; May 2005 - Gianluca Li Causi, INAF - Rome Astronomical Observatory ; - Fix a bug for which the file units weren't deallocated. ; September 2005 - Gianluca Li Causi, INAF - Rome Astronomical Observatory ; - Add dynamic re-definition of structure in order ; to allow the reading of arrays with unknown number of elements. ; ;- PRO Read_Parameters, filename, structure ON_ERROR, 2 IF N_PARAMS() LT 2 THEN MESSAGE, 'Both Filename and Structure must be given!' IF n_elements(structure) EQ 0 THEN structure = 0 IF size(structure, /type) LT 8 THEN BEGIN Read_Parameters_Number, filename, number, tags=tags structure = CREATE_STRUCT(tags[0], '') FOR i = 1, number-1 DO structure = CREATE_STRUCT(structure, tags[i], '') ENDIF tags = tag_names(structure) tags = strlowcase(tags) ntags = n_elements(tags) OPENR, unit, filename, /GET_LUN line = "" i = 0 WHILE i LT ntags DO BEGIN IF NOT EOF(unit) THEN BEGIN READF, unit, line line = strtrim(line, 2) ;elimina eventuali spazi iniziali o finali pos_equal = strpos(line, "=") IF pos_equal GE 0 THEN BEGIN tag_side = strmid(line, 0, pos_equal) ;parte prima dell'uguale pos = strpos(strlowcase(tag_side), tags[i]) ;posizione del tag cercato tag_string = strtrim(strlowcase(tag_side), 2) ;elimina gli spazi iniziali e finali IF tag_string EQ tags[i] AND pos EQ 0 AND strlen(line) GE 3 THEN BEGIN ;il tag deve essere la prima scritta sulla riga pos = strpos(line, '=', pos) value_string = strmid(line, pos+1, strlen(line)) value_string = str_subst(value_string, '"', '') ;elimina eventuali virgolette doppie value_string = str_subst(value_string, "'", '') ;elimina eventuali virgolette semplici value_string = strtrim(value_string, 2) ;elimina eventuali spazi iniziali o finali ;size = size([structure.(i)]) ;n_el = n_elements(structure.(i)) ;;Check of scalar or array: ;pos_bra1 = strpos(value_string, '[') ;pos_bra2 = strpos(value_string, ']') ;IF pos_bra1 EQ 0 AND pos_bra2 EQ (strlen(value_string)-1) THEN BEGIN ;array di piu' elementi ; ;IF n_el GT 1 THEN BEGIN ;array di piu' elementi value_string = str_subst(value_string, '[', '') ;elimina "[" value_string = str_subst(value_string, ']', '') ;elimina "]" value_string = strsplit(value_string, ',', /extract) ;elementi separati da virgola ;ENDIF type = size(structure.(i), /type) n_el = n_elements(value_string) IF n_el EQ 1 THEN value_string = value_string[0] IF n_el NE n_elements(structure.(i)) THEN BEGIN ;se diverso numero di elementi della definizione della structure, la ridefinisce ;Define the first tag: IF i NE 0 THEN BEGIN new_structure = CREATE_STRUCT(tags[0], structure.(0)) ENDIF ELSE BEGIN new_structure = CREATE_STRUCT(tags[0], make_array(n_el, TYPE=type)) ENDELSE ;Define the other tags: FOR c = 1, ntags-1 DO BEGIN IF c NE i THEN BEGIN new_structure = CREATE_STRUCT(new_structure, tags[c], structure.(c)) ENDIF ELSE BEGIN new_structure = CREATE_STRUCT(new_structure, tags[c], make_array(n_el, TYPE=type)) ENDELSE ENDFOR structure = new_structure ENDIF ;Assign value to the current tag: IF type EQ 1 THEN BEGIN ;dato booleano --> byte per idl FOR j = 0, n_el-1 DO structure.(i)[j] = where(strupcase(value_string[j]) EQ ['NO', 'YES']) ENDIF ELSE BEGIN structure.(i) = FIX(value_string, TYPE=type) ENDELSE i = i + 1 ;next tag point_lun, unit, 0 ;rewind the file ENDIF ENDIF ENDIF ELSE BEGIN i = i + 1 ;next tag point_lun, unit, 0 ;rewind the file ENDELSE ENDWHILE FREE_LUN, unit, /FORCE END