int sdf_helper_read_data(sdf_file_t *h, sdf_block_t *b) { int i; sdf_block_t *block; for (i = 0; i < b->n_ids; i++) { // Fill in derived components which are not already cached if (b->must_read[i]) { block = sdf_find_block_by_id(h, b->variable_ids[i]); if (block && !block->data) { sdf_block_set_array_section(block, b->ndims, b->array_starts, b->array_ends, b->array_strides); sdf_helper_read_data(h, block); } } } if (b->blocktype == SDF_BLOCKTYPE_PLAIN_DERIVED || b->blocktype == SDF_BLOCKTYPE_POINT_DERIVED) { // Allocate derived variable data if required if (!b->data && !b->dont_allocate) { // First fix up array dimensions. This should be moved into the // metadata setup. sdf_block_t *mesh; if (b->mesh_id) mesh = sdf_find_block_by_id(h, b->mesh_id); else mesh = b->subblock; b->ndims = mesh->ndims; memcpy(b->local_dims, mesh->local_dims, b->ndims * sizeof(*b->local_dims)); if (b->blocktype == SDF_BLOCKTYPE_POINT_DERIVED) { b->nelements_local = mesh->dims[0]; } else { b->nelements_local = 1; for (i=0; i < b->ndims; i++) { if (!b->station_id && b->stagger == SDF_STAGGER_CELL_CENTRE) b->local_dims[i]--; b->nelements_local *= b->local_dims[i]; } } if (!b->datatype_out) b->datatype_out = mesh->datatype_out; sdf_stack_alloc(h, b); } // Execute callback to fill in the derived variable if (b->populate_data) b->populate_data(h, b); } sdf_stack_alloc(h, b); h->current_block = b; return sdf_read_data(h); }
int sdf_read_blocklist_all(sdf_file_t *h) { sdf_extension_t *ext; char **preload; sdf_block_t *b, *next, *cur, *block; int i; // Retrieve the extended interface library from the plugin manager sdf_extension_load(h); ext = sdf_global_extension; if (h->blocklist) { if (ext) ext->timestate_update(ext, h); return 0; } sdf_read_blocklist(h); // Append derived data to the blocklist using built-in library. sdf_add_derived_blocks(h); if (ext) { preload = ext->preload(ext, h); // For each entry in the preload array, try to find the block // and populate its data. if (preload) { int n = 0; cur = h->current_block; while(preload[n]) { b = sdf_find_block_by_id(h, preload[n]); if (b && !b->data) { h->current_block = b; sdf_read_data(h); } free(preload[n]); n++; } free(preload); h->current_block = cur; } // Append derived data to the blocklist using the extension library. ext->read_blocklist(ext, h); } // Append additional derived data for blocks added by the extension. sdf_add_derived_blocks_final(h); sdf_purge_duplicates(h); // Fill in dimensions for derived blocks next = h->last_block_in_file; while (next) { b = next; next = b->next; if (b->blocktype != SDF_BLOCKTYPE_PLAIN_DERIVED && b->blocktype == SDF_BLOCKTYPE_POINT_DERIVED) continue; if (b->ndims > 0 || !b->mesh_id) continue; block = sdf_find_block_by_id(h, b->mesh_id); b->ndims = block->ndims; memcpy(b->local_dims, block->local_dims, b->ndims * sizeof(*b->local_dims)); if (b->blocktype == SDF_BLOCKTYPE_POINT_DERIVED) { b->nelements_local = block->dims[0]; } else { b->nelements_local = 1; for (i = 0; i < b->ndims; i++) { if (b->stagger == SDF_STAGGER_CELL_CENTRE && !b->station_id) b->local_dims[i]--; b->nelements_local *= b->local_dims[i]; } } if (!b->datatype_out) b->datatype_out = block->datatype_out; } return 0; }