CAMEX-4 DC-8 Lightning Instrument Package (LIP)

Table of Contents

Introduction
Instrument Description
Field Mill Location and Data Collection System
Data Format
Data Software
    read_dc8_block.m
    sload_dc8_data.m
Contact Information

Introduction

The fourth field campaign in the Convection and Moisture Experiment series (CAMEX-4) ran from 16 August to 25 September, 2001 and was based out of Jacksonville Naval Air Station, Florida. CAMEX-4 focused on the study of tropical cyclone (hurricane) development, tracking, intensification, and landfalling impacts using NASA-funded aircraft and surface remote sensing instrumentation. The NASA DC-8 carried numerous instruments during the the experiment.

Instrument Description

The DC-8 Lightning Instrument Package (LIP) consists of six state of the art digital electric field mills. The field mills allow the determination of the vector components of the electric field (i.e., Ex, Ey, Ez ). These data will greatly improve our knowledge of the electrical structure of storms.

Each field mill incorporates self-calibration capabilities that reduce the time required to obtain a full aircraft calibration. In addition, the electric field signals are digitized at each mill and transmitted as a digital data stream, reducing signal noise and simplifying aircraft integration. The DC-8 electric field mills are compact sensors, each weighing less than 10 lbs.

Field Mill Location and Data Collection System

The field mills are installed as follows:

Field mill #1 is near station 330 on the top of the fuselage along the centerline of the aircraft
Field mill #2 is near station 1095 on the top of the fuselage offset to the port side of the aircraft
Field mills #3 and #4 are mounted in the port and starboard windows at station 1280
Field mill #5 is located on the bottom of the forward fuselage near the center line near station 320
Field mill #6 is located on the bottom of the fuselage along the center line at station 1510 just aft of the dropsonde tube.

In this configuration, the field mills measure the components of the electric field over a wide dynamic range extending from fair weather electric fields (i.e., a few to tens of V/m) to large thunderstorm fields (i.e., tens of kV/m). The field mills also provide a measurement of the electric charge (Q) on the aircraft. Total lightning (i.e., cloud-to-ground, intracloud) is identified from the abrupt electric field changes in the data. Often it is possible to differentiate between intracloud and cloud-to-ground discharges.

Output from the field mills is collected on a hard drive on the aircraft at the field mill equipment rack (station 960), and is downloaded at the end of mission to a workstation for further quality control and analysis.

Data Format

Data are 'tarred' into daily (mission) data files of the form:

c4dlip_yyyy.jjj_010mmm.tar

where c4dlip represents CAMEX4 and the DC-8 LIP instrument, yyyy.jjj is the four digit year and day of year, 010mmm is the mission number.

When untarred, this will yield a data file. File naming convention for the data file is:

2001.jjj_hhmm.dc8

where jjj is the day of the year, and hhmm is the start time of the data block.

Data Software

Data is binary, and is analyzed using MatLab (see contact information below) a commercially available program. Two pieces of code (MatLab functions) are included with this dataset for use with Matlab. They are called read_dc9_block.m and sload_dc8_data.m and are shown below:

**************************************************************
function [efm_block, nav_block] = read_dc8_block(fid, efm_block, nav_block);
% [efm_block,nav_block] = read_dc8_block(fid, efm_block, nav_block);
%
% Reads one dc8 fm and nav block from the file fid and
% writes it to the structures efm_block and nav_block.
%

%
% Start the reading process (we will skip a lot of junk in the block)
% (We will assume the structure has already been set up)
% The first stuff up is the nav_block data
the_year = 2001;
%
% C Identifier (24)
%
[nav_block.day, count] = fread(fid, 1, 'int16');
if count ~= 1
efm_block.version = 0;
return;
end
%
0.000000or now, we hard wire the year as it is not read out of the ICATS system
%
nav_block.year = the_year;
[hr_min, count] = fread(fid, 1, 'int16');
nav_block.hour = fix(hr_min/100);
nav_block.min = mod(hr_min,100);
[nav_block.sec,count] = fread(fid, 1, 'int32');
nav_block.sec = nav_block.sec*0.001;
[deg, count] = fread(fid, 1, 'int16');
[min, count] = fread(fid, 1, 'int16');
if deg < 0
nav_block.latitude = deg - (min*0.1)*0.0166667;
else
nav_block.latitude = deg + (min*0.1)*0.0166667;
end
[deg, count] = fread(fid, 1, 'int16');
[min, count] = fread(fid, 1, 'int16');
if deg < 0
nav_block.longitude = deg - (min*0.1)*0.0166667;
else
nav_block.longitude = deg + (min*0.1)*0.0166667;
end
[nav_block.pitch, counts] = fread(fid, 1, 'int16');
nav_block.pitch = nav_block.pitch*0.1;
[nav_block.roll, counts] = fread(fid, 1, 'int32');
nav_block.roll = nav_block.roll*0.1;
[nav_block.wind_speed, count] = fread(fid, 1, 'int16');
%
0oing D Identifier section (28)
%
[nav_block.wind_dir, count] = fread(fid, 1, 'int16');
[nav_block.true_air_speed, count] = fread(fid, 1, 'int16');
[nav_block.gnd_speed, count] = fread(fid, 1, 'int16');
[nav_block.true_head,count] = fread(fid, 1, 'int16');
nav_block.true_head = nav_block.true_head*0.1;
[nav_block.drift_angle, count] = fread(fid, 1, 'int32');
nav_block.drift_angle = nav_block.drift_angle*0.1;
[nav_block.press_alt, count] = fread(fid, 1, 'int32');
[nav_block.radar_alt, count] = fread(fid, 1, 'int32');
[nav_block.dew_frost_1011, count] = fread(fid, 1, 'int32');
[nav_block.dew_frost_300, count] = fread(fid, 1, 'int32');
%
0oing E Identifier section (24)
%
[nav_block.stat_air_temp, count] = fread(fid, 1, 'int16');
nav_block.stat_air_temp = nav_block.stat_air_temp*.1;
[nav_block.tot_air_temp, count] = fread(fid, 1, 'int16');
nav_block.tot_air_temp = nav_block.tot_air_temp*.1;
[nav_block.IR_surf_temp, count] = fread(fid, 1, 'int16');
nav_block.IR_surf_temp = nav_block.IR_surf_temp*.1;
[nav_block.stat_Tair, count] = fread(fid, 1, 'int16');
nav_block.stat_Tair = nav_block.stat_Tair*.1;
[nav_block.ind_air_speed, count] = fread(fid, 1, 'int16');
[nav_block.vert_speed, count] = fread(fid, 1, 'int32');
[nav_block.dist_togo, count] = fread(fid, 1, 'int32');
nav_block.dist_togo = nav_block.dist_togo*0.1;
[nav_block.time_togo, count] = fread(fid, 1, 'int32');
nav_block.time_togo = nav_block.time_togo*0.1;
[nav_block.align_stat, count] = fread(fid, 1, 'int16');
%
% These within F identifier (26)
%
[nav_block.cabin_alt, count] = fread(fid, 1, 'int32');
[nav_block.press, count] = fread(fid, 1, 'int32');
nav_block.press = nav_block.press*0.1;
[nav_block.mach, count] = fread(fid, 1, 'int16');
nav_block.mach = nav_block.mach*0.001;
[nav_block.cross_track_dist, count] = fread(fid, 1, 'int32');
nav_block.cross_track_dist = nav_block.cross_track_dist*0.1;
[nav_block.desired_track, count] = fread(fid, 1, 'int32');
nav_block.desired_track = nav_block.desired_track*0.1;
[nav_block.track_ang_err, count] = fread(fid, 1, 'int32');
nav_block.track_ang_err = nav_block.track_ang_err*0.1;
[nav_block.track_ang, count] = fread(fid, 1, 'int16');
nav_block.track_ang = nav_block.track_ang*0.1;
[nav_block.spec_humid, count] = fread(fid, 1, 'int16');
nav_block.spec_humid = nav_block.spec_humid*0.001;
%
% These within G identifier (20)
%
[nav_block.par_press_h20, count] = fread(fid, 1, 'int16');
nav_block.par_press_h20 = nav_block.par_press_h20*0.1;
[nav_block.RH_ice, count] = fread(fid, 1, 'int16');
nav_block.RH_ice = nav_block.RH_ice*0.1;
[nav_block.RH_wat, count] = fread(fid, 1, 'int16');
nav_block.RH_wat = nav_block.RH_wat*0.1;
[nav_block.sat_wat_vap_press, count] = fread(fid, 1, 'int16');
nav_block.sat_wat_vap_press = nav_block.sat_wat_vap_press*0.01;
[nav_block.sat_wat_vap_press_ice, count] = fread(fid, 1, 'int16');
nav_block.sat_wat_vap_press_ice = nav_block.sat_wat_vap_press_ice*0.01;
[nav_block.sun_elev_gnd_refracted, count] = fread(fid, 1, 'int16');
nav_block.sun_elev_gnd_refracted = nav_block.sun_elev_gnd_refracted*0.1;
[nav_block.sun_elev_air_refracted, count] = fread(fid, 1, 'int16');
nav_block.sun_elev_air_refracted = nav_block.sun_elev_air_refracted*0.1;
[nav_block.sun_azimuth_gnd_refracted, count] = fread(fid, 1, 'int16');
nav_block.sun_azimuth_gnd_refracted = nav_block.sun_azimuth_gnd_refracted*0.1;
[nav_block.sun_azimuth_air_refracted, count] = fread(fid, 1, 'int32');
nav_block.sun_azimuth_air_refracted = nav_block.sun_azimuth_air_refracted*0.1;
%
% These within H identifier (16)
%
[nav_block.egi_true_hdg, count] = fread(fid, 1, 'int16');
nav_block.egi_true_hdg = nav_block.egi_true_hdg*0.1;
[nav_block.egi_mag_hdg, count] = fread(fid, 1, 'int16');
nav_block.egi_mag_hdg = nav_block.egi_mag_hdg*0.1;
[nav_block.egi_x_velocity, count] = fread(fid, 1, 'int16');
[nav_block.egi_y_velocity, count] = fread(fid, 1, 'int16');
[nav_block.egi_z_velocity, count] = fread(fid, 1, 'int16');
[nav_block.egi_x_accel, count] = fread(fid, 1, 'int16');
[nav_block.egi_y_accel, count] = fread(fid, 1, 'int16');
[nav_block.egi_z_accel, count] = fread(fid, 1, 'int16');
%
% These within I identifier (18)
%
[nav_block.adc_tat, count] = fread(fid, 1, 'int16');
nav_block.adc_tat = nav_block.adc_tat*0.1;
[nav_block.rose_tat, count] = fread(fid, 1, 'int16');
nav_block.rose_tat = nav_block.rose_tat*0.1;
[nav_block.potential_temp, count] = fread(fid, 1, 'int16');
nav_block.potential_temp = nav_block.potential_temp*0.1;
[nav_block.gps_alt_msl, count] = fread(fid, 1, 'int32');
[nav_block.camex_dfpoint, count] = fread(fid, 1, 'int16');
nav_block.camex_dfpoint = nav_block.camex_dfpoint*0.1;
[nav_block.sun_elev_earth, count] = fread(fid, 1, 'int16');
nav_block.sun_elev_earth = nav_block.sun_elev_earth*0.1;
[nav_block.sun_elev_aircraft, count] = fread(fid, 1, 'int16');
nav_block.sun_elev_aircraft = nav_block.sun_elev_aircraft*0.1;
[nav_block.sun_azi_earth, count] = fread(fid, 1, 'int16');
nav_block.sun_azi_earth = nav_block.sun_azi_earth*0.1;
%
% Now read the first block of junk
%
junk1 = fread(fid, 14, 'int8');
%
% Read GPS time
%
[efm_block.GPSTime.tm_yday, count] = fread(fid, 1, 'int16');
[efm_block.GPSTime.tm_hour, count] = fread(fid, 1, 'int8');
[efm_block.GPSTime.tm_min, count] = fread(fid, 1, 'int8');
[efm_block.GPSTime.tm_sec, count] = fread(fid, 1, 'int8');
%
0ne byte of junk
%
junk2 = fread(fid, 1, 'int8');
[efm_block.subseconds, count] = fread(fid, 1, 'int32');
%
% Read PC time
%
[efm_block.version, count] = fread(fid, 1, 'int16');
[efm_block.pcUTC.tm_yday, count] = fread(fid, 1, 'int16');
[efm_block.pcUTC.tm_year, count] = fread(fid, 1, 'int16');
[efm_block.pcUTC.tm_wday, count] = fread(fid, 1, 'int8');
[efm_block.pcUTC.tm_hour, count] = fread(fid, 1, 'int8');
[efm_block.pcUTC.tm_min, count] = fread(fid, 1, 'int8');
[efm_block.pcUTC.tm_sec, count] = fread(fid, 1, 'int8');
[efm_block.pcUTC.tm_hsecond, count] = fread(fid, 1, 'int8');
%
% Populate rest of strucutre
%
date_vec = datevec(yearday(efm_block.pcUTC.tm_year,efm_block.pcUTC.tm_yday));
efm_block.pcUTC.tm_mon = date_vec(2)-1;
efm_block.pcUTC.tm_mday = date_vec(3);
%
% Populate rest of strucutre
%
date_vec = datevec(yearday(efm_block.pcUTC.tm_year,efm_block.GPSTime.tm_yday));
efm_block.GPSTime.tm_year = date_vec(1)-1900;
efm_block.GPSTime.tm_mon = date_vec(2)-1;
efm_block.GPSTime.tm_mday = date_vec(3);
efm_block.GPSTime.tm_yday;
efm_block.GPSTime.tm_hour;
efm_block.GPSTime.tm_min;
efm_block.GPSTime;
efm_block.pcUTC.tm_year = efm_block.pcUTC.tm_year - 1900;
%
% Read back time ?
%
[efm_block.back.tm_sec, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_min, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_hour, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_yday, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_mon, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_year, count] = fread(fid, 1, 'int8');
[efm_block.back.tm_wday, count] = fread(fid, 1, 'int8');
%
% Convert the time to a number
%
efm_block.timeGPS = datenum(efm_block.GPSTime.tm_year+1900, efm_block.GPSTime.tm_mon+1, efm_block.GPSTime.tm_mday, efm_block.GPSTime.tm_hour, efm_block.GPSTime.tm_min, efm_block.GPSTime.tm_sec);
efm_block.timePC = datenum(efm_block.pcUTC.tm_year+1900, efm_block.pcUTC.tm_mon+1, efm_block.pcUTC.tm_mday, efm_block.pcUTC.tm_hour, efm_block.pcUTC.tm_min, efm_block.pcUTC.tm_sec);
%
% Now get to the real stuff, the FM data
%
for i=1:6
[efm_block.efmrecord(i).sync(1), count] = fread(fid, 1, 'int8');
[efm_block.efmrecord(i).sync(2), count] = fread(fid, 1, 'int8');
[efm_block.efmrecord(i).header, count] = fread(fid, 10, 'uchar');
[efm_block.efmrecord(i).one, count] = fread(fid, 25, 'bit12',4);
[efm_block.efmrecord(i).two, count] = fread(fid, 25, 'bit12',4);
[efm_block.efmrecord(i).three, count] = fread(fid, 25, 'bit12',4);
[efm_block.efmrecord(i).four, count] = fread(fid, 25, 'bit12',4);
0.000000or j=1:25
0f efm_block.efmrecord(i).one(j) > 2048
0.000000e+00fm_block.efmrecord(i).one(j) = efm_block.efmrecord(i).one(j) - 4096;
0.000000e+00nd
0f efm_block.efmrecord(i).two(j) > 2048
0.000000e+00fm_block.efmrecord(i).two(j) = efm_block.efmrecord(i).two(j) - 4096;
0.000000e+00nd
0f efm_block.efmrecord(i).three(j) > 2048
0.000000e+00fm_block.efmrecord(i).three(j) = efm_block.efmrecord(i).three(j) - 4096;
0.000000e+00nd
0f efm_block.efmrecord(i).four(j) > 2048
0.000000e+00fm_block.efmrecord(i).four(j) = efm_block.efmrecord(i).four(j) - 4096;
0.000000e+00nd
0.000000e+00nd
[efm_block.efmrecord(i).crc, count] = fread(fid, 1, 'int16');
end
%
% Now read cal block
%
[efm_block.cal_buf, count] = fread(fid, 300, 'int16');
%
% That should be all!
%
return;
*****************************************************

The second function call is named sload_dc8_data.m and is shown below:

************************************************************************

function [efm_data_matrix, time_array, mill_array, N, summary_data, summary_count, time_gaps,nav_data] = sload_dc8_data(file_count, file_list, base_directory, pps, cut_off, order);
% [efm_data_matrix, time_array, mill_array, N, summary_data, summary_count, time_gaps] =
load_dc8_data(file_count, file_list, directory, pps, cut_off, order);
%
% This routine loads a boatload of efm data into two arrays, one for the data
% and one for time. It will use "resample" to take the data from 50 samples per second to the
% value set in pps. Note that "resample" is set to NOT filter the data.
%
% Inputs:
0.000000ile_count = # input files
0.000000ile_list(file_count,?) = char string array of input files
0irectory = char of base directory to find files (default: current directory)
0ps = how many points per second in the output (default: all 50)
nd pre-set the values for the time sorted mill data
%
0.000000e+00time(clock,T1)
% T1 = clock;
0isp('Pre-allocating new efm data');
% time_sort_efm_data(4,6,Ntot) = 0;
0.000000e+00time(clock,T1)
% T1 = clock;
0isp('Make all data NaN');
% time_sort_efm_data = NaN;
%
% Now dump the mill data into the time ordered and alighned array
%
etime(clock,T1)
T1 = clock;
disp('Put Alighned Data Into Array');
time_index = 1;
tom_index = 1;
time_sort_efm_data = efm_data;
0.000000or block_index=1:max_times
0n_block_start = (block_index-1)*25 + 1;
0n_block_end = (block_index-1)*25 + 25;
0ut_block_start = (sort_index(block_index)-1)*25 + 1;
0ut_block_end = (sort_index(block_index)-1)*25 + 25;
0.000000or mill_index=1:6
%
0etermine time block for this mill's data
%
% time_of_mill = round((summary_data(block_index).best_time)*60*60*24 - summary_data(block_index).mill_delta_time(mill_index) - base_time);
% tom(mill_index,block_index) = time_of_mill;
% while time_of_mill > block_times(time_index)
% time_index = time_index+1;
0.000000e+00nd
% while time_of_mill < block_times(time_index)
% time_index = time_index-1;
0.000000e+00nd
%
% Now we have found the correct block to put in the data
%
0ut_block = (time_index-1)*25;
% Ntot;
0.000000or data_index=in_block_start:in_block_end
0ut_block = out_block + 1;
0.000000or gain_index=1:4
% time_sort_efm_data(gain_index,mill_index,out_block) = efm_data(gain_index,mill_index,data_index);
0.000000e+00nd
0.000000e+00nd
0.000000e+00nd
% time_sort_efm_data(:,:,in_block_start:in_block_end) = efm_data(:,:,out_block_start:out_block_end);
0.000000e+00nd
%
% Now resample data
%
etime(clock,T1)
T1 = clock;
disp('Resampling Data');
Ntot
d = gcd(pps,25);
p = pps/d;
q = 25/d;
N = ceil(Ntot*p/q)
if pps ~= 25
efm_data_matrix(4,6,N) = 0;
for mill_index=1:6
dummy_array_1 = resample(squeeze(time_sort_efm_data(1,mill_index,1:Ntot)),p,q,0);
dummy_array_2 = resample(squeeze(time_sort_efm_data(2,mill_index,1:Ntot)),p,q,0);
dummy_array_3 = resample(squeeze(time_sort_efm_data(3,mill_index,1:Ntot)),p,q,0);
dummy_array_4 = resample(squeeze(time_sort_efm_data(4,mill_index,1:Ntot)),p,q,0);
efm_data_matrix(1,mill_index,:) = dummy_array_1;
efm_data_matrix(2,mill_index,:) = dummy_array_2;
efm_data_matrix(3,mill_index,:) = dummy_array_3;
efm_data_matrix(4,mill_index,:) = dummy_array_4;
end
time_array = resample(time(1:Ntot),p,q,0);
else
efm_data_matrix = time_sort_efm_data(:,:,1:Ntot);
time_array = time(1:Ntot);
end
etime(clock,T1)
T1 = clock;
disp('Convert to Matlab time and log time gaps');
%
% Change time array back to Matlab format
%
time_array = (time_array + base_time)/86400;
%
% Convert counts to volts
%
efm_data_matrix = efm_data_matrix*counts_2_volts;
%
% Log all time gaps
%
delta_time = q/(25*p)
gap_count = 0;
for time_index=2:N
delt = (time_array(time_index)-time_array(time_index-1))*86400;
delta_time;
if abs(delt-delta_time)/delta_time > 0.4
gap_count = gap_count + 1;
time_gap_string = sprintf(' 0.00 gap starting at ',delt,datestr(time_array(time_index-1)));
time_gaps(gap_count,1:45) = time_gap_string(1:45);
disp(time_gaps(gap_count,:));
end
end
etime(clock,T1)
etime(clock,T0)
***************************************

MatLab is available from MathWorks.

Contact Information

The data producer is:

Dr. Monte Bateman
NSSTC
320 Sparkman Dr.
Huntsville, AL  35805

To order these data or for further information, please contact:

Global Hydrology Resource Center
User Services
320 Sparkman Drive
Huntsville, AL 35805
Phone: 256-961-7932
E-mail: support-ghrc@earthdata.nasa.gov
Web: http://ghrc.nsstc.nasa.gov/