Add matio library and add test case for it

This commit is contained in:
Carles Fernandez 2017-11-17 14:47:50 +01:00
parent c45c8f80af
commit 929125cce5
5 changed files with 285 additions and 0 deletions

View File

@ -1442,6 +1442,54 @@ endif(ENABLE_GPROF)
########################################################################
# Matio (OPTIONAL) - https://github.com/tbeu/matio
########################################################################
find_package(MATIO)
if(NOT MATIO_FOUND)
find_package(ZLIB)
get_filename_component(ZLIB_BASE_DIR ${ZLIB_INCLUDE_DIRS} DIRECTORY)
find_package(HDF5)
list(GET ${HDF5_INCLUDE_DIRS} 0 HDF5_INCLUDE_FIRST_DIR)
get_filename_component(HDF5_BASE_DIR ${HDF5_INCLUDE_FIRST_DIR} DIRECTORY)
if(OS_IS_MACOSX)
if(EXISTS /opt/local/include/hdf5.h)
set(HDF5_BASE_DIR /opt/local)
endif(EXISTS /opt/local/include/hdf5.h)
if(EXISTS /usr/local/include/hdf5.h)
set(HDF5_BASE_DIR /usr/local)
endif(EXISTS /usr/local/include/hdf5.h)
endif(OS_IS_MACOSX)
if(CMAKE_VERSION VERSION_LESS 3.2)
ExternalProject_Add(
matio
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio
GIT_REPOSITORY https://github.com/tbeu/matio
GIT_TAG master
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio/autogen.sh
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix=<INSTALL_DIR>
BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}"
)
else(CMAKE_VERSION VERSION_LESS 3.2)
ExternalProject_Add(
matio
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio
GIT_REPOSITORY https://github.com/tbeu/matio
GIT_TAG master
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio/autogen.sh
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix=<INSTALL_DIR>
BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}"
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX}
)
endif(CMAKE_VERSION VERSION_LESS 3.2)
set(MATIO_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} ${HDF5_LIBRARIES} ${ZLIB_LIBRARIES} )
set(MATIO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/matio/include )
endif(NOT MATIO_FOUND)
########################################################################
# Set compiler flags
########################################################################

View File

@ -0,0 +1,100 @@
# FindMATIO
#
# Try to find MATIO library
#
# Once done this will define:
#
# MATIO_FOUND - True if MATIO found.
# MATIO_LIBRARIES - MATIO libraries.
# MATIO_INCLUDE_DIRS - where to find matio.h, etc..
# MATIO_VERSION_STRING - version number as a string (e.g.: "1.3.4")
#
#=============================================================================
# Copyright 2015 Avtech Scientific <http://avtechscientific.com>
#
# 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.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# 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.
#=============================================================================
#
# Look for the header file.
find_path(MATIO_INCLUDE_DIR NAMES matio.h DOC "The MATIO include directory")
# Look for the library.
find_library(MATIO_LIBRARY NAMES matio DOC "The MATIO library")
if(MATIO_INCLUDE_DIR)
# ---------------------------------------------------
# Extract version information from MATIO
# ---------------------------------------------------
# If the file is missing, set all values to 0
set(MATIO_MAJOR_VERSION 0)
set(MATIO_MINOR_VERSION 0)
set(MATIO_RELEASE_LEVEL 0)
# new versions of MATIO have `matio_pubconf.h`
if(EXISTS ${MATIO_INCLUDE_DIR}/matio_pubconf.h)
set(MATIO_CONFIG_FILE "matio_pubconf.h")
else()
set(MATIO_CONFIG_FILE "matioConfig.h")
endif()
if(MATIO_CONFIG_FILE)
# Read and parse MATIO config header file for version number
file(STRINGS "${MATIO_INCLUDE_DIR}/${MATIO_CONFIG_FILE}" _matio_HEADER_CONTENTS REGEX "#define MATIO_((MAJOR|MINOR)_VERSION)|(RELEASE_LEVEL) ")
foreach(line ${_matio_HEADER_CONTENTS})
if(line MATCHES "#define ([A-Z_]+) ([0-9]+)")
set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}")
endif()
endforeach()
unset(_matio_HEADER_CONTENTS)
endif()
set(MATIO_VERSION_STRING "${MATIO_MAJOR_VERSION}.${MATIO_MINOR_VERSION}.${MATIO_RELEASE_LEVEL}")
endif ()
#==================
mark_as_advanced(MATIO_INCLUDE_DIR MATIO_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set MATIO_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MATIO REQUIRED_VARS MATIO_LIBRARY MATIO_INCLUDE_DIR VERSION_VAR MATIO_VERSION_STRING)
if(MATIO_FOUND)
set(MATIO_LIBRARIES ${MATIO_LIBRARY})
set(MATIO_INCLUDE_DIRS ${MATIO_INCLUDE_DIR})
else(MATIO_FOUND)
set(MATIO_LIBRARIES)
set(MATIO_INCLUDE_DIRS)
endif(MATIO_FOUND)

View File

@ -320,6 +320,7 @@ include_directories(
${VOLK_GNSSSDR_INCLUDE_DIRS}
${GNSS_SDR_TEST_OPTIONAL_HEADERS}
${GNSS_SDR_TEST_OPTIONAL_HEADERS}
${MATIO_INCLUDE_DIRS}
)
@ -354,6 +355,7 @@ if(ENABLE_UNIT_TESTING)
signal_processing_testing_lib
${VOLK_GNSSSDR_LIBRARIES}
${GNSS_SDR_TEST_OPTIONAL_LIBS}
${MATIO_LIBRARIES}
)
if(NOT ${GTEST_DIR_LOCAL})
add_dependencies(run_tests gtest-${GNSSSDR_GTEST_LOCAL_VERSION})

View File

@ -70,6 +70,7 @@ DECLARE_string(log_dir);
#include "unit-tests/arithmetic/code_generation_test.cc"
#include "unit-tests/arithmetic/fft_length_test.cc"
#include "unit-tests/arithmetic/fft_speed_test.cc"
#include "unit-tests/arithmetic/matio_test.cc"
#include "unit-tests/control-plane/file_configuration_test.cc"
#include "unit-tests/control-plane/in_memory_configuration_test.cc"

View File

@ -0,0 +1,134 @@
/*!
* \file matio_test.cc
* \brief This file implements tests for the matio library
* in long arrays.
* \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es
*
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include <matio.h>
#include <cstdio>
#include <gnuradio/gr_complex.h>
TEST(MatioTest, WriteAndReadDoubles)
{
// Write a .mat file
mat_t *matfp;
matvar_t *matvar;
std::string filename = "./test.mat";
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
ASSERT_FALSE(reinterpret_cast<long*>(matfp) == NULL) << "Error creating .mat file";
double x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
size_t dims[2] = {10, 1};
matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, x, 0);
ASSERT_FALSE(reinterpret_cast<long*>(matvar) == NULL) << "Error creating variable for x";
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
Mat_Close(matfp);
// Read a .mat file
mat_t *matfp_read;
matvar_t *matvar_read;
matfp_read = Mat_Open(filename.c_str(), MAT_ACC_RDONLY);
ASSERT_FALSE(reinterpret_cast<long*>(matfp_read) == NULL) << "Error reading .mat file";
matvar_read = Mat_VarReadInfo(matfp_read, "x");
ASSERT_FALSE(reinterpret_cast<long*>(matvar_read) == NULL) << "Error reading variable in .mat file";
matvar_read = Mat_VarRead(matfp_read, "x");
double *x_read = reinterpret_cast<double*>(matvar_read->data);
Mat_Close(matfp_read);
for(int i = 0; i < 10; i++)
{
EXPECT_DOUBLE_EQ(x[i], x_read[i]);
}
ASSERT_EQ(remove(filename.c_str()), 0);
}
TEST(MatioTest, WriteAndReadGrComplex)
{
// Write a .mat file
mat_t *matfp;
matvar_t *matvar;
std::string filename = "./test2.mat";
matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73);
ASSERT_FALSE(reinterpret_cast<long*>(matfp) == NULL) << "Error creating .mat file";
std::vector<gr_complex> x_v = { {1, 10}, {2, 9}, {3, 8}, {4, 7}, {5, 6}, {6, -5}, {7, -4}, {8, 3}, {9, 2}, {10, 1}};
const int size = x_v.size();
float x_real[size];
float x_imag[size];
for (int i = 0; i < x_v.size(); i++)
{
x_real[i] = x_v.at(i).real();
x_imag[i] = x_v.at(i).imag();
}
struct mat_complex_split_t x = {x_real, x_imag};
size_t dims[2] = {static_cast<size_t>(size), 1};
matvar = Mat_VarCreate("x", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, &x, MAT_F_COMPLEX);
ASSERT_FALSE(reinterpret_cast<long*>(matvar) == NULL) << "Error creating variable for x";
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar);
Mat_Close(matfp);
// Read a .mat file
mat_t *matfp_read;
matvar_t *matvar_read;
matfp_read = Mat_Open(filename.c_str(), MAT_ACC_RDONLY);
ASSERT_FALSE(reinterpret_cast<long*>(matfp_read) == NULL) << "Error reading .mat file";
matvar_read = Mat_VarReadInfo(matfp_read, "x");
ASSERT_FALSE(reinterpret_cast<long*>(matvar_read) == NULL) << "Error reading variable in .mat file";
matvar_read = Mat_VarRead(matfp_read, "x");
mat_complex_split_t *x_read_st = reinterpret_cast<mat_complex_split_t*>(matvar_read->data);
float * x_read_real = reinterpret_cast<float*>(x_read_st->Re);
float * x_read_imag = reinterpret_cast<float*>(x_read_st->Im);
std::vector<gr_complex> x_v_read;
for(int i = 0; i < size; i++)
{
x_v_read.push_back(gr_complex(x_read_real[i], x_read_imag[i]));
}
Mat_Close(matfp_read);
for(int i = 0; i < size; i++)
{
EXPECT_FLOAT_EQ(x_v[i].real(), x_v_read[i].real());
EXPECT_FLOAT_EQ(x_v[i].imag(), x_v_read[i].imag());
}
ASSERT_EQ(remove(filename.c_str()), 0);
}