diff --git a/.gitattributes b/.gitattributes index 245c88584eb80682220a158162e4d762fb0d1b5b..2e988deb11f822fe71ce97a14c029b8e6e31c035 100644 --- a/.gitattributes +++ b/.gitattributes @@ -458,16 +458,6 @@ CEP/DP3/DPPP_DDECal/test/tDDECal.sh -text CEP/DP3/DPPP_DDECal/test/tDDECal_ref -text CEP/DP3/DPPP_DDECal/test/tRotationConstraint.cc -text CEP/DP3/DPPP_DDECal/test/tRotationConstraint.sh -text -CEP/DP3/DPPP_Interpolate/CMake/CheckCXXSymbolExists.cmake -text -CEP/DP3/DPPP_Interpolate/CMake/FindCFITSIO.cmake -text -CEP/DP3/DPPP_Interpolate/CMake/FindCasacore.cmake -text -CEP/DP3/DPPP_Interpolate/CMakeLists-standalone.txt -text -CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/CMakeLists.txt -text -CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/Interpolate.h -text -CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/buffered_lane.h -text -CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/lane.h -text -CEP/DP3/DPPP_Interpolate/src/CMakeLists.txt -text -CEP/DP3/DPPP_Interpolate/src/Interpolate.cc -text CEP/DP3/PythonDPPP/CMakeLists.txt -text CEP/DP3/PythonDPPP/include/PythonDPPP/CMakeLists.txt -text CEP/DP3/PythonDPPP/include/PythonDPPP/DPStepBase.h -text diff --git a/CEP/DP3/DPPP_Interpolate/CMake/CheckCXXSymbolExists.cmake b/CEP/DP3/DPPP_Interpolate/CMake/CheckCXXSymbolExists.cmake deleted file mode 100644 index 084fbb422f5a607b4083e5d7108aefbf90d9aa3c..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/CMake/CheckCXXSymbolExists.cmake +++ /dev/null @@ -1,49 +0,0 @@ -#.rst: -# CheckCXXSymbolExists -# -------------------- -# -# Check if a symbol exists as a function, variable, or macro in C++ -# -# CHECK_CXX_SYMBOL_EXISTS(<symbol> <files> <variable>) -# -# Check that the <symbol> is available after including given header -# <files> and store the result in a <variable>. Specify the list of -# files in one argument as a semicolon-separated list. -# CHECK_CXX_SYMBOL_EXISTS() can be used to check in C++ files, as -# opposed to CHECK_SYMBOL_EXISTS(), which works only for C. -# -# If the header files define the symbol as a macro it is considered -# available and assumed to work. If the header files declare the symbol -# as a function or variable then the symbol must also be available for -# linking. If the symbol is a type or enum value it will not be -# recognized (consider using CheckTypeSize or CheckCSourceCompiles). -# -# The following variables may be set before calling this macro to modify -# the way the check is run: -# -# :: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages - -#============================================================================= -# Copyright 2003-2011 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -include(CheckSymbolExists) - -macro(CHECK_CXX_SYMBOL_EXISTS SYMBOL FILES VARIABLE) - _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) -endmacro() diff --git a/CEP/DP3/DPPP_Interpolate/CMake/FindCFITSIO.cmake b/CEP/DP3/DPPP_Interpolate/CMake/FindCFITSIO.cmake deleted file mode 100644 index 6501f7762ca300f4ec488a0adf66e013723cfc5c..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/CMake/FindCFITSIO.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# - Try to find CFITSIO. -# Variables used by this module: -# CFITSIO_ROOT_DIR - CFITSIO root directory -# Variables defined by this module: -# CFITSIO_FOUND - system has CFITSIO -# CFITSIO_INCLUDE_DIR - the CFITSIO include directory (cached) -# CFITSIO_INCLUDE_DIRS - the CFITSIO include directories -# (identical to CFITSIO_INCLUDE_DIR) -# CFITSIO_LIBRARY - the CFITSIO library (cached) -# CFITSIO_LIBRARIES - the CFITSIO libraries -# (identical to CFITSIO_LIBRARY) - -# Copyright (C) 2009 -# ASTRON (Netherlands Institute for Radio Astronomy) -# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -# -# This file is part of the LOFAR software suite. -# The LOFAR software suite 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. -# -# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. -# -# $Id: FindCFITSIO.cmake 22498 2012-10-23 10:51:12Z loose $ - -if(NOT CFITSIO_FOUND) - - find_path(CFITSIO_INCLUDE_DIR fitsio.h - HINTS ${CFITSIO_ROOT_DIR} PATH_SUFFIXES include include/cfitsio include/libcfitsio0) - find_library(CFITSIO_LIBRARY cfitsio - HINTS ${CFITSIO_ROOT_DIR} PATH_SUFFIXES lib) - find_library(M_LIBRARY m) - mark_as_advanced(CFITSIO_INCLUDE_DIR CFITSIO_LIBRARY M_LIBRARY) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(CFITSIO DEFAULT_MSG - CFITSIO_LIBRARY M_LIBRARY CFITSIO_INCLUDE_DIR) - - set(CFITSIO_INCLUDE_DIRS ${CFITSIO_INCLUDE_DIR}) - set(CFITSIO_LIBRARIES ${CFITSIO_LIBRARY} ${M_LIBRARY}) - -endif(NOT CFITSIO_FOUND) diff --git a/CEP/DP3/DPPP_Interpolate/CMake/FindCasacore.cmake b/CEP/DP3/DPPP_Interpolate/CMake/FindCasacore.cmake deleted file mode 100644 index e4689f75102cc9e72847ed03ac2e71bc7ded82c7..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/CMake/FindCasacore.cmake +++ /dev/null @@ -1,267 +0,0 @@ -# - Try to find Casacore include dirs and libraries -# Usage: -# find_package(Casacore [REQUIRED] [COMPONENTS components...]) -# Valid components are: -# casa, coordinates, derivedmscal, fits, images, lattices, -# meas, measures, mirlib, ms, msfits, python, scimath, scimath_f, tables -# -# Note that most components are dependent on other (more basic) components. -# In that case, it suffices to specify the "top-level" components; dependent -# components will be searched for automatically. -# -# The dependency tree can be generated using the script get_casacore_deps.sh. -# For this, you need to have a complete casacore installation, built with shared -# libraries, at your disposal. -# -# The dependencies in this macro were generated against casacore release 1.7.0. -# -# Variables used by this module: -# CASACORE_ROOT_DIR - Casacore root directory. -# -# Variables defined by this module: -# CASACORE_FOUND - System has Casacore, which means that the -# include dir was found, as well as all -# libraries specified (not cached) -# CASACORE_INCLUDE_DIR - Casacore include directory (cached) -# CASACORE_INCLUDE_DIRS - Casacore include directories (not cached) -# identical to CASACORE_INCLUDE_DIR -# CASACORE_LIBRARIES - The Casacore libraries (not cached) -# CASA_${COMPONENT}_LIBRARY - The absolute path of Casacore library -# "component" (cached) -# HAVE_AIPSPP - True if system has Casacore (cached) -# for backward compatibility with AIPS++ -# HAVE_CASACORE - True if system has Casacore (cached) -# identical to CASACORE_FOUND -# TAQL_EXECUTABLE - The absolute path of the TaQL executable -# (cached) -# -# ATTENTION: The component names need to be in lower case, just as the -# casacore library names. However, the CMake variables use all upper case. - -# Copyright (C) 2009 -# ASTRON (Netherlands Institute for Radio Astronomy) -# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -# -# This file is part of the LOFAR software suite. -# The LOFAR software suite 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. -# -# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. -# -# $Id: FindCasacore.cmake 31487 2015-04-16 11:28:17Z dijkema $ - -# - casacore_resolve_dependencies(_result) -# -# Resolve the Casacore library dependencies for the given components. -# The list of dependent libraries will be returned in the variable result. -# It is sorted from least dependent to most dependent library, so it can be -# directly fed to the linker. -# -# Usage: casacore_resolve_dependencies(result components...) -# -macro(casacore_resolve_dependencies _result) - set(${_result} ${ARGN}) - set(_index 0) - # Do a breadth-first search through the dependency graph; append to the - # result list the dependent components for each item in that list. - # Duplicates will be removed later. - while(1) - list(LENGTH ${_result} _length) - if(NOT _index LESS _length) - break() - endif(NOT _index LESS _length) - list(GET ${_result} ${_index} item) - list(APPEND ${_result} ${Casacore_${item}_DEPENDENCIES}) - math(EXPR _index "${_index}+1") - endwhile(1) - # Remove all duplicates in the current result list, while retaining only the - # last of each duplicate. - list(REVERSE ${_result}) - list(REMOVE_DUPLICATES ${_result}) - list(REVERSE ${_result}) -endmacro(casacore_resolve_dependencies _result) - - -# - casacore_find_library(_name) -# -# Search for the library ${_name}. -# If library is found, add it to CASACORE_LIBRARIES; if not, add ${_name} -# to CASACORE_MISSING_COMPONENTS and set CASACORE_FOUND to false. -# -# Usage: casacore_find_library(name) -# -macro(casacore_find_library _name) - string(TOUPPER ${_name} _NAME) - find_library(${_NAME}_LIBRARY ${_name} - HINTS ${CASACORE_ROOT_DIR} PATH_SUFFIXES lib) - mark_as_advanced(${_NAME}_LIBRARY) - if(${_NAME}_LIBRARY) - list(APPEND CASACORE_LIBRARIES ${${_NAME}_LIBRARY}) - else(${_NAME}_LIBRARY) - set(CASACORE_FOUND FALSE) - list(APPEND CASACORE_MISSING_COMPONENTS ${_name}) - endif(${_NAME}_LIBRARY) -endmacro(casacore_find_library _name) - - -# - casacore_find_package(_name) -# -# Search for the package ${_name}. -# If the package is found, add the contents of ${_name}_INCLUDE_DIRS to -# CASACORE_INCLUDE_DIRS and ${_name}_LIBRARIES to CASACORE_LIBRARIES. -# -# If Casacore itself is required, then, strictly speaking, the packages it -# requires must be present. However, when linking against static libraries -# they may not be needed. One can override the REQUIRED setting by switching -# CASACORE_MAKE_REQUIRED_EXTERNALS_OPTIONAL to ON. Beware that this might cause -# compile and/or link errors. -# -# Usage: casacore_find_package(name [REQUIRED]) -# -macro(casacore_find_package _name) - if("${ARGN}" MATCHES "^REQUIRED$" AND - Casacore_FIND_REQUIRED AND - NOT CASACORE_MAKE_REQUIRED_EXTERNALS_OPTIONAL) - find_package(${_name} REQUIRED) - else() - find_package(${_name}) - endif() - if(${_name}_FOUND) - list(APPEND CASACORE_INCLUDE_DIRS ${${_name}_INCLUDE_DIRS}) - list(APPEND CASACORE_LIBRARIES ${${_name}_LIBRARIES}) - endif(${_name}_FOUND) -endmacro(casacore_find_package _name) - -# Define the Casacore components. -set(Casacore_components - casa - coordinates - derivedmscal - fits - images - lattices - meas - measures - mirlib - ms - msfits - python - scimath - scimath_f - tables -) - -# Define the Casacore components' inter-dependencies. -set(Casacore_casa_DEPENDENCIES) -set(Casacore_coordinates_DEPENDENCIES fits measures casa) -set(Casacore_derivedmscal_DEPENDENCIES ms measures tables casa) -set(Casacore_fits_DEPENDENCIES measures tables casa) -set(Casacore_images_DEPENDENCIES mirlib lattices coordinates fits measures scimath tables casa) -set(Casacore_lattices_DEPENDENCIES tables scimath casa) -set(Casacore_meas_DEPENDENCIES measures tables casa) -set(Casacore_measures_DEPENDENCIES tables casa) -set(Casacore_mirlib_DEPENDENCIES) -set(Casacore_ms_DEPENDENCIES measures scimath tables casa) -set(Casacore_msfits_DEPENDENCIES ms fits measures tables casa) -set(Casacore_python_DEPENDENCIES casa) -set(Casacore_scimath_DEPENDENCIES scimath_f casa) -set(Casacore_scimath_f_DEPENDENCIES) -set(Casacore_tables_DEPENDENCIES casa) - -# Initialize variables. -set(CASACORE_FOUND FALSE) -set(CASACORE_DEFINITIONS) -set(CASACORE_LIBRARIES) -set(CASACORE_MISSING_COMPONENTS) - -# Search for the header file first. -if(NOT CASACORE_INCLUDE_DIR) - find_path(CASACORE_INCLUDE_DIR casacore/casa/aips.h - HINTS ${CASACORE_ROOT_DIR} PATH_SUFFIXES include) - mark_as_advanced(CASACORE_INCLUDE_DIR) -endif(NOT CASACORE_INCLUDE_DIR) - -# Fallback for systems that have old casacore installed in directory not called 'casacore' -# This fallback can be removed once we move to casacore 2.0 which always puts headers in 'casacore' -if(NOT CASACORE_INCLUDE_DIR) - find_path(CASACORE_INCLUDE_DIR casa/aips.h - HINTS ${CASACORE_ROOT_DIR} PATH_SUFFIXES include) - mark_as_advanced(CASACORE_INCLUDE_DIR) -endif(NOT CASACORE_INCLUDE_DIR) - -if(NOT CASACORE_INCLUDE_DIR) - set(CASACORE_ERROR_MESSAGE "Casacore: unable to find the header file casa/aips.h.\nPlease set CASACORE_ROOT_DIR to the root directory containing Casacore.") -else(NOT CASACORE_INCLUDE_DIR) - # We've found the header file; let's continue. - set(CASACORE_FOUND TRUE) - # Note that new Casacore uses #include<casacore/casa/...>, while - # LOFAR still uses #include<casa/...>. Hence use both in -I path. - set(CASACORE_INCLUDE_DIRS ${CASACORE_INCLUDE_DIR} ${CASACORE_INCLUDE_DIR}/casacore) - - # Search for some often used binaries. - find_program(TAQL_EXECUTABLE taql - HINTS ${CASACORE_ROOT_DIR}/bin) - mark_as_advanced(TAQL_EXECUTABLE) - - # If the user specified components explicity, use that list; otherwise we'll - # assume that the user wants to use all components. - if(NOT Casacore_FIND_COMPONENTS) - set(Casacore_FIND_COMPONENTS ${Casacore_components}) - endif(NOT Casacore_FIND_COMPONENTS) - - # Get a list of all dependent Casacore libraries that need to be found. - casacore_resolve_dependencies(_find_components ${Casacore_FIND_COMPONENTS}) - - # Find the library for each component, and handle external dependencies - foreach(_comp ${_find_components}) - casacore_find_library(casa_${_comp}) - if(${_comp} STREQUAL casa) - casacore_find_package(HDF5) - casacore_find_library(m) - list(APPEND CASACORE_LIBRARIES ${CMAKE_DL_LIBS}) - elseif(${_comp} STREQUAL coordinates) - casacore_find_package(WCSLIB REQUIRED) - elseif(${_comp} STREQUAL fits) - casacore_find_package(CFITSIO REQUIRED) - elseif(${_comp} STREQUAL scimath_f) - casacore_find_package(LAPACK REQUIRED) - endif(${_comp} STREQUAL casa) - endforeach(_comp ${_find_components}) -endif(NOT CASACORE_INCLUDE_DIR) - -# Set HAVE_CASACORE; and HAVE_AIPSPP (for backward compatibility with AIPS++). -if(CASACORE_FOUND) - set(HAVE_CASACORE TRUE CACHE INTERNAL "Define if Casacore is installed") - set(HAVE_AIPSPP TRUE CACHE INTERNAL "Define if AIPS++/Casacore is installed") -endif(CASACORE_FOUND) - -# Compose diagnostic message if not all necessary components were found. -if(CASACORE_MISSING_COMPONENTS) - set(CASACORE_ERROR_MESSAGE "Casacore: the following components could not be found:\n ${CASACORE_MISSING_COMPONENTS}") -endif(CASACORE_MISSING_COMPONENTS) - -# Print diagnostics. -if(CASACORE_FOUND) - if(NOT Casacore_FIND_QUIETLY) - message(STATUS "Found the following Casacore components: ") - foreach(_comp ${_find_components}) - string(TOUPPER casa_${_comp} _COMP) - message(STATUS " ${_comp}: ${${_COMP}_LIBRARY}") - endforeach(_comp ${_find_components}) - endif(NOT Casacore_FIND_QUIETLY) -else(CASACORE_FOUND) - if(Casacore_FIND_REQUIRED) - message(FATAL_ERROR "${CASACORE_ERROR_MESSAGE}") - else(Casacore_FIND_REQUIRED) - message(STATUS "${CASACORE_ERROR_MESSAGE}") - endif(Casacore_FIND_REQUIRED) -endif(CASACORE_FOUND) - diff --git a/CEP/DP3/DPPP_Interpolate/CMakeLists-standalone.txt b/CEP/DP3/DPPP_Interpolate/CMakeLists-standalone.txt deleted file mode 100644 index 798f11ee87b4e503c317dc8e8d280c36025c39cf..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/CMakeLists-standalone.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -project(DPPP_Interpolate) - -# Casacore has a separate CMake file in this directory -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake) - -SET(CASACORE_MAKE_REQUIRED_EXTERNALS_OPTIONAL TRUE) -find_package(Casacore REQUIRED COMPONENTS casa ms tables measures) - -find_package(Threads REQUIRED) - -include_directories(${CASACORE_INCLUDE_DIRS} ../../../build/gnucxx11_opt/include/) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -DNDEBUG --std=c++11 -ggdb") - -add_library(interpolate-object OBJECT - src/Interpolate.cc - ../../../LCS/Common/src/LofarLogCout.cc) -set_property(TARGET interpolate-object PROPERTY POSITION_INDEPENDENT_CODE 1) - -# Note: casapy fails if Casa is linked in the storage manager, so we have to trust that -# casapy's version of casacore is binary compatible with this storage manager's casacore. -add_library(dppp_interpolate SHARED $<TARGET_OBJECTS:interpolate-object>) -target_link_libraries(dppp_interpolate ${CASACORE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - -install (TARGETS dppp_interpolate DESTINATION lib) diff --git a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/CMakeLists.txt b/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/CMakeLists.txt deleted file mode 100644 index 3d9cb5dee52325f9070cf7377adc73744106910e..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# $Id: CMakeLists.txt 39071 2018-02-08 15:50:02Z dijkema $ - -# List of header files that will be installed. -set(inst_HEADERS - buffered_lane.h Interpolate.h lane.h - ) - -# Create symbolic link to include directory. -execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_BINARY_DIR}/include/${PACKAGE_NAME}) - -# Install header files. -install(FILES ${inst_HEADERS} DESTINATION include/${PACKAGE_NAME}) diff --git a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/Interpolate.h b/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/Interpolate.h deleted file mode 100644 index 97570460a720a504820db81f30831d21cf5be37f..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/Interpolate.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef INTERPOLATE_H -#define INTERPOLATE_H - -#include <deque> -#include <string> - -#include <DPPP/DPInput.h> -#include <DPPP/DPBuffer.h> - -#include <Common/ParameterSet.h> - -#include <casacore/casa/Arrays/Cube.h> - -#include "lane.h" - -extern "C" void register_interpolate(); - -namespace LOFAR { namespace DPPP { - - class Interpolate : public DPStep - { - public: - // Construct the object. - // Parameters are obtained from the parset using the given prefix. - Interpolate (DPInput*, const ParameterSet&, const string& prefix); - - virtual ~Interpolate() = default; - - // Process the data. - // It keeps the data. - // When processed, it invokes the process function of the next step. - virtual bool process (const DPBuffer&); - - // Finish the processing of this step and subsequent steps. - virtual void finish(); - - // Update the general info. - virtual void updateInfo (const DPInfo&); - - // Show the step parameters. - virtual void show (std::ostream&) const; - - // Show the timings. - virtual void showTimings (std::ostream&, double duration) const; - - static DPStep::ShPtr makeStep(DPInput* input, const ParameterSet& parset, const std::string& prefix); - - private: - void interpolateTimestep(size_t index); - void interpolateSample(size_t timestep, size_t baseline, size_t channel, size_t pol); - void sendFrontBufferToNextStep(); - void interpolationThread(); - - struct Sample { - Sample() = default; - Sample(size_t timestep_, size_t baseline_, size_t channel_, size_t pol_) : - timestep(timestep_), baseline(baseline_), channel(channel_), pol(pol_) - { } - size_t timestep; - size_t baseline; - size_t channel; - size_t pol; - }; - - //# Data members. - std::string _name; - size_t _interpolatedPos; - std::deque<DPBuffer> _buffers; - size_t _windowSize; - NSTimer _timer; - ao::lane<Sample> _lane; - std::vector<float> _kernelLookup; - }; - -} } //# end namespace - -#endif diff --git a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/buffered_lane.h b/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/buffered_lane.h deleted file mode 100644 index d9c0f9ec07316b11d42c73c8661a425fce426ae3..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/buffered_lane.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef BUFFER_LANE_H -#define BUFFER_LANE_H - -#include <vector> - -#include "lane.h" - -template<typename Tp> -class lane_write_buffer -{ -public: - typedef typename ao::lane<Tp>::size_type size_type; - typedef typename ao::lane<Tp>::value_type value_type; - - lane_write_buffer() : _buffer_size(0), _lane(0) - { } - - lane_write_buffer(ao::lane<Tp>* lane, size_type buffer_size) : _buffer_size(buffer_size), _lane(lane) - { - _buffer.reserve(buffer_size); - } - - ~lane_write_buffer() - { - flush(); - } - - void reset(ao::lane<Tp>* lane, size_type buffer_size) - { - _buffer.clear(); - _buffer.reserve(buffer_size); - _buffer_size = buffer_size; - _lane = lane; - } - - void clear() - { - _lane->clear(); - _buffer.clear(); - } - - void write(const value_type& element) - { - _buffer.push_back(element); - if(_buffer.size() == _buffer_size) - flush(); - } - - void write(value_type&& element) - { - _buffer.push_back(std::move(element)); - if(_buffer.size() == _buffer_size) - flush(); - } - - template<typename... Args> - void emplace(Args&&... args) - { - _buffer.emplace_back(args...); - if(_buffer.size() == _buffer_size) - flush(); - } - - void write_end() - { - flush(); - _lane->write_end(); - } - - void flush() - { - _lane->move_write(&_buffer[0], _buffer.size()); - _buffer.clear(); - } -private: - size_type _buffer_size; - std::vector<value_type> _buffer; - ao::lane<Tp>* _lane; -}; - -template<typename Tp> -class lane_read_buffer -{ -public: - lane_read_buffer(ao::lane<Tp>* lane, size_t buffer_size) : - _buffer(new Tp[buffer_size]), - _buffer_size(buffer_size), - _buffer_pos(0), - _buffer_fill_count(0), - _lane(lane) - { - } - - ~lane_read_buffer() - { - delete[] _buffer; - } - - bool read(Tp& element) - { - if(_buffer_pos == _buffer_fill_count) - { - _buffer_fill_count = _lane->read(_buffer, _buffer_size); - _buffer_pos = 0; - if(_buffer_fill_count == 0) - return false; - } - element = std::move(_buffer[_buffer_pos]); - ++_buffer_pos; - return true; - } - -private: - lane_read_buffer(const lane_read_buffer&) = delete; - lane_read_buffer& operator=(const lane_read_buffer&) = delete; - - Tp* _buffer; - size_t _buffer_size, _buffer_pos, _buffer_fill_count; - ao::lane<Tp>* _lane; -}; - -#endif diff --git a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/lane.h b/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/lane.h deleted file mode 100644 index 4be42a6e061dfb3acc26c7d25f75d611040b1bfe..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/include/DPPP_Interpolate/lane.h +++ /dev/null @@ -1,576 +0,0 @@ -#ifndef AO_LANE_11_H -#define AO_LANE_11_H - -#include <cstring> -#include <deque> -#include <mutex> -#include <condition_variable> - -/** - * @file - * Internal header file for the lane. - * @headername{lane.h} - */ - -//#define LANE_DEBUG_MODE - -#ifdef LANE_DEBUG_MODE -#include <string> -#include <iostream> -#include <sstream> -#include <cmath> -#endif - -namespace ao -{ - -#ifdef LANE_DEBUG_MODE -#define set_lane_debug_name(lane, str) (lane).setDebugName(str) -#define LANE_REGISTER_DEBUG_INFO registerDebugInfo() -#define LANE_REGISTER_DEBUG_WRITE_WAIT registerDebugWriteWait() -#define LANE_REGISTER_DEBUG_READ_WAIT registerDebugReadWait() -#define LANE_REPORT_DEBUG_INFO reportDebugInfo() - -#else - -#define set_lane_debug_name(lane, str) -#define LANE_REGISTER_DEBUG_INFO -#define LANE_REGISTER_DEBUG_WRITE_WAIT -#define LANE_REGISTER_DEBUG_READ_WAIT -#define LANE_REPORT_DEBUG_INFO - -#endif - -/** - * @brief The lane is an efficient cyclic buffer that is synchronized. - * @details - * A lane can typically be used in a multi-threaded producer-consumer - * situation. The lane also holds a state which allows for - * an ellegant way of communicating from producer(s) to - * consumer(s) that all data has been produced. - * - * A simple example: - * @code - * void producer(lane<Task>* taskLane) - * { - * while(moreTasks) - * taskLane->write(nextTask()); - * taskLane->write_end(); - * } - * - * void consumer(lane<Task>* taskLane) - * { - * Task task; - * while(taskLane->read(task)) - * processTask(task); - * } - * - * void run() - * { - * lane<Task> taskLane; - * std::thread consumerThread(&consumer(), &taskLane); - * producer(&taskLane); - * consumerThread.join(); - * } - * @endcode - * - * The various read and write methods, as well as the empty(), - * capacity() and size() methods are always thread safe. The other - * methods are not: assignment, swap(), clear() and resize() can not - * be called from a different thread while another thread is also - * accessing the lane. The same holds obviously for the constructors - * and destructor. This is chosen because these methods should almost never - * be called in parallel with other methods, and hence it is not worth - * to increase every call with extra locks to make this possible. - * - * With one reader and one writer, the order is guaranteed to be consistent. - * With multiple readers or writers in combination with multi-element - * write or read functions, a sequence of symbols might be interrupted. For - * example, if a multi-element write() won't fit completely in the buffer, - * the thread will wait for free space. Another thread might get now write - * access first, causing the single call to the multi-element write to be - * "split up". - * - * @author Andre Offringa - * @tparam Tp Type of elements to be stored in the lane. - */ -template<typename Tp> -class lane -{ - public: - /** @brief Integer type used to store size types. */ - typedef std::size_t size_type; - - /** @brief Type of elements stored in the lane. */ - typedef Tp value_type; - - /** @brief Construct a lane with zero elements. - * @details A lane with zero elements can not be written to or read to - * (both operations will wait forever). - * - * This constructor makes it easy to construct e.g. a container - * of lanes. After the container is created, the lanes can be - * resized with @ref resize(). - */ - lane() noexcept : - _buffer(0), - _capacity(0), - _write_position(0), - _free_write_space(0), - _status(status_normal) - { - } - - /** @brief Construct a lane with the given capacity. - * @details After construction, the lane is ready for writing to and reading from. - * @param capacity Number of elements that the lane can hold at once. - */ - explicit lane(size_t capacity) : - _buffer(new Tp[capacity]), - _capacity(capacity), - _write_position(0), - _free_write_space(_capacity), - _status(status_normal) - { - } - - lane(const lane<Tp>& source) = delete; - - /** @brief Move construct a lane. - * @details This operation is not thread safe: the behaviour is undefined when - * other threads access the source lane. - * @param source Original lane to be moved from. - */ - lane(lane<Tp>&& source) noexcept : - _buffer(0), - _capacity(0), - _write_position(0), - _free_write_space(0), - _status(status_normal) - { - swap(source); - } - - /** @brief Destructor. - * @details The destructor is not synchronized. - */ - ~lane() - { - LANE_REPORT_DEBUG_INFO; - delete[] _buffer; - } - - lane<Tp>& operator=(const lane<Tp>& source) = delete; - - /** @brief Move assignment. - * @details This operation is not thread safe: the behaviour is undefined when - * other threads access the source lane. - * @param source Original lane to be moved from. - * @returns This lane. - */ - lane<Tp>& operator=(lane<Tp>&& source) noexcept - { - swap(source); - return *this; - } - - /** @brief Swap the contents of this lane with another. - * @details This operation is not thread safe: the behaviour is undefined when - * other threads access either lane. - */ - void swap(lane<Tp>& other) noexcept - { - std::swap(_buffer, other._buffer); - std::swap(_capacity, other._capacity); - std::swap(_write_position, other._write_position); - std::swap(_free_write_space, other._free_write_space); - std::swap(_status, other._status); - } - - /** @brief Clear the contents and reset the state of the lane. - * @details After calling clear(), the lane is in the same state as after - * construction. This also means that after clearing the lane, it - * is as if write_end() has not been called yet. - * - * This method is not thread safe. - */ - void clear() noexcept - { - _write_position = 0; - _free_write_space = _capacity; - _status = status_normal; - } - - /** @brief Write a single element. - * @details This method is thread safe, and can be called together with - * other write and read methods from different threads. - * - * If this call comes after a call to write_end(), the call - * will be ignored. - * @param element Object to be copied into the cyclic buffer. - */ - void write(const value_type& element) - { - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - - if(_status == status_normal) - { - while(_free_write_space == 0) - { - LANE_REGISTER_DEBUG_WRITE_WAIT; - _writing_possible_condition.wait(lock); - } - - _buffer[_write_position] = element; - _write_position = (_write_position+1) % _capacity; - --_free_write_space; - // Now that there is less free write space, there is more free read - // space and thus readers can possibly continue. - _reading_possible_condition.notify_all(); - } - } - - /** @brief Write a single element by constructing it. - * @details This method is thread safe, and can be called together with - * other write and read methods from different threads. - * - * If this call comes after a call to write_end(), the call - * will be ignored. The implementation does not construct the value - * in place, but rather constructs the value and then move assigns it. - * This is because the value that it is moved into has already been - * constructed (in the current implementation). - * @param element Object to be moved into the cyclic buffer. - */ - template<typename... Args> - void emplace(Args&&... args) - { - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - - if(_status == status_normal) - { - while(_free_write_space == 0) - { - LANE_REGISTER_DEBUG_WRITE_WAIT; - _writing_possible_condition.wait(lock); - } - - _buffer[_write_position] = value_type(args...); - _write_position = (_write_position+1) % _capacity; - --_free_write_space; - // Now that there is less free write space, there is more free read - // space and thus readers can possibly continue. - _reading_possible_condition.notify_all(); - } - } - - /** @brief Write a single element by moving it in. - * @details This method is thread safe, and can be called together with - * other write and read methods from different threads. - * - * If this call comes after a call to write_end(), the call - * will be ignored. - * @param element Object to be moved into the cyclic buffer. - */ - void write(value_type&& element) - { - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - - if(_status == status_normal) - { - while(_free_write_space == 0) - { - LANE_REGISTER_DEBUG_WRITE_WAIT; - _writing_possible_condition.wait(lock); - } - - _buffer[_write_position] = std::move(element); - _write_position = (_write_position+1) % _capacity; - --_free_write_space; - // Now that there is less free write space, there is more free read - // space and thus readers can possibly continue. - _reading_possible_condition.notify_all(); - } - } - - void write(const value_type* elements, size_t n) - { - write_generic(elements, n); - } - - void move_write(value_type* elements, size_t n) - { - write_generic(elements, n); - } - - bool read(value_type& destination) - { - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - while(free_read_space() == 0 && _status == status_normal) - { - LANE_REGISTER_DEBUG_READ_WAIT; - _reading_possible_condition.wait(lock); - } - if(free_read_space() == 0) - return false; - else - { - destination = std::move(_buffer[read_position()]); - ++_free_write_space; - // Now that there is more free write space, writers can possibly continue. - _writing_possible_condition.notify_all(); - return true; - } - } - - size_t read(value_type* destinations, size_t n) - { - size_t n_left = n; - - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - - size_t free_space = free_read_space(); - size_t read_size = free_space > n ? n : free_space; - immediate_read(destinations, read_size); - n_left -= read_size; - - while(n_left != 0 && _status == status_normal) - { - destinations += read_size; - - do { - LANE_REGISTER_DEBUG_READ_WAIT; - _reading_possible_condition.wait(lock); - } while(free_read_space() == 0 && _status == status_normal); - - free_space = free_read_space(); - read_size = free_space > n_left ? n_left : free_space; - immediate_read(destinations, read_size); - n_left -= read_size; - } - return n - n_left; - } - - void write_end() - { - std::lock_guard<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - _status = status_end; - _writing_possible_condition.notify_all(); - _reading_possible_condition.notify_all(); - } - - size_t capacity() const noexcept - { - return _capacity; - } - - size_t size() const - { - std::lock_guard<std::mutex> lock(_mutex); - return _capacity - _free_write_space; - } - - bool empty() const - { - std::lock_guard<std::mutex> lock(_mutex); - return _capacity == _free_write_space; - } - - /** - * Change the capacity of the lane. This will erase all data in the lane. - */ - void resize(size_t new_capacity) - { - Tp *new_buffer = new Tp[new_capacity]; - delete[] _buffer; - _buffer = new_buffer; - _capacity = new_capacity; - _write_position = 0; - _free_write_space = new_capacity; - _status = status_normal; - } - -#ifdef LANE_DEBUG_MODE - /** - * Change the name of this lane to make it appear in the output along - * with statistics. Do not use this function directly; use the - * set_lane_debug_name() macro instead. - * @param nameStr New debug description of this lane. - */ - void setDebugName(const std::string& nameStr) - { - _debugName = nameStr; - } -#endif - private: - Tp* _buffer; - - size_t _capacity; - - size_t _write_position; - - size_t _free_write_space; - - enum { status_normal, status_end } _status; - - mutable std::mutex _mutex; - - std::condition_variable _writing_possible_condition, _reading_possible_condition; - - size_t read_position() const noexcept - { - return (_write_position + _free_write_space) % _capacity; - } - - size_t free_read_space() const noexcept - { - return _capacity - _free_write_space; - } - - // This is a template to allow const and non-const (to be able to move) - template<typename T> - void write_generic(T* elements, size_t n) - { - std::unique_lock<std::mutex> lock(_mutex); - LANE_REGISTER_DEBUG_INFO; - - if(_status == status_normal) - { - size_t write_size = _free_write_space > n ? n : _free_write_space; - immediate_write(elements, write_size); - n -= write_size; - - while(n != 0) { - elements += write_size; - - do { - LANE_REGISTER_DEBUG_WRITE_WAIT; - _writing_possible_condition.wait(lock); - } while(_free_write_space == 0 && _status == status_normal); - - write_size = _free_write_space > n ? n : _free_write_space; - immediate_write(elements, write_size); - n -= write_size; - } while(n != 0); - } - } - - // This is a template to allow const and non-const (to be able to move) - template<typename T> - void immediate_write(T *elements, size_t n) noexcept - { - // Split the writing in two ranges if needed. The first range fits in - // [_write_position, _capacity), the second range in [0, end). By doing - // so, we only have to calculate the modulo in the write position once. - if(n > 0) - { - size_t nPart; - if(_write_position + n > _capacity) - { - nPart = _capacity - _write_position; - } else { - nPart = n; - } - for(size_t i = 0; i < nPart ; ++i, ++_write_position) - { - _buffer[_write_position] = std::move(elements[i]); - } - - _write_position = _write_position % _capacity; - - for(size_t i = nPart; i < n ; ++i, ++_write_position) - { - _buffer[_write_position] = std::move(elements[i]); - } - - _free_write_space -= n; - - // Now that there is less free write space, there is more free read - // space and thus readers can possibly continue. - _reading_possible_condition.notify_all(); - } - } - - void immediate_read(value_type *elements, size_t n) noexcept - { - // As with write, split in two ranges if needed. The first range fits in - // [read_position(), _capacity), the second range in [0, end). - if(n > 0) - { - size_t nPart; - size_t position = read_position(); - if(position + n > _capacity) - { - nPart = _capacity - position; - } else { - nPart = n; - } - for(size_t i = 0; i < nPart ; ++i, ++position) - { - elements[i] = std::move(_buffer[position]); - } - - position = position % _capacity; - - for(size_t i = nPart; i < n ; ++i, ++position) - { - elements[i] = std::move(_buffer[position]); - } - - _free_write_space += n; - - // Now that there is more free write space, writers can possibly continue. - _writing_possible_condition.notify_all(); - } - } -#ifdef LANE_DEBUG_MODE - void registerDebugInfo() noexcept - { - _debugSummedSize += _capacity - _free_write_space; - _debugMeasureCount++; - } - void registerDebugReadWait() noexcept - { - ++_debugReadWaitCount; - } - void registerDebugWriteWait() noexcept - { - ++_debugWriteWaitCount; - } - void reportDebugInfo() - { - if(!_debugName.empty()) - { - std::stringstream str; - str - << "*** Debug report for the following lane: ***\n" - << "\"" << _debugName << "\"\n" - << "Capacity: " << _capacity << '\n' - << "Total read/write ops: " << _debugMeasureCount << '\n' - << "Average size of buffer, measured per read/write op.: " << round(double(_debugSummedSize)*100.0/_debugMeasureCount)/100.0 << '\n' - << "Number of wait events during reading: " << _debugReadWaitCount << '\n' - << "Number of wait events during writing: " << _debugWriteWaitCount << '\n'; - std::cout << str.str(); - } - } - std::string _debugName; - size_t - _debugSummedSize = 0, _debugMeasureCount = 0, - _debugReadWaitCount = 0, _debugWriteWaitCount = 0; -#endif -}; - -template<typename Tp> -void swap(ao::lane<Tp>& first, ao::lane<Tp>& second) noexcept -{ - first.swap(second); -} - -} // end of namespace - -#endif // AO_LANE11_H diff --git a/CEP/DP3/DPPP_Interpolate/src/CMakeLists.txt b/CEP/DP3/DPPP_Interpolate/src/CMakeLists.txt deleted file mode 100644 index 5b3f208133558312634dd8f520bc664d26516b24..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/src/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -include(LofarPackageVersion) - -lofar_add_library(dppp_interpolate - Interpolate.cc -) diff --git a/CEP/DP3/DPPP_Interpolate/src/Interpolate.cc b/CEP/DP3/DPPP_Interpolate/src/Interpolate.cc deleted file mode 100644 index 0f622e92fd12853037c2f0931692dd7192fe5224..0000000000000000000000000000000000000000 --- a/CEP/DP3/DPPP_Interpolate/src/Interpolate.cc +++ /dev/null @@ -1,246 +0,0 @@ -#include <DPPP_Interpolate/Interpolate.h> -#include <DPPP_Interpolate/buffered_lane.h> - -#include <lofar_config.h> -#include <DPPP/DPBuffer.h> -#include <DPPP/DPInfo.h> -#include <DPPP/DPRun.h> -#include <Common/ParameterSet.h> -#include <Common/LofarLogger.h> -#include <casacore/casa/Arrays/ArrayMath.h> -#include <Common/StringUtil.h> - -#include <iostream> -#include <iomanip> -#include <thread> - -using namespace casacore; - -void register_interpolate() -{ - LOFAR::DPPP::DPRun::registerStepCtor("interpolate", LOFAR::DPPP::Interpolate::makeStep); -} - -namespace LOFAR { namespace DPPP { - -Interpolate::Interpolate(DPInput* /*input*/, const ParameterSet& parset, const string& prefix) : - _name(prefix), - _interpolatedPos(0), - _windowSize(parset.getUint(prefix+"windowsize", 15)) -{ - if(_windowSize%2 != 1) - throw std::runtime_error("Window size of Interpolate action should be an odd number"); - - _kernelLookup.reserve(_windowSize*_windowSize); - for(int t=0; t!=int(_windowSize); ++t) - { - int y = t - int(_windowSize/2); - for(int ch=0; ch!=int(_windowSize); ++ch) - { - int x = ch - int(_windowSize/2); - double windowDist = double(x*x + y*y); - // Gaussian function with sigma = 1 - // (evaluated with double prec, then converted to floats) - double w = std::exp(windowDist * -0.5); - _kernelLookup.emplace_back(w); - } - } -} - -DPStep::ShPtr Interpolate::makeStep(DPInput* input, const ParameterSet& parset, const std::string& prefix) -{ - return DPStep::ShPtr(new Interpolate(input, parset, prefix)); -} - -void Interpolate::updateInfo(const DPInfo& infoIn) -{ - info() = infoIn; - info().setNeedVisData(); - info().setWriteData(); - info().setWriteFlags(); - info().setMetaChanged(); -} - -void Interpolate::show(std::ostream& os) const -{ - os << "Interpolate " << _name << '\n'; - os << " windowsize: " << _windowSize; -} - -void Interpolate::showTimings(std::ostream& os, double duration) const -{ - os << " "; - FlagCounter::showPerc1 (os, _timer.getElapsed(), duration); - os << " Interpolate " << _name << endl; -} - -bool Interpolate::process(const DPBuffer& buf) -{ - _timer.start(); - // Collect the data in buffers. - _buffers.emplace_back(); - _buffers.back().copy(buf); - // If we have a full window of data, interpolate everything - // up to the middle of the window - if(_buffers.size() >= _windowSize) - { - size_t mid = _windowSize/2; - while(_interpolatedPos <= mid) - { - interpolateTimestep(_interpolatedPos); - ++_interpolatedPos; - } - // Buffers are only pushed to the next step when they are completely - // out of the window. This is because flags need to be set to false, - // however the flag information of the entire window is needed during - // interpolation, so these can only be set to false after processing. - sendFrontBufferToNextStep(); - } - _timer.stop(); - return true; -} - -void Interpolate::sendFrontBufferToNextStep() -{ - IPosition shp = _buffers.front().getData().shape(); - size_t - nPol = shp[0], - nChan = shp[1], - nBl = shp[2], - n = nPol * nChan * nBl; - // Set all flags to false - bool* flags = _buffers.front().getFlags().data(); - Complex* data = _buffers.front().getData().data(); - std::fill(flags, flags+n, false); - // Flag NaN values (values for which the entire window was flagged on input) - for(size_t i=0; i!=n; ++i) - { - if(!std::isfinite(data[i].real()) || !std::isfinite(data[i].imag())) - { - // The datum value is also set to 0, because NaNs sometimes give problems in - // certain software, even when they are flagged (e.g. in Sagecal). - data[i] = 0.0; - flags[i] = true; - } - } - - _timer.stop(); - getNextStep()->process(_buffers.front()); - _timer.start(); - - _buffers.pop_front(); - --_interpolatedPos; -} - -void Interpolate::finish() -{ - _timer.start(); - - // Interpolate everything up to the end of the window - while(_interpolatedPos<_buffers.size()) { - interpolateTimestep(_interpolatedPos); - ++_interpolatedPos; - } - while(!_buffers.empty()) - { - sendFrontBufferToNextStep(); - } - - _timer.stop(); - - getNextStep()->finish(); -} - -#define BUFFER_SIZE 1024 - -void Interpolate::interpolateTimestep(size_t index) -{ - const IPosition shp = _buffers.front().getData().shape(); - const size_t - nPol = shp[0], - nChan = shp[1], - nPerBl = nPol*nChan, - nBl = shp[2]; - - std::vector<std::thread> threads; - size_t nthreads = std::min<size_t>(sysconf(_SC_NPROCESSORS_ONLN), 8); - _lane.resize(nthreads*BUFFER_SIZE); - lane_write_buffer<Sample> buflane(&_lane, BUFFER_SIZE); - threads.reserve(nthreads); - for(size_t i=0; i!=nthreads; ++i) - threads.emplace_back(&Interpolate::interpolationThread, this); - - std::vector<Complex> dataBlock; - for (size_t bl=0; bl<nBl; ++bl) - { - bool* flags = _buffers[index].getFlags().data() + bl*nPerBl; - for(size_t ch=0; ch!=nChan; ++ch) - { - for(size_t p=0; p!=nPol; ++p) - { - if(*flags) { - buflane.emplace(index, bl, ch, p); - } - ++flags; - } - } - } - buflane.write_end(); - - for(std::thread& t : threads) - t.join(); -} - -void Interpolate::interpolationThread() -{ - lane_read_buffer<Sample> buflane(&_lane, BUFFER_SIZE); - Sample sample; - while(buflane.read(sample)) - { - interpolateSample(sample.timestep, sample.baseline, sample.channel, sample.pol); - } -} - -void Interpolate::interpolateSample(size_t timestep, size_t baseline, size_t channel, size_t pol) -{ - const IPosition shp = _buffers.front().getData().shape(); - const size_t - nPol = shp[0], - nChan = shp[1], - timestepBegin = (timestep > _windowSize/2) ? (timestep - _windowSize/2) : 0, - timestepEnd = std::min(timestep + _windowSize/2 + 1, _buffers.size()), - channelBegin = (channel > _windowSize/2) ? (channel - _windowSize/2) : 0, - channelEnd = std::min(channel + _windowSize/2 + 1, nChan); - - std::complex<float> valueSum = 0.0; - float windowSum = 0.0; - - for(size_t t=timestepBegin; t!=timestepEnd; ++t) - { - Complex* data = _buffers[t].getData().data() + (baseline*nChan + channelBegin)*nPol + pol; - const bool* flags = _buffers[t].getFlags().data() + (baseline*nChan + channelBegin)*nPol + pol; - const float* row = &_kernelLookup[_windowSize * (t + int(_windowSize/2) - timestep)]; - for(size_t ch=channelBegin; ch!=channelEnd; ++ch) - { - if(!*flags) - { - int x = ch + int(_windowSize/2) - channel; - float w = row[x]; - valueSum += *data * w; - windowSum += w; - } - - data += nPol; - flags += nPol; - } - } - // This write is multithreaded, but is allowed because this value is never read from in - // the loops above (because flagged values are skipped). - Complex& value = _buffers[timestep].getData().data()[(baseline*nChan + channel)*nPol + pol]; - if(windowSum != 0.0) - value = valueSum / windowSum; - else - value = Complex(std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN()); -} - -} } //# end namespace