|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
aerotex
Joined: 05 Jul 2007 Posts: 10
|
Posted: Tue Jan 27, 2009 7:58 pm Post subject: Keyword driven input in Fortran |
|
|
Is there a way to use keywords in an input file for a Fortran code, so that the entries can be listed in any order, and entries can be left out if not required?
My current input file is along the lines of:
60.10 Velocity
0 Verbose output (0 is false, 1 is true)
1.091 Chord
i.e. the inputs are in a specific order and are all required. I would like to do something along the lines of:
$chord = 1.091
$velocity = 60.1
(where the verbose input can be left out as it is false, and it would not matter what order the inputs were listed, as they are discerned by their keyword, starting with $).
Is this possible in Fortran (I believe I have seen it done in C++), and if so, can anyone recommend a good source of information on how to achieve it?
Many thanks
Richard |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Jan 27, 2009 9:13 pm Post subject: |
|
|
Richard,
Read each line into a CHARACTER variable, and then work out what the heck it all means by a process of deconstruction - looking at characters and groups of characters. A computer scientist would call this "parsing".
It is always easier to do this if you use a token (such as your $) that denotes the start of the descriptor, and another (such as =) that denotes the end of the descriptor and beginning of the value.
May I suggest that you also add another token (such as ;) at the end of the line, so that you simply need to find the positions in the string where descriptor and value end.
Then extract the substrings, and remove blanks. Start with the descriptor, and change all to the same case. Then compare to your valid descriptors - possibly using length as a factor. Finally, when you have found the descriptor, you will know whether to look for an INTEGER or REAL (or COMPLEX etc) value. Extract that from the substring using an internal read (e.g. READ(SUBSTRING, ... etc)
If you want to be able to use:
value=descriptor or
descriptor=value
interchangeably, then you have a more difficult job than if all lines are the same way round. It is a little more involved if you want to extract multiple values, but lots more complex if you wish to parse expressions like
3.5 + 2.3*sin(30)
I've seen code to do that advertised on the web, but I can't find it now.
You have to be prepared to handle errors at every stage.
Hope this helps.
Eddie |
|
Back to top |
|
|
aerotex
Joined: 05 Jul 2007 Posts: 10
|
Posted: Tue Jan 27, 2009 9:37 pm Post subject: |
|
|
Eddie,
Thanks very much. I was hoping there was a simpler way to do it than a forced comparison, but that was obviously wishful thinking!
I can stipulate the form of descriptor=variable to simplify slightly, and I do not need to read any complex statements such as the example you gave.
Thanks for the tips on how to deconstruct it all.
Richard |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2555 Location: Sydney
|
Posted: Tue Jan 27, 2009 10:35 pm Post subject: |
|
|
Richard,
You could also try NAMELIST formatting, as this may more easily provide what you want.
I've used my own parsing routines for reading free format named variables, as Eddie has suggested, but that has been a project over many years.
If anyone has had success with NAMELIST, I'd like to know.
John |
|
Back to top |
|
|
aerotex
Joined: 05 Jul 2007 Posts: 10
|
Posted: Wed Jan 28, 2009 8:56 am Post subject: |
|
|
I have used the NAMELIST method in previous programmes. However, in this case it doesn't really offer me the flexibility I am after. Also, some other users do not seem to like the input method, finding it unclear. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Jan 28, 2009 3:46 pm Post subject: |
|
|
I always thought that namelist was one of the daftest bits of Fortran, as it required the user to know the variable names inside a program, which you wouldn't necessarily want to put all that in the "user manual". That namelist keeps on being part of fortran, whereas really useful and traditional things go on the list for deletion, always strikes me as bonkers.
The substring notation even in Fortran-77 is enough to do the basic job.
You don't necessarily have to blindly sort through all possible keywords (say) alphabetically. You can do a preliminary sort based on length, and another based on initial letter.
Fortunately, you can do the most elaborate things in very little time on a modern PC.
Perhaps the first job is to write down a list of possible keywords, and see what patterns there are. I used to do such things on the back of old computer cards ....
Eddie |
|
Back to top |
|
|
brucebowler Guest
|
Posted: Thu Jan 29, 2009 2:46 pm Post subject: Re: |
|
|
LitusSaxonicum wrote: | I always thought that namelist was one of the daftest bits of Fortran, as it required the user to know the variable names inside a program, which you wouldn't necessarily want to put all that in the "user manual". |
And how is that different than what the O/P wants, which is to have the user provide a keyword based input where the user needs to know the keywords (or variables :-). It's up to the programmer to make the names meaningful (and then only those the programmer specifies as enter-able via namelist).
LitusSaxonicum wrote: | That namelist keeps on being part of fortran, whereas really useful and traditional things go on the list for deletion, always strikes me as bonkers. |
That useful things get on the list strikes me as bonkers as well. If namelist makes it to the list, that will be the MOST bonkers decision IMHO.
Bruce |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Thu Jan 29, 2009 10:56 pm Post subject: |
|
|
Bruce,
You obviously use NAMELIST, or like it, or both. Your comments taking me to task made me do several bits of research to see if my opinion was unsupportable. In FTN95, as the CHM file tells us:
"Although not described here, namelist input has been extended to allow comments to follow one or more object name / value pairs on a line. This allows users to document how a namelist input file is structured, which values are valid, and the meaning of certain values. Each line in the namelist input may contain information about name / value pairs. This additional information may improve the documentation of the input file."
I couldn't actually remember the precise syntax for namelist (obviously, as I don't use it), so I looked back at the user manuals for several earlier versions of fortran I have used, and trawled through a number of books. I had a recollection that namelist was not widely supported. It is now too difficult to check various mainframes, but I started to look through the manuals for some old PC compilers. The manual for FTN77/386 does not mention it. Nor Digital Research Fortran 77, Nor MS Fortran 77 version 1.3, 3.1 or 5.1. Nor Prospero Fortran for GEM ... It is in Fortran Powerstation 1.0 (which is fortran-77), although there it has bizarre behaviour, possibly (depending on compiler settings) truncating the namelist names to 6 characters. Finally finding namelist stopped me from researching several other compilers' manuals tonight.
Turning to my textbook collection, I had a look in Metcalf's Effective Fortran 77, which doesn't mention namelist. I looked in Metcalf's Fortran Optimization - no namelist. In Kruger's Efficient Fortran Programming - no namelist. It does get a little over a page in Metcalf and Reid's Fortran 8x Explained, although that is not a user manual, and Fortran-90 had some differences when it eventually came out. I began to wonder if it was new to fortran-90. But I couldn't credit that, as I clearly remembered reading it in the CDC-6400 manual when even fortran-77 was esoteric, and had a vague memory of seeing it in McCracken, and in a Fortran-66 compiler I had with my first PC. Finally, in Willé's Advanced Scientific Fortran I found the answer. In the half-page devoted to namelist, I read "Another useful addition to Fortran 90 is the NAMELIST construct", and later "The reader should note that, although supported by many Fortran 77 compilers, the exact form of the records read and written by NAMELIST was not standardised until Fortran 90". The "many" presumably didn't include most of those for the PC!
At least now I know the underlying reason for my prejudice: namelist wasn't always available, and even when it was, it was non-standard. Since fortran-90, it has been standard, which I suppose has given me over a decade and a half to find out about it and change my mind. But where on earth do I find out about FTN95's implementation, or its extensions so tantalisingly described in the quote above, so that discovering the truth I may recant? (Please don't point me at the ANSI standard. That too is not a user guide).
So, my flip remark about namelist being daft relates to the many years when it was non-standard, or not included in some compilers. Things are better now ... Oh Dear ... namelist in FTN95 is also non-standard!
Returning to those things scheduled for termination, am I not correct in thinking that the list is ever-changing? Progress is one thing, but backwards compatibility is often useful. I could give many examples both inside and outside the computing field. To paraphrase a well known saying "if it ain't broke, don't break it"!
Best regards
Eddie
PS. So how about posting a code snippet? |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2555 Location: Sydney
|
Posted: Fri Jan 30, 2009 12:13 am Post subject: |
|
|
Thanks Eddie and Bruce for your comments.
I have long had a project of improved free format input, both for data presentation and programming style and in the last few months I have been trying to find some free time to progress my latest effort. So my interest in this subject.
I have not had the time to put into testing NAMELIST, but as an overview it does look a bit clumsy. Bruce, any experience of this ?
I've certainly developed input line parsing routines, including the use of +-*/, but not functions. This was included to improve the definition of values, by including equations which clarify the value or for unit conversion. The result of this routine is a list of tokens and values, to be later analysed wrt the input requirement.
The hardest part of free format input is error checking and confirmation of a minimum amount of supplied data. Here again my impression was NAMELIST does not help.
Any comments ?
John |
|
Back to top |
|
|
brucebowler Guest
|
Posted: Fri Jan 30, 2009 2:36 pm Post subject: |
|
|
You asked, here's a code snippet...
Code: | subroutine readOptFile(filename)
implicit none
character (len=*), intent(in) :: filename
include '\mergedata\commoncode\includes\optcommon.inc'
include '\mergedata\commoncode\includes\unitcommon.inc'
logical :: fileExists
namelist /optlist/ &
ac9Cals, ac9ScatterType, &
ac9pretime,ac9posttime, ac9PreTemp, ac9PostTemp, ac9prea,ac9prec,ac9posta,ac9postc,&
ac9NumGooses,ac9Gooses, &
dawnCals, dawnpretime,dawnposttime,dawnprecal,dawnpostcal, &
chlCals, chlType, chlStart, chlEnd, chlCoeffCount, chlCoeff, &
hsNumSweeps, hsSweeps, &
gmtoffsethours, hscatinifile, sasinifile, firstStation
inquire (filename, exist=fileExists)
hsSweeps = 0
ac9Gooses = 0
chlType = 0
chlCoeffCount= 0
chlStart = 0
chlEnd = 0
chlCoeff = 0
if (fileExists) then
open (unit=optunit,file=filename,status='readonly')
read (optunit, nml=optlist)
close (unit=optunit)
end if
return
end
|
The input file looks like this
Code: | &optlist
!
! ac9ScatterType = 1 -> a(l) = a(l) - a(715)
! ac9ScatterType = 3 -> a(l) = a(l) - (a(715)/b(715))*b(l)
! ac9ScatterType = 0 -> no scatter correction
!
! ac9gooses and hssweeps are of the form
! xxx(n,1:3) = time at start of seq, time at end of seq, time at start of next seq
! "start of seq" is start of data or 1st valid data after an event
! "end of seq" is last valid data point prior to an event
! "event" is sweeping the HS2 or goosing the ac9
!
! chlCoeff - coefficients of the calibration eqn, starting with constant, ending with x^n
! chlType = 1 indicates a chl vs fl relationship.
! chlType = 2 indicates a chl/fl vs time relationship
!
chlCoeff(1,1:5) = 1.4305, -15.359, 69.454, -101.1, 46.416
chlType = 2
chlStart = 0
chlEnd = 1
chlCoeffCount = 5
chlCals = 1
ac9Cals = 1
ac9ScatterType = 3
ac9PreTime = 071.4215
ac9PostTime = 072.7431
!ac9PreTemp = 18.0 ! not recorded
ac9PreTemp = 14.8
gmtoffsethours = 4
hscatinifile="hydroscat.040416"
sasinifile="sas3332k.060307"
firstStation = 4
/
|
Note the comments.
Note that not all the variables need to be specified in the input file
Note that the user only needs to know about the variables specified in the "namelist /optlist/" statement.
Note that you can have integer, float and string variables
Note that you can specify specific elements of an array.
I'm reasonably certain that you can have logical variables as well as the ones I mentioned above, but I haven't done that and it would not surprise me if there's a way to deal with structures and parts of structures but, again, I haven't tried it so I can't provide examples.
All "do-able" with a private parser, but why bother, when it exists in the standard? |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Fri Jan 30, 2009 4:05 pm Post subject: |
|
|
Hi Bruce,
Thanks for rising to the challenge. Code snippet was a very useful and informative illustration of the method.
Is the ! comment prefix an FTN95 extension? What are the allowed separators for multiple items on a line, and what FTN95 extensions, if any, are there?
What happens if the user mistypes a name? (Yup, it crashes, as always with fortran). What happens if there is an error trapped with ERR= ... where does one pick up again in the datafile - the next line, or the end of the namelist group? If the latter, then how is that defined (with the solidus?)? Are the remaining items in the namelist simply ignored (I think so)? How does one find out (It looks like you can't)? (Comparing the value to the previously held one doesn't tell you if the namelist value wasn't specified, was ignored because an earlier value had an error, or had the same value as before. You can go back and parse the items one at a time!).
Can you format a namelist on output?
I still don't think it's for me. Thanks for your trouble.
Regards
Eddie |
|
Back to top |
|
|
brucebowler Guest
|
Posted: Fri Jan 30, 2009 4:49 pm Post subject: Re: |
|
|
LitusSaxonicum wrote: | Hi Bruce,
Thanks for rising to the challenge. Code snippet was a very useful and informative illustration of the method. |
No problem, glad to be of help...
LitusSaxonicum wrote: | Is the ! comment prefix an FTN95 extension? What are the allowed separators for multiple items on a line, and what FTN95 extensions, if any, are there? |
Yes, the comment is a FTN95 enhancement. I believe that the comma is the only permitted separator. Note that one can also put multiple variables on one line, thus
is a valid input file
LitusSaxonicum wrote: | What happens if the user mistypes a name? (Yup, it crashes, as always with fortran). What happens if there is an error trapped with ERR= ... where does one pick up again in the datafile - the next line, or the end of the namelist group? If the latter, then how is that defined (with the solidus?)? Are the remaining items in the namelist simply ignored (I think so)? How does one find out (It looks like you can't)? (Comparing the value to the previously held one doesn't tell you if the namelist value wasn't specified, was ignored because an earlier value had an error, or had the same value as before. You can go back and parse the items one at a time!). |
I don't know, I don't make errors :-) I believe it picks up at the end of the group (yes, defined by the slash), and yes, it can be a "challenge" to find where the error is.
LitusSaxonicum wrote: | Can you format a namelist on output? |
If you write a namelist, it will format it so it's suitable for input by another read statement. It may not be pretty, but it works.
LitusSaxonicum wrote: | I still don't think it's for me. Thanks for your trouble. |
Your loss :-) |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Fri Jan 30, 2009 5:44 pm Post subject: |
|
|
My try also accepted ; as a separator.
To ERR is human ...
E |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|