//--------------------------------------------------------------andiLinkDef.h // LinkDef.h for including netCDF and AIA MS in ROOT #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class NcFile; #pragma link C++ class NcVar; #pragma link C++ class NcAtt; #pragma link C++ class NcDim; #pragma link C++ class NcTypedComponent; #pragma link C++ class NcError; #pragma link C++ class NcValues; /* -*-C-*- ******************************************************************************* * File: ms10io.h * Description: Public-domain implementation of the AIA MS Version 1.0.1 Data * Interchange Specification, Categories 1 and 2 data elements. * This file is a header file for the netCDF file I/O functions * of the MS specification. * Author: David Stranz * Language: C * Status: Public Domain (Distribute with Copyright Notice) * (C) Copyright 1992, 1993, Analytical Instrument Association * All rights reserved. ******************************************************************************* */ #ifndef MS10_IO_INCLUDED #define MS10_IO_INCLUDED 1 /* THIS FILE SHOULD BE INCLUDED *ONLY* BY FILE ms10io.c !! */ /* ******************************************************************************** * * Global, static variables * ******************************************************************************** */ #pragma link C global static char * ms_completeness_att = "C1+C2"; #pragma link C global static char * ms_template_att = "1.0.1"; #pragma link C global static char * ms_netcdf_att = "2.3.2"; #pragma link C global static char * ms_languages_att = "English"; /* This definition is for those compilers which do not supply one (usually supplied in stddef.h, but it may be absent in non-ANSI compilers).*/ #ifndef offsetof #define offsetof(s_name,m_name) (long)(&(((s_name*)0))->m_name) #endif /* ******************************************************************************** * MS_Dimensions data structure: This keeps track of all the dimension id * numbers used when reading or writing netCDF files. ******************************************************************************** */ #pragma link C typedef struct ms_dim; /* dimension size */ #pragma link C typedef struct MS_Dimensions; /* ******************************************************************************** * MS_Variables data structure: Keeps track of the netCDF variable ids. * The data structure member names might seem a bit long, but they are what * the "ncgen" utility would produce from the CDL file. ******************************************************************************** */ #pragma link C++ typedef struct MS_Variables; /* ******************************************************************************** * Client data structure: each time an AIA MS file is opened, a new "client" * is registered for that file, associating the netCDF file ID with dimension, * variable, data format, and other information. * * The array, ms_clients, and counter (ms_client_count) keep track of * client information and are dynamically adjusted. The function * ms_associate_id() adds a new client, and ms_dissociate_id() removes it. ******************************************************************************** */ #pragma link C++ typedef struct MS_Client_Data; #pragma link C++ global static MS_Client_Data * * ms_clients = NULL; #pragma link C++ global static int ms_client_count = 0; /* ******************************************************************************** * Datatype to format conversion table ******************************************************************************** */ #pragma link C++ static struct { nc_type cdf_type; ms_data_format_t ms_fmt; } ms_types[] = { { NC_SHORT, data_short }, { NC_LONG, data_long }, { NC_FLOAT, data_float }, { NC_DOUBLE, data_double } }; #pragma link C++ global static int nTypes = 4; /* ******************************************************************************** * Data structures * Most netCDF dimension, variable, and attribute definitions are presented * as arrays of data, defined by the three structures below. This affords more * easily maintainable code and avoids lengthy subroutines with explicit * calls to create or retrieve each element. * There are a few exceptions to this table-driven algorithm; these are clearly * identified in the code. ******************************************************************************** */ #pragma link C++ typedef struct MS_Dimension_Data; #pragma link C++ typedef struct MS_Variable_Data; #pragma link C++ typedef struct MS_Attribute_Data; /* ******************************************************************************** * MS_Dimension_Data arrays ******************************************************************************** */ /* Dimensions with implementation-defined sizes are included in this table. Those which are data-dependent (e.g. number of scans) are explicitly created in code. */ #pragma link C++ global static MS_Dimension_Data ms_dimensions[] = { { offsetof( MS_Dimensions, _2_byte_dim ), "_2_byte_string", 2L }, { offsetof( MS_Dimensions, _4_byte_dim ), "_4_byte_string", 4L }, { offsetof( MS_Dimensions, _8_byte_dim ), "_8_byte_string", 8L }, { offsetof( MS_Dimensions, _16_byte_dim ), "_16_byte_string", 16L }, { offsetof( MS_Dimensions, _32_byte_dim ), "_32_byte_string", 32L }, { offsetof( MS_Dimensions, _64_byte_dim ), "_64_byte_string", 64L }, { offsetof( MS_Dimensions, _128_byte_dim ), "_128_byte_string", 128L }, { offsetof( MS_Dimensions, _255_byte_dim ), "_255_byte_string", 255L }, { offsetof( MS_Dimensions, range_dim ), "range", 2L }, { offsetof( MS_Dimensions, point_number_dim ), "point_number", NC_UNLIMITED }, { offsetof( MS_Dimensions, error_number_dim ), "error_number", 1L } }; #pragma link C++ global static int nDims = (sizeof( ms_dimensions ) / sizeof( MS_Dimension_Data )); /* ******************************************************************************** * MS Variable data arrays ******************************************************************************** */ /* Error log */ #pragma link C++ global static MS_Variable_Data error_variables[] = { { offsetof( MS_Variables, error_log_id ), "error_log", NC_CHAR, (long)offsetof( MS_Admin_Data, error_log ), 2, { (long)offsetof( MS_Dimensions, error_number_dim ), (long)offsetof( MS_Dimensions, _64_byte_dim ) }} }; #pragma link C++ global static int nError = sizeof( error_variables ) / sizeof( MS_Variable_Data ); /* Raw data per-scan variables */ #pragma link C++ global static MS_Variable_Data raw_variables[] = { { offsetof( MS_Variables, a_d_sampling_rate_id ), "a_d_sampling_rate", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, a_d_rate ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, a_d_coaddition_factor_id ), "a_d_coaddition_factor", NC_SHORT, (long)offsetof( MS_Raw_Per_Scan, a_d_coadditions ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, scan_acquisition_time_id ), "scan_acquisition_time", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, scan_acq_time ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, scan_duration_id ), "scan_duration", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, scan_duration ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, inter_scan_time_id ), "inter_scan_time", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, inter_scan_time ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, resolution_id ), "resolution", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, resolution ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, actual_scan_id ), "actual_scan_number", NC_LONG, (long)offsetof( MS_Raw_Per_Scan, actual_scan_no ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, total_intensity_id ), "total_intensity", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, total_intensity ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, mass_range_min_id ), "mass_range_min", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, mass_range_min ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, mass_range_max_id ), "mass_range_max", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, mass_range_max ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, time_range_min_id ), "time_range_min", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, time_range_min ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, time_range_max_id ), "time_range_max", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Scan, time_range_max ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } } }; #pragma link C++ global static int nRawP = sizeof( raw_variables ) / sizeof( MS_Variable_Data ); /* Raw data per scan group variables */ #pragma link C++ global static MS_Variable_Data group_variables[] = { { offsetof( MS_Variables, group_mass_count_id ), "group_mass_count", NC_LONG, (long)offsetof( MS_Raw_Per_Group, mass_count ), 1, { (long)offsetof( MS_Dimensions, group_number_dim ), -1 } }, { offsetof( MS_Variables, group_start_id ), "group_starting_scan", NC_LONG, (long)offsetof( MS_Raw_Per_Group, starting_scan ), 1, { (long)offsetof( MS_Dimensions, group_number_dim ), -1 } }, { offsetof( MS_Variables, group_masses_id ), "group_masses", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Group, masses ), 2, { (long)offsetof( MS_Dimensions, group_number_dim ), (long)offsetof( MS_Dimensions, group_max_masses_dim ) } }, { offsetof( MS_Variables, group_samplings_id ), "group_sampling_times", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Group, sampling_times ), 2, { (long)offsetof( MS_Dimensions, group_number_dim ), (long)offsetof( MS_Dimensions, group_max_masses_dim ) } }, { offsetof( MS_Variables, group_delays_id ), "group_delay_times", NC_DOUBLE, (long)offsetof( MS_Raw_Per_Group, delay_times ), 2, { (long)offsetof( MS_Dimensions, group_number_dim ), (long)offsetof( MS_Dimensions, group_max_masses_dim ) } } }; #pragma link C++ global static int nGroupP = sizeof( group_variables ) / sizeof( MS_Variable_Data ); /* INSTRUMENT-ID variables */ #pragma link C++ global static MS_Variable_Data instrument_variables[] = { { offsetof( MS_Variables, instrument_name_id ), "instrument_name", NC_CHAR, (long)offsetof( MS_Instrument_Data, name ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_id_id ), "instrument_id", NC_CHAR, (long)offsetof( MS_Instrument_Data, id ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_mfr_id ), "instrument_mfr", NC_CHAR, (long)offsetof( MS_Instrument_Data, manufacturer ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_model_id ), "instrument_model", NC_CHAR, (long)offsetof( MS_Instrument_Data, model_number ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_serial_no_id ), "instrument_serial_no", NC_CHAR, (long)offsetof( MS_Instrument_Data, serial_number ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_sw_version_id ), "instrument_sw_version", NC_CHAR, (long)offsetof( MS_Instrument_Data, software_version ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_fw_version_id ), "instrument_fw_version", NC_CHAR, (long)offsetof( MS_Instrument_Data, firmware_version ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_os_version_id ), "instrument_os_version", NC_CHAR, (long)offsetof( MS_Instrument_Data, operating_system ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_app_version_id ), "instrument_app_version", NC_CHAR, (long)offsetof( MS_Instrument_Data, application_software ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, instrument_comments_id ), "instrument_comments", NC_CHAR, (long)offsetof( MS_Instrument_Data, comments ), 2, { (long)offsetof( MS_Dimensions, instrument_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } } }; #pragma link C++ global static int nInst = sizeof( instrument_variables ) / sizeof( MS_Variable_Data ); /* LIBRARY DATA PER-SCAN variables */ #pragma link C++ global static MS_Variable_Data library_variables[] = { { offsetof( MS_Variables, entry_name_id ), "entry_name", NC_CHAR, (long)offsetof( MS_Raw_Library, entry_name ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, entry_id_id ), "entry_id", NC_CHAR, (long)offsetof( MS_Raw_Library, entry_id ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, entry_number_id ), "entry_number", NC_LONG, (long)offsetof( MS_Raw_Library, entry_number ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, source_data_file_id ), "source_data_file_reference", NC_CHAR, (long)offsetof( MS_Raw_Library, source_data_file_reference ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, CAS_name_id ), "CAS_name", NC_CHAR, (long)offsetof( MS_Raw_Library, cas_name ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, CAS_number_id ), "CAS_number", NC_LONG, (long)offsetof( MS_Raw_Library, cas_number ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, other_name_0_id ), "other_name_0", NC_CHAR, (long)offsetof( MS_Raw_Library, other_name_0 ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, other_name_1_id ), "other_name_1", NC_CHAR, (long)offsetof( MS_Raw_Library, other_name_1 ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, other_name_2_id ), "other_name_2", NC_CHAR, (long)offsetof( MS_Raw_Library, other_name_2 ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, other_name_3_id ), "other_name_3", NC_CHAR, (long)offsetof( MS_Raw_Library, other_name_3 ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, chemical_formula_id ), "chemical_formula", NC_CHAR, (long)offsetof( MS_Raw_Library, formula ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _64_byte_dim ) } }, { offsetof( MS_Variables, smiles_id ), "smiles", NC_CHAR, (long)offsetof( MS_Raw_Library, smiles ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } }, { offsetof( MS_Variables, wiswesser_id ), "wiswesser", NC_CHAR, (long)offsetof( MS_Raw_Library, wiswesser ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _128_byte_dim ) } }, { offsetof( MS_Variables, molfile_id ), "molfile_reference", NC_CHAR, (long)offsetof( MS_Raw_Library, molfile_reference ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, other_structure_id ), "other_structure", NC_CHAR, (long)offsetof( MS_Raw_Library, other_structure ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _128_byte_dim ) } }, { offsetof( MS_Variables, retention_index_id ), "retention_index", NC_DOUBLE, (long)offsetof( MS_Raw_Library, retention_index ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, retention_type_id ), "retention_type", NC_CHAR, (long)offsetof( MS_Raw_Library, retention_type ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _32_byte_dim ) } }, { offsetof( MS_Variables, relative_retention_id ), "relative_retention", NC_DOUBLE, (long)offsetof( MS_Raw_Library, relative_retention ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, absolute_retention_id ), "absolute_retention", NC_DOUBLE, (long)offsetof( MS_Raw_Library, absolute_retention ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, retention_reference_name_id ), "retention_reference_name", NC_CHAR, (long)offsetof( MS_Raw_Library, retention_reference ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _128_byte_dim ) } }, { offsetof( MS_Variables, retention_reference_CAS_id ), "retention_reference_CAS", NC_LONG, (long)offsetof( MS_Raw_Library, retention_cas ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, melting_point_id ), "melting_point", NC_FLOAT, (long)offsetof( MS_Raw_Library, mp ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, boiling_point_id ), "boiling_point", NC_FLOAT, (long)offsetof( MS_Raw_Library, bp ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, chemical_mass_id ), "chemical_mass", NC_DOUBLE, (long)offsetof( MS_Raw_Library, chemical_mass ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, nominal_mass_id ), "nominal_mass", NC_LONG, (long)offsetof( MS_Raw_Library, nominal_mass ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, accurate_mass_id ), "accurate_mass", NC_DOUBLE, (long)offsetof( MS_Raw_Library, accurate_mass ), 1, { (long)offsetof( MS_Dimensions, scan_number_dim ), -1 } }, { offsetof( MS_Variables, entry_other_information_id ), "entry_other_information", NC_CHAR, (long)offsetof( MS_Raw_Library, other_info ), 2, { (long)offsetof( MS_Dimensions, scan_number_dim ), (long)offsetof( MS_Dimensions, _255_byte_dim ) } } }; #pragma link C++ global static int nLib = sizeof( library_variables ) / sizeof( MS_Variable_Data ); /* ******************************************************************************** * MS Attribute data arrays ******************************************************************************** */ /* Attribute data array for ADMINISTRATIVE INFORMATION attributes */ #pragma link C++ global static MS_Attribute_Data admin_attributes[] = { { offsetof( MS_Admin_Data, dataset_completeness ), "dataset_completeness", NC_GLOBAL, NC_CHAR, 1, 0, 0 }, { offsetof( MS_Admin_Data, ms_template_revision ), "ms_template_revision", NC_GLOBAL, NC_CHAR, 1, 0, 0 }, { offsetof( MS_Admin_Data, netcdf_revision), "netcdf_revision", NC_GLOBAL, NC_CHAR, 1, 0, 0 }, { offsetof( MS_Admin_Data, languages ), "languages", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, comments ), "administrative_comments", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, dataset_origin ), "dataset_origin", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, dataset_owner ), "dataset_owner", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, netcdf_date_time ), "netcdf_file_date_time_stamp", NC_GLOBAL, NC_CHAR, 1, 0, 0 }, { offsetof( MS_Admin_Data, experiment_title ), "experiment_title", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, experiment_date_time ), "experiment_date_time_stamp", NC_GLOBAL, NC_CHAR, 1, 0, 0 }, { offsetof( MS_Admin_Data, experiment_x_ref_0 ), "experiment_x_ref_0", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, experiment_x_ref_1 ), "experiment_x_ref_1", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, experiment_x_ref_2 ), "experiment_x_ref_2", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, experiment_x_ref_3 ), "experiment_x_ref_3", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, operator_name ), "operator_name", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, pre_expt_program_name ), "pre_experiment_program_name", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, post_expt_program_name ), "post_experiment_program_name", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, source_file_reference ), "source_file_reference", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, source_file_format ), "source_file_format", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, source_file_date_time ), "source_file_date_time_stamp", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, external_file_ref_0 ), "external_file_ref_0", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, external_file_ref_1 ), "external_file_ref_1", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, external_file_ref_2 ), "external_file_ref_2", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, external_file_ref_3 ), "external_file_ref_3", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, calibration_history_0 ), "calibration_history_0", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, calibration_history_1 ), "calibration_history_1", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, calibration_history_2 ), "calibration_history_2", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, calibration_history_3 ), "calibration_history_3", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Admin_Data, experiment_type ), "experiment_type", NC_GLOBAL, NC_CHAR, 0, 1, (int)expt_centroid }, { offsetof( MS_Admin_Data, number_times_processed ), "number_of_times_processed", NC_GLOBAL, NC_LONG, 0, 0, 0 }, { offsetof( MS_Admin_Data, number_times_calibrated ), "number_of_times_calibrated", NC_GLOBAL, NC_LONG, 0, 0, 0 } }; #pragma link C++ global static int nAdminA = sizeof( admin_attributes ) / sizeof( MS_Attribute_Data ); /* Attribute data array for SAMPLE DESCRIPTION attributes */ #pragma link C++ global static MS_Attribute_Data sample_attributes[] = { { offsetof( MS_Sample_Data, internal_id ), "sample_internal_id", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, external_id ), "sample_external_id", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, receipt_date_time ), "sample_receipt_date_time_stamp", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, owner ), "sample_owner", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, procedure_name ), "sample_procedure_name", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, matrix ), "sample_matrix", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, storage ), "sample_storage", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, disposal ), "sample_disposal", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, history ), "sample_history", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, prep_procedure ), "sample_prep_procedure", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, prep_comments ), "sample_prep_comments", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, manual_handling ), "sample_manual_handling", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, comments ), "sample_comments", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Sample_Data, state ), "sample_state", NC_GLOBAL, NC_CHAR, 0, 1, (int)state_other } }; #pragma link C++ global static int nSamp = sizeof( sample_attributes ) / sizeof( MS_Attribute_Data ); /* Attribute data array for TEST METHOD attributes */ #pragma link C++ global static MS_Attribute_Data test_attributes[] = { { offsetof( MS_Test_Data, separation_type ), "test_separation_type", NC_GLOBAL, NC_CHAR, 0, 1, (int)separation_none }, { offsetof( MS_Test_Data, ms_inlet ), "test_ms_inlet", NC_GLOBAL, NC_CHAR, 0, 1, (int)inlet_direct }, { offsetof( MS_Test_Data, ms_inlet_temperature ), "test_ms_inlet_temperature", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, ionization_mode ), "test_ionization_mode", NC_GLOBAL, NC_CHAR, 0, 1, (int)ionization_ei }, { offsetof( MS_Test_Data, ionization_polarity ), "test_ionization_polarity", NC_GLOBAL, NC_CHAR, 0, 1, (int)polarity_plus }, { offsetof( MS_Test_Data, electron_energy ), "test_electron_energy", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, laser_wavelength), "test_laser_wavelength", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, reagent_gas ), "test_reagent_gas", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, reagent_gas_pressure ), "test_reagent_gas_pressure", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, fab_type ), "test_fab_type", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, fab_matrix ), "test_fab_matrix", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, source_temperature ), "test_source_temperature", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, filament_current ), "test_filament_current", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, emission_current ), "test_emission_current", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, accelerating_potential), "test_accelerating_potential", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, detector_type ), "test_detector_type", NC_GLOBAL, NC_CHAR, 0, 1, (int)detector_em }, { offsetof( MS_Test_Data, detector_potential ), "test_detector_potential", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, detector_entrance_potential ), "test_detector_entrance_potential", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, resolution_type ), "test_resolution_type", NC_GLOBAL, NC_CHAR, 0, 1, (int)resolution_constant }, { offsetof( MS_Test_Data, resolution_method ), "test_resolution_method", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, scan_function ), "test_scan_function", NC_GLOBAL, NC_CHAR, 0, 1, (int)function_scan }, { offsetof( MS_Test_Data, scan_direction ), "test_scan_direction", NC_GLOBAL, NC_CHAR, 0, 1, (int)direction_up }, { offsetof( MS_Test_Data, scan_law ), "test_scan_law", NC_GLOBAL, NC_CHAR, 0, 1, (int)law_linear }, { offsetof( MS_Test_Data, scan_time ), "test_scan_time", NC_GLOBAL, NC_FLOAT, 0, 0, 0 }, { offsetof( MS_Test_Data, mass_calibration_file ), "mass_calibration_file", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, external_reference_file ), "test_external_reference_file", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, internal_reference_file ), "test_internal_reference_file", NC_GLOBAL, NC_CHAR, 0, 0, 0 }, { offsetof( MS_Test_Data, comments ), "test_comments", NC_GLOBAL, NC_CHAR, 0, 0, 0 } }; #pragma link C++ global static int nTest = sizeof( test_attributes ) / sizeof( MS_Attribute_Data ); /* Attribute data array for RAW DATA GLOBAL attributes */ #pragma link C++ global static MS_Attribute_Data raw_data_attributes[] = { { offsetof( MS_Raw_Data_Global, mass_format ), "raw_data_mass_format", NC_GLOBAL, NC_CHAR, 0, 1, (int)data_short }, { offsetof( MS_Raw_Data_Global, time_format ), "raw_data_time_format", NC_GLOBAL, NC_CHAR, 0, 1, (int)data_short }, { offsetof( MS_Raw_Data_Global, intensity_format ), "raw_data_intensity_format", NC_GLOBAL, NC_CHAR, 0, 1, (int)data_long }, { offsetof( MS_Raw_Data_Global, mass_units ), "units", (long)offsetof( MS_Variables, mass_values_id ), NC_CHAR, 0, 1, (int)mass_m_z }, { offsetof( MS_Raw_Data_Global, time_units ), "units", (long)offsetof( MS_Variables, time_values_id ), NC_CHAR, 0, 1, (int)time_seconds }, { offsetof( MS_Raw_Data_Global, intensity_units ), "units", (long)offsetof( MS_Variables, intensity_values_id ), NC_CHAR, 0, 1, (int)intensity_arbitrary }, { offsetof( MS_Raw_Data_Global, intensity_offset ), "add_offset", (long)offsetof( MS_Variables, intensity_values_id ), NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, mass_factor ), "scale_factor", (long)offsetof( MS_Variables, mass_values_id ), NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, time_factor ), "scale_factor", (long)offsetof( MS_Variables, time_values_id ), NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, intensity_factor ), "scale_factor", (long)offsetof( MS_Variables, intensity_values_id ), NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, total_intensity_units ), "units", (long)offsetof( MS_Variables, total_intensity_id ), NC_CHAR, 0, 1, (int)intensity_arbitrary }, { offsetof( MS_Raw_Data_Global, mass_label ), "long_name", (long)offsetof( MS_Variables, mass_values_id ), NC_CHAR, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, time_label ), "long_name", (long)offsetof( MS_Variables, time_values_id ), NC_CHAR, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, intensity_label ), "long_name", (long)offsetof( MS_Variables, intensity_values_id ), NC_CHAR, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, starting_scan_number ), "starting_scan_number", NC_GLOBAL, NC_LONG, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, mass_axis_global_min ), "global_mass_min", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, mass_axis_global_max ), "global_mass_max", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, time_axis_global_min ), "global_time_min", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, time_axis_global_max ), "global_time_max", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, intensity_axis_global_min ), "global_intensity_min", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, intensity_axis_global_max ), "global_intensity_max", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, calibrated_mass_min ), "calibrated_mass_min", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, calibrated_mass_max ), "calibrated_mass_max", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, run_time ), "actual_run_time_length", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, delay_time ), "actual_delay_time", NC_GLOBAL, NC_DOUBLE, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, uniform_flag ), "raw_data_uniform_sampling_flag", NC_GLOBAL, NC_SHORT, 0, 0, 0 }, { offsetof( MS_Raw_Data_Global, comments ), "raw_data_comments", NC_GLOBAL, NC_CHAR, 0, 0, 0 } }; #pragma link C++ global static int nRaw = sizeof( raw_data_attributes ) / sizeof( MS_Attribute_Data ); #endif /* MS10_IO_INCLUDED */ /* DON'T ADD ANYTHING AFTER THIS #endif */ /* -*-C-*- ******************************************************************************* * File: ms10.h * Description: Header file for the public-domain implementation of the * MS netCDF Data Interchange Specification, Categories 1 & 2 * data elements * Author: David Stranz * Language: C * Status: Public Domain (Distribute with Copyright Notice) * (C) Copyright 1992, Analytical Instrument Association * All rights reserved. ******************************************************************************* */ #ifndef MS10_INCLUDED #define MS10_INCLUDED 1 #ifndef NULL #define NULL ((void *) 0) #endif #pragma link C++ global MS_NULL_FLT ((float) -9999.0); #pragma link C++ global MS_NULL_INT (-9999); #pragma link C++ global MS_NULL_BYTE (255); #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif #pragma link C++ global MS_ERROR (-1); /* Returned for all errors */ #pragma link C++ global MS_NO_ERROR (0); /* Returned when successful */ #pragma link C++ global MS_INST_LENGTH (32); /* Length of INSTRUMENT-ID data strings, including NULL */ #pragma link C++ global MS_MAX_STRING_LENGTH (255); /* Maximum allowed length of string variables and attributes */ #pragma link C++ global MS_STAMP_LENGTH (20); /* Length of a time stamp string, including NULL */ #pragma link C++ typedef enum ms_admin_expt_t; #pragma link C++ typedef enum ms_sample_state_t; #pragma link C++ typedef enum ms_test_separation_t; #pragma link C++ typedef enum ms_test_inlet_t; #pragma link C++ typedef enum ms_test_ioniz_t; #pragma link C++ typedef enum ms_test_polarity_t; #pragma link C++ typedef enum ms_test_detector_t; #pragma link C++ typedef enum ms_test_res_t; #pragma link C++ typedef enum ms_test_function_t; #pragma link C++ typedef enum ms_test_direction_t; #pragma link C++ typedef enum ms_test_law_t; #pragma link C++ typedef enum ms_data_format_t; #pragma link C++ typedef enum ms_data_mass_t; #pragma link C++ typedef enum ms_data_time_t; #pragma link C++ typedef enum ms_data_intensity_t; #pragma link C++ typedef struct MS_Date_Time; #pragma link C++ typedef struct MS_Admin_Data; #pragma link C++ typedef struct MS_Instrument_Data; #pragma link C++ typedef struct MS_Sample_Data; #pragma link C++ typedef struct MS_Test_Data; #pragma link C++ typedef struct MS_Raw_Data_Global; #pragma link C++ typedef struct MS_Raw_Per_Scan; #pragma link C++ typedef struct MS_Raw_Per_Group; #pragma link C++ typedef struct MS_Raw_Library; /* ******************************************************************************** * Peak flags - these may be "ORed" together to yield a composite flag ******************************************************************************** */ #pragma link C++ global MS_FLAG_NOT_HRP (1L << 0 ); #pragma link C++ global MS_FLAG_MISSED_REF (1L << 1 ); #pragma link C++ global MS_FLAG_UNRESOLVED (1L << 2 ); #pragma link C++ global MS_FLAG_DBL_CHARGED (1L << 3 ); #pragma link C++ global MS_FLAG_REFERENCE (1L << 4 ); #pragma link C++ global MS_FLAG_EXCEPTION (1L << 5 ); #pragma link C++ global MS_FLAG_SATURATED (1L << 6 ); #pragma link C++ global MS_FLAG_SIGNIFICANT (1L << 7 ); #pragma link C++ global MS_FLAG_MERGED (1L << 8 ); #pragma link C++ global MS_FLAG_FRAGMENTED (1L << 9 ); #pragma link C++ global MS_FLAG_AREA_HEIGHT (1L << 10); #pragma link C++ global MS_FLAG_MATH_MODIFIED (1L << 11); #pragma link C++ global MS_FLAG_NEGATIVE (1L << 12); #pragma link C++ global MS_FLAG_EXTENDED (1L << 13); #pragma link C++ global MS_FLAG_CALCULATED (1L << 14); #pragma link C++ global MS_FLAG_LOCK_MASS (1L << 15); /* ******************************************************************************** * Exported functions ******************************************************************************** */ #ifdef __STDC__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* From ms10aux.c: */ #pragma link C++ function int ms_read_enum_attribute( int, int, char * ); #pragma link C++ function char * ms_read_string_variable( int, int, long, long, int ); #pragma link C++ function int ms_write_string_variable( int, int, long, long, int, char * ); #pragma link C++ function int ms_open_write( char *, ms_admin_expt_t, long, long, ms_data_format_t, ms_data_format_t, ms_data_format_t, int, int ); #pragma link C++ function int ms_open_read( char * ); #pragma link C++ function void ms_close( int ); #pragma link C++ function int ms_associate_id( int ); #pragma link C++ function int ms_dissociate_id( int ); #pragma link C++ function int ms_convert_date( int, MS_Date_Time * ); #pragma link C++ function void ms_copy_array( void *, ms_data_format_t, long, void *, ms_data_format_t, int ); /* From ms10enum.c: */ #pragma link C++ function char * ms_enum_to_string( int ); #pragma link C++ function int ms_string_to_enum( char * ); /* From ms10io.c: */ #pragma link C++ function int ms_write_dimensions( int, long, long ); #pragma link C++ function int ms_read_dimensions( int ); #pragma link C++ function int ms_write_variables( int, ms_admin_expt_t, ms_data_format_t, ms_data_format_t, ms_data_format_t, int, int ); #pragma link C++ function int ms_read_variables( int ); #pragma link C++ function int ms_write_global( int, MS_Admin_Data *, MS_Sample_Data *, MS_Test_Data *, MS_Raw_Data_Global * ); #pragma link C++ function int ms_read_global( int, MS_Admin_Data *, MS_Sample_Data *, MS_Test_Data *, MS_Raw_Data_Global * ); #pragma link C++ function void ms_init_global( int, MS_Admin_Data *, MS_Sample_Data *, MS_Test_Data *, MS_Raw_Data_Global * ); #pragma link C++ function int ms_write_instrument( int, MS_Instrument_Data * ); #pragma link C++ function int ms_read_instrument( int, MS_Instrument_Data * ); #pragma link C++ function void ms_init_instrument( int, MS_Instrument_Data * ); #pragma link C++ function int ms_write_per_scan( int, MS_Raw_Per_Scan *, MS_Raw_Library * ); #pragma link C++ function int ms_read_per_scan( int, MS_Raw_Per_Scan *, MS_Raw_Library * ); #pragma link C++ function void ms_init_per_scan( int, MS_Raw_Per_Scan *, MS_Raw_Library * ); #pragma link C++ function int ms_write_group_global( int, long, long ); #pragma link C++ function int ms_read_group_global( int, long *, long * ); #pragma link C++ function int ms_write_per_group( int, MS_Raw_Per_Group * ); #pragma link C++ function int ms_read_per_group( int, MS_Raw_Per_Group * ); #pragma link C++ function void ms_init_per_group( int, MS_Raw_Per_Group * ); #pragma link C++ function int ms_read_TIC( int, long *, double * *, double * * ); #ifdef __cplusplus } #endif /* __cplusplus */ #else /* __STDC__ */ /* From ms10aux.c: */ #pragma link C++ function int ms_read_enum_attribute(); #pragma link C++ function char * ms_read_string_variable(); #pragma link C++ function int ms_write_string_variable(); #pragma link C++ function int ms_open_write(); #pragma link C++ function int ms_open_read(); #pragma link C++ function void ms_close(); #pragma link C++ function int ms_associate_id(); #pragma link C++ function int ms_dissociate_id(); #pragma link C++ function int ms_convert_date(); #pragma link C++ function void ms_copy_array(); /* From ms10enum.c: */ #pragma link C++ function char * ms_enum_to_string(); #pragma link C++ function int ms_string_to_enum(); /* From ms10io.c: */ #pragma link C++ function int ms_write_dimensions(); #pragma link C++ function int ms_read_dimensions(); #pragma link C++ function int ms_write_variables(); #pragma link C++ function int ms_read_variables(); #pragma link C++ function int ms_write_global(); #pragma link C++ function int ms_read_global(); #pragma link C++ function void ms_init_global(); #pragma link C++ function int ms_write_instrument(); #pragma link C++ function int ms_read_instrument(); #pragma link C++ function void ms_init_instrument(); #pragma link C++ function int ms_write_per_scan(); #pragma link C++ function int ms_read_per_scan(); #pragma link C++ function void ms_init_per_scan(); #pragma link C++ function int ms_write_group_global(); #pragma link C++ function int ms_read_group_global(); #pragma link C++ function int ms_write_per_group(); #pragma link C++ function int ms_read_per_group(); #pragma link C++ function void ms_init_per_group(); #pragma link C++ function int ms_read_TIC(); #endif /* __STDC__ */ #endif /* MS10_INCLUDED */ /* DON'T ADD ANYTHING AFTER THIS #endif */ /* -*-C-*- ******************************************************************************* * File: ms10aux.c * Description: Public-domain implementation of the MS netCDF Data * Interchange Specification, Categories 1 and 2 data elements. * This file contains auxilliary functions to support the MS * implementation. * Author: David Stranz * Language: C * Package: N/A * Status: Public Domain (Distribute with Copyright Notice) * (C) Copyright 1992, Analytical Instrument Association * All rights reserved. ******************************************************************************* */ /* ******************************************************************************** * FUNCTION: put_number (static) * DESCRIPTION: Formats an integer number into a character string, with * leading zeros. This function will fail if the count exceeds * the number of digits (i.e. the power of ten) which can be * represented in an integer. No assumption is made that the * string is NULL terminated on entry, and it is not NULL * terminated on exit. In other words, the arguments had * better be valid. * ARGUMENTS: (char *) string, (int) starting string index, * (int) number of characters required, (int) integer value * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int put_number( char * string, int start, int count, int value ) #else /* __STDC__ */ #pragma link C++ function static int put_number( string, start, count, value ) char * string; int start; int count; int value; #endif /* not __STDC__ */ { int index; if ( NULL == string ) return MS_ERROR; if ( value < 0 ) value = -value; index = start + count - 1; while ( value ) { string[index--] = '0' + (char)(value % 10); value /= 10; } while( index >= start ) /* add leading zeros */ string[index--] = '0'; return MS_NO_ERROR; } /* put_number */ /* ******************************************************************************** * FUNCTION: get_number (static) * DESCRIPTION: Retrieves an integer number from a character string. This * function will also fail if the character count exceeds the * the power of ten which can be represented by an integer. * The same assumptions as for put_number (above) apply. * ARGUMENTS: (char *) string, (int) starting index of number in string, * (int) number of characters to decode * RETURNS: (int) unsigned integer value (MS_ERROR on error) ******************************************************************************** */ #ifdef __STDC__ static int #pragma link C++ function get_number( char * string, int start, int count ) #else /* __STDC__ */ #pragma link C++ function static int get_number( string, start, count ) char * string; int start; int count; #endif /* not __STDC__ */ { int ret_val = 0; if ( NULL == string ) return MS_ERROR; while( count ) { ret_val *= 10; ret_val += (int)(string[start++] - '0'); count--; } return ret_val; } /* get_number */ /* -*-C-*- ******************************************************************************* * File: ms10enum.c * Description: Enumerated value <-> string literal translations for the MS * netCDF Data Interchange Specification, Categories 1 & 2 data * Author: David Stranz * Language: C * Status: Public Domain (Distribute with Copyright Notice) * (C) Copyright 1992, Analytical Instrument Association * All rights reserved. ******************************************************************************* */ /* ******************************************************************************** * Enumerated set enum to string correspondences * NOTE: The strings below are sorted in case-insensitive ascending alphabetical * order. If you add new strings, ensure that order is maintained! It is also * a requirement that all string literals be unique. * A binary search is used to find string literals in this array; that is * the reason for the sorting and uniqueness requirements. ******************************************************************************** */ #pragma link C++ function typedef struct { char * literal_value; int enum_value; } EnumLiteral; #pragma link C++ global static EnumLiteral ms_enums[] = { { "Arbitrary Mass Units", (int) mass_arbitrary }, { "Arbitrary Intensity Units", (int) intensity_arbitrary }, { "Arbitrary Time Units", (int) time_arbitrary }, { "Atmospheric Pressure Chemical Ionization", (int) ionization_apci }, { "Atmospheric Pressure Chemical Ionization Inlet", (int) inlet_apci }, { "Capillary Direct", (int) inlet_capillary }, { "Capillary Zone Electrophoresis", (int) separation_cze }, { "Centroided Mass Spectrum", (int) expt_centroid }, { "Chemical Ionization", (int) ionization_ci }, { "Constant Resolution", (int) resolution_constant }, { "Continuum Mass Spectrum", (int) expt_continuum }, { "Conversion Dynode Electron Multiplier", (int) detector_dynode_em }, { "Conversion Dynode Photomultiplier", (int) detector_dynode_pm }, { "Counts Per Second", (int) intensity_cps }, { "Current", (int) intensity_current }, { "Direct Inlet Probe", (int) inlet_direct }, { "Double", (int) data_double }, { "Down", (int) direction_down }, { "Electron Impact", (int) ionization_ei }, { "Electron Multiplier", (int) detector_em }, { "Electrospray Inlet", (int) inlet_es }, { "Electrospray Ionization", (int) ionization_es }, { "Exponential", (int) law_exponential }, { "Faraday Cup", (int) detector_cup }, { "Fast Atom Bombardment", (int) ionization_fab }, { "Field Desorption", (int) ionization_fd }, { "Field Flow Fractionation", (int) separation_fff }, { "Field Ionization", (int) ionization_fi }, { "Float", (int) data_float }, { "Flow Injection Analysis", (int) inlet_fia }, { "Focal Plane Array", (int) detector_focal }, { "Gas", (int) state_gas }, { "Gas-Liquid Chromatography", (int) separation_glc }, { "Gas-Solid Chromatography", (int) separation_gsc }, { "Infusion", (int) inlet_infusion }, { "Ion Exchange Liquid Chromatography", (int) separation_ielc }, { "Ion Pair Liquid Chromatography", (int) separation_iplc }, { "Jet Separator", (int) inlet_jet }, { "Laser Desorption", (int) ionization_ld }, { "Library Mass Spectrum", (int) expt_library }, { "Linear", (int) law_linear }, { "Liquid", (int) state_liquid }, { "Long", (int) data_long }, { "M/Z", (int) mass_m_z }, { "Mass Scan", (int) function_scan }, { "Membrane Separator", (int) inlet_membrane }, { "Moving Belt", (int) inlet_belt }, { "Multicollector", (int) detector_multicoll }, { "Negative Polarity", (int) polarity_minus }, { "No Chromatography", (int) separation_none }, { "Normal Phase Liquid Chromatography", (int) separation_nplc }, { "Open Split", (int) inlet_opensplit }, { "Other Chromatography", (int) separation_other }, { "Other Detector", (int) detector_other }, { "Other Direction", (int) direction_other }, { "Other Function", (int) function_other }, { "Other Inlet", (int) inlet_other }, { "Other Intensity", (int) intensity_other }, { "Other Ionization", (int) ionization_other }, { "Other Law", (int) law_other }, { "Other Liquid Chromatography", (int) separation_olc }, { "Other Mass", (int) mass_other }, { "Other Probe", (int) inlet_probe }, { "Other State", (int) state_other }, { "Other Time", (int) time_other }, { "Particle Beam", (int) inlet_pb }, { "Photomultiplier", (int) detector_pm }, { "Plasma", (int) state_plasma }, { "Plasma Desorption", (int) ionization_pd }, { "Positive Polarity", (int) polarity_plus }, { "Proportional Resolution", (int) resolution_proportional }, { "Quadratic", (int) law_quadratic }, { "Reservoir", (int) inlet_reservoir }, { "Reverse Phase Liquid Chromatography", (int) separation_rplc }, { "Seconds", (int) time_seconds }, { "Selected Ion Detection", (int) function_sid }, { "Septum", (int) inlet_septum }, { "Short", (int) data_short }, { "Size Exclusion Liquid Chromatography", (int) separation_selc }, { "Solid", (int) state_solid }, { "Spark Ionization", (int) ionization_spark }, { "Supercritical Fluid Chromatography", (int) separation_sfc }, { "Supercritical Fluid", (int) state_supercrit }, { "Thermal Ionization", (int) ionization_thermal }, { "Thermospray Inlet", (int) inlet_ts }, { "Thermospray Ionization", (int) ionization_ts }, { "Thin Layer Chromatography", (int) separation_tlc }, { "Total Counts", (int) intensity_counts }, { "Up", (int) direction_up }, { "Volts", (int) intensity_volts } }; #pragma link C++ global ENUM_COUNT (sizeof( ms_enums ) / sizeof( EnumLiteral )) /* TEST_ENUM */ /* -*-C-*- ******************************************************************************* * File: ms10io.c * Description: Public-domain implementation of the MS netCDF Data * Interchange Specification, Categories 1 and 2 data elements. * This file implements the netCDF file I/O functions of the * MS specification. * Author: David Stranz * Language: C * Status: Public Domain (Distribute with Copyright Notice) * (C) Copyright 1992, Analytical Instrument Association * All rights reserved. ******************************************************************************* */ /* ******************************************************************************** * FUNCTION: format_to_datatype (static) * DESCRIPTION: Converts a mass, time, or intensity format to a netCDF * data type. * ARGUMENTS: (ms_data_format_t) format specifier, (nc_type) default type * RETURNS: (nc_type) datatype specifier ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static nc_type format_to_datatype( ms_data_format_t fmt, nc_type default_type ) #else /* __STDC__ */ #pragma link C++ function static nc_type format_to_datatype( fmt, default_type ) ms_data_format_t fmt; nc_type default_type; #endif /* not __STDC__ */ { int i; for ( i = 0; i < nTypes; i++ ) if ( fmt == ms_types[i].ms_fmt ) return ms_types[i].cdf_type; return default_type; } /* format_to_datatype */ /* ******************************************************************************** * FUNCTION: datatype_to_format (static) * DESCRIPTION: Returns the datatype given the nc_type * ARGUMENTS: (nc_type) input type, (ms_data_format_t) default format * RETURNS: (ms_data_format_t) corresponding format ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static ms_data_format_t datatype_to_format( nc_type typ, ms_data_format_t default_fmt ) #else /* __STDC__ */ #pragma link C++ function static ms_data_format_t datatype_to_format( typ, default_fmt ) nc_type typ; ms_data_format_t default_fmt; #endif /* not __STDC__ */ { int i; for ( i = 0; i < nTypes; i++ ) if ( typ == ms_types[i].cdf_type ) return ms_types[i].ms_fmt; return default_fmt; } /* datatype_to_format */ /* ******************************************************************************** * FUNCTION: put_default (static) * DESCRIPTION: Utility routine to cast and load a default numeric data value * ARGUMENTS: (nc_type) datatype, (void *) address of variable, (int) array * index * RETURNS: (void) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static void put_default( nc_type datatype, void * value, int offset ) #else /* __STDC__ */ #pragma link C++ function static void put_default( datatype, value, offset ) nc_type datatype; void * value; int offset; #endif /* not __STDC__ */ { switch (datatype ) { case NC_BYTE: *((char *)value + offset) = (char)MS_NULL_BYTE; break; case NC_SHORT: *((short *)value + offset) = (short)MS_NULL_INT; break; case NC_LONG: *((long *)value + offset) = (long)MS_NULL_INT; break; case NC_FLOAT: *((float *)value + offset) = (float)MS_NULL_FLT; break; case NC_DOUBLE: *((double *)value + offset) = (double)MS_NULL_FLT; break; default: break; } return; } /* put_default */ /* ******************************************************************************** * FUNCTION: make_array (static) * DESCRIPTION: Allocates an array of the appropriate length and data type * ARGUMENTS: (long) number of points, (nc_type) datatype * RETURNS: (void *) pointer to array (NULL if error) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static void * make_array( long npts, nc_type datatype ) #else /* __STDC__ */ #pragma link C++ function static void * make_array( npts, datatype ) long npts; nc_type datatype; #endif /* not __STDC__ */ { long size; switch ( datatype ) { case NC_SHORT: size = sizeof( short ); break; case NC_LONG: size = sizeof( long ); break; case NC_FLOAT: size = sizeof( float ); break; case NC_DOUBLE: size = sizeof( double ); break; default: return NULL; } return (void *) malloc( (unsigned long)(npts * size) ); } /* make_array */ /* ******************************************************************************** * FUNCTION: init_indexed_variables (static) * DESCRIPTION: Initializes (and optionally clears) variables which are * present on a per-scan or per-instrument basis. * ARGUMENTS: (char *) values data structure pointer, * (int) number of variables, * (MS_Variable_Data *) variable definitions array pointer, * (int) clear flag * RETURNS: (void) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static void init_indexed_variables( char * values, int nDefs, MS_Variable_Data * defs, int clear ) #else /* __STDC__ */ #pragma link C++ function static void init_indexed_variables( values, nDefs, defs, clear ) char * values; int nDefs; MS_Variable_Data * defs; int clear; #endif /* not __STDC__ */ { int i; if ( NULL == values || NULL == defs ) return; for ( i = 0; i < nDefs; i++ ) { if ( 0 == defs[i].ndim ) { /* not possible */ continue; } else if ( 1 == defs[i].ndim ) { /* single dimension */ if ( NC_CHAR == defs[i].datatype ) { continue; /* not possible */ } else { put_default( defs[i].datatype, (void *)(values + defs[i].data_offset), 0 ); } } else if ( 2 == defs[i].ndim ) { if ( NC_CHAR == defs[i].datatype ) { if ( clear && (*((char * *)(values + defs[i].data_offset))) ) free( *((char * *)(values + defs[i].data_offset)) ); *((char * *)(values + defs[i].data_offset)) = NULL; } else continue; } else continue; } /* for ( i = ... ) */ return; } /* init_indexed_variables */ /* ******************************************************************************** * FUNCTION: write_variables (static) * DESCRIPTION: Defines netCDF variables given an array of definitions * ARGUMENTS: (int) netcdf file id, (int) number of variables, * (MS_Variables *) variable ids data structure, * (MS_Dimensions *) dimension ids data structure * (MS_Variable_Data *) variable data array * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int write_variables( int cdfid, int nDefs, MS_Variables * varbls, MS_Dimensions * dimens, MS_Variable_Data * defs ) #else /* __STDC__ */ #pragma link C++ function static int write_variables( cdfid, nDefs, varbls, dimens, defs ) int cdfid; int nDefs; MS_Variables * varbls; MS_Dimensions * dimens; MS_Variable_Data * defs; #endif /* not __STDC__ */ { int i; /* index into variable data */ int j; /* index into dimension array */ int dim_ids[3]; /* dimension ids */ /* Error checking: nDefs > 0; varbls, dimens, defs must be non-NULL */ if ( nDefs <= 0 || NULL == varbls || NULL == dimens || NULL == defs ) return MS_ERROR; /* For each definition in the array, create a new netCDF variable */ for ( i = 0; i < nDefs; i++ ) { /* Load dimension ids into argument array for ncvardef call */ for ( j = 0; j < defs[i].ndim; j++ ) dim_ids[j] = ((ms_dim *)((char *)dimens + defs[i].dim[j]))->id; if ( MS_ERROR == (*((int *)(((char *)varbls) + defs[i].offset)) = ncvardef( cdfid, defs[i].name, defs[i].datatype, defs[i].ndim, dim_ids )) ) return MS_ERROR; } return MS_NO_ERROR; } /* write_variables */ /* ******************************************************************************** * FUNCTION: read_variables (static) * DESCRIPTION: Reads netCDF variable ids into the definitions array * ARGUMENTS: (int) netCDF file id, (int) number of variables, * (MS_Variables *) variables data structure pointer, * (MS_Dimensions *) dimensions data structure pointer, * (MS_Variable_Data *) pointer to array of variable definitions * RETURNS: (int) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int read_variables( int cdfid, int nDefs, MS_Variables * varbls, MS_Dimensions * dimens, MS_Variable_Data * defs ) #else /* __STDC__ */ #pragma link C++ function static int read_variables( cdfid, nDefs, varbls, dimens, defs ) int cdfid; int nDefs; MS_Variables * varbls; MS_Dimensions * dimens; MS_Variable_Data * defs; #endif /* not __STDC__ */ { int i; /* Error checking: nDefs > 0; varbls, dimens, defs non-NULL */ if ( nDefs <= 0 || NULL == varbls || NULL == dimens || NULL == defs ) return MS_ERROR; for ( i = 0; i < nDefs; i++ ) { *((int *)(((char *)varbls) + defs[i].offset)) = ncvarid( cdfid, defs[i].name ); } return MS_NO_ERROR; } /* read_variables */ /* ******************************************************************************** * FUNCTION: init_attributes (static) * DESCRIPTION: Initializes an attribute data structure to default values. * Optionally (clear flag == TRUE), will also free non-NULL * strings. * ARGUMENTS: (char *) cast pointer to attribute data structure, * (int) number of attributes, * (MS_Attribute_Data *) pointer to attribute values structure, * (int) clear flag * RETURNS: (void) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static void init_attributes( char * values, int nAtts, MS_Attribute_Data * atts, int clear ) #else /* __STDC__ */ #pragma link C++ function static void init_attributes( values, nAtts, atts, clear ) char * values; int nAtts; MS_Attribute_Data * atts; int clear; #endif /* not __STDC__ */ { int i; if ( NULL == atts || NULL == values ) return; for ( i = 0; i < nAtts; i++ ) { if ( NC_CHAR == atts[i].datatype ) { if ( atts[i].enumerated ) *((int *)(values + atts[i].offset)) = atts[i].default_value; else { if ( clear && (*((char * *)(values + atts[i].offset))) ) free( *((char * *)(values + atts[i].offset)) ); *((char * *)(values + atts[i].offset)) = NULL; } } else put_default( atts[i].datatype, (void *)(values + atts[i].offset), 0 ); } } /* init_attributes */ /* ******************************************************************************** * FUNCTION: write_attributes (static) * DESCRIPTION: Writes attribute values to the netCDF file * ARGUMENTS: (int) netCDF file id, (int) number of attributes, * (MS_Variables *) variables data structure pointer, * (MS_Attribute_Data *) attribute definition data structure pointer, * (char *) cast pointer to attribute values data structure * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int write_attributes( int cdfid, int nAtt, MS_Variables * varbls, MS_Attribute_Data * atts, char * values ) #else /* __STDC__ */ #pragma link C++ function static int write_attributes( cdfid, nAtt, varbls, atts, values ) int cdfid; int nAtt; MS_Variables * varbls; MS_Attribute_Data * atts; char * values; #endif /* not __STDC__ */ { int i; int len = 1; int id; long int_val; double dbl_val; int write_it; void * value; if ( nAtt <= 0 || NULL == varbls || NULL == atts || NULL == values ) return MS_ERROR; for ( i = 0; i < nAtt; i++ ) { write_it = TRUE; switch( atts[i].datatype ) { case NC_CHAR: if ( atts[i].enumerated ) { value = (void *)ms_enum_to_string( *((int *)(values + atts[i].offset)) ); } else { value = (void *)(*((char * *)(values + atts[i].offset))); } if ( NULL == value ) { write_it = FALSE; break; } len = (long)strlen( (char *) value ) + 1; break; case NC_BYTE: len = 1; value = (void *)(values + atts[i].offset); int_val = (long)(*((char *)value)); if ( MS_NULL_INT == int_val ) write_it = FALSE; break; case NC_SHORT: len = 1; value = (void *)(values + atts[i].offset); int_val = (long)(*((short *)value)); if ( MS_NULL_INT == int_val ) write_it = FALSE; break; case NC_LONG: len = 1; value = (void *)(values + atts[i].offset); int_val = *((long *)value); if ( MS_NULL_INT == int_val ) write_it = FALSE; break; case NC_FLOAT: len = 1; value = (void *)(values + atts[i].offset); dbl_val = (double)(*((float *)value)); if ( (int)MS_NULL_FLT == (int)dbl_val ) write_it = FALSE; break; case NC_DOUBLE: len = 1; value = (void *)(values + atts[i].offset); dbl_val = *((double *)value); if ( (int)MS_NULL_FLT == (int)dbl_val ) write_it = FALSE; break; default: return MS_ERROR; /* invalid datatype! */ } if ( !write_it ) { continue; } /* Check for local or global attribute. If local, retrieve variable id from MS_Variables data structure */ if ( NC_GLOBAL == atts[i].id ) id = NC_GLOBAL; else id = *((int *)((char *)varbls + atts[i].id)); /* Finally, write the attribute definition */ if ( MS_ERROR == ncattput( cdfid, id, atts[i].name, atts[i].datatype, len, value ) ) return MS_ERROR; } return MS_NO_ERROR; } /* write_attributes */ /* ******************************************************************************** * FUNCTION: read_attributes (static) * DESCRIPTION: Reads attribute values from the netCDF file. Numeric attribute * values are read directly into the fields for them; space is * first allocated for string attributes, then the values are * read in. This space must be freed before the next read (or the * pointer copied so it can later be freed), or a memory leak * will occur. * Attributes which are defined but not present in the netCDF * file will be returned with default values (MS_NULL_INT, * MS_NULL_FLT, NULL, or the default enumerated type) as * appropriate. * ARGUMENTS: (int) netCDF file id, (int) number of attributes, * (MS_Variables *) variables data structure pointer, * (MS_Attribute_Data *) attribute definition data structure pointer, * (char * *) cast pointer to attribute values data structure * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int read_attributes( int cdfid, int nAtts, MS_Variables * varbls, MS_Attribute_Data * atts, char * values ) #else /* __STDC__ */ #pragma link C++ function static int read_attributes( cdfid, nAtts, varbls, atts, values ) int cdfid; int nAtts; MS_Variables * varbls; MS_Attribute_Data * atts; char * values; #endif /* not __STDC__ */ { int i; int isPresent; int varid; int length; nc_type datatype; char buffer[MS_MAX_STRING_LENGTH]; /* Error checking: all pointers must be non-NULL; nAtts > 0 */ if ( nAtts <= 0 || NULL == varbls || NULL == atts || NULL == values ) return MS_ERROR; for ( i = 0; i < nAtts; i++ ) { /* Determine the datatype, and retrieve appropriately */ if ( NC_GLOBAL == atts[i].id ) varid = NC_GLOBAL; else varid = *((int *)((char *)varbls + atts[i].id)); /* Inquire about the attribute. An error return indicates the attribute was not found. */ if ( MS_ERROR == ncattinq( cdfid, varid, atts[i].name, &datatype, &length ) ) isPresent = FALSE; else isPresent = TRUE; /* Check for datatype mismatch. */ if ( isPresent && ( datatype != atts[i].datatype ) ) return MS_ERROR; /* Check for missing mandatory attribute */ if ( atts[i].mandatory && FALSE == isPresent ) { return MS_ERROR; } switch ( atts[i].datatype ) { case NC_CHAR: /* A character string */ if ( isPresent ) { memset( buffer, 0, sizeof( buffer ) ); if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)buffer ) ) { return MS_ERROR; } if ( atts[i].enumerated ) { *((int *)(values + atts[i].offset)) = ms_string_to_enum( buffer ); } else { char * p; p = (char *)malloc((unsigned long)(length + 1) * sizeof( char )); if ( NULL == p ) return MS_ERROR; (void)strcpy( p, buffer ); *((char * *)(values + atts[i].offset)) = p; } } else { if ( atts[i].enumerated ) *((int *)(values + atts[i].offset)) = atts[i].default_value; else *((char * *)(values + atts[i].offset)) = NULL; } break; case NC_BYTE: { char byte_val = (char) MS_NULL_BYTE; if ( isPresent ) if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)&byte_val ) ) return MS_ERROR; *(values + atts[i].offset) = byte_val; break; } case NC_SHORT: { short short_val = (short) MS_NULL_INT; if ( isPresent ) if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)&short_val ) ) return MS_ERROR; *((short *)(values + atts[i].offset)) = short_val; break; } case NC_LONG: { long long_val = (long) MS_NULL_INT; if ( isPresent ) if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)&long_val ) ) return MS_ERROR; *((long *)(values + atts[i].offset)) = long_val; break; } case NC_FLOAT: { float float_val = (float) MS_NULL_FLT; if ( isPresent ) if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)&float_val ) ) return MS_ERROR; *((float *)(values + atts[i].offset)) = float_val; break; } case NC_DOUBLE: { double double_val = (double) MS_NULL_FLT; if ( isPresent ) if ( MS_ERROR == ncattget( cdfid, varid, atts[i].name, (void *)&double_val ) ) return MS_ERROR; *((double *)(values + atts[i].offset)) = double_val; break; } default: return MS_ERROR; /* undefined type */ } /* switch */ } /* for */ return MS_NO_ERROR; } /* read_attributes */ /* ******************************************************************************** * FUNCTION: write_info (static) * DESCRIPTION: Writes variable values to the netCDF file * ARGUMENTS: (int) netCDF file id, * (MS_Variables *) variable ids data structure pointer, * (MS_Dimensions *) dimension ids data structure pointer, * (long) major dimension for array variables, * (int) number of data variables, * (char *) pointer to variable values data structure * (MS_Variable_Data *) pointer to MS_Variable_Data array * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int write_info( int cdfid, MS_Variables * varbls, MS_Dimensions * dimens, long index, int nvals, char * values, MS_Variable_Data * var_data ) #else /* __STDC__ */ #pragma link C++ function static int write_info( cdfid, varbls, dimens, index, nvals, values, var_data ) int cdfid; MS_Variables * varbls; MS_Dimensions * dimens; long index; int nvals; char * values; MS_Variable_Data * var_data; #endif /* not __STDC__ */ { int i; int j; int varid; /* variable id */ long dt_count[2]; /* size of array or string */ long dt_start[2]; /* indices into hyperslab */ void * value; /* address of value to be written */ int nminor; /* Error checking: varbls, dimens, values, var_data non NULL */ if ( NULL == varbls || NULL == dimens || NULL == values || NULL == var_data ) return MS_ERROR; for ( i = 0; i < nvals; i++ ) { /* loop over all data fields */ varid = *((int *)((char *)varbls + var_data[i].offset)); if ( index < 0 ) { /* case 1 */ if ( 0 == var_data[i].ndim ) { /* case 1a */ if ( NC_CHAR == var_data[i].datatype ) return MS_ERROR; /* error - strings are arrays */ /* Write a non-dimensioned variable value */ dt_start[0] = 0L; value = (void *)((char *)values + var_data[i].data_offset); if ( MS_ERROR == ncvarput1( cdfid, varid, dt_start, value ) ) return MS_ERROR; } else if ( 1 == var_data[i].ndim ) { /* case 1b */ if ( NC_CHAR == var_data[i].datatype ) { /* put a string */ dt_count[0] = ((ms_dim *)((char *)dimens + var_data[i].dim[0]))->size; if ( MS_ERROR == ms_write_string_variable( cdfid, varid, index, -1, dt_count[0], *((char * *) (values + var_data[i].data_offset)) ) ) return MS_ERROR; } else { /* put an array */ dt_start[0] = 0L; dt_count[0] = ((ms_dim *)((char *)dimens + var_data[i].dim[0]))->size; value = (void *)((char *)values + var_data[i].data_offset); if ( MS_ERROR == ncvarput( cdfid, varid, dt_start, dt_count, value ) ) return MS_ERROR; } } else if ( 2 == var_data[i].ndim ) { /* case 1c */ if ( NC_CHAR != var_data[i].datatype ) return MS_ERROR; /* error - no 2D arrays */ /* Put each string separately */ nminor = ((ms_dim *)((char *)dimens + var_data[i].dim[0]))->size; for ( j = 0; j < nminor; j++ ) { dt_count[0] = ((ms_dim *)((char *)dimens + var_data[i].dim[1]))->size; if ( MS_ERROR == ms_write_string_variable( cdfid, varid, (long)j, -1, dt_count[0], *((char * *) (values + var_data[i].data_offset) + j) ) ) return MS_ERROR; } } else /* case 1d - error */ return MS_ERROR; } /* if ( index < 0 ) */ else { /* case 2 */ if ( 0 == var_data[i].ndim ) /* case 2a - error */ return MS_ERROR; if ( 1 == var_data[i].ndim ) { /* case 2b */ if ( NC_CHAR == var_data[i].datatype ) return MS_ERROR; /* error */ dt_start[0] = (long)index; value = (void *)((char *)values + var_data[i].data_offset); if ( MS_ERROR == ncvarput1( cdfid, varid, dt_start, value ) ) return MS_ERROR; } else if ( 2 == var_data[i].ndim ) { /* case 2c */ dt_count[0] = 1L; dt_count[1] = ((ms_dim *)((char *)dimens + var_data[i].dim[1]))->size; if ( NC_CHAR == var_data[i].datatype ) { if ( MS_ERROR == ms_write_string_variable( cdfid, varid, index, -1, dt_count[1], *((char * *) (values + var_data[i].data_offset)) ) ) return MS_ERROR; } else { dt_start[0] = (long) index; dt_start[1] = 0L; value = (void *)(*((char * *)(values + var_data[i].data_offset))); if ( MS_ERROR == ncvarput( cdfid, varid, dt_start, dt_count, value ) ) return MS_ERROR; } } else /* case 2d */ return MS_ERROR; } } /* for ( i = 0; ... ) */ return MS_NO_ERROR; } /* write_info */ /* ******************************************************************************** * FUNCTION: read_info (static) * DESCRIPTION: Reads variable values from the netCDF file. * ARGUMENTS: (int) netCDF file id, * (MS_Variables *) variables data structure pointer, * (MS_Dimensions *) dimensions data structure pointer, * (long) major dimension for array variables, * (int) number of data variables, * (char *) pointer to variable values data structure * (MS_Variable_Data *) pointer to MS_Variable_Data array * RETURNS: (int) error code (MS_ERROR / MS_NO_ERROR) ******************************************************************************** */ #ifdef __STDC__ #pragma link C++ function static int read_info( int cdfid, MS_Variables * varbls, MS_Dimensions * dimens, long index, int nvals, char * values, MS_Variable_Data * var_data ) #else /* __STDC__ */ #pragma link C++ function static int read_info( cdfid, varbls, dimens, index, nvals, values, var_data ) int cdfid; MS_Variables * varbls; MS_Dimensions * dimens; long index; int nvals; char * values; MS_Variable_Data * var_data; #endif /* not __STDC__ */ { int i; long j; int varid; nc_type datatype; int nAtts; int ndim; int dim_id[3]; int isPresent; long dt_start[2]; long dt_count[2]; void * value; /* Error check: all pointers must be non-NULL; nvals > 0 */ if ( nvals <= 0 || NULL == varbls || NULL == dimens || NULL == values || NULL == var_data ) { return MS_ERROR; } for ( i = 0; i < nvals; i++ ) { /* loop over all data fields */ varid = *((int *)((char *)varbls + var_data[i].offset)); /* Inquire about the variable; this is primarily to determine that the variable is present in the file. If it is not, we will assign a default value to it. */ if ( MS_ERROR == ncvarinq( cdfid, varid, (char *)0, &datatype, &ndim, dim_id, &nAtts ) ) isPresent = FALSE; else isPresent = TRUE; /* Check for datatype and dimensionality mismatch. */ if ( isPresent ) { if ( datatype != var_data[i].datatype ) { return MS_ERROR; } if ( ndim != var_data[i].ndim ) { return MS_ERROR; } } if ( index < 0 ) { /* case 1 */ if ( 0 == var_data[i].ndim ) { /* case 1a */ if ( NC_CHAR == var_data[i].datatype ) return MS_ERROR; /* error - strings are arrays */ /* Read a non-dimensioned numeric value */ if ( isPresent ) { dt_start[0] = 0L; value = (void *)((char *)values + var_data[i].data_offset); if ( MS_ERROR == ncvarget1( cdfid, varid, dt_start, value ) ) { return MS_ERROR; } } else { put_default( var_data[i].datatype, (void *) ((char *)values + var_data[i].data_offset), 0 ); } } else if ( 1 == var_data[i].ndim ) { /* case 1b */ dt_count[0] = ((ms_dim *)((char *)dimens + var_data[i].dim[0]))->size; if ( NC_CHAR == var_data[i].datatype ) { /* get a string */ *((char * *)(values + var_data[i].data_offset)) = ms_read_string_variable( cdfid, varid, index, -1, dt_count[0] ); } else { /* get an array */ if ( isPresent ) { dt_start[0] = 0L; if ( MS_ERROR == ncvarget( cdfid, varid, dt_start, dt_count, (void *)((char *)values + var_data[i].data_offset) ) ) { return MS_ERROR; } } else { /* assign default */ for ( j = 0; j < dt_count[0]; j++ ) { put_default( var_data[i].datatype, (void *)(((char *)values + var_data[i].data_offset)), j ); } } } } else if ( 2 == var_data[i].ndim ) { /* case 1c */ if ( NC_CHAR != var_data[i].datatype ) { return MS_ERROR; } /* Read an array of strings */ dt_count[0] = ((ms_dim *)((char *)dimens + var_data[i].dim[0]))->size; for ( j = 0; j < dt_count[0]; j++ ) { *((char * *)(values + var_data[i].data_offset) + j) = ms_read_string_variable( cdfid, varid, j, -1, dt_count[0] ); } } else { return MS_ERROR; /* case 1d */ } } /* if ( index < 0 ) */ else { /* case 2 */ if ( 0 == var_data[i].ndim ) /* case 2a - error */ return MS_ERROR; else if ( 1 == var_data[i].ndim ) { /* case 2b */ if ( NC_CHAR == var_data[i].datatype ) { return MS_ERROR; /* no indexed 1D strings*/ } dt_start[0] = (long) index; if ( isPresent ) { if ( MS_ERROR == ncvarget1( cdfid, varid, dt_start, (void *)((values + var_data[i].data_offset)) ) ) { return MS_ERROR; } } else { put_default ( var_data[i].datatype, (void *) ((char *)values + var_data[i].data_offset), 0 ); } } else if ( 2 == var_data[i].ndim ) { /* case 2c */ dt_count[0] = 1L; dt_count[1] = ((ms_dim *)((char *)dimens + var_data[i].dim[1]))->size; if ( NC_CHAR == var_data[i].datatype ) { *((char * *)(values + var_data[i].data_offset)) = ms_read_string_variable( cdfid, varid, index, -1, dt_count[1] ); } else { if ( isPresent ) { dt_start[0] = (long)index; dt_start[1] = 0L; value = (void *)(*((char * *)(values + var_data[i].data_offset))); if ( MS_ERROR == ncvarget( cdfid, varid, dt_start, dt_count, value ) ) { return MS_ERROR; } } else { for ( j = 0; j < dt_count[1]; j++ ) { put_default( var_data[i].datatype, (void *) ((char *)(values + var_data[i].data_offset)), j ); } } } } else { /* case 2d */ return MS_ERROR; } } /* else */ } /* for ( i = 0; ... ) */ return MS_NO_ERROR; } /* read_info */