LCOV - code coverage report
Current view: top level - air_casawvr/src - radiometermeasure.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 12 21 57.1 %
Date: 2024-12-11 20:54:31 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /**
       2             :    Bojan Nikolic <bn204@mrao.cam.ac.uk>, <bojan@bnikolic.co.uk>
       3             :    Initial version February 2008
       4             :    Maintained by ESO since 2013.
       5             : 
       6             :    This file is part of LibAIR and is licensed under GNU Public
       7             :    License Version 2
       8             : 
       9             :    \file radiometermeasure.hpp
      10             :    Renamed radiometermeasure.h 2023
      11             : 
      12             :    Model the radiometer measurement process
      13             : */
      14             : 
      15             : #ifndef _LIBAIR_RADIOMETERMEASURE_HPP__
      16             : #define _LIBAIR_RADIOMETERMEASURE_HPP__
      17             : 
      18             : #include <vector>
      19             : #include <stdexcept>
      20             : #include <string>
      21             : #include <memory>
      22             : 
      23             : namespace LibAIR2 {
      24             : 
      25             :   /**
      26             :      General exception class for errors in the radiometer subsystem.
      27             :    */
      28             :   class RadiometerError : 
      29             :     public std::runtime_error
      30             :   {
      31             :   public:
      32             :     
      33           0 :     RadiometerError(const std::string & s):
      34           0 :       std::runtime_error(s)
      35           0 :     {}
      36             :     
      37             :   };
      38             : 
      39             : 
      40             : 
      41             :   /** \brief Base class for radiometers 
      42             :    */
      43             :   class Radiometer {
      44             : 
      45             :     /** The frequency grid over which measurements are expected.
      46             :      */
      47             :     std::vector<double> FGrid;
      48             : 
      49             :     /** \brief Coefficients used to compute the output of the
      50             :         radiomter from sky brigthnesses
      51             : 
      52             :         Multiple vectors of coefficients allow multiple channels
      53             :         
      54             :      */
      55             :     std::vector< std::vector<double> > coeffs_v;
      56             : 
      57             :   public:
      58             : 
      59             :     // ---------- Construction / Destruction --------------
      60             : 
      61             :     /** \brief Constructs a single channel radiometer
      62             :      */
      63             :     Radiometer( const std::vector<double> & FGrid,
      64             :                 const std::vector<double> & coeffs);
      65             : 
      66             :     /** \brief Construct a multi channel radiometer
      67             :      */
      68             :     Radiometer( const std::vector<double> & FGrid,
      69             :                 const std::vector< std::vector<double> >  & coeffs_v);
      70             : 
      71             :     // ---------- Public interface  --------------------------
      72             : 
      73             :     /**
      74             :        \brief
      75             :        Return the frequency grid required by this radiometer
      76             :      */
      77         729 :     const std::vector<double> & getFGrid(void)  const
      78             :     {
      79         729 :       return FGrid;
      80             :     }
      81             : 
      82         324 :     const std::vector<double> & getCoeffs(size_t ch)  const
      83             :     {
      84         324 :       return coeffs_v[ch];
      85             :     }
      86             : 
      87             :     /** \brief Returns the number of channels
      88             : 
      89             :      */
      90    80313105 :     size_t nchannels(void) const 
      91             :     {
      92    80313105 :       return coeffs_v.size();
      93             :     }
      94             : 
      95             :     
      96             : 
      97             :     /** \brief Return the meausrement from a vector of sky Tbs
      98             :         evaluated on grid as returned by getFGrid.
      99             : 
     100             :         \param ch is zero-indexed
     101             :      */
     102   318021220 :     double eval( const std::vector<double> & skyTb,
     103             :                  size_t ch) const
     104             :     {
     105   318021220 :       const std::vector<double> & coeffs = coeffs_v[ch];
     106             : 
     107   318021220 :       double res = 0;
     108 13038870020 :       for (size_t i = 0 ; i < FGrid.size() ; ++i )
     109 12720848800 :         res += coeffs[i] * skyTb[i];
     110   318021220 :       return res;
     111             :       
     112             :     }
     113             : 
     114           0 :     double eval( const std::vector<double> & skyTb) const
     115             :     {
     116           0 :       if ( nchannels()  > 1 )
     117             :       {
     118           0 :         std::string err("More than one channel but asking for single result");
     119           0 :         throw RadiometerError(err);
     120           0 :       }
     121             : 
     122           0 :       return eval( skyTb, 0);
     123             :     }
     124             : 
     125             :   };
     126             : 
     127             :   /**
     128             :      \brief Model of a simple double-sideband radiometer.
     129             : 
     130             :      At the moment this is single-channel only
     131             : 
     132             :    */
     133             :   class DSBRadio
     134             :   {
     135             : 
     136             :     std::unique_ptr<Radiometer> r;
     137             : 
     138             :   public:
     139             : 
     140             :     // ---------- Public data  ------------ --------------
     141             : 
     142             :     /// The central frequency
     143             :     const double f_0;
     144             : 
     145             :     /// The frequency of the middle of the IF band
     146             :     const double f_if;
     147             : 
     148             :     // ---------- Construction / Destruction --------------
     149             : 
     150             :     /** The basic constructor
     151             : 
     152             :      */
     153             :     DSBRadio( double f_0,
     154             :               double f_if);
     155             : 
     156             :     /** Use the supplied radiometer -- for derived classes
     157             :      */
     158             :     DSBRadio( double f_0,
     159             :               double f_if,
     160             :               Radiometer * rr);
     161             : 
     162             :     // ---------- Public interface  --------------------------
     163             : 
     164             :     /** \brief Return a const reference to the actual radiometer
     165             :      */
     166             :     const Radiometer & getRadiometer(void) const;
     167             : 
     168             :     double eval( const std::vector<double> & skyTb) const;
     169             : 
     170             :     const std::vector<double> & getFGrid(void)  const
     171             :     {
     172             :       return r->getFGrid();
     173             :     }
     174             : 
     175             :   };
     176             : 
     177             : 
     178             :   /** \brief Incoroporate the effect of bandiwdth of radiometer filters.
     179             : 
     180             :       This version calculates the average of the signal over the band
     181             :       using rectangular integration of the signal over 30 points --
     182             :       not very efficient.
     183             : 
     184             :    */
     185             :   class DSBBWRadio:
     186             :     public DSBRadio
     187             :   {
     188             : 
     189             :   public:
     190             : 
     191             :     /// The fitlter bandwidth
     192             :     const double f_bw;
     193             : 
     194             :     // ---------- Construction / Destruction --------------
     195             : 
     196             :     DSBBWRadio( double f_0,
     197             :                 double f_if,
     198             :                 double f_bw);
     199             : 
     200             :     // ---------- Public interface  --------------------------
     201             : 
     202             :     static Radiometer * MkRadio( double f_0,
     203             :                                  double f_if,
     204             :                                  double f_bw);
     205             :   };
     206             : 
     207             :   /**
     208             :      Generate finite bandwidth radiometers with Gaussian quadrature
     209             :      integration.
     210             :    */
     211             :   class DSBBW_QuadRadio:
     212             :     public DSBRadio
     213             :   {
     214             : 
     215             :   public:
     216             : 
     217             :     // ---------- Construction / Destruction --------------
     218             : 
     219             :     DSBBW_QuadRadio( double f_0,
     220             :                      double f_if,
     221             :                      double f_bw);
     222             : 
     223             :     // ---------- Public interface  --------------------------
     224             : 
     225             :     static Radiometer * MkRadio( double f_0,
     226             :                                  double f_if,
     227             :                                  double f_bw);
     228             :   };
     229             : 
     230             :   
     231             : 
     232             :   /** \brief Exception type representing for errors due to unknown
     233             :       radiometer channel.
     234             : 
     235             :    */
     236             :   struct InvalidWVRChannel 
     237             :   {
     238             :     int chlow, chhigh, ch;
     239             : 
     240             :     InvalidWVRChannel(int chlow,
     241             :                       int chhigh,
     242             :                       int ch);
     243             :   };
     244             : 
     245             :   /** \brief Returns WVR perfectly to spec for ALMA
     246             : 
     247             :       \param ch the WVR channel (1 to 4 inclusive).
     248             : 
     249             :    */
     250             :   DSBRadio * MkALMARadiometer(int ch,
     251             :                               double cf_off=0.0,
     252             :                               double bw_off=0.0) noexcept(false);
     253             : 
     254             :   /** \brief Returns WVR Dicke prototype 
     255             : 
     256             :       \param ch the WVR channel (1 to 4 inclusive).
     257             : 
     258             :    */
     259             :   DSBRadio * MkALMADickeProto(int ch) noexcept(false);
     260             : 
     261             : 
     262             :   /**
     263             :      \brief Create the four channel production ALMA WVR
     264             :      
     265             :    */
     266             :   Radiometer * MkFullALMAWVR(void);
     267             : 
     268             :   /**
     269             :      \brief Create the ALMA radiometer but offset the centre
     270             :      frequencies by foffset (in GHz)
     271             :   */
     272             :   Radiometer * MkALMAWVR_offset(double cf,
     273             :                                 double bw);
     274             : 
     275             :   /**
     276             :      \brief Measured properties of ALMA Production radiometers
     277             :    */
     278             :   struct ALMAWVRCharacter {
     279             :     /// Measured centre frequencies of each of the filters
     280             :     double cf1, cf2, cf3, cf4;
     281             :     /// Measured bandwidths of each fo the filters
     282             :     double bw1, bw2, bw3, bw4;
     283             : 
     284             :     /// By default set to the nominal character
     285             :     ALMAWVRCharacter(void);
     286             :   };
     287             :   
     288             :   /** \brief Create ALMA radiometer with measured characteristics
     289             :    */
     290             :   Radiometer *MkALMAWVR(const ALMAWVRCharacter &c);
     291             : 
     292             :   /**
     293             :      \brief Create the four channel dicke Prototype WVR
     294             :      
     295             :    */
     296             :   Radiometer * MkFullDickeProtoWVR(void);
     297             : 
     298             :   /**
     299             :      \brief Create a single sideband radiometer
     300             : 
     301             :      The filter is approximated by five-point Gaussian quadrature
     302             :      
     303             :      \param f_c Centre frequency of the filter
     304             :      
     305             :      \param f_bw Filter bandwidth 
     306             :   */
     307             :   Radiometer * MkSSBRadio(double f_c,
     308             :                           double f_bw);
     309             : 
     310             : 
     311             :   /**
     312             :      \brief Make a model of the IRAM 22 GHz WVRs
     313             :      
     314             :      The channel centres and bandwidths are typical values for units
     315             :      at the PdB
     316             :   */
     317             :   Radiometer * MkIRAM22(void);
     318             : 
     319             : }
     320             : 
     321             : #endif
     322             : 

Generated by: LCOV version 1.16