Skip to content

Commit

Permalink
improve error reporting for incomplete / corrupt chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
appelmar committed Mar 4, 2024
1 parent b9521ab commit dbfe8f6
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
26 changes: 21 additions & 5 deletions src/gdalcubes/src/cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,12 +716,18 @@ void cube::write_netcdf_file(std::string path, uint8_t compression_level, bool w
if (dim_x_bnds) std::free(dim_x_bnds);
}

std::function<void(chunkid_t, std::shared_ptr<chunk_data>, std::mutex &)> f = [this, op, prg, &v_bands, ncout, &packing, &v_chunkstatus](chunkid_t id, std::shared_ptr<chunk_data> dat, std::mutex &m) {
uint32_t chunk_error_count = 0;
std::function<void(chunkid_t, std::shared_ptr<chunk_data>, std::mutex &)> f = [this, op, prg, &v_bands, &chunk_error_count, ncout, &packing, &v_chunkstatus](chunkid_t id, std::shared_ptr<chunk_data> dat, std::mutex &m) {

// TODO: check if it is OK to simply not write anything to netCDF or if we need to fill dat explicity with no data values, check also for packed output
int nc_chunk_status = (int)dat->status();
std::size_t nc_chunk_id = std::size_t(id);
m.lock();
nc_put_var1_int(ncout, v_chunkstatus, &nc_chunk_id, &nc_chunk_status);
if (dat->status() != chunk_data::chunk_status::OK) {
chunk_error_count++;
}
m.unlock();
if (!dat->empty()) {
chunk_size_btyx csize = dat->size();
bounds_nd<uint32_t, 3> climits = chunk_limits(id);
Expand Down Expand Up @@ -854,6 +860,15 @@ void cube::write_netcdf_file(std::string path, uint8_t compression_level, bool w
nc_close(ncout);
prg->finalize();



if(chunk_error_count > 0) {
std::string msg = std::to_string(chunk_error_count) + " out of " + std::to_string(count_chunks()) + " chunks have repoprted errors / incompleteness. "\
"This is most likely caused by failed computations and/or inaccessible image data. Please check detailed output or run with debug option again.";
GCBS_WARN(msg);
}


// netCDF is now written, write additional per-time-slice VRT datasets if needed

if (with_VRT) {
Expand Down Expand Up @@ -1547,8 +1562,9 @@ void chunk_data::write_ncdf(std::string path, uint8_t compression_level, bool fo
}

if (!force) {
if (empty() || all_nan()) {
GCBS_WARN("Requested chunk is completely empty (NAN), and will not be written to a netCDF file on disk");
// Only avoid writing chunks if they have status OK and are empty / all NAN
if (_status == chunk_status::OK && all_nan()) {
GCBS_DEBUG("Requested chunk is completely empty (NAN), and will not be written to a netCDF file on disk");
return;
}
}
Expand Down Expand Up @@ -1604,14 +1620,14 @@ void chunk_data::read_ncdf(std::string path) {
}

int s = 0;
if (nc_get_att_int(ncfile, NC_GLOBAL, "chunk_status", &s)) {
if (nc_get_att_int(ncfile, NC_GLOBAL, "chunk_status", &s) == NC_NOERR) {
set_status(static_cast<chunk_data::chunk_status>(s));
}
else {
GCBS_DEBUG("NetCDF chunk file does not contain chunk status data. ");
set_status(chunk_data::chunk_status::UNKNOWN);
}

int dim_id_x = -1;
int dim_id_y = -1;
int dim_id_t = -1;
Expand Down
14 changes: 8 additions & 6 deletions src/gdalcubes/src/image_collection_cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
std::string bandsel_vrt_name = "";
GDALDataset *g = (GDALDataset *)GDALOpen(it->first.c_str(), GA_ReadOnly);
if (!g) {
GCBS_WARN("GDAL could not open '" + it->first + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("GDAL could not open '" + it->first + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand Down Expand Up @@ -507,7 +507,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
resampling::to_string(view()->resampling_method()), nodata_value_list);
}
if (!gdal_out) {
GCBS_WARN("GDAL could not warp '" + it->first + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("GDAL could not warp '" + it->first + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand Down Expand Up @@ -536,7 +536,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
res = gdal_out->GetRasterBand(std::get<1>(it->second[b]))->RasterIO(GF_Read, 0, 0, size_btyx[3], size_btyx[2], ((double *)img_buf) + b_internal * size_btyx[2] * size_btyx[3], size_btyx[3], size_btyx[2], GDT_Float64, 0, 0, NULL);
}
if (res != CE_None) {
GCBS_WARN("RasterIO (read) failed for '" + std::string(gdal_out->GetDescription()) + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("RasterIO (read) failed for '" + std::string(gdal_out->GetDescription()) + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand Down Expand Up @@ -568,7 +568,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
GDALDataset *bandsel_vrt = nullptr;
GDALDataset *g = (GDALDataset *)GDALOpen(mask_dataset_band.first.c_str(), GA_ReadOnly);
if (!g) {
GCBS_WARN("GDAL could not open '" + mask_dataset_band.first + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("GDAL could not open '" + mask_dataset_band.first + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand Down Expand Up @@ -618,7 +618,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
"near", std::vector<double>());
}
if (!gdal_out) {
GCBS_WARN("GDAL could not warp '" + mask_dataset_band.first + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("GDAL could not warp '" + mask_dataset_band.first + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand All @@ -634,7 +634,7 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {
CPLErr res = gdal_out->GetRasterBand(mask_dataset_band.second)->RasterIO(GF_Read, 0, 0, size_btyx[3], size_btyx[2], mask_buf, size_btyx[3], size_btyx[2], GDT_Float64, 0, 0, NULL);

if (res != CE_None) {
GCBS_WARN("RasterIO (read) failed for '" + std::string(gdal_out->GetDescription()) + "': ERROR no " + std::to_string(CPLGetLastErrorNo()) + ":" + CPLGetLastErrorMsg());
GCBS_WARN("RasterIO (read) failed for '" + std::string(gdal_out->GetDescription()) + "': ERROR (" + std::to_string(CPLGetLastErrorNo()) + "): " + CPLGetLastErrorMsg());
if (_strict) {
if (img_buf) std::free(img_buf);
if (mask_buf) std::free(mask_buf);
Expand Down Expand Up @@ -672,7 +672,9 @@ std::shared_ptr<chunk_data> image_collection_cube::read_chunk(chunkid_t id) {

// check if chunk is completely NAN and if yes, return empty chunk
if (out->all_nan()) {
auto s = out->status();
out = std::make_shared<chunk_data>();
out->set_status(s);
}

// CPLFree(srs_out_str);
Expand Down
2 changes: 1 addition & 1 deletion src/multiprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void chunk_processor_multiprocess::exec(std::string json_path, uint16_t pid, uin
std::string outfile_temp = filesystem::join(work_dir, "." + std::to_string(id) + ".nc");

// TODO: exception handling?!
cube->read_chunk(id)->write_ncdf(outfile_temp, ncdf_compression_level);
cube->read_chunk(id)->write_ncdf(outfile_temp, ncdf_compression_level, false);
if (filesystem::exists(outfile_temp)) {
filesystem::move(outfile_temp, outfile);
}
Expand Down

0 comments on commit dbfe8f6

Please sign in to comment.