diff --git a/CMakeLists.txt b/CMakeLists.txt index 63af603797d0db050bf07c91d84c13b79b0280f2..5596166d6f3adb3ef4bc5762febf6c26dc92a51a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ add_library(stationresponse SHARED set_target_properties(stationresponse PROPERTIES VERSION 3) -target_link_libraries(stationresponse ${CASACORE_LIBRARIES}) +target_link_libraries(stationresponse ${CASACORE_LIBRARIES} lobes) target_link_libraries(stationresponse hamaker oskar) diff --git a/ElementResponse.h b/ElementResponse.h index b0bdfa73061079ef3ac4372aa864ba064f177a20..05bbbca31020a92b6b2cd8cc4ea8f49263dd8b34 100644 --- a/ElementResponse.h +++ b/ElementResponse.h @@ -2,8 +2,9 @@ #define ELEMENT_RESPONSE_H #include <complex> +#include "Response.h" -class ElementResponse +class ElementResponse : private Response { public: virtual void element_response( diff --git a/MutablePtr.h b/MutablePtr.h new file mode 100644 index 0000000000000000000000000000000000000000..09dbb2c4269efdc6cda4f1294cc0bc65453d1fa8 --- /dev/null +++ b/MutablePtr.h @@ -0,0 +1,88 @@ +//# MutablePtr.h: Representation of an LBA antenna field. +//# +//# Copyright (C) 2013 +//# 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$ + +#ifndef LOFAR_STATIONRESPONSE_MUTABLEPTR_H +#define LOFAR_STATIONRESPONSE_MUTABLEPTR_H + +namespace LOFAR +{ +namespace StationResponse +{ + +/*! + * \brief MutablePtr is a mutable smart pointer derived from std::shared_ptr. + * + * Its purpose is to have a pointer that + * 1. can by copied/passed by value, + * 2. can be modified after it has been copied + * 3. the copies will dereference to the new value + * + * This behaviour is different from a `reset` of a std::shared_ptr + * There the copies will keep to point to the original object + * + * This pointer does not manage the object it points to + * + * Usage: + * + * \code + * #include<iostream> + * + * class Msg { + * public: + * Msg(const std::string &t) : text(t) {} + * std::string text; + * }; + * + * typedef MutablePtr<Msg> MsgMutPtr; + * + * int main() + * { + * Msg m1("Hello from object number one"); + * Msg m2("Greetings from object number two"); + * + * MsgMutPtr mut_ptr(&m1); + * MsgMutPtr mut_ptr_copy = mut_ptr; + * + * mut_ptr.set(&m2); + * + * std::cout << mut_ptr->text << std::endl; + * std::cout << mut_ptr_copy->text << std::endl; + * + * // Output: + * // Greetings from object number two + * // Greetings from object number two + * + * \endcode + */ +template<typename T> +class MutablePtr : public std::shared_ptr<T*> { +public: + MutablePtr(T* ptr) : std::shared_ptr<T*>(new T*(ptr)) {} + T& operator*() const { return **(this->get()); } + T* operator->() const { return *(this->get()); } + void set(T* ptr) { *(this->get()) = ptr;} +}; + +} //# namespace StationResponse +} //# namespace LOFAR + +#endif diff --git a/Singleton.h b/Singleton.h new file mode 100644 index 0000000000000000000000000000000000000000..2f559bccf24f1c0cbba2984e538bc6bd05cdd42c --- /dev/null +++ b/Singleton.h @@ -0,0 +1,18 @@ +template<typename T> +class Singleton +{ + public: + static T& getInstance() + { + static T instance; // Guaranteed to be destroyed. + // Instantiated on first use. + return instance; + } + private: + Singleton() {} // Constructor? (the {} brackets) are needed here. + + public: + Singleton(Singleton const&) = delete; + void operator=(Singleton const&) = delete; + +}; diff --git a/Station.cc b/Station.cc index 01b46b6d7fada8aa9511c7be64c1cf24701dc624..5dc3db513a04a1385ec729f2a7ad77a4fd137aad 100644 --- a/Station.cc +++ b/Station.cc @@ -24,7 +24,8 @@ #include "MathUtil.h" #include "hamaker/HamakerElementResponse.h" -#include "oskar/OskarElementResponse.h" +#include "oskar/OSKARElementResponse.h" +#include "lobes/LOBESElementResponse.h" #include "DualDipoleAntenna.h" #include "TileAntenna.h" @@ -39,46 +40,23 @@ Station::Station( const ElementResponseModel model) : itsName(name), itsPosition(position), - itsPhaseReference(position) + itsPhaseReference(position), { - if (itsModel != ElementResponseModel::Unknown && - itsModel != model) - { - throw std::runtime_error("Every station must have the same element response model."); - } else { - itsModel = model; - } + setModel(model); +} +void Station::setModel(const ElementResponseModel model) +{ switch (model) { case Hamaker: - if (DualDipoleAntenna::itsElementResponse == nullptr) { - DualDipoleAntenna::itsElementResponse.reset(new HamakerElementResponseLBA); - } - if (TileAntenna::itsElementResponse == nullptr) { - TileAntenna::itsElementResponse.reset(new HamakerElementResponseHBA); - } + itsElementResponse = HamakerElementResponse.getInstance(itsName); break; case OSKAR: - #if 0 - DualDipoleAntenna::itsElementResponse.reset(new OSKARElementResponseDipole()); - TileAntenna::itsElementResponse.reset(new OSKARElementResponseDipole()); - #else - if (DualDipoleAntenna::itsElementResponse == nullptr || - TileAntenna::itsElementResponse == nullptr) - { - #if 0 - // TODO: this should work, but causes memory corruption - ElementResponse* elementResponseModel = new OskarElementResponseSphericalWave(); - DualDipoleAntenna::itsElementResponse.reset(elementResponseModel); - TileAntenna::itsElementResponse.reset(elementResponseModel); - #else - // TODO: for now, just create the same model twice - DualDipoleAntenna::itsElementResponse.reset(new OskarElementResponseSphericalWave()); - TileAntenna::itsElementResponse.reset(new OskarElementResponseSphericalWave()); - #endif - } - #endif + itsElementResponse = OSKARElementResponse.getInstance(); + break; + case LOBES: + itsElementResponse = LOBESElementResponse.getInstance(); break; default: std::stringstream message; diff --git a/Station.h b/Station.h index aee87e3cd77c33c3737cd5ce9b50ec2ef6450cf8..fb6870acb7a91cb0e8383fd2d199bebbc5ef609c 100644 --- a/Station.h +++ b/Station.h @@ -29,6 +29,7 @@ #include "AntennaField.h" #include "Types.h" #include "ElementResponseModel.h" +#include "Response.h" #include <memory> #include <vector> @@ -41,7 +42,7 @@ namespace StationResponse // \addtogroup StationResponse // @{ -class Station +class Station : private Response { public: typedef std::shared_ptr<Station> Ptr; @@ -160,6 +161,12 @@ public: real_t freq0, const vector3r_t &station0, const vector3r_t &tile0, const bool rotate = true) const; + virtual void response( + double freq, + double theta, + double phi, + std::complex<double> (&response)[2][2]) const {} + /*! * \brief Compute the array factor of the station for a plane wave of * frequency \p freq, arriving from direction \p direction, with the diff --git a/lobes/CMakeLists.txt b/lobes/CMakeLists.txt index 57ee382cac1a0094abfbdef851c83ff880665aae..34e527996b68238020ea6c1e66b2314adde8a51f 100644 --- a/lobes/CMakeLists.txt +++ b/lobes/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(pybind11 REQUIRED) find_package (Eigen3 REQUIRED NO_MODULE) find_package(HDF5 COMPONENTS C CXX REQUIRED) -pybind11_add_module(lobes lobes.cc ElementResponse.cc) +pybind11_add_module(lobes SHARED lobes.cc ElementResponse.cc) configure_file(test.py test.py COPYONLY) diff --git a/lobes/lobes.h b/lobes/lobes.h index 1269d87c01754a5eef66ff202779b5ec36c12eb3..b2386c7b352b2e1c90d7cc4241f5c5d5f87c3fa6 100644 --- a/lobes/lobes.h +++ b/lobes/lobes.h @@ -1,3 +1,4 @@ +#include <Eigen/Core> #include <pybind11/pybind11.h> #include <pybind11/eigen.h>