% LISST100Xasc2nc convert LISST.EXE processed ascii output to netCDF EPIC % % function lisst = LISST100Xasc2nc(LISSTroot, ncroot, metadata) % LISSTroot = root file name for the LISST.EXE output % will seek the processed .asc files % does not work on settling experiment files % ncroot = root file name for converted netCDF data % processed data will go to an .nc file as a time series % the .asc file columns are % 1:32 Volume concentration (in ul/l) for size class 1 through 32 % 33 Laser transmission Sensor % 34 Battery voltage in calibrated units % 35 External Auxiliary input 1 in calibrated units % 36 Laser Reference sensor in calibrated units % 37 Pressure in calibrated units % 38 Temperature in calibrated units of degrees C % 39 (Day*100 + Hour) at which data taken % 40 (Minutes*100 + Seconds) at which data taken % 41 Computed % Optical transmission over path % 42 Computed Beam-C in units of 1/m % there must be a deployment start date!! % metadata.deployment_start = gatt.Deployment_date; % the in water time % metadata.deployment_end = gatt.Recovery_date; % the out of water time % metadata.lon = gatt.longitude; % decimal degrees, West = negative % metadata.lat = gatt.latitude; % decimal degrees, South = negative % metadata.WATER_DEPTH = gatt.WATER_DEPTH; % m (DO NOT OMIT!) % % LISST specific information % metadata.serial = '1172'; % serial number of the LISST % metadata.type = 'C'; % LISST type (indicating size range) % metadata.zscFile = '1172bench29nov07gmt1602.asc'; %best background scatter file % metadata.factoryFile = 'factory_zsc_1172.asc'; % best background scatter file % metadata.ringFile = 'ringarea_1172.asc'; % best background scatter file % % these are [slope, offset] % metadata.cal.laserpower = [0.00081556 0]; % raw count to mW % metadata.cal.battery = [0.01 0]; % raw count to volts % metadata.cal.external = [0 0]; % none for LISST-ST % metadata.cal.laserreference = [0.00076741 0]; %raw count to mW % metadata.cal.pressure = [0.01 -10]; %raw count to meters % metadata.cal.temperature = [0.01 0]; % raw count to deg C % metadata.cal.volumeconversion = 45733; %in instrumentdata.txt % % this height will be tagged to all variables % metadata.inst_height = 0.31; % m pressure port height, about the same as the optics % metadata.STtopopening_height = 0; % m % metadata.STnsettlingsamples = 0; % a settling experiment % metadata.MOORING = '8482'; % % metadata.metafile = mfilename('fullpath'); % metadata.metafile_date = datestr(now); % metadata.metafile_version = '0.0'; % metadata.metafile_author = 'MM'; % % metadata.DATA_ORIGIN = gatt.DATA_ORIGIN; % with collaborator's data, could be USC, etc. % metadata.EXPERIMENT = gatt.EXPERIMENT; % metadata.PROJECT = gatt.PROJECT; % might also use OFA funding agency, such as MWRA, EPA, WCMG % metadata.DESCRIPTION = gatt.DESCRIPTION; % metadata.SciPi = gatt.SciPi; % metadata.Conventions = gatt.Conventions; % metadata.DATA_CMNT = ''; % your metadata % metadata.longitude = gatt.longitude; % negative degrees in western hemisphere % metadata.lonUnits = 'degrees_east'; % metadata.latitude = gatt.latitude; % always positive degrees in northern % metadata.latUnits = 'degrees_north'; % % metadata.dataFile = LISSTroot; % % metadata.goodsamples = [681 20528]; % use [1 Inf] for all data % % lisst = a structure of the data % tm: [1x378 double] % tj: [1x378 double] % volconc: [378x32 double] % laserxmit: [1x378 double] % batt: [1x378 double] % aux1: [1x378 double] % laserref: [1x378 double] % press: [1x378 double] % temp: [1x378 double] % ptrans: [1x378 double] % beamc: [1x378 double] % sizes: [1x32 double] % procFile: source file name % zscData: background scatter data % % Settling experiments will be treated as simple time series. % 8/12/08 brain dead, beam-c and % trans was swapped. % 7/22/08 More metadata stuff % 5/4/06 Add EPIC compliance details % Written by Marinna Martini 2/18/06 function lisst = LISST100Xasc2nc(LISSTroot, ncroot, metadata) % get the current SVN version- the value is automatically obtained in svn % is the file's svn.keywords which is set to "Revision" rev_info = 'SVN $Revision$'; disp(sprintf('%s %s running',mfilename,rev_info)) lisst = []; metadata.settling = 0; ndatacols = 42; disp(sprintf('%s now running %s',mfilename,datestr(now,0))) if ~exist('metadata','var'), disp('Metadata is required for processing') eval(['help ',mfilename]) end if ~exist('LISSTroot','var'), LISSTroot = ''; end [pathname, fname] = fileparts(LISSTroot); procFile = fullfile(pathname,[fname,'.asc']); % get the data file if fname(1) == 'S', disp('This is a settling experiment') metadata.settling = 1; if ~isfield(metadata,'nsettlingsamples') buf = inputdlg('Enter the number of samples per settling experiment: ',... 'Required information',1,{'82'}); if isempty(buf), return, end metadata.nsettlingsamples = str2double(buf{1}); end else metadata.nsettlingsamples = 0; end if ~exist(procFile,'file'), FilterSpec(1,:) = {'*.asc','*.asc processed LISST data file'}; [fname, pathname] = uigetfile(FilterSpec, 'Pick a LISST data file'); if isequal(fname,0) || isequal(pathname,0) disp('User pressed cancel') return end procFile = fullfile(pathname, fname); end disp(['User selected processed data file ', procFile]) % metadata.zscFile = background scatter file chosen by user based on field conditions if ~isfield(metadata, 'zscFile') FilterSpec(1,:) = {'*.asc','*.asc LISST background scatter file'}; [fname, pathname] = uigetfile(FilterSpec, 'Pick a LISST background scatter file'); metadata.zscFile = fullfile(pathname, fname); end metadata.zscData = load(metadata.zscFile); if isempty(metadata.zscData) disp('No background scatter file data available, aborting') return end % metadata.factoryFile = factory background scatter file if ~isfield(metadata, 'factoryFile') FilterSpec(1,:) = {'*.asc','*.asc LISST factory background scatter file'}; [fname, pathname] = uigetfile(FilterSpec, 'Pick a LISST factory background scatter file'); metadata.factoryFile = fullfile(pathname, fname); end metadata.factoryData = load(metadata.factoryFile); if isempty(metadata.factoryData) disp('No factory background scatter file data available, aborting') return end % metadata.ringFile = ring area calibration file if ~isfield(metadata, 'ringFile') FilterSpec(1,:) = {'*.asc','*.asc LISST ring file'}; [fname, pathname] = uigetfile(FilterSpec, 'Pick a LISST ring file'); metadata.ringFile = fullfile(pathname, fname); end metadata.ringData = load(metadata.ringFile); if isempty(metadata.ringData) disp('No ring file data available, aborting') return end % figure out the time if ~isfield(metadata,'deployment_start'), % guess from the data file time stamp junk = dir(rawFile); dvec = datevec(datenum(junk.date)); disp(sprintf('Deployment year %d taken from data file time stamp',dvec(1))) disp(sprintf('Deployment month %d taken from data file time stamp',dvec(2))) else % take it from the in water time dvec = datevec(datenum(metadata.deployment_start)); disp(sprintf('Deployment year %d taken from in water time',dvec(1))) disp(sprintf('Deployment month %d taken from in water time',dvec(2))) end if isfield(metadata,'goodsamples'), goodsamples = metadata.goodsamples; if goodsamples(1) < 1, goodsamples(1) = 1; end %if goodsamples(2) > nsamples, goodsamples(2) = nsamples; end %data = data(goodsamples(1):goodsamples(2),:); end if isfield(metadata, 'type'), metadata.type = lower(metadata.type); else metadata.type = {'A','B','C','F'}; [n,v] = listdlg('PromptString','Select type of instrument:',... 'SelectionMode','single','ListString',metadata.type); if ~v, disp('LISST type is required information') return end metadata.type = lower(metadata.type{n}); end disp(sprintf('The LISST type is %s',metadata.type)) if ~isfield(metadata, 'serial'), metadata.serial = ''; disp('No serial number provided') end % make sure this is a time series experiment, not a settling experiment fid = fopen(procFile,'r'); buf = fgetl(fid); [data, count] = sscanf(buf, '%f', ndatacols); if count < ndatacols, disp(sprintf('detected %d columns of data where %d were expected',... count, ndatacols)) disp(sprintf('%s only reads output from LISST.EXE for the LISST 100X',... mfilename)) return end fclose(fid); disp('defining netCDF') [pathname] = fileparts(procFile); ncFile = fullfile(pathname,[ncroot,'.nc']); nc = netcdf(ncFile,'clobber'); definenc(nc, metadata) fid = fopen(procFile,'r'); % we are reading line by line so that large time series will not overwhelm % computer memory. But it does take longer than load() % TODO try to estimate number of samples by files size % and preallocate for speed tic; count = ndatacols; ncidx = 0; dataidx = 0; while count == ndatacols, dataidx = dataidx + 1; [data,count] = fscanf(fid, '%f', ndatacols); if count < 42, break; end data = data'; if isempty(data), break; end nzeros = length(find(data == 0)); if metadata.settling && (nzeros == count), % this is a header, do nothing disp(sprintf('skipping record %d as settling experiment header',dataidx)) elseif dataidx >= goodsamples(1), ncidx = ncidx + 1; rec(ncidx) = dataidx; % compute the time stamps % yearday includes the first day, so dayone is decremented by one dayone = datenum([dvec(1),1,1,0,0,0])-1; % the first index of yearday is Jan 1 of the given year yearday = floor(data(1,39)./100); yday(ncidx) = yearday; % save for finding year rollover later hour = rem(data(1,39),100); min = floor(data(1,40)./100); sec = rem(data(1,40),100); tm(ncidx) = dayone+yearday+hour./24+min./(24*60)+sec./(24*3600); tj(ncidx) = julian(datevec(tm(ncidx))); %clear yearday hour min sec dayone % parse the other data volconc(ncidx,:) = data(:,1:32); laserxmit(ncidx) = data(:,33); batt(ncidx) = data(:,34); aux1(ncidx) = data(:,35); laserref(ncidx) = data(:,36); press(ncidx) = data(:,37); temp(ncidx) = data(:,38); ptrans(ncidx) = data(:,41); beamc(ncidx) = data(:,42); % attempt to fix temperature rollover % hmm... this created a mess... maybe fixed in new firmware? % if temp(ncidx) < 377, % temp(ncidx) = (temp(ncidx) + 655.36)./100; % end nc{'rec'}(ncidx,1,1,1) = rec(ncidx); nc{'time'}(ncidx,1,1,1) = floor(tj(ncidx)); nc{'time2'}(ncidx,1,1,1) = (tj(ncidx) - floor(tj(ncidx))).*(3600*24*1000); nc{'vconc'}(ncidx,:) = volconc(ncidx,:); nc{'ltrans'}(ncidx,1,1,1) = laserxmit(ncidx); nc{'batt'}(ncidx,1,1,1) = batt(ncidx); nc{'lref'}(ncidx,1,1,1) = laserref(ncidx); nc{'P_1'}(ncidx,1,1,1) = press(ncidx); nc{'T_20'}(ncidx,1,1,1) = temp(ncidx); nc{'ATTN_55'}(ncidx,1,1,1) = beamc(ncidx); nc{'ptrans'}(ncidx,1,1,1) = ptrans(ncidx); end if dataidx > goodsamples(2), break; end if exist('tm','var'), if ncidx == 1, disp(sprintf('First date stamp is %s',datestr(datenum(gregorian(tj(1)))))); end if ncidx<50 && ~rem(ncidx,10), disp(sprintf('Finished sample #%d %s %4.2f min elapsed',ncidx,datestr(tm(ncidx)),toc./60)), end if ncidx>50 && ~rem(ncidx,100), disp(sprintf('Finished sample #%d %s %4.2f min elapsed',ncidx,datestr(tm(ncidx)),toc./60)), end end end metadata.nsamples = ncidx; % must correct time if there was a year rollover if (yday(1) > 1), % we didn't start at the beginning of a year yendidx = find(yday == 365,1,'last'); if ~isempty(yendidx), % a new year started during our experiment disp(sprintf('Found a year rollover at index %d, correcting for it',yendidx)) tj(yendidx+1:end) = tj(yendidx+1:end)+365; % tg = gregorian(tj); % TODO fix this leap year code % if (any(~mod(tg(:,1),4)) && any(mod(tg(:,1),100))) || any(~mod(tg(:,1),400)), % then leap % this next line bombs for starts after feb! % mar1idx = find(tg(:,2) > 2 ,1,'first'); % if ~isempty(mar1idx) % disp(sprintf('Found a leap year Mar 1 at index %d, correcting for it',mar1idx)) % tj(mar1idx-1:end) = tj(mar1idx-1:end)+1; % end % end nc{'time'}(:,1,1,1) = floor(tj); end end disp(sprintf('%d samples stored to nc file',ncidx)) fclose(fid); % finish up the EPIC attributes nc.history = ncchar(sprintf('Converted by %s %s;\n',mfilename,rev_info)); nc.DELTA_T = gmean(diff(tj)).*(24*3600); nc.start_time = ncchar(datestr(datenum(gregorian(tj(1))))); nc.stop_time = ncchar(datestr(datenum(gregorian(tj(end))))); nc.original_data_file = ncchar(LISSTroot); add_minmaxvalues(nc); add_fillvalues(nc,1E35); add_vardesc(nc); % add depth attributes to variables % uses the height of the pressure port or whatever is given by inst_height add_depth_atts(nc) close(nc); lisst.tm = tm; lisst.tj = tj; lisst.volconc = volconc; lisst.laserxmit = laserxmit; lisst.batt = batt; lisst.aux1 = aux1; lisst.laserref = laserref; lisst.press = press; lisst.temp = temp; lisst.ptrans = ptrans; lisst.beamc = beamc; lisst.sizes = sizeclass(metadata.type); lisst.procFile = procFile; if metadata.type == 'a' || metadata.type == 'f', lisst.sizeunits = 'ring number'; else lisst.sizeunits = 'microns'; end return function definenc(nc, metadata) % data from read_globalatts if isfield(metadata,'DATA_ORIGIN'), nc.DATA_ORIGIN = ncchar(metadata.DATA_ORIGIN); end if isfield(metadata,'EXPERIMENT'), nc.EXPERIMENT = ncchar(metadata.EXPERIMENT); end if isfield(metadata,'PROJECT'), nc.PROJECT = ncchar(metadata.PROJECT); end if isfield(metadata,'DESCRIPTION'), nc.DESCRIPTION = ncchar(metadata.DESCRIPTION); end if isfield(metadata,'SciPi'), nc.SciPi = ncchar(metadata.SciPi); end if isfield(metadata,'Conventions'), nc.Conventions = ncchar(metadata.Conventions); end if isfield(metadata,'DATA_CMNT'), nc.DATA_CMNT = ncchar(metadata.DATA_CMNT); end if isfield(metadata,'latitude'), nc.latitude = metadata.latitude; else nc.latitude = ncfloat(999); end if isfield(metadata,'latUnits'), nc.latUnits = metadata.latUnits; end if isfield(metadata,'longitude'), nc.longitude = ncfloat(metadata.longitude); else nc.longitude = ncfloat(999); end if isfield(metadata,'lonUnits'), nc.lonUnits = metadata.lonUnits; end if isfield(metadata,'Deployment_date'), nc.Deployment_date = ncfloat(metadata.Deployment_date); else nc.Deployment_date = ncfloat(999); end if isfield(metadata,'Recovery_date'), nc.Recovery_date = ncfloat(metadata.Recovery_date); else nc.Recovery_date = ncfloat(999); end if isfield(metadata,'DATA_SUBTYPE'), nc.DATA_SUBTYPE = ncchar(metadata.DATA_SUBTYPE); end if isfield(metadata,'MOORING'), nc.MOORING = ncchar(metadata.MOORING); end if isfield(metadata,'WATER_DEPTH'), nc.WATER_DEPTH = ncfloat(metadata.WATER_DEPTH); end nc.CREATION_DATE = ncchar(datestr(now)); nc.DATA_TYPE = ncchar('TIME'); cdf.COORD_SYSTEM = ncchar('GEOGRAPHICAL'); nc.WATER_MASS = ncchar('?'); nc.COMPOSITE = nclong(0); % for flagging patched together data sets nc.POS_CONST = nclong(0); nc.DEPTH_CONST = nclong(1); % depth will change nc.FILL_FLAG = nclong(1); nc.VAR_FILL = ncfloat(1e35); nc.water_depth = ncfloat(metadata.WATER_DEPTH); nc.INST_TYPE = ncchar('Sequoia LISST100X'); nc.inst_height = ncfloat(metadata.inst_height); nc.inst_depth = ncfloat(metadata.WATER_DEPTH-metadata.inst_height); if metadata.settling, nc.STnsettlingsamples = metadata.STnsettlingsamples; nc.STtopopening_height = metadata.STtopopening_height; end nc.ringFile = ncchar(metadata.ringFile); nc.ringData = ncdouble(metadata.ringData); nc.factoryFile = ncchar(metadata.factoryFile); nc.factoryData = ncdouble(metadata.factoryData); nc.zscFile = ncchar(metadata.zscFile); nc.zscData = ncdouble(metadata.zscData); nc.cal_laserpower = metadata.cal.laserpower; % raw count to mW nc.cal_battery = metadata.cal.battery; % raw count to volts nc.cal_external = metadata.cal.external; % none for LISST-ST nc.cal_laserreference = metadata.cal.laserreference; %raw count to mW nc.cal_pressure = metadata.cal.pressure; %raw count to meters nc.cal_temperature = metadata.cal.temperature; % raw count to deg C nc.cal_volumeconversion = metadata.cal.volumeconversion; %in instrumentdata.txt %% Dimensions: nc('time') = 0; nc('depth') = 1; nc('lat') = 1; nc('lon') = 1; nc('size') = 32; %% Variables and attributes: %% coordinate variables: nc{'time'} = nclong('time') ; nc{'time'}.FORTRAN_format = ncchar('F10.2'); nc{'time'}.units = ncchar('True Julian Day'); nc{'time'}.type = ncchar('EVEN'); nc{'time'}.epic_code = nclong(624); nc{'time2'} = nclong('time') ; nc{'time2'}.FORTRAN_format = ncchar('F10.2'); nc{'time2'}.units = ncchar('msec since 0:00 GMT'); nc{'time2'}.type = ncchar('EVEN'); nc{'time2'}.epic_code = nclong(624); nc{'depth'} = ncfloat('depth') ; nc{'depth'}.FORTRAN_format = ncchar('F10.2'); nc{'depth'}.units = ncchar('m'); nc{'depth'}.type = ncchar('EVEN'); nc{'depth'}.epic_code = nclong(3); nc{'lat'} = ncfloat('lat') ; nc{'lat'}.FORTRAN_format = ncchar('F10.2'); nc{'lat'}.units = ncchar('degrees_north'); nc{'lat'}.type = ncchar('EVEN'); nc{'lat'}.epic_code = nclong(500); nc{'lon'} = ncfloat('lon') ; nc{'lon'}.FORTRAN_format = ncchar('F10.2'); nc{'lon'}.units = ncchar('degrees_east'); nc{'lon'}.type = ncchar('EVEN'); nc{'lon'}.epic_code = nclong(502); nc{'size'} = ncfloat('size') ; ncobj = nc{'size'}; ncobj.FORTRAN_format = ncchar('F10.2'); ncobj(:) = sizeclass(metadata.type); if metadata.type == 'a' || metadata.type == 'f', ncobj.units = 'ring number'; else ncobj.units = 'microns'; end %% record variables: nc{'rec'} = ncdouble('time', 'depth', 'lat', 'lon'); ncobj = nc{'rec'}; ncobj.long_name = ncchar('Record Number'); ncobj.units = ncchar('count'); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.valid_range = ncfloat([1 2^32]); nc{'vconc'} = ncdouble('time', 'size', 'lat', 'lon'); ncobj = nc{'vconc'}; ncobj.long_name = ncchar('VOLUME CONCENTRATION (UL/L) '); ncobj.units = ncchar('ul/l'); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(metadata.serial); ncobj.valid_range = ncfloat([0 10000]); nc{'ltrans'} = ncfloat('time', 'depth','lat','lon'); ncobj = nc{'ltrans'}; ncobj.long_name = ncchar('LASER TRANSMISSION '); ncobj.units = ncchar('mW'); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(metadata.serial); ncobj.valid_range = ncfloat([0 10000]); nc{'batt'} = ncfloat('time', 'depth','lat','lon'); ncobj = nc{'batt'}; ncobj.long_name = ncchar('BATTERY VOLTAGE '); ncobj.units = ncchar('V'); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(metadata.serial); ncobj.valid_range = ncfloat([0 10000]); nc{'lref'} = ncfloat('time', 'depth','lat','lon'); ncobj = nc{'lref'}; ncobj.long_name = ncchar('LASER REFERENCE'); ncobj.units = ncchar('mW'); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(metadata.serial); ncobj.valid_range = ncfloat([0 10000]); nc{'ptrans'} = ncfloat('time', 'depth','lat','lon'); ncobj = nc{'ptrans'}; ncobj.long_name = ncchar('% OPTICAL TRANSMISSION'); ncobj.units = ncchar('%'); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(metadata.serial); ncobj.valid_range = ncfloat([0 100]); nc{'P_1'} = ncfloat('time', 'depth', 'lat', 'lon'); ncobj = nc{'P_1'}; ncobj.name = ncchar('P'); ncobj.long_name = ncchar('PRESSURE (DB) '); ncobj.generic_name = ncchar('depth'); ncobj.FORTRAN_format = ncchar('f10.1'); ncobj.units = ncchar('dbar'); ncobj.epic_code = nclong(1); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(' '); ncobj.valid_range = ncfloat([0 10000]); ncobj.comment = ncchar('Absolute pressure reduced by 10.1325 to remove atmospheric pressure.'); nc{'T_20'} = ncfloat('time', 'depth', 'lat', 'lon') ; ncobj = nc{'T_20'}; ncobj.name = ncchar('T'); ncobj.long_name = ncchar('TEMPERATURE (C) '); ncobj.generic_name = ncchar('temp'); ncobj.FORTRAN_format = ncchar('f10.2'); ncobj.units = ncchar('C'); ncobj.epic_code = nclong(20); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(' '); ncobj.valid_range = ncfloat([-50 50]); ncobj.comment = ncchar('IPTS-1968 Standard'); nc{'ATTN_55'} = ncfloat('time', 'depth', 'lat', 'lon') ; ncobj = nc{'ATTN_55'}; ncobj.name = ncchar('ATTN'); ncobj.long_name = ncchar('ATTENUATION '); ncobj.generic_name = ncchar('attn'); ncobj.FORTRAN_format = ncchar('f7.5'); ncobj.units = ncchar('m-1'); ncobj.epic_code = nclong(55); ncobj.sensor_depth = ncfloat(0); ncobj.minimum = ncfloat(0); ncobj.maximum = ncfloat(0); ncobj.serial_number = ncchar(' '); ncobj.valid_range = ncfloat([0 10000]); %% calibration information nc{'field_zscat'} = ncdouble('size'); ncobj = nc{'field_zscat'}; ncobj.long_name = ncchar('background scatter field readings'); ncobj.units = ncchar('counts'); ncobj.serial_number = ncchar(metadata.serial); ncobj.calibration_file = ncchar(metadata.zscFile); data = dir(metadata.zscFile); ncobj.calibration_date = ncchar(data.date); ncobj(:) = metadata.zscData(1:32); nc{'factory_zscat'} = ncdouble('size'); ncobj = nc{'factory_zscat'}; ncobj.long_name = ncchar('background scatter factory readings'); ncobj.units = ncchar('counts'); ncobj.serial_number = ncchar(metadata.serial); ncobj.calibration_file = ncchar(metadata.factoryFile); data = dir(metadata.factoryFile); ncobj.calibration_date = ncchar(data.date); ncobj(:) = metadata.factoryData(1:32); nc{'ring_data'} = ncdouble('size'); ncobj = nc{'ring_data'}; ncobj.long_name = ncchar('detector ring calibration'); ncobj.units = ncchar('counts'); ncobj.serial_number = ncchar(metadata.serial); ncobj.calibration_file = ncchar(metadata.ringFile); data = dir(metadata.ringFile); ncobj.calibration_date = ncchar(data.date); ncobj(:) = metadata.ringData; return function sc = sizeclass(type) switch type, case 'a', sc = 1:32; case 'b', sc = [1.36 1.60 1.89 2.23 2.63 3.11 3.67 4.33 ... 5.11 6.03 7.11 8.39 9.90 11.7 13.8 16.3 ... 19.2 22.7 26.7 31.6 37.2 44.0 51.9 61.2 ... 72.2 85.2 101 119 140 165 195 230]; case 'c', sc = [2.73 3.22 3.80 4.48 5.29 6.24 7.36 8.69 ... 10.2 12.1 14.3 16.8 19.9 23.5 27.7 32.7 ... 38.5 45.5 53.7 63.3 74.7 88.2 104 128 ... 157 186 219 259 293 332 391 462]; ncobj.units = 'microns'; case 'f', sc = 1:32; end return % add depth attributes to variables % uses the height of the pressure port or whatever is given by inst_height function add_depth_atts(cdf) theVars = var(cdf); for i = 1:length(theVars), if ~strcmp(ncnames(theVars{i}),'time') && ... ~strcmp(ncnames(theVars{i}),'time2') && ... ~strcmp(ncnames(theVars{i}),'lat') && ... ~strcmp(ncnames(theVars{i}),'lon') && ... ~strcmp(ncnames(theVars{i}),'rings'), theVars{i}.sensor_depth = ncfloat(cdf.WATER_DEPTH(:)-cdf.inst_height(:)); theVars{i}.sensor_height = ncfloat(cdf.inst_height(:)); end end return