Remote access using Fortran95 | Doc home | Madrigal home |
Unlike the Matlab, IDL, or python API, the Fortran 95 Madrigal APIis built on a low level language, and so there are only lower-level commands available. This API could be used to build similar functionality to global isprint or global download methods of the higher-level languages if third party Fortran libraries for such things as date manipulation were added to it.
Use of this API requires that wget be installed on your machine (freely available on the web).
The following are the methods for accessing Madrigal data remotely via Fortran 95:
These methods return the following Fortran types:
A good way to learn how to use this Fortran 95API is to run the example.
function get_connection(madrigal_url, user_fullname, & user_email, user_affiliation) ! get_connection returns the connection type needed by all other methods ! always the first method called for each session ! arguments: ! madrigal_url - url of particular Madrigal site's home page ! user_fullname - your full name ! user_email - your email ! user_affiliation - your affiliation. Use 'None' if none ! returns a connection structure which is the first argument of all other calls
subroutine get_instruments(conn, inst_arr, inst_count) ! get_instruments allocates an array of instrument structures ! describing all available Madrigal instruments ! ! arguments: ! conn - the connection structure created by get_connection call ! inst_arr - a pointer to an instrument array to be allocated and populated. ! user is responsible for calling deallocate and nullify when done ! inst_count - set to the number of instruments in inst_arr
subroutine get_sites(conn, site_arr, site_count) ! get_sites allocates an array of site structures ! describing all available Madrigal sites ! ! arguments: ! conn - the connection structure created by get_connection call ! site_arr - a pointer to a site array to be allocated and populated. ! user is responsible for calling deallocate and nullify when done ! site_count - set to the number of sites in site_arr
subroutine get_experiments(conn, kinst, syear, smonth, sday, shour, sminute, ssecond, & eyear, emonth, eday, ehour, eminute, esecond, local_only, exp_arr, exp_count) ! get_experiments allocates an array of exteriment structures ! describing all available Madrigal experiments with the given kinst and time range ! ! arguments: ! conn - the connection structure created by get_connection call ! syear, smonth, sday, shour, sminute, ssecond - exclude exps before this time ! eyear, emonth, eday, ehour, eminute, esecond - exclude exps after this time ! local_only - if True, only return experiments local to this server. ! if False, return local and remote experiments ! exp_arr - a pointer to an experiment array to be allocated and populated. ! user is responsible for calling deallocate and nullify when done ! exp_count - set to the number of experiments in exp_arr
subroutine get_experiment_files(conn, exp_id, file_arr, file_count) ! get_experiment_files allocates an array of experiment_file structures ! describing all available Madrigal files for the given experiment id ! ! arguments: ! conn - the connection structure created by get_connection call ! exp_id - experiment id as returned by get_experiments ! file_arr - a pointer to ae experiment_file array to be allocated and populated. ! user is responsible for calling deallocate and nullify when done ! file_count - set to the number of file in file_arr
subroutine get_cedar_parameters(conn, fullname, parm_arr, parm_count) ! get_cedar_parameters allocates an array of cedar_parameter structures ! describing all available Madrigal parameters for the given fullname of file ! as returned by get_experiment_files ! ! arguments: ! conn - the connection structure created by get_connection call ! fullname - fullname of madrigal file as returned by get_experiment_files ! parm_arr - a pointer to an cedar_parameter array to be allocated and populated. ! user is responsible for calling deallocate and nullify when done ! parm_count - set to the number of cedar_parameters in parm_arr ! ! delimiter is \, not , !
function download_file(conn, fullname, destination, user_fullname, user_email, user_affiliation, file_format) ! download_file downloads fullname as returned by get_experiment_files to destination is specified ! file_format ! ! arguments: ! conn - the connection structure created by get_connection call ! fullname - fullname of madrigal file as returned by get_experiment_files ! destination - full path to save file as locally ! user_fullname, user_email, user_affiliation - three string describing requester ! file_format - must be 'ascii', 'hdf5', or 'netCDF4'. 'netCDF4' requires ! a madrigal 3.0 site of higher ! ! Returns 0 is success, -1 if not !
function isprint(conn, fullname, parms, filters, destination, user_fullname, user_email, user_affiliation) ! isprint downloads fullname to destination with requested parms and filters applied. parms ! may include both measured and derived parameters. Format of output file is hdf5, netCDF4, or ! ascii as determined by destination extension ! ! arguments: ! conn - the connection structure created by get_connection call ! fullname - fullname of madrigal file as returned by get_experiment_files ! parms - Comma delimited string listing requested parameters (no spaces allowed). ! filters - Space delimited string listing filters desired, as in isprint command All filters ! begin with ==filter=. Details: --filter=<[mnemonic] or [mnemonic1,[+-*/]mnemonic2]>,<lower limit1>, ! <upper limit1>[or<lower limit2>,<upper limit2>...] a filter using any measured or derived Madrigal ! parameter, or two Madrigal parameters either added, subtracted, multiplied or divided. Each filter ! has one or more allowed ranges. The filter accepts data that is in any allowed range. If the Madrigal ! parameter value is missing, the filter will always reject that data. Multiple filter arguments are ! allowed. To skip either a lower limit or an upper limit, leave it blank. Examples: (--filter=ti,500,1000 ! (Accept when 500 <= Ti <= 1000) or --filter=gdalt,-,sdwht,0, (Accept when gdalt > shadowheight - that is, ! point in direct sunlight) or --filter=gdalt,200,300or1000,1200 ! (Accept when 200 <= gdalt <= 300 OR 1000 <= gdalt <= 1200)) ! destination - full path to save file as locally. If extention is .h5, .hdf, or .hdf5, ! will download in Madrigal Hdf5 format. If it has a .nc extension, will ! download as netCDF4. Otherwise, it will download as column delimited ascii. ! Trying to save as Hdf5 or netCDF4 with a Madrigal 2 site will raise an exception ! user_fullname, user_email, user_affiliation - three string describing requester ! ! Returns 0 is success, -1 if not !
function mad_calculator(conn, parms, destination, year, month, day, hour, minute, second, & start_lat, stop_lat, step_lat, start_lon, stop_lon, step_lon, start_alt, stop_alt, step_alt, & one_d_parms, one_d_values) ! mad_calculator runs the Madrigal derivation engine to derive the requested parameters for the specified time ! and range of geodetic locations. Writes ascii output to destination. Optional arguments ! are one_d_parms and one_d_values, where if given these set additional one d values for the given one d parms. ! ! arguments: ! conn - the connection structure created by get_connection call ! parms - Comma delimited string listing requested parameters (no spaces allowed). ! destination - full path to save ascii file as locally. ! year, month, day, hour. minute. second - six integers that set input time ! start_lat, stop_lat, step_lat - three real dp that set latitude range and step in degrees (-90 to 90) ! start_lon, stop_lon, step_lon - three real dp that set longitude range and step in degrees (-180 to 180) ! start_alt, stop_alt, step_alt - three real dp that set altitude range and step in km ! one_d_parms - a string with comma separated mnemonics representing the one D parameters to specify (no spaces) ! (optional argument). Example: 'azm,elm' ! one_d_values - a string with comma separated float strings representing the one D values to specify (no spaces) ! (optional argument) Number of values must match number of parms in one_d_parms. Example: '27.5,-165' ! ! Returns 0 is success, -1 if not !
! connection - created by get_connection ! passed into all other methods type :: connection character (len=1024) :: main_url character (len=1024) :: cgi_url character (len=512) :: user_fullname character (len=512) :: user_email character (len=512) :: user_affiliation integer :: site_id ! site id of site connected to character (len=1024) :: version ! version of local Madrigal site in form I.I[.I] end type connection
! instrument - created by get_instruments type :: instrument character (len=1024) :: name ! instrument name integer :: code ! instrument id code (kinst) character (len=12) :: mnemonic ! 3 letter code double precision :: latitude double precision :: longitude double precision :: altitude ! in km character (len=1024) :: category ! Example: 'Incoherent Scatter Radars' character (len=1024) :: pi ! Instrument PI. Will be 'Unknown' for Madrigal 2.X sites character (len=1024) :: pi_email ! Instrument PI email. Will be 'Unknown' for Madrigal 2.X sites end type instrument
! site - created by get_sites type :: site integer :: site_id character (len=1024) :: site_name ! site name character (len=1024) :: site_url ! url to site home page character (len=1024) :: contact_name ! site contact name character (len=1024) :: contact_email ! site contact email end type site
! experiment - created by get_experiments type :: experiment integer :: id ! unique id that identifies experiment character (len=1024) :: url ! Example: 'http://madrigal.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97' character (len=1024) :: name ! experiment name. Example: 'Wide Latitude Substorm Study' integer :: site_id ! site id of Madrigal site where data located character (len=1024) :: site_name ! site name of site where data is. eg: 'Millstone Hill' integer :: kinst ! id code of instrument character (len=1024) :: inst_name ! Example: 'Millstone Hill Zenith Radar' integer :: syear, smonth, sday, shour, sminute, ssecond ! start time integer :: eyear, emonth, eday, ehour, eminute, esecond ! end time logical :: is_local ! True if local data to this Madrigal site, False if remote data character (len=1024) :: madrigal_url ! url to Madrigal site where data is. If local, same as init character (len=1024) :: pi ! Instrument PI. Will be 'Unknown' for Madrigal 2.X sites character (len=1024) :: pi_email ! Instrument PI email. Will be 'Unknown' for Madrigal 2.X sites character (len=1024) :: real_url ! real url to Madrigal experiment. url string is only historical format integer :: uttimestamp ! st_mtime of expDir. -999 if not supported by the Madrigal site integer :: access ! access code of the experiment (0 if public, 2 if public, -999 if n/a). character (len=1024) :: version ! version of Madrigal site where data is in form I.I[.I] end type experiment
! experiment_file - created by get_experiment_files type :: experiment_file character (len=1024) :: fullname ! file fullname integer :: kindat ! kind of data code of this file character (len=2048) :: kindat_desc ! string describing kind of data integer :: category ! (1=default, 2=variant, 3=history, 4=real-time) character (len=1024) :: status ! status description integer :: permission ! 0 for public, 1 for private integer :: exp_id ! experiment id this file belongs to end type experiment_file
! cedar_parameter - created by get_cedar_parameters type :: cedar_parameter character (len=128) :: mnemonic ! parameter mnemonic character (len=2048) :: description ! parameter description integer :: is_error ! 1 if error parameter, 0 if not character (len=128) :: units ! units description integer :: is_measured ! 1 if parm in file, 0 if derived character (len=1028) :: category ! parameter category description end type cedar_parameter
program testMadrigalWeb use madrigal_web ! testMadrigalWeb is menat as an example of how to use madrigal_web fortran api ! Written by Bill Rideout ! $Id: testMadrigalWeb.f95 5690 2016-06-01 16:17:33Z brideout $ ! mad_connection is the main object to be used by all calls after get_connection type(connection) mad_connection ! arguments needed by get_instruments call type(instrument), dimension(:), pointer :: inst_arr ! returns an allocated array of instrument structures integer :: inst_count ! returns the number of instruments returned ! arguments needed by get_sites call type(site), dimension(:), pointer :: site_arr ! returns an allocated array of site structures integer :: site_count ! returns the number of site returned ! arguments needed by get_experiments call type(experiment), dimension(:), pointer :: exp_arr ! returns an allocated array of experiment structures integer :: exp_count ! returns the number of experiments returned ! arguments needed by get_experiment_files call type(experiment_file), dimension(:), pointer :: file_arr ! returns an allocated array of experiment file structures integer :: file_count ! returns the number of experiment files returned ! arguments needed by get_cedar_parameters call type(cedar_parameter), dimension(:), pointer :: parm_arr ! returns an allocated array of cedar parameter structures integer :: parm_count ! returns the number of parameters returned ! other variables integer :: exp_id, result character (len=1024) :: fullname ! to be done - declare arugments for all other api calls ! first call is always get_connection mad_connection = get_connection('http://madrigal3.haystack.mit.edu', "Bill Rideout", & "brideout@haystack.mit.edu", "MIT") !mad_connection = get_connection('http://isr.sri.com/madrigal/', "Bill Rideout", & !"brideout@haystack.mit.edu", "MIT") !mad_connection = get_connection('http://madrigal.haystack.mit.edu/madrigal/', "Bill Rideout", & !"brideout@haystack.mit.edu", "MIT") ! prove that first call succeeded print *, trim(mad_connection%user_fullname) print *, mad_connection%site_id print *, mad_connection%version ! get information on all available Madrigal instruments call get_instruments(mad_connection, inst_arr, inst_count) ! prove success by simply printing instrument data print *, 'inst_count is ', inst_count do i=1,3 ! shorten - could be inst_count print *, 'line ', i print *, trim(inst_arr(i)%name) print *, inst_arr(i)%code print *, trim(inst_arr(i)%mnemonic) print *, inst_arr(i)%latitude print *, inst_arr(i)%longitude print *, inst_arr(i)%altitude print *, trim(inst_arr(i)%category) print *, trim(inst_arr(i)%pi) print *, trim(inst_arr(i)%pi_email) end do deallocate(inst_arr) ! should be done only after you are done with it nullify(inst_arr) call get_sites(mad_connection, site_arr, site_count) ! prove success by simply printing site data print *, 'site_count is ', site_count do i=1,3 ! shorten - could be site_count print *, 'line ', i print *, site_arr(i)%site_id print *, trim(site_arr(i)%site_name) print *, trim(site_arr(i)%site_url) print *, trim(site_arr(i)%contact_name) print *, trim(site_arr(i)%contact_email) end do deallocate(site_arr) ! should be done only after you are done with it nullify(site_arr) call get_experiments(mad_connection, 30, 1998,1,1,0,0,0, 1998,2,1,0,0,0, .true., exp_arr, exp_count) ! do something with exp_arr print *, 'exp_count is ', exp_count do i=1,exp_count print *, exp_arr(i)%id, trim(exp_arr(i)%url), ' ', trim(exp_arr(i)%name) print *, exp_arr(i)%site_id, trim(exp_arr(i)%site_name), exp_arr(i)%kinst print *, trim(exp_arr(i)%inst_name) print *, exp_arr(i)%syear, exp_arr(i)%smonth, exp_arr(i)%sday print *, exp_arr(i)%shour, exp_arr(i)%sminute, exp_arr(i)%ssecond print *, exp_arr(i)%eyear, exp_arr(i)%emonth, exp_arr(i)%eday print *, exp_arr(i)%ehour, exp_arr(i)%eminute, exp_arr(i)%esecond print *, exp_arr(i)%is_local, trim(exp_arr(i)%madrigal_url) print *, trim(exp_arr(i)%pi), ' ', trim(exp_arr(i)%pi_email) print *, trim(exp_arr(i)%real_url), exp_arr(i)%uttimestamp, exp_arr(i)%access print *, trim(exp_arr(i)%version) end do exp_id = exp_arr(1)%id deallocate(exp_arr) ! should be done only after you are done with it nullify(exp_arr) call get_experiment_files(mad_connection, exp_id, file_arr, file_count) ! do something with file_arr print *, 'file_count is ', file_count do i=1,file_count print *, trim(file_arr(i)%fullname), file_arr(i)%kindat print *, trim(file_arr(i)%kindat_desc) print *, file_arr(i)%category, trim(file_arr(i)%status) print *, file_arr(i)%permission, file_arr(i)%exp_id end do fullname = file_arr(1)%fullname deallocate(file_arr) ! should be done only after you are done with it nullify(file_arr) call get_cedar_parameters(mad_connection, fullname, parm_arr, parm_count) ! do something with parm_arr print *, 'parm_count is ', parm_count do i=1,3 ! parm_count (to shorten output) print *, trim(parm_arr(i)%mnemonic), ' ', trim(parm_arr(i)%description) print *, parm_arr(i)%is_error, trim(parm_arr(i)%units) print *, parm_arr(i)%is_measured, trim(parm_arr(i)%category) end do deallocate(parm_arr) ! should be done only after you are done with it nullify(parm_arr) ! download_file print*, 'about to call download file' result = download_file(mad_connection, fullname, '/tmp/junk.h5', 'Bill Rideout', & 'brideout@haystack.mit.edu', 'MIT Haystack', 'hdf5') print*, 'download_file complete' ! isprint print*, 'about to call isprint' result = isprint(mad_connection, fullname, 'gdalt,elm,azm,nel', 'filter=recno,,5', '/tmp/junk.h5', & 'Bill Rideout', 'brideout@haystack.mit.edu', 'MIT Haystack') print*, 'isprint complete' ! mad_calculator print*, 'about to call mad_calculator' result = mad_calculator(mad_connection, 'kp,ap3', '/tmp/junk.txt', 2001, 1, 1, 13, 0, 0, & 20D+0, 60D+0, 5D+0, -90D+0, -60D+0, 5D+0, 100D+0, 1000D+0, 100D+0, 'ph+,elm', '0.03,-160') ! test of private methods - users should not need to call these methods ! test of compare_versions print*, 'comparing 3.0 and 2.6' print*, compare_versions('3.0', '2.6') print*, 'comparing 2.6 and 3.0' print*, compare_versions('2.6', '3.0') print*, 'comparing 3.1 and 3.0' print*, compare_versions('3.1', '3.0') print*, 'comparing 3.0 and 3.1' print*, compare_versions('3.0', '3.1') print*, 'comparing 3 and 3.1' print*, compare_versions('3', '3.1') print*, 'comparing 3 and 2.6' print*, compare_versions('3', '2.6') print*, 'comparing 3.0 and 3.0' print*, compare_versions('3.0', '3.0') print*, 'comparing 3.0.1 and 3.0' print*, compare_versions('3.0.1', '3.0') print*, 'comparing 3.0 and 3.0.1' print*, compare_versions('3.0', '3.0.1') print*, 'comparing 3.0.1 and 3.0.1' print*, compare_versions('3.0.1', '3.0.1') end program testMadrigalWeb
Remote access using Fortran 95 | Doc home | Madrigal home |