Skip to content

Commit

Permalink
Core: improved file not found warning and Exception messages.
Browse files Browse the repository at this point in the history
Added `exists()` to OVF_File class.
IO_Image_Read and IO_Chain_Read now give better messages when a file does not exist, after checking for its existance.
Exception messages now also give the file and line of an API function. This helps if try/catch blocks are nested.
  • Loading branch information
GPMueller committed May 7, 2018
1 parent c7536ca commit 9dc0da6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 26 deletions.
2 changes: 2 additions & 0 deletions core/include/io/OVF_File.hpp
Expand Up @@ -93,6 +93,8 @@ namespace IO
public:
// constructor
File_OVF( std::string filename, VF_FileFormat format = VF_FileFormat::OVF_TEXT );
// Check if the file already exists
bool exists();
// Check if the file is in OVF format
bool is_OVF();
// Get the number of segments in the file
Expand Down
4 changes: 2 additions & 2 deletions core/include/utility/Exception.hpp
Expand Up @@ -75,7 +75,7 @@ namespace Utility
// Handle_Exception_API finalizes what should be done when an exception is encountered at the API layer.
// This function should only be used inside API functions, since that is the top level at which an
// exception is caught.
void Handle_Exception_API( const std::string & function="", int idx_image=-1, int idx_chain=-1 );
void Handle_Exception_API( const char * file, unsigned int line, const std::string & function="", int idx_image=-1, int idx_chain=-1 );

// Handle_Exception_Core finalizes what should be done when an exception is encountered inside the core.
// This function should only be used inside the core, below the API layer.
Expand All @@ -89,7 +89,7 @@ namespace Utility
#define spirit_rethrow(message) Utility::rethrow(message, __FILE__, __LINE__, __func__)

// Handle exception with backtrace and logging information on the calling API function
#define spirit_handle_exception_api(idx_image, idx_chain) Utility::Handle_Exception_API(__func__, idx_image, idx_chain)
#define spirit_handle_exception_api(idx_image, idx_chain) Utility::Handle_Exception_API(__FILE__, __LINE__, __func__, idx_image, idx_chain)

// Handle exception with backtrace and logging information on the calling core function
#define spirit_handle_exception_core(message) Utility::Handle_Exception_Core(message, __FILE__, __LINE__, __func__)
Expand Down
18 changes: 17 additions & 1 deletion core/src/Spirit/IO.cpp
Expand Up @@ -216,6 +216,14 @@ void IO_Image_Read( State *state, const char *file, int idx_image_infile,
// Create an OVF object
IO::File_OVF file_ovf( file );

if ( !file_ovf.exists() )
{
Log( Utility::Log_Level::Warning, Utility::Log_Sender::API,
fmt::format( "IO_Image_Read: file \"{}\" does not seem to exist", file ),
idx_image_inchain, idx_chain );
return;
}

if ( file_ovf.is_OVF() )
{
file_ovf.read_segment( spins, geometry, idx_image_infile );
Expand Down Expand Up @@ -450,7 +458,15 @@ void IO_Chain_Read( State *state, const char *file, int start_image_infile,
{
// Create an OVF object
IO::File_OVF file_ovf( file );


if ( !file_ovf.exists() )
{
Log( Utility::Log_Level::Warning, Utility::Log_Sender::API,
fmt::format( "IO_Chain_Read: file \"{}\" does not seem to exist", file ),
insert_idx, idx_chain );
return;
}

if ( file_ovf.is_OVF() )
{
int noi_infile = file_ovf.get_n_segments();
Expand Down
45 changes: 25 additions & 20 deletions core/src/io/OVF_File.cpp
Expand Up @@ -614,11 +614,16 @@ namespace IO

// Public methods ------------------------------------------------------------------------------

bool File_OVF::exists()
{
return this->file_exists;
}

bool File_OVF::is_OVF()
{
return this->isOVF;
}

int File_OVF::get_n_segments()
{
return this->n_segments;
Expand Down Expand Up @@ -666,14 +671,14 @@ namespace IO
spirit_rethrow( fmt::format("Failed to read OVF file \"{}\".", this->filename) );
}
}

void File_OVF::write_segment( const vectorfield& vf, const Data::Geometry& geometry,
const std::string comment, const bool append )
{
try
{
this->output_to_file.reserve( int( 0x08000000 ) ); // reserve 128[MByte]

// If we are not appending or the file does not exists we need to write the top header
// and to turn the file_exists attribute to true so we can append more segments
if ( !append || !this->file_exists )
Expand All @@ -682,43 +687,43 @@ namespace IO
read_n_segments_from_top_header(); // finds the file position of n_segments
this->file_exists = true;
}

this->output_to_file += fmt::format( this->empty_line );
this->output_to_file += fmt::format( "# Begin: Segment\n" );
this->output_to_file += fmt::format( "# Begin: Header\n" );
this->output_to_file += fmt::format( this->empty_line );

this->output_to_file += fmt::format( "# Title: SPIRIT Version {}\n",
Utility::version_full );
this->output_to_file += fmt::format( this->empty_line );

this->output_to_file += fmt::format( "# Desc: {}\n", comment );
this->output_to_file += fmt::format( this->empty_line );

// The value dimension is always 3 since we are writting Vector3-data
this->output_to_file += fmt::format( "# valuedim: {} ##Value dimension\n", 3 );
this->output_to_file += fmt::format( "# valueunits: None None None\n" );
this->output_to_file +=
fmt::format("# valuelabels: spin_x_component spin_y_component "
"spin_z_component \n");
this->output_to_file += fmt::format( this->empty_line );

this->output_to_file += fmt::format( "## Fundamental mesh measurement unit. "
"Treated as a label:\n" );
this->output_to_file += fmt::format( "# meshunit: unspecified\n" );
this->output_to_file += fmt::format( this->empty_line );

this->output_to_file += fmt::format( "# xmin: {}\n", geometry.bounds_min[0] );
this->output_to_file += fmt::format( "# ymin: {}\n", geometry.bounds_min[1] );
this->output_to_file += fmt::format( "# zmin: {}\n", geometry.bounds_min[2] );
this->output_to_file += fmt::format( "# xmax: {}\n", geometry.bounds_max[0] );
this->output_to_file += fmt::format( "# ymax: {}\n", geometry.bounds_max[1] );
this->output_to_file += fmt::format( "# zmax: {}\n", geometry.bounds_max[2] );
this->output_to_file += fmt::format( this->empty_line );

// TODO: Spirit does not support irregular geometry yet. Write ONLY rectangular mesh
this->output_to_file += fmt::format( "# meshtype: rectangular\n" );

// Bravais Lattice
this->output_to_file += fmt::format( "# xbase: {} {} {}\n",
geometry.bravais_vectors[0][0],
Expand All @@ -732,42 +737,42 @@ namespace IO
geometry.bravais_vectors[2][0],
geometry.bravais_vectors[2][1],
geometry.bravais_vectors[2][2] );

this->output_to_file += fmt::format( "# xstepsize: {}\n",
geometry.lattice_constant * geometry.bravais_vectors[0][0] );
this->output_to_file += fmt::format( "# ystepsize: {}\n",
geometry.lattice_constant * geometry.bravais_vectors[1][1] );
this->output_to_file += fmt::format( "# zstepsize: {}\n",
geometry.lattice_constant * geometry.bravais_vectors[2][2] );

this->output_to_file += fmt::format( "# xnodes: {}\n", geometry.n_cells[0] );
this->output_to_file += fmt::format( "# ynodes: {}\n", geometry.n_cells[1] );
this->output_to_file += fmt::format( "# znodes: {}\n", geometry.n_cells[2] );
this->output_to_file += fmt::format( this->empty_line );

this->output_to_file += fmt::format( "# End: Header\n" );
this->output_to_file += fmt::format( this->empty_line );

// Data
this->output_to_file += fmt::format( "# Begin: Data {}\n", this->datatype_out );

if ( this->format == VF_FileFormat::OVF_BIN8 || format == VF_FileFormat::OVF_BIN4 )
write_data_bin( vf );
else if ( this->format == VF_FileFormat::OVF_TEXT )
write_data_txt( vf );
else if ( this->format == VF_FileFormat::OVF_CSV )
write_data_txt( vf, "," );

this->output_to_file += fmt::format( "# End: Data {}\n", this->datatype_out );

this->output_to_file += fmt::format( "# End: Segment\n" );

// Append the #End keywords
Append_String_to_File( this->output_to_file, this->filename );

// reset output string buffer
this->output_to_file = "";

// Increment the n_segments after succesfully appending the segment body to the file
increment_n_segments();
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/utility/Exception.cpp
Expand Up @@ -70,7 +70,7 @@ namespace Utility
}
}

void Handle_Exception_API( const std::string & api_function, int idx_image, int idx_chain )
void Handle_Exception_API( const char * file, unsigned int line, const std::string & api_function, int idx_image, int idx_chain )
{
try
{
Expand All @@ -87,7 +87,7 @@ namespace Utility
str_exception = "exception";
else
str_exception = "SEVERE exception";
Log(ex.level, Log_Sender::API, fmt::format("Caught {} in API function \'{}\'\n{:>49}Exception backtrace:", str_exception, api_function, " "), idx_image, idx_chain);
Log(ex.level, Log_Sender::API, fmt::format("Caught {} in API function \'{}\' (at {}:{})\n{:>49}Exception backtrace:", str_exception, api_function, file, line, " "), idx_image, idx_chain);

// Create backtrace
Backtrace_Exception();
Expand All @@ -110,7 +110,7 @@ namespace Utility
}
catch ( const std::exception & ex )
{
std::cerr << "Caught exception in API function \'" << api_function << "\'" << std::endl;
std::cerr << "Caught std::exception in API function \'" << api_function << "\'" << std::endl;
std::cerr << "Unable to handle std::exception \'" << ex.what() << "\'! TERMINATING!" << std::endl;
std::exit(EXIT_FAILURE); // exit the application. may lead to data loss
}
Expand Down

0 comments on commit 9dc0da6

Please sign in to comment.