[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ldmMcidas #JRE-535181]: NLDN LDM data decoder
- Subject: [ldmMcidas #JRE-535181]: NLDN LDM data decoder
- Date: Wed, 06 Aug 2008 15:06:36 -0600
Hi Ken,
re:
> I'm a researcher at The University of Oklahoma who is interested in
> looking at the NLDN data we are currently receiving. I believe McIDAS
> and GEMPAK have built in decoders, but I need to see the actual data
> values.
Yes, the ldm-mcidas package contains a decoder that converts the NLDN data
sent in the IDD into McIDAS-compatible (MD) files, and Unidata GEMPAK
contains a decoder that converts the same data into GEMPAK-compatible files.
> I found some notes on the internet stating there is currently
> no decoder to convert to NetCDF format. Is that correct?
There is no program available through Unidata that does this decoding. I do
not know if someone in the community has created such a routine, however.
> I am currently
> working on a converter for the binary LDM access, but I have been unable
> to correctly decipher the data. I've been following the documentation
> located here <http://www.unidata.ucar.edu/data/lightning.html> but the
> data files I have do not appear to match this format.
Hmm... I updated the contents of the web page you reference to give specific
information on the data being sent in the LDM/IDD 'NLDN' datastream. I am
surprised by your comment that the information does not correspond to what
you have, but I guess that it has mostly to do with the header found at
the beginning of each IDD product.
> Can you provide some more information or answer a few questions.
>
> * How many bytes is the file header. I make it out to be 84 bytes.
> * How long is each data record? I make them out to be 28 bytes by
> looking at patterns in the binary file, but would assume 33 from
> the description in the table.
> * Is "NLDN" written at the start of each flash? (ASCII?)
> * What does the Size notation indicate in the Description table?
> I'm assuming char[4] means 4 single character bytes and int[4]
> means 1 integer of size 4 bytes.
I think that the routine I use in the ldm-mcidas package would answer
all of your questions, so I have attached it to this reply.
> * What is the fill/padding value used?
I am not sure. We skip over the padding value as they contain no useful
information.
> * Are all the bytes signed or unsigned?
We treat them as unsigned.
> Any information you can provide me would be very helpful.
Please let me know if the source code (nldninput.c) answers your questions.
Cheers,
Tom
****************************************************************************
Unidata User Support UCAR Unidata Program
(303) 497-8642 P.O. Box 3000
address@hidden Boulder, CO 80307
----------------------------------------------------------------------------
Unidata HomePage http://www.unidata.ucar.edu
****************************************************************************
Ticket Details
===================
Ticket ID: JRE-535181
Department: Support ldm-mcidas
Priority: Normal
Status: Closed
/* ---------------------------------------------------------------------
**
** Name: ingestnldn.c
**
** Purpose: Read NLDN binary records from LDM feed
**
** History: 19940302 - Adapted from 'ingesttonc.c' written by Ron
** Henderson of SUNY Albany
**
** ---------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <signal.h>
#include "ulog.h"
#include "cfortran.h"
#include "alarm.h"
#define INGESTORFLASHLEN 28
static unsigned alarm_timeout = 60; /* seconds; should suffice */
/*
* SIGALRM handler.
*/
static void
alarm_handler( sig )
int sig;
{
assert( SIGALRM == sig );
uerror( "nldninput(): no data read in %u seconds: simulating EOF",
alarm_timeout );
}
/*
* Read a character from a file.
*
* Returns:
* 1 Success
* 0 Failure
*/
static int
read_char( file, value )
FILE *file;
char *value;
{
return fread(value, 1, 1, file) == 1;
}
/*
* Read a short from a file.
*
* Returns:
* 1 Success
* 0 Failure
*/
static int
read_short( file, value )
FILE *file;
short *value;
{
unsigned char x[2]; /* NB: 16-bits assumed! */
int retcode;
int num = 1;
if (fread(x, 1, sizeof(x), file) == sizeof(x))
{
*value = (x[0] << 8) | x[1];
retcode = 1;
}
else
{
retcode = 0;
}
return retcode;
}
/*
* Read an integer from a file.
*
* Returns:
* 1 Success
* 0 Failure
*/
static int
read_int( file, value )
FILE *file;
int *value;
{
unsigned char x[4]; /* NB: 32-bits assumed! */
int retcode;
int num = 1;
if (fread(x, 1, sizeof(x), file) == sizeof(x))
{
*value = (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3];
retcode = 1;
}
else
{
retcode = 0;
}
return retcode;
}
/*
* Read an undetermined 4-byte sequence from a file; determine whether
* or not it is a beginning of a header record; eat all header records
* if they exist; and return the integer value at the beginning of a
* flash record.
*
* Returns:
* 1 Success
* 0 Failure
*/
static int
read_begin( file, value )
FILE *file;
int *value;
{
unsigned char x[4]; /* NB: 32-bits assumed! */
int retcode = 0; /* failure default */
int num = 1;
if (fread(x, 1, sizeof(x), file) == sizeof(x))
{
if (strncmp((const char *)x, "NLDN", 4) != 0)
{
/*
* Not a header record. Just return the data value.
*/
retcode = 1;
}
else
{
/*
* Start of header records. Read them and the first data
* value.
*/
int nhead;
uinfo("nldninput(): Product header record found");
if (read_int(file, &nhead))
{
int nflash;
if (read_int(file, &nflash))
{
unsigned char headr[280]; /* NB: 32-bits assumed! */
int bufsiz = nhead * INGESTORFLASHLEN - 12;
if (fread(&headr[12], 1, bufsiz, file) == bufsiz)
{
if (nflash != 0)
{
if (fread(x, 1, sizeof(x), file) == sizeof(x))
retcode = 1;
}
}
}
}
}
if (retcode == 1)
*value = (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3];
}
return retcode;
}
/*
* Read an NLDN record from a file stream.
*
* Returns:
* INGESTORFLASHLEN -> Success
* 0 -> Failure
*/
static int
nldn_read( file, time_sec, time_nsec, lat, lon, sgnl, mult, semimaj, eccent,
angle, chisqr )
FILE *file;
int *time_sec;
int *time_nsec;
float *lat;
float *lon;
float *sgnl;
int *mult;
float *semimaj;
float *eccent;
float *angle;
float *chisqr;
{
int iret;
int nbytes;
short fill_short;
char fill_char;
int rc = 0; /* failure */
struct {
int lat;
int lon;
short sgnl;
char mult;
char semimaj;
char eccent;
char angle;
char chisqr;
} obs;
if ( read_begin(file, time_sec) && /* 32-bits assumed */
read_int(file, time_nsec) && /* 32-bits assumed */
read_int(file, &obs.lat) &&
read_int(file, &obs.lon) &&
read_short(file, &fill_short) &&
read_short(file, &obs.sgnl) &&
read_short(file, &fill_short) &&
read_char(file, &obs.mult) &&
read_char(file, &fill_char) &&
read_char(file, &obs.semimaj) &&
read_char(file, &obs.eccent) &&
read_char(file, &obs.angle) &&
read_char(file, &obs.chisqr) ) {
*lat = obs.lat / 1000.0;
*lon = obs.lon / 1000.0;
*sgnl = obs.sgnl / 10.0;
*mult = obs.mult;
*semimaj = obs.semimaj;
*eccent = obs.eccent;
*angle = obs.angle;
*chisqr = obs.chisqr;
rc = INGESTORFLASHLEN;
}
return( rc );
}
/*
* Return parameters from the input. In order to handle the situation in
* which we're being fed by an LDM and the end of the data product is never
* seen, we set an alarm prior to the read.
*
* Returns:
* -1 Error: read error or EOF
* 0 No data
* INGESTORFLASHLEN Number of bytes read
*/
int
nldninput(time_sec, time_nsec, lat, lon, sgnl, mult, semimaj, eccent,
angle, chisqr)
int *time_sec;
int *time_nsec;
float *lat;
float *lon;
float *sgnl;
int *mult;
float *semimaj;
float *eccent;
float *angle;
float *chisqr;
{
int rc = -1; /* failure default */
static int alarm_initialized = 0;
static Alarm timeout_alarm;
if ( !alarm_initialized ) {
alarm_init( &timeout_alarm, alarm_timeout, alarm_handler );
alarm_initialized = 1;
}
alarm_on(&timeout_alarm); /* set alarm */
rc = nldn_read( stdin, time_sec, time_nsec, lat, lon, sgnl, mult,
semimaj, eccent, angle, chisqr );
alarm_off( &timeout_alarm ); /* disable alarm */
if ( !rc ) {
if ( feof(stdin) ) {
uinfo( "nldninput(): EOF on stdin" );
} else if ( ferror(stdin) ) {
serror( "nldninput(): NLDN read error" );
} else {
uinfo( "nldninput(): No data to read" );
}
}
return( rc );
}
/*
* FORTRAN interface to the above function.
*/
FCALLSCFUN10(INT,nldninput,NLDNIN,nldnin,PINT,PINT,PFLOAT,PFLOAT,PFLOAT,PINT,PFLOAT,PFLOAT,PFLOAT,PFLOAT)