McIDAS Programmer's Manual

Chapter 5 - Accessing Data

This chapter provides the information you will need to access and use McIDAS-X data. You'll learn:

This chapter is organized into these sections:

McIDAS disk files

Reading and writing data to and from disk is fundamental to many applications programs. A McIDAS-X disk file stores information that applications can randomly access by byte address using standard system library calls.

This section describes:

Basic concepts

McIDAS-X disk file utilities have several characteristics that distinguish them from other file system utilities.

Disk file APIs

The table below describes the McIDAS-X library functions that you will use when programming with disk files. In McIDAS-X, a disk file is called an LW (Large Word) array file. You will notice that many of the Fortran APIs below begin with the letters lw .

C function

Fortran function

Description

Mcpathname

volnam

converts a disk file name to a fully qualified pathname/filename

Mcread

lbi

reads bytes from a disk file into memory

not available

lwi

reads words (4-byte groups) from a disk file

Mcwrite

lbo

creates a disk file by writing bytes into it from memory

not available

lwo

creates a disk file by writing words (4-byte groups) into it

Mcremove

lwd

deletes a disk file

Mctruncate

lwtrunc

deletes the contents of a disk file without deleting the file itself

not available

lwfile

determines if a file exists

not available

lock

acquires an exclusive lock on a file

not available

unlock

frees the lock on a file

Each function is described in the sections below, along with sample code illustrating its use.

Reading and writing disk files

The McIDAS-X library provides the Mcread and Mcwrite functions for reading and writing disk files in C. The comparable functions in Fortran are lbi and lbo , which are shown in the code fragment below. The lwi and lwo functions read and write words (4-byte groups) from a disk file.

c --- an example of writing data
    integer array_out(3)
    integer array_in(3)
    integer nwords, status, lwo, lwi, first

    ...
c --- initialize
    first = 0
    nwords = 3
    do 200 i = 1, nwords
200 array_out(i) = i * 100


c --- write the data to disk -- note that there are four bytes
c ---    in each array element

    status = lbo('testdata', first*4, nwords*4, array_out)

    if (status .lt. 0) then
        call edest('Failed to write testdata', status)
        call mccodeset(1)
        return
    endif

c --- at this point, the file 'testdata' will consist of:
c ---    word 0 = integer value 100
c ---    word 1 = integer value 200
c ---    word 2 = integer value 300
c ---    words 3 and beyond are unwritten

c --- now, read the data in, skipping the first word:
    
    first = 1
    status = lbi('testdata', first*4, nwords*4, array_in)
    
c --- at this point, the array array_in will consist of:
c ---    word 1 = integer value 200
c ---    word 2 = integer value 300
c ---    word 3 = 0x80808080 (the missing value indicating
c ---    this word was never written)

Assigning a system pathname to a disk file

If your application uses Fortran or C library functions for disk I/O, you must use the volnam or Mcpathname function to convert the name of the disk file into a fully qualified, system pathname/filename . This pathname is essential for locating and working on a file.

The code fragment below illustrates the use of volnam with a Fortran OPEN statement. The maximum number of characters allowed for the fully-qualified pathname is stored in the constant MAXPATHLENGTH in the Fortran INCLUDE file, fileparm.inc . The limit for C is in the file /usr/include/sys/limits.h .

c --- For illustration, assume the user has done a REDIRECT 
c ---    command that looks like this:
c ---    REDIRECT ADD MYDATA "/home/me/mcidas/data
c --- 

    include 'fileparm.inc'
       character*(MAXPATHLENGTH) fullname 
    character*12 filename
    integer rc, volnam
    ...
    filename = 'MYDATA'
    ...
    rc = volnam(filename, fullname) 
    if (rc.lt.0) then
        call edest('Problem resolving path for '//
filename,0)
        call mccodeset(1)
        return
    endif
c --- At this point, fullname will contain the fully-qualified
c ---    name ('/home/me/mcidas/data/MYDATA')

    open(unit=12, file=fullname, mode='share', status='old')
    ...

Determining if a disk file exists

Use the function lwfile to determine if a file with a given name already exists. If the file does not exist, lwfile returns a zero; it does not create the file for you. The following code fragment illustrates how to use lwfile .

c --- find out if file 'mystuff' exists

    status = lwfile('mystuff') 

    if (status .ne. 0) then
        call sdest('The file is there!',0)
    else
        call edest('The file is NOT there!!!',0)
    endif
    ...

Deleting the contents of a disk file

To delete the contents of a disk file but not the file itself, use the lwtrunc or Mctruncate function. These functions remove the contents of the file, leaving one word (4 bytes) of 0x80808080 at the beginning of the file.

Deleting only the contents of a file and not the file itself is important if the file name appears in more than one location in the MCPATH tree. For example, if you delete the file ABC from a directory where you have write permissions but the file also exists further down your MCPATH in a directory where you have only read permissions, you won't be able to create a writable file by that name. If you use lwtrunc or Mctruncate to delete only the file's contents, you can write into it again in the future, since it resides in the original, writable directory.

The code fragment below uses the lwtrunc function to delete the contents of a file.

c --- assume the user's MCPATH contains the directories
c --- /home/my/data and /home/your/data, with a file named
c --- DATAFILE residing in both directories; further assume
c --- that I only have write permissions to /home/my/data

    status = lwtrunc('DATAFILE') 

    if (status .lt. 0) then
        call edest('Error occurred trying to truncate file',0)

    endif

c --- now write the contents of buffer to DATAFILE

    status = lbo('DATAFILE', 0, bufsiz, buffer) 

c --- at this point, the contents of buffer were written to
c --- /home/my/data/DATAFILE; if lwd had been called instead of
c --- lwtrunc, the lbo call would have returned an error because
c --- I don't have write permissions to /home/your/data/DATAFILE

Deleting a disk file

Use the lwd or Mcremove functions to delete a disk file, as shown in the code fragment below.

    ...
    character filename*20
    integer status, lwd

c --- try to remove the file
    status = lwd(filename) 

    if (status .lt. 0) then
        call edest('Error trying to remove file '//
filename,0)
        call mccodeset(2)
        goto 999
    else
    ...
c --- do some other processing

Locking and unlocking a disk file

As long as a user has read and write permissions, the McIDAS-X disk file I/O subsystem will open all files and permit simultaneous access to these files for both reading and writing. If you write applications that update information in disk files, you must synchronize access to the file to avoid potential file collisions.

McIDAS-X has a locking mechanism called lock for coordinating file updates between applications or between copies of the same application. The lock function acquires exclusive use of a unique lock. If your application is using the lock, another application trying to lock the file must wait until you free the lock with the unlock function before using it.

The lock and unlock functions do not prevent other applications from reading a file or writing to it. They simply ensure an orderly means of updating a file without losing or overwriting information.

The code fragment below shows how to lock and unlock a file to protect its integrity during updating.

    ...
c --- protect against simultaneous attempts to use this lock
    call lock( 'myfile ') 
c --- when control is returned, this application has exclusive use

    rc = lbi('myfile', 0,100,array) 
    ...
c --- update the values in array
    ...
c --- now save the updated info back into 'myfile'
    rc = lbo('myfile',0,100,array) 

c --- now free the lock
    call unlock('myfile') 
    ...

Copying a disk file

Use the lwcopy function to copy one disk file into another, as shown in the code fragment below.

c --- set up some variables
    integer status, lwcopy, lwo
    integer source(3)
    integer destination(3)

c --- fill up source array
    do 200 i=1,3
    source(i) = I*100
200 continue

c --- write out array to file "first"

    status = lwo('first', 0,3,source)

    if (status.lt.0) then
        call edest('Error writing to "first" file',0)
        call mccodeset(2)
        goto 999
    endif

c --- now copy file 'first' into 'backup'

    status = lwcopy('first', 'backup') 

    if (status.lt.0) then
        call edest('Error during copy...',status)
        call mccodeset(2)
        goto 999
    endif
    ...

Image data

McIDAS-X images are typically composed of atmospheric and oceanographic data, which are measured from remote sensing platforms such as satellites and radar. Images may contain any data that can be represented in a two-dimensional matrix.

This section describes:

Basic concepts

Image data has several unique attributes that determine how an image is displayed on the McIDAS-X Image Window. The resolution of the image, the size of the data points and the number of spectral bands all influence the final product.

Image resolution

A satellite observes features by scanning small slices of the earth's surface with each pass of the sensors. The geographic width of each image line helps determine the size of the smallest surface feature the satellite can detect. This concept is called resolution .

Image resolution refers to the number of satellite image lines represented in each data point of an image line. If the image resolution is one, the image is stored at full resolution . This means that one image data point represents one satellite sensor data point. If the image resolution is four, either sampling or averaging was performed on the image so that one data point in the image represents 16 satellite scan data points. Each satellite has its own scan resolution, so an image resolution of one will mean different geographic resolutions from one satellite to another.

When copying or displaying an image, a user can modify its resolution. Image resolution can be artificially increased, or blown up , by replicating data point values, much like enlarging a 3 x 5 photograph to 8 x 10. Image resolution can be decreased, or blown down, by sampling or averaging the image data points. For example, if a blowdown factor of two is applied to a McIDAS-X image, every other data point along the line and every other line in the image is dropped out. Each data point on the displayed image represents four data points from the original, scanned image.

Data-point size

Data-point size refers to the number of bytes needed to accurately represent the value of a data point. Although the size varies among sensor sources, data is one, two or four bytes. For example, Meteosat-7 data is 1-byte per data point while GOES-12 data is 2-byte.

Spectral bands

A spectral band is the wavelength in which a scanning instrument measures data; for example, band 4 for the GOES-8 Imager senses 10.7 micron wavelength radiation. These wavelengths are specific to the measuring instrument. Most satellites can measure radiation from many wavelengths simultaneously over the same geographic location.

 

For more information about the bands for satellite imagery, see Appendix B, Satellite Information .

What is an image object?

Image data is quantitatively useless unless it is transformed into physical units (calibration) and oriented relative to time and physical space (navigation). In addition, it is often necessary to know when and how an image was collected and processed. The actual image, along with these ancillary data , is collectively called an image object . Each image object in McIDAS-X is composed of the following blocks of information:

The API functions and the procedures for reading, writing and deleting image objects follow.

Reading image objects

Most applications for reading image objects will do one of the following:

The table below lists alphabetically the McIDAS-X library functions for performing these tasks.

Function

Description

mcaaux

reads the auxiliary (supplemental) block of an image object

mcacal

reads the calibration block of an image object

mcacrd

reads the comment block of an image object

mcadir

opens a connection to read the directory block from an image object

mcadrd

reads the directory block from an image object

mcafree

frees the handle and memory of a connection opened by mcaget

mcaget

opens a connection to read the data block from an image object

mcalin

reads the data portion of the current image line

mcanav

reads the navigation block of an image object

mcapfx

reads the prefix portion of the current image line

mcasort

gets the parameters from the command line and adds them to the selection array for a future mcaget call

mcpcal

parses a list of valid calibration types from the comment cards

mcpnav

parses out geographic resolution information from the comment cards

These functions are described below along with sample code.

 

See the online man pages provided with the McIDAS-X software for detailed information about any of the API functions discussed in this section.

Opening a connection to read the directory block

In ADDE, a client has the ability to request only directory blocks from a server. This allows the client to sample information on a server without transferring large amounts of image data that may not be necessary for an application. For example, the McIDAS-X IMGLIST command reads only directory blocks.

The ADDE interface to the image directory is through mcadir , which opens a connection based on a set of selection clauses for a given dataset name. The valid selection conditions are provided in the table below.

Selection clause

Description

AUX YES or
AUX NO

appends center latitude/longitude, resolution, and calibration types to the comment block (default=YES)

DAY bday eday

image day range

SS ss1 ss2

SSEC sensor source number range, from 1 to 999

SUBSET bpos epos

position range or SUBSET ALL

TIME btime etime

image time range

Selection clauses can restrict the search based on the image day, image start time and SSEC sensor source number. With the exception of AUX, you must specify these selection clauses as a range of values.

Note that in a mcadir call the dataset name does not contain the position field. The position, if known, is specified with the SUBSET selection clause. For example, if the application requires the first 10 images for a given dataset, the selection clause is SUBSET 1 10. If the application requires all the image directories in a dataset, the selection clause is SUBSET ALL.

If you include the selection clause AUX YES in the condition list, the image object directory server will append comment entries describing the latitude and longitude of the center element of the image, the earth area (in latitude and longitude resolution) covered by the center element of the image, and the valid calibration types for the image. These values can subsequently be parsed out with the mcpnav and mcpcal functions, as shown in the code fragment on the next page.

Reading the directory block

Once the connection is opened with mcadir , the application makes repeated calls to mcadrd until all image object directory blocks are retrieved. The mcadir call must precede the call to mcadrd , as shown below.

      character*4   calkeys(12)
      character*12  expkeys(12)
    character
      real          lat
      real          lon
      real          latres
      real          lonres

c --- set selection conditions
    selects(1) = 'SS 72 72'
    selects(2) = 'DAY 97001 97001'
    selects(3) = 'TIME 10:00:00 10:00:00'
    selects(4) = 'SUBSET ALL'
    selects(5) = 'AUX YES'
    nselect = 5

c --- dataset name
    dataset = 'RT/GOES-9'

c --- turn error reporting on 
    error_flag = 1

c --- open a connection for the specified dataset
    status = mcadir(dataset, nselect, selects, error_flag)

if(status .lt.0 )return

 100  continue
c --- read an image directory block meeting the selection conditions
    readstat = mcadrd(directory,comment_cards)


c --- read failed 
    if( readstat.lt.0 ) then
       call edest('Failed during directory read of '//dataset,0)
       return

c --- found one
    else if( readstat.eq.0 ) then

c --- process the data
       ...

c --- get the list of cal types for band 4

       band = 4
       ok = mcpcal (comment_buffer, ncards, band, calkeys, expkeys, nkeys)


c --- get the navigation information at the center of the image

       ok = mcpnav (comment_buffer, ncards, lat, lon, latres, lonres)


       goto 100

    endif 

The directory block contains a list of ancillary information about the image. The entries in the directory block are described in the table below.

IMPORTANT: When using mcadir to read the dataset, a 65 word block is returned, which includes the absolute position number. When using mcaget, the directory is 64 words long, including only words 1-64 in the the table below.

Entry

Description

0

absolute position of the image object in the ADDE dataset

1

relative position of the image object in the ADDE dataset

2

version number; currently=4

3

SSEC sensor source number; see the Appendices

4

nominal year and Julian day of the image, ccyyddd

5

nominal time of the image, hhmmss

6

upper-left image line coordinate

7

upper-left image element coordinate

8

reserved

9

number of lines in the image

10

number of data points per line

11

number of bytes per data point

12

line resolution

13

element resolution

14

number of spectral bands

15

length of the line prefix

16

SSEC project number used when creating the file

17

year and Julian day the file was created, ccyyddd

18

time the file was created, hhmmss

19

spectral band map, bands 1-32

20

spectral band map, bands 33-64

21 - 24

reserved for sensor-specific data

25 - 32

memo field; 32 ASCII characters

33

reserved

34

byte offset to the start of the data block

35

byte offset to the start of the navigation block

36

validity code

37 - 44

PDL (Program Data Load); used for pre-GOES-8 satellites

45

source of band 8; used for GOES AA processing

46

actual image start year and Julian day, ccyyddd

47

actual image start time, hhmmss; in milliseconds for POES data

48

actual image start scan

49

length of the prefix documentation

50

length of the prefix calibration

51

length of the prefix band list

52

source type; satellite specific (ASCII)

53

calibration type; satellite specific (ASCII)

54 - 56

reserved

57

original source type

58

units

59

scaling

60

byte offset to the supplemental block

61

number of entries in the supplemental block

62

reserved

63

byte offset to the start of the calibration block

64

number of comment cards

 

 

For more information about the directory block, see the AREAnnnn data structure in Chapter 6, Format of the Data Files.

Opening a connection to read an image object

In ADDE, a client can request an entire image object, including the directory, data, line prefix, navigation, calibration and comment blocks, from a server. For example, the McIDAS-X IMGDISP and IMGCOPY commands typically request entire image objects.

To open a connection to read an image object's data block, an application must perform these two steps:

  1. Define the selection conditions for the desired image sector in the dataset.
  2. Send a request to an image server.

Each is described below.

Defining the selection conditions

Applications use selection clauses to specify the spatial, temporal and spectral limits of the transaction with the server. This eliminates the need for the application to scan the dataset for a particular image object and also limits the size of the transmission to only that needed. The number and format of selection clauses are strictly regulated. Below is a list of the valid selection clause formats for the mcaget interface, which passes the request for an image sector from the client to the server. Additional information for each selection clause follows.

Selection clause

Description

AUX YES or AUX NO

additional information requested from server

BAND band

spectral band, if the image has multiple bands

CAL QTIR

quick calibration switch for POES images

DAY bday

image Julian day (no default)

DOC YES or DOC NO

includes the documentation from the line prefix (default=NO)

LOCATE cor ycor xcor

sets the coordinate type and the coordinate positions relative to the coordinate type (default=AU 0 0)

MAG lmag emag

line and element magnification factor (default=1 1)

POS pos

absolute position in the dataset

SIZE lines elems

number of image lines and data elements
(default=480 x 640)

SU name

stretching table name (default=no stretch)

TIME btime etime

image time range (no default)

AUX YES
-- Data server: use this clause to insert the unit and scale factor of the image data into entries 58 and 59 of the directory block.
-- Directory server: use this clause to get center point and calibration information from the server as additional comment cards.

BAND --use this clause to identify a spectral band of image data. Specify BAND ALL to return all spectral bands in the source image.

CAL (obsolete) --use this clause only when the source data type is TIRO. Use CAL QTIR for quick calibration.

DAY --use this clause to specify the day of the source. Using DAY implies that the image object position (POS) is not specified in the connection request. If POS is specified, the DAY clause is ignored.

DOC YES --use this clause to include the line prefix's documentation when reading an image object.

LOCATE --use this clause to position the request spatially. LOCATE specifies a reference point from which sector bounds are determined. To specify the reference point of the image sector, use one of three coordinate systems (I=satellite, A=array or file, E=earth) with one of two standard offsets (U=upper-left, C=center); for example, EC=earth center, IU=satellite upper-left. Following the reference point are two values (ycor and xcor ) that identify the absolute position of the reference point in the chosen coordinate system. For earth coordinates, the values are latitude and longitude; for satellite coordinates, the values are line and element; for array coordinates, the values are array row and column. If you don't specify LOCATE, the default is a satellite upper-left (IU) reference point of the first scan line and pixel of the source image object.

MAG --use this clause to specify the resolution magnification factor for the line and element dimensions of the image object. Enter a negative integer for a blowdown; enter a positive integer for a blowup. For example, a magnification factor of -4 will use every fourth data point on the line and every fourth line in the image. A magnification factor of 16 for both line and element dimensions will duplicate each data point in the image 256 times (16 x 16). The mcaget function performs all line and element duplication. The application must reduce the size of the data request to allow for a blowup factor. To use a magnification factor other than one, modify the input for SIZE accordingly. For example, to get an image that is 500 x 1000 with a MAG value of 2 2, you must specify SIZE 250 500. You cannot store images with non-integer line/element resolutions in the McIDAS-X image object data structure.

POS --use this clause to specify the position of the image in the dataset. If POS isn't specified, the server uses the most current (time-relative) image. Specify POS as either absolute or time relative. Numbers less than one imply time-relative position, with zero as the most current image.

SIZE --use this clause to specify the image line and data element limits of the transaction. Specify SIZE ALL to read the entire source image object.

SU --use this clause to specify the name of an image data stretching table. These tables are generated with the McIDAS-X SU command.

TIME --use this clause to specify a range of image start times identifying specific images in a dataset. Using this clause implies that the image object position (POS) is not part of the connection request. If a POS clause does exist, the TIME clause is ignored.

Server-specific selection clause

Description

ID

NEXRAD station ID (NEXRAD server)

TIME btime etime C

Coverage; accesses data for specified time range (realtime POES server)

WL

wavelength (AIRS server)

WN

wavenumber (AIRS server)

Sending a request to an image server

Once the selection conditions for the image sector are defined, the mcaget function passes the request for the image sector from the client to the server. The return status shows if the connection is open and if the request can be completed.

The mcaget function lets the application specify the units and format of the data points. Since these parameters are necessary to any data transaction, they are specified as separate parameters to the mcaget function and are not entered as selection clauses. Units may be any unit identifier valid for the image object type. A list of valid unit identifiers is available to an application through the mcadir function by specifying the AUX YES selection clause. Use the format parameter to specify the bytes-per-data point in the return array. The valid formats are I1 (1 byte per data point), I2 (2 bytes per data point) and I4 (4 bytes per data point).

If you request that 2-byte data be returned as a 1-byte representation, without going through a calibration process that converts the 2-byte data to 1-byte, the server will truncate the least significant byte.

Because mcaget requires many selection conditions to request image data, the mcasort function can be called to translate command line keyword parameters into equivalent mcaget selection clauses. Any application-level program may call mcasort to retrieve these keywords and return them as mcaget selection clauses. The table below lists the keywords for accessing image objects and their equivalent selection clauses.

Command line keyword

Equivalent mcaget selection clause

Remarks

 

AUX YES

always set by mcasort

BAND=band

BAND band

only one spectral band in the clause

DAY=bday

DAY bday

 

LATLON=lat lon

LOCATE Eloc lat lon

loc defaults to center (EC) if keyword PLACE is not specified

LINELE=line ele sys

LOCATE Iloc line ele

loc defaults to center (IC) if keyword PLACE is not specified

MAG=lmag emag

MAG lmag emag

 

PLACE=loc

none

sets loc for the LATLON, LINELE, and STATION keywords

RTIME=bmin emin

TIME btime etime

keyword RTIME overrides keyword TIME

STATION=stn

LOCATE Eloc lat lon

loc defaults to center (EC) if keyword PLACE is not specified

TIME=btime etime

TIME btime etime

 

WL=bwl ewl

WL bwl ewl

 

WN=bwn ewn

WN bwn ewn

 

Reading the image data

If an image sector in the dataset satisfies the client request, a connection is established between the server and the client and the transaction proceeds. Because applications manipulating image data must sometimes sample data from different sources simultaneously, ADDE allows an application to receive data from multiple datasets in any order required for that application. When a request for data is initiated with mcaget , a handle identifying the request is returned. This handle is subsequently used to retrieve each line of data for the request. If your application requires accessing data from multiple requests simultaneously, you only have to manage a handle for each request.

This section describes the functions you should use to get the requested image data from the server and to read the image object's line prefix, navigation, calibration and comment blocks.

Getting the requested image data

The mcalin function reads the requested image data from the server one line at a time. When all the data is read, the connection is closed. Then the mcafree function readies the environment for the next request by freeing the image handle and the memory allocated to store the image data from the previous request.

If you request multispectral data, each data point in the line will contain the measurements for the bands arranged consecutively. For example, Figure 5-1 shows the arrangement of data points for an image line of 1-byte data containing three spectral bands.


Figure 5-1. An image line may contain multispectral data stored in bands arranged consecutively.

 

 

For more information about manipulating data at the byte level, see the section titled Conversion utilities in Chapter 4, McIDAS-X Utilities.

Below is a code fragment showing the steps for reading an image object data block. Note that the mcaget call must precede a call to mcalin .

c --- get selection conditions
    nselect = 1
    selects(nselect) = 'DAY 96300'
    nselect = nselect + 1
    selects(nselect) = 'LOCATE IC 1000 1000'
    nselect = nselect + 1
    selects(nselect) = 'TIME 19:00 19:15'
    nselect = nselect + 1
    selects(nselect) = 'SIZE 200 300'

c --- set the format of the returned data buffer
    format = 'I4'

c --- set the units of the returned data
    unit = 'TEMP'
c --- specify the number of bytes available in the data_buffer
c --- (note that data_buffer is usually an integer array with 
c --- four bytes per array element) 

max_byte = 300


c --- open a connection 
    status = mcaget(dataset, nselect, selects, unit, format, 
    &                   max_byte, msg_flag, directory, handle) 
    if( status.lt.0 ) return

100   continue
c --- read the data block
    status = mcalin(handle, data_buffer) 
    if( status.lt.0 ) then
       call edest('Read failed',0)
       return

c --- got a line of data
    else if( status.eq.0 ) then

c --- process the data
       ...
       goto 100

    endif

c --- Free the handle
    status = mcafree( handle )
       ...

Reading the line prefix block

If processing the image requires the line prefix, the application must get the prefix using the mcapfx function. The line prefix is the set of information that may precede the data on an image line; its maximum size is 1000 bytes. As shown in Figure 5-2, an image line consists of an optional line prefix and the actual data values.

Figure 5-2. Each image line contains an optional line prefix and data values.

The line prefix is divided into four regions:

The line prefix is the same length for each line in an image. The sensor source determines the size and content of the line prefix and which of its four regions are present.

As shown in the sample code below, the call to mcapfx must occur immediately after the call to mcalin so that the prefix and data are for the same image line.

c --- set up the ADDE transaction
      ...

100   continue
c --- read the data block
    status = mcalin(handle, data_buffer)
    if( status.lt.0 ) then
       call edest('Data Read failed',0)
       return

c --- got a line of data
    else if( status.eq.0 ) then

c --- read the line prefix
       pfxstatus = mcapfx(handle, prefix_buffer)
       if( pfxstatus.lt.0 ) then
          call edest('Prefix Read failed',0)
          goto 100
       endif

c --- process the data
         ...
         goto 100

      endif
      ...

Reading the navigation block

The mcanav function reads an image object's navigation block. At any point after the connection is opened by mcaget , the application may retrieve the navigation block using the handle returned by the preceding mcaget call. See the code segment below. To eliminate the risk of buffer overflow, dimension the nav_buffer to 4096 bytes.

c --- open a connection 
    status = mcaget(dataset, nselect, selects, unit, format,
     &                  max_byte, msg_flag, directory, HANDLE)
    if( status.lt.0 ) return

    ...

c --- read the navigation block
    status = mcanav(HANDLE, nav_buffer)
    if( status.lt.0 ) then
       call edest('Navigation Block Read failed',0)
       return
    endif
    ... 

Reading the calibration block

The mcacal function reads the calibration block of an image object. The call to mcacal can occur any time after the connection is opened by the mcaget call. The handle returned by mcaget is passed to mcacal , which returns the associated calibration block. To eliminate the risk of buffer overflow, dimension the cal_buffer to 40,000 bytes.

c --- open a connection 
    status = mcaget(dataset, nselect, selects, unit, format,
     &                  max_byte, msg_flag, directory, HANDLE)
    if( status.lt.0 ) return

    ...

c --- read the calibration block
    status = mcacal(HANDLE, cal_buffer)
    if( status.lt.0 ) then
       call edest('Calibration Block Read failed',0)
       return
    endif
    ... 

Reading the comment block

To read the comment block, use mcacrd and the handle returned by mcaget . The mcacrd function returns the entire comment block to the application. The call to mcacrd can occur only after the calls to mcalin are done.

Below is an example using mcaget , mcalin and mcacrd to read a comment block. To eliminate the risk of buffer overflow, dimension the comment_buffer to 40,000 bytes.

c --- open a connection 
    status = mcaget(dataset, nselect, selects, unit, format,
     &                  max_byte, msg_flag, directory, HANDLE) 
    if( status.lt.0 ) return

100   continue
c --- read the data block
    status = mcalin(handle, data_buffer)
    if( status.lt.0 ) then
       call edest('Read failed',0)
       return

c --- get a line of data
    else if( status.eq.0 ) then

c --- process the data
       ...
       goto 100

    endif

c --- read the comment block
    if( mcacrd(handle, comment_buffer).ne.0 ) then 
       call edest('Read of Comment Block failed',0)
       return
    endif
    ...

Writing image objects to a dataset

To write an image object to an image dataset, the application must identify a dataset and position, and open a connection with the server. Use the API functions below to write image objects to a dataset.

Function

Description

mcaput

opens a connection to write the directory, navigation and calibration blocks of an image object

mcaout

writes the line prefix and data portions of an image line

mcacou

writes the comment block of an image object

Opening a connection to write an image object

The request to open a connection is performed by the mcaput function, which requires the following:

Because mcaput does not return an object handle, only one image object is written at a time.

The only valid selection clause for writing image objects is POS, which defines the location of the image object in the dataset. You must specify this clause or the request to open a connection will fail.

Writing the data block

Once the connection is open, the server expects to transfer the number of bytes defined by the entries in the directory block. Transferring too few or too many bytes results in an error. All data block write transactions are performed by mcaout , which is called as many times as necessary to transfer the bytes. The mcaout function has only one argument, which is an array of data points to write to the data block. The call to mcaput must occur prior to mcaout .

Writing the comment block

The comment block is written after the last byte of the data block is transferred. The number of comment entries is defined in word 64 of the directory block. If this entry is nonzero, the specified number of 80-byte entries is transferred. The mcacou function transfers the comment block. It has only one argument, which is an array holding the entire comment block.

The sample code fragment below writes image objects to a dataset. For another mcaput code example, see the function imgcopy.f

c --- initialize the directory block
      call zeros(directory_block, 64)

c --- create a comment card
      call getday( day )
      call gettim( time )
      cday = cfu( day )
      ctime = cfu( time )
      comment = cday(1:5)//' '//ctime(1:6)//' This is a comment '
      ncard = ( len_trim(comment) / 80 ) + 1

c --- fill the essential directory block entries
      directory_block(2) = 4        ! version
      directory_block(3) = sss      ! satellite number
      directory_block(4) = jday     ! Julian day of image
      directory_block(5) = time     ! nominal start time of image
      directory_block(6) = start_line       ! starting image line number
      directory_block(7) = start_elem       ! starting image element number
      directory_block(9) = num_lines        ! number of lines of image data
      directory_block(10)= num_elems        ! number of data points/line
      directory_block(11)= num_bytes        ! number of bytes/data element
      directory_block(12)= line_res     ! line resolution
      directory_block(13)= elem_res     ! element resolution
      directory_block(14)= num_bands        ! number of bands
      directory_block(19)= 2**(band-1)      ! band map
      call movcw(memo, directory_block(25)) ! memo field
      directory_block(34)= data_offset      ! byte offset to the data block
      directory_block(35)= nav_offset       ! byte offset to the nav block
      directory_block(49)= doc_length       ! length of prefix doc section 
      directory_block(50)= cal_length       ! length of prefix cal section
      directory_block(51)= lev_length       ! length of prefix lev section
      directory_block(52)= lit( stype )     ! sensor source type
      directory_block(53)= lit( ctype )     ! calibration type
      directory_block(63)= cal_offset       ! byte offset to the cal block
      directory_block(64)= ncard        ! number of comment cards

c --- initialize the navigation block
      call zeros(nav_block, nav_size)

c --- fill the navigation block entries
c     Note: "navigation_params" is an array of navigation parameters
c     that describes the geo-location of the elements of the
c     image object.
      do 10 i = 1,nav_size
      nav_block(i) = navigation_params(i)
10    continue

c --- initialize the calibration block
      call zeros(cal_block, cal_size)

c --- fill the calibration block entries
c     Note: "calibration_parms" is an array of calibration parameters
c     that transforms the data elements to physical units.
      do 20 i = 1,cal_size
      cal_block(i) = calibration_params(i)
20    continue

c --- fill the selection array
      nselect = 1
      selects(nselect) = 'POS '//cfu(position)

c --- open a connection to write the image object
      if( mcaput( image, nselect, selects, directory_block, nav_block,
   &       cal_block).ne.0 ) then 
         call edest('Unable to initialize image ='//image,0)
         return
      endif

c --- loop to write image lines to the image object
      do 100 line = 1,num_lines

c --- pack the data array
c     "data_array" is a (num_lines) by (num_elems) array of data
c     elements each of which is (num_bytes) long. The elements
c     represent data for (band) from the sensor numbered (sss)
c     on (jday) at (time). "data_buffer" is a one-dimension array
c     sized to (num_elems)

c     Note: this assumes a 4 byte to 1 byte compression of the data.
      call pack( num_elems, data_array(line, 1), data_buffer)

c --- write a line of data to the image object
      if( mcaout( data_buffer ).ne.0 ) then 
         call edest('failed to write image line=',line)
         return
      endif

100   continue

c --- write the comment block
      if( mcacou( comment ).ne.0 ) then
         call edest('failed to write comment block',0)
         return
      endif 

Deleting image objects

You can delete image objects from a dataset using mcadel, as long as you have write permission. The mcadel function has one valid selection clause, SUBSET, which you must specify during the connection phase of the transaction or the server request will fail. The code fragment below deletes the image objects at locations pos1 through pos2 from the dataset.

c --- construct selection clause
      nselect =1
      selects(nselect) = 'SUBSET '//cfu( pos1 )//' '//cfu( pos2 )
      call bsquez( selects(nselect) )

c --- delete image object
      if( mcadel( dataset, nselect, selects, msgflg ).ne.0 ) then 
         call edest(' Failed to delete image objects ',0)
      else
         call sdest(' Image objects deleted',0)
      endif

Grid data

McIDAS-X grids are typically composed of atmospheric and oceanographic data, which are produced by numerical models or derived from observational data using an objective analysis scheme. Grids may contain any data that can be represented in a two-dimensional matrix.

Because grid data and image data can both be represented in two-dimensional matrices, it's important to know how they're different. The attributes that distinguish them are listed in the table below.

Attribute

Grid data

Image data

data volume

low

high

data value resolution

high

low

geographic resolution between data points

low

high

representation to users

graphical contours

gray shading


This section describes:

Basic concepts

Grid data has five unique attributes: valid time, level, parameter, origin and navigation. Each is described below.

Valid time

Grid data is often used to store output from numerical models that simulate the atmosphere and ocean. Because these models predict what the atmosphere or ocean will look like at some time in the future, grids must contain two different time attributes when representing model forecasts:

For example, if a model run on 17 January at 00 UTC generates forecast fields valid 36 hours later, the primary time attribute is 17 January at 00 UTC and the secondary time attribute is 18 January at 12 UTC. If the grid does not represent a model forecast, no secondary time attribute is needed.

Level

Grids store information that represents data at some vertical location in the atmosphere. The level can be the constant height above the surface, such as 100 meters or 32000 feet; the constant pressure surface, such as 500 millibars; or some other meteorological surface, such as the level of the tropopause or isentropic surface.

Parameter

The grid parameter is the data type the grid represents. Parameters can be any field that can be stored as a number, such as temperature, wind speed or dew point. Grids must also contain the stored units used in the grid.

Origin

A grid's origin refers to the process that created the grid. For example, if a grid is created by a forecast model, the origin is the name of the model, such as ECMWF or GFS. If the grid is created from another objective analysis process, that name can appear as the origin.

Navigation

Navigation is the process of determining the latitude and longitude location of data points on a grid. This information is needed when colocating data points from a grid with another data type. For example, you can use this information to contour the gridded field on a satellite image displayed on the McIDAS-X Image Window.

McIDAS-X currently recognizes these grid projection formats:

The diagrams below show how a three-dimensional Earth is represented on a two-dimensional surface for the pseudo-Mercator, polar stereographic and Lambert conformal projection formats, and the orientation of the data points on these projections. A sixth grid projection format is also available, but since it has no navigation, the data points can't be converted to planetary coordinates.

 

For more information about grid projections and McIDAS-X navigation, see the section titled McIDAS navigation later in this chapter.

 

Figure 5-3. Pseudo-Mercator projection.

Figure 5-4. Polar stereographic projection .

Figure 5-5. Lambert conformal secant cone (left) and tangent cone (right) projections

What is a grid object?

Gridded data is two-dimensional data representing an atmospheric or oceanic parameter along an evenly spaced matrix. For the matrix to be useful, ancillary information about the grid must also be known. This ancillary information, along with the gridded data, is collectively called a grid object . Grid objects in McIDAS-X contain two blocks of information.

The API functions and procedures for reading and writing grid objects are described below.

Reading grid objects

Most applications for reading grid objects will do one of the following:

The table below lists alphabetically the McIDAS-X library functions for performing these tasks.

Function

Description

mcgdrd

reads the grid header from a grid object

mcgget

opens a connection to read the data block of a grid object

mcgdir

opens a connection to read the grid header of a grid object

mcgfdrd

retrieves the grid file header

mcgridc

reads the grid object and returns the grid in row-major ( C ) format

mcgridf

reads the grid object and returns the grid in column-major (Fortran) format

m0gsort

gets the parameters from the command line and adds them to the selection array for future mcgget call

These functions are described below along with sample code, following an explanation of the selection conditions for requesting grid objects.

Defining selection conditions

Applications use selection clauses to restrict the information sent from the server to the client. For example, selection clauses can restrict the search based on grid time attributes, the parameter type and level, or the process that generated the grid. Below is a list of the valid grid selection clauses as sent to the server. Additional information for each follows.

Selection clause

Description

DAY day1 .. dayn

list of primary grid days

DRANGE bday eday inc

range of primary grid days with a day increment

FDAY day

forecast day

FHOUR hour1 .. hourn

list of forecast hours

FRANGE bvt evt inc

range of forecast hours with an hour increment

FTIME time

forecast time

GRIB geographic parameter model level

specific grib numbers to find

GRID bgrid egrid

specific range of grids in a grid file

LEV lev1 .. levn

list of data levels

NUM numgrid

number of grids to find

OUT option

header output format to return

PARM p1 .. pn

list of parameters

POS offset

relative position offset in a dataset

PRO projection

grid projection type

SRC src1 .. srcn

list of sources that generated the grid

TIME time1 .. timen

list of primary grid times

TRANGE btime etime inc

range of primary grid times with a time increment

DAY --use this clause to identify a list of primary days that the grids represent. For model forecast grids, these values will be the day the model was initialized. Otherwise, DAY is the Julian day the data represents.

DRANGE --use this clause to identify a range of primary days that the grid represents. Enter the beginning and ending day numbers and the increment between days in the range. The increment default is one day.

FDAY --use this clause to identify the secondary day attribute for requested forecast grids. For example, if you want only the forecast fields valid for day 1997017, specify FDAY=1997017.

FHOUR --use this clause to identify a list of secondary forecast hours that the grids represent. For example if you want only the 12-, 24- and 48-hour forecasts from a model run, specify FHOUR=12 24 48.

FRANGE --use this clause to identify a range of forecast hours that the grids represent. Enter the beginning and ending forecast hours and the increment between hours in the range. The increment default is one hour.

FTIME --use this clause to identify the secondary time attribute for the grids requested. Use this field with the FDAY clause to isolate grids that are valid at a particular time. The format for the arguments is hhmmss . For example, to request all grids valid at 12 UTC on day 96017, specify FDAY=96017 FTIME=120000.

GRIB --use this clause to select grids with the GRIB values specified for the geographic region, the parameter, the model, or the level. This is a useful way to find grids when other sort conditions provide insufficient information to differentiate between grids.

GRID --use this clause to access grids based on their position in specific grid files. Since this is an artifact of previous McIDAS-X API functions, avoid using this clause if a practical alternative exists.

LEV --use this clause to identify a list (not a range) of levels in the atmosphere or ocean that this data represents. This field is typically filled with height in millibars or words such as SFC, MSL or TRO. To retrieve data for several levels, enumerate them individually.

NUM --use this clause to specify the maximum number of grids returned from the server. The default is one grid. To receive all grids matching the selection conditions, use NUM=ALL.