netcdf4-wasm
Version:
NetCDF4 library compiled to WebAssembly with TypeScript bindings
149 lines • 6.59 kB
JavaScript
"use strict";
// Group class for hierarchical data organization
Object.defineProperty(exports, "__esModule", { value: true });
exports.Group = void 0;
const dimension_1 = require("./dimension");
const variable_1 = require("./variable");
const constants_1 = require("./constants");
class Group {
constructor(netcdf, name, groupId) {
this.netcdf = netcdf;
this.name = name;
this.groupId = groupId;
this.dimensions = {};
this.variables = {};
this.groups = {};
this._attributes = {};
}
// Attribute methods
setAttr(name, value) {
this._attributes[name] = value;
// Store in mock file system if in test mode
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
const mockFiles = global.__netcdf4_mock_files;
const dataset = this.netcdf;
if (mockFiles && dataset.filename && mockFiles[dataset.filename]) {
mockFiles[dataset.filename].attributes[name] = value;
}
}
// TODO: Implement actual NetCDF global attribute setting
}
getAttr(name) {
// Check mock file system first if in test mode
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
const mockFiles = global.__netcdf4_mock_files;
const dataset = this.netcdf;
if (mockFiles && dataset.filename && mockFiles[dataset.filename]) {
const value = mockFiles[dataset.filename].attributes[name];
if (value !== undefined) {
this._attributes[name] = value; // Sync local cache
return value;
}
}
}
return this._attributes[name];
}
attrs() {
return Object.keys(this._attributes);
}
async createDimension(name, size) {
// Check for duplicate dimension name
if (this.dimensions[name]) {
throw new Error(`Dimension '${name}' already exists`);
}
// Check for invalid size values
if (size !== null && size < 0 && size !== constants_1.NC_CONSTANTS.NC_UNLIMITED) {
throw new Error(`Invalid dimension size: ${size}. Size must be non-negative or null for unlimited.`);
}
// Handle unlimited dimension (null or NC_UNLIMITED constant)
const isUnlimited = size === null || size === constants_1.NC_CONSTANTS.NC_UNLIMITED;
const ncSize = isUnlimited ? 0 : size; // Use 0 for unlimited in the actual NetCDF API
const dimid = await this.netcdf.defineDimension(this.groupId, name, ncSize);
const actualSize = isUnlimited ? constants_1.NC_CONSTANTS.NC_UNLIMITED : size;
const dimension = new dimension_1.Dimension(name, actualSize, isUnlimited);
this.dimensions[name] = dimension;
return dimension;
}
// Load dimensions and variables from mock storage when in test mode
loadMockDimensions() {
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
const mockFiles = global.__netcdf4_mock_files;
const dataset = this.netcdf;
if (mockFiles && dataset.filename && mockFiles[dataset.filename]) {
// Load dimensions
const mockDims = mockFiles[dataset.filename].dimensions;
for (const [name, dimData] of Object.entries(mockDims)) {
const dimension = new dimension_1.Dimension(name, dimData.size, dimData.unlimited);
this.dimensions[name] = dimension;
}
// Load variables
const mockVars = mockFiles[dataset.filename].variables;
for (const [name, varData] of Object.entries(mockVars)) {
const varInfo = varData;
// Reconstruct variable - for now, assume double datatype and no dimensions for simplicity
const variable = new variable_1.Variable(this.netcdf, name, varInfo.datatype || 'f8', varInfo.dimensions || [], 1, this.groupId);
// Restore variable attributes
if (varInfo.attributes) {
for (const [attrName, attrValue] of Object.entries(varInfo.attributes)) {
variable.setAttr(attrName, attrValue);
}
}
this.variables[name] = variable;
}
}
}
}
async createVariable(name, datatype, dimensions = [], options = {}) {
const ncType = constants_1.DATA_TYPE_MAP[datatype];
if (ncType === undefined) {
throw new Error(`Unsupported datatype: ${datatype}`);
}
// Get dimension IDs
const dimIds = dimensions.map(dimName => {
const dim = this.dimensions[dimName];
if (!dim) {
throw new Error(`Dimension '${dimName}' not found`);
}
// For now, we'll use the dimension name as ID (simplified)
return Object.keys(this.dimensions).indexOf(dimName);
});
const varid = await this.netcdf.defineVariable(this.groupId, name, ncType, dimIds);
const variable = new variable_1.Variable(this.netcdf, name, datatype, dimensions, varid, this.groupId);
this.variables[name] = variable;
// Store variable metadata in mock storage if in test mode
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
const mockFiles = global.__netcdf4_mock_files;
const dataset = this.netcdf;
if (mockFiles && dataset.filename && mockFiles[dataset.filename]) {
mockFiles[dataset.filename].variables[name] = {
datatype: datatype,
dimensions: dimensions,
data: new Float64Array(0),
attributes: {}
};
}
}
return variable;
}
createGroup(name) {
// For simplicity, groups use the same ncid for now
const group = new Group(this.netcdf, name, this.groupId);
this.groups[name] = group;
return group;
}
// Python-like method to get all children
children() {
return this.groups;
}
// Get group path (Python-like)
get path() {
if (this.name === '')
return '/';
return `/${this.name}`;
}
toString() {
return `<netCDF4.Group '${this.path}'>`;
}
}
exports.Group = Group;
//# sourceMappingURL=group.js.map