(#434) Added NRLib for LAS support. Created CMake file to build it.

Readme.txt describes how to update the source code contained in NRLib.
This commit is contained in:
Pål Hagen
2015-09-11 16:32:38 +02:00
parent 69019115a2
commit a9027ecefa
61 changed files with 18204 additions and 0 deletions

29
ThirdParty/NRLib/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,29 @@
cmake_minimum_required (VERSION 2.8)
project (NRLib)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/boost
${CMAKE_CURRENT_SOURCE_DIR}/nrlib
${CMAKE_CURRENT_SOURCE_DIR}/nrlib/well
)
file ( GLOB NRLIB_IOTOOLS_SRC
nrlib/iotools/*.hpp
nrlib/iotools/*.cpp
)
file ( GLOB NRLIB_WELL_SRC
nrlib/well/*.hpp
nrlib/well/*.cpp
)
add_library( ${PROJECT_NAME}
boost/filesystem/operations.cpp
boost/filesystem/path.cpp
boost/filesystem/portability.cpp
boost/system/error_code.cpp
${NRLIB_IOTOOLS_SRC}
${NRLIB_WELL_SRC}
)

20
ThirdParty/NRLib/Readme.txt vendored Normal file
View File

@@ -0,0 +1,20 @@
How to update the source code files contained in NRLib
------------------------------------------------------
Download the latest boost files needed and place them in the boost folder:
https://github.com/CRAVA/crava/tree/master/libs/boost
Download the latest nrlib sub folders from here and replace the contents:
https://github.com/CRAVA/crava/tree/master/libs/nrlib
The following sub folders are currently used:
exception
grid
iotools
stormgrid
surface
volume
well

331
ThirdParty/NRLib/boost/cerrno.hpp vendored Normal file
View File

@@ -0,0 +1,331 @@
// Boost cerrno.hpp header -------------------------------------------------//
// Copyright Beman Dawes 2005.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
#ifndef BOOST_CERRNO_HPP
#define BOOST_CERRNO_HPP
#include <cerrno>
// supply errno values likely to be missing, particularly on Windows
#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT 9901
#endif
#ifndef EADDRINUSE
#define EADDRINUSE 9902
#endif
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL 9903
#endif
#ifndef EISCONN
#define EISCONN 9904
#endif
#ifndef EBADMSG
#define EBADMSG 9905
#endif
#ifndef ECONNABORTED
#define ECONNABORTED 9906
#endif
#ifndef EALREADY
#define EALREADY 9907
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED 9908
#endif
#ifndef ECONNRESET
#define ECONNRESET 9909
#endif
#ifndef EDESTADDRREQ
#define EDESTADDRREQ 9910
#endif
#ifndef EHOSTUNREACH
#define EHOSTUNREACH 9911
#endif
#ifndef EIDRM
#define EIDRM 9912
#endif
#ifndef EMSGSIZE
#define EMSGSIZE 9913
#endif
#ifndef ENETDOWN
#define ENETDOWN 9914
#endif
#ifndef ENETRESET
#define ENETRESET 9915
#endif
#ifndef ENETUNREACH
#define ENETUNREACH 9916
#endif
#ifndef ENOBUFS
#define ENOBUFS 9917
#endif
#ifndef ENOLINK
#define ENOLINK 9918
#endif
#ifndef ENODATA
#define ENODATA 9919
#endif
#ifndef ENOMSG
#define ENOMSG 9920
#endif
#ifndef ENOPROTOOPT
#define ENOPROTOOPT 9921
#endif
#ifndef ENOSR
#define ENOSR 9922
#endif
#ifndef ENOTSOCK
#define ENOTSOCK 9923
#endif
#ifndef ENOSTR
#define ENOSTR 9924
#endif
#ifndef ENOTCONN
#define ENOTCONN 9925
#endif
#ifndef ENOTSUP
#define ENOTSUP 9926
#endif
#ifndef ECANCELED
#define ECANCELED 9927
#endif
#ifndef EINPROGRESS
#define EINPROGRESS 9928
#endif
#ifndef EOPNOTSUPP
#define EOPNOTSUPP 9929
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK 9930
#endif
#ifndef EOWNERDEAD
#define EOWNERDEAD 9931
#endif
#ifndef EPROTO
#define EPROTO 9932
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT 9933
#endif
#ifndef ENOTRECOVERABLE
#define ENOTRECOVERABLE 9934
#endif
#ifndef ETIME
#define ETIME 9935
#endif
#ifndef ETXTBSY
#define ETXTBSY 9936
#endif
#ifndef ETIMEDOUT
#define ETIMEDOUT 9938
#endif
#ifndef ELOOP
#define ELOOP 9939
#endif
#ifndef EOVERFLOW
#define EOVERFLOW 9940
#endif
#ifndef EPROTOTYPE
#define EPROTOTYPE 9941
#endif
#ifndef ENOSYS
#define ENOSYS 9942
#endif
#ifndef EINVAL
#define EINVAL 9943
#endif
#ifndef ERANGE
#define ERANGE 9944
#endif
#ifndef EILSEQ
#define EILSEQ 9945
#endif
// Windows Mobile doesn't appear to define these:
#ifndef E2BIG
#define E2BIG 9946
#endif
#ifndef EDOM
#define EDOM 9947
#endif
#ifndef EFAULT
#define EFAULT 9948
#endif
#ifndef EBADF
#define EBADF 9949
#endif
#ifndef EPIPE
#define EPIPE 9950
#endif
#ifndef EXDEV
#define EXDEV 9951
#endif
#ifndef EBUSY
#define EBUSY 9952
#endif
#ifndef ENOTEMPTY
#define ENOTEMPTY 9953
#endif
#ifndef ENOEXEC
#define ENOEXEC 9954
#endif
#ifndef EEXIST
#define EEXIST 9955
#endif
#ifndef EFBIG
#define EFBIG 9956
#endif
#ifndef ENAMETOOLONG
#define ENAMETOOLONG 9957
#endif
#ifndef ENOTTY
#define ENOTTY 9958
#endif
#ifndef EINTR
#define EINTR 9959
#endif
#ifndef ESPIPE
#define ESPIPE 9960
#endif
#ifndef EIO
#define EIO 9961
#endif
#ifndef EISDIR
#define EISDIR 9962
#endif
#ifndef ECHILD
#define ECHILD 9963
#endif
#ifndef ENOLCK
#define ENOLCK 9964
#endif
#ifndef ENOSPC
#define ENOSPC 9965
#endif
#ifndef ENXIO
#define ENXIO 9966
#endif
#ifndef ENODEV
#define ENODEV 9967
#endif
#ifndef ENOENT
#define ENOENT 9968
#endif
#ifndef ESRCH
#define ESRCH 9969
#endif
#ifndef ENOTDIR
#define ENOTDIR 9970
#endif
#ifndef ENOMEM
#define ENOMEM 9971
#endif
#ifndef EPERM
#define EPERM 9972
#endif
#ifndef EACCES
#define EACCES 9973
#endif
#ifndef EROFS
#define EROFS 9974
#endif
#ifndef EDEADLK
#define EDEADLK 9975
#endif
#ifndef EAGAIN
#define EAGAIN 9976
#endif
#ifndef ENFILE
#define ENFILE 9977
#endif
#ifndef EMFILE
#define EMFILE 9978
#endif
#ifndef EMLINK
#define EMLINK 9979
#endif
#endif // include guard

20
ThirdParty/NRLib/boost/filesystem.hpp vendored Normal file
View File

@@ -0,0 +1,20 @@
// boost/filesystem/filesystem.hpp -----------------------------------------//
// Copyright Beman Dawes 2005
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP
#define BOOST_FILESYSTEM_FILESYSTEM_HPP
#include <boost/filesystem/operations.hpp> // includes path.hpp
#include <boost/filesystem/convenience.hpp>
#endif

View File

@@ -0,0 +1,122 @@
// boost/filesystem/config.hpp ---------------------------------------------//
// Copyright Beman Dawes 2003
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_CONFIG_HPP
#define BOOST_FILESYSTEM_CONFIG_HPP
#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions
// ability to change namespace aids path_table.cpp ------------------------//
#ifndef BOOST_FILESYSTEM_NAMESPACE
# define BOOST_FILESYSTEM_NAMESPACE filesystem
#endif
// This header implements separate compilation features as described in
// http://www.boost.org/more/separate_compilation.html
// #include <boost/config.hpp>
// #include <boost/detail/workaround.hpp>
// determine platform ------------------------------------------------------//
// BOOST_CYGWIN_PATH implies BOOST_WINDOWS_PATH and BOOST_POSIX_API
# if defined(BOOST_CYGWIN_PATH)
# if defined(BOOST_POSIX_PATH)
# error BOOST_POSIX_PATH is invalid when BOOST_CYGWIN_PATH is defined
# endif
# if defined(BOOST_WINDOWS_API)
# error BOOST_WINDOWS_API is invalid when BOOST_CYGWIN_PATH is defined
# endif
# define BOOST_WINDOWS_PATH
# define BOOST_POSIX_API
# endif
// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use
# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API )
# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined
# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API )
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
# define BOOST_WINDOWS_API
# else
# define BOOST_POSIX_API
# endif
# endif
// BOOST_WINDOWS_PATH enables Windows path syntax recognition
# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
# define BOOST_WINDOWS_PATH
# endif
// narrow support only for badly broken compilers or libraries -------------//
// NRLib-version: Support for wide characters does not compile.
//# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, <0x610)
# define BOOST_FILESYSTEM_NARROW_ONLY
//# endif
// enable dynamic linking on Windows ---------------------------------------//
# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)) && defined(__BORLANDC__) && __BORLANDC__ < 0x610 && defined(__WIN32__)
# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead
# endif
#ifdef BOOST_HAS_DECLSPEC // defined in config system
// we need to import/export our code only if the user has specifically
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK
// if they want just this one to be dynamically liked:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
// export if this is our own source, otherwise import:
#ifdef BOOST_FILESYSTEM_SOURCE
# define BOOST_FILESYSTEM_DECL __declspec(dllexport)
#else
# define BOOST_FILESYSTEM_DECL __declspec(dllimport)
#endif // BOOST_FILESYSTEM_SOURCE
#endif // DYN_LINK
#endif // BOOST_HAS_DECLSPEC
//
// if BOOST_FILESYSTEM_DECL isn't defined yet define it now:
#ifndef BOOST_FILESYSTEM_DECL
#define BOOST_FILESYSTEM_DECL
#endif
// enable automatic library variant selection ------------------------------//
#if 0 // NRLib: Comment out auto-linking
#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_filesystem
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // #if 0
// NRLib: Definitions copied from other places in Boost.
#define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment
#define BOOST_FILESYSTEM_NO_DEPRECATED
#endif // BOOST_FILESYSTEM_CONFIG_HPP

View File

@@ -0,0 +1,333 @@
// boost/filesystem/convenience.hpp ----------------------------------------//
// Copyright Beman Dawes, 2002-2005
// Copyright Vladimir Prus, 2002
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP
#define BOOST_FILESYSTEM_CONVENIENCE_HPP
#include <boost/filesystem/operations.hpp>
#include <boost/system/error_code.hpp>
#include <vector>
#include <stack>
//#include <boost/config/abi_prefix.hpp> // must be the last #include
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
# define BOOST_FS_FUNC(BOOST_FS_TYPE) \
template<class Path> typename boost::enable_if<is_basic_path<Path>, \
BOOST_FS_TYPE>::type
# define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type)
# define BOOST_FS_TYPENAME typename
# else
# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
typedef boost::filesystem::path Path;
# define BOOST_FS_FUNC_STRING inline std::string
# define BOOST_FS_TYPENAME
# endif
namespace boost
{
namespace filesystem
{
BOOST_FS_FUNC(bool) create_directories(const Path& ph)
{
if (ph.empty() || exists(ph))
{
if ( !ph.empty() && !is_directory(ph) )
throw basic_filesystem_error<Path>(
"boost::filesystem::create_directories", ph,
make_error_code( boost::system::errc::file_exists ) );
return false;
}
// First create branch, by calling ourself recursively
create_directories(ph.parent_path());
// Now that parent's path exists, create the directory
create_directory(ph);
return true;
}
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
BOOST_FS_FUNC_STRING extension(const Path& ph)
{
typedef BOOST_FS_TYPENAME Path::string_type string_type;
string_type filename = ph.filename();
BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
if (n != string_type::npos)
return filename.substr(n);
else
return string_type();
}
BOOST_FS_FUNC_STRING basename(const Path& ph)
{
typedef BOOST_FS_TYPENAME Path::string_type string_type;
string_type filename = ph.filename();
BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
return filename.substr(0, n);
}
BOOST_FS_FUNC(Path) change_extension( const Path & ph,
const BOOST_FS_TYPENAME Path::string_type & new_extension )
{ return ph.parent_path() / (basename(ph) + new_extension); }
# endif
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
// "do-the-right-thing" overloads ---------------------------------------//
inline bool create_directories(const path& ph)
{ return create_directories<path>(ph); }
inline bool create_directories(const wpath& ph)
{ return create_directories<wpath>(ph); }
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
inline std::string extension(const path& ph)
{ return extension<path>(ph); }
inline std::wstring extension(const wpath& ph)
{ return extension<wpath>(ph); }
inline std::string basename(const path& ph)
{ return basename<path>( ph ); }
inline std::wstring basename(const wpath& ph)
{ return basename<wpath>( ph ); }
inline path change_extension( const path & ph, const std::string& new_ex )
{ return change_extension<path>( ph, new_ex ); }
inline wpath change_extension( const wpath & ph, const std::wstring& new_ex )
{ return change_extension<wpath>( ph, new_ex ); }
# endif
# endif
// basic_recursive_directory_iterator helpers --------------------------//
namespace detail
{
template< class Path >
struct recur_dir_itr_imp
{
typedef basic_directory_iterator< Path > element_type;
std::stack< element_type, std::vector< element_type > > m_stack;
int m_level;
bool m_no_push;
bool m_no_throw;
recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {}
};
} // namespace detail
// basic_recursive_directory_iterator ----------------------------------//
template< class Path >
class basic_recursive_directory_iterator
//: public boost::iterator_facade<
// basic_recursive_directory_iterator<Path>,
// basic_directory_entry<Path>,
// boost::single_pass_traversal_tag >
{
public:
typedef Path path_type;
typedef basic_directory_entry<Path> value_type;
typedef value_type& reference;
typedef const value_type* pointer;
typedef ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
basic_recursive_directory_iterator() : m_imp(0) {} // creates the "end" iterator
explicit basic_recursive_directory_iterator( const Path & dir_path );
basic_recursive_directory_iterator( const Path & dir_path,
system::error_code & ec );
~basic_recursive_directory_iterator() { delete m_imp; }
reference operator*() const
{ return dereference(); }
pointer operator->() const
{ return &(operator*()); }
const basic_recursive_directory_iterator& operator++() {
increment();
return *this;
}
basic_recursive_directory_iterator operator++(int) {
basic_recursive_directory_iterator tmp(*this);
++*this;
return tmp;
}
bool operator==(const basic_recursive_directory_iterator& rhs) const
{ return equal (rhs); }
bool operator!=(const basic_recursive_directory_iterator& rhs) const
{ return !operator==(rhs); }
int level() const { return m_imp->m_level; }
void pop();
void no_push()
{
BOOST_ASSERT( m_imp->get() && "attempt to no_push() on end iterator" );
m_imp->m_no_push = true;
}
file_status status() const
{
BOOST_ASSERT( m_imp->get()
&& "attempt to call status() on end recursive_iterator" );
return m_imp->m_stack.top()->status();
}
file_status symlink_status() const
{
BOOST_ASSERT( m_imp->get()
&& "attempt to call symlink_status() on end recursive_iterator" );
return m_imp->m_stack.top()->symlink_status();
}
private:
// shared_ptr provides shallow-copy semantics required for InputIterators.
// m_imp->get()==0 indicates the end iterator.
detail::recur_dir_itr_imp< Path > * m_imp;
//typename boost::iterator_facade<
// basic_recursive_directory_iterator<Path>,
// basic_directory_entry<Path>,
// boost::single_pass_traversal_tag >::reference
reference dereference() const
{
assert( m_imp != 0 && "attempt to dereference end iterator" );
return *m_imp->m_stack.top();
}
void increment();
bool equal( const basic_recursive_directory_iterator & rhs ) const
{ return m_imp == rhs.m_imp; }
};
typedef basic_recursive_directory_iterator<path> recursive_directory_iterator;
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;
# endif
// basic_recursive_directory_iterator implementation -------------------//
// constructors
template<class Path>
basic_recursive_directory_iterator<Path>::
basic_recursive_directory_iterator( const Path & dir_path )
: m_imp( new detail::recur_dir_itr_imp<Path> )
{
m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path ) );
if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() )
{ m_imp->reset (); }
}
template<class Path>
basic_recursive_directory_iterator<Path>::
basic_recursive_directory_iterator( const Path & dir_path,
system::error_code & ec )
: m_imp( new detail::recur_dir_itr_imp<Path> )
{
m_imp->m_no_throw = true;
m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path, ec ) );
if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() )
{ m_imp->reset (); }
}
// increment
template<class Path>
void basic_recursive_directory_iterator<Path>::increment()
{
BOOST_ASSERT( m_imp->get() && "increment on end iterator" );
static const basic_directory_iterator<Path> end_itr;
if ( m_imp->m_no_push )
{ m_imp->m_no_push = false; }
else if ( is_directory( m_imp->m_stack.top()->status() ) )
{
system::error_code ec;
#if 0 // BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
if ( m_imp->m_no_throw ) {
m_imp->m_stack.push(
basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec )
);
}
else {
m_imp->m_stack.push(
basic_directory_iterator<Path>( *m_imp->m_stack.top() )
);
}
#else
m_imp->m_stack.push(
m_imp->m_no_throw
? basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec )
: basic_directory_iterator<Path>( *m_imp->m_stack.top() ) );
#endif
if ( m_imp->m_stack.top() != end_itr )
{
++m_imp->m_level;
return;
}
m_imp->m_stack.pop();
}
while ( !m_imp->m_stack.empty()
&& ++m_imp->m_stack.top() == end_itr )
{
m_imp->m_stack.pop();
--m_imp->m_level;
}
if ( m_imp->m_stack.empty() ) m_imp->reset(); // done, so make end iterator
}
// pop
template<class Path>
void basic_recursive_directory_iterator<Path>::pop()
{
BOOST_ASSERT( m_imp->get() && "pop on end iterator" );
BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" );
static const basic_directory_iterator<Path> end_itr;
do
{
m_imp->m_stack.pop();
--m_imp->m_level;
}
while ( !m_imp->m_stack.empty()
&& ++m_imp->m_stack.top() == end_itr );
if ( m_imp->m_stack.empty() ) m_imp->reset(); // done, so make end iterator
}
} // namespace filesystem
} // namespace boost
#undef BOOST_FS_FUNC_STRING
#undef BOOST_FS_FUNC
//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP

View File

@@ -0,0 +1,584 @@
// boost/filesystem/fstream.hpp --------------------------------------------//
// Copyright Beman Dawes 2002.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_FSTREAM_HPP
#define BOOST_FILESYSTEM_FSTREAM_HPP
#include <boost/filesystem/operations.hpp> // for 8.3 hack (see below)
//#include <boost/utility/enable_if.hpp>
//#include <boost/detail/workaround.hpp>
#include <iosfwd>
#include <fstream>
//#include <boost/config/abi_prefix.hpp> // must be the last #include
// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for
// various compiler problems. They have been removed to ease development of the
// basic i18n functionality. Once the new interface is stable, the workarounds
// will be reinstated for any compilers that otherwise can support the rest of
// the library after internationalization.
namespace boost
{
namespace filesystem
{
namespace detail
{
# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405
// The 8.3 hack:
// C++98 does not supply a wchar_t open, so try to get an equivalent
// narrow char name based on the short, so-called 8.3, name.
// Not needed for Dinkumware 405 and later as they do supply wchar_t open.
BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph,
std::ios_base::openmode mode ); // true if succeeds
BOOST_FILESYSTEM_DECL std::string narrow_path_api(
const std::wstring & ph ); // return is empty if fails
inline std::string path_proxy( const std::wstring & file_ph,
std::ios_base::openmode mode )
// Return a non-existant path if cannot supply narrow short path.
// An empty path doesn't work because some Dinkumware versions
// assert the path is non-empty.
{
std::string narrow_ph;
bool created_file( false );
if ( !exists( file_ph )
&& (mode & std::ios_base::out) != 0
&& create_file_api( file_ph, mode ) )
{
created_file = true;
}
narrow_ph = narrow_path_api( file_ph );
if ( narrow_ph.empty() )
{
if ( created_file ) remove_api( file_ph );
narrow_ph = "\x01";
}
return narrow_ph;
}
# else
// Dinkumware 405 and later does supply wchar_t functions
inline const std::wstring & path_proxy( const std::wstring & file_ph,
std::ios_base::openmode )
{ return file_ph; }
# endif
# endif
inline const std::string & path_proxy( const std::string & file_ph,
std::ios_base::openmode )
{ return file_ph; }
} // namespace detail
template < class charT, class traits = std::char_traits<charT> >
class basic_filebuf : public std::basic_filebuf<charT,traits>
{
private: // disallow copying
basic_filebuf( const basic_filebuf & );
const basic_filebuf & operator=( const basic_filebuf & );
public:
basic_filebuf() {}
virtual ~basic_filebuf() {}
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
template<class Path>
typename boost::enable_if<is_basic_path<Path>,
basic_filebuf<charT,traits> *>::type
open( const Path & file_ph, std::ios_base::openmode mode );
basic_filebuf<charT,traits> *
open( const wpath & file_ph, std::ios_base::openmode mode );
# endif
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
basic_filebuf<charT,traits> *
open( const path & file_ph, std::ios_base::openmode mode );
# endif
};
template < class charT, class traits = std::char_traits<charT> >
class basic_ifstream : public std::basic_ifstream<charT,traits>
{
private: // disallow copying
basic_ifstream( const basic_ifstream & );
const basic_ifstream & operator=( const basic_ifstream & );
public:
basic_ifstream() {}
// use two signatures, rather than one signature with default second
// argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
template<class Path>
explicit basic_ifstream( const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
template<class Path>
basic_ifstream( const Path & file_ph, std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph, std::ios_base::openmode mode );
explicit basic_ifstream( const wpath & file_ph );
basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode );
void open( const wpath & file_ph );
void open( const wpath & file_ph, std::ios_base::openmode mode );
# endif
explicit basic_ifstream( const path & file_ph );
basic_ifstream( const path & file_ph, std::ios_base::openmode mode );
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
void open( const path & file_ph );
void open( const path & file_ph, std::ios_base::openmode mode );
# endif
virtual ~basic_ifstream() {}
};
template < class charT, class traits = std::char_traits<charT> >
class basic_ofstream : public std::basic_ofstream<charT,traits>
{
private: // disallow copying
basic_ofstream( const basic_ofstream & );
const basic_ofstream & operator=( const basic_ofstream & );
public:
basic_ofstream() {}
// use two signatures, rather than one signature with default second
// argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
template<class Path>
explicit basic_ofstream( const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
explicit basic_ofstream( const wpath & file_ph );
template<class Path>
basic_ofstream( const Path & file_ph, std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph );
void open( const wpath & file_ph );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph, std::ios_base::openmode mode );
void open( const wpath & file_ph, std::ios_base::openmode mode );
# endif
explicit basic_ofstream( const path & file_ph );
basic_ofstream( const path & file_ph, std::ios_base::openmode mode );
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
void open( const path & file_ph );
void open( const path & file_ph, std::ios_base::openmode mode );
# endif
virtual ~basic_ofstream() {}
};
template < class charT, class traits = std::char_traits<charT> >
class basic_fstream : public std::basic_fstream<charT,traits>
{
private: // disallow copying
basic_fstream( const basic_fstream & );
const basic_fstream & operator=( const basic_fstream & );
public:
basic_fstream() {}
// use two signatures, rather than one signature with default second
// argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
template<class Path>
explicit basic_fstream( const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
explicit basic_fstream( const wpath & file_ph );
template<class Path>
basic_fstream( const Path & file_ph, std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
basic_fstream( const wpath & file_ph, std::ios_base::openmode mode );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph );
void open( const wpath & file_ph );
template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
open( const Path & file_ph, std::ios_base::openmode mode );
void open( const wpath & file_ph, std::ios_base::openmode mode );
# endif
explicit basic_fstream( const path & file_ph );
basic_fstream( const path & file_ph, std::ios_base::openmode mode );
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
void open( const path & file_ph );
void open( const path & file_ph, std::ios_base::openmode mode );
# endif
virtual ~basic_fstream() {}
};
typedef basic_filebuf<char> filebuf;
typedef basic_ifstream<char> ifstream;
typedef basic_ofstream<char> ofstream;
typedef basic_fstream<char> fstream;
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
typedef basic_filebuf<wchar_t> wfilebuf;
typedef basic_ifstream<wchar_t> wifstream;
typedef basic_fstream<wchar_t> wfstream;
typedef basic_ofstream<wchar_t> wofstream;
# endif
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
// basic_filebuf definitions -----------------------------------------------//
template <class charT, class traits>
template<class Path>
typename boost::enable_if<is_basic_path<Path>,
basic_filebuf<charT,traits> *>::type
basic_filebuf<charT,traits>::open( const Path & file_ph,
std::ios_base::openmode mode )
{
return (std::basic_filebuf<charT,traits>::open( detail::path_proxy(
file_ph.external_file_string(), mode ).c_str(), mode )
== 0) ? 0 : this;
}
template <class charT, class traits>
basic_filebuf<charT,traits> *
basic_filebuf<charT, traits>::open( const wpath & file_ph,
std::ios_base::openmode mode )
{
return this->BOOST_NESTED_TEMPLATE open<wpath>( file_ph, mode );
}
// basic_ifstream definitions ----------------------------------------------//
template <class charT, class traits> template<class Path>
basic_ifstream<charT,traits>::basic_ifstream(const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_ifstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in ).c_str(), std::ios_base::in ) {}
template <class charT, class traits>
basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph )
: std::basic_ifstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in ).c_str(), std::ios_base::in ) {}
template <class charT, class traits> template<class Path>
basic_ifstream<charT,traits>::basic_ifstream( const Path & file_ph,
std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_ifstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in ) {}
template <class charT, class traits>
basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph,
std::ios_base::openmode mode )
: std::basic_ifstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in ) {}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_ifstream<charT,traits>::open( const Path & file_ph )
{
std::basic_ifstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in ).c_str(), std::ios_base::in );
}
template <class charT, class traits>
void basic_ifstream<charT,traits>::open( const wpath & file_ph )
{
std::basic_ifstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in ).c_str(), std::ios_base::in );
}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_ifstream<charT,traits>::open( const Path & file_ph,
std::ios_base::openmode mode )
{
std::basic_ifstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in );
}
template <class charT, class traits>
void basic_ifstream<charT,traits>::open( const wpath & file_ph,
std::ios_base::openmode mode )
{
std::basic_ifstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in );
}
// basic_ofstream definitions ----------------------------------------------//
template <class charT, class traits> template<class Path>
basic_ofstream<charT,traits>::basic_ofstream(const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_ofstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::out ).c_str(), std::ios_base::out ) {}
template <class charT, class traits>
basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph )
: std::basic_ofstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::out ).c_str(), std::ios_base::out ) {}
template <class charT, class traits> template<class Path>
basic_ofstream<charT,traits>::basic_ofstream( const Path & file_ph,
std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_ofstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::out ) {}
template <class charT, class traits>
basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph,
std::ios_base::openmode mode )
: std::basic_ofstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::out ) {}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_ofstream<charT,traits>::open( const Path & file_ph )
{
std::basic_ofstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::out ).c_str(), std::ios_base::out );
}
template <class charT, class traits>
void basic_ofstream<charT,traits>::open( const wpath & file_ph )
{
std::basic_ofstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::out ).c_str(), std::ios_base::out );
}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_ofstream<charT,traits>::open( const Path & file_ph,
std::ios_base::openmode mode )
{
std::basic_ofstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::out );
}
template <class charT, class traits>
void basic_ofstream<charT,traits>::open( const wpath & file_ph,
std::ios_base::openmode mode )
{
std::basic_ofstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::out );
}
// basic_fstream definitions -----------------------------------------------//
template <class charT, class traits> template<class Path>
basic_fstream<charT,traits>::basic_fstream(const Path & file_ph,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_fstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in|std::ios_base::out ).c_str(),
std::ios_base::in|std::ios_base::out ) {}
template <class charT, class traits>
basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph )
: std::basic_fstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in|std::ios_base::out ).c_str(),
std::ios_base::in|std::ios_base::out ) {}
template <class charT, class traits> template<class Path>
basic_fstream<charT,traits>::basic_fstream( const Path & file_ph,
std::ios_base::openmode mode,
typename boost::enable_if<is_basic_path<Path> >::type* )
: std::basic_fstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {}
template <class charT, class traits>
basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph,
std::ios_base::openmode mode )
: std::basic_fstream<charT,traits>(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_fstream<charT,traits>::open( const Path & file_ph )
{
std::basic_fstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in|std::ios_base::out ).c_str(),
std::ios_base::in|std::ios_base::out );
}
template <class charT, class traits>
void basic_fstream<charT,traits>::open( const wpath & file_ph )
{
std::basic_fstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
std::ios_base::in|std::ios_base::out ).c_str(),
std::ios_base::in|std::ios_base::out );
}
template <class charT, class traits> template<class Path>
typename boost::enable_if<is_basic_path<Path>, void>::type
basic_fstream<charT,traits>::open( const Path & file_ph,
std::ios_base::openmode mode )
{
std::basic_fstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in | std::ios_base::out );
}
template <class charT, class traits>
void basic_fstream<charT,traits>::open( const wpath & file_ph,
std::ios_base::openmode mode )
{
std::basic_fstream<charT,traits>::open(
detail::path_proxy( file_ph.external_file_string(),
mode ).c_str(), mode | std::ios_base::in | std::ios_base::out );
}
# endif
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
template <class charT, class traits>
basic_filebuf<charT,traits> *
basic_filebuf<charT, traits>::open( const path & file_ph,
std::ios_base::openmode mode )
{
return std::basic_filebuf<charT,traits>::open(
file_ph.file_string().c_str(), mode ) == 0 ? 0 : this;
}
# endif
template <class charT, class traits>
basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph )
: std::basic_ifstream<charT,traits>(
file_ph.file_string().c_str(), std::ios_base::in ) {}
template <class charT, class traits>
basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph,
std::ios_base::openmode mode )
: std::basic_ifstream<charT,traits>(
file_ph.file_string().c_str(), mode ) {}
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
template <class charT, class traits>
void basic_ifstream<charT,traits>::open( const path & file_ph )
{
std::basic_ifstream<charT,traits>::open(
file_ph.file_string().c_str(), std::ios_base::in );
}
template <class charT, class traits>
void basic_ifstream<charT,traits>::open( const path & file_ph,
std::ios_base::openmode mode )
{
std::basic_ifstream<charT,traits>::open(
file_ph.file_string().c_str(), mode );
}
# endif
template <class charT, class traits>
basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph )
: std::basic_ofstream<charT,traits>(
file_ph.file_string().c_str(), std::ios_base::out ) {}
template <class charT, class traits>
basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph,
std::ios_base::openmode mode )
: std::basic_ofstream<charT,traits>(
file_ph.file_string().c_str(), mode ) {}
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
template <class charT, class traits>
void basic_ofstream<charT,traits>::open( const path & file_ph )
{
std::basic_ofstream<charT,traits>::open(
file_ph.file_string().c_str(), std::ios_base::out );
}
template <class charT, class traits>
void basic_ofstream<charT,traits>::open( const path & file_ph,
std::ios_base::openmode mode )
{
std::basic_ofstream<charT,traits>::open(
file_ph.file_string().c_str(), mode );
}
# endif
template <class charT, class traits>
basic_fstream<charT,traits>::basic_fstream( const path & file_ph )
: std::basic_fstream<charT,traits>(
file_ph.file_string().c_str(),
std::ios_base::in|std::ios_base::out ) {}
template <class charT, class traits>
basic_fstream<charT,traits>::basic_fstream( const path & file_ph,
std::ios_base::openmode mode )
: std::basic_fstream<charT,traits>(
file_ph.file_string().c_str(), mode ) {}
# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
template <class charT, class traits>
void basic_fstream<charT,traits>::open( const path & file_ph )
{
std::basic_fstream<charT,traits>::open(
file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out );
}
template <class charT, class traits>
void basic_fstream<charT,traits>::open( const path & file_ph,
std::ios_base::openmode mode )
{
std::basic_fstream<charT,traits>::open(
file_ph.file_string().c_str(), mode );
}
# endif
} // namespace filesystem
} // namespace boost
//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#endif // BOOST_FILESYSTEM_FSTREAM_HPP

View File

@@ -0,0 +1,3 @@
SRC += filesystem/operations.cpp \
filesystem/path.cpp \
filesystem/portability.cpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
// path.cpp ----------------------------------------------------------------//
// Copyright 2005 Beman Dawes
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_FILESYSTEM_SOURCE
#include <boost/filesystem/config.hpp>
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
#include <boost/filesystem/path.hpp>
#include <boost/scoped_array.hpp>
#include <locale>
#include <boost/cerrno.hpp>
#include <boost/system/error_code.hpp>
#include <cwchar> // for std::mbstate_t
namespace
{
// std::locale construction can throw (if LC_MESSAGES is wrong, for example),
// so a static at function scope is used to ensure that exceptions can be
// caught. (A previous version was at namespace scope, so initialization
// occurred before main(), preventing exceptions from being caught.)
std::locale & loc()
{
// ISO C calls this "the locale-specific native environment":
static std::locale lc("");
return lc;
}
const std::codecvt<wchar_t, char, std::mbstate_t> *&
converter()
{
static const std::codecvt<wchar_t, char, std::mbstate_t> *
cvtr(
&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
( loc() ) );
return cvtr;
}
bool locked(false);
} // unnamed namespace
namespace boost
{
namespace filesystem
{
bool wpath_traits::imbue( const std::locale & new_loc, const std::nothrow_t & )
{
if ( locked ) return false;
locked = true;
loc() = new_loc;
converter() = &std::use_facet
<std::codecvt<wchar_t, char, std::mbstate_t> >( loc() );
return true;
}
void wpath_traits::imbue( const std::locale & new_loc )
{
if ( locked ) boost::throw_exception(
wfilesystem_error(
"boost::filesystem::wpath_traits::imbue() after lockdown",
make_error_code( system::posix::not_supported ) ) );
imbue( new_loc, std::nothrow );
}
//namespace detail
//{
// BOOST_FILESYSTEM_DECL
// const char * what( const char * sys_err_what,
// const path & path1, const path & path2, std::string & target)
// {
// try
// {
// if ( target.empty() )
// {
// target = sys_err_what;
// if ( !path1.empty() )
// {
// target += ": \"";
// target += path1.file_string();
// target += "\"";
// }
// if ( !path2.empty() )
// {
// target += ", \"";
// target += path2.file_string();
// target += "\"";
// }
// }
// return target.c_str();
// }
// catch (...)
// {
// return sys_err_what;
// }
// }
//}
# ifdef BOOST_POSIX_API
// Because this is POSIX only code, we don't have to worry about ABI issues
// described in http://www.boost.org/more/separate_compilation.html
wpath_traits::external_string_type
wpath_traits::to_external( const wpath & ph,
const internal_string_type & src )
{
locked = true;
std::size_t work_size( converter()->max_length() * (src.size()+1) );
boost::scoped_array<char> work( new char[ work_size ] );
std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
const internal_string_type::value_type * from_next;
external_string_type::value_type * to_next;
if ( converter()->out(
state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
work.get()+work_size, to_next ) != std::codecvt_base::ok )
boost::throw_exception( boost::filesystem::wfilesystem_error(
"boost::filesystem::wpath::to_external conversion error",
ph, system::error_code( system::posix::invalid_argument, system::system_category ) ) );
*to_next = '\0';
return external_string_type( work.get() );
}
wpath_traits::internal_string_type
wpath_traits::to_internal( const external_string_type & src )
{
locked = true;
std::size_t work_size( src.size()+1 );
boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] );
std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
const external_string_type::value_type * from_next;
internal_string_type::value_type * to_next;
if ( converter()->in(
state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
work.get()+work_size, to_next ) != std::codecvt_base::ok )
boost::throw_exception( boost::filesystem::wfilesystem_error(
"boost::filesystem::wpath::to_internal conversion error",
system::error_code( system::posix::invalid_argument, system::system_category ) ) );
*to_next = L'\0';
return internal_string_type( work.get() );
}
# endif // BOOST_POSIX_API
} // namespace filesystem
} // namespace boost
#endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY

1551
ThirdParty/NRLib/boost/filesystem/path.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
// portability.cpp ---------------------------------------------------------//
// Copyright 2002-2005 Beman Dawes
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
// at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_FILESYSTEM_SOURCE
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;
#include <cstring> // SGI MIPSpro compilers need this
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strerror; }
# endif
//----------------------------------------------------------------------------//
namespace
{
const char invalid_chars[] =
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
"<>:\"/\\|";
// note that the terminating '\0' is part of the string - thus the size below
// is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I
const std::string windows_invalid_chars( invalid_chars, sizeof(invalid_chars) );
const std::string valid_posix(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-" );
} // unnamed namespace
namespace boost
{
namespace filesystem
{
// name_check functions ----------------------------------------------//
# ifdef BOOST_WINDOWS
BOOST_FILESYSTEM_DECL bool native( const std::string & name )
{
return windows_name( name );
}
# else
BOOST_FILESYSTEM_DECL bool native( const std::string & name )
{
return name.size() != 0
&& name[0] != ' '
&& name.find('/') == std::string::npos;
}
# endif
BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name )
{
return name.size() != 0
&& name.find_first_not_of( valid_posix ) == std::string::npos;
}
BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name )
{
return name.size() != 0
&& name[0] != ' '
&& name.find_first_of( windows_invalid_chars ) == std::string::npos
&& *(name.end()-1) != ' '
&& (*(name.end()-1) != '.'
|| name.length() == 1 || name == "..");
}
BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name )
{
return
name.size() != 0
&& ( name == "."
|| name == ".."
|| (windows_name( name )
&& portable_posix_name( name )
&& name[0] != '.' && name[0] != '-'));
}
BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name )
{
return
name == "."
|| name == ".."
|| (portable_name( name )
&& name.find('.') == std::string::npos);
}
BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name )
{
std::string::size_type pos;
return
portable_name( name )
&& name != "."
&& name != ".."
&& ( (pos = name.find( '.' )) == std::string::npos
|| (name.find( '.', pos+1 ) == std::string::npos
&& (pos + 5) > name.length() ))
;
}
} // namespace filesystem
} // namespace boost

View File

@@ -0,0 +1,78 @@
// boost/system/config.hpp -------------------------------------------------//
// Copyright Beman Dawes 2003, 2006
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/system for documentation.
#ifndef BOOST_SYSTEM_CONFIG_HPP
#define BOOST_SYSTEM_CONFIG_HPP
// #include <boost/config.hpp>
// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use.
// If not specified, a sensible default will be applied.
# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API )
# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined
# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API )
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
# define BOOST_WINDOWS_API
# else
# define BOOST_POSIX_API
# endif
# endif
// enable dynamic linking on Windows ---------------------------------------//
//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__)
//# error Dynamic linking Boost.System does not work for Borland; use static linking instead
//# endif
#ifdef BOOST_HAS_DECLSPEC // defined in config system
// we need to import/export our code only if the user has specifically
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
// libraries to be dynamically linked, or BOOST_SYSTEM_DYN_LINK
// if they want just this one to be dynamically liked:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)
// export if this is our own source, otherwise import:
#ifdef BOOST_SYSTEM_SOURCE
# define BOOST_SYSTEM_DECL __declspec(dllexport)
#else
# define BOOST_SYSTEM_DECL __declspec(dllimport)
#endif // BOOST_SYSTEM_SOURCE
#endif // DYN_LINK
#endif // BOOST_HAS_DECLSPEC
//
// if BOOST_SYSTEM_DECL isn't defined yet define it now:
#ifndef BOOST_SYSTEM_DECL
#define BOOST_SYSTEM_DECL
#endif
// enable automatic library variant selection ------------------------------//
#if 0 // NRLib: Disable automatic library selection.
#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_system
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif
#define BOOST_SYSTEM_NO_DEPRECATED
#endif // BOOST_SYSTEM_CONFIG_HPP

View File

@@ -0,0 +1,56 @@
// boost/system/cygwin_error.hpp -------------------------------------------//
// Copyright Beman Dawes 2007
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
#ifndef BOOST_CYGWIN_ERROR_HPP
#define BOOST_CYGWIN_ERROR_HPP
// This header is effectively empty for compiles on operating systems where
// it is not applicable.
# ifdef __CYGWIN__
#include <boost/system/error_code.hpp>
namespace boost
{
namespace system
{
// To construct an error_code after a API error:
//
// error_code( errno, system_category )
// User code should use the portable "posix" enums for POSIX errors; this
// allows such code to be portable to non-POSIX systems. For the non-POSIX
// errno values that POSIX-based systems typically provide in addition to
// POSIX values, use the system specific enums below.
namespace cygwin_error
{
enum cygwin_errno
{
no_net = ENONET,
no_package = ENOPKG,
no_share = ENOSHARE
};
} // namespace cygwin_error
template<> struct is_error_code_enum<cygwin_error::cygwin_errno>
{ static const bool value = true; };
namespace cygwin_error
{
inline error_code make_error_code( cygwin_errno e )
{ return error_code( e, get_system_category() ); }
}
}
}
#endif // __CYGWIN__
#endif // BOOST_CYGWIN_ERROR_HPP

View File

@@ -0,0 +1,445 @@
// error_code support implementation file ----------------------------------//
// Copyright Beman Dawes 2002, 2006
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
//----------------------------------------------------------------------------//
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
// Error 'function': was declared deprecated
// http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx
// This error is emitted when you use some perfectly conforming
// std lib functions in a perfectly correct way, and also by
// some of Microsoft's own std lib code !
# pragma warning(disable:4996)
#endif
#if defined(__INTEL_COMPILER) || defined(__ICL)
// As above: gives warning when a "deprecated"
// std library function is encountered.
# pragma warning(disable:1786)
#endif
// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_SYSTEM_SOURCE
#include <boost/system/config.hpp>
#include <boost/system/error_code.hpp>
#include <boost/cerrno.hpp>
#include <vector>
#include <cstdlib>
#include <cassert>
using namespace boost::system;
using namespace boost::system::errc;
#include <cstring> // for strerror/strerror_r
# if defined( BOOST_WINDOWS_API )
# include <windows.h>
# ifndef ERROR_INCORRECT_SIZE
# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
# endif
# endif
//----------------------------------------------------------------------------//
namespace
{
// standard error categories ---------------------------------------------//
class generic_error_category : public error_category
{
public:
generic_error_category(){}
const char * name() const;
std::string message( int ev ) const;
};
class system_error_category : public error_category
{
public:
system_error_category(){}
const char * name() const;
std::string message( int ev ) const;
error_condition default_error_condition( int ev ) const;
};
// generic_error_category implementation ---------------------------------//
const char * generic_error_category::name() const
{
return "generic";
}
std::string generic_error_category::message( int ev ) const
{
static std::string unknown_err( "Unknown error" );
// strerror_r is preferred because it is always thread safe,
// however, we fallback to strerror in certain cases because:
// -- Windows doesn't provide strerror_r.
// -- HP and Sundo provide strerror_r on newer systems, but there is
// no way to tell if is available at runtime and in any case their
// versions of strerror are thread safe anyhow.
// -- Linux only sometimes provides strerror_r.
// -- Tru64 provides strerror_r only when compiled -pthread.
// -- VMS doesn't provide strerror_r, but on this platform, strerror is
// thread safe.
# if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
|| (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
|| (defined(__osf__) && !defined(_REENTRANT))\
|| (defined(__vms))\
|| (defined(__QNXNTO__))
const char * c_str = std::strerror( ev );
return c_str
? std::string( c_str )
: unknown_err;
# else // use strerror_r
char buf[64];
char * bp = buf;
std::size_t sz = sizeof(buf);
# if defined(__CYGWIN__) || defined(__USE_GNU)
// Oddball version of strerror_r
const char * c_str = strerror_r( ev, bp, sz );
return c_str
? std::string( c_str )
: unknown_err;
# else
// POSIX version of strerror_r
int result;
for (;;)
{
// strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
// invalid_argument if ev not a valid error number
# if defined (__sgi)
const char * c_str = strerror( ev );
result = 0;
return c_str
? std::string( c_str )
: unknown_err;
# else
result = strerror_r( ev, bp, sz );
# endif
if (result == 0 )
break;
else
{
# if defined(__linux)
// Linux strerror_r returns -1 on error, with error number in errno
result = errno;
# endif
if ( result != ERANGE ) break;
if ( sz > sizeof(buf) ) std::free( bp );
sz *= 2;
if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
return std::string( "ENOMEM" );
}
}
std::string msg;
try
{
msg = ( ( result == invalid_argument ) ? "Unknown error" : bp );
}
# ifndef BOOST_NO_EXCEPTIONS
// See ticket #2098
catch(...)
{
// just eat the exception
}
# endif
if ( sz > sizeof(buf) ) std::free( bp );
sz = 0;
return msg;
# endif // else POSIX version of strerror_r
# endif // else use strerror_r
}
// system_error_category implementation --------------------------------//
const char * system_error_category::name() const
{
return "system";
}
error_condition system_error_category::default_error_condition( int ev ) const
{
switch ( ev )
{
case 0: return make_error_condition( success );
# if defined(BOOST_POSIX_API)
// POSIX-like O/S -> posix_errno decode table ---------------------------//
case E2BIG: return make_error_condition( argument_list_too_long );
case EACCES: return make_error_condition( permission_denied );
case EADDRINUSE: return make_error_condition( address_in_use );
case EADDRNOTAVAIL: return make_error_condition( address_not_available );
case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
case EAGAIN: return make_error_condition( resource_unavailable_try_again );
# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino
case EALREADY: return make_error_condition( connection_already_in_progress );
# endif
case EBADF: return make_error_condition( bad_file_descriptor );
case EBADMSG: return make_error_condition( bad_message );
case EBUSY: return make_error_condition( device_or_resource_busy );
case ECANCELED: return make_error_condition( operation_canceled );
case ECHILD: return make_error_condition( no_child_process );
case ECONNABORTED: return make_error_condition( connection_aborted );
case ECONNREFUSED: return make_error_condition( connection_refused );
case ECONNRESET: return make_error_condition( connection_reset );
case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
case EDESTADDRREQ: return make_error_condition( destination_address_required );
case EDOM: return make_error_condition( argument_out_of_domain );
case EEXIST: return make_error_condition( file_exists );
case EFAULT: return make_error_condition( bad_address );
case EFBIG: return make_error_condition( file_too_large );
case EHOSTUNREACH: return make_error_condition( host_unreachable );
case EIDRM: return make_error_condition( identifier_removed );
case EILSEQ: return make_error_condition( illegal_byte_sequence );
case EINPROGRESS: return make_error_condition( operation_in_progress );
case EINTR: return make_error_condition( interrupted );
case EINVAL: return make_error_condition( invalid_argument );
case EIO: return make_error_condition( io_error );
case EISCONN: return make_error_condition( already_connected );
case EISDIR: return make_error_condition( is_a_directory );
case ELOOP: return make_error_condition( too_many_synbolic_link_levels );
case EMFILE: return make_error_condition( too_many_files_open );
case EMLINK: return make_error_condition( too_many_links );
case EMSGSIZE: return make_error_condition( message_size );
case ENAMETOOLONG: return make_error_condition( filename_too_long );
case ENETDOWN: return make_error_condition( network_down );
case ENETRESET: return make_error_condition( network_reset );
case ENETUNREACH: return make_error_condition( network_unreachable );
case ENFILE: return make_error_condition( too_many_files_open_in_system );
case ENOBUFS: return make_error_condition( no_buffer_space );
case ENODATA: return make_error_condition( no_message_available );
case ENODEV: return make_error_condition( no_such_device );
case ENOENT: return make_error_condition( no_such_file_or_directory );
case ENOEXEC: return make_error_condition( executable_format_error );
case ENOLCK: return make_error_condition( no_lock_available );
case ENOLINK: return make_error_condition( no_link );
case ENOMEM: return make_error_condition( not_enough_memory );
case ENOMSG: return make_error_condition( no_message );
case ENOPROTOOPT: return make_error_condition( no_protocol_option );
case ENOSPC: return make_error_condition( no_space_on_device );
case ENOSR: return make_error_condition( no_stream_resources );
case ENOSTR: return make_error_condition( not_a_stream );
case ENOSYS: return make_error_condition( function_not_supported );
case ENOTCONN: return make_error_condition( not_connected );
case ENOTDIR: return make_error_condition( not_a_directory );
# if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
case ENOTEMPTY: return make_error_condition( directory_not_empty );
# endif // ENOTEMPTY != EEXIST
case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
case ENOTSOCK: return make_error_condition( not_a_socket );
case ENOTSUP: return make_error_condition( not_supported );
case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
case ENXIO: return make_error_condition( no_such_device_or_address );
# if EOPNOTSUPP != ENOTSUP
case EOPNOTSUPP: return make_error_condition( operation_not_supported );
# endif // EOPNOTSUPP != ENOTSUP
case EOVERFLOW: return make_error_condition( value_too_large );
case EOWNERDEAD: return make_error_condition( owner_dead );
case EPERM: return make_error_condition( operation_not_permitted );
case EPIPE: return make_error_condition( broken_pipe );
case EPROTO: return make_error_condition( protocol_error );
case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
case ERANGE: return make_error_condition( result_out_of_range );
case EROFS: return make_error_condition( read_only_file_system );
case ESPIPE: return make_error_condition( invalid_seek );
case ESRCH: return make_error_condition( no_such_process );
case ETIME: return make_error_condition( stream_timeout );
case ETIMEDOUT: return make_error_condition( timed_out );
case ETXTBSY: return make_error_condition( text_file_busy );
# if EAGAIN != EWOULDBLOCK
case EWOULDBLOCK: return make_error_condition( operation_would_block );
# endif // EAGAIN != EWOULDBLOCK
case EXDEV: return make_error_condition( cross_device_link );
#else
// Windows system -> posix_errno decode table ---------------------------//
// see WinError.h comments for descriptions of errors
case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
case ERROR_CANTOPEN: return make_error_condition( io_error );
case ERROR_CANTREAD: return make_error_condition( io_error );
case ERROR_CANTWRITE: return make_error_condition( io_error );
case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
case ERROR_LOCKED: return make_error_condition( no_lock_available );
case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
case ERROR_NOACCESS: return make_error_condition( permission_denied );
case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
case ERROR_OPEN_FAILED: return make_error_condition( io_error );
case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
case ERROR_READ_FAULT: return make_error_condition( io_error );
case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
case ERROR_SEEK: return make_error_condition( io_error );
case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
case ERROR_WRITE_FAULT: return make_error_condition( io_error );
case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
case WSAEACCES: return make_error_condition( permission_denied );
case WSAEADDRINUSE: return make_error_condition( address_in_use );
case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
case WSAEALREADY: return make_error_condition( connection_already_in_progress );
case WSAEBADF: return make_error_condition( bad_file_descriptor );
case WSAECONNABORTED: return make_error_condition( connection_aborted );
case WSAECONNREFUSED: return make_error_condition( connection_refused );
case WSAECONNRESET: return make_error_condition( connection_reset );
case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
case WSAEFAULT: return make_error_condition( bad_address );
case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
case WSAEINTR: return make_error_condition( interrupted );
case WSAEINVAL: return make_error_condition( invalid_argument );
case WSAEISCONN: return make_error_condition( already_connected );
case WSAEMFILE: return make_error_condition( too_many_files_open );
case WSAEMSGSIZE: return make_error_condition( message_size );
case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
case WSAENETDOWN: return make_error_condition( network_down );
case WSAENETRESET: return make_error_condition( network_reset );
case WSAENETUNREACH: return make_error_condition( network_unreachable );
case WSAENOBUFS: return make_error_condition( no_buffer_space );
case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
case WSAENOTCONN: return make_error_condition( not_connected );
case WSAENOTSOCK: return make_error_condition( not_a_socket );
case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
case WSAETIMEDOUT: return make_error_condition( timed_out );
case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
#endif
default: return error_condition( ev, system_category );
}
}
# if !defined( BOOST_WINDOWS_API )
std::string system_error_category::message( int ev ) const
{
return generic_category.message( ev );
}
# else
// TODO:
//Some quick notes on the implementation (sorry for the noise if
//someone has already mentioned them):
//
//- The ::LocalFree() usage isn't exception safe.
//
//See:
//
//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
//
//in the implementation of what() for an example.
//
//Cheers,
//Chris
std::string system_error_category::message( int ev ) const
{
# ifndef BOOST_NO_ANSI_APIS
LPVOID lpMsgBuf;
DWORD retval = ::FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
ev,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPSTR) &lpMsgBuf,
0,
NULL
);
if (retval == 0)
return std::string("Unknown error");
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
::LocalFree( lpMsgBuf ); // free the buffer
# else // WinCE workaround
LPVOID lpMsgBuf;
DWORD retval = ::FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
ev,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPWSTR) &lpMsgBuf,
0,
NULL
);
if (retval == 0)
return std::string("Unknown error");
int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
return std::string("Unknown error");
std::string str( narrow_buffer );
::LocalFree( lpMsgBuf ); // free the buffer
# endif
while ( str.size()
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
str.erase( str.size()-1 );
if ( str.size() && str[str.size()-1] == '.' )
{ str.erase( str.size()-1 ); }
return str;
}
# endif
} // unnamed namespace
namespace boost
{
namespace system
{
BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code;
// note that it doesn't matter if this
// isn't initialized before use since
// the only use is to take its
// address for comparison purposes
BOOST_SYSTEM_DECL const error_category & get_system_category()
{
static const system_error_category system_category_const;
return system_category_const;
}
BOOST_SYSTEM_DECL const error_category & get_generic_category()
{
static const generic_error_category generic_category_const;
return generic_category_const;
}
} // namespace system
} // namespace boost

View File

@@ -0,0 +1,506 @@
// boost/system/error_code.hpp ---------------------------------------------//
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
#ifndef BOOST_ERROR_CODE_HPP
#define BOOST_ERROR_CODE_HPP
#include <boost/system/config.hpp>
//#include <boost/cstdint.hpp>
//#include <boost/assert.hpp>
//#include <boost/operators.hpp>
//#include <boost/noncopyable.hpp>
//#include <boost/utility/enable_if.hpp>
#include <ostream>
#include <string>
#include <stdexcept>
#include <functional>
// TODO: undef these macros if not already defined
#include <boost/cerrno.hpp>
#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API)
# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined
#endif
// #include <boost/config/abi_prefix.hpp> // must be the last #include
namespace boost
{
namespace system
{
class error_code;
class error_condition;
// "Concept" helpers ---------------------------------------------------//
template< class T >
struct is_error_code_enum { static const bool value = false; };
template< class T >
struct is_error_condition_enum { static const bool value = false; };
// generic error_conditions --------------------------------------------//
namespace errc
{
enum errc_t
{
success = 0,
address_family_not_supported = EAFNOSUPPORT,
address_in_use = EADDRINUSE,
address_not_available = EADDRNOTAVAIL,
already_connected = EISCONN,
argument_list_too_long = E2BIG,
argument_out_of_domain = EDOM,
bad_address = EFAULT,
bad_file_descriptor = EBADF,
bad_message = EBADMSG,
broken_pipe = EPIPE,
connection_aborted = ECONNABORTED,
connection_already_in_progress = EALREADY,
connection_refused = ECONNREFUSED,
connection_reset = ECONNRESET,
cross_device_link = EXDEV,
destination_address_required = EDESTADDRREQ,
device_or_resource_busy = EBUSY,
directory_not_empty = ENOTEMPTY,
executable_format_error = ENOEXEC,
file_exists = EEXIST,
file_too_large = EFBIG,
filename_too_long = ENAMETOOLONG,
function_not_supported = ENOSYS,
host_unreachable = EHOSTUNREACH,
identifier_removed = EIDRM,
illegal_byte_sequence = EILSEQ,
inappropriate_io_control_operation = ENOTTY,
interrupted = EINTR,
invalid_argument = EINVAL,
invalid_seek = ESPIPE,
io_error = EIO,
is_a_directory = EISDIR,
message_size = EMSGSIZE,
network_down = ENETDOWN,
network_reset = ENETRESET,
network_unreachable = ENETUNREACH,
no_buffer_space = ENOBUFS,
no_child_process = ECHILD,
no_link = ENOLINK,
no_lock_available = ENOLCK,
no_message_available = ENODATA,
no_message = ENOMSG,
no_protocol_option = ENOPROTOOPT,
no_space_on_device = ENOSPC,
no_stream_resources = ENOSR,
no_such_device_or_address = ENXIO,
no_such_device = ENODEV,
no_such_file_or_directory = ENOENT,
no_such_process = ESRCH,
not_a_directory = ENOTDIR,
not_a_socket = ENOTSOCK,
not_a_stream = ENOSTR,
not_connected = ENOTCONN,
not_enough_memory = ENOMEM,
not_supported = ENOTSUP,
operation_canceled = ECANCELED,
operation_in_progress = EINPROGRESS,
operation_not_permitted = EPERM,
operation_not_supported = EOPNOTSUPP,
operation_would_block = EWOULDBLOCK,
owner_dead = EOWNERDEAD,
permission_denied = EACCES,
protocol_error = EPROTO,
protocol_not_supported = EPROTONOSUPPORT,
read_only_file_system = EROFS,
resource_deadlock_would_occur = EDEADLK,
resource_unavailable_try_again = EAGAIN,
result_out_of_range = ERANGE,
state_not_recoverable = ENOTRECOVERABLE,
stream_timeout = ETIME,
text_file_busy = ETXTBSY,
timed_out = ETIMEDOUT,
too_many_files_open_in_system = ENFILE,
too_many_files_open = EMFILE,
too_many_links = EMLINK,
too_many_synbolic_link_levels = ELOOP,
value_too_large = EOVERFLOW,
wrong_protocol_type = EPROTOTYPE
};
} // namespace errc
# ifndef BOOST_SYSTEM_NO_DEPRECATED
namespace posix = errc;
namespace posix_error = errc;
# endif
template<> struct is_error_condition_enum<errc::errc_t>
{ static const bool value = true; };
// ----------------------------------------------------------------------//
// Operating system specific interfaces --------------------------------//
// The interface is divided into general and system-specific portions to
// meet these requirements:
//
// * Code calling an operating system API can create an error_code with
// a single category (system_category), even for POSIX-like operating
// systems that return some POSIX errno values and some native errno
// values. This code should not have to pay the cost of distinguishing
// between categories, since it is not yet known if that is needed.
//
// * Users wishing to write system-specific code should be given enums for
// at least the common error cases.
//
// * System specific code should fail at compile time if moved to another
// operating system.
// The system specific portions of the interface are located in headers
// with names reflecting the operating system. For example,
//
// <boost/system/cygwin_error.hpp>
// <boost/system/linux_error.hpp>
// <boost/system/windows_error.hpp>
//
// These headers are effectively empty for compiles on operating systems
// where they are not applicable.
// ----------------------------------------------------------------------//
// class error_category ------------------------------------------------//
class error_category // : public noncopyable
{
public:
error_category() {}
virtual ~error_category(){}
virtual inline const char * name() const; // see implementation note below
virtual inline std::string message( int ev ) const; // see implementation note below
virtual inline error_condition default_error_condition( int ev ) const;
virtual inline bool equivalent( int code, const error_condition & condition ) const;
virtual inline bool equivalent( const error_code & code, int condition ) const;
bool operator==(const error_category & rhs) const { return this == &rhs; }
bool operator!=(const error_category & rhs) const { return this != &rhs; }
bool operator<( const error_category & rhs ) const
{
return std::less<const error_category*>()( this, &rhs );
}
private:
//non-copyable
error_category(const error_category& );
error_category& operator=(const error_category& );
};
// predefined error categories -----------------------------------------//
BOOST_SYSTEM_DECL const error_category & get_system_category();
BOOST_SYSTEM_DECL const error_category & get_generic_category();
static const error_category & system_category = get_system_category();
static const error_category & generic_category = get_generic_category();
# ifndef BOOST_SYSTEM_NO_DEPRECATED
// deprecated synonyms
inline const error_category & get_posix_category() { return get_generic_category(); }
static const error_category & posix_category = get_generic_category();
static const error_category & errno_ecat = get_generic_category();
static const error_category & native_ecat = get_system_category();
# endif
// class error_condition -----------------------------------------------//
// error_conditions are portable, error_codes are system or library specific
class error_condition
{
public:
// constructors:
error_condition() : m_val(0), m_cat(&get_generic_category()) {}
error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}
//template <class ErrorConditionEnum>
// error_condition(ErrorConditionEnum e,
// typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0)
//{
// *this = make_error_condition(e);
//}
// modifiers:
void assign( int val, const error_category & cat )
{
m_val = val;
m_cat = &cat;
}
//template<typename ErrorConditionEnum>
// typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type &
// operator=( ErrorConditionEnum val )
//{
// *this = make_error_condition(val);
// return *this;
//}
void clear()
{
m_val = 0;
m_cat = &get_generic_category();
}
// observers:
int value() const { return m_val; }
const error_category & category() const { return *m_cat; }
std::string message() const { return m_cat->message(value()); }
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
operator unspecified_bool_type() const // true if error
{
return m_val == 0 ? 0 : unspecified_bool_true;
}
bool operator!() const // true if no error
{
return m_val == 0;
}
// relationals:
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
inline friend bool operator==( const error_condition & lhs,
const error_condition & rhs )
{
return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
}
inline friend bool operator<( const error_condition & lhs,
const error_condition & rhs )
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
{
return lhs.m_cat < rhs.m_cat
|| (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
}
private:
int m_val;
const error_category * m_cat;
};
// class error_code ----------------------------------------------------//
// We want error_code to be a value type that can be copied without slicing
// and without requiring heap allocation, but we also want it to have
// polymorphic behavior based on the error category. This is achieved by
// abstract base class error_category supplying the polymorphic behavior,
// and error_code containing a pointer to an object of a type derived
// from error_category.
class error_code
{
public:
// constructors:
error_code() : m_val(0), m_cat(&get_system_category()) {}
error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}
//template <class ErrorCodeEnum>
// error_code(ErrorCodeEnum e,
// typename boost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0)
//{
// *this = make_error_code(e);
//}
// modifiers:
void assign( int val, const error_category & cat )
{
m_val = val;
m_cat = &cat;
}
//template<typename ErrorCodeEnum>
// typename boost::enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type &
// operator=( ErrorCodeEnum val )
//{
// *this = make_error_code(val);
// return *this;
//}
void clear()
{
m_val = 0;
m_cat = &get_system_category();
}
// observers:
int value() const { return m_val; }
const error_category & category() const { return *m_cat; }
error_condition default_error_condition() const { return m_cat->default_error_condition(value()); }
std::string message() const { return m_cat->message(value()); }
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
operator unspecified_bool_type() const // true if error
{
return m_val == 0 ? 0 : unspecified_bool_true;
}
bool operator!() const // true if no error
{
return m_val == 0;
}
// relationals:
inline friend bool operator==( const error_code & lhs,
const error_code & rhs )
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
{
return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
}
inline friend bool operator<( const error_code & lhs,
const error_code & rhs )
// the more symmetrical non-member syntax allows enum
// conversions work for both rhs and lhs.
{
return lhs.m_cat < rhs.m_cat
|| (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
}
private:
int m_val;
const error_category * m_cat;
};
// predefined error_code object used as "throw on error" tag
BOOST_SYSTEM_DECL extern error_code throws;
// non-member functions ------------------------------------------------//
inline bool operator!=( const error_code & lhs,
const error_code & rhs )
{
return !(lhs == rhs);
}
inline bool operator!=( const error_condition & lhs,
const error_condition & rhs )
{
return !(lhs == rhs);
}
inline bool operator==( const error_code & code,
const error_condition & condition )
{
return code.category().equivalent( code.value(), condition )
|| condition.category().equivalent( code, condition.value() );
}
inline bool operator!=( const error_code & lhs,
const error_condition & rhs )
{
return !(lhs == rhs);
}
inline bool operator==( const error_condition & condition,
const error_code & code )
{
return condition.category().equivalent( code, condition.value() )
|| code.category().equivalent( code.value(), condition );
}
inline bool operator!=( const error_condition & lhs,
const error_code & rhs )
{
return !(lhs == rhs);
}
// TODO: both of these may move elsewhere, but the LWG hasn't spoken yet.
template <class charT, class traits>
inline std::basic_ostream<charT,traits>&
operator<< (std::basic_ostream<charT,traits>& os, error_code ec)
{
os << ec.category().name() << ':' << ec.value();
return os;
}
inline std::size_t hash_value( const error_code & ec )
{
return static_cast<std::size_t>(ec.value())
+ reinterpret_cast<std::size_t>(&ec.category());
}
// make_* functions for errc::errc_t -----------------------------//
namespace errc
{
// explicit conversion:
inline error_code make_error_code( errc_t e )
{ return error_code( e, get_generic_category() ); }
// implicit conversion:
inline error_condition make_error_condition( errc_t e )
{ return error_condition( e, get_generic_category() ); }
}
// error_category default implementation -------------------------------//
inline error_condition error_category::default_error_condition( int ev ) const
{
return error_condition( ev, *this );
}
inline bool error_category::equivalent( int code,
const error_condition & condition ) const
{
return default_error_condition( code ) == condition;
}
inline bool error_category::equivalent( const error_code & code,
int condition ) const
{
return *this == code.category() && code.value() == condition;
}
// error_category implementation note: VC++ 8.0 objects to name() and
// message() being pure virtual functions. Thus these implementations.
inline const char * error_category::name() const
{
return "error: should never be called";
}
inline std::string error_category::message( int ) const
{
static std::string s("error: should never be called");
return s;
}
} // namespace system
} // namespace boost
//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
# ifdef BOOST_ERROR_CODE_HEADER_ONLY
# include <boost/../libs/system/src/error_code.cpp>
# endif
#endif // BOOST_ERROR_CODE_HPP

View File

@@ -0,0 +1,110 @@
// boost/system/linux_error.hpp -------------------------------------------//
// Copyright Beman Dawes 2007
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
#ifndef BOOST_LINUX_ERROR_HPP
#define BOOST_LINUX_ERROR_HPP
// This header is effectively empty for compiles on operating systems where
// it is not applicable.
#if defined(linux) || defined(__linux) || defined(__linux__)
#include <boost/system/error_code.hpp>
namespace boost
{
namespace system
{
// To construct an error_code after a API error:
//
// error_code( errno, system_category )
// User code should use the portable "posix" enums for POSIX errors; this
// allows such code to be portable to non-POSIX systems. For the non-POSIX
// errno values that POSIX-based systems typically provide in addition to
// POSIX values, use the system specific enums below.
namespace linux_error
{
enum linux_errno
{
advertise_error = EADV,
bad_exchange = EBADE,
bad_file_number = EBADFD,
bad_font_format = EBFONT,
bad_request_code = EBADRQC,
bad_request_descriptor = EBADR,
bad_slot = EBADSLT,
channel_range = ECHRNG,
communication_error = ECOMM,
dot_dot_error = EDOTDOT,
exchange_full = EXFULL,
host_down = EHOSTDOWN,
is_named_file_type= EISNAM,
key_expired = EKEYEXPIRED,
key_rejected = EKEYREJECTED,
key_revoked = EKEYREVOKED,
level2_halt= EL2HLT,
level2_no_syncronized= EL2NSYNC,
level3_halt = EL3HLT,
level3_reset = EL3RST,
link_range = ELNRNG,
medium_type = EMEDIUMTYPE,
no_anode= ENOANO,
no_block_device = ENOTBLK,
no_csi = ENOCSI,
no_key = ENOKEY,
no_medium = ENOMEDIUM,
no_network = ENONET,
no_package = ENOPKG,
not_avail = ENAVAIL,
not_named_file_type= ENOTNAM,
not_recoverable = ENOTRECOVERABLE,
not_unique = ENOTUNIQ,
owner_dead = EOWNERDEAD,
protocol_no_supported = EPFNOSUPPORT,
remote_address_changed = EREMCHG,
remote_io_error = EREMOTEIO,
remote_object = EREMOTE,
restart_needed = ERESTART,
shared_library_access = ELIBACC,
shared_library_bad = ELIBBAD,
shared_library_execute = ELIBEXEC,
shared_library_max_ = ELIBMAX,
shared_library_section= ELIBSCN,
shutdown = ESHUTDOWN,
socket_type_not_supported = ESOCKTNOSUPPORT,
srmount_error = ESRMNT,
stream_pipe_error = ESTRPIPE,
too_many_references = ETOOMANYREFS,
too_many_users = EUSERS,
unattached = EUNATCH,
unclean = EUCLEAN
};
} // namespace linux_error
# ifndef BOOST_SYSTEM_NO_DEPRECATED
namespace Linux = linux_error;
# endif
template<> struct is_error_code_enum<linux_error::linux_errno>
{ static const bool value = true; };
namespace linux_error
{
inline error_code make_error_code( linux_errno e )
{ return error_code( e, get_system_category() ); }
}
} // namespace system
} // namespace boost
#endif // Linux
#endif // BOOST_LINUX_ERROR_HPP

View File

@@ -0,0 +1 @@
SRC += system/error_code.cpp

View File

@@ -0,0 +1,81 @@
// Boost system_error.hpp --------------------------------------------------//
// Copyright Beman Dawes 2006
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_SYSTEM_ERROR_HPP
#define BOOST_SYSTEM_ERROR_HPP
#include <string>
#include <stdexcept>
#include <cassert>
#include <boost/system/error_code.hpp>
namespace boost
{
namespace system
{
// class system_error --------------------------------------------------//
class system_error : public std::runtime_error
{
public:
system_error( error_code ec )
: std::runtime_error(""), m_error_code(ec) {}
system_error( error_code ec, const std::string & what_arg )
: std::runtime_error(what_arg), m_error_code(ec) {}
system_error( error_code ec, const char* what_arg )
: std::runtime_error(what_arg), m_error_code(ec) {}
system_error( int ev, const error_category & ecat )
: std::runtime_error(""), m_error_code(ev,ecat) {}
system_error( int ev, const error_category & ecat,
const std::string & what_arg )
: std::runtime_error(what_arg), m_error_code(ev,ecat) {}
system_error( int ev, const error_category & ecat,
const char * what_arg )
: std::runtime_error(what_arg), m_error_code(ev,ecat) {}
virtual ~system_error() throw() {}
const error_code & code() const throw() { return m_error_code; }
const char * what() const throw();
private:
error_code m_error_code;
mutable std::string m_what;
};
// implementation ------------------------------------------------------//
inline const char * system_error::what() const throw()
// see http://www.boost.org/more/error_handling.html for lazy build rationale
{
if ( m_what.empty() )
{
try
{
m_what = this->std::runtime_error::what();
if ( m_error_code )
{
if ( !m_what.empty() ) m_what += ": ";
m_what += m_error_code.message();
}
}
catch (...) { return std::runtime_error::what(); }
}
return m_what.c_str();
}
} // namespace system
} // namespace boost
#endif // BOOST_SYSTEM_ERROR_HPP

View File

@@ -0,0 +1,118 @@
// boost/system/windows_error.hpp ------------------------------------------//
// Copyright Beman Dawes 2007
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/system
#ifndef BOOST_WINDOWS_ERROR_HPP
#define BOOST_WINDOWS_ERROR_HPP
// This header is effectively empty for compiles on operating systems where
// it is not applicable.
#include <boost/system/config.hpp>
#ifdef BOOST_WINDOWS_API
#include <boost/system/error_code.hpp>
#include <winerror.h>
namespace boost
{
namespace system
{
// Microsoft Windows ---------------------------------------------------//
// To construct an error_code after a API error:
//
// error_code( ::GetLastError(), system_category )
namespace windows_error
{
enum windows_error_code
{
success = 0,
// These names and values are based on Windows winerror.h
invalid_function = ERROR_INVALID_FUNCTION,
file_not_found = ERROR_FILE_NOT_FOUND,
path_not_found = ERROR_PATH_NOT_FOUND,
too_many_open_files = ERROR_TOO_MANY_OPEN_FILES,
access_denied = ERROR_ACCESS_DENIED,
invalid_handle = ERROR_INVALID_HANDLE,
arena_trashed = ERROR_ARENA_TRASHED,
not_enough_memory = ERROR_NOT_ENOUGH_MEMORY,
invalid_block = ERROR_INVALID_BLOCK,
bad_environment = ERROR_BAD_ENVIRONMENT,
bad_format = ERROR_BAD_FORMAT,
invalid_access = ERROR_INVALID_ACCESS,
outofmemory = ERROR_OUTOFMEMORY,
invalid_drive = ERROR_INVALID_DRIVE,
current_directory = ERROR_CURRENT_DIRECTORY,
not_same_device = ERROR_NOT_SAME_DEVICE,
no_more_files = ERROR_NO_MORE_FILES,
write_protect = ERROR_WRITE_PROTECT,
bad_unit = ERROR_BAD_UNIT,
not_ready = ERROR_NOT_READY,
bad_command = ERROR_BAD_COMMAND,
crc = ERROR_CRC,
bad_length = ERROR_BAD_LENGTH,
seek = ERROR_SEEK,
not_dos_disk = ERROR_NOT_DOS_DISK,
sector_not_found = ERROR_SECTOR_NOT_FOUND,
out_of_paper = ERROR_OUT_OF_PAPER,
write_fault = ERROR_WRITE_FAULT,
read_fault = ERROR_READ_FAULT,
gen_failure = ERROR_GEN_FAILURE,
sharing_violation = ERROR_SHARING_VIOLATION,
lock_violation = ERROR_LOCK_VIOLATION,
wrong_disk = ERROR_WRONG_DISK,
sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED,
handle_eof = ERROR_HANDLE_EOF,
handle_disk_full= ERROR_HANDLE_DISK_FULL,
rem_not_list = ERROR_REM_NOT_LIST,
dup_name = ERROR_DUP_NAME,
bad_net_path = ERROR_BAD_NETPATH,
network_busy = ERROR_NETWORK_BUSY,
// ...
file_exists = ERROR_FILE_EXISTS,
cannot_make = ERROR_CANNOT_MAKE,
// ...
broken_pipe = ERROR_BROKEN_PIPE,
open_failed = ERROR_OPEN_FAILED,
buffer_overflow = ERROR_BUFFER_OVERFLOW,
disk_full= ERROR_DISK_FULL,
// ...
lock_failed = ERROR_LOCK_FAILED,
busy = ERROR_BUSY,
cancel_violation = ERROR_CANCEL_VIOLATION,
already_exists = ERROR_ALREADY_EXISTS
// ...
// TODO: add more Windows errors
};
} // namespace windows
# ifndef BOOST_SYSTEM_NO_DEPRECATED
namespace windows = windows_error;
# endif
template<> struct is_error_code_enum<windows_error::windows_error_code>
{ static const bool value = true; };
namespace windows_error
{
inline error_code make_error_code( windows_error_code e )
{ return error_code( e, get_system_category() ); }
}
} // namespace system
} // namespace boost
#endif // BOOST_WINDOWS_API
#endif // BOOST_WINDOWS_ERROR_HPP

View File

@@ -0,0 +1,99 @@
// $Id: exception.hpp 1107 2012-11-06 08:40:41Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_EXCEPTION_HPP
#define NRLIB_EXCEPTION_HPP
#include <exception>
#include <string>
//Test: Information flows from external back to original?
//Test: And of course it flows downwards?
namespace NRLib {
class Exception : public std::exception
{
public:
explicit Exception(const std::string& msg = "") : msg_(msg) { }
virtual ~Exception() throw() {}
virtual const char * what() const throw() {return msg_.c_str();}
private:
std::string msg_;
};
class IndexOutOfRange : public Exception
{
public:
explicit IndexOutOfRange(const std::string& msg = "")
: Exception(msg) {}
virtual ~IndexOutOfRange() throw() {}
};
class FFTError : public Exception
{
public:
explicit FFTError(const std::string& msg = "")
: Exception(msg) {}
virtual ~FFTError() throw() {}
};
class IOError : public Exception
{
public:
explicit IOError(const std::string& msg = "")
: Exception(msg) {}
virtual ~IOError() throw() {}
};
class FileFormatError : public IOError
{
public:
explicit FileFormatError(const std::string& msg = "")
: IOError(msg) {}
virtual ~FileFormatError() throw() {}
};
class EndOfFile : public IOError
{
public:
explicit EndOfFile(const std::string& msg = "")
: IOError(msg) {}
virtual ~EndOfFile() throw() {}
};
class JobCanceled : public Exception
{
public:
explicit JobCanceled(const std::string& msg = "")
: Exception(msg) {}
virtual ~JobCanceled() throw() {}
};
}
#endif

271
ThirdParty/NRLib/nrlib/grid/grid.hpp vendored Normal file
View File

@@ -0,0 +1,271 @@
// $Id: grid.hpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_GRID_HPP
#define NRLIB_GRID_HPP
#include <cassert>
#include <sstream>
#include <vector>
#include <limits>
//#include "../../../src/definitions.h"
namespace NRLib {
template<class A>
class Grid {
public:
typedef typename std::vector<A>::iterator iterator;
typedef typename std::vector<A>::const_iterator const_iterator;
typedef typename std::vector<A>::reference reference;
typedef typename std::vector<A>::const_reference const_reference;
Grid();
/// \param val Initial cell value.
Grid(size_t ni, size_t nj, size_t nk, const A& val = A());
virtual ~Grid();
/// All values in the grid are erased when the grid is
/// resized.
/// \param val Initial cell value.
void Resize(size_t ni, size_t nj, size_t nk, const A& val = A());
void GetAvgMinMax(A& avg, A& min, A& max);
void GetAvgMinMaxWithMissing(A& avg, A& min, A& max, A missing);
void LogTransform(A missing);
inline reference operator()(size_t i, size_t j, size_t k);
inline reference operator()(size_t index);
inline reference GetValue(size_t i, size_t j, size_t k);
inline const_reference operator()(size_t i, size_t j, size_t k) const;
inline const_reference operator()(size_t index) const;
inline const_reference GetValue(size_t i, size_t j, size_t k) const;
iterator begin() {return( data_.begin()); }
iterator end() {return( data_.end()); }
const_iterator begin() const { return(data_.begin()); }
const_iterator end() const { return(data_.end()); }
size_t GetNI() const { return(ni_); }
size_t GetNJ() const { return(nj_); }
size_t GetNK() const { return(nk_); }
size_t GetN() const { return data_.size(); }
inline size_t GetIndex(size_t i, size_t j, size_t k) const;
void GetIJK(size_t index, size_t &i, size_t &j, size_t &k) const;
void SetValue(size_t i, size_t j, size_t k, const A& value);
void Swap(Grid<A>& other);
private:
size_t ni_;
size_t nj_;
size_t nk_;
/// The grid data, column-major ordering.
std::vector<A> data_;
};
template<class A>
Grid<A>::Grid()
: ni_(0),
nj_(0),
nk_(0),
data_()
{}
template<class A>
Grid<A>::Grid(size_t ni, size_t nj, size_t nk, const A& val)
: ni_(ni),
nj_(nj),
nk_(nk),
data_(ni*nj*nk, val)
{}
template<class A>
Grid<A>::~Grid()
{}
template<class A>
void Grid<A>::Resize(size_t ni, size_t nj, size_t nk, const A& val)
{
ni_ = ni;
nj_ = nj;
nk_ = nk;
data_.resize(0); //To avoid copying of elements
data_.resize(ni_ * nj_ * nk_, val);
}
template<class A>
void Grid<A>::GetAvgMinMax(A& avg, A& min, A& max)
{
A sum = 0.0;
A value = 0.0;
max = -std::numeric_limits<A>::infinity();
min = +std::numeric_limits<A>::infinity();
for(unsigned int i = 0; i < ni_; i++) {
for(unsigned int j = 0; j < nj_; j++) {
for(unsigned int k = 0; k < nk_; k++) {
value = data_[GetIndex(i, j, k)];
sum += value;
if(value > max)
max = value;
if(value < min)
min = value;
}
}
}
avg = sum /= GetN();
}
template<class A>
void Grid<A>::GetAvgMinMaxWithMissing(A& avg, A& min, A& max, A missing)
{
A sum = 0.0;
A value = 0.0;
max = -std::numeric_limits<A>::infinity();
min = +std::numeric_limits<A>::infinity();
unsigned int n = 0;
for(unsigned int i = 0; i < ni_; i++) {
for(unsigned int j = 0; j < nj_; j++) {
for(unsigned int k = 0; k < nk_; k++) {
value = data_[GetIndex(i, j, k)];
if(value != missing) {
sum += value;
n++;
if(value > max)
max = value;
if(value < min)
min = value;
}
}
}
}
avg = sum/static_cast<A>(n);
}
template<class A>
void Grid<A>::LogTransform(A missing)
{
for(size_t i = 0; i < ni_; i++) {
for(size_t j = 0; j < nj_; j++) {
for(size_t k = 0; k < nk_; k++) {
A value = data_[GetIndex(i, j, k)];
if(value == missing || value <= 0.0) //First RMISSING
data_[GetIndex(i, j, k)] = 0.0;
else
data_[GetIndex(i, j, k)] = log(value);
}
}
}
}
template<class A>
typename Grid<A>::reference Grid<A>::operator()(size_t i, size_t j, size_t k)
{
return data_[GetIndex(i, j, k)];
}
template<class A>
typename Grid<A>::reference Grid<A>::operator()(size_t index)
{
assert(index < GetN());
return data_[index];
}
template<class A>
typename Grid<A>::reference Grid<A>::GetValue(size_t i, size_t j, size_t k)
{
return data_[GetIndex(i, j, k)];
}
template<class A>
typename Grid<A>::const_reference Grid<A>::operator()(size_t i, size_t j, size_t k) const
{
return data_[GetIndex(i, j, k)];
}
template<class A>
typename Grid<A>::const_reference Grid<A>::operator()(size_t index) const
{
assert(index < GetN());
return data_[index];
}
template<class A>
typename Grid<A>::const_reference Grid<A>::GetValue(size_t i, size_t j, size_t k) const
{
return data_[GetIndex(i, j, k)];
}
template<class A>
size_t Grid<A>::GetIndex(size_t i, size_t j, size_t k) const
{
assert(i < GetNI() && j < GetNJ() && k < GetNK());
return i + j*ni_ + k*ni_*nj_;
}
template<class A>
void Grid<A>::GetIJK(size_t index, size_t &i, size_t &j, size_t &k) const
{
assert(index < GetN());
i = index % ni_;
j = (index-i)/ni_ % nj_;
k = (index - j*ni_ - i)/ni_/nj_;
}
template<class A>
void Grid<A>::SetValue(size_t i, size_t j, size_t k, const A& value)
{
data_[GetIndex(i, j, k)] = value;
}
template<class A>
void Grid<A>::Swap(NRLib::Grid<A> &other)
{
std::swap(ni_, other.ni_);
std::swap(nj_, other.nj_);
std::swap(nk_, other.nk_);
data_.swap(other.data_);
}
}
#endif

207
ThirdParty/NRLib/nrlib/grid/grid2d.hpp vendored Normal file
View File

@@ -0,0 +1,207 @@
// $Id: grid2d.hpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_GRID2D_HPP
#define NRLIB_GRID2D_HPP
#include <cassert>
#include <sstream>
#include <vector>
namespace NRLib {
template<class A>
class Grid2D {
public:
typedef typename std::vector<A>::iterator iterator;
typedef typename std::vector<A>::const_iterator const_iterator;
typedef typename std::vector<A>::reference reference;
typedef typename std::vector<A>::const_reference const_reference;
Grid2D();
/// \param val Initial cell value.
Grid2D(size_t ni, size_t nj, const A& val = A());
virtual ~Grid2D();
/// All values in the grid are erased when the grid is
/// resized.
/// \param val Initial cell value.
virtual void Resize(size_t ni, size_t nj, const A& val = A());
inline reference operator()(size_t i, size_t j);
inline reference operator()(size_t index);
inline const_reference operator()(size_t i, size_t j) const;
inline const_reference operator()(size_t index) const;
iterator begin() { return data_.begin(); }
iterator end() { return data_.end(); }
const_iterator begin() const { return data_.begin(); }
const_iterator end() const { return data_.end(); }
size_t GetNI() const { return ni_; }
size_t GetNJ() const { return nj_; }
size_t GetN() const { return data_.size(); }
inline size_t GetIndex(size_t i, size_t j) const;
void GetIJ(size_t index, size_t &i, size_t &j) const;
bool IsValidIndex(int i, int j) const;
void Swap(Grid2D<A>& other);
A FindMin(A missingValue) const;
A FindMax(A missingValue) const;
private:
size_t ni_;
size_t nj_;
/// The grid data, column-major ordering.
std::vector<A> data_;
};
template<class A>
Grid2D<A>::Grid2D()
: ni_(0),
nj_(0),
data_()
{}
template<class A>
Grid2D<A>::Grid2D(size_t ni, size_t nj, const A& val)
: ni_(ni),
nj_(nj),
data_(ni*nj, val)
{}
template<class A>
Grid2D<A>::~Grid2D()
{}
template<class A>
void Grid2D<A>::Resize(size_t ni, size_t nj, const A& val)
{
ni_ = ni;
nj_ = nj;
data_.resize(0); //To avoid copying of elements
data_.resize(ni_ * nj_, val);
}
template<class A>
typename Grid2D<A>::reference Grid2D<A>::operator()(size_t i, size_t j)
{
return(data_[GetIndex(i, j)]);
}
template<class A>
typename Grid2D<A>::reference Grid2D<A>::operator()(size_t index)
{
assert(index < GetN());
return(data_[index]);
}
template<class A>
typename Grid2D<A>::const_reference Grid2D<A>::operator()(size_t i, size_t j) const
{
return(data_[GetIndex(i, j)]);
}
template<class A>
typename Grid2D<A>::const_reference Grid2D<A>::operator()(size_t index) const
{
assert(index < GetN());
return(data_[index]);
}
template<class A>
size_t Grid2D<A>::GetIndex(size_t i, size_t j) const
{
assert(i < ni_);
assert(j < nj_);
return(i+j*ni_);
}
template<class A>
void Grid2D<A>::GetIJ(size_t index, size_t &i, size_t &j) const
{
assert (index < GetN());
i = (index % ni_);
j = ((index-i)/ni_ % nj_);
}
template<class A>
bool Grid2D<A>::IsValidIndex(int i, int j) const
{
if (i >= 0 && static_cast<size_t>(i) < ni_ &&
j >= 0 && static_cast<size_t>(j) < nj_)
return true;
return false;
}
template<class A>
void Grid2D<A>::Swap(NRLib::Grid2D<A> &other)
{
std::swap(ni_, other.ni_);
std::swap(nj_, other.nj_);
data_.swap(other.data_);
}
template<class A>
A Grid2D<A>::FindMin(A missingValue) const
{
A minVal = (*this)(0);
typename std::vector<A>::const_iterator i;
for (i = this->begin(); i < this->end(); i++) {
if ((minVal == missingValue || (*i) < minVal) && (*i) != missingValue)
minVal = *i;
}
return minVal;
}
template<class A>
A Grid2D<A>::FindMax(A missingValue) const
{
A maxVal = (*this)(0);
typename std::vector<A>::const_iterator i;
for (i = this->begin(); i < this->end(); i++) {
if ((maxVal == missingValue || (*i) > maxVal) && (*i) != missingValue)
maxVal = *i;
}
return maxVal;
}
} // namespace NRLib
#endif // NRLIB_GRID2D_HPP

186
ThirdParty/NRLib/nrlib/grid/grid4d.hpp vendored Normal file
View File

@@ -0,0 +1,186 @@
// $Id: grid4d.hpp 1142 2013-03-18 15:13:41Z hgolsen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_GRID4D_HPP
#define NRLIB_GRID4D_HPP
#include <cassert>
#include <sstream>
#include <vector>
namespace NRLib {
template<class A>
class Grid4D {
public:
typedef typename std::vector<A>::iterator iterator;
typedef typename std::vector<A>::const_iterator const_iterator;
typedef typename std::vector<A>::reference reference;
typedef typename std::vector<A>::const_reference const_reference;
Grid4D();
/// \param val Initial cell value.
Grid4D(size_t ni, size_t nj, size_t nk, size_t nl, const A& val = A());
virtual ~Grid4D();
/// All values in the grid are erased when the grid is
/// resized.
/// \param val Initial cell value.
void Resize(size_t ni, size_t nj, size_t nk, size_t nl, const A& val = A());
inline reference operator()(size_t i, size_t j, size_t k, size_t l);
inline reference operator()(size_t index);
inline const_reference operator()(size_t i, size_t j, size_t k, size_t l) const;
inline const_reference operator()(size_t index) const;
iterator begin() {return( data_.begin()); }
iterator end() {return( data_.end()); }
const_iterator begin() const { return(data_.begin()); }
const_iterator end() const { return(data_.end()); }
size_t GetNI() const { return(ni_); }
size_t GetNJ() const { return(nj_); }
size_t GetNK() const { return(nk_); }
size_t GetNL() const { return(nl_); }
size_t GetN() const { return data_.size(); }
inline size_t GetIndex(size_t i, size_t j, size_t k, size_t l) const;
void GetIJKL(size_t index, size_t &i, size_t &j, size_t &k, size_t &l) const;
void Swap(Grid4D<A>& other);
private:
size_t ni_;
size_t nj_;
size_t nk_;
size_t nl_;
/// The grid data, column-major ordering.
std::vector<A> data_;
};
template<class A>
Grid4D<A>::Grid4D()
: ni_(0),
nj_(0),
nk_(0),
nl_(0),
data_()
{}
template<class A>
Grid4D<A>::Grid4D(size_t ni, size_t nj, size_t nk, size_t nl, const A& val)
: ni_(ni),
nj_(nj),
nk_(nk),
nl_(nl),
data_(ni*nj*nk*nl, val)
{}
template<class A>
Grid4D<A>::~Grid4D()
{}
template<class A>
void Grid4D<A>::Resize(size_t ni, size_t nj, size_t nk, size_t nl, const A& val)
{
ni_ = ni;
nj_ = nj;
nk_ = nk;
nl_ = nl;
data_.resize(0); //To avoid copying of elements
data_.resize(ni_ * nj_ * nk_ * nl, val);
}
template<class A>
typename Grid4D<A>::reference Grid4D<A>::operator()(size_t i, size_t j, size_t k, size_t l)
{
return data_[GetIndex(i, j, k, l)];
}
template<class A>
typename Grid4D<A>::reference Grid4D<A>::operator()(size_t index)
{
assert(index < GetN());
return data_[index];
}
template<class A>
typename Grid4D<A>::const_reference Grid4D<A>::operator()(size_t i, size_t j, size_t k, size_t l) const
{
return data_[GetIndex(i, j, k, l)];
}
template<class A>
typename Grid4D<A>::const_reference Grid4D<A>::operator()(size_t index) const
{
assert(index < GetN());
return data_[index];
}
template<class A>
size_t Grid4D<A>::GetIndex(size_t i, size_t j, size_t k, size_t l) const
{
assert(i < GetNI() && j < GetNJ() && k < GetNK() && l < GetNL());
return i + j*ni_ + k*ni_*nj_ + l*ni_*nj_*nk_;
}
template<class A>
void Grid4D<A>::GetIJKL(size_t index, size_t &i, size_t &j, size_t &k, size_t &l) const
{
assert(index < GetN());
i = index % ni_;
j = (index-i)/ni_ % nj_;
k = (index - j*ni_ - i)/ni_/nj_;
l = (index - k*ni_*nj_)/ni_/nj_/nk_; //?
}
template<class A>
void Grid4D<A>::Swap(NRLib::Grid4D<A> &other)
{
std::swap(ni_, other.ni_);
std::swap(nj_, other.nj_);
std::swap(nk_, other.nk_);
std::swap(nl_, other.nl_);
data_.swap(other.data_);
}
}
#endif

193
ThirdParty/NRLib/nrlib/grid/grid5d.hpp vendored Normal file
View File

@@ -0,0 +1,193 @@
// $Id: grid5d.hpp 1142 2013-03-18 15:13:41Z hgolsen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_GRID5D_HPP
#define NRLIB_GRID5D_HPP
#include <cassert>
#include <sstream>
#include <vector>
namespace NRLib {
template<class A>
class Grid5D {
public:
typedef typename std::vector<A>::iterator iterator;
typedef typename std::vector<A>::const_iterator const_iterator;
typedef typename std::vector<A>::reference reference;
typedef typename std::vector<A>::const_reference const_reference;
Grid5D();
/// \param val Initial cell value.
Grid5D(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val = A());
virtual ~Grid5D();
/// All values in the grid are erased when the grid is
/// resized.
/// \param val Initial cell value.
void Resize(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val = A());
inline reference operator()(size_t i, size_t j, size_t k, size_t l, size_t m);
inline reference operator()(size_t index);
inline const_reference operator()(size_t i, size_t j, size_t k, size_t l, size_t m) const;
inline const_reference operator()(size_t index) const;
iterator begin() {return( data_.begin()); }
iterator end() {return( data_.end()); }
const_iterator begin() const { return(data_.begin()); }
const_iterator end() const { return(data_.end()); }
size_t GetNI() const { return(ni_); }
size_t GetNJ() const { return(nj_); }
size_t GetNK() const { return(nk_); }
size_t GetNL() const { return(nl_); }
size_t GetNM() const { return(nm_); }
size_t GetN() const { return data_.size(); }
inline size_t GetIndex(size_t i, size_t j, size_t k, size_t l, size_t m) const;
void GetIJKLM(size_t index, size_t &i, size_t &j, size_t &k, size_t &l, size_t &m) const;
void Swap(Grid5D<A>& other);
private:
size_t ni_;
size_t nj_;
size_t nk_;
size_t nl_;
size_t nm_;
/// The grid data, column-major ordering.
std::vector<A> data_;
};
template<class A>
Grid5D<A>::Grid5D()
: ni_(0),
nj_(0),
nk_(0),
nl_(0),
nm_(0),
data_()
{}
template<class A>
Grid5D<A>::Grid5D(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val)
: ni_(ni),
nj_(nj),
nk_(nk),
nl_(nl),
nm_(nm),
data_(ni*nj*nk*nl*nm, val)
{}
template<class A>
Grid5D<A>::~Grid5D()
{}
template<class A>
void Grid5D<A>::Resize(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val)
{
ni_ = ni;
nj_ = nj;
nk_ = nk;
nl_ = nl;
nm_ = nm
data_.resize(0); //To avoid copying of elements
data_.resize(ni_ * nj_ * nk_ * nl * nm, val);
}
template<class A>
typename Grid5D<A>::reference Grid5D<A>::operator()(size_t i, size_t j, size_t k, size_t l, size_t m)
{
return data_[GetIndex(i, j, k, l, m)];
}
template<class A>
typename Grid5D<A>::reference Grid5D<A>::operator()(size_t index)
{
assert(index < GetN());
return data_[index];
}
template<class A>
typename Grid5D<A>::const_reference Grid5D<A>::operator()(size_t i, size_t j, size_t k, size_t l, size_t m) const
{
return data_[GetIndex(i, j, k, l, m)];
}
template<class A>
typename Grid5D<A>::const_reference Grid5D<A>::operator()(size_t index) const
{
assert(index < GetN());
return data_[index];
}
template<class A>
size_t Grid5D<A>::GetIndex(size_t i, size_t j, size_t k, size_t l, size_t m) const
{
assert(i < GetNI() && j < GetNJ() && k < GetNK() && l < GetNL() && m < GetNM());
return i + j*ni_ + k*ni_*nj_ + l*ni_*nj_*nk_ + m*ni_*nj_*nk_*nl_;
}
template<class A>
void Grid5D<A>::GetIJKLM(size_t index, size_t &i, size_t &j, size_t &k, size_t &l, size_t &m) const
{
assert(index < GetN());
i = index % ni_;
j = (index-i)/ni_ % nj_;
k = (index - j*ni_ - i)/ni_/nj_;
l = (index - k*ni_*nj_)/ni_/nj_/nk_; //?
m = (index - m*ni_*nj_*nk_)/ni_/nj_/nk_/nl_; //?
}
template<class A>
void Grid5D<A>::Swap(NRLib::Grid5D<A> &other)
{
std::swap(ni_, other.ni_);
std::swap(nj_, other.nj_);
std::swap(nk_, other.nk_);
std::swap(nl_, other.nl_);
std::swap(nm_, other.nm_);
data_.swap(other.data_);
}
}
#endif

1
ThirdParty/NRLib/nrlib/grid/module.mk vendored Normal file
View File

@@ -0,0 +1 @@
SRC +=

View File

@@ -0,0 +1,733 @@
//$Id: fileio.cpp 1068 2012-09-18 11:21:53Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "fileio.hpp"
#include "../exception/exception.hpp"
#include "stringtools.hpp"
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/filesystem.hpp>
#include <fstream>
#include <iostream>
#include <locale>
#include <sstream>
#include <string>
using namespace NRLib::NRLibPrivate;
using namespace NRLib;
const std::string format_desc[5] = {"storm_petro_binary",
"storm_petro_ascii",
"storm_facies_binary",
"storm_facies_ascii",
"NORSAR"};
void NRLib::OpenRead(std::ifstream& stream,
const std::string& filename,
std::ios_base::openmode mode)
{
namespace fs = boost::filesystem;
try {
boost::filesystem::path file_path(filename);
if (!fs::exists(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for reading: " +
"File does not exist.");
}
if (fs::is_directory(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for reading: " +
" It is a directory.");
}
stream.open(file_path.file_string().c_str(), mode);
if (!stream) {
throw IOError("Failed to open " + file_path.file_string() + " for reading.");
}
}
catch (fs::filesystem_error& e) {
throw IOError("Failed to open " + filename + " for reading: " + e.what());
}
}
void NRLib::OpenRead(std::fstream& stream,
const std::string& filename,
std::ios_base::openmode mode)
{
namespace fs = boost::filesystem;
try {
boost::filesystem::path file_path(filename);
if (!fs::exists(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for reading: " +
"File does not exist.");
}
if (fs::is_directory(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for reading: " +
" It is a directory.");
}
stream.open(file_path.file_string().c_str(), mode);
if (!stream) {
throw IOError("Failed to open " + file_path.file_string() + " for reading.");
}
}
catch (fs::filesystem_error& e) {
throw IOError("Failed to open " + filename + " for reading: " + e.what());
}
}
void NRLib::OpenWrite(std::ofstream& stream,
const std::string& filename,
std::ios_base::openmode mode,
bool create_dir)
{
namespace fs = boost::filesystem;
try {
fs::path file_path(filename);
fs::path dir = file_path.parent_path();
if (fs::is_directory(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for writing: " +
" It is a directory.");
}
if (!dir.empty()) {
if (!fs::exists(dir) && create_dir) {
create_directories(dir);
}
else if (!fs::exists(dir)) {
throw IOError("Failed to open " + file_path.file_string() + " for writing: "
+ "Parent directory does not exist.");
}
}
stream.open(file_path.file_string().c_str(), mode);
if (!stream) {
throw IOError("Failed to open " + file_path.file_string() + " for writing.");
}
}
catch (fs::filesystem_error& e) {
throw IOError("Failed to open " + filename + " for writing: " + e.what());
}
}
void NRLib::OpenWrite(std::fstream& stream,
const std::string& filename,
std::ios_base::openmode mode,
bool create_dir)
{
namespace fs = boost::filesystem;
try {
fs::path file_path(filename);
fs::path dir = file_path.parent_path();
if (fs::is_directory(file_path)) {
throw IOError("Failed to open " + file_path.file_string() + " for writing: " +
" It is a directory.");
}
if (!dir.empty()) {
if (!fs::exists(dir) && create_dir) {
create_directories(dir);
}
else if (!fs::exists(dir)) {
throw IOError("Failed to open " + file_path.file_string() + " for writing: "
+ "Parent directory does not exist.");
}
}
stream.open(file_path.file_string().c_str(), mode);
if (!stream) {
throw IOError("Failed to open " + file_path.file_string() + " for writing.");
}
}
catch (fs::filesystem_error& e) {
throw IOError("Failed to open " + filename + " for writing: " + e.what());
}
}
void NRLib::CopyFile(const std::string & from_path,
const std::string & to_path,
bool allow_overwrite)
{
if (allow_overwrite)
RemoveFile(to_path);
else {
if (boost::filesystem::exists(to_path))
throw IOError("Failed to open " + to_path + " for writing: The file already exists.");
}
boost::filesystem::copy_file(from_path, to_path);
}
void NRLib::RemoveFile(const std::string & filename)
{
if (boost::filesystem::exists(filename))
boost::filesystem::remove(filename);
}
bool NRLib::FileExists(const std::string & filename)
{
return boost::filesystem::exists(filename);
}
void NRLib::CreateDirIfNotExists(const std::string & filename)
{
namespace fs = boost::filesystem;
fs::path file_path(filename);
fs::path dir = file_path.parent_path();
if (!dir.empty()){
if (!fs::exists(dir))
create_directories(dir);
}
}
std::istream& NRLib::ReadNextToken(std::istream & stream,
std::string & s,
int & line_num)
{
std::locale loc = std::locale();
char c;
if (!stream.good()) {
stream.setstate(std::ifstream::failbit);
s = "";
return stream;
}
while(stream.get(c) && std::isspace(c,loc) == true ) {
if (c == '\n')
line_num++;
}
if (stream.good()) {
s = c;
while(stream.get(c) && std::isspace(c, loc) == false) {
s = s+c;
}
}
if (stream.good() == true) // Do not insert anything at eof.
stream.putback(c); // Put back to make sure that line-numbers are OK.
return stream;
}
void NRLib::DiscardRestOfLine(std::istream& stream,
int& line_num,
bool throw_if_non_whitespace)
{
std::locale loc;
std::string s;
std::getline(stream, s);
line_num++;
if (throw_if_non_whitespace) {
std::string::iterator it = s.begin();
while(it != s.end() && std::isspace(*it, loc))
++it;
if (it != s.end())
throw IOError("Non-whitespace characters encountered.");
}
}
std::istream& NRLib::GetNextNonEmptyLine(std::istream & stream,
int & line_num,
std::string & line)
{
while (std::getline(stream, line)) {
++line_num;
if (line.find_first_not_of(Whitespace()) != std::string::npos) {
return stream;
}
}
line = "";
return stream;
}
std::string NRLib::FindLastNonEmptyLine(std::istream & stream, const std::ios::pos_type & max_line_len)
{
stream.seekg(0, std::ios::end);
std::ios::pos_type file_len = stream.tellg();
std::ios::pos_type offset = std::min(file_len, max_line_len);
stream.seekg(static_cast<std::ios::off_type>(file_len) - offset);
std::string line = "";
std::string last_line = "";
int dummy = 0;
while (GetNextNonEmptyLine(stream, dummy, line))
{
last_line = line;
}
return last_line;
}
void NRLib::SkipComments(std::istream & stream,
char comment_symbol,
int & line_num)
{
std::locale loc = std::locale();
std::string line;
bool comment = true;
while (comment == true && stream.good()) {
char c;
while(stream.get(c) && std::isspace(c, loc)) {
if (c == '\n')
line_num++;
}
if (c == comment_symbol) {
std::getline(stream, line);
line_num++;
}
else {
stream.unget();
comment = false;
}
}
}
bool NRLib::CheckEndOfFile(std::istream& stream)
{
char c;
stream >> c;
if (stream.eof()) {
return true;
}
else {
// printf("end of file? %s\n", c);
stream.putback(c);
return false;
}
}
unsigned long long
NRLib::FindFileSize(const std::string& filename)
{
if ( !boost::filesystem::exists(filename) ) {
throw IOError("File " + filename + " does not exist.");
}
return static_cast<unsigned long long>(boost::filesystem::file_size(filename));
}
int NRLib::FindGridFileType(const std::string& filename )
{
unsigned long long length = FindFileSize(filename);
std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary);
if (!file) {
throw IOError("Error opening " + filename);
}
char buffer[3201];
if (length > 161) {
file.read(buffer, 3200);
buffer[3200] = '\0';
}
else {
file.read(buffer, static_cast<std::streamsize>(length));
buffer[length] = '\0';
}
std::string stringbuffer = std::string(buffer);
std::istringstream i(stringbuffer);
std::string token;
i>>token;
if (token == format_desc[STORM_PETRO_BINARY]) {
return STORM_PETRO_BINARY;
}
else if (token == format_desc[STORM_PETRO_ASCII]) {
return STORM_PETRO_ASCII;
}
else if (token == format_desc[STORM_FACIES_BINARY]) {
return STORM_FACIES_BINARY;
}
else if (token == format_desc[STORM_FACIES_ASCII]) {
return STORM_FACIES_ASCII;
}
else if (token == format_desc[SGRI]) {
//std::getline(i, token);
i>>token;
i>>token;
i>>token;
i>>token;
if(token == "v1.0" ||token == "v2.0" )
return SGRI;
}
else if (NRLib::IsType<double>(token)) {
return PLAIN_ASCII;
}
else if (length>3200) //Check SEGY: Looking for EBCDIC header.
{
unsigned char * buf = reinterpret_cast<unsigned char *>(buffer);
std::vector<int> frequency(256,0);
int i;
for(i=0;i<3200;i++)
frequency[buf[i]]++;
bool segy_ok = true;
int low_count = 0;
for(i=0;i<64;i++)
low_count += frequency[i];
if(low_count > 5)
segy_ok = false;
i++;
for(;(i<256) && (segy_ok == true);i++) {
if(frequency[i] > frequency[64]) //Assumption is that EBCDIC 64 (space) is most common in header.
segy_ok = false;
}
if(segy_ok == true)
{
return SEGY;
}
}
return(UNKNOWN);
}
void NRLib::WriteBinaryShort(std::ostream& stream,
short s,
Endianess file_format)
{
char buffer[2];
switch (file_format) {
case END_BIG_ENDIAN:
WriteUInt16BE(buffer, static_cast<unsigned short>(s));
break;
case END_LITTLE_ENDIAN:
WriteUInt16LE(buffer, static_cast<unsigned short>(s));
break;
default:
throw Exception("Invalid file format.");
}
if (!stream.write(buffer, 2)) {
throw Exception("Error writing to stream.");
}
}
short NRLib::ReadBinaryShort(std::istream& stream,
Endianess file_format)
{
unsigned short us;
char buffer[2];
if (!stream.read(buffer, 2)) {
if(stream.eof())
throw EndOfFile();
else
throw Exception("Error reading from stream (a).");
}
switch (file_format) {
case END_BIG_ENDIAN:
ParseUInt16BE(buffer, us);
break;
case END_LITTLE_ENDIAN:
ParseUInt16LE(buffer, us);
break;
default:
throw Exception("Invalid file format.");
}
return static_cast<short>(us);
}
void NRLib::WriteBinaryInt(std::ostream& stream,
int i,
Endianess file_format)
{
char buffer[4];
switch (file_format) {
case END_BIG_ENDIAN:
WriteUInt32BE(buffer, static_cast<unsigned int>(i));
break;
case END_LITTLE_ENDIAN:
WriteUInt32LE(buffer, static_cast<unsigned int>(i));
break;
default:
throw Exception("Invalid file format.");
}
if (!stream.write(buffer, 4)) {
throw Exception("Error writing to stream.");
}
}
int NRLib::ReadBinaryInt(std::istream& stream,
Endianess file_format)
{
unsigned int ui;
char buffer[4];
if (!stream.read(buffer, 4)) {
if(stream.eof())
throw EndOfFile();
else
throw Exception("Error reading from stream (b).");
}
switch (file_format) {
case END_BIG_ENDIAN:
ParseUInt32BE(buffer, ui);
break;
case END_LITTLE_ENDIAN:
ParseUInt32LE(buffer, ui);
break;
default:
throw Exception("Invalid file format.");
}
return static_cast<int>(ui);
}
void NRLib::WriteBinaryFloat(std::ostream& stream,
float f,
Endianess file_format)
{
char buffer[4];
switch (file_format) {
case END_BIG_ENDIAN:
WriteIEEEFloatBE(buffer, f);
break;
case END_LITTLE_ENDIAN:
WriteIEEEFloatLE(buffer, f);
break;
default:
throw Exception("Invalid file format.");
}
if (!stream.write(buffer, 4)) {
throw Exception("Error writing to stream.");
}
}
float NRLib::ReadBinaryFloat(std::istream& stream,
Endianess file_format)
{
float f;
char buffer[4];
if (!stream.read(buffer, 4)) {
if(stream.eof())
throw EndOfFile();
else
throw Exception("Error reading from stream (c).");
}
switch (file_format) {
case END_BIG_ENDIAN:
ParseIEEEFloatBE(buffer, f);
break;
case END_LITTLE_ENDIAN:
ParseIEEEFloatLE(buffer, f);
break;
default:
throw Exception("Invalid file format.");
}
return f;
}
void NRLib::WriteBinaryDouble(std::ostream& stream,
double d,
Endianess file_format)
{
char buffer[8];
switch (file_format) {
case END_BIG_ENDIAN:
WriteIEEEDoubleBE(buffer, d);
break;
case END_LITTLE_ENDIAN:
WriteIEEEDoubleLE(buffer, d);
break;
default:
throw Exception("Invalid file format.");
}
if (!stream.write(buffer, 8)) {
throw Exception("Error writing to stream.");
}
}
double NRLib::ReadBinaryDouble(std::istream& stream,
Endianess file_format)
{
double d;
char buffer[8];
if (!stream.read(buffer, 8)) {
if(stream.eof())
throw EndOfFile();
else
throw Exception("Error reading from stream (d).");
}
switch (file_format) {
case END_BIG_ENDIAN:
ParseIEEEDoubleBE(buffer, d);
break;
case END_LITTLE_ENDIAN:
ParseIEEEDoubleLE(buffer, d);
break;
default:
throw Exception("Invalid file format.");
}
return d;
}
void NRLib::WriteBinaryIbmFloat(std::ostream& stream,
float f,
Endianess file_format)
{
char buffer[4];
switch (file_format) {
case END_BIG_ENDIAN:
WriteIBMFloatBE(buffer, f);
break;
case END_LITTLE_ENDIAN:
WriteIBMFloatLE(buffer, f);
break;
default:
throw Exception("Invalid file format.");
}
if (!stream.write(buffer, 4)) {
throw Exception("Error writing to stream.");
}
}
float NRLib::ReadBinaryIbmFloat(std::istream& stream,
Endianess file_format)
{
float f;
char buffer[4];
if (!stream.read(buffer, 4)) {
if(stream.eof())
throw EndOfFile();
else
throw Exception("Error reading from stream (e).");
}
switch (file_format) {
case END_BIG_ENDIAN:
ParseIBMFloatBE(buffer, f);
break;
case END_LITTLE_ENDIAN:
ParseIBMFloatLE(buffer, f);
break;
default:
throw Exception("Invalid file format.");
}
return f;
}
void NRLib::ReadNextQuoted(std::istream& stream, char quote, std::string& s, int& line)
{
char c = 0;
int found = 0;
while( found == 0 && !stream.eof() ){
stream.get(c);
if (c == '\n'){
line++;
}
if (c == quote){
found++;
stream.get(c);
}
}
s ="";
while( found == 1 && !stream.eof() ) {
s = s+c;
stream.get(c);
if (c == '\n'){
line++;
}
if (c == quote){
found++;
}
}
if (s == "") //We are at end of file if nothing is read.
throw EndOfFile();
}
bool
NRLib::IgnoreComment(std::ifstream& file, char chin){
char ch;
do {
if(!file.get(ch)) {
throw Exception("Unexpected end of file.");
// NRLib::LogKit::LogMessage(NRLib::LogKit::Error, "Unexpected end of file. \n\n");
// Havana::Exit(EXIT_FAILURE);
}
} while(isspace(ch));
std::string dummy;
if (ch == chin){
getline(file, dummy);
return true;
}
else {
file.unget();
return false;
}
}
int NRLib::Seek(FILE * file, long long offset, int origin)
{
int ret;
#if defined(_MSC_VER)
ret = _fseeki64(file, offset, origin);
#else
ret = fseek(file, offset, origin);
#endif
return(ret);
}

1198
ThirdParty/NRLib/nrlib/iotools/fileio.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
// $Id: logkit.cpp 1127 2012-12-04 12:54:33Z ulvmoen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// • Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// • Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <fstream>
#include <iostream>
#include <stdarg.h>
#include "logkit.hpp"
#include "../exception/exception.hpp"
using namespace NRLib;
std::vector<LogStream*> LogKit::logstreams_(0);
int LogKit::screenLog_ = -1;
std::vector<BufferMessage *> * LogKit::buffer_ = NULL;
// Making a long table to allow direct access.
std::vector<int> LogKit::n_messages_(65, 0);
std::vector<std::string> LogKit::prefix_(65, "");
void
LogKit::SetFileLog(const std::string & fileName, int levels,
bool includeNRLibLogging)
{
std::ofstream * file = new std::ofstream(fileName.c_str());
if (!(*file)) {
//NBNB-PAL: Tmp fix pfga. manglende feilhåndtering (catch)
delete file;
printf("Could not open file %s\n",fileName.c_str());
throw IOError("Error opening " + fileName);
}
LogStream * curStream;
if (includeNRLibLogging == true)
curStream = new LogStream(file, levels);
else {
std::vector<int> phaseLevels;
phaseLevels.push_back(0); //No logging in NRLib, phase 0.
phaseLevels.push_back(levels); //This will be used for all other phases.
curStream = new LogStream(file, phaseLevels);
}
logstreams_.push_back(curStream);
DumpBuffer(curStream);
}
void
LogKit::SetFileLog(const std::string & fileName, const std::vector<int> & levels, bool ignore_general) {
std::ofstream * file = new std::ofstream(fileName.c_str());
if (!(*file)) {
delete file;
throw IOError("Error opening " + fileName);
}
LogStream * curStream = new LogStream(file, levels, ignore_general);
logstreams_.push_back(curStream);
DumpBuffer(curStream);
}
void
LogKit::SetFileLog(const std::string & fileName, int levels, int phase, bool ignore_general) {
std::ofstream * file = new std::ofstream(fileName.c_str());
if (!(*file)) {
delete file;
throw IOError("Error opening " + fileName);
}
std::vector<int> phaseLevels(1000,0);
phaseLevels[phase] = levels;
LogStream * curStream = new LogStream(file, phaseLevels, ignore_general);
logstreams_.push_back(curStream);
DumpBuffer(curStream);
}
void
LogKit::SetScreenLog(int levels, bool includeNRLibLogging)
{
LogStream * curStream;
if (includeNRLibLogging == true)
curStream = new LogStream(NULL, levels);
else {
std::vector<int> phaseLevels;
phaseLevels.push_back(0); //No logging in NRLib, phase 0.
phaseLevels.push_back(levels); //This will be used for all other phases.
curStream = new LogStream(NULL, phaseLevels);
}
if (screenLog_ < 0) {
screenLog_ = static_cast<int>(logstreams_.size());
logstreams_.push_back(curStream);
}
else {
delete logstreams_[screenLog_];
logstreams_[screenLog_] = curStream;
}
}
void
LogKit::SetScreenLog(const std::vector<int> & levels, bool ignore_general) {
LogStream * curStream = new LogStream(NULL, levels, ignore_general);
if (screenLog_ < 0) {
screenLog_ = static_cast<int>(logstreams_.size());
logstreams_.push_back(curStream);
}
else {
delete logstreams_[screenLog_];
logstreams_[screenLog_] = curStream;
}
}
void
LogKit::LogMessage(int level, const std::string & message) {
unsigned int i;
n_messages_[level]++;
std::string new_message = prefix_[level] + message;
for (i=0;i<logstreams_.size();i++)
logstreams_[i]->LogMessage(level, new_message);
SendToBuffer(level,-1,new_message);
}
void
LogKit::LogMessage(int level, int phase, const std::string & message) {
unsigned int i;
n_messages_[level]++;
std::string new_message = prefix_[level] + message;
for (i=0;i<logstreams_.size();i++)
logstreams_[i]->LogMessage(level, phase, new_message);
SendToBuffer(level,phase,new_message);
}
void
LogKit::LogFormatted(int level, std::string format, ...) {
va_list ap;
char message[5000];
va_start(ap, format);
vsprintf(message, format.c_str(), ap);
va_end(ap);
LogMessage(level, std::string(message));
}
void
LogKit::LogFormatted(int level, int phase, std::string format, ...) {
va_list ap;
char message[1000];
va_start(ap, format);
vsprintf(message, format.c_str(), ap);
va_end(ap);
LogMessage(level, phase, std::string(message));
}
void
LogKit::EndLog() {
unsigned int i;
for (i=0;i<logstreams_.size();i++)
delete logstreams_[i];
if (buffer_ != NULL)
EndBuffering(); //Also deletes buffer.
}
void
LogKit::StartBuffering() {
buffer_ = new std::vector<BufferMessage *>;
}
void
LogKit::EndBuffering() {
if (buffer_ != NULL) {
for (unsigned int i=0;i<buffer_->size();i++) {
delete (*buffer_)[i];
(*buffer_)[i] = NULL;
}
delete buffer_;
buffer_ = NULL;
}
}
void
LogKit::SendToBuffer(int level, int phase, const std::string & message) {
if (buffer_ != NULL) {
BufferMessage * bm = new BufferMessage;
bm->level_ = level;
bm->phase_ = phase;
bm->text_ = message;
buffer_->push_back(bm);
}
}
void
LogKit::DumpBuffer(LogStream *logstream) {
if (buffer_ != NULL) {
for (unsigned int i=0;i<buffer_->size();i++) {
if ((*buffer_)[i]->phase_ < 0)
logstream->LogMessage((*buffer_)[i]->level_, (*buffer_)[i]->text_);
else
logstream->LogMessage((*buffer_)[i]->level_, (*buffer_)[i]->phase_, (*buffer_)[i]->text_);
}
}
}
void
LogKit::SetPrefix(const std::string & prefix, int level) {
prefix_[level] = prefix;
}
void
LogKit::WriteHeader(const std::string & text,
MessageLevels logLevel)
{
int width = 100; // Total width of header
std::string ruler(width,'*');
std::string stars("*****");
LogFormatted(logLevel,"\n"+ruler+"\n");
int starLength = int(stars.length());
int textLength = int(text.length());
int blankLength = width - textLength - 2*starLength;
std::string blanks(blankLength/2,' ');
std::string center;
if(blankLength % 2)
center = stars + blanks + text + blanks + " " + stars;
else
center = stars + blanks + text + blanks +stars;
LogFormatted(logLevel,center+"\n");
LogFormatted(logLevel,ruler+"\n");
}
LogStream::LogStream(std::ostream * logstream, int level) {
fullLevel_ = level;
if (logstream != NULL) {
logstream_ = logstream;
deleteStream = true;
}
else {
logstream_ = &(std::cout);
deleteStream = false;
}
}
LogStream::LogStream(std::ostream * logstream, const std::vector<int> & levels, bool ignore_general) {
unsigned int i;
fullLevel_ = 0;
for (i=0;i<levels.size();i++) {
if(ignore_general == false)
fullLevel_ = (fullLevel_ | levels[i]);
levels_.push_back(levels[i]);
}
if (logstream != NULL) {
logstream_ = logstream;
deleteStream = true;
}
else {
logstream_ = &(std::cout);
deleteStream = false;
}
}
LogStream::~LogStream() {
if (deleteStream == true) {
delete logstream_;
}
}
void
LogStream::LogMessage(int level, const std::string & message) {
if ((level & fullLevel_) > 0) {
*logstream_ << message;
logstream_->flush();
}
}
void
LogStream::LogMessage(int level, int phase, const std::string & message) {
if (phase < static_cast<int>(levels_.size())) {
if ((level & levels_[phase]) > 0) {
*logstream_ << message;
logstream_->flush();
}
}
else if ((level & fullLevel_) > 0) {
*logstream_ << message;
logstream_->flush();
}
}

View File

@@ -0,0 +1,145 @@
// $Id: logkit.hpp 1072 2012-09-18 13:53:37Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_LOGKIT_H
#define NRLIB_LOGKIT_H
#include<ostream>
#include<vector>
#include<string>
namespace NRLib {
class LogStream;
struct BufferMessage;
/// Kit for logging of messages from program.
class LogKit {
public:
///Philosophy:
///A message has a level, determining the type of message, and a phase,
///determining the stage in the program. Each stream has a level (which may
///be a combination of basic levels) for each phase. If phase and flag
///matches, the message is sent to the stream. A message without phase is
///default sent to all streams that would send it in at least one phase. If
///the ignore_general flag is set to true when generating a stream, that
///stream will ignore messages without phase.
///
///The system can be used without bothering with phases. All NRLib logging
///is phase 0 LOW.
///
///Symbols for use when sending message level and parsing exact levels.
enum MessageLevels {Error = 1, Warning = 2, Low = 4, Medium = 8, High = 16, DebugLow = 32, DebugHigh = 64};
///Symbols for use when parsing given level and lower.
enum LimitLevels {L_Error = 1, L_Warning = 3, L_Low = 7, L_Medium = 15,
L_High = 31, L_DebugLow = 63, L_DebugHigh = 127};
///Set a file that logs independent of phase.
static void SetFileLog(const std::string & fileName, int levels,
bool includeNRLibLogging = true);
///Set a full phase dependent file log
static void SetFileLog(const std::string & fileName,
const std::vector<int> & levels,
bool ignore_general = false);
///Set single-phase file log, useful for debugging given phase.
static void SetFileLog(const std::string & fileName,
int levels,
int phase,
bool ignore_general = false);
///Set a screen log independent of phase.
static void SetScreenLog(int levels, bool includeNRLibLogging = true);
///Set a full phase dependent screen log
static void SetScreenLog(const std::vector<int> & levels, bool ignore_general = false);
///Send message independent of phase
static void LogMessage(int level, const std::string & message);
///Send message in given phase
static void LogMessage(int level, int phase, const std::string & message);
///Send message as c-style format string and arguments.
// Sending format as reference fails.
static void LogFormatted(int level, std::string format, ...);
///Send message as c-style format string and arguments.
static void LogFormatted(int level, int phase, std::string format, ...);
///Close streams
static void EndLog();
///Buffering allows temporary storage of messages for sending to files
///opened later. When a file log is opened, the buffer is dumped to it.
///EndBuffering should be called once all files are opened.
static void StartBuffering();
static void EndBuffering();
static void SetPrefix(const std::string & prefix, int level);
static int GetNMessages(int level) { return n_messages_[level];}
static void WriteHeader(const std::string & text, MessageLevels logLevel = Low);
private:
static std::vector<LogStream *> logstreams_;
static int screenLog_; //Remembers which log is screen.
static std::vector<BufferMessage *> * buffer_;
static std::vector<int> n_messages_;
static std::vector<std::string> prefix_;
static void SendToBuffer(int level, int phase, const std::string & message);
static void DumpBuffer(LogStream * logstream);
};
///Class LogStream is for internal use in LogKit only.
class LogStream {
public:
///Convention: logstream = NULL means cout.
LogStream(std::ostream * logstream, int level);
LogStream(std::ostream * logstream, const std::vector<int> & levels, bool ignore_general = false);
~LogStream();
void LogMessage(int level, const std::string & message);
void LogMessage(int level, int phase, const std::string & message);
private:
std::ostream * logstream_;
std::vector<int> levels_;
int fullLevel_;
bool deleteStream;
};
struct BufferMessage {
std::string text_;
int phase_;
int level_;
};
}
#endif

View File

@@ -0,0 +1,6 @@
SRC += $(NRLIB_BASE_DIR)iotools/fileio.cpp \
$(NRLIB_BASE_DIR)iotools/logkit.cpp \
$(NRLIB_BASE_DIR)iotools/stringtools.cpp \
$(NRLIB_BASE_DIR)iotools/tabularfile.cpp
TEST_SRC += $(NRLIB_BASE_DIR)iotools/unittests/fileio_test.cpp

View File

@@ -0,0 +1,190 @@
// $Id: stringtools.cpp 1068 2012-09-18 11:21:53Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stringtools.hpp"
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/filesystem.hpp>
using namespace NRLib;
template <>
std::string NRLib::ParseType<std::string>(const std::string& s)
{
return s; //Just to ensure that whitespace-containing strings survive.
}
std::string
NRLib::GetPath(const std::string& filename)
{
boost::filesystem::path path(filename);
return path.parent_path().file_string();
}
std::string
NRLib::GetExtension(const std::string& filename)
{
boost::filesystem::path path(filename);
return path.extension();
}
std::string
NRLib::RemovePath(const std::string& filename)
{
boost::filesystem::path path(filename);
return path.filename();
}
std::string
NRLib::PrependDir(const std::string& prefix,
const std::string& str)
{
boost::filesystem::path path(prefix);
path /= str;
return path.file_string();
}
std::string
NRLib::ReplaceExtension(const std::string& filename,
const std::string& extension)
{
boost::filesystem::path file(filename);
file.replace_extension(extension);
return file.file_string();
}
std::string
NRLib::AddExtension(const std::string& filename,
const std::string& extension)
{
std::string new_filename = filename + "." + extension;
return new_filename;
}
std::string
NRLib::GetStem(const std::string& filename)
{
boost::filesystem::path path(filename);
return path.stem();
}
std::vector<std::string>
NRLib::GetTokens(const std::string& s)
{
std::vector<std::string> v;
std::istringstream iss(s);
std::string tmp;
while(iss >> tmp) {
v.push_back(tmp);
}
return v;
}
std::vector<std::string>
NRLib::GetQuotedTokens(const std::string& s)
{
std::vector<std::string> v;
std::istringstream iss(s);
std::string tmp;
std::string char_tmp;
size_t quotation_last_position = 0;
while(iss >> tmp) {
char_tmp = tmp.substr(0, 1);
if (char_tmp != "\"")
v.push_back(tmp);
else{
quotation_last_position = s.find_first_of("\"", quotation_last_position + 1);
size_t first_quotation_mark = quotation_last_position;
quotation_last_position = s.find_first_of("\"", quotation_last_position + 1);
size_t second_quotation_mark = quotation_last_position;
std::string quotation = s.substr(first_quotation_mark + 1, (second_quotation_mark - first_quotation_mark - 1));
v.push_back(quotation);
if (char_tmp == tmp)
iss >> tmp;
while (tmp.substr((tmp.size() - 1), 1) != "\"")
iss >> tmp;
}
}
return v;
}
void
NRLib::Substitute(std::string & text,
const std::string & out,
const std::string & in)
{
std::string::size_type len = in.size();
std::string::size_type pos = text.find(out);
while (pos != std::string::npos) {
text.replace(pos, len, in);
pos = text.find(out);
}
}
std::string
NRLib::Uppercase(const std::string& text)
{
std::string out = text;
for (size_t i = 0; i < out.length(); ++i)
out[i] = static_cast<char>(std::toupper(out[i]));
return out;
}
bool
NRLib::IsNumber(const std::string & s)
{
std::istringstream inStream(s);
double inValue = 0.0;
if (inStream >> inValue)
return true;
else
return false;
}
std::string
NRLib::Chomp(const std::string& s)
{
std::string out = s;
size_t first, last;
first = out.find_first_not_of(" ");
last = out.find_last_not_of(" ");
out.erase(last + 1);
out.erase(0, first);
return out;
}

View File

@@ -0,0 +1,218 @@
// $Id: stringtools.hpp 1068 2012-09-18 11:21:53Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_STRINGTOOLS_HPP
#define NRLIB_STRINGTOOLS_HPP
#include <stdlib.h> // For atoi and atof
#include <string>
#include <iomanip>
#include <vector>
#include <sstream>
#include <typeinfo>
#include "../exception/exception.hpp"
namespace NRLib {
std::vector<std::string> GetTokens(const std::string& s);
std::vector<std::string> GetQuotedTokens(const std::string& s);
/// OBS: Negative values are recognized as unsigned integers on Windows.
/// Works OK on Linux. (gcc 4.*)
template <typename T>
bool IsType(const std::string& s);
/// OBS: Negative values are recognized as unsigned integers on Windows.
/// Works OK on Linux. (gcc 4.*)
template <typename T>
T ParseType(const std::string& s);
/// If used in a template function, we may get string ot string parse.
/// Will not work with the version above, so handle special case.
template <>
std::string ParseType<std::string>(const std::string& s);
/// \todo Replace precision with a format object.
template <typename T>
std::string ToString(const T obj, int precision=-99999);
/// Not safe. Replaces whitespace in s with \0.
template <typename I>
I ParseAsciiArrayFast(std::string& s, I begin, size_t n);
/// Get the path from a full file name.
std::string GetPath(const std::string& filename);
/// Get the stem of the filename (filename without path and extension)
std::string GetStem(const std::string& filename);
/// Get filename extension
std::string GetExtension(const std::string& filename);
/// Get file name only (no path) from full file name.
std::string RemovePath(const std::string& filename);
/// Prepend prefix to str. Returns str if prefix is empty, if str is empty
/// or if str is a complete path starting with /.
/// Adds '/' as directory seperator if missing.
std::string PrependDir(const std::string& prefix,
const std::string& str);
/// Replace file extension.
std::string ReplaceExtension(const std::string& filename,
const std::string& extension);
/// Add an extension to the filename.
std::string AddExtension(const std::string& filename,
const std::string& extension);
/// In string text replace all occurences odf string "out" with string "in".
void Substitute(std::string & text,
const std::string & out,
const std::string & in);
/// Return uppercase of input string.
std::string Uppercase(const std::string& text);
bool IsNumber(const std::string & s);
std::string Chomp(const std::string& s);
/// String with different kinds of whitespace characters.
inline std::string Whitespace() { return " \t\n\r\f\v"; }
namespace NRLibPrivate {
template <class A>
class UnsafeParser
{
public:
static A ParseType(const char* s) {
return NRLib::ParseType<A>(s);
}
};
template <>
class UnsafeParser<int>
{
public:
static int ParseType(const char* s) {
return atoi(s);
}
};
template <>
class UnsafeParser<double>
{
public:
static double ParseType(const char* s) {
return atof(s);
}
};
template <>
class UnsafeParser<float>
{
public:
static double ParseType(const char* s) {
return static_cast<float>(atof(s));
}
};
} // namespace NRLibPrivate
} // namespace NRLib
/// @todo Use correct exceptions.
template <typename T>
bool NRLib::IsType(const std::string& s)
{
std::istringstream i(s);
T x;
char c;
if (!(i >> x) || i.get(c))
return false;
return true;
}
template <typename T>
T NRLib::ParseType(const std::string& s)
{
std::istringstream i(s);
T x;
char c;
if (!(i >> x))
throw Exception("Failed to convert \"" + s + "\" to " + typeid(T).name());
if (i.get(c))
throw Exception("Could not convert whole \"" + s + "\" to " + typeid(T).name());
return x;
}
template <typename T>
std::string NRLib::ToString(const T obj, int precision)
{
std::ostringstream o;
if (precision!=-99999) {
o << std::fixed << std::setprecision(precision);
}
if (!(o << obj)) {
throw Exception("Bad conversion.");
}
return o.str();
}
template <typename I>
I NRLib::ParseAsciiArrayFast(std::string& s, I begin, size_t n)
{
typedef typename std::iterator_traits<I>::value_type T;
std::string whitespace = " \n\r\f\t";
size_t pos = s.find_first_not_of(whitespace, 0);
size_t next_pos = s.find_first_of(whitespace, pos+1);
size_t i = 0;
while (i < n && pos != s.npos) {
if (next_pos != s.npos) {
s[next_pos] = '\0';
}
*begin = NRLibPrivate::UnsafeParser<T>::ParseType(&s[pos]);
++begin;
pos = s.find_first_not_of(whitespace, next_pos + 1);
next_pos = s.find_first_of(whitespace, pos + 1);
++i;
}
if (i != n) {
throw Exception("Not enough elements parsed from string.");
}
return begin;
}
#endif // NRLIB_STRINGTOOLS_HPP

View File

@@ -0,0 +1,135 @@
// $Id: tabularfile.cpp 1078 2012-09-25 11:13:53Z veralh $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "tabularfile.hpp"
#include <fstream>
#include "fileio.hpp"
#include "../exception/exception.hpp"
namespace NRLib {
TabularFile::TabularFile(const std::string& filename)
{
size_t first_data_line, n_columns;
bool read_last_line;
std::string last_line;
if (!CheckFile(filename, first_data_line, n_columns, read_last_line, last_line))
throw FileFormatError("The format of " + filename + " is not supported.");
ReadFromFile(filename, first_data_line, n_columns, read_last_line);
}
TabularFile::TabularFile(const std::string & filename,
size_t first_data_line,
size_t n_columns,
bool read_last_line)
{
ReadFromFile(filename, first_data_line, n_columns, read_last_line);
}
bool TabularFile::CheckFile(const std::string & filename,
size_t & first_data_line,
size_t & n_columns,
bool & read_last_line,
std::string & last_line)
{
// Check if the last line of the file consists of data
// and make initial guess if the last line shoud be read (not reading when equal to 0 or -999)
std::ifstream in_file0;
OpenRead(in_file0, filename);
last_line = FindLastNonEmptyLine(in_file0);
std::vector<std::string> tokens = GetTokens(last_line);
read_last_line = true;
if (!IsType<double>(tokens[0])) {
read_last_line = false;
}
else {
for (size_t i = 0; i < tokens.size(); ++i) {
if (!IsType<double>(tokens[i]))
read_last_line = false;
else {
if(atof(tokens[i].c_str()) == 0.0 || atof(tokens[i].c_str()) == -999.0)
read_last_line = false;
}
}
}
std::ifstream in_file;
OpenRead(in_file, filename);
int line_number = 0;
std::string line;
while (GetNextNonEmptyLine(in_file, line_number, line)) {
std::vector<std::string> tokens = GetTokens(line);
if (IsType<double>(tokens[0])) {
first_data_line = line_number;
n_columns = tokens.size();
for (size_t i = 0; i < n_columns; ++i) {
if (!IsType<double>(tokens[i]))
return false;
}
return true;
}
}
return false;
}
void TabularFile::ReadFromFile(const std::string & filename,
size_t first_data_line,
size_t n_columns,
bool read_last_line)
{
std::ifstream in_file;
OpenRead(in_file, filename);
std::string line;
columns_.resize(n_columns);
std::vector<double> data(n_columns);
// First line in file is line number 1. Read and discard up to first_data_line
for (size_t i = 1; i < first_data_line; ++i) {
std::getline(in_file, line);
}
std::string this_line, next_line;
std::getline(in_file, this_line);
while(std::getline(in_file, next_line)) {
ParseAsciiArrayFast(this_line, data.begin(), n_columns);
for (size_t i = 0; i < n_columns; ++i) {
columns_[i].push_back(data[i]);
}
this_line = next_line;
}
// Reading last line
if(read_last_line) {
ParseAsciiArrayFast(this_line, data.begin(), n_columns);
for (size_t i = 0; i < n_columns; ++i) {
columns_[i].push_back(data[i]);
}
}
}
} // namespace NRLib

View File

@@ -0,0 +1,70 @@
// $Id: tabularfile.hpp 1078 2012-09-25 11:13:53Z veralh $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_IOTOOLS_TABULARFILE_HPP
#define NRLIB_IOTOOLS_TABULARFILE_HPP
#include <cassert>
#include <string>
#include <vector>
namespace NRLib {
/// Class for files with tabular data, i.e. data values separated by a delimiter.
/// Currently only supports doubles separated by spaces with an optional text header.
class TabularFile
{
public:
explicit TabularFile(const std::string& filename);
TabularFile(const std::string& filename, size_t first_data_line, size_t n_columns, bool read_last_line = true);
/// Simple check of file. Just checks that the file contains tabular data.
/// \param[out] first_data_line Number of lines with header data.
static bool CheckFile(const std::string& filename,
size_t& first_data_line,
size_t& n_columns,
bool& read_last_line,
std::string& last_line);
void ReadFromFile(const std::string& filename,
size_t first_data_line,
size_t n_columns,
bool read_last_line = true);
size_t GetNColumns() const { return columns_.size(); }
inline const std::vector<double>& GetColumn(size_t i) const;
private:
std::vector<std::vector<double> > columns_;
};
// ========== INLINE FUNCTIONS =========
const std::vector<double>& TabularFile::GetColumn(size_t i) const
{
assert(i < columns_.size());
return columns_[i];
}
} // namespace NRLib
#endif // NRLIB_IOTOOLS_TABULARFILE_HPP

View File

@@ -0,0 +1,2 @@
SRC += $(NRLIB_BASE_DIR)stormgrid/stormfaciesgrid.cpp \
$(NRLIB_BASE_DIR)stormgrid/stormcontgrid.cpp

View File

@@ -0,0 +1,788 @@
// $Id: stormcontgrid.cpp 1190 2013-07-03 10:57:27Z ulvmoen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stormcontgrid.hpp"
#include <cmath>
#include <fstream>
#include <math.h>
#include <locale>
#include <cassert>
#include "../exception/exception.hpp"
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
#include "../surface/surface.hpp"
#include "../surface/regularsurface.hpp"
#include "../surface/regularsurfacerotated.hpp"
using namespace NRLib;
const float STD_MISSING_CODE = -999.0F;
const std::string format_desc[2] = {"storm_petro_binary",
"storm_petro_ascii"};
StormContGrid::StormContGrid(size_t nx, size_t ny, size_t nz)
: Grid<float>(nx, ny, nz, STD_MISSING_CODE)
{
// Default values
file_format_ = STORM_BINARY;
missing_code_ = STD_MISSING_CODE;
zone_number_ = 0;
model_file_name_ = "ModelFile";
variable_name_ = "UNKNOWN";
}
StormContGrid::StormContGrid(const Volume &vol, size_t nx, size_t ny, size_t nz)
:Volume(vol)
{
file_format_ = STORM_BINARY;
missing_code_ = STD_MISSING_CODE;
zone_number_ = 0;
model_file_name_ = "ModelFile";
variable_name_ = "UNKNOWN";
Resize(nx,ny,nz);
}
StormContGrid::StormContGrid(const Volume &vol, const Grid<float> & grid)
:Grid<float>(grid),
Volume(vol)
{
file_format_ = STORM_BINARY;
missing_code_ = STD_MISSING_CODE;
zone_number_ = 0;
model_file_name_ = "ModelFile";
variable_name_ = "UNKNOWN";
}
StormContGrid::StormContGrid(const std::string& filename, Endianess file_format)
{
ReadFromFile(filename, true, file_format);
}
void StormContGrid::ReadFromFile(const std::string& filename, bool commonPath, Endianess number_representation)
{
std::ifstream file;
OpenRead(file, filename, std::ios::in | std::ios::binary);
std::string path = "";
if (commonPath == true)
path = GetPath(filename);
if (!file) {
throw new IOError("Error opening " + filename);
}
// Current line number
int line = 0;
// Header
try {
std::string token = ReadNext<std::string>(file, line);
if (token == format_desc[STORM_BINARY]) {
file_format_ = STORM_BINARY;
}
else if (token == format_desc[STORM_ASCII]) {
file_format_ = STORM_ASCII;
}
else if(token=="NORSAR")
{
std::string binfilename;
ReadSgriHeader(file, binfilename);
if (binfilename.empty())
binfilename = NRLib::ReplaceExtension(filename, "Sgri");
else
binfilename = path + "/" + binfilename;
std::ifstream binFile(binfilename.c_str(), std::ios::in | std::ios::binary);
if(!binFile) {
throw Exception("Error: Could not open Sgri binary file"+binfilename+"for reading.\n");
return;
}
binFile.close();
ReadSgriBinaryFile(binfilename);
file_format_ = STORM_BINARY; // when writing to file, use binary format.
zone_number_ = 0;
model_file_name_ = "ModelFile";
variable_name_ = "UNKNOWN";
return;
}
else {
throw FileFormatError("Unknown format: " + token);
}
zone_number_ = ReadNext<int>(file, line);
model_file_name_ = ReadNext<std::string>(file, line);
missing_code_ = ReadNext<float>(file, line);
variable_name_ = ReadNext<std::string>(file, line);
ReadVolumeFromFile(file, line, path);
int nx = ReadNext<int>(file, line);
int ny = ReadNext<int>(file, line);
int nz = ReadNext<int>(file, line);
Resize(nx, ny, nz);
switch (file_format_) {
case STORM_BINARY:
DiscardRestOfLine(file, line, true);
ReadBinaryFloatArray(file, begin(), GetN(), number_representation);
break;
case STORM_ASCII:
ReadAsciiArrayFast(file, begin(), GetN());
break;
default:
throw Exception("Bug in STORM grid parser: unknown fileformat");
}
try {
int n_barriers = ReadNext<int>(file, line); // line is now wrong.
if (n_barriers != 0) {
throw FileFormatError("Number of barriers greater than 0 found. "
"Only grids without barriers are supported.");
}
}
catch (EndOfFile& ) {
// Number of barriers not present in file.
}
}
catch (EndOfFile& ) {
throw FileFormatError("Unexcpected end of file found while parsing "
" \"" + filename + "\"");
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"STORM file : " + e.what()+"\n");
}
}
void StormContGrid::WriteToFile(const std::string& filename, const std::string& predefinedHeader, bool plainAscii, Endianess file_format, bool remove_path) const
{
std::ofstream file;
OpenWrite(file, filename, std::ios::out | std::ios::binary);
//file.precision(14);
file.precision(4);
// Header
if (predefinedHeader == "" && plainAscii==false) {
file << format_desc[file_format_] << "\n\n"
<< zone_number_ << " " << model_file_name_ << " "
<< missing_code_ << "\n\n" << variable_name_ << "\n\n" ;
WriteVolumeToFile(file, filename, remove_path);
file << "\n";
file << GetNI() << " " << GetNJ() << " " << GetNK() << "\n";
}
else
file << predefinedHeader;
// Data
int n_data = 0;
switch (file_format_) {
case STORM_BINARY:
WriteBinaryFloatArray(file, begin(), end(), file_format);
break;
case STORM_ASCII:
for (const_iterator it = begin(); it != end(); ++it) {
file << *it << " ";
++n_data;
if (n_data % 10 == 0) {
file << "\n";
}
}
break;
default:
throw Exception("Unknown fileformat");
}
// Final 0 (Number of barriers)
if (plainAscii==false)
file << 0;
}
void StormContGrid::WriteToSgriFile(const std::string & file_name,
const std::string & file_name_header,
const std::string & label,
double simbox_dz,
Endianess file_format) const
{
// Header
double vert_scale = 0.001;
double hor_scale = 0.001;
std::ofstream header_file;
NRLib::OpenWrite(header_file, file_name_header);
header_file << "NORSAR General Grid Format v1.0\n";
header_file << "3\n";
header_file << "X (km)\n";
header_file << "Y (km)\n";
header_file << "T (s)\n";
header_file << "FFT-grid\n";
header_file << "1\n";
header_file << label << std::endl;
header_file << "1 1 1\n";
double z_max = GetZMax();
double z_min = GetZMin();
/* float dz = static_cast<float> (floor(simbox->getdz()+0.5)); //To have the same sampling as in SegY
if (dz == 0.0)
dz = 1.0; */
float dz = static_cast<float> (simbox_dz);
int nz = static_cast<int> (ceil((z_max - z_min)/dz));
int ny = static_cast<int>(GetNJ());
int nx = static_cast<int>(GetNI());
header_file << nx << " " << ny << " " << nz << std::endl;
header_file << std::setprecision(10);
header_file << GetDX()*hor_scale << " " << GetDY()*hor_scale << " " << dz*vert_scale << std::endl;
double x0 = GetXMin() + 0.5 * GetDX();
double y0 = GetYMin() + 0.5 * GetDY();
double z0 = z_min + 0.5 * dz;
header_file << x0*hor_scale << " " << y0*hor_scale << " " << z0*vert_scale << std::endl;
header_file << GetAngle() << " 0\n";
header_file << missing_code_ << std::endl;
//fName = fileName + IO::SuffixSgri();
header_file << file_name << std::endl;
header_file << "0\n";
std::ofstream file;
OpenWrite(file, file_name, std::ios::out | std::ios::binary);
file.precision(14);
// Data
WriteBinaryFloatArray(file, begin(), end(), file_format);
// Final 0 (Number of barriers)
file << 0;
}
/// \todo Common implementation with StormFaciesGrid
size_t StormContGrid::FindIndex(double x, double y, double z) const
{
size_t i, j, k;
FindIndex(x, y, z, i, j, k);
return GetIndex(i, j, k);
}
void StormContGrid::FindXYIndex(double x, double y, size_t& i_out, size_t& j_out) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
i_out = static_cast<size_t>(local_x / GetDX());
j_out = static_cast<size_t>(local_y / GetDY());
if(i_out >= GetNI()) {
std::string text ="Trying to look up an xy-position outside grid. Index in x direction is too large.\n";
text += " Index : "+ToString(i_out)+"\n";
text += " Max : "+ToString(GetNI())+"\n";
throw Exception(text);
}
if(j_out >= GetNJ()) {
std::string text ="Trying to look up an xy-position outside grid: Index in y direction is too large.\n";
text += " Index : "+ToString(j_out)+"\n";
text += " Max : "+ToString(GetNJ())+"\n";
throw Exception(text);
}
if(local_x < 0.0) {
std::string text ="Trying to look up an xy-position outside grid: Local x-coordinate is too small ("+NRLib::ToString(local_x, 2)+").\n";
throw Exception(text);
}
if(local_y < 0.0) {
std::string text ="Trying to look up an xy-position outside grid: Local y-coordinate is too small ("+NRLib::ToString(local_y, 2)+").\n";
throw Exception(text);
}
}
void StormContGrid::FindIndex(double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const
{
FindXYIndex(x, y, i_out, j_out);
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
if(z < z_top)
throw Exception("Z value is above top.\n");
if(z > z_bot)
throw Exception("Z value is below bottom. \n");
if (dz == 0) {
k_out = 0;
}
else {
k_out = static_cast<size_t>((z - z_top)/dz);
}
}
void StormContGrid::FindZInterpolatedIndex(const double & x,
const double & y,
const double & z,
size_t & ind1,
size_t & ind2,
double & t) const
{
size_t i;
size_t j;
size_t k;
FindXYIndex(x, y, i, j);
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
if (z<=z_top+0.5*dz) {
k = 0;
t = missing_code_;
ind1 = GetIndex(i, j, k);
ind2 = 0;
}
else if (z>=z_bot-0.5*dz) {
k = GetNK()-1;
t = missing_code_;
ind1 = GetIndex(i, j, k);
ind2 = 0;
}
else {
k = static_cast<size_t>(floor(((z - z_top) / dz) - 0.5));
t = (z-z_top)/dz - 0.5 - static_cast<double>(k);
ind1 = GetIndex(i, j, k);
ind2 = GetIndex(i, j, k+1);
}
}
float StormContGrid::GetValueZInterpolatedFromIndex(const size_t & ind1,
const size_t & ind2,
const double & t) const
{
float value;
if (t == missing_code_)
value = (*this)(ind1);
else {
float v1 = (*this) (ind1);
float v2 = (*this) (ind2);
if(v1 != missing_code_) {
if(v2 != missing_code_)
value = static_cast<float>(v1*(1-t) + v2*t);
else
value = v1;
}
else
value = v2; //Ok even if v2 is missing, then both are missing so missing is result.
}
return(value);
}
double StormContGrid::GetValueZInterpolatedFromIndexNoMissing(const size_t & ind1,
const size_t & ind2,
const double & t) const
{ // Removed tests for missing from identical function
// GetValueZInterpolatedFromIndex to decrease computation time for multizone background model
double value;
if (t == missing_code_)
value = (*this)(ind1);
else {
float v1 = (*this) (ind1);
float v2 = (*this) (ind2);
value = v1*(1-t) + v2*t;
}
return(value);
}
float StormContGrid::GetValueInterpolated(const int & i,
const int & j,
const float & k_value) const
{
float value, val1, val2;
int k1 = int(floor(k_value));
val1 = GetValue(i, j, k1);
if (val1 == missing_code_)
return(missing_code_);
int k2 = k1+1;
if (k1 == static_cast<int>(GetNK()-1))
k2 = k1;
val2 = GetValue(i, j, k2);
if (val2 == missing_code_)
return (val1);
value = float(1.0-(k_value-k1))*val1+float(k_value-k1)*val2;
return(value);
}
float StormContGrid::GetValueZInterpolated(double x, double y, double z)const
{
size_t ind1;
size_t ind2;
double t;
FindZInterpolatedIndex(x, y, z, ind1, ind2, t);
float value = GetValueZInterpolatedFromIndex(ind1, ind2, t);
return(value);
}
float StormContGrid::GetValueClosestInZ(double x, double y, double z)const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
size_t i = static_cast<size_t>(local_x / GetDX());
size_t j = static_cast<size_t>(local_y / GetDY());
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
if (local_x < 0.0 || i >= GetNI() || local_y < 0.0 || j >= GetNJ())
return(missing_code_);
if (z<z_top+0.5*dz)
z = z_top+0.5*dz;
else if (z>z_bot+0.5*dz)
z = z_bot+0.5*dz;
int zInd1 = static_cast<int>(floor((z-z_top)/dz)-0.5);
double t = (z-z_top)/dz - 0.5 - static_cast<double>(zInd1);
int zInd2 = zInd1+1;
float value = static_cast<float>((1-t)*(*this)(GetIndex(i,j,zInd1))+t*(*this)(GetIndex(i,j,zInd2)));
return(value);
}
void StormContGrid::FindCenterOfCell(size_t i, size_t j, size_t k,
double& x, double& y, double& z) const
{
double xloc = (i+0.5)*GetDX();
double yloc = (j+0.5)*GetDY();
LocalToGlobalCoord(xloc, yloc, x, y);
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
z = z_top + (k+0.5)*dz;
}
double StormContGrid::RecalculateLZ()
{
double lz = 0;
for (size_t i = 0; i < GetNI(); ++i) {
for (size_t j = 0; j < GetNJ(); ++j) {
double x, y;
LocalToGlobalCoord(i * GetDX(), j * GetDY(), x, y);
lz = std::max(lz, GetBotSurface().GetZ(x, y) -
GetTopSurface().GetZ(x, y));
}
}
return lz;
}
void StormContGrid::ReadSgriHeader(std::ifstream &headerFile, std::string &binFileName)
{
// std::ifstream headerFile(filename.c_str(), std::ios::in); //checkFileOpen performed previously
int i;
std::string tmpStr;
int dim;
//Reading record 1: Version header
getline(headerFile, tmpStr);
//Reading record 2: Grid dimension
headerFile >> dim;
if(dim!=3)
throw Exception("Wrong dimension of Sgri file. Must be 3.");
getline(headerFile, tmpStr);
//Reading record 3 ... 3+dim: Axis labels + grid value label
std::vector<std::string> axisLabels(dim);
for (i=0; i<dim; i++)
getline(headerFile, axisLabels[i]);
getline(headerFile, tmpStr);
//int config = IMISSING;
//Reading record 4+dim: Number of grids
int nGrid;
headerFile >> nGrid;
if (nGrid < 1) {
throw Exception("Error: Number of grids read from sgri file must be >0");
}
getline(headerFile, tmpStr);
//Reading record 5+dim ... 5+dim+ngrid-1: Grid labels
for (i=0; i<nGrid; i++)
getline(headerFile, tmpStr);
float *dValues1 = new float[dim];
float *dValues2 = new float[dim];
int *iValues = new int[dim];
//Reading record 5+dim+ngrid: Scaling factor of grid values
for (i=0; i<dim; i++)
headerFile >> dValues1[i];
getline(headerFile,tmpStr);
//Reading record 6+dim+ngrid: Number of samples in each dir.
for (i=0; i<dim; i++)
headerFile >> iValues[i];
getline(headerFile,tmpStr);
//Reading record 7+dim+ngrid: Grid sampling in each dir.
for (i=0; i<dim; i++) {
headerFile >> dValues2[i];
}
getline(headerFile,tmpStr);
//Reading record 8+dim+ngrid: First point coord.
float *minValues = new float[dim];
for (i=0; i<dim; i++)
{
headerFile >> minValues[i];
}
int nX=1;
int nY=1;
int nZ=1;
double dX, dY, dZ;
// scaleX_ = dValues1[0];
nX = iValues[0];
dX = dValues2[0];
// scaleY_ = dValues1[1];
nY = iValues[1];
dY = dValues2[1];
// scaleZ_ = dValues1[2];
nZ = iValues[2];
dZ = dValues2[2];
if (nX < 1) {
throw Exception("Error: Number of samples in X-dir must be >= 1.\n");
}
if (nY < 1) {
throw Exception("Error: Number of samples in Y-dir must be >= 1.\n");
}
if (nZ < 1) {
throw Exception("Error: Number of samples in Z-dir must be >= 1.\n");
}
if (dX <= 0.0) {
throw Exception("Error: Grid sampling in X-dir must be > 0.0.\n");
}
if (dY <= 0.0) {
throw Exception("Error: Grid sampling in Y-dir must be > 0.0.\n");
}
if (dZ <= 0.0) {
throw Exception("Error: Grid sampling in Z-dir must be > 0.0.\n");
}
double lx = nX*dX;
double ly = nY*dY;
//double lz = (nY-1)*dZ;
double x_min = minValues[0]-0.5*dX;
double y_min = minValues[1]-0.5*dY;
// z0_ = -0.5f * (nZ-1)*dZ;
SetDimensions(x_min,y_min,lx, ly);
delete [] dValues1;
delete [] dValues2;
delete [] iValues;
Resize(nX,nY,nZ);
//Reading record 9+dim+ngrid: Angle of rotation
double angle;
headerFile >> angle;
// SetAngle(angle*NRLib::PI/180.0);
SetAngle(angle);
double dipangle;
headerFile >> dipangle;
if(dipangle==0)
{
ConstantSurface<double> z_top(minValues[2]-0.5*dZ);
ConstantSurface<double> z_bot(minValues[2]+nZ*dZ-0.5*dZ);
SetSurfaces(z_top,z_bot);
//z_top_ = new RegularSurface<double>(x_min_,y_min_,lx_,ly_,nX,nY,-0.5f*(nZ-1)*dZ);
// z_bot_ = new RegularSurface<double>(x_min_,y_min_,lx_,ly_,nX,nY, 0.5f*(nZ-1)*dZ);
}
else
{
RegularSurfaceRotated<double> z_top(x_min,y_min,lx,ly,nX,nY,dipangle,minValues[2]-0.5*dZ);
RegularSurfaceRotated<double> z_bot(x_min,y_min,lx,ly,nX,nY,dipangle,minValues[2]+nZ*dZ-0.5*dZ);
/* int i,j;
for(i=0;i<nX;i++)
for(j=0;j<nY;j++)
{
(*z_top)(i,j)+=i*nX*tan(dipangle);
(*z_bot)(i,j)+=i*nX*tan(dipangle);
}*/
SetSurfaces(z_top,z_bot);
}
delete [] minValues;
RecalculateLZ();
//erosion_top_ = new ConstantSurface<double>(0.0);
//erosion_bot_ = new ConstantSurface<double>(0.0);
getline(headerFile, tmpStr);
//Reading record 10+dim+ngrid: Undef value
headerFile >> missing_code_;
getline(headerFile, tmpStr);
//Reading record 11+dim+ngrid: Filename of binary file.
getline(headerFile, tmpStr);
if (tmpStr.empty())
binFileName = "";
else {
std::locale loc;
int i = 0;
char c = tmpStr[i];
while (!std::isspace(c,loc)) {
i++;
c = tmpStr[i];
}
tmpStr.erase(tmpStr.begin()+i, tmpStr.end());
binFileName = tmpStr;
}
//Reading record 12+dim+ngrid: Complex values
bool hasComplex;
headerFile >> hasComplex;
if (hasComplex != 0 ) {
throw Exception("Error: Can not read Sgri binary file. Complex values?");
}
//The remaining records are not relevant, stop reading
}
void StormContGrid::ReadSgriBinaryFile(const std::string& filename)
{
std::ifstream binFile(filename.c_str(),std::ios::in | std::ios::binary); //Check opening of file before calling this function
try {
ReadBinaryFloatArray(binFile, begin(), GetN());
}
catch (Exception& e) {
throw Exception("Error: Reading from binary sgri file " +filename + "." + e.what() +"\n");
}
return;
}
void
StormContGrid::WriteCravaFile(const std::string & file_name,
double inline_0,
double crossline_0,
double il_step_x,
double il_step_y,
double xl_step_x,
double xl_step_y)
{
try {
std::ofstream bin_file;
//std::string f_name = file_name + IO::SuffixCrava();
NRLib::OpenWrite(bin_file, file_name, std::ios::out | std::ios::binary);
std::string file_type = "crava_fftgrid_binary";
bin_file << file_type << "\n";
NRLib::WriteBinaryDouble(bin_file, GetXMin());
NRLib::WriteBinaryDouble(bin_file, GetYMin());
NRLib::WriteBinaryDouble(bin_file, GetDX());
NRLib::WriteBinaryDouble(bin_file, GetDY());
NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNI()));
NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNJ()));
NRLib::WriteBinaryDouble(bin_file, inline_0);
NRLib::WriteBinaryDouble(bin_file, crossline_0);
NRLib::WriteBinaryDouble(bin_file, il_step_x);
NRLib::WriteBinaryDouble(bin_file, il_step_y);
NRLib::WriteBinaryDouble(bin_file, xl_step_x);
NRLib::WriteBinaryDouble(bin_file, xl_step_y);
NRLib::WriteBinaryDouble(bin_file, GetAngle());
NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNI()));
NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNJ()));
NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNK()));
//for(int i=0;i<rsize_;i++)
// NRLib::WriteBinaryFloat(binFile, rvalue_[i]);
float value = 0.0f;
for (size_t i = 0; i < GetNI(); i++) {
for (size_t j = 0; j < GetNJ(); j++) {
for (size_t k = 0; k < GetNK(); k++) {
value = GetValue(i, j, k);
NRLib::WriteBinaryFloat(bin_file, value);
}
}
}
bin_file.close();
}
catch (NRLib::Exception & e) {
std::string message = "Error: "+std::string(e.what())+"\n";
throw Exception(message);
}
}
double StormContGrid::GetAvgRelThick(void) const
{
double avgThick = 0.0f;
for (int i = 0 ; i < static_cast<int>(GetNI()); i++) {
for (int j = 0 ; j < static_cast<int>(GetNJ()) ; j++) {
avgThick += GetRelThick(i, j);
}
}
avgThick /= GetNI()*GetNJ();
return avgThick;
}
double StormContGrid::GetRelThick(int i, int j) const
{
double rx = (static_cast<double>(i) + 0.5)*GetDX();
double ry = (static_cast<double>(j) + 0.5)*GetDY();
double x = rx*cos(GetAngle())-ry*sin(GetAngle()) + GetXMin();
double y = rx*sin(GetAngle())+ry*cos(GetAngle()) + GetYMin();
return(GetRelThick(x, y));
}
double StormContGrid::GetRelThick(double x, double y) const
{
double relThick = 1; //Default value to be used outside grid.
double zTop = GetTopSurface().GetZ(x,y);
double zBot = GetBotSurface().GetZ(x,y);
if(GetTopSurface().IsMissing(zTop) == false &&
GetBotSurface().IsMissing(zBot) == false)
relThick = (zBot-zTop)/GetLZ();
return(relThick);
}

View File

@@ -0,0 +1,152 @@
// $Id: stormcontgrid.hpp 1190 2013-07-03 10:57:27Z ulvmoen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_STORMCONTGRID_HPP
#define NRLIB_STORMCONTGRID_HPP
#include <string>
#include "../volume/volume.hpp"
#include "../grid/grid.hpp"
#include "../iotools/fileio.hpp"
namespace NRLib {
class StormContGrid : public Grid<float>, public Volume {
public:
enum FileFormat {STORM_BINARY = 0, STORM_ASCII};
explicit StormContGrid(const std::string& filename, Endianess file_format = END_BIG_ENDIAN);
explicit StormContGrid(size_t nx = 0, size_t ny = 0, size_t nz = 0);
explicit StormContGrid(const Volume &vol, const Grid<float> & grid);
explicit StormContGrid(const Volume &vol, size_t nx = 0, size_t ny = 0, size_t nz = 0);
void SetMissingCode(float missing_code)
{ missing_code_ = missing_code; }
float GetMissingCode() const
{ return missing_code_; }
bool IsMissing(float val) const
{ return val == missing_code_; }
void SetFormat(FileFormat format)
{ file_format_ = format; }
FileFormat GetFormat() const
{ return file_format_; }
void SetModelFileName(const std::string& filename)
{ model_file_name_ = filename; }
std::string GetModelFileName() const
{ return model_file_name_; }
void SetVariableName(const std::string& name)
{ variable_name_ = name; }
std::string GetVariableName() const
{ return variable_name_; }
void SetZoneNumber(int zone_number)
{ zone_number_ = zone_number; }
int GetZoneNumber() const
{ return zone_number_; }
/// Write to file. If predefinedHeader is not empty, this header is written instead
/// of standard, and surfaces are not written.
void WriteToFile(const std::string& filename,
const std::string& predefinedHeader = "",
bool plainAscii=false,
Endianess file_format = END_BIG_ENDIAN,
bool remove_path = true) const;
void WriteToSgriFile(const std::string & file_name,
const std::string & file_name_header,
const std::string & label,
double simbox_dz,
Endianess file_format = END_BIG_ENDIAN) const;
/// \throw IOError if the file can not be opened.
/// \throw FileFormatError if file format is not either storm_binary or storm_ascii, or if grid contains barriers.
void ReadFromFile(const std::string& filename, bool commonPath = true, Endianess file_format = END_BIG_ENDIAN);
double GetDX() const { return GetLX() / GetNI(); }
double GetDY() const { return GetLY() / GetNJ(); }
size_t FindIndex(double x, double y, double z) const;
void FindIndex( double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const;
void FindXYIndex(double x, double y, size_t& i_out, size_t& j_out) const;
void FindZInterpolatedIndex(const double & x,
const double & y,
const double & z,
size_t & ind1,
size_t & ind2,
double & t) const;
float GetValueZInterpolatedFromIndex(const size_t & ind1,
const size_t & ind2,
const double & t) const;
double GetValueZInterpolatedFromIndexNoMissing(const size_t & ind1,
const size_t & ind2,
const double & t) const;
float GetValueInterpolated(const int & i,
const int & j,
const float & k_value) const;
double GetAvgRelThick() const;
float GetValueZInterpolated(double x, double y, double z)const;
float GetValueClosestInZ(double x, double y, double z)const;
double GetZMin()const { return Volume::GetZMin(GetNI(), GetNJ()); }
double GetZMax()const { return Volume::GetZMax(GetNI(), GetNJ()); }
void FindCenterOfCell(size_t i, size_t j, size_t k,
double& x, double& y, double& z) const;
void WriteCravaFile(const std::string & file_name,
double inline_0,
double crossline_0,
double il_step_x,
double il_step_y,
double xl_step_x,
double xl_step_y);
private:
double RecalculateLZ();
void ReadSgriHeader(std::ifstream &headerFile, std::string &binFileName);
void ReadSgriBinaryFile(const std::string& filename);
double GetRelThick(int i, int j) const;
double GetRelThick(double x, double y) const;
FileFormat file_format_;
float missing_code_;
int zone_number_;
std::string model_file_name_;
std::string variable_name_;
};
}
#endif // NRLIB_STORMCONTGRID_HPP

View File

@@ -0,0 +1,347 @@
// $Id: stormfaciesgrid.cpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stormfaciesgrid.hpp"
#include <fstream>
#include "../exception/exception.hpp"
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
#include "../surface/surface.hpp"
using namespace NRLib;
const int STD_MISSING_CODE = -999;
const std::string format_desc[2] = {"storm_facies_binary",
"storm_facies_ascii"};
StormFaciesGrid::StormFaciesGrid(const std::string& filename,Endianess file_format )
{
ReadFromFile(filename, true, file_format);
}
StormFaciesGrid::StormFaciesGrid(size_t nx, size_t ny, size_t nz)
: Grid<int>(nx, ny, nz, STD_MISSING_CODE)
{
// Default values
file_format_ = STORM_BINARY;
missing_code_ = STD_MISSING_CODE;
zone_number_ = 0;
model_file_name_ = "ModelFile";
}
StormFaciesGrid::StormFaciesGrid(const Volume &vol, size_t nx, size_t ny, size_t nz)
:Volume(vol)
{
file_format_ = STORM_BINARY;
missing_code_ = STD_MISSING_CODE;
zone_number_ = 0;
model_file_name_ = "ModelFile";
Resize(nx,ny,nz);
}
int StormFaciesGrid::GetFaciesCode(int body_index) const
{
if (body_index < 0 || body_index >= static_cast<int>(body_facies_.size())) {
throw Exception("Body index " + ToString(body_index)
+ " is outside the defined range [0, " + ToString(body_facies_.size()) );
}
return body_facies_[body_index];
}
int StormFaciesGrid::GetFaciesFromCell(size_t cell_index) const
{
return GetFaciesCode((*this)(cell_index));
}
const std::string& StormFaciesGrid::GetFaciesName(int facies_code) const
{
if (facies_code < 0 || facies_code >= static_cast<int>(facies_names_.size())) {
throw Exception("Body index " + ToString(facies_code) + " is outside "
+ "the valid range [0, " + ToString(facies_names_.size()-1) + "]." );
}
return facies_names_[facies_code];
}
void StormFaciesGrid::SetBodyFacies(const std::vector<int>& body_facies)
{
body_facies_ = body_facies;
}
void StormFaciesGrid::SetFaciesNames(const std::vector<std::string>& facies_names)
{
facies_names_ = facies_names;
}
void StormFaciesGrid::WriteToFile(const std::string& filename, Endianess file_format) const
{
CheckConsistency();
std::ofstream file;
OpenWrite(file, filename, std::ios::out | std::ios::binary);
file << format_desc[file_format_] << "\n\n"
<< zone_number_ << " " << model_file_name_ << " "
<< missing_code_ << "\n\n";
file << facies_names_.size() << "\n";
/// \todo Print on several lines, if there are many facies.
for (size_t i = 0; i < facies_names_.size(); ++i) {
file << facies_names_[i] << " ";
}
file << "\n\n";
file << body_facies_.size() << "\n";
for (size_t i = 0; i < body_facies_.size(); ++i) {
file << body_facies_[i] << " ";
}
file << "\n\n";
WriteVolumeToFile(file, filename);
file << "\n";
file << GetNI() << " " << GetNJ() << " " << GetNK() << "\n";
// Data
int n_data = 0;
switch (file_format_) {
case STORM_BINARY:
WriteBinaryIntArray(file, begin(), end(), file_format);
break;
case STORM_ASCII:
for (const_iterator it = begin(); it != end(); ++it) {
file << *it << " ";
++n_data;
if (n_data % 10 == 0) {
file << "\n";
}
}
break;
default:
throw Exception("Unknown fileformat");
}
// Final 0 (Number of barriers)
file << 0;
}
void StormFaciesGrid::ReadFromFile(const std::string& filename, bool commonPath,Endianess file_format)
{
std::ifstream file;
OpenRead(file, filename, std::ios::in | std::ios::binary);
std::string path = "";
if (commonPath == true)
path = GetPath(filename);
// Current line number
int line = 0;
// Header
try {
std::string token = ReadNext<std::string>(file, line);
if (token == format_desc[STORM_BINARY]) {
file_format_ = STORM_BINARY;
}
else if (token == format_desc[STORM_ASCII]) {
file_format_ = STORM_ASCII;
}
else {
throw FileFormatError("Unknown format: " + token);
}
zone_number_ = ReadNext<int>(file, line);
model_file_name_ = ReadNext<std::string>(file, line);
missing_code_ = ReadNext<int>(file, line);
int size = ReadNext<int>(file, line);
facies_names_.resize(size);
for (int i = 0; i < size; ++i) {
facies_names_[i] = ReadNext<std::string>(file, line);
}
size = ReadNext<int>(file, line);
body_facies_.resize(size);
for (int i = 0; i < size; ++i) {
body_facies_[i] = ReadNext<int>(file, line);
}
ReadVolumeFromFile(file, line, path);
int nx = ReadNext<int>(file, line);
int ny = ReadNext<int>(file, line);
int nz = ReadNext<int>(file, line);
Resize(nx, ny, nz);
switch (file_format_) {
case STORM_BINARY:
DiscardRestOfLine(file, line, true);
ReadBinaryIntArray(file, begin(), GetN(), file_format);
break;
case STORM_ASCII:
ReadAsciiArrayFast(file, begin(), GetN());
break;
default:
throw Exception("Bug in STORM grid parser: unknown fileformat");
}
try {
int n_barriers = ReadNext<int>(file, line); // line is now wrong.
if (n_barriers != 0) {
throw FileFormatError("Number of barriers greater than 0 found. "
"Only grids without barriers are supported.");
}
}
catch (EndOfFile& ) {
// Number of barriers not present in file.
}
}
catch (EndOfFile& ) {
throw FileFormatError("Unexcpected end of file found while parsing "
" \"" + filename + "\"");
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"STORM file at line " + ToString(line) + ":" + e.what());
}
CheckConsistency();
}
void StormFaciesGrid::CheckConsistency() const
{
for (size_t i = 0; i < body_facies_.size(); ++i) {
if (body_facies_[i] < 0 ||
body_facies_[i] >= static_cast<int>(facies_names_.size())) {
throw Exception("Consistency check failed: facies "
+ ToString(body_facies_[i]) + " in body " + ToString(i)
+ " is outside the valid range [0, "
+ ToString(facies_names_.size()-1) + "].");
}
}
for (size_t ind = 0; ind < GetN(); ++ind) {
int body = (*this)(ind);
if ( !IsMissing(body)
&& (body < 0 || body > static_cast<int>(body_facies_.size())) ) {
size_t i, j, k;
GetIJK(ind, i, j, k);
throw Exception("Consistency check failed: body number "
+ ToString(body) + " in cell (" + ToString(i) + ", " + ToString(j)
+ ", " + ToString(k) + ") is outside the valid range [0, "
+ ToString(body_facies_.size()-1) + "].");
}
}
}
size_t StormFaciesGrid::FindIndex(double x, double y, double z) const
{
size_t i, j, k;
FindIndex(x, y, z, i, j, k);
return GetIndex(i, j, k);
}
void StormFaciesGrid::FindIndex(double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
i_out = static_cast<size_t>(local_x / GetDX());
j_out = static_cast<size_t>(local_y / GetDY());
if(i_out >= GetNI())
throw Exception("Index in x direction is too large.\n");
if(j_out >= GetNJ())
throw Exception("Index in y direction is too large.\n");
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
if(z < z_top)
throw Exception("Z value is above top.\n");
if(z > z_bot)
throw Exception("Z value is below bottom. \n");
if (dz == 0) {
k_out = 0;
}
else {
k_out = static_cast<size_t>((z - z_top)/dz);
}
}
/*
/// \todo Common implementation with StormContGrid
size_t StormFaciesGrid::FindIndex(double x, double y, double z) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
size_t i = static_cast<size_t>(local_x / GetDX());
size_t j = static_cast<size_t>(local_y / GetDY());
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
size_t k;
if (dz == 0) {
k = 0;
}
else {
k = static_cast<size_t>((z - z_top)/dz);
}
return GetIndex(i, j, k);
}
*/
double StormFaciesGrid::RecalculateLZ()
{
double lz = 0;
for (size_t i = 0; i < GetNI(); ++i) {
for (size_t j = 0; j < GetNJ(); ++j) {
double x, y;
LocalToGlobalCoord(i * GetDX(), j * GetDY(), x, y);
lz = std::max(lz, GetBotSurface().GetZ(x, y) -
GetTopSurface().GetZ(x, y));
}
}
return lz;
}
void StormFaciesGrid::FindCenterOfCell(size_t i, size_t j, size_t k,
double& x, double& y, double& z) const
{
double xloc = (i+0.5)*GetDX();
double yloc = (j+0.5)*GetDY();
LocalToGlobalCoord(xloc, yloc, x, y);
double z_top = GetTopSurface().GetZ(x, y);
double z_bot = GetBotSurface().GetZ(x, y);
double dz = (z_bot - z_top) / GetNK();
z = z_top + (k+0.5)*dz;
}

View File

@@ -0,0 +1,97 @@
// $Id: stormfaciesgrid.hpp 883 2011-09-26 09:17:05Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_STORMFACIESGRID_HPP
#define NRLIB_STORMFACIESGRID_HPP
#include "../volume/volume.hpp"
#include "../grid/grid.hpp"
#include "../iotools/fileio.hpp"
namespace NRLib {
class StormFaciesGrid : public Grid<int>, public Volume {
public:
enum FileFormat {STORM_BINARY = 0, STORM_ASCII};
explicit StormFaciesGrid(const std::string& filename,Endianess file_format = END_BIG_ENDIAN);
explicit StormFaciesGrid(size_t nx = 0, size_t ny = 0, size_t nz = 0);
explicit StormFaciesGrid(const Volume &vol, size_t nx, size_t ny, size_t nz);
void SetMissingCode(int missing_code)
{ missing_code_ = missing_code; }
int GetMissingCode() const
{ return missing_code_; }
bool IsMissing(int val) const
{ return val == missing_code_; }
void SetFormat(FileFormat format)
{ file_format_ = format; }
FileFormat GetFormat() const
{ return file_format_; }
void SetModelFileName(const std::string& filename)
{ model_file_name_ = filename; }
std::string GetModelFileName() const
{ return model_file_name_; }
void SetZoneNumber(int zone_number)
{ zone_number_ = zone_number; }
int GetZoneNumber() const
{ return zone_number_; }
int GetFaciesCode(int body_index) const;
int GetFaciesFromCell(size_t cell_index) const;
int GetFaciesFromCell(size_t i, size_t j, size_t k) const
{ return GetFaciesFromCell(GetIndex(i, j, k)); }
const std::string& GetFaciesName(int facies_code) const;
void SetBodyFacies(const std::vector<int>& body_facies);
void SetFaciesNames(const std::vector<std::string>& facies_names);
void WriteToFile(const std::string& filename, Endianess file_format = END_BIG_ENDIAN) const;
void ReadFromFile(const std::string& filename, bool commonPath = true, Endianess file_format = END_BIG_ENDIAN);
/// \brief Check that all the facies value for each body, and the
/// body values inside the grid are inside the given range.
void CheckConsistency() const;
double GetDX() const {return GetLX()/GetNI();}
double GetDY() const {return GetLY()/GetNJ();}
size_t FindIndex(double x, double y, double z) const;
void FindIndex( double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const;
void FindCenterOfCell(size_t i, size_t j, size_t k,
double& x, double& y, double& z) const;
private:
double RecalculateLZ();
FileFormat file_format_;
int missing_code_;
int zone_number_;
std::string model_file_name_;
std::vector<std::string> facies_names_;
std::vector<int> body_facies_;
};
}
#endif // NRLIB_STORMFACIESGRID_HPP

View File

@@ -0,0 +1 @@
SRC += $(NRLIB_BASE_DIR)surface/surfaceio.cpp

View File

@@ -0,0 +1,883 @@
// $Id: regularsurface.hpp 1196 2013-09-09 12:01:04Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_REGULARSURFACE_HPP
#define NRLIB_REGULARSURFACE_HPP
#include <algorithm>
#include <cmath>
#include <iostream>
#include "surface.hpp"
#include "surfaceio.hpp"
#include "../grid/grid2d.hpp"
#include "../iotools/stringtools.hpp"
namespace NRLib {
/// Surface represented as a regular grid, where each of the grid cells
/// are modelled as bilinear surfaces.
template <class A>
class RegularSurface : public Grid2D<A>, public Surface<A> {
public:
RegularSurface();
RegularSurface(double x0, double y0, double lx, double ly, size_t nx, size_t ny,
const A& value = A());
RegularSurface(double x0, double y0, double lx, double ly, Grid2D<A> grid);
/// \brief Read surface file on given format.
/// \param filename File name.
/// \param format File format. If SURF_UNKNOWN we try to determine the format.
/// \throws IOError If we failed to open the file
/// \throws FileFormatError If we can not determine the file format, or the contents
/// of the file does not match the file format.
RegularSurface(const std::string & filename,
SurfaceFileFormat format = SURF_UNKNOWN);
Surface<A>* Clone() const
{ return new RegularSurface<A>(*this); }
/// Return z. Returns missing if we are outside the grid.
/// Returns also values when not all grid cell corners are present,
/// e.g. when (x,y) is just outside the grid.
A GetZ(double x, double y) const;
/// Return z. Returns missing if not all grid cell corners are present,
/// e.g. when (x,y) is just outside the grid.
A GetZInside(double x, double y) const;
/// Checks if point is inside definition area for surface.
bool IsInsideSurface(double x, double y) const;
bool EnclosesRectangle(double x_min, double x_max,
double y_min, double y_max) const;
/// Sets all values on the surface to a constant value.
void Assign(A c) {
typename Grid2D<A>::iterator i;
for (i=this->begin();i<this->end();i++)
*i = c;
}
void Add(A c) {
typename Grid2D<A>::iterator i;
for (i=this->begin();i<this->end();i++)
if (*i != missing_val_)
*i += c;
}
void Subtract(A c) {
typename Grid2D<A>::iterator i;
for (i=this->begin();i<this->end();i++)
if (*i != missing_val_)
*i -= c;
}
void Multiply(A c) {
typename Grid2D<A>::iterator i;
for (i=this->begin();i<this->end();i++)
if (*i != missing_val_)
*i *= c;
}
///The following routines are for binary operations with non-conform grids.
///Missing areas will shrink.
///Also works for identical definitions without missing, but is inefficient.
bool AddNonConform(const Surface<A> * s2);
bool SubtractNonConform(const Surface<A> * s2);
bool MultiplyNonConform(const Surface<A> * s2);
bool DivideNonConform(const Surface<A> *s2);
A Min() const;
A MinNode(size_t &i, size_t &j) const;
A Max() const;
A MaxNode(size_t &i, size_t &j) const;
A Avg() const;
// n_nodes is number of nodes with non-missing values.
A Avg(int& n_nodes) const;
/// Returns vector with the four corners around the point (x,y).
/// Fails if failOutside is false and either ni or nj is greater than 2^31.
/// \param[out] corners The corners of the cell containing (x,y) or missing_val_ if
/// the given corner is outside the grid, or does not have a valid
/// value.
inline void GetCorners(double x,
double y,
A corners[4]) const;
/// Returns the arithmetic average of the up to 8 (non-missing)-values from neighbouring grid cells.
/// If no neighborud cells have non-missing values, missing is returned.
bool CreateNeighbourAvg(size_t i, size_t j);
/// Gets the index to left of x.
/// The found index corresponds to the cell index.
inline size_t FindI(double x) const;
/// Gets the index to left of x.
/// The found index corresponds to the cell index.
inline size_t FindJ(double y) const;
/// Gets the index for the nearest point up, and to the left of
/// (x,y), the corner point with the lowest i and j values.
/// The found index corresponds to the cell index.
inline void FindIndex(double x, double y, size_t& i, size_t& j) const;
// Find continuous index
void FindContIndex(double x, double y, double& i, double& j) const;
/// Gets the index for the nearest point up, and to the left of
/// (x,y), the corner point with the lowest i and j values.
/// May give values outside the grid.
/// Fails if either ni or nj is greater than 2^31.
/// The found index corresponds to the cell index.
inline void FindGeneralIndex(double x, double y, int& i, int& j) const;
/// Find nearest node.
/// Similar to FindIndex, but finds index of nearest node instead of cell index.
inline void FindNearestNodeIndex(double x, double y, size_t& i, size_t& j) const;
double GetX(size_t i) const
{ return x_min_ + i*dx_; }
double GetY(size_t j) const
{ return y_min_ + j*dy_; }
void GetXY(size_t i, size_t j, double & x, double & y) const {
x = x_min_ + i*dx_;
y = y_min_ + j*dy_;
}
void GetXY(size_t index, double & x, double & y) const {
size_t j = index / this->GetNI();
size_t i = index - j*this->GetNI();
GetXY(i, j, x, y);
}
void GetNode(size_t index, double& x, double& y, double& z) const {
size_t i, j;
this->GetIJ(index, i, j);
GetNode(i, j, x, y, z);
}
void GetNode(size_t i, size_t j, double& x, double& y, double& z) const {
GetXY(i, j, x, y);
z = (*this)(i, j);
}
double GetXMin() const { return x_min_; }
double GetYMin() const { return y_min_; }
double GetXMax() const { return x_min_ + lx_; }
double GetYMax() const { return y_min_ + ly_; }
double GetDX() const { return dx_; }
double GetDY() const { return dy_; }
double GetLengthX() const { return lx_; }
double GetLengthY() const { return ly_; }
void SetDimensions(double x_min, double y_min,
double lx, double ly);
/// Resize grid. Overrides Grid2D's resize.
void Resize(size_t ni, size_t nj, const A& val = A());
/// Check if grid value is missing
bool IsMissing(A val) const {
return val == missing_val_;
}
// Change names:
// IsMissing(A) ==> EqualsMissingValue(A) ??
// IsMissingAt(i,j) ==> GetMissingAt(i,j)
// SetMissing(i,j) ==> SetMissingAt(i,j)
/// Check if grid value is missing
bool IsMissingAt(size_t i, size_t j) const {
return (*this)(i, j) == missing_val_;
}
/// Set missing
void SetMissing(size_t i, size_t j) {
(*this)(i, j) = missing_val_;
}
A GetMissingValue() const { return missing_val_ ;}
void SetMissingValue(A missing_val) { missing_val_ = missing_val; }
const std::string& GetName() const { return name_; }
void SetName(const std::string& name) { name_ = name; }
/// \brief Read surface file on given format.
/// \param filename File name.
/// \param format File format. If SURF_UNKNOWN we try to determine the format.
/// \throws IOError If we failed to open the file
/// \throws FileFormatError If we can not determine the file format, or the contents
/// of the file does not match the file format.
void ReadFromFile(const std::string& filename,
SurfaceFileFormat format = SURF_UNKNOWN);
void WriteToFile(const std::string& filename,
SurfaceFileFormat format = SURF_STORM_BINARY) const;
void Swap(RegularSurface<A>& other);
private:
double CellRelX(double x) const;
double CellRelY(double y) const;
double x_min_;
double y_min_;
double lx_;
double ly_;
double dx_;
double dy_;
// double rotation_;
/// Fault name. Usually obtained from filename.
std::string name_;
/// Missing value
A missing_val_;
inline static A GetBilinearZ(A corners[4], double u, double v);
/// Bilinear interpolation with missing corner.
inline A GetBilinearZMissingCorners(A corners[4], double u, double v) const;
};
// ==================== TEMPLATE IMPLEMENTATIONS ====================
template <class A>
RegularSurface<A>::RegularSurface()
: Grid2D<A>(0, 0),
x_min_(0),
y_min_(0),
lx_(0),
ly_(0),
dx_(0),
dy_(0),
missing_val_(static_cast<A>(-999.0))
{}
template <class A>
RegularSurface<A>::RegularSurface(double x_min, double y_min,
double lx, double ly,
size_t nx, size_t ny,
const A& value)
: Grid2D<A>(nx, ny, value),
x_min_(x_min),
y_min_(y_min),
lx_(lx),
ly_(ly),
missing_val_(static_cast<A>(-999.0))
{
dx_ = (nx > 1) ? lx / (nx-1) : 1.0;
dy_ = (ny > 1) ? ly / (ny-1) : 1.0;
}
template <class A>
RegularSurface<A>::RegularSurface(double x_min, double y_min,
double lx, double ly,
Grid2D<A> grid)
: Grid2D<A>(grid),
x_min_(x_min),
y_min_(y_min),
lx_(lx),
ly_(ly),
missing_val_(static_cast<A>(-999.0))
{
size_t ni = grid.GetNI();
size_t nj = grid.GetNJ();
dx_ = (ni > 1) ? lx / (ni-1) : 1.0;
dy_ = (nj > 1) ? ly / (nj-1) : 1.0;
}
template <class A>
RegularSurface<A>::RegularSurface(const std::string& filename,
SurfaceFileFormat format)
: lx_(0.0),
ly_(0.0),
missing_val_(static_cast<A>(-999.0))
{
ReadFromFile(filename, format);
}
/// \todo Move to a more suitable location.
template <class A>
A RegularSurface<A>::GetBilinearZ(A corners[4], double u, double v)
{
A a = corners[0];
A b = corners[1] - a;
A c = corners[2] - a;
A d = corners[3] - a - b - c;
return static_cast<A>(a + b*u + c*v + d*u*v);
}
template <class A>
A RegularSurface<A>::GetBilinearZMissingCorners(A corners[4], double u, double v) const
{
double weights[4];
weights[0] = (1.0-u) * (1.0-v);
weights[1] = u * (1.0 - v);
weights[2] = (1.0-u) * v;
weights[3] = u * v;
double sum = 0.0;
double sum_weights = 0.0;
for (size_t i = 0; i < 4; ++i) {
if (!IsMissing(corners[i])) {
sum += weights[i] * corners[i];
sum_weights += weights[i];
}
}
if (sum_weights == 0.0) {
return GetMissingValue();
}
return static_cast<A>(sum / sum_weights);
}
template <class A>
A RegularSurface<A>::GetZ(double x, double y) const
{
A corner[4];
GetCorners(x, y, corner);
int n_missing = 0;
for (int pix = 0; pix < 4; pix++)
{
if (IsMissing(corner[pix]))
n_missing++;
}
if (n_missing == 4) {
return(missing_val_);
}
else {
double x1 = CellRelX(x);
double y1 = CellRelY(y);
if (n_missing == 0) {
return GetBilinearZ(corner, x1, y1);
}
else {
return GetBilinearZMissingCorners(corner, x1, y1);
}
}
}
template <class A>
A RegularSurface<A>::GetZInside(double x, double y) const
{
A corner[4];
GetCorners(x, y, corner);
bool missing = false;
int pix = 0;
while (pix < 4 && !missing) {
if (IsMissing(corner[pix]))
missing = true;
pix++;
}
if (missing)
return(missing_val_);
else {
double x1 = CellRelX(x);
double y1 = CellRelY(y);
return GetBilinearZ(corner, x1, y1);
}
}
template <class A>
bool RegularSurface<A>::IsInsideSurface(double x, double y) const
{
if (x < GetXMin() || x > GetXMax() || y < GetYMin() || y > GetYMax())
return false;
return true;
}
template <class A>
bool RegularSurface<A>::AddNonConform(const Surface<A> * s2)
{
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val_) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) += value;
else
(*this)(i) = missing_val_;
}
}
return(true);
}
template <class A>
bool RegularSurface<A>::SubtractNonConform(const Surface<A> * s2)
{
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val_) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) -= value;
else
(*this)(i) = missing_val_;
}
}
return(true);
}
template <class A>
bool RegularSurface<A>::MultiplyNonConform(const Surface<A> * s2)
{
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val_) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) *= value;
else
(*this)(i) = missing_val_;
}
}
return(true);
}
template <class A>
bool RegularSurface<A>::DivideNonConform(const Surface<A> * s2)
{
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val_) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) /= value;
else
(*this)(i) = missing_val_;
}
}
return(true);
}
template <class A>
A RegularSurface<A>::Min() const
{
A minVal = (*this)(0);
typename std::vector<A>::const_iterator i;
for (i = this->begin(); i < this->end(); i++) {
if ((IsMissing(minVal) || (*i) < minVal) && IsMissing(*i) == false)
minVal = *i;
}
return minVal;
}
template <class A>
A RegularSurface<A>::MinNode(size_t &i, size_t &j) const
{
A minVal = (*this)(0);
typename std::vector<A>::const_iterator it;
size_t min_index = 0;
for (it = this->begin(); it < this->end(); it++) {
if ((IsMissing(minVal) || (*it) < minVal) && IsMissing(*it) == false) {
minVal = *it;
min_index = static_cast<size_t> (it - this->begin());
}
}
this->GetIJ(min_index, i, j);
return minVal;
}
template <class A>
A RegularSurface<A>::Max() const
{
A maxVal = (*this)(0);
typename std::vector<A>::const_iterator i;
for (i = this->begin(); i < this->end(); i++) {
if ((IsMissing(maxVal) || (*i) > maxVal) && IsMissing(*i) == false)
maxVal = *i;
}
return maxVal;
}
template <class A>
A RegularSurface<A>::MaxNode(size_t &i, size_t &j) const
{
A maxVal = (*this)(0);
typename std::vector<A>::const_iterator it;
size_t max_index = 0;
for (it = this->begin(); it < this->end(); it++) {
if ((IsMissing(maxVal) || (*it) > maxVal) && IsMissing(*it) == false) {
maxVal = *it;
max_index = static_cast<size_t> (it - this->begin());
}
}
this->GetIJ(max_index, i, j);
return maxVal;
}
template <class A>
A RegularSurface<A>::Avg() const
{
int n;
return Avg(n);
}
template <class A>
A RegularSurface<A>::Avg(int& n_nodes) const
{
A sum = static_cast<A>(0);
int count = 0;
typename std::vector<A>::const_iterator i;
for (i = this->begin(); i < this->end(); i++) {
if (!IsMissing(*i)) {
sum += *i;
count++;
}
}
double avg;
if (count > 0)
avg = sum / count;
else
avg = missing_val_;
n_nodes = count;
return avg;
}
template <class A>
bool RegularSurface<A>::EnclosesRectangle(double x_min, double x_max,
double y_min, double y_max) const
{
if (x_min < GetXMin() || x_max > GetXMax() ||
y_min < GetYMin() || y_max > GetYMax()) {
return false;
}
return true;
}
template <class A>
size_t RegularSurface<A>::FindI(double x) const
{
assert (x >= GetXMin() && x <= GetXMax());
return static_cast<size_t>( (x-GetXMin()) / GetDX() );
}
template <class A>
size_t RegularSurface<A>::FindJ(double y) const
{
assert (y >= GetYMin() && y <= GetYMax());
return static_cast<size_t>( (y-GetYMin()) / GetDY() );
}
template <class A>
void RegularSurface<A>::FindIndex(double x, double y, size_t& i, size_t& j) const
{
assert(x >= GetXMin() && x <= GetXMax() &&
y >= GetYMin() && y <= GetYMax());
i = static_cast<size_t>( (x-GetXMin()) / GetDX() );
j = static_cast<size_t>( (y-GetYMin()) / GetDY() );
}
template <class A>
void RegularSurface<A>::FindContIndex(double x, double y, double& i, double& j) const
{
assert(x >= GetXMin() && x <= GetXMax() &&
y >= GetYMin() && y <= GetYMax());
i = (x-GetXMin()) / GetDX() ;
j = (y-GetYMin()) / GetDY() ;
}
template <class A>
void RegularSurface<A>::FindGeneralIndex(double x, double y, int& i, int& j) const
{
i = static_cast<int>(std::floor( (x-GetXMin()) / GetDX() ));
j = static_cast<int>(std::floor( (y-GetYMin()) / GetDY() ));
}
template <class A>
void RegularSurface<A>::FindNearestNodeIndex(double x, double y, size_t& i, size_t& j) const
{
int tmp_i, tmp_j;
int ni = static_cast<int>(this->GetNI());
int nj = static_cast<int>(this->GetNJ());
FindGeneralIndex(x + 0.5*dx_, y + 0.5*dy_, tmp_i, tmp_j);
if (tmp_i < 0)
tmp_i = 0;
else if (tmp_i >= ni)
tmp_i = ni - 1;
if (tmp_j < 0)
tmp_j = 0;
else if (tmp_j >= nj)
tmp_j = nj - 1;
i = static_cast<size_t>(tmp_i);
j = static_cast<size_t>(tmp_j);
}
template <class A>
void RegularSurface<A>::GetCorners(double x,
double y,
A corners[4]) const
{
int i, j;
int ni = static_cast<int>(this->GetNI());
int nj = static_cast<int>(this->GetNJ());
FindGeneralIndex(x, y, i , j);
if (i+1 >= 0 && i < ni && j+1 >= 0 && j < nj) {
if (i >= 0 && j >= 0)
corners[0] = (*this)(i, j);
else
corners[0] = missing_val_;
if (i+1 < ni && j >= 0)
corners[1] = (*this)(i+1, j);
else
corners[1] = missing_val_;
if (i >= 0 && j+1 < nj)
corners[2] = (*this)(i, j+1);
else
corners[2] = missing_val_;
if (i+1 < ni && j+1 < nj)
corners[3] = (*this)(i+1, j+1);
else
corners[3] = missing_val_;
}
else {
corners[0] = missing_val_;
corners[1] = missing_val_;
corners[2] = missing_val_;
corners[3] = missing_val_;
}
}
template <class A>
bool RegularSurface<A>::CreateNeighbourAvg(size_t i, size_t j)
{
double sum = 0.0;
int n = 0;
if (i > 0) {
if (j > 0) {
if (!IsMissingAt(i-1,j-1)) {
sum += (*this)(i-1,j-1);
n++;
}
}
if (j < this->GetNJ() - 1) {
if (!IsMissingAt(i-1,j+1)) {
sum += (*this)(i-1,j+1);
n++;
}
}
if (!IsMissingAt(i-1,j)) {
sum += (*this)(i-1,j);
n++;
}
}
if (i < this->GetNI() - 1) {
if (j > 0) {
if (!IsMissingAt(i+1,j-1)) {
sum += (*this)(i+1,j-1);
n++;
}
}
if (j < this->GetNJ() - 1) {
if (!IsMissingAt(i+1,j+1)) {
sum += (*this)(i+1,j+1);
n++;
}
}
if (!IsMissingAt(i+1,j)) {
sum += (*this)(i+1,j);
n++;
}
}
if (j > 0) {
if (!IsMissingAt(i,j-1)) {
sum += (*this)(i,j-1);
n++;
}
}
if (j < this->GetNJ() - 1) {
if (!IsMissingAt(i,j+1)) {
sum += (*this)(i,j+1);
n++;
}
}
double avg = missing_val_;
bool non_missing = false;
if (n > 0) {
avg = sum / n;
non_missing = true;
}
(*this)(i,j) = avg;
return (non_missing);
}
template <class A>
void RegularSurface<A>::SetDimensions(double x_min, double y_min,
double lx, double ly)
{
x_min_ = x_min;
y_min_ = y_min;
lx_ = lx;
ly_ = ly;
size_t ni = Grid2D<A>::GetNI();
size_t nj = Grid2D<A>::GetNJ();
dx_ = (ni > 1) ? lx / (ni - 1) : 1.0;
dy_ = (nj > 1) ? ly / (nj - 1) : 1.0;
}
template <class A>
void RegularSurface<A>::Resize(size_t nx, size_t ny, const A& value)
{
Grid2D<A>::Resize(nx, ny, value);
dx_ = (nx > 1) ? lx_ / (nx-1) : 1.0;
dy_ = (ny > 1) ? ly_ / (ny-1) : 1.0;
}
template <class A>
void RegularSurface<A>::ReadFromFile(const std::string& filename,
SurfaceFileFormat format)
{
if (format == SURF_UNKNOWN) {
format = FindSurfaceFileType(filename);
if (format == SURF_UNKNOWN) {
throw FileFormatError("Failed to determine file format for surface file: " + filename);
}
}
double angle = 0.0;
switch (format) {
case SURF_IRAP_CLASSIC_ASCII:
ReadIrapClassicAsciiSurf(filename, *this, angle);
break;
case SURF_STORM_BINARY:
ReadStormBinarySurf(filename, *this);
break;
case SURF_SGRI:
ReadSgriSurf(filename, *this, angle);
break;
default:
throw FileFormatError("Reading of file " + filename + " on format " + ToString(format)
+ " as non-rotated grid is currently not supported.");
}
if (angle != 0.0) {
throw FileFormatError("Error reading regular surface: " + filename
+ ". Rotated grids are not supported.");
}
}
template <class A>
void RegularSurface<A>::WriteToFile(const std::string& filename,
SurfaceFileFormat format) const
{
switch (format) {
case SURF_IRAP_CLASSIC_ASCII:
WriteIrapClassicAsciiSurf(*this, 0.0, filename);
break;
case SURF_STORM_BINARY:
WriteStormBinarySurf(*this, filename);
break;
default:
throw FileFormatError("Writing of surface to file " + filename + " on format "
+ ToString(format) + " is currently not supported.");
}
}
template <class A>
double RegularSurface<A>::CellRelX(double x) const
{
double i;
return std::modf((x-GetXMin())/GetDX(), &i);
}
template <class A>
double RegularSurface<A>::CellRelY(double y) const
{
double j;
return std::modf((y-GetYMin())/GetDY(), &j);
}
template <class A>
void RegularSurface<A>::Swap(NRLib::RegularSurface<A> &other)
{
Grid2D<A>::Swap(other);
std::swap(x_min_, other.x_min_);
std::swap(y_min_, other.y_min_);
std::swap(lx_, other.lx_);
std::swap(ly_, other.ly_);
std::swap(dx_, other.dx_);
std::swap(dy_, other.dy_);
std::swap(name_, other.name_);
std::swap(missing_val_, other.missing_val_);
}
} // namespace NRLib
#endif // NRLIB_REGULARSURFACE_HPP

View File

@@ -0,0 +1,595 @@
// $Id: regularsurfacerotated.hpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_REGULARSURFACEROTATED_HPP
#define NRLIB_REGULARSURFACEROTATED_HPP
#include "surface.hpp"
#include "regularsurface.hpp"
#include "../grid/grid2d.hpp"
#include "../iotools/stringtools.hpp"
#include <cmath>
#include <algorithm>
namespace NRLib {
template <class A>
class RegularSurfaceRotated : public Surface<A> {
public:
RegularSurfaceRotated();
RegularSurfaceRotated(double x0,
double y0,
double lx,
double ly,
size_t nx,
size_t ny,
double angle,
const A& value = A());
RegularSurfaceRotated(const RegularSurface<A>& surface, double angle);
RegularSurfaceRotated(double x0, double y0, double lx, double ly, Grid2D<A> grid, double angle);
/// \brief Read surface file on given format.
/// \param filename File name.
/// \param format File format. If SURF_UNKNOWN we try to determine the format.
/// \throws IOError If we failed to open the file
/// \throws FileFormatError If we can not determine the file format, or the contents
/// of the file does not match the file format.
RegularSurfaceRotated(std::string filename,
SurfaceFileFormat format = SURF_UNKNOWN,
double angle = 0.0,
double x_ref = 0.0,
double y_ref = 0.0,
double lx = 0.0,
double ly = 0.0,
int * ilxl_area = NULL,
double il0_ref = 0.0,
double xl0_ref = 0.0);
Surface<A>* Clone() const
{ return new RegularSurfaceRotated<A>(*this); }
typedef typename std::vector<A>::iterator iterator;
iterator begin() { return surface_.begin(); }
iterator end() { return surface_.end(); }
typedef typename std::vector<A>::const_iterator const_iterator;
const_iterator begin() const { return surface_.begin(); }
const_iterator end() const { return surface_.end(); }
typedef typename std::vector<A>::reference reference;
inline reference operator()(size_t i, size_t j) { return surface_(i,j); }
inline reference operator()(size_t index) { return surface_(index); }
typedef typename std::vector<A>::const_reference const_reference;
inline const_reference operator()(size_t i, size_t j) const { return surface_(i,j); }
inline const_reference operator()(size_t index) const { return surface_(index); }
/// Return z. Returns missing if we are outside the grid.
/// Returns also values when not all grid cell corners are present,
/// e.g. when (x,y) is just outside the grid.
A GetZ(double x, double y) const;
/// Return z. Returns missing if not all grid cell corners are present,
/// e.g. when (x,y) is just outside the grid.
A GetZInside(double x, double y) const;
/// Checks if point is inside definition area for surface.
bool IsInsideSurface(double x, double y) const;
bool EnclosesRectangle(double x_min, double x_max,
double y_min, double y_max) const;
/// Sets all values on the surface to a constant value.
void Assign(A c) {surface_.Assign(c);}
void Add(A c) { surface_.Add(c);}
void Subtract(A c) {surface_.Subtract(c);}
void Multiply(A c) {surface_.Multiply(c);}
void GetXY(size_t i, size_t j, double & x, double & y) const;
void GetXY(size_t index, double & x, double & y) const;
double GetDX() const { return surface_.GetDX(); }
double GetDY() const { return surface_.GetDY(); }
double GetLengthX() const { return surface_.GetLengthX(); }
double GetLengthY() const { return surface_.GetLengthY(); }
void SetDimensions(double x_min, double y_min,
double lx, double ly);
/// Resize grid. Overrides Grid2D's resize.
void Resize(size_t ni, size_t nj, const A& val = A());
size_t GetNI() const { return surface_.GetNI(); }
size_t GetNJ() const { return surface_.GetNJ(); }
size_t GetN() const { return surface_.GetN(); }
/// Check if grid value is missing
bool IsMissing(A val) const { return surface_.IsMissing(val); }
bool IsMissingAt(size_t i, size_t j) const { return surface_.IsMissingAt(i, j); }
void SetMissing(size_t i, size_t j) { surface_.SetMissing(i, j); }
A Min() const { return surface_.Min(); }
A Max() const { return surface_.Max(); }
A Avg() const { return surface_.Avg(); }
A Avg(int& n_nodes) const { return surface_.Avg(n_nodes); }
///The following routines are for binary operations with non-conform grids.
///Missing areas will shrink.
///Also works for identical definitions without missing, but is inefficient.
bool AddNonConform(const Surface<A> * s2);
bool SubtractNonConform(const Surface<A> * s2);
bool MultiplyNonConform(const Surface<A> * s2);
bool DivideNonConform(const Surface<A> *s2);
double GetXRef() const { return x_ref_; }
double GetYRef() const { return y_ref_; }
double GetXMin() const { return x_min_; }
double GetYMin() const { return y_min_; }
double GetXMax() const { return x_max_; }
double GetYMax() const { return y_max_; }
RegularSurface<A> ResampleSurface() const ;
double GetAngle() const { return angle_ ;}
void SetAngle(double angle) { angle_ = angle ;}
A GetMissingValue() const { return surface_.GetMissingValue() ;}
void SetMissingValue(A missing_val) { surface_.SetMissingValue(missing_val); }
// We do not want to use the following methods if possible
// RegularSurface<A> GetSurface() const {return surface_;}
// Grid2D<A> GetSurfaceGrid2D() const { return surface_;}
const std::string& GetName() const { return surface_.GetName(); }
void SetName(const std::string& name) { surface_.SetName(name); }
/// \brief Read surface file on given format.
/// \param filename File name.
/// \param format File format. If SURF_UNKNOWN we try to determine the format.
/// \throws IOError If we failed to open the file
/// \throws FileFormatError If we can not determine the file format, or the contents
/// of the file does not match the file format.
void ReadFromFile(std::string filename,
SurfaceFileFormat format = SURF_UNKNOWN,
double angle = 0.0,
double x_ref = 0.0,
double y_ref = 0.0,
double lx = 0.0,
double ly = 0.0,
int * ilxl_area = NULL,
double il0_ref = 0.0,
double xl0_ref = 0.0);
/// \brief Write surface to file on given format.
/// If the file format does not support rotation, the resampled surface is written to file.
/// \throws IOError If we failed to open the file
void WriteToFile(const std::string& filename,
SurfaceFileFormat format = SURF_STORM_BINARY) const;
private:
void GlobalToLocalCoord(double global_x,
double global_y,
double& local_x,
double& local_y) const;
void LocalToGlobalCoord(double local_x,
double local_y,
double& global_x,
double& global_y) const;
void CalculateMinMaxXY();
RegularSurface<A> surface_;
double angle_;
double x_ref_;
double y_ref_;
double x_min_;
double y_min_;
double x_max_;
double y_max_;
};
// ==================== TEMPLATE IMPLEMENTATIONS ====================
template <class A>
RegularSurfaceRotated<A>::RegularSurfaceRotated()
:angle_(0),
x_ref_(0.0),
y_ref_(0.0)
{
surface_ = RegularSurface<A>();
CalculateMinMaxXY();
}
template <class A>
RegularSurfaceRotated<A>::RegularSurfaceRotated(double x_min, double y_min,
double lx, double ly,
size_t nx, size_t ny, double angle,
const A& value)
: angle_(angle),
x_ref_(x_min),
y_ref_(y_min)
{
surface_ = RegularSurface<A>(x_min, y_min, lx, ly, nx, ny, value);
CalculateMinMaxXY();
}
template <class A>
RegularSurfaceRotated<A>::RegularSurfaceRotated(const RegularSurface<A>& surface, double angle)
: angle_(angle)
{
surface_ = surface;
x_ref_ = surface.GetXMin();
y_ref_ = surface.GetYMin();
CalculateMinMaxXY();
}
template <class A>
RegularSurfaceRotated<A>::RegularSurfaceRotated(double x_min, double y_min,
double lx, double ly,
Grid2D<A> grid, double angle)
: angle_(angle),
x_ref_(x_min),
y_ref_(y_min)
{
surface_ = RegularSurface<A>(x_min, y_min, lx, ly, grid);
CalculateMinMaxXY();
}
template <class A>
RegularSurfaceRotated<A>::RegularSurfaceRotated(std::string filename,
SurfaceFileFormat format,
double angle,
double x_ref,
double y_ref,
double lx,
double ly,
int * ilxl_area,
double il0_ref,
double xl0_ref)
{
ReadFromFile(filename,
format,
angle,
x_ref,
y_ref,
lx,
ly,
ilxl_area,
il0_ref,
xl0_ref);
}
template <class A>
void
RegularSurfaceRotated<A>::GlobalToLocalCoord(double global_x,
double global_y,
double& local_x,
double& local_y) const
{
double x_rel = global_x - x_ref_;
double y_rel = global_y - y_ref_;
local_x = std::cos(angle_)*x_rel + std::sin(angle_)*y_rel ;
local_y = - std::sin(angle_)*x_rel + std::cos(angle_)*y_rel ;
}
template <class A>
void RegularSurfaceRotated<A>::LocalToGlobalCoord(double local_x,
double local_y,
double& global_x,
double& global_y) const
{
global_x = std::cos(angle_)*local_x - std::sin(angle_)*local_y + x_ref_;
global_y = std::sin(angle_)*local_x + std::cos(angle_)*local_y + y_ref_;
}
template <class A>
A RegularSurfaceRotated<A>::GetZ(double x, double y) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
A z = surface_.GetZ(local_x+x_ref_, local_y+y_ref_);
return z;
}
template <class A>
A RegularSurfaceRotated<A>::GetZInside(double x, double y) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
A z = surface_.GetZInside(local_x+x_ref_, local_y+y_ref_);
return z;
}
template <class A>
bool RegularSurfaceRotated<A>::IsInsideSurface(double x, double y) const
{
double local_x, local_y;
GlobalToLocalCoord(x, y, local_x, local_y);
bool z = surface_.IsInsideSurface(local_x+x_ref_, local_y+y_ref_);
return z;
}
template <class A>
bool RegularSurfaceRotated<A>::AddNonConform(const Surface<A> * s2)
{
A missing_val = surface_.GetMissingValue();
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) += value;
else
(*this)(i) = missing_val;
}
}
return(true);
}
template <class A>
bool RegularSurfaceRotated<A>::SubtractNonConform(const Surface<A> * s2)
{
A missing_val = surface_.GetMissingValue();
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) -= value;
else
(*this)(i) = missing_val;
}
}
return(true);
}
template <class A>
bool RegularSurfaceRotated<A>::MultiplyNonConform(const Surface<A> * s2)
{
A missing_val = surface_.GetMissingValue();
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) *= value;
else
(*this)(i) = missing_val;
}
}
return(true);
}
template <class A>
bool RegularSurfaceRotated<A>::DivideNonConform(const Surface<A> * s2)
{
A missing_val = surface_.GetMissingValue();
for (size_t i = 0; i < this->GetN(); i++) {
if ((*this)(i) != missing_val) {
double x, y, value;
GetXY(i, x, y);
value = s2->GetZ(x, y);
if (s2->IsMissing(value) == false)
(*this)(i) /= value;
else
(*this)(i) = missing_val;
}
}
return(true);
}
template <class A>
bool RegularSurfaceRotated<A>::EnclosesRectangle(double x_min, double x_max,
double y_min, double y_max) const
{
if (x_min < GetXMin() || x_max > GetXMax() ||
y_min < GetYMin() || y_max > GetYMax()) {
return false;
}
return true;
}
template <class A>
void RegularSurfaceRotated<A>::CalculateMinMaxXY()
{
std::vector<double> x(4);
std::vector<double> y(4);
LocalToGlobalCoord(0, 0, x[0], y[0]);
LocalToGlobalCoord(surface_.GetLengthX(), 0, x[1], y[1]);
LocalToGlobalCoord(0, surface_.GetLengthY(), x[2], y[2]);
LocalToGlobalCoord(surface_.GetLengthX(), surface_.GetLengthY(), x[3], y[3]);
x_min_ = *(std::min_element(x.begin(), x.end()));
y_min_ = *(std::min_element(y.begin(), y.end()));
x_max_ = *(std::max_element(x.begin(), x.end()));
y_max_ = *(std::max_element(y.begin(), y.end()));
}
template <class A>
void RegularSurfaceRotated<A>::SetDimensions(double x_min, double y_min,
double lx, double ly)
{
surface_.SetDimensions(x_min, y_min, lx, ly);
x_ref_ = x_min;
y_ref_ = y_min;
CalculateMinMaxXY();
}
template <class A>
void RegularSurfaceRotated<A>::Resize(size_t nx, size_t ny, const A& value)
{
surface_.Resize(nx, ny, value);
}
template <class A>
void RegularSurfaceRotated<A>::GetXY(size_t i, size_t j, double & x, double & y) const
{
double x_tmp, y_tmp;
surface_.GetXY(i,j,x_tmp,y_tmp);
double x_loc = x_tmp - x_ref_;
double y_loc = y_tmp - y_ref_;
LocalToGlobalCoord(x_loc,y_loc,x,y);
}
template <class A>
void RegularSurfaceRotated<A>::GetXY(size_t index, double & x, double & y) const
{
double x_tmp, y_tmp;
surface_.GetXY(index,x_tmp,y_tmp);
double x_loc = x_tmp - x_ref_;
double y_loc = y_tmp - y_ref_;
LocalToGlobalCoord(x_loc,y_loc,x,y);
}
template <class A>
RegularSurface<A> RegularSurfaceRotated<A>::ResampleSurface() const
{
double dx = surface_.GetDX()*cos(angle_);
double dy = surface_.GetDY()*cos(angle_);
int nx = int((x_max_-x_min_)/dx) + 1;
int ny = int((y_max_-y_min_)/dy) +1;
RegularSurface<A> surf(x_min_, y_min_, x_max_-x_min_, y_max_-y_min_, nx, ny, 0.0);
surf.SetMissingValue(GetMissingValue());
A value;
double x,y;
int i,j;
for(i=0;i<nx;i++)
for(j=0;j<ny;j++)
{
x = x_min_ + i*dx;
y = y_min_ + j*dy;
value = GetZ(x,y);
surf(i,j) = value;
}
return surf;
}
template <class A>
void RegularSurfaceRotated<A>::ReadFromFile(std::string filename,
SurfaceFileFormat format,
double segy_angle,
double x_ref,
double y_ref,
double lx,
double ly,
int * ilxl_area,
double il0_ref,
double xl0_ref)
{
if (format == SURF_UNKNOWN) {
format = FindSurfaceFileType(filename);
if (format == SURF_UNKNOWN) {
throw FileFormatError("Failed to determine file format for surface file: " + filename);
}
}
switch (format) {
case SURF_IRAP_CLASSIC_ASCII:
ReadIrapClassicAsciiSurf(filename, surface_, angle_);
break;
case SURF_STORM_BINARY:
ReadStormBinarySurf(filename, surface_);
angle_ = 0.0;
break;
case SURF_SGRI:
ReadSgriSurf(filename, surface_, angle_);
break;
case SURF_MULT_ASCII:
ReadMulticolumnAsciiSurf(filename,
surface_,
x_ref,
y_ref,
lx,
ly,
ilxl_area,
il0_ref,
xl0_ref);
angle_ = segy_angle;
break;
default:
throw FileFormatError("Reading of file " + filename + " on format " + ToString(format)
+ " as a rotated grid is currently not supported.");
}
x_ref_ = surface_.GetXMin();
y_ref_ = surface_.GetYMin();
CalculateMinMaxXY();
}
template <class A>
void RegularSurfaceRotated<A>::WriteToFile(const std::string& filename,
SurfaceFileFormat format) const
{
switch (format) {
case SURF_IRAP_CLASSIC_ASCII:
WriteIrapClassicAsciiSurf(surface_, angle_, filename);
break;
case SURF_STORM_BINARY:
{
if (angle_ != 0.0) {
RegularSurface<A> resampled_surf = ResampleSurface();
WriteStormBinarySurf(resampled_surf, filename);
}
else {
WriteStormBinarySurf(surface_, filename);
}
}
break;
default:
throw FileFormatError("Writing of surface to file " + filename + " on format "
+ ToString(format) + " is currently not supported.");
}
}
}
#endif

View File

@@ -0,0 +1,136 @@
// $Id: surface.hpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_SURFACE_HPP
#define NRLIB_SURFACE_HPP
#include <limits>
namespace NRLib {
template <class A>
class Surface {
public:
virtual ~Surface();
/// \brief Generate a copy of the underlying object.
virtual Surface * Clone() const = 0;
virtual A GetZ(double x, double y) const = 0;
virtual bool EnclosesRectangle(double x_min, double x_max,
double y_min, double y_max) const = 0;
virtual bool IsMissing(A) const { return(false) ;}
virtual bool IsInsideSurface(double /*x*/, double /*y*/) const = 0;
virtual void Add(A c) = 0;
virtual void Multiply(A c) = 0;
virtual A Min() const = 0;
virtual A Max() const = 0;
virtual double GetXMin() const = 0;
virtual double GetYMin() const = 0;
virtual double GetXMax() const = 0;
virtual double GetYMax() const = 0;
};
template <class A>
class ConstantSurface : public Surface<A> {
public:
ConstantSurface(A z);
Surface<A>* Clone() const
{ return new ConstantSurface(*this); }
A GetZ() const {
return z_;
}
bool IsInsideSurface(double /*x*/, double /*y*/) const {return(true);}
A GetZ(double /*x*/, double /*y*/) const
{ return z_; }
bool EnclosesRectangle(double /*x_min*/, double /*x_max*/,
double /*y_min*/, double /*y_max*/) const
{ return true; }
void Add(A c) {
z_ += c;
}
void Multiply(A c) {
z_ *= c;
}
A Min() const {return(z_);}
A Max() const {return(z_);}
double GetXMin() const
{
if ( std::numeric_limits<double>::has_infinity )
return -std::numeric_limits<double>::infinity();
else
return -std::numeric_limits<double>::max();
}
double GetYMin() const
{
if ( std::numeric_limits<double>::has_infinity )
return -std::numeric_limits<double>::infinity();
else
return -std::numeric_limits<double>::max();
}
double GetXMax() const
{
if ( std::numeric_limits<double>::has_infinity )
return(std::numeric_limits<double>::infinity());
else
return std::numeric_limits<double>::max();
}
double GetYMax() const
{
if ( std::numeric_limits<double>::has_infinity )
return(std::numeric_limits<double>::infinity());
else
return std::numeric_limits<double>::max();
}
private:
A z_;
};
template <class A>
Surface<A>::~Surface()
{}
template <class A>
ConstantSurface<A>::ConstantSurface(A z)
: z_(z)
{}
} // namespace NRLib
#endif // NRLIB_SURFACE_HPP

View File

@@ -0,0 +1,325 @@
// $Id: surfaceio.cpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cmath>
#include <fstream>
#include <string>
#include "surfaceio.hpp"
#include "regularsurface.hpp"
#include "regularsurfacerotated.hpp"
#include "surface.hpp"
#include "../exception/exception.hpp"
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
namespace NRLib {
//const double IRAP_MISSING = 9999900.0;
//const double STORM_MISSING = -999.0;
namespace NRLibPrivate {
/// \todo Move to a suitable place
bool Equal(double a, double b)
{
if ( fabs(a-b) <= 0.0001 * a ) {
return true;
}
return false;
}
} // namespace NRLibPrivate
SurfaceFileFormat FindSurfaceFileType(const std::string& filename)
{
std::ifstream file;
OpenRead(file, filename, std::ios::in | std::ios::binary);
std::string first_token;
if (!(file >> first_token)) {
// Empty file.
return SURF_UNKNOWN;
}
if (first_token == "-996")
return SURF_IRAP_CLASSIC_ASCII;
else if (first_token == "STORMGRID_BINARY")
return SURF_STORM_BINARY;
else if (first_token == "NORSAR") {
std::string token;
file >> token;
file >> token;
file >> token;
file >> token;
if(token == "v1.0" ||token == "v2.0" )
return SURF_SGRI;
}
else if (IsType<double>(first_token)) {
file.seekg(0, std::ios_base::beg);
std::string line;
std::getline(file, line);
std::vector<std::string> tokens = GetTokens(line);
if (tokens.size() == 3) {
// Check last line of file.
file.seekg(0, std::ios_base::end);
std::streampos file_len = file.tellg();
std::streampos offset = std::min(static_cast<std::streampos>(50), file_len);
file.seekg(-offset, std::ios_base::end);
tokens.clear();
while (std::getline(file, line)) {
if (GetTokens(line).size() > 0) {
tokens = GetTokens(line);
}
}
if (tokens.size() == 3) {
try {
if (ParseType<double>(tokens[0]) == 999.0 &&
ParseType<double>(tokens[1]) == 999.0 &&
ParseType<double>(tokens[2]) == 999.0) {
return SURF_RMS_POINTS_ASCII;
}
}
catch (Exception& ) {
// Do nothing - failed to parse tokens as doubles.
}
}
}
return SURF_UNKNOWN;
}
//Try multicolum ascii
int dummy;
bool is_multicolumn_ascii = FindMulticolumnAsciiLine(filename, dummy);
if (is_multicolumn_ascii == true)
return SURF_MULT_ASCII;
return SURF_UNKNOWN;
}
std::string GetSurfFormatString(NRLib::SurfaceFileFormat format)
{
switch (format) {
case SURF_UNKNOWN:
return "Unknown surface format";
case SURF_IRAP_CLASSIC_ASCII:
return "IRAP classic ASCII";
case SURF_STORM_BINARY:
return "Storm binary";
case SURF_SGRI:
return "NORSAR SGRI";
case SURF_RMS_POINTS_ASCII:
return "RMS XYZ point set surface";
case SURF_MULT_ASCII:
return "Multicolumn ASCII";
default:
throw Exception("Missing format description for format: " + ToString(format));
}
}
std::vector<RegularSurfaceRotated<float> >
ReadMultipleSgriSurf(const std::string& filename, const std::vector<std::string> & labels)
{
std::ifstream header_file;
OpenRead(header_file, filename.c_str(), std::ios::in | std::ios::binary);
int i, dim;
std::string tmp_str;
try {
//Reading record 1: Version header
getline(header_file, tmp_str);
//Reading record 2: Grid dimension
header_file >> dim;
if(dim!=2)
throw Exception("Wrong dimension of Sgri file. We expect a surface, dimension should be 2.\n");
getline(header_file, tmp_str);
//Reading record 3 ... 3+dim: Axis labels + grid value label
std::vector<std::string> axis_labels(dim);
std::string err_txt;
for (i=0; i<dim; i++) {
getline(header_file, axis_labels[i]);
if(labels.size() > static_cast<size_t>(i)) {
NRLib::Uppercase(axis_labels[i]);
NRLib::Uppercase(labels[i]);
if (axis_labels[i].find(labels[i]) == std::string::npos)
err_txt += "Wrong axis labels. Label for axis "+NRLib::ToString(i)+" should be '"+labels[i]+"'.\n";
}
}
getline(header_file, tmp_str);
//Reading record 4+dim: Number of grids
int n_grid;
header_file >> n_grid;
if (n_grid < 1) {
throw Exception("Error: Number of grids read from sgri file must be > 0");
}
getline(header_file, tmp_str);
//Reading record 5+dim ... 5+dim+ngrid-1: Grid labels
for (i=0; i<n_grid; i++)
getline(header_file, tmp_str);
std::vector<float> d_values1(dim);
std::vector<float> d_values2(dim);
std::vector<int> i_values(dim);
//Reading record 5+dim+ngrid: Scaling factor of grid values
for (i=0; i<dim; i++)
header_file >> d_values1[i];
getline(header_file,tmp_str);
//Reading record 6+dim+ngrid: Number of samples in each dir.
for (i=0; i<dim; i++)
header_file >> i_values[i];
getline(header_file,tmp_str);
//Reading record 7+dim+ngrid: Grid sampling in each dir.
for (i=0; i<dim; i++)
header_file >> d_values2[i];
getline(header_file,tmp_str);
//Reading record 8+dim+ngrid: First point coord.
std::vector<float> min_values(dim);
for (i=0; i<dim; i++)
header_file >> min_values[i];
int nx=1;
int ny=1;
double dx, dy;
nx = i_values[0];
dx = d_values2[0];
ny = i_values[1];
dy = d_values2[1];
if (nx < 1)
throw Exception("Error: Number of samples on first axis must be >= 1.\n");
if (ny < 1)
throw Exception("Error: Number of samples on second axis must be >= 1.\n");
if (dx <= 0.0)
throw Exception("Error: Grid sampling on first axis must be > 0.0.\n");
if (dy <= 0.0)
throw Exception("Error: Grid sampling on second axis must be > 0.0.\n");
double lx = (nx-1)*dx;
double ly = (ny-1)*dy;
double x_min = min_values[0]-0.5*dx;
double y_min = min_values[1]-0.5*dy;
double angle;
header_file >> angle;
getline(header_file, tmp_str);
//Reading record 10+dim+ngrid: Undef value
float missing_code;
header_file >> missing_code;
getline(header_file, tmp_str);
//Reading record 11+dim+ngrid: Filename of binary file
std::string bin_file_name;
getline(header_file, tmp_str);
if (!tmp_str.empty()) {
std::locale loc;
int i = 0;
char c = tmp_str[i];
while (!std::isspace(c,loc)) {
i++;
c = tmp_str[i];
}
tmp_str.erase(tmp_str.begin()+i, tmp_str.end());
}
if (tmp_str.empty())
bin_file_name = NRLib::ReplaceExtension(filename, "Sgri");
else {
std::string path = GetPath(filename);
bin_file_name = path + "/" + tmp_str;
}
//Reading record 12+dim+ngrid: Complex values
bool has_complex;
header_file >> has_complex;
if (has_complex != 0 ) {
throw Exception("Error: Can not read Sgri binary file. Complex values?");
}
std::vector<RegularSurfaceRotated<float> > surfaces(n_grid);
std::ifstream bin_file;
OpenRead(bin_file, bin_file_name.c_str(), std::ios::in | std::ios::binary);
for (i=0; i<n_grid; i++) {
surfaces[i] = RegularSurfaceRotated<float>(x_min,y_min,lx,ly,nx,ny,angle,0.0f);
surfaces[i].SetMissingValue(missing_code);
ReadBinaryFloatArray(bin_file, surfaces[i].begin(), surfaces[i].GetN());
}
return surfaces;
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"Sgri surface file " + e.what() + "\n");
}
}
bool FindMulticolumnAsciiLine(const std::string& filename, int & header_start_line)
{
//Contains five columns: X, Y, IL, CL, Attribute
//File starts with several information lines
std::ifstream file;
NRLib::OpenRead(file, filename);
int line = 0;
//Find first line with five numbers
bool found_mult_ascii_line = false;
while (found_mult_ascii_line == false) {
//Read line
std::string line_string;
std::getline(file, line_string);
std::vector<std::string> tokens = NRLib::GetTokens(line_string);
//Check if the line has five number elements
if (tokens.size() == 5) {
for (int i = 0; i < 5; i++) {
if (!NRLib::IsNumber(tokens[i])) {
found_mult_ascii_line = false;
break;
}
else
found_mult_ascii_line = true;
}
}
line++;
}
file.close();
header_start_line = line -2;
return found_mult_ascii_line;
}
//void WritePointAsciiSurf(const RegularSurface<double>& surf,
// const std::string& filename);
} // namespace NRLib

View File

@@ -0,0 +1,727 @@
// $Id: surfaceio.hpp 1232 2014-01-13 12:22:40Z gudmundh $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_SURFACEIO_HPP
#define NRLIB_SURFACEIO_HPP
#include <string>
#include <vector>
#include <locale>
namespace NRLib {
template <class A> class RegularSurface;
template <class A> class RegularSurfaceRotated;
template <class A> class Grid2D;
const double MULT_IRAP_MISSING = -999.25;
const double IRAP_MISSING = 9999900.0;
const double STORM_MISSING = -999.0;
enum SurfaceFileFormat {
SURF_UNKNOWN,
SURF_IRAP_CLASSIC_ASCII,
SURF_STORM_BINARY,
SURF_SGRI,
SURF_RMS_POINTS_ASCII,
SURF_MULT_ASCII
// SURF_PLAIN_ASCII
// SURF_CPS3_ASCII
};
/// \brief Find type of file.
SurfaceFileFormat FindSurfaceFileType(const std::string& filename);
/// \brief String describing file format
std::string GetSurfFormatString(SurfaceFileFormat format);
template <class A>
void ReadStormBinarySurf(const std::string & filename,
RegularSurface<A> & surface);
template <class A>
void ReadIrapClassicAsciiSurf(const std::string & filename,
RegularSurface<A> & surface,
double & angle);
template <class A>
void ReadSgriSurf(const std::string & filename,
RegularSurface<A> & surface,
double & angle);
// If labels is non-empty, the labels of the axes on the file are compared with these. Throws if mismatch.
std::vector<RegularSurfaceRotated<float> > ReadMultipleSgriSurf(const std::string& filename,
const std::vector<std::string> & labels);
template <class A>
void ReadMulticolumnAsciiSurf(std::string filename,
RegularSurface<A> & surface,
double x_ref,
double y_ref,
double lx,
double ly,
int * ilxl_area,
double il0_ref,
double xl0_ref);
template <class A>
void WriteIrapClassicAsciiSurf(const RegularSurface<A> & surf,
double angle,
const std::string & filename);
template <class A>
void WriteStormBinarySurf(const RegularSurface<A> & surf,
const std::string & filename);
bool FindMulticolumnAsciiLine(const std::string& filename, int & header_start_line);
// void WritePointAsciiSurf(const RegularSurface<double>& surf,
// const std::string& filename);
namespace NRLibPrivate {
/// \todo Move to a suitable place
bool Equal(double a, double b);
}
} // namespace NRLib
// ----------- TEMPLATE IMPLEMENTATIONS ----------------------
#include <fstream>
#include <string>
#include "regularsurface.hpp"
#include "surface.hpp"
#include "../exception/exception.hpp"
#include "../math/constants.hpp"
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
template<class A>
void NRLib::ReadStormBinarySurf(const std::string & filename,
RegularSurface<A> & surface)
{
std::ifstream file;
OpenRead(file, filename.c_str(), std::ios::in | std::ios::binary);
int line = 0;
// Header
try {
std::string token = ReadNext<std::string>(file, line);
if (token != "STORMGRID_BINARY") {
throw FileFormatError("Error reading " + filename + ", file is not "
"in STORM binary format.");
}
int ni = ReadNext<int>(file, line);
int nj = ReadNext<int>(file, line);
double dx = ReadNext<double>(file, line);
double dy = ReadNext<double>(file, line);
double x_min = ReadNext<double>(file, line);
double x_max = ReadNext<double>(file, line);
double y_min = ReadNext<double>(file, line);
double y_max = ReadNext<double>(file, line);
double lx = x_max - x_min;
double ly = y_max - y_min;
if (!NRLibPrivate::Equal(lx/(ni-1), dx)) {
throw FileFormatError("Inconsistent data in file. dx != lx/(nx-1).");
}
if (!NRLibPrivate::Equal(ly/(nj-1), dy)) {
throw FileFormatError("Inconsistent data in file. dy != ly/(ny-1).");
}
surface.Resize(ni, nj);
surface.SetDimensions(x_min, y_min, lx, ly);
DiscardRestOfLine(file, line, true);
ReadBinaryDoubleArray(file, surface.begin(), surface.GetN());
surface.SetMissingValue(static_cast<A>(STORM_MISSING));
if (!CheckEndOfFile(file)) {
throw FileFormatError("File too long.");
}
surface.SetName(GetStem(filename));
}
catch (EndOfFile& ) {
throw FileFormatError("Unexcpected end of file found while parsing "
" \"" + filename + "\"");
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"STORM surface file at line " + ToString(line) + ":" + e.what() + "\n");
}
}
template <class A>
void NRLib::ReadIrapClassicAsciiSurf(const std::string & filename,
RegularSurface<A> & surface,
double & angle)
{
std::ifstream file;
OpenRead(file, filename);
int line = 0;
// Header
try {
ReadNext<int>(file, line); // -996
int nj = ReadNext<int>(file, line);
double dx = ReadNext<double>(file, line);
double dy = ReadNext<double>(file, line);
// ----------- line shift --------------
double x_min = ReadNext<double>(file, line);
double x_max = ReadNext<double>(file, line);
double y_min = ReadNext<double>(file, line);
double y_max = ReadNext<double>(file, line);
// ----------- line shift --------------
int ni = ReadNext<int>(file, line);
angle = ReadNext<double>(file, line);
angle = NRLib::Degree*angle;
ReadNext<double>(file, line); // rotation origin - x
ReadNext<double>(file, line); // rotation origin - y
// ----------- line shift --------------
ReadNext<int>(file, line);
ReadNext<int>(file, line);
ReadNext<int>(file, line);
ReadNext<int>(file, line);
ReadNext<int>(file, line);
ReadNext<int>(file, line);
ReadNext<int>(file, line);
//double lx = (ni-1)*dx;
//double ly = (nj-1)*dy;
double lx = (x_max - x_min)*cos(angle);
double ly = (y_max - y_min)*cos(angle);
if (!NRLibPrivate::Equal(lx/(ni-1), dx)) {
std::string text = "Inconsistent data in file. dx != lx/(nx-1).\n";
text += "dx = "+NRLib::ToString(dx,2)+"\n";
text += "lx = "+NRLib::ToString(lx,2)+"\n";
text += "nx = "+NRLib::ToString(ni,0)+"\n";
text += "lx/(nx-1) = "+NRLib::ToString(lx/(ni - 1),2);
throw FileFormatError(text);
}
if (!NRLibPrivate::Equal(ly/(nj-1), dy)) {
std::string text = "Inconsistent data in file. dy != ly/(ny-1).\n";
text += "dy = "+NRLib::ToString(dy,2)+"\n";
text += "ly = "+NRLib::ToString(ly,2)+"\n";
text += "ny = "+NRLib::ToString(nj,0)+"\n";
text += "ly/(ny-1) = "+NRLib::ToString(ly/(nj - 1),2);
throw FileFormatError(text);
}
surface.Resize(ni, nj);
surface.SetDimensions(x_min, y_min, lx, ly);
ReadAsciiArrayFast(file, surface.begin(), surface.GetN());
surface.SetMissingValue(static_cast<A>(IRAP_MISSING));
surface.SetName(GetStem(filename));
if (!CheckEndOfFile(file)) {
throw FileFormatError("File too long.");
}
}
catch (EndOfFile& ) {
throw FileFormatError("Unexcpected end of file found while parsing "
" \"" + filename + "\"");
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"IRAP ASCII surface file at line " + ToString(line) + ":" + e.what() + "\n");
}
}
template<class A>
void NRLib::ReadSgriSurf(const std::string & filename,
RegularSurface<A> & surface,
double & angle)
{
std::ifstream header_file;
OpenRead(header_file, filename.c_str(), std::ios::in | std::ios::binary);
int i;
std::string tmp_str;
int dim;
try {
//Reading record 1: Version header
getline(header_file, tmp_str);
//Reading record 2: Grid dimension
header_file >> dim;
if(dim!=2)
throw Exception("Wrong dimension of Sgri file. We expect a surface, dimension should be 2.\n");
getline(header_file, tmp_str);
//Reading record 3 ... 3+dim: Axis labels + grid value label
std::vector<std::string> axis_labels(dim);
for (i=0; i<dim; i++)
getline(header_file, axis_labels[i]);
if (((axis_labels[0].find("X") == std::string::npos) && (axis_labels[0].find("x") == std::string::npos)) ||
((axis_labels[1].find("Y") == std::string::npos) && (axis_labels[1].find("y") == std::string::npos)))
throw Exception("Wrong axis labels. First axis should be x-axis, second axis should be y-axis.\n");
// if((axis_labels[0]!="X" && axis_labels[0] !="x") || (axis_labels[1]!="Y" && axis_labels[1]!="y"))
// throw Exception("Wrong axis labels. First axis should be x-axis, second axis should be y-axis.\n");
getline(header_file, tmp_str);
//int config = IMISSING;
//Reading record 4+dim: Number of grids
int n_grid;
header_file >> n_grid;
if (n_grid < 1) {
throw Exception("Error: Number of grids read from sgri file must be >0");
}
getline(header_file, tmp_str);
//Reading record 5+dim ... 5+dim+ngrid-1: Grid labels
for (i=0; i<n_grid; i++)
getline(header_file, tmp_str);
std::vector<float> d_values1(dim);
std::vector<float> d_values2(dim);
std::vector<int> i_values(dim);
//Reading record 5+dim+ngrid: Scaling factor of grid values
for (i=0; i<dim; i++)
header_file >> d_values1[i];
getline(header_file,tmp_str);
//Reading record 6+dim+ngrid: Number of samples in each dir.
for (i=0; i<dim; i++)
header_file >> i_values[i];
getline(header_file,tmp_str);
//Reading record 7+dim+ngrid: Grid sampling in each dir.
for (i=0; i<dim; i++) {
header_file >> d_values2[i];
}
getline(header_file,tmp_str);
//Reading record 8+dim+ngrid: First point coord.
std::vector<float> min_values(dim);
for (i=0; i<dim; i++)
{
header_file >> min_values[i];
}
int nx = 1;
int ny = 1;
double dx, dy;
nx = i_values[0];
dx = d_values2[0];
ny = i_values[1];
dy = d_values2[1];
if (nx < 1) {
throw Exception("Error: Number of samples in X-dir must be >= 1.\n");
}
if (ny < 1) {
throw Exception("Error: Number of samples in Y-dir must be >= 1.\n");
}
if (dx <= 0.0) {
throw Exception("Error: Grid sampling in X-dir must be > 0.0.\n");
}
if (dy <= 0.0) {
throw Exception("Error: Grid sampling in Y-dir must be > 0.0.\n");
}
double lx = nx*dx;
double ly = ny*dy;
double x_min = min_values[0]-0.5*dx; //In regular grid, these are at value;
double y_min = min_values[1]-0.5*dy; //in sgri, at corner of cell, hence move.
header_file >> angle;
surface.Resize(nx, ny, 0.0);
surface.SetDimensions(x_min, y_min, lx, ly);
getline(header_file, tmp_str);
//Reading record 10+dim+ngrid: Undef value
float missing_code;
header_file >> missing_code;
surface.SetMissingValue(missing_code);
getline(header_file, tmp_str);
//Reading record 11+dim+ngrid: Filename of binary file
std::string bin_file_name;
getline(header_file, tmp_str);
if (!tmp_str.empty()) {
std::locale loc;
int i = 0;
char c = tmp_str[i];
while (!std::isspace(c,loc)) {
i++;
c = tmp_str[i];
}
tmp_str.erase(tmp_str.begin()+i, tmp_str.end());
}
if (tmp_str.empty())
bin_file_name = NRLib::ReplaceExtension(filename, "Sgri");
else {
std::string path = GetPath(filename);
bin_file_name = path + "/" + tmp_str;
}
//Reading record 12+dim+ngrid: Complex values
bool has_complex;
header_file >> has_complex;
if (has_complex != 0 ) {
throw Exception("Error: Can not read Sgri binary file. Complex values?");
}
surface.SetName(GetStem(bin_file_name));
std::ifstream bin_file;
OpenRead(bin_file, bin_file_name, std::ios::in | std::ios::binary);
ReadBinaryFloatArray(bin_file, surface.begin(), surface.GetN());
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"Sgri surface file " + e.what() + "\n");
}
}
template <class A>
void NRLib::ReadMulticolumnAsciiSurf(std::string filename,
RegularSurface<A> & surface,
double x_ref,
double y_ref,
double lx,
double ly,
int * ilxl_area,
double il0_ref,
double xl0_ref)
{
try {
//Create surface with area corresponding to segy-grid (ilxl_area), but use sampling from surface file
//il0_ref and xl0_ref are il/xl values at rotation corner, this is used to match IL/XL values from surface with segy
int header_start_line;
bool is_multicolumn_ascii = false;
is_multicolumn_ascii = FindMulticolumnAsciiLine(filename, header_start_line);
if (is_multicolumn_ascii == false)
throw Exception("Error: Did not recognize file as a multicolumns ascii file.\n");
std::ifstream file;
NRLib::OpenRead(file, filename);
int line = 0;
for (int i = 0; i < header_start_line; i++) {
NRLib::DiscardRestOfLine(file, line, false);
}
//Header line, contains X, Y, Z, Inline, Crossline
std::vector<std::string> variable_names(5);
variable_names[0] = NRLib::ReadNext<std::string>(file, line);
variable_names[1] = NRLib::ReadNext<std::string>(file, line);
variable_names[2] = NRLib::ReadNext<std::string>(file, line);
variable_names[3] = NRLib::ReadNext<std::string>(file, line);
variable_names[4] = NRLib::ReadNext<std::string>(file, line);
std::vector<std::vector<double> > data(5);
while (NRLib::CheckEndOfFile(file)==false) {
for (int i = 0; i < 5; i++) {
data[i].push_back(NRLib::ReadNext<double>(file, line));
}
}
int il_index = -1;
int xl_index = -1;
int x_index = -1;
int y_index = -1;
int z_index = -1;
for (int i = 0; i < 5; i++) {
if (variable_names[i] == "Inline" || variable_names[i] == "IL")
il_index = i;
if (variable_names[i] == "Crossline" || variable_names[i] == "XL")
xl_index = i;
if (variable_names[i] == "X" || variable_names[i] == "UTMX")
x_index = i;
if (variable_names[i] == "Y" || variable_names[i] == "UTMY")
y_index = i;
if (variable_names[i] == "Attribute" || variable_names[i] == "Z" || variable_names[i] == "TWT")
z_index = i;
}
std::string err_txt = "";
if (il_index == -1)
err_txt += "Could not find variable name for Inline in file " + filename +". (Tried Inline, IL).\n";
if (xl_index == -1)
err_txt += "Could not find variable name for Crossline in file " + filename +". (Tried Crossline, XL).\n";
if (x_index == -1)
err_txt += "Could not find variable name for X in file " + filename +". (Tried X, UTMX).\n";
if (y_index == -1)
err_txt += "Could not find variable name for Y in file " + filename +". (Tried Y, UTMY).\n";
if (z_index == -1)
err_txt += "Could not find variable name for Attribute in file " + filename +". (Tried Attribute, Z, TWT).\n";
if (err_txt != "")
throw Exception("Error when finding header information in " + filename + " :" + err_txt + "\n");
std::vector<double> il_vec = data[il_index];
std::vector<double> xl_vec = data[xl_index];
std::vector<double> x_vec = data[x_index];
std::vector<double> y_vec = data[y_index];
std::vector<double> z_vec = data[z_index];
//Find min and max IL/XL
std::vector<double> il_vec_sorted = il_vec;
std::sort(il_vec_sorted.begin(), il_vec_sorted.end());
il_vec_sorted.erase(std::unique(il_vec_sorted.begin(), il_vec_sorted.end()), il_vec_sorted.end());
std::vector<double> xl_vec_sorted = xl_vec;
std::sort(xl_vec_sorted.begin(), xl_vec_sorted.end());
xl_vec_sorted.erase(std::unique(xl_vec_sorted.begin(), xl_vec_sorted.end()), xl_vec_sorted.end());
int ni_file = static_cast<int>(il_vec_sorted.size());
int nj_file = static_cast<int>(xl_vec_sorted.size());
int il_min_file = static_cast<int>(il_vec_sorted[0]);
int il_max_file = static_cast<int>(il_vec_sorted[ni_file-1]);
int xl_min_file = static_cast<int>(xl_vec_sorted[0]);
int xl_max_file = static_cast<int>(xl_vec_sorted[nj_file-1]);
int n = static_cast<int>(data[0].size());
A missing = static_cast<A>(NRLib::MULT_IRAP_MISSING);
NRLib::Grid2D<A> ilxl_grid_file(ni_file, nj_file, missing);
int d_il_file = static_cast<int>((il_max_file - il_min_file) / (ni_file - 1));
int d_xl_file = static_cast<int>((xl_max_file - xl_min_file) / (nj_file - 1));
for (int k = 0; k < n; k++) {
//Local IL/XL
int il_loc = (static_cast<int>(data[il_index][k]) - il_min_file)/d_il_file;
int xl_loc = (static_cast<int>(data[xl_index][k]) - xl_min_file)/d_xl_file;
ilxl_grid_file(il_loc, xl_loc) = static_cast<A>(data[z_index][k]);
}
//Check consistency between IL/XL sampling in surface and sampling of grid values
int t1 = 0;
int t2 = 0;
for (int i = 0; i < ni_file; i++) {
if (ilxl_grid_file(i,nj_file/2) != missing) {
t1 = i;
for (int k = t1+1; k < ni_file; k++) {
if (ilxl_grid_file(k,nj_file/2) != missing) {
t2 = k;
k = ni_file-1;
i = ni_file-1;
}
}
}
}
int diff_il = (t2 - t1)*d_il_file;
t1 = 0;
t2 = 0;
for (int j = 0; j < nj_file; j++) {
if (ilxl_grid_file(ni_file/2,j) != missing) {
t1 = j;
for (int k = t1+1; k < nj_file; k++) {
if (ilxl_grid_file(ni_file/2,k) != missing) {
t2 = k;
k = nj_file-1;
j = nj_file-1;
}
}
}
}
int diff_xl = (t2 - t1)*d_xl_file;
if (diff_il != d_il_file) {
err_txt += "Found sampling of IL-values to be " + NRLib::ToString(d_il_file) +
", but grid values are given with a IL-sampling of " + NRLib::ToString(diff_il) + ".\n";
}
if (diff_xl != d_xl_file) {
err_txt += "Found sampling of XL-values to be " + NRLib::ToString(d_xl_file) +
", but grid values are given with a XL-sampling of " + NRLib::ToString(diff_xl) + ".\n";
}
if (err_txt != "")
throw Exception(err_txt);
int il_min_segy = ilxl_area[0];
int il_max_segy = ilxl_area[1];
int xl_min_segy = ilxl_area[2];
int xl_max_segy = ilxl_area[3];
int il_step_segy = ilxl_area[4];
int xl_step_segy = ilxl_area[5];
//Create IL/XL surface as large as segy geometry, but with sampling from file
int n_il = (il_max_segy - il_min_segy)/d_il_file + 1;
int n_xl = (xl_max_segy - xl_min_segy)/d_xl_file + 1;
//Find IL/XL of rotation corner
int il0_segy = static_cast<int>(il0_ref+0.5);
int xl0_segy = static_cast<int>(xl0_ref+0.5);
// To ensure that the IL XL we find are existing traces
if (il0_segy < il_min_segy)
il0_segy -= (il0_segy - il_min_segy) % il_step_segy;
else if (il0_segy > il_max_segy)
il0_segy += (il_max_segy - il0_segy) % il_step_segy;
if (xl0_segy < xl_min_segy)
xl0_segy -= (xl0_segy - xl_min_segy) % xl_step_segy;
else if (xl0_segy > xl_max_segy)
xl0_segy += (xl_max_segy - xl0_segy) % xl_step_segy;
NRLib::Grid2D<A> surface_grid(n_il, n_xl, static_cast<A>(NRLib::MULT_IRAP_MISSING));
int grid_i, grid_j;
for (int i = 0; i < n_il; i++) {
for (int j = 0; j < n_xl; j++) {
//Global IL/XL of surface_grid
int il_glob = il_min_segy + i*d_il_file;
int xl_glob = xl_min_segy + j*d_xl_file;
//Get corresponding IL/XL from file_grid
int il_loc_file = (il_glob - il_min_file)/d_il_file;
int xl_loc_file = (xl_glob - xl_min_file)/d_xl_file;
//If surface is smaller than segy-grid, we set is as missing
A z;
if (il_loc_file < 0 || il_loc_file > ni_file-1 || xl_loc_file < 0 || xl_loc_file > nj_file-1)
z = missing;
else
z = ilxl_grid_file(il_loc_file, xl_loc_file);
//Fill in correct corner
if (il0_segy == il_min_segy && xl0_segy == xl_min_segy) {
grid_i = i;
grid_j = j;
}
else if (il0_segy == il_max_segy && xl0_segy == xl_max_segy) {
grid_i = n_il - i - 1;
grid_j = n_xl - j - 1;
}
else if (il0_segy == il_min_segy && xl0_segy == xl_max_segy) {
grid_i = i;
grid_j = n_xl - j - 1;
}
else { //il0_segy == il_max_segy && xl0_segy == xl_min_segy
grid_i = n_il - i - 1;
grid_j = j;
}
surface_grid(grid_i, grid_j) = z;
}
}
surface = RegularSurface<A>(x_ref, y_ref, lx, ly, surface_grid);
surface.SetMissingValue(static_cast<A>(MULT_IRAP_MISSING));
surface.SetName(GetStem(filename));
}
catch (Exception& e) {
throw FileFormatError("Error parsing \"" + filename + "\" as a "
"Multicolumn ASCII file: \n" + e.what() + "\n");
}
}
template <class A>
void NRLib::WriteIrapClassicAsciiSurf(const RegularSurface<A> & surf,
double angle,
const std::string & filename)
{
std::ofstream file;
OpenWrite(file, filename);
file << std::fixed
<< std::setprecision(6)
<< -996 << " "
<< surf.GetNJ() << " "
<< surf.GetDX() << " "
<< surf.GetDY() << "\n"
<< std::setprecision(2)
<< surf.GetXMin() << " "
<< surf.GetXMax() << " "
<< surf.GetYMin() << " "
<< surf.GetYMax() << "\n"
<< surf.GetNI() << " "
<< std::setprecision(6)
<< angle*180/NRLib::Pi << " "
<< std::setprecision(2)
<< surf.GetXMin() << " "
<< surf.GetYMin() << "\n"
<< " 0 0 0 0 0 0 0\n";
file.precision(6);
if (surf.GetMissingValue() == IRAP_MISSING) {
for (size_t i = 0; i < surf.GetN(); i++) {
file << surf(i) << " ";
if((i+1) % 6 == 0)
file << "\n";
}
}
else {
for (size_t i = 0; i < surf.GetN(); i++) {
if (surf.IsMissing(surf(i)))
file << IRAP_MISSING << " ";
else
file << surf(i) << " ";
if((i+1) % 6 == 0)
file << "\n";
}
}
file.close();
}
template <class A>
void NRLib::WriteStormBinarySurf(const RegularSurface<A> & surf,
const std::string & filename)
{
std::ofstream file;
OpenWrite(file, filename.c_str(), std::ios::out | std::ios::binary);
file.precision(14);
file << "STORMGRID_BINARY\n\n"
<< surf.GetNI() << " " << surf.GetNJ() << " "
<< surf.GetDX() << " " << surf.GetDY() << "\n"
<< surf.GetXMin() << " " << surf.GetXMax() << " "
<< surf.GetYMin() << " " << surf.GetYMax() << "\n";
if (surf.GetMissingValue() == STORM_MISSING) {
// Purify *sometimes* claims a UMR for the call below. No-one understands why...
WriteBinaryDoubleArray(file, surf.begin(), surf.end());
}
else {
std::vector<double> data(surf.GetN());
std::copy(surf.begin(), surf.end(), data.begin());
std::replace(data.begin(), data.end(), surf.GetMissingValue(), static_cast<A>(STORM_MISSING));
WriteBinaryDoubleArray(file, data.begin(), data.end());
}
file.close();
}
#endif // NRLIB_SURFACEIO_HPP

View File

@@ -0,0 +1 @@
SRC += $(NRLIB_BASE_DIR)volume/volume.cpp

592
ThirdParty/NRLib/nrlib/volume/volume.cpp vendored Normal file
View File

@@ -0,0 +1,592 @@
// $Id: volume.cpp 1061 2012-09-13 09:09:57Z georgsen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "volume.hpp"
#include <algorithm>
#include <cmath>
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
#include "../math/constants.hpp"
#include "../surface/regularsurface.hpp"
#include "../surface/regularsurfacerotated.hpp"
#include "../surface/surface.hpp"
#include "../surface/surfaceio.hpp"
using namespace NRLib;
Volume::Volume()
{
x_min_ = 0.0;
y_min_ = 0.0;
lx_ = 0.0;
ly_ = 0.0;
lz_ = 0.0;
angle_ = 0.0;
z_top_ = new ConstantSurface<double>(0.0);
z_bot_ = new ConstantSurface<double>(0.0);
tolerance_ = 1e-6;
}
Volume::Volume(double x_min, double y_min, double z_min, double lx, double ly, double lz, double angle)
: x_min_(x_min),
y_min_(y_min),
lx_(lx),
ly_(ly),
lz_(lz),
angle_(angle)
{
z_top_ = new ConstantSurface<double>(z_min);
z_bot_ = new ConstantSurface<double>(z_min+lz);
tolerance_ = 1e-6;
}
Volume::Volume(double x_min,
double y_min,
double lx,
double ly,
const Surface<double> & top,
const Surface<double> & bot,
double angle)
: x_min_(x_min),
y_min_(y_min),
lx_(lx),
ly_(ly),
angle_(angle)
{
z_top_ = top.Clone(),
z_bot_ = bot.Clone(),
lz_ = RecalculateLZ();
tolerance_ = 1e-6;
}
Volume::Volume(const Volume & volume)
{
x_min_ = volume.x_min_;
y_min_ = volume.y_min_;
lx_ = volume.lx_;
ly_ = volume.ly_;
lz_ = volume.lz_;
angle_ = volume.angle_;
if (volume.z_top_ != 0) {
z_top_ = volume.z_top_->Clone();
}
else {
z_top_ = 0;
}
if (volume.z_bot_ != 0) {
z_bot_ = volume.z_bot_->Clone();
}
else {
z_bot_ = 0;
}
tolerance_ = 1e-6;
}
Volume::~Volume()
{
delete z_top_;
delete z_bot_;
}
Volume& Volume::operator=(const Volume& rhs)
{
/// \todo Use "copy and swap" for exception safety.
if (this == &rhs) return *this;
x_min_ = rhs.x_min_;
y_min_ = rhs.y_min_;
lx_ = rhs.lx_;
ly_ = rhs.ly_;
lz_ = rhs.lz_;
angle_ = rhs.angle_;
tolerance_=rhs.tolerance_;
delete z_top_;
if (rhs.z_top_ != 0) {
z_top_ = rhs.z_top_->Clone();
}
else {
z_top_ = 0;
}
delete z_bot_;
if (rhs.z_bot_ != 0) {
z_bot_ = rhs.z_bot_->Clone();
}
else {
z_bot_ = 0;
}
/*
delete erosion_top_;
if (rhs.erosion_top_ != 0) {
erosion_top_ = rhs.erosion_top_->Clone();
}
else {
erosion_top_ = 0;
}
delete erosion_bot_;
if (rhs.erosion_bot_ != 0) {
erosion_bot_ = rhs.erosion_bot_->Clone();
}
else {
erosion_bot_ = 0;
}
*/
return *this;
}
void Volume::SetDimensions(double x_min, double y_min,
double lx, double ly)
{
x_min_ = x_min;
y_min_ = y_min;
lx_ = lx;
ly_ = ly;
CheckSurfaces();
lz_ = RecalculateLZ();
}
void Volume::SetAngle(double angle)
{
angle_ = angle;
CheckSurfaces();
lz_ = RecalculateLZ();
}
void Volume::SetSurfaces(const Surface<double>& top_surf,
const Surface<double>& bot_surf,
bool skip_check)
{
delete z_top_;
z_top_ = top_surf.Clone();
delete z_bot_;
z_bot_ = bot_surf.Clone();
if ((lx_ > 0.0 || ly_ > 0.0 ) && skip_check == false) { //Make sure area is set, and we need to check
CheckSurfaces();
}
lz_ = RecalculateLZ();
}
/*
void Volume::SetSurfaces(const Surface<double>& top_surf,
const Surface<double>& bot_surf)
//const Surface<double>& erosion_top,
//const Surface<double>& erosion_bot)
{
delete z_top_;
z_top_ = top_surf.Clone();
delete z_bot_;
z_bot_ = bot_surf.Clone();
delete erosion_top_;
erosion_top_ = erosion_top.Clone();
delete erosion_bot_;
erosion_bot_ = erosion_bot.Clone();
if (lx_ > 0.0 || ly_ > 0.0 ) { //Check that area is set.
CheckSurfaces();
}
lz_ = RecalculateLZ();
}
*/
double
Volume::GetZMin(size_t nx, size_t ny) const
{
return(GetTopZMin(nx, ny));
}
double
Volume::GetZMax(size_t nx, size_t ny) const
{
return(GetBotZMax(nx, ny));
}
double
Volume::GetTopZMin(size_t nx, size_t ny) const
{
return(GetZExtreme(nx,ny,z_top_,true));
}
double
Volume::GetTopZMax(size_t nx, size_t ny) const
{
return(GetZExtreme(nx,ny,z_top_,false));
}
double
Volume::GetBotZMin(size_t nx, size_t ny) const
{
return(GetZExtreme(nx,ny,z_bot_,true));
}
double
Volume::GetBotZMax(size_t nx, size_t ny) const
{
return(GetZExtreme(nx,ny,z_bot_,false));
}
double
Volume::GetZExtreme(size_t nx, size_t ny, const Surface<double> * surf, bool getmin) const
{
if (surf == NULL)
surf = z_top_;
double result;
if (lx_ > 0.0 || ly_ > 0.0 ) {//Check that area is set.
size_t i, j;
double di = lx_/static_cast<double>(nx);
double dj = ly_/static_cast<double>(ny);
double dxi = cos(angle_)*di;
double dyi = sin(angle_)*di;
double dxj = -sin(angle_)*dj;
double dyj = cos(angle_)*dj;
double x, y, z;
double x0 = x_min_+0.5*(dxi+dxj); //Cell center x
double y0 = y_min_+0.5*(dyi+dyj); //Cell center y
result = surf->GetZ(x0,y0);
for (j = 0; j < ny; j++) {
x = x0 + dxj*j;
y = y0 + dyj*j;
for (i = 0; i < nx; i++) {
z = surf->GetZ(x, y);
if (surf->IsMissing(z) == false && ( //Found actual value.
surf->IsMissing(result) == true || //Had no value
(getmin == true && z < result) || //Looking for min, found new.
(getmin == false && z > result))) //Looking for max, found new.
result = z;
x += dxi;
y+= dyi;
}
}
}
else {
if (getmin == true)
result = surf->Min();
else
result = surf->Max();
}
return(result);
}
void
Volume::FindCenter(double & x, double & y, double & z) const
{
x = GetXMin() + 0.5 * GetLX();
y = GetYMin() + 0.5 * GetLY();
z = 0.5 * (z_top_->GetZ(x,y) + z_bot_->GetZ(x,y));
}
// Writes surface to file if non-constant. Returns filename or
// surface level if surface is constant.
static std::string WriteSingleSurface(const Surface<double>* surf,
const std::string& grid_filename,
const std::string& surface_name,
bool remove_path
)
{
if (surf == 0) {
return "0";
}
if (typeid(*surf) == typeid(ConstantSurface<double>)) {
return (ToString((dynamic_cast<const ConstantSurface<double>*>(surf))->GetZ()));
}
else if (typeid(*surf) == typeid(RegularSurface<double>)) {
std::string filename = grid_filename + surface_name;
/// \todo Fix this.
// std::string filename = MainPart(grid_filename) + surface_name + ".s";
const RegularSurface<double>* rsurf
= dynamic_cast<const RegularSurface<double>*>(surf);
rsurf->WriteToFile(filename, SURF_STORM_BINARY);
if(remove_path)
return RemovePath(filename);
else
return filename;
}
else if (typeid(*surf) == typeid(RegularSurfaceRotated<double>)) {
std::string filename = grid_filename + surface_name;
/// \todo Fix this.
// std::string filename = MainPart(grid_filename) + surface_name + ".s";
const RegularSurfaceRotated<double>* rsurf
= dynamic_cast<const RegularSurfaceRotated<double>*>(surf);
rsurf->WriteToFile(filename, SURF_STORM_BINARY);
if(remove_path)
return RemovePath(filename);
else
return filename;
}
else {
throw Exception("Bug: Trying to write unsupported surface type to file.");
}
}
void Volume::WriteVolumeToFile(std::ofstream& file,
const std::string& filename, bool remove_path) const
{
file << x_min_ << " " << lx_ << " " << y_min_ << " " << ly_ << " "
<< WriteSingleSurface(z_top_, filename, "_top", remove_path) << " "
<< WriteSingleSurface(z_bot_, filename, "_bot", remove_path) << " "
// << WriteSingleSurface(erosion_top_, filename, "_erosion_top", remove_path) << " "
// << WriteSingleSurface(erosion_bot_, filename, "_erosion_bot", remove_path) << "\n"
<< GetLZ() << " " << (180.0*angle_)/NRLib::Pi << "\n";
}
void Volume::ReadVolumeFromFile(std::ifstream& file, int line, const std::string& path)
{
x_min_ = ReadNext<double>(file, line);
lx_ = ReadNext<double>(file, line);
y_min_ = ReadNext<double>(file, line);
ly_ = ReadNext<double>(file, line);
bool topfile, botfile;//, toperofile, boterofile;
std::string token = ReadNext<std::string>(file, line);
delete z_top_;
z_top_ = NULL;
if (IsType<double>(token)) {
z_top_ = new ConstantSurface<double>(ParseType<double>(token));
topfile = false;
} else {
std::string path_file_name = NRLib::PrependDir(path, token);
z_top_ = new RegularSurface<double>(path_file_name);
topfile = true;
}
token = ReadNext<std::string>(file, line);
delete z_bot_;
if (IsType<double>(token)) {
z_bot_ = new ConstantSurface<double>(ParseType<double>(token));
botfile = false;
} else {
std::string path_file_name = NRLib::PrependDir(path, token);
z_bot_ = new RegularSurface<double>(path_file_name);
botfile = true;
}
token = ReadNext<std::string>(file, line);
/*
delete erosion_top_;
if (IsType<double>(token)) {
erosion_top_ = new ConstantSurface<double>(ParseType<double>(token));
toperofile = false;
} else {
std::string path_file_name = NRLib::PrependDir(path, token);
erosion_top_ = new RegularSurface<double>(path_file_name);
toperofile = true;
}*/
token = ReadNext<std::string>(file, line);
/*
delete erosion_bot_;
if (IsType<double>(token)) {
erosion_bot_ = new ConstantSurface<double>(ParseType<double>(token));
boterofile = false;
} else {
std::string path_file_name = NRLib::PrependDir(path, token);
erosion_bot_ = new RegularSurface<double>(path_file_name);
boterofile = true;
}
*/
lz_ = ReadNext<double>(file, line);
angle_ = (NRLib::Pi * ReadNext<double>(file, line)) / 180.0;
if(topfile == true){
if (!CheckSurface(*z_top_)) {
throw Exception("The top surface does not fit with the volume.");
}
}
if(botfile == true){
if (!CheckSurface(*z_bot_)) {
throw Exception("The bottom surface does not fit with the volume.");
}
}
/*
if(toperofile == true){
if (!CheckSurface(*erosion_top_)) {
throw Exception("The erosion top surface does not fit with the volume.");
}
}
if(boterofile == true){
if (!CheckSurface(*erosion_bot_)) {
throw Exception("The erosion bottom surface does not fit with the volume.");
}
}
*/
}
void Volume::GlobalToLocalCoord(double global_x,
double global_y,
double& local_x,
double& local_y) const
{
double x_rel = global_x - x_min_;
double y_rel = global_y - y_min_;
local_x = std::cos(angle_)*x_rel + std::sin(angle_)*y_rel;
local_y = - std::sin(angle_)*x_rel + std::cos(angle_)*y_rel;
}
void Volume::LocalToGlobalCoord(double local_x,
double local_y,
double& global_x,
double& global_y) const
{
global_x = std::cos(angle_)*local_x - std::sin(angle_)*local_y + x_min_;
global_y = std::sin(angle_)*local_x + std::cos(angle_)*local_y + y_min_;
}
double Volume::RecalculateLZ()
{
double lz = 0.0;
if (lx_ > 0.0 || ly_ > 0.0) { //Only do if area is initialized.
// Just using a arbitary grid resolution.
int nx = 100;
int ny = 100;
double dx = lx_ / nx;
double dy = ly_ / ny;
double z_value_bot = 0.0;
double z_value_top = 0.0;
for (int i = 0; i < nx; ++i) {
for (int j = 0; j < ny; ++j) {
double x, y;
LocalToGlobalCoord(dx * i, dy * j, x, y);
z_value_bot = z_bot_->GetZ(x, y);
z_value_top = z_top_->GetZ(x, y);
if (z_bot_->IsMissing(z_value_bot) == false && z_top_->IsMissing(z_value_top) == false)
lz = std::max(lz, z_bot_->GetZ(x, y) - z_top_->GetZ(x, y));
}
}
}
return lz;
}
bool Volume::CheckSurface(const Surface<double>& surface) const
{
std::vector<double> x(4);
std::vector<double> y(4);
LocalToGlobalCoord( 0, 0, x[0], y[0]);
LocalToGlobalCoord(lx_, 0, x[1], y[1]);
LocalToGlobalCoord( 0, ly_, x[2], y[2]);
LocalToGlobalCoord(lx_, ly_, x[3], y[3]);
double x_min = *(std::min_element(x.begin(), x.end()));
double y_min = *(std::min_element(y.begin(), y.end()));
double x_max = *(std::max_element(x.begin(), x.end()));
double y_max = *(std::max_element(y.begin(), y.end()));
return surface.EnclosesRectangle(x_min, x_max, y_min, y_max);
}
bool Volume::CheckSurfaces() const
{
if (!CheckSurface(*z_top_)) {
throw Exception("The top surface does not cover the volume.");
}
if (!CheckSurface(*z_bot_)) {
throw Exception("The bottom surface does not cover the volume.");
}
/*
if (erosion_top_ && !CheckSurface(*erosion_top_)) {
throw Exception("The erosion top surface does not cover the volume.");
}
if (erosion_bot_ && !CheckSurface(*erosion_bot_)) {
throw Exception("The erosion bottom surface does not cover the volume.");
}
*/
return true;
}
int Volume::IsInsideTolerance(double x, double y)const
{
double rx = (x-x_min_)*cos(angle_)+(y-y_min_)*sin(angle_);
double ry = -(x-x_min_)*sin(angle_) + (y-y_min_)*cos(angle_);
if (rx+tolerance_ < 0.0 || rx-tolerance_ > lx_ || ry+tolerance_ <0.0 || ry-tolerance_ > ly_)
return(0);
else
return(1);
}
int Volume::IsInside(double x, double y)const
{
double rx = (x-x_min_)*cos(angle_)+(y-y_min_)*sin(angle_);
double ry = -(x-x_min_)*sin(angle_) + (y-y_min_)*cos(angle_);
if (rx < 0.0 || rx > lx_ || ry <0.0 || ry > ly_)
return(0);
else
return(1);
}
bool Volume::IsInside(double x, double y, double z)const
{
if (IsInside(x, y) &&
z > z_top_->GetZ(x, y) && z < z_bot_->GetZ(x, y)) {
return true;
}
return false;
}
bool Volume::IsInsideZTolerance(double x, double y, double z, double tolerance)const
{
if (IsInside(x, y) &&
z > (z_top_->GetZ(x, y) - tolerance) && z < (z_bot_->GetZ(x, y) + tolerance)) {
return true;
}
return false;
}

146
ThirdParty/NRLib/nrlib/volume/volume.hpp vendored Normal file
View File

@@ -0,0 +1,146 @@
// $Id: volume.hpp 1061 2012-09-13 09:09:57Z georgsen $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_VOLUME_HPP
#define NRLIB_VOLUME_HPP
#include <fstream>
namespace NRLib {
template <class A>
class Surface;
class Volume {
public:
Volume();
Volume(double x_min, double y_min, double z_min, double lx, double ly, double lz, double angle);
/// \brief Constructor with surfaces.
Volume(double x_min,
double y_min,
double lx,
double ly,
const Surface<double> & top,
const Surface<double> & bot,
double angle);
Volume(const Volume& volume);
virtual ~Volume();
Volume& operator=(const Volume& rhs);
void SetDimensions(double x_min, double y_min,
double lx, double ly);
void SetAngle(double angle);
void SetTolerance(double tolerance){tolerance_=tolerance;}
double GetTolerance(){return tolerance_;}
double GetXMin() const {return x_min_;}
double GetYMin() const {return y_min_;}
/// \brief Get extreme values of z for volume, with nx, ny resolution.
double GetZMin(size_t nx, size_t ny) const;
double GetZMax(size_t nx, size_t ny) const;
double GetLX() const {return lx_;}
double GetLY() const {return ly_;}
double GetAngle() const {return angle_;}
/// \brief Maximum height of grid.
double GetLZ() const {return lz_;}
/// rel_x and rel_y in [0,1].
void GetXYFromRelative(double rel_x, double rel_y, double &x, double &y) const{
LocalToGlobalCoord(rel_x*lx_, rel_y*ly_, x, y);
}
/// \brief Get z-range for top and bottom surfaces, with nx, ny resolution.
double GetTopZMin(size_t nx, size_t ny) const; //Equal to GetZMin
double GetTopZMax(size_t nx, size_t ny) const;
double GetBotZMin(size_t nx, size_t ny) const;
double GetBotZMax(size_t nx, size_t ny) const; //Equal to GetZMax
/// \brief Set surfaces.
void SetSurfaces(const Surface<double>& top_surf,
const Surface<double>& bot_surf,
bool skip_check = true); //Sometimes, we do not want an area cover check here.
/*
void SetSurfaces(const Surface<double>& top_surf,
const Surface<double>& bot_surf);
const Surface<double>& erosion_top,
const Surface<double>& erosion_bot);
*/
const Surface<double> & GetTopSurface() const {return *z_top_;}
const Surface<double> & GetBotSurface() const {return *z_bot_;}
//const Surface<double>& GetErosionTop() const {return *erosion_top_;}
//const Surface<double>& GetErosionBot() const {return *erosion_bot_;}
Surface<double> & GetTopSurface() {return *z_top_;}
Surface<double> & GetBotSurface() {return *z_bot_;}
int IsInside(double x, double y) const;
bool IsInside(double x, double y, double z)const;
int IsInsideTolerance(double x, double y)const;
bool IsInsideZTolerance(double x, double y, double z, double tolerance) const;
void FindCenter(double & x, double & y, double & z) const;
/// \brief Checks if surface covers the whole volume.
bool CheckSurface(const Surface<double>& surface) const;
protected:
/// \brief Reader and writer on storm-format.
/// \todo Maybe move to storm-specific files.
void WriteVolumeToFile(std::ofstream& file,
const std::string& filename,
bool remove_path = true) const;
void ReadVolumeFromFile(std::ifstream& file, int line, const std::string& path);
/// \brief The local coorinates are (0,0) in (x_min, y_min), and
/// have the same orientation as the volume.
void GlobalToLocalCoord(double global_x, double global_y,
double& local_x, double& local_y) const;
void LocalToGlobalCoord(double local_x, double local_y,
double& global_x, double& global_y) const;
private:
virtual double RecalculateLZ();
/// \brief Check all surfaces.
bool CheckSurfaces() const;
/// \brief Returns min or max of surface on nx by ny grid in volume.
double GetZExtreme(size_t nx, size_t ny, const Surface<double> * surf, bool getmin) const;
double x_min_;
double y_min_;
double lx_;
double ly_;
double lz_;
Surface<double>* z_top_;
Surface<double>* z_bot_;
//Surface<double>* erosion_top_;
//Surface<double>* erosion_bot_;
double angle_;
double tolerance_;
};
} // namespace NRLib
#endif // NRLIB_VOLUME_HPP

535
ThirdParty/NRLib/nrlib/well/laswell.cpp vendored Normal file
View File

@@ -0,0 +1,535 @@
// $Id: laswell.cpp 1245 2014-02-25 09:57:02Z hauge $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cassert>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include "laswell.hpp"
#include "../iotools/fileio.hpp"
#include "../iotools/stringtools.hpp"
using namespace NRLib;
LasWell::LasWell(const std::string & filename) :
version_("Unknown"),
wrap_(false),
comma_delimited_(false),
depth_unit_("Unknown"),
start_depth_(0),
stop_depth_(0),
depth_increment_(0)
{
std::string err_txt;
std::ifstream fin;
try {
ReadHeader(filename, fin, err_txt);
if(err_txt == "") {
if(fin.eof() == false)
ReadLogs(fin, err_txt);
else
err_txt = "No log data found in well "+GetWellName()+"\n";
}
}
catch(Exception & e) {
err_txt += e.what();
}
if(fin.is_open())
fin.close();
if(err_txt != "")
throw(FileFormatError(err_txt));
else { //Final initialisation of unset values
if(stop_depth_ == 0)
stop_depth_ = GetContMissing();
if(depth_increment_ == 0)
depth_increment_ = GetContMissing();
}
const std::map<std::string,std::vector<double> > & logs = GetContLog();
std::map<std::string,std::vector<double> >::const_iterator it = logs.begin();
int n_data = static_cast<int>(it->second.size());
this->SetNumberOfData(n_data);
}
void
LasWell::ReadHeader(const std::string & filename,
std::ifstream & fin,
std::string & err_txt)
{
std::string well_name = NRLib::GetStem(filename);
SetWellName(well_name);
fin.open(filename.c_str());
if (fin.is_open()) {
bool version_read = false;
bool well_read = false;
bool curve_read = false;
std::string line;
getline (fin,line); // First log line
bool end_of_header = false;
while ( !fin.eof() && !end_of_header) {
line = NRLib::Chomp(line);
if (line.empty()) { // Empty line, do nothing
getline (fin,line);
continue;
}
else if (line[0] == '#') { // Comment line, do nothing
getline (fin,line);
continue;
}
else if (line[0] == '~') { // Command trigger
if (line[1] == 'V') {
if(version_read == true)
err_txt += "~VERSION INFORMATION given more than once in file "+filename+".\n";
else {
version_read = true;
ParseVersionInformation(fin, line, err_txt);
}
}
else if (line[1] == 'W') {
if(well_read == true)
err_txt += "~WELL INFORMATION given more than once in file "+filename+".\n";
else {
well_read = true;
ParseWellInformation(fin, line, err_txt);
}
}
else if (line[1] == 'C') {
if(curve_read == true)
err_txt += "~CURVE INFORMATION given more than once in file "+filename+".\n";
else{
curve_read = true;
ParseCurveInformation(fin, line, err_txt);
}
}
else if (line[1] == 'P')
ParseInformation(parameter_info_, "~PARAMETER INFORMATION", fin, line, err_txt);
else if (line[1] == 'O')
ParseInformation(other_info_, "~OTHER INFORMATION", fin, line, err_txt);
else if (line[1] == 'A')
end_of_header = true;
else {
err_txt += "Invalid keyword \'~"+NRLib::ToString(line[1])+"\' has been encountered in LAS file "+filename+".\n";
std::vector<std::string> junk_info;
ParseInformation(junk_info, "", fin, line, err_txt);
}
}
else {
err_txt = "Unexpected end of header in file " + filename + "\n";
end_of_header = true;
}
}
if(curve_read == false)
err_txt += "No ~CURVE INFORMATION given in LAS file "+filename+".\n";
if(well_read == false)
err_txt += "No ~WELL INFORMATION given in LAS file "+filename+".\n";
if(version_read == false)
err_txt += "No ~VERSION INFORMATION given in LAS file "+filename+".\n";
}
else {
err_txt = std::string(" Cannot open file ") + filename + std::string("\n");
}
}
void
LasWell::ParseInformation(std::vector<std::string> & info,
const std::string & text,
std::ifstream & fin,
std::string & line,
std::string & err_txt)
{
if (info.size() == 0) {
bool end_of_section = false;
while ( !fin.eof() && !end_of_section && err_txt == "") {
getline (fin,line);
line = NRLib::Chomp(line);
if (line[0] == '~') {
end_of_section = true;
continue;
}
else if (line[0] == '#') {
continue;
}
else {
info.push_back(line);
}
}
}
else {
err_txt += "There is more than one "+text+" section present in well "+GetWellName()+".\n";
}
}
void
LasWell::ParseVersionInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt)
{
bool end_of_section = false;
while (!fin.eof() && !end_of_section) {
getline (fin,line);
line = NRLib::Chomp(line);
if(line.size() == 0 || line[0] == '#') {
continue;
}
else if (line[0] == '~') {
end_of_section = true;
continue;
}
else {
std::string::size_type end_pos = line.find_first_of(".");
std::string token = NRLib::Chomp(line.substr(0, end_pos));
std::string::size_type start_pos = end_pos;
start_pos = line.find_first_of(" ",start_pos);
end_pos = line.find_first_of(":",start_pos);
if(end_pos == std::string::npos)
err_txt += "Not enough items under keyword "+token+" under ~VERSION INOFRMATION in "+GetWellName()+".\n";
else {
std::string value = NRLib::Chomp(line.substr(start_pos,end_pos-start_pos));
if(token == "VERS")
version_ = value;
else if(token == "WRAP") {
if(value == "NO")
wrap_ = false;
else
wrap_ = true;
}
else if(token == "DLM") {
if(value == "COMMA")
comma_delimited_ = true;
}
else
version_info_.push_back(line);
}
}
}
}
void
LasWell::ParseWellInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt)
{
bool end_of_section = false;
while (!fin.eof() && !end_of_section) {
getline (fin,line);
line = NRLib::Chomp(line);
if(line.size() == 0 || line[0] == '#') {
continue;
}
else if (line[0] == '~') {
end_of_section = true;
continue;
}
else {
std::string::size_type end_pos = line.find_first_of(".");
std::string token = NRLib::Chomp(line.substr(0, end_pos));
std::string::size_type start_pos = end_pos;
start_pos = line.find_first_of(" ",start_pos);
end_pos = line.find_first_of(":",start_pos);
if(end_pos == std::string::npos)
err_txt += "Not enough items under keyword "+token+" under ~WELL INOFRMATION in "+GetWellName()+".\n";
else {
std::string value = NRLib::Chomp(line.substr(start_pos,end_pos-start_pos));
ParseWellToken(token, value, line, err_txt);
}
}
}
}
void
LasWell::ParseWellToken(const std::string & token,
const std::string & value,
const std::string & line,
std::string & err_txt)
{
if(token == "WELL") {
if(value.empty() == false)
SetWellName(value);
}
else if(token == "STRT" || token == "STOP" || token == "STEP" ||
token == "NULL" || token == "XWELL" || token == "YWELL")
{
if(value.empty() == false) { //Do not set value if there is nothing to set. Do not trust missingcode, may change later.
try {
double val = NRLib::ParseType<double>(value);
if(token == "STRT")
start_depth_ = val;
else if(token == "STOP")
stop_depth_ = val;
else if(token == "STEP")
depth_increment_ = val;
else if(token == "NULL")
SetMissing(val);
else if(token == "XWELL")
SetXPos0(val);
else if(token == "YWELL")
SetYPos0(val);
}
catch(NRLib::Exception & e) {
err_txt += std::string(e.what())+" for keyword "+token+" under ~WELL INFORMATION in well "+GetWellName();
}
}
}
else
well_info_.push_back(line);
}
void
LasWell::ParseCurveInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt)
{
bool end_of_section = false;
while (!fin.eof() && !end_of_section) {
getline (fin,line);
line = NRLib::Chomp(line);
if(line.size() == 0 || line[0] == '#') {
continue;
}
else if (line[0] == '~') {
end_of_section = true;
continue;
}
else {
std::string::size_type end_pos = line.find_first_of(".");
std::string token = NRLib::Chomp(line.substr(0, end_pos));
std::string::size_type start_pos = end_pos+1;
end_pos = line.find_first_of(" ",start_pos);
std::string unit = NRLib::Chomp(line.substr(start_pos, end_pos-start_pos));
start_pos = line.find_first_of(":",start_pos);
if(start_pos == std::string::npos)
err_txt += "Not enough items under keyword "+token+" under ~CURVE INOFRMATION in "+GetWellName()+".\n";
else {
log_name_.push_back(token);
log_unit_.push_back(unit);
std::string comment = NRLib::Chomp(line.substr(start_pos+1));
log_comment_.push_back(comment);
}
}
}
if(log_unit_.size() > 0)
depth_unit_ = log_unit_[0];
}
void
LasWell::ReadLogs(std::ifstream & fin,
std::string & err_txt)
{
std::string tmp_err_txt;
std::vector<std::vector<double> > log(log_name_.size());
size_t n_data = 2000000000; //Anything more than this will easily give indexing problems, so ok upper limit.
bool n_data_given = false;
if(IsMissing(start_depth_) == false && IsMissing(stop_depth_) == false && IsMissing(depth_increment_) == false &&
stop_depth_ > start_depth_ && depth_increment_ != 0) {
n_data_given = true;
n_data = static_cast<size_t>(floor(0.5+(stop_depth_ - start_depth_)/depth_increment_))+1;
for(size_t i=0;i<log.size();i++)
log[i].resize(n_data);
}
std::string line;
size_t n_records = 0;
size_t n_errors = 0;
std::vector<std::string> record;
while(GetRecord(fin, log.size(), record) == true && n_errors < 5 && n_records < n_data) {
n_records++;
if(record.size() != log.size()) {
n_errors++;
tmp_err_txt += "Error in well "+GetWellName()+", record "+NRLib::ToString(n_records)+"("+log_name_[0]+"="+record[0]
+"?): Wrong number of items, found "+NRLib::ToString(record.size())+" when expecting "+NRLib::ToString(log.size())+".\n";
}
else {
for(size_t i=0;i<log.size();i++) {
if(n_data_given == false)
log[i].push_back(0);
try {
log[i][n_records-1] = NRLib::ParseType<double>(record[i]);
}
catch(Exception & e) {
tmp_err_txt += "Error in well "+GetWellName()+", record "+NRLib::ToString(n_records)+"("+log_name_[0]+"="+record[0]
+"?), item "+NRLib::ToString(i+1)+": "+std::string(e.what());
n_errors++;
}
}
}
}
while(GetRecord(fin, log.size(), record) == true) //Find actual record count.
n_records++;
if(n_errors >= 5) //Note intentional use of err_txt below, final error.
err_txt += tmp_err_txt +"Too many log errors found in well "+GetWellName()+". Stopped processing.\n";
else if(tmp_err_txt == "" && n_records < n_data && n_data_given == true) { //Note intentional use of err_txt below, only this error has occured.
err_txt += "Wrong number of data records found in well "+GetWellName()+", found "+NRLib::ToString(n_records)
+" while expecting "+NRLib::ToString(n_data)+".\n";
}
else {
for(size_t i=0;i<log.size();i++) {
AddContLog(log_name_[i],log[i]);
}
}
}
bool
LasWell::GetRecord(std:: ifstream & fin,
size_t n_items,
std::vector<std::string> & record) const
{
std::string line;
while(line.empty()==true && fin.eof() == false)
getline(fin,line);
if(line.empty() == true)
return(false);
NRLib::Substitute(line, ",", " "); //Makes comma delimited space delimited.
record = NRLib::GetTokens(line);
if(wrap_ == true) {
while(record.size() < n_items && fin.eof()==false) {
getline(fin,line);
NRLib::Substitute(line, ",", " "); //Makes comma delimited space delimited.
std::vector<std::string> items = GetTokens(line);
record.insert(record.end(), items.begin(), items.end());
}
}
return(true);
}
void LasWell::AddLog(const std::string & name,
const std::string & units,
const std::string & comment,
const std::vector<double> & log)
{
Well::AddContLog(name, log);
log_name_.push_back(name);
log_unit_.push_back(units);
log_comment_.push_back(comment);
}
void LasWell::WriteToFile(const std::string & filename,
const std::vector<std::string> & comment_header)
{
std::ofstream file;
OpenWrite(file, filename);
// Comment header
for (size_t i = 0; i < comment_header.size(); ++i) {
file << "# " << comment_header[i] << "\n";
}
file << "\n";
// Version information
file << "~Version information\n";
WriteLasLine(file, "VERS", "", version_, "");
WriteLasLine(file, "WRAP", "", (wrap_ ? "YES" : "NO"), "");
for(size_t i=0;i<version_info_.size();i++)
file << version_info_[i] << "\n";
file << "\n";
file.setf(std::ios_base::fixed);
file.precision(5);
// Well information
file << "~Well information\n";
WriteLasLine(file, "STRT", depth_unit_, start_depth_, "");
WriteLasLine(file, "STOP", depth_unit_, stop_depth_, "");
WriteLasLine(file, "STEP", depth_unit_, depth_increment_, "");
WriteLasLine(file, "NULL", "", GetContMissing(), "");
for(size_t i=0;i<version_info_.size();i++)
file << version_info_[i] << "\n";
file << "\n";
if (GetNContLog() == 0) {
// No log data in file.
return;
}
//Parameter information. Only what is read from file; may add Set-functions.
file << "~Parameter information\n";
for(size_t i=0;i<version_info_.size();i++)
file << parameter_info_[i] << "\n";
file << "\n";
// Curve information
// LAS only supports continuous logs...
file << "~Curve information\n";
for (size_t i = 0; i < GetNContLog(); ++i) {
WriteLasLine(file, log_name_[i], log_unit_[i], "", log_comment_[i]);
}
file << "\n";
// Data section
file << "~Ascii\n";
std::vector<const std::vector<double> *> logs(GetNContLog());
for (size_t i = 0; i < GetNContLog(); ++i) {
logs[i] = &(GetContLog(log_name_[i]));
}
// We don't support wrapped output yet.
assert(wrap_ == false);
file.precision(3);
for (size_t i = 0; i < logs[0]->size(); ++i) {
for (size_t j = 0; j < logs.size(); ++j) {
file << (*logs[j])[i] << " ";
}
file << "\n";
}
}
void LasWell::WriteLasLine(std::ofstream & file,
const std::string & mnemonic,
const std::string & units,
const std::string & data,
const std::string & description)
{
file << mnemonic << " ." << units << " " << data << " : " << description << "\n";
}
void LasWell::WriteLasLine(std::ofstream & file,
const std::string & mnemonic,
const std::string & units,
double data,
const std::string & description)
{
file << mnemonic << " ." << units << " " << data << " : " << description << "\n";
}

133
ThirdParty/NRLib/nrlib/well/laswell.hpp vendored Normal file
View File

@@ -0,0 +1,133 @@
// $Id: laswell.hpp 1244 2014-02-24 15:57:16Z hauge $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_WELL_LASWELL_HPP
#define NRLIB_WELL_LASWELL_HPP
#include <string>
#include <vector>
#include "well.hpp"
namespace NRLib {
/// Support for the LAS well format.
/// Currently mainly LAS 2.0 is supported. Some LAS 3.0 support.
/// \sa{http://www.cwls.org/las_info.php}
class LasWell : public Well {
public:
enum DepthType {
Depth,
Time
};
/// Constructor with relevant parameters.
LasWell(const std::string & filename);
void AddLog(const std::string & name,
const std::string & units,
const std::string & comment,
const std::vector<double> & log);
void WriteToFile(const std::string & filename,
const std::vector<std::string> & comment_header);
private:
void ReadHeader(const std::string & filename,
std::ifstream & fin,
std::string & err_txt);
void ParseInformation(std::vector<std::string> & info,
const std::string & text,
std::ifstream & fin,
std::string & line,
std::string & err_txt);
void ParseVersionInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt);
void ParseWellInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt);
void ParseWellToken(const std::string & token,
const std::string & value,
const std::string & line,
std::string & err_txt);
void ParseCurveInformation(std::ifstream & fin,
std::string & line,
std::string & err_txt);
void ReadLogs(std::ifstream & fin,
std::string & err_txt);
bool GetRecord(std:: ifstream & fin,
size_t n_items,
std::vector<std::string> & record) const;
void WriteLasLine(std::ofstream & file,
const std::string & mnemonic,
const std::string & units,
const std::string & data,
const std::string & description);
void WriteLasLine(std::ofstream & file,
const std::string & mnemonic,
const std::string & units,
double data,
const std::string & description);
/// Version ID. Possible version ID's include 1.2, 2.0 and 3.0.
std::string version_;
/// True if wrap around mode is used. If wrap mode is used the depth value will be
/// on its own line and all lines of data will be no longer than 80 characters (including CR+LF).
bool wrap_;
///True if comma delimited file.
bool comma_delimited_;
/// Possible depth units:
/// For logs in depth: M (meter), F (feet) or FT (feet)
/// For logs in time: S (seconds), MS (milliseconds), etc.
std::string depth_unit_;
/// Depth of first depth sample.
double start_depth_;
/// Depth of last depth sample.
double stop_depth_;
/// Depth increment. 0 if the increment is not constant.
double depth_increment_;
std::vector<std::string> log_name_; //Needed to preserve log order, may be important in LAS-files.
std::vector<std::string> log_unit_;
std::vector<std::string> log_comment_;
std::vector<std::string> version_info_; //Unused version keywords, only read from file and rewritten.
std::vector<std::string> well_info_; //Unused well keywords, only read from file and rewritten.
std::vector<std::string> parameter_info_; //Not used, only read from file and rewritten.
std::vector<std::string> other_info_; //Not used, only read from file and rewritten.
};
}
#endif // NRLIB_WELL_LASWELL_HPP

5
ThirdParty/NRLib/nrlib/well/module.mk vendored Normal file
View File

@@ -0,0 +1,5 @@
SRC += $(NRLIB_BASE_DIR)well/norsarwell.cpp \
$(NRLIB_BASE_DIR)well/laswell.cpp \
$(NRLIB_BASE_DIR)well/rmswell.cpp \
$(NRLIB_BASE_DIR)well/well.cpp \
$(NRLIB_BASE_DIR)well/welloperations.cpp

View File

@@ -0,0 +1,339 @@
// $Id: norsarwell.cpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <fstream>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "norsarwell.hpp"
#include "../iotools/stringtools.hpp"
#include "../iotools/fileio.hpp"
//#include "src/definitions.h"
using namespace NRLib;
NorsarWell::NorsarWell(const std::string & filename)
: header_units_(8)
{
std::ifstream file;
NRLib::OpenRead(file, filename);
std::string token;
getline(file, token);
if(token.find("[Version information]",0) > 0)
throw(FileFormatError("Found '"+token+"' instead of '[Version information]' on first line in file "+filename+"."));
int line = 2;
ReadNext<std::string>(file, line);
version_ = ReadNext<std::string>(file, line);
if(version_ != "1000")
throw(FileFormatError("Found '"+version_+"' as version number in file "+filename+". Can only read version 1000."));
ReadNext<std::string>(file, line);
format_ = ReadNext<std::string>(file, line);
if(format_ != "ASCII")
throw(FileFormatError("Found '"+format_+"' as format in file "+filename+". Can only read ASCII format."));
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line); //Together with previous, reads '[Well information]'
ReadNext<std::string>(file, line); //'MDMIN'
header_units_[0] = ReadNext<std::string>(file, line); //unit for MDMIN
md_min_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'MDMAX'
header_units_[1] = ReadNext<std::string>(file, line); //unit for MDMAX
md_max_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'MDMINSTEP'
header_units_[2] = ReadNext<std::string>(file, line); //unit for MDMINSTEP
md_min_step_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'MDMAXSTEP'
header_units_[3] = ReadNext<std::string>(file, line); //unit for MDMAXSTEP
md_max_step_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'UTMX'
header_units_[4] = ReadNext<std::string>(file, line); //unit for UTMX
xpos0_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'UTMY'
header_units_[5] = ReadNext<std::string>(file, line); //unit for UTMY
ypos0_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'EKB'
header_units_[6] = ReadNext<std::string>(file, line); //unit for EKB
ekb_ = ReadNext<double>(file, line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'UNDEFVAL'
header_units_[7] = ReadNext<std::string>(file, line); //unit for UNDEFVAL
SetMissing(ReadNext<double>(file, line));
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line); //Together with previous, reads '[Well track data information]'
ReadNext<std::string>(file, line); //'NUMMD'
int n_track = ReadNext<int>(file,line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'NUMPAR'
int n_track_par = ReadNext<int>(file,line);
DiscardRestOfLine(file, line, false);
typedef std::pair<std::string,std::string> unitpair;
int track_MD = -1;
std::string name;
std::vector<std::string> log_name;
for(int i=0; i<n_track_par;i++) {
name = ReadNext<std::string>(file, line); //parameter
log_name.push_back(NRLib::Uppercase(name));
if(name == "MD")
track_MD = i;
token = ReadNext<std::string>(file, line); //unit
units_.insert(unitpair(name,token));
DiscardRestOfLine(file, line, false);
}
if(track_MD < 0)
throw(FileFormatError("Could not find MD for track file in file '"+filename+"'."));
std::string track_filename = ReplaceExtension(filename, ".nwt");
std::vector<std::vector<double> > track_logs = ReadLogs(track_filename, n_track_par, n_track,1);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line); //Together with previous, reads '[Well log data information]'
std::string path = GetPath(filename);
std::string log_filename;
std::string log_section_name;
std::vector<std::vector<double> > log_logs;
int n_log, n_log_par, log_MD;
while(CheckEndOfFile(file) == false) {
ReadNext<std::string>(file, line);
log_section_name = ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line);
log_filename = ReadNext<std::string>(file, line);
ReadNext<std::string>(file, line); //'NUMMD'
n_log = ReadNext<int>(file,line);
DiscardRestOfLine(file, line, false);
ReadNext<std::string>(file, line); //'NUMPAR'
n_log_par = ReadNext<int>(file,line);
DiscardRestOfLine(file, line, false);
log_MD = -1;
for(int i=0; i<n_log_par;i++) {
name = ReadNext<std::string>(file, line); //parameter
if(name == "MD")
log_MD = i;
else
log_name.push_back(NRLib::Uppercase(name));
token = ReadNext<std::string>(file, line); //unit
if(log_MD != i)
units_.insert(unitpair(name,token));
DiscardRestOfLine(file, line, false);
}
if(log_MD < 0)
throw(FileFormatError("Could not find MD for logs '"+log_section_name+"' in file '"+filename+"'."));
log_filename = PrependDir(path, log_filename);
log_logs = ReadLogs(log_filename, n_log_par, n_log, 2);
track_logs = MergeLogs(track_logs, track_MD, log_logs, log_MD);
}
file.close();
for(int i=0;i<static_cast<int>(track_logs.size());i++)
AddContLog(log_name[i], track_logs[i]);
// find n_data including WELLMISSING values
int n_data = static_cast<int>(GetContLog(log_name[0]).size());
SetNumberOfData(n_data);
SetXPos0(xpos0_);
SetYPos0(ypos0_);
}
std::vector<std::vector<double> >
NorsarWell::ReadLogs(const std::string & filename, int n_col, int n_row, int skip_lines)
{
std::ifstream file;
OpenRead(file, filename);
std::vector<std::vector<double> > result(n_col, std::vector<double>(n_row, 0));
int line = 1;
std::string token;
for(int i=0;i<skip_lines;i++)
DiscardRestOfLine(file, line, false);
int baseline = line;
int i,j; //For use in error message.
//int legal_data = 0;
try {
for(i=0;i<n_row;i++) {
for(j=0;j<n_col;j++)
{
result[j][i] = ReadNext<double>(file, line);
if(line-i > baseline) {
std::string error = "Too few elements on line "+NRLib::ToString(line-1)+" in file "+filename+": Expected to read "+NRLib::ToString(n_col)+" elements, found only "+NRLib::ToString(j)+".";
throw (NRLib::IOError(error));
}
else if(line-i < baseline) {
while(line-i < baseline) {
j++;
ReadNext<double>(file, line);
}
std::string error = "Too many elements on line "+NRLib::ToString(line-1)+" in file "+filename+": Expected to read "+NRLib::ToString(n_col)+" elements, found "+NRLib::ToString(n_col+j)+".";
throw (NRLib::IOError(error));
}
}
//if(result[0][i] != WELLMISSING) //H [0] First?
// legal_data++;
}
}
catch (NRLib::EndOfFile) {
std::string error = "Unexpected end of file "+filename+": Expected to read "+NRLib::ToString(n_row*n_col)+"elements, found only "+NRLib::ToString(i*n_col+j)+".";
throw (NRLib::IOError(error));
}
//this->SetNumberOfLegalData(legal_data);
return(result);
}
std::vector<std::vector<double> >
NorsarWell::MergeLogs(const std::vector<std::vector<double> > & track_logs, int track_MD,
const std::vector<std::vector<double> > & log_logs, int log_MD)
{
int nt = static_cast<int>(track_logs[0].size());
int nl = static_cast<int>(log_logs[0].size());
int n = nt;
if(nl > nt)
n = nl; //Minimum number of rows.
int nc = static_cast<int>(track_logs.size() + log_logs.size()) - 1;
std::vector<std::vector<double> > result(nc);
for(int i = 0; i < nc; i++) {
result[i].reserve(n);
}
double depth_track, depth_log;
int ntl = static_cast<int>(track_logs.size());
int nll = static_cast<int>(log_logs.size());
int it = 0; //track counter
int il = 0; //log counter
while(it < nt && il < nl) {
depth_track = track_logs[track_MD][it];
depth_log = log_logs[log_MD][il];
if(depth_track == depth_log) { //Lucky.
for(int i=0;i<ntl;i++)
result[i].push_back(track_logs[i][it]);
int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed.
for(int i=0;i<nll;i++) {
if(i != log_MD)
result[i-mdp+ntl].push_back(log_logs[i][il]);
else
mdp = 1;
}
it++;
il++;
}
else if(depth_track < depth_log) {
for(int i=0;i<ntl;i++)
result[i].push_back(track_logs[i][it]);
for(int i=0;i<nll-1;i++)
result[i+ntl].push_back(GetContMissing());
it++;
}
else {
for(int i=0;i<ntl;i++) {
if(i != track_MD)
result[i].push_back(GetContMissing());
else
result[i].push_back(depth_log); //Always log MD, must take form log instead of track here.
}
int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed.
for(int i=0;i<nll;i++) {
if(i != log_MD)
result[i-mdp+ntl].push_back(log_logs[i][il]);
else
mdp = 1;
}
il++;
}
}
for(;it<nt;it++) {
for(int i=0;i<ntl;i++)
result[i].push_back(track_logs[i][it]);
for(int i=0;i<nll-1;i++)
result[i+ntl].push_back(GetContMissing());
}
for(;il<nl;il++) {
for(int i=0;i<ntl;i++) {
if(i != track_MD)
result[i].push_back(GetContMissing());
else
result[i].push_back(log_logs[log_MD][il]); //Always log MD, must take form log instead of track here.
}
int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed.
for(int i=0;i<nll;i++) {
if(i != log_MD)
result[i-mdp+ntl].push_back(log_logs[i][il]);
else
mdp = 1;
}
il++;
}
return(result);
}
std::string
NorsarWell::GetLogUnit(const std::string & name)
{
std::map<std::string,std::string>::iterator item = units_.find(name);
if(item == units_.end())
return("");
else
return(item->second);
}

View File

@@ -0,0 +1,85 @@
// $Id: norsarwell.hpp 883 2011-09-26 09:17:05Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_NORSARWELL_HPP
#define NRLIB_NORSARWELL_HPP
#include <vector>
#include <sstream>
#include <map>
#include "../exception/exception.hpp"
#include "well.hpp"
namespace NRLib {
class NorsarWell : public Well
{
public:
/// Constructor
/// \param[in] filename Name of well file
NorsarWell(const std::string & filename);
///NBNB add when convenient
/*
/// Copy constructor
NorsarWell(Well *wellobj);
/// Write well to file
void WriteWell(const std::string& filename);
*/
double GetXPosOrigin() {return(xpos0_);}
double GetYPosOrigin() {return(ypos0_);}
std::string GetLogUnit(const std::string & name);
private:
/// Version (currently only reading 1000)
std::string version_;
/// Format (currently only reading ascii)
std::string format_;
/// Minimum measured depth
double md_min_;
/// Maximum measured depth
double md_max_;
/// Minimum measured depth step
double md_min_step_;
/// Maximum measured depth step
double md_max_step_;
/// Original position
double xpos0_, ypos0_;
/// Kelly bushing elevation
double ekb_;
/// Units for the above, in order
std::vector<std::string> header_units_;
/// Names and units of logs
std::map<std::string,std::string> units_;
std::vector<std::vector<double> > ReadLogs(const std::string & filename, int n_col, int n_row, int skip_lines);
std::vector<std::vector<double> > MergeLogs(const std::vector<std::vector<double> > & track_logs, int track_MD,
const std::vector<std::vector<double> > & log_logs, int log_MD);
};
}
#endif

288
ThirdParty/NRLib/nrlib/well/rmswell.cpp vendored Normal file
View File

@@ -0,0 +1,288 @@
// $Id: rmswell.cpp 1194 2013-08-19 08:24:58Z anner $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "rmswell.hpp"
#include "../iotools/stringtools.hpp"
#include "../iotools/fileio.hpp"
using namespace NRLib;
RMSWell::RMSWell(const std::string& filename)
{
std::ifstream file;
OpenRead(file, filename);
size_t nlog;
std::string dummy;
getline(file,line1_);
getline(file,line2_);
int line = 0;
std::string token;
std::string wellName = ReadNext<std::string>(file, line);
SetWellName(wellName);
xpos0_ = ReadNext<double>(file, line);
ypos0_ = ReadNext<double>(file, line); // read wellname and positions
// getline(file,dummy);// Line may contain a dummy number
//-----line shift
DiscardRestOfLine(file, line, false);
nlog = ReadNext<int>(file, line); // read number of logs
DiscardRestOfLine(file, line, false);
lognames_.resize(nlog+3);
lognames_[0] = "X";
lognames_[1] = "Y";
lognames_[2] = "Z";
int ident;
std::string identstr;
size_t j(0);
size_t k(0);
isDiscrete_.resize(nlog+3);
unit_.resize(nlog);
scale_.resize(nlog);
isDiscrete_[0] = false;
isDiscrete_[1] = false;
isDiscrete_[2] = false;
for (size_t i = 0; i < nlog; i++) {
getline(file,dummy);
std::istringstream ist(dummy);
lognames_[i+3] = NRLib::Uppercase(ReadNext<std::string>(ist, line));
//token = ReadNext<std::string>(ist, line); //H Error if line only containts log-name (test_case 19).
ReadNextToken(ist, token, line);
if (token != "") {
if (token=="DISC") { // discrete log
isDiscrete_[i+3] = true;
std::map<int, std::string> disc;
while(ReadNextToken(ist,token,line)) {
ident = ParseType<int>(token);
identstr = ReadNext<std::string>(ist, line);
disc.insert(std::pair<int, std::string> (ident, identstr));
}
discnames_[lognames_[i+3]] = disc;
j++;
}
else {
isDiscrete_[i+3] = false;
unit_[k] = token;
scale_[k] = ReadNext<std::string>(ist, line);
k++;
}
}
else {
isDiscrete_[i+3] = false;
k++;
}
}
size_t ndisc(j);
size_t ncont = nlog + 3 - ndisc;
std::vector<std::vector<int> > disclogs(ndisc);
std::vector<std::vector<double> > contlogs(ncont);
int count = 0;
while(NRLib::CheckEndOfFile(file)==false && getline(file,dummy)) {
count ++;
std::istringstream ist(dummy);
contlogs[0].push_back(ReadNext<double>(ist, line)); //x
contlogs[1].push_back(ReadNext<double>(ist, line)); //y
contlogs[2].push_back(ReadNext<double>(ist, line)); //z
j = 0;
k = 3;
for (size_t i = 0; i < nlog; i++) {
if (isDiscrete_[i+3]) {
double dummy = ReadNext<double>(ist, line); //Double because of a problem with ReadNext<int> and facies on the form -9.9900000e+002
if(IsMissing(dummy) == false)
disclogs[j].push_back(static_cast<int>(dummy));
else
disclogs[j].push_back(GetIntMissing());
j++;
}
else {
contlogs[k].push_back(ReadNext<double>(ist, line));
k++;
}
}
}
AddContLog(lognames_[0], contlogs[0]);
AddContLog(lognames_[1], contlogs[1]);
AddContLog(lognames_[2], contlogs[2]);
j = 0;
k = 3;
for (size_t i = 0; i < nlog; i++) {
if (isDiscrete_[i+3]) {
AddDiscLog(lognames_[i+3], disclogs[j]);
j++;
}
else {
AddContLog(lognames_[i+3], contlogs[k]);
k++;
}
}
// Find n_data including WELLMISSING values
int n_data = static_cast<int>(GetContLog(lognames_[0]).size());
this->SetNumberOfData(n_data);
SetXPos0(xpos0_);
SetYPos0(ypos0_);
}
RMSWell::RMSWell(const Well& wellobj)
: Well(wellobj)
{
xpos0_ = GetContValue(0, "x");
ypos0_ = GetContValue(0, "y");
line1_ = "1.0";
line2_ = "Undefined";
size_t nlog = wellobj.GetNlog();
lognames_.resize(nlog + 3);
lognames_[0] = "x";
lognames_[1] = "y";
lognames_[2] = "z";
isDiscrete_.resize(nlog + 3);
isDiscrete_[0] = false;
isDiscrete_[1] = false;
isDiscrete_[2] = false;
size_t i = 0;
size_t k = 0;
typedef std::map<std::string, std::vector<int> >::const_iterator CI;
std::map<std::string,std::vector<int> > disclog = wellobj.GetDiscLog();
for (CI p = disclog.begin(); p != disclog.end(); ++p) {
lognames_[i+3] = p->first;
isDiscrete_[i+3] = true;
i++;
}
typedef std::map<std::string, std::vector<double> >::const_iterator CID;
std::map<std::string,std::vector<double> > contlog = wellobj.GetContLog();
for (CID p = contlog.begin(); p != contlog.end(); ++p) {
if (p->first != "x" && p->first != "y" && p->first != "z") {
lognames_[i+3] = p->first;
isDiscrete_[i+3] = false;
i++;
k++;
}
}
unit_.resize(k);
scale_.resize(k);
for (i = 0; i < k; i++) {
unit_[i] = "unit1";
scale_[i] ="scale1";
}
size_t ndisc = nlog - k - 3;
std::vector<std::vector<int> > discvalues(ndisc);
i = 0;
size_t j;
size_t kk = 0;
bool found = false;
for (CI p = disclog.begin(); p != disclog.end(); ++p) {
while(wellobj.IsMissing((p->second)[kk]))
kk++;
discvalues[i].push_back((p->second)[kk]);
for (j = kk + 1; j < p->second.size(); j++) {
for (k = 0; k < discvalues[i].size(); k++)
if ((p->second)[j] == discvalues[i][k])
found = true;
if (found == false && (!wellobj.IsMissing((p->second)[j])))
discvalues[i].push_back((p->second)[j]);
found = false;
}
}
////Frode NB: M<> se n<>yere p<> dette.
typedef std::pair<int, std::string> pp;
std::string identstr;
for (CI p = disclog.begin(); p !=disclog.end(); ++p) {
std::string disc_name = p->first;
for (j = 0; j < p->second.size(); j++) {
std::string identstr = ToString(p->second[j]);
discnames_[disc_name].insert(pp(p->second[j], identstr));
}
}
}
const std::map<int, std::string>
RMSWell::GetDiscNames(const std::string& log_name) const
{
return (discnames_.find(log_name)->second);
}
void RMSWell::WriteToFile(const std::string& filename)
{
std::ofstream file;
OpenWrite(file, filename, std::ios::out);
file << line1_ << "\n"
<< line2_ << "\n"
<< std::setprecision(8)
<< GetWellName() << " " << xpos0_ <<" " << ypos0_ << "\n"
<< GetNlog() - 3 << "\n";
size_t k = 0;
std::map<std::string, std::map<int, std::string> >::iterator iter = discnames_.begin();
typedef std::map<int, std::string>::const_iterator ci;
for (size_t i = 0; i < GetNlog(); i++) {
if (lognames_[i] != "x" && lognames_[i] != "y" && lognames_[i] != "z") {
file<< lognames_[i] << " ";
iter = discnames_.find(lognames_[i]);
if (isDiscrete_[i]==true) {
file << "DISC" << " ";
for (ci p = iter->second.begin(); p !=iter->second.end();++p)
file << p->first << " " << p->second << " ";
file << "\n";
// ++iter;
}
else {
file<< unit_[k] << " " << scale_[k] <<"\n";
k++;
}
}
}
file.precision(8);
size_t n = GetContLogLength(lognames_[0]);
for (size_t i = 0; i < n; i++) {
for (size_t j = 0; j < GetNlog(); j++) {
if (isDiscrete_[j]==true)
file << GetDiscValue(i, lognames_[j]) << " ";
else
file << GetContValue(i, lognames_[j]) << " ";
}
file << "\n";
}
file.close();
}

71
ThirdParty/NRLib/nrlib/well/rmswell.hpp vendored Normal file
View File

@@ -0,0 +1,71 @@
// $Id: rmswell.hpp 1068 2012-09-18 11:21:53Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_RMSWELL_HPP
#define NRLIB_RMSWELL_HPP
#include <vector>
#include <sstream>
#include <map>
#include "../exception/exception.hpp"
#include "well.hpp"
namespace NRLib {
class RMSWell : public Well
{
public:
/// Constructor
/// \param[in] filename Name of well file
RMSWell(const std::string& filename);
/// Construct RMSWell from general well.
RMSWell(const Well& wellobj);
/// Get the discnames for discrete log with index
const std::map<int, std::string> GetDiscNames(const std::string& log_name) const;
/// Write well to file
void WriteToFile(const std::string& filename);
//protected:
//void SetNumberOfData(int n_data) { Well::SetNumberOfData(n_data) ;}
private:
/// Names for discrete logs
std::map<std::string, std::map<int, std::string> > discnames_;
double xpos0_, ypos0_;
/// First line of RMSwell file
std::string line1_;
/// Second line of RMSwell file
std::string line2_;
/// Name of logs
std::vector<std::string> lognames_;
/// Vector telling which logs are discrete
std::vector<bool> isDiscrete_;
/// Units for continuous logs
std::vector<std::string> unit_;
/// Scale for continuous logs
std::vector<std::string> scale_;
};
}
#endif

338
ThirdParty/NRLib/nrlib/well/well.cpp vendored Normal file
View File

@@ -0,0 +1,338 @@
// $Id: well.cpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cassert>
#include <fstream>
#include <string>
#include "well.hpp"
#include "norsarwell.hpp"
#include "laswell.hpp"
#include "rmswell.hpp"
#include "../iotools/stringtools.hpp"
#include "nrlib/iotools/logkit.hpp"
#include "nrlib/iotools/stringtools.hpp"
#include "nrlib/surface/surface.hpp"
//#include "src/definitions.h"
using namespace NRLib;
Well::Well()
{
well_rmissing_ = -999.0;
well_imissing_ = -999;
}
Well::Well(const std::string & name,
double rmissing,
int imissing)
{
well_name_ = name;
well_rmissing_ = rmissing;
well_imissing_ = imissing;
}
Well::Well(const std::map<std::string,std::vector<double> > & cont_log,
const std::map<std::string,std::vector<int> > & disc_log,
const std::string & well_name)
{
cont_log_ = cont_log;
disc_log_ = disc_log;
well_name_ = well_name;
well_rmissing_ = -999.0;
well_imissing_ = -999;
}
Well::~Well()
{
}
Well *
Well::ReadWell(const std::string & file_name,
int & well_format)
{
Well * well;
if(well_format == NORSAR || file_name.find(".nwh",0) != std::string::npos) {
well = new NorsarWell(file_name);
std::string name = NRLib::RemovePath(file_name);
well->SetWellName(NRLib::ReplaceExtension(name, ""));
well_format = NORSAR;
return(well);
}
if(well_format == LAS || file_name.find(".las",0) != std::string::npos) {
well = new LasWell(file_name);
well_format = LAS;
}
else {
well = new RMSWell(file_name);
well_format = RMS;
}
return(well);
}
void
Well::AddContLog(const std::string& name, const std::vector<double>& log)
{
cont_log_[name] = log;
}
void
Well::AddContLogSeismicResolution(const std::string& name, const std::vector<double>& log)
{
cont_log_seismic_resolution_[name] = log;
}
void
Well::AddContLogBackgroundResolution(const std::string& name, const std::vector<double>& log)
{
cont_log_background_resolution_[name] = log;
}
bool Well::HasDiscLog(const std::string& name) const{
std::map<std::string, std::vector<int> >::const_iterator it = disc_log_.find(name);
if(it != disc_log_.end()){
return true;
}
else{
return false;
}
}
bool
Well::HasContLog(const std::string& name) const
{
//std::map<std::string, std::vector<double> >::const_iterator item = cont_log_.find(name);
if(cont_log_.find(name) != cont_log_.end())
return true;
else
return false;
}
std::vector<double>&
Well::GetContLog(const std::string& name)
{
std::map<std::string, std::vector<double> >::iterator item = cont_log_.find(name);
assert(item != cont_log_.end());
return item->second;
}
std::vector<double>&
Well::GetContLogSeismicResolution(const std::string& name)
{
std::map<std::string, std::vector<double> >::iterator item = cont_log_seismic_resolution_.find(name);
assert(item != cont_log_.end());
return item->second;
}
std::vector<double>&
Well::GetContLogBackgroundResolution(const std::string& name)
{
std::map<std::string, std::vector<double> >::iterator item = cont_log_background_resolution_.find(name);
assert(item != cont_log_.end());
return item->second;
}
const std::vector<double>&
Well::GetContLog(const std::string& name) const
{
std::map<std::string, std::vector<double> >::const_iterator item = cont_log_.find(name);
assert(item != cont_log_.end());
return item->second;
}
const std::vector<double>&
Well::GetContLogSeismicResolution(const std::string& name) const
{
std::map<std::string, std::vector<double> >::const_iterator item = cont_log_seismic_resolution_.find(name);
assert(item != cont_log_seismic_resolution_.end());
return item->second;
}
const std::vector<double>&
Well::GetContLogBackgroundResolution(const std::string& name) const
{
std::map<std::string, std::vector<double> >::const_iterator item = cont_log_background_resolution_.find(name);
assert(item != cont_log_background_resolution_.end());
return item->second;
}
void
Well::RemoveContLog(const std::string& name)
{
cont_log_.erase(name);
}
void
Well::AddDiscLog(const std::string& name, const std::vector<int>& log)
{
disc_log_[name] = log;
}
std::vector<int> &
Well::GetDiscLog(const std::string& name)
{
std::map<std::string, std::vector<int> >::iterator item = disc_log_.find(name);
assert(item != disc_log_.end());
return item->second;
}
const std::vector<int> &
Well::GetDiscLog(const std::string& name) const
{
std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(name);
assert(item != disc_log_.end());
return item->second;
}
void
Well::RemoveDiscLog(const std::string& name)
{
disc_log_.erase(name);
}
void
Well::MakeLogsUppercase()
{
std::map<std::string, std::vector<int> > d_log;
std::map<std::string, std::vector<int> >::iterator d_item = disc_log_.begin();
for(;d_item != disc_log_.end(); ++d_item) {
std::string u_name = NRLib::Uppercase(d_item->first);
d_log[u_name] = d_item->second;
}
disc_log_ = d_log;
std::map<std::string, std::vector<double> > c_log;
std::map<std::string, std::vector<double> >::iterator c_item = cont_log_.begin();
for(;c_item != cont_log_.end(); ++c_item) {
std::string u_name = NRLib::Uppercase(c_item->first);
c_log[u_name] = c_item->second;
}
cont_log_ = c_log;
}
void Well::SetWellName(const std::string& wellname)
{
well_name_ = wellname;
}
bool Well::IsMissing(double x)const
{
if (x == well_rmissing_)
return true;
else
return false;
}
bool Well::IsMissing(int n)const
{
if (n == well_imissing_)
return true;
else
return false;
}
int Well::GetDiscValue(size_t index, const std::string& logname) const
{
std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(logname);
assert(item != disc_log_.end());
const std::vector<int>& log = item->second;
assert(index < log.size());
return log[index];
}
double Well::GetContValue(size_t index, const std::string& logname) const
{
std::map<std::string,std::vector<double> >::const_iterator item = cont_log_.find(logname);
assert(item != cont_log_.end());
const std::vector<double>& log = item->second;
assert(index < log.size());
return log[index];
}
void Well::SetDiscValue(int value, size_t index, const std::string& logname)
{
std::map<std::string,std::vector<int> >::iterator item = disc_log_.find(logname);
assert(item != disc_log_.end());
assert(index < item->second.size());
(item->second)[index] = value;
}
void Well::SetContValue(double value, size_t index, const std::string& logname)
{
std::map<std::string,std::vector<double> >::iterator item = cont_log_.find(logname);
assert(item != cont_log_.end());
assert(index < item->second.size());
(item->second)[index] = value;
}
size_t Well::GetNlog() const
{
return cont_log_.size() + disc_log_.size();
}
size_t Well::GetNContLog() const
{
return cont_log_.size();
}
size_t Well::GetContLogLength(const std::string& logname) const
{
std::map<std::string,std::vector<double> >::const_iterator item = cont_log_.find(logname);
assert(item != cont_log_.end());
return (item->second).size();
}
const std::map<int, std::string>
Well::GetDiscNames(const std::string& log_name) const
{
std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(log_name);
assert(item != disc_log_.end());
const std::vector<int>& log = item->second;
std::map<int, std::string> name_map;
for(size_t i=0;i<log.size();i++) {
if(IsMissing(log[i]) == false) {
std::string name(NRLib::ToString(log[i]));
if(name_map.find(log[i]) == name_map.end())
name_map.insert(std::pair<int, std::string> (log[i], name));
}
}
return(name_map);
}

219
ThirdParty/NRLib/nrlib/well/well.hpp vendored Normal file
View File

@@ -0,0 +1,219 @@
// $Id: well.hpp 883 2011-09-26 09:17:05Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_WELL_HPP
#define NRLIB_WELL_HPP
#include <vector>
#include <sstream>
#include <map>
namespace NRLib {
class Well{
public:
/// Default constructor
Well();
/// Construct well with given name and no logs.
Well(const std::string & name,
double rmissing = -999.0,
int imissing = -999);
/// Construct well from file
Well(const std::string & file_name,
bool & read_ok,
const std::string & facies_log = "");
/// Constructor
/// \param[in] cont_log Continuous logs
/// \param[in] disc_log Discrete logs
/// \param[in] well_name
Well(const std::map<std::string, std::vector<double> > & cont_log,
const std::map<std::string, std::vector<int> > & disc_log,
const std::string & well_name);
/// Destructor
virtual ~Well();
static Well * ReadWell(const std::string & file_name,
int & well_format);
/// Check existence of discrete log
bool HasDiscLog(const std::string & name) const;
/// Check existence of continuous log
bool HasContLog(const std::string& name) const;
/// Return continuous logs
std::vector<double> & GetContLog(const std::string& name);
std::vector<double> & GetContLogSeismicResolution(const std::string& name);
std::vector<double> & GetContLogBackgroundResolution(const std::string& name);
/// Return continuous logs
const std::vector<double> & GetContLog(const std::string& name) const;
const std::vector<double> & GetContLogSeismicResolution(const std::string& name) const;
const std::vector<double> & GetContLogBackgroundResolution(const std::string& name) const;
/// Return discrete logs
std::vector<int> & GetDiscLog(const std::string& name);
/// Return discrete logs
const std::vector<int> & GetDiscLog(const std::string& name) const;
/// Add a continuous log
/// Replaces the log if there is already a log with the given name.
void AddContLog(const std::string& name, const std::vector<double>& log);
void AddContLogSeismicResolution(const std::string& name, const std::vector<double>& log);
void AddContLogBackgroundResolution(const std::string& name, const std::vector<double>& log);
/// Remove continuous log
/// Does nothing if there is no log with the given name.
void RemoveContLog(const std::string& name);
/// Add discrete log
/// Replaces the log if there is already a log with the given name.
void AddDiscLog(const std::string& name, const std::vector<int>& log);
/// Remove discrete log
/// Does nothing if there is no log with the given name.
void RemoveDiscLog(const std::string& name);
/// Change case of all logs to uppercase, to remove case sensitivity on log names
void MakeLogsUppercase();
/// Set name of well
void SetWellName(const std::string& wellname);
///
const std::string& GetWellName() const { return well_name_; };
/// Return true if x is missing
bool IsMissing(double x) const;
/// Return true if n is missing
bool IsMissing(int n) const;
/// Check if deviated
bool IsDeviated() const { return is_deviated_; }
/// Return cont. missing value
double GetContMissing() const { return(well_rmissing_); }
/// Return number of time data
int GetNData(void) const { return n_data_ ;}
/// Return disc. missing value
int GetIntMissing() const { return(well_imissing_); }
/// Set deviated
void SetDeviated(bool b) {is_deviated_ = b ;}
/// Set missing values
void SetMissing(double value) {well_rmissing_ = value; well_imissing_ = static_cast<int>(value);}
/// Return discrete value at position index in log with name logname
/// Returns missing if there is no log with the given name, or index is out of range.
int GetDiscValue(size_t index, const std::string& logname) const;
/// Return continuous value at position index in log with name logname
/// Returns missing if there is no log with the given name, or index is out of range.
double GetContValue(size_t index, const std::string& logname) const;
/// Set value at position index in log with name logname
void SetDiscValue(int value, size_t index, const std::string& logname);
/// Set value at position index in log with name logname
void SetContValue(double value, size_t index, const std::string& logname);
/// Return total number of logs
size_t GetNlog() const;
/// Return number of discrete logs
size_t GetNContLog() const;
/// Return length of log with name logname
size_t GetContLogLength(const std::string& logname) const;
/// Return all continuous logs
const std::map<std::string,std::vector<double> > & GetContLog() const { return cont_log_; };
const std::map<std::string,std::vector<double> > & GetContLogSeismicResolution() const { return cont_log_seismic_resolution_; };
const std::map<std::string,std::vector<double> > & GetContLogBackgroundResolution() const { return cont_log_background_resolution_; };
/// Return all discrete logs
const std::map<std::string,std::vector<int> > & GetDiscLog() const { return disc_log_; };
/// Facies
int GetNFacies() const { return static_cast<int>(facies_map_.size()) ;}
/// Map integer log to facies name
const std::map<int, std::string> & GetFaciesMap() const { return facies_map_ ;}
void SetXPos0(double x_pos0) { x_pos0_ = x_pos0 ;}
void SetYPos0(double y_pos0) { y_pos0_ = y_pos0 ;}
double GetXPos0() { return x_pos0_ ;}
double GetYPos0() { return y_pos0_ ;}
/// Set number of non-missing data
void SetNumberOfNonMissingData(int n_data_nonmissing) { n_data_nonmissing_ = n_data_nonmissing ;}
/// Set number of data
void SetNumberOfData(int n_data) {n_data_ = n_data ;}
void SetFaciesMappingFromDiscLog(const std::string & name) {facies_map_ = GetDiscNames(name);}
virtual const std::map<int, std::string> GetDiscNames(const std::string& log_name) const;
const unsigned int GetNumberOfNonMissingData() const {return n_data_nonmissing_ ;}
void SetUseForBackgroundTrend(int use_for_background_trend) { use_for_background_trend_ = use_for_background_trend ;}
void SetUseForFiltering(int use_for_filtering) { use_for_filtering_ = use_for_filtering ;}
void SetUseForFaciesProbabilities(int use_for_facies_probabilities) { use_for_facies_probabilities_ = use_for_facies_probabilities ;}
void SetUseForWaveletEstimation(int use_for_wavelet_estimation) { use_for_wavelet_estimation_ = use_for_wavelet_estimation ;}
void SetRealVsLog(int real_vs_log) { real_vs_log_ = real_vs_log ;}
void SetUseForRockPhysics(int use_for_rock_physics) { use_for_rock_physics_ = use_for_rock_physics ;}
int GetUseForBackgroundTrend(void) const { return use_for_background_trend_ ;}
int GetUseForFiltering(void) const { return use_for_filtering_ ;}
int GetUseForFaciesProbabilities(void) const { return use_for_facies_probabilities_ ;}
int GetUseForWaveletEstimation(void) const { return use_for_wavelet_estimation_ ;}
int GetRealVsLog(void) const { return real_vs_log_ ;}
int GetUseForRockPhysics(void) const { return use_for_rock_physics_ ;}
bool HasSyntheticVsLog(void) const { return(real_vs_log_)==0 ;}
enum WELL_FILE_FORMAT {RMS=0, NORSAR = 1, LAS = 2};
protected:
// Number of time data including WELLMISSING values
unsigned int n_data_;
// Number of data excluding WELLMISSING values
unsigned int n_data_nonmissing_;
private:
/// Continuous logs
std::map<std::string,std::vector<double> > cont_log_;
/// Discrete logs
std::map<std::string,std::vector<int> > disc_log_;
/// Continuous logs
std::map<std::string,std::vector<double> > cont_log_seismic_resolution_;
/// Continuous logs
std::map<std::string,std::vector<double> > cont_log_background_resolution_;
/// Name of well
std::string well_name_;
/// Missing value for continous logs.
double well_rmissing_;
/// Missing value for discrete logs.
int well_imissing_;
/// Parameter from ModelGeneral
bool is_deviated_;
/// Facies variables
std::map<int, std::string> facies_map_;
int use_for_background_trend_; //Uses the indicator enum from Modelsettings
int use_for_filtering_; //Uses the indicator enum from Modelsettings
int use_for_wavelet_estimation_; //Uses the indicator enum from Modelsettings
int use_for_facies_probabilities_; //Uses the indicator enum from Modelsettings
int real_vs_log_; //Uses the indicator enum from Modelsettings
int use_for_rock_physics_; //Uses the indicator enum from Modelsettings
double x_pos0_; // x-coordinate from well file header
double y_pos0_; // y-coordinate from well file header
};
}
#endif

View File

@@ -0,0 +1,25 @@
// $Id: welloperations.cpp 882 2011-09-23 13:10:16Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "welloperations.hpp"
using namespace NRLib;

View File

@@ -0,0 +1,168 @@
// $Id: welloperations.hpp 883 2011-09-26 09:17:05Z perroe $
// Copyright (c) 2011, Norwegian Computing Center
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// <20> Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// <20> Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NRLIB_WELLOPERATIONS_HPP
#define NRLIB_WELLOPERATIONS_HPP
#include <string>
#include <iomanip>
#include <vector>
#include <sstream>
#include "../exception/exception.hpp"
#include "well.hpp"
#include "rmswell.hpp"
#include "../stormgrid/stormcontgrid.hpp"
#include "../stormgrid/stormfaciesgrid.hpp"
namespace NRLib {
/// Block the well into the grid.
/// Possible grids to use are StormContGrid and StormFaciesGrid
template <typename A>
void BlockWell(const NRLib::Well & well,
const A & grid,
NRLib::Well & blocked_well);
}
template <typename A>
void NRLib::BlockWell(const NRLib::Well & well,
const A & grid,
NRLib::Well & blocked_well)
{
size_t i;
size_t loglength = well.GetContLogLength("x");
std::vector<size_t> index(loglength);
double x, y, z;
for (i = 0; i < loglength; i++) {
x = well.GetContValue(i, "x");
y = well.GetContValue(i, "y");
z = well.GetContValue(i, "z");
index[i] = grid.FindIndex(x, y, z);
}
std::vector<size_t> indexvalues;
indexvalues.push_back(index[0]);
bool found = false;
size_t k;
for (i = 0; i < loglength; i++) {
for (k = 0; k < indexvalues.size(); k++)
if (index[i] == indexvalues[k])
found = true;
if (found == false)
indexvalues.push_back(index[i]);
found = false;
}
size_t novalues = indexvalues.size();
std::vector<int> no(novalues);
for (i = 0; i < novalues; i++) {
no[i] = 0;
for (k = 0; k < loglength; k++) {
if (index[k] == indexvalues[i])
no[i]++;
}
}
size_t ncont = well.GetNContLog();
size_t ndisc = well.GetNlog() - ncont;
std::vector<std::vector<int> > disclogs(ndisc, std::vector<int>(novalues));
std::vector<std::vector<int> > nodisc(ndisc, std::vector<int>(novalues));
std::vector<std::vector<int> > nocont(ncont, std::vector<int>(novalues));
std::vector<std::vector<double> > contlogs(ncont, std::vector<double>(novalues));
for (k = 0; k < novalues; k++) {
for (i = 0; i < ncont; i++) {
contlogs[i][k] = 0.0;
nocont[i][k] = 0;
}
for (i = 0; i < ndisc; i++) {
disclogs[i][k] = 0;
nodisc[i][k] = 0;
}
}
std::vector<std::string> discnames(ndisc);
std::vector<std::string> contnames(ncont);
typedef std::map<std::string, std::vector<int> >::const_iterator CI;
const std::map<std::string,std::vector<int> >& disclog = well.GetDiscLog();
i = 0;
for (CI p = disclog.begin(); p != disclog.end(); ++p) {
discnames[i] = p->first;
i++;
}
i = 0;
typedef std::map<std::string, std::vector<double> >::const_iterator CID;
const std::map<std::string,std::vector<double> >& contlog = well.GetContLog();
for (CID p = contlog.begin(); p != contlog.end(); ++p) {
contnames[i] = p->first;
i++;
}
size_t j;
double valuec;
int valuei;
for (i = 0; i < loglength; i++) {
for (k = 0; k < novalues; k++) {
if (index[i] == indexvalues[k]) {
for (j = 0; j < ncont; j++) {
valuec = well.GetContValue(i, contnames[j]);
if (!well.IsMissing(valuec)) {
contlogs[j][k] += valuec;
nocont[j][k]++;
}
}
for (j = 0; j < ndisc; j++) {
valuei = well.GetDiscValue(i, discnames[j]);
if (!well.IsMissing(valuei)) {
disclogs[j][k] += valuei;
nodisc[j][k]++;
}
}
}
}
}
for (k = 0; k < novalues; k++) {
for (j = 0; j < ncont; j++) {
if (nocont[j][k] == 0)
contlogs[j][k] = well.GetContMissing();
else
contlogs[j][k] /= nocont[j][k];
}
for (j = 0; j < ndisc; j++) {
if (nodisc[j][k] == 0)
disclogs[j][k] = well.GetIntMissing();
else
disclogs[j][k] /= nodisc[j][k];
}
}
std::map<std::string,std::vector<double> > contlognew;
for (i = 0; i < ncont; i++) {
contlognew[contnames[i]] = contlogs[i];
}
std::map<std::string, std::vector<int> > disclognew;
for (i = 0; i < ndisc; i++) {
disclognew[discnames[i]] = disclogs[i];
}
std::string well_name = well.GetWellName() + "blocked";
blocked_well = Well(contlognew, disclognew, well_name);
}
#endif