Xyst test code coverage report
Current view: top level - IO - PDFWriter.cpp (source / functions) Hit Total Coverage
Commit: 5689ba12dc66a776d3d75f1ee48cc7d78eaa18dc Lines: 55 76 72.4 %
Date: 2024-11-22 19:17:03 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 87 248 35.1 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/IO/PDFWriter.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.,
       7                 :            :              2022-2024 J. Bakosi
       8                 :            :              All rights reserved. See the LICENSE file for details.
       9                 :            :   \brief     Univariate PDF writer
      10                 :            :   \brief     PDF writer class definition
      11                 :            :   \details   This file defines a PDF writer class that facilitates outputing
      12                 :            :     probability density functions (PDFs) into files in various formats using
      13                 :            :     various configurations.
      14                 :            : */
      15                 :            : // *****************************************************************************
      16                 :            : 
      17                 :            : #include <iomanip>
      18                 :            : 
      19                 :            : #include "NoWarning/exodusII.hpp"
      20                 :            : 
      21                 :            : #include "PDFWriter.hpp"
      22                 :            : #include "Exception.hpp"
      23                 :            : 
      24                 :            : using tk::PDFWriter;
      25                 :            : 
      26                 :        726 : PDFWriter::PDFWriter( const std::string& filename,
      27                 :            :                       const std::string& format,
      28                 :        726 :                       std::streamsize precision ) :
      29                 :        726 :   Writer( filename )
      30                 :            : // *****************************************************************************
      31                 :            : //  Constructor
      32                 :            : //! \param[in] filename Output filename to which output the PDF
      33                 :            : //! \param[in] format Configure floating-point output format for ASCII output
      34                 :            : //! \param[in] precision Configure precision for floating-point ASCII output
      35                 :            : // *****************************************************************************
      36                 :            : {
      37                 :            :   // Set floating-point format for output file stream
      38         [ -  + ]:        726 :   if (format == "default")
      39                 :            :     {} //m_outFile << std::defaultfloat;   GCC does not yet support this
      40         [ -  - ]:          0 :   else if (format == "fixed")
      41         [ -  - ]:          0 :     m_outFile << std::fixed;
      42         [ -  - ]:          0 :   else if (format == "scientific")
      43         [ -  - ]:          0 :     m_outFile << std::scientific;
      44 [ -  - ][ -  - ]:          0 :   else Throw( "Text floating-point format not recognized." );
                 [ -  - ]
      45                 :            : 
      46                 :            :   // Set numeric precision for output file stream if the input makes sense
      47 [ +  - ][ +  - ]:        726 :   if (precision > 0 && precision < std::numeric_limits< tk::real >::digits10+2)
      48                 :        726 :     m_outFile << std::setprecision( static_cast<int>(precision) );
      49                 :        726 : }
      50                 :            : 
      51                 :            : void
      52                 :        726 : PDFWriter::writeTxt( const UniPDF& pdf, const tk::ctr::PDFInfo& info ) const
      53                 :            : // *****************************************************************************
      54                 :            : //  Write out standardized univariate PDF to file
      55                 :            : //! \param[in] pdf Univariate PDF
      56                 :            : //! \param[in] info PDF metadata
      57                 :            : // *****************************************************************************
      58                 :            : {
      59                 :        726 :   const auto& name = info.name;
      60                 :        726 :   const auto& uext = info.exts;
      61                 :        726 :   const auto& vars = info.vars;
      62                 :        726 :   const auto& it = info.it;
      63                 :        726 :   const auto& time = info.time;
      64                 :            : 
      65         [ +  - ]:        726 :   assertSampleSpaceDimensions< 1 >( vars );
      66         [ +  - ]:        726 :   assertSampleSpaceExtents< 1 >( uext );
      67                 :            : 
      68                 :            :   // Query and optionally override number of bins and minimum of sample space if
      69                 :            :   // user-specified extents were given and copy probabilities from pdf to an
      70                 :            :   // array for output
      71                 :            :   std::size_t nbi;
      72                 :            :   tk::real min, max;
      73                 :        726 :   std::vector< tk::real > outpdf;
      74                 :            :   tk::real binsize;
      75                 :            :   std::array< long, 2*UniPDF::dim > ext;
      76         [ +  - ]:        726 :   extents( pdf, uext, nbi, min, max, binsize, ext, outpdf );
      77                 :            : 
      78                 :            :   // Output header
      79                 :            :   m_outFile << "# vim: filetype=sh:\n#\n"
      80                 :        726 :             << "# Univariate PDF: " << name << '(' << vars[0] << ')' << '\n'
      81                 :            :             << "# -----------------------------------------------\n"
      82 [ +  - ][ +  - ]:        726 :             << "# Numeric precision: " << m_outFile.precision() << '\n'
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      83 [ +  - ][ +  - ]:        726 :             << "# Bin size: " << binsize << '\n'
      84 [ +  - ][ +  - ]:        726 :             << "# Number of bins estimated: " << ext[1] - ext[0] + 1
         [ +  - ][ +  - ]
      85                 :            :             << '\n'
      86 [ +  - ][ +  - ]:        726 :             << "# Number of bins output: " << nbi << '\n'
      87 [ +  - ][ +  - ]:        726 :             << "# Sample space extent: [" << min << " : " << max << "]\n"
         [ +  - ][ +  - ]
                 [ +  - ]
      88 [ +  - ][ +  - ]:        726 :             << "# Integral: " << pdf.integral() << "\n"
         [ +  - ][ +  - ]
                 [ +  - ]
      89 [ +  - ][ +  - ]:        726 :             << "# Iteration: " << it << "\n"
                 [ +  - ]
      90 [ +  - ][ +  - ]:        726 :             << "# Physical time: " << time << "\n#\n"
                 [ +  - ]
      91                 :            :             << "# Example step-by-step visualization with gnuplot\n"
      92                 :            :             << "# -----------------------------------------------\n"
      93                 :            :             << "# gnuplot> set grid\n"
      94                 :            :             << "# gnuplot> unset key\n"
      95                 :        726 :             << "# gnuplot> set xlabel \"" << vars[0] << "\"\n"
      96                 :        726 :             << "# gnuplot> set ylabel \"" << name << "(" << vars[0] << ")\"\n"
      97 [ +  - ][ +  - ]:        726 :             << "# gnuplot> plot ";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      98 [ -  + ][ -  - ]:        726 :   if (!uext.empty()) m_outFile << "[" << uext[0] << ':' << uext[1] << "] ";
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      99                 :        726 :   m_outFile << "\"" << m_filename << "\" with points\n#\n"
     100                 :            :             << "# Gnuplot one-liner for quick copy-paste\n"
     101                 :            :             << "# -----------------------------------------------\n"
     102                 :        726 :             << "# set grid; unset key; set xlabel \"" << vars[0]
     103                 :        726 :             << "\"; set ylabel \"" << name << "(" << vars[0]
     104 [ +  - ][ +  - ]:        726 :             << ")\"; plot";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     105 [ -  + ][ -  - ]:        726 :   if (!uext.empty()) m_outFile << " [" << uext[0] << ':' << uext[1] << "]";
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     106                 :        726 :   m_outFile << " \"" << m_filename << "\" w p\n#\n"
     107                 :       1452 :             << "# Data columns: " << vars[0] << ", " << name << "(" << vars[0]
     108 [ +  - ][ +  - ]:        726 :             << ")\n# -----------------------------------------------\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     109                 :            : 
     110                 :            :   // If no user-specified sample space extents, output pdf map directly
     111         [ +  - ]:        726 :   if (uext.empty()) {
     112         [ +  + ]:     163071 :     for (const auto& p : pdf.map())
     113 [ +  - ][ +  - ]:     162345 :       m_outFile << binsize * static_cast<tk::real>(p.first) << '\t'
     114                 :     162345 :                 << static_cast<tk::real>(p.second) / binsize /
     115         [ +  - ]:     162345 :                    static_cast<tk::real>(pdf.nsample())
     116         [ +  - ]:     162345 :                 << std::endl;
     117                 :            :   } else { // If user-specified sample space extents, output outpdf array
     118                 :          0 :     std::size_t bin = 0;
     119         [ -  - ]:          0 :     for (const auto& p : outpdf)
     120 [ -  - ][ -  - ]:          0 :       m_outFile << binsize * static_cast<tk::real>(bin++) + uext[0] << '\t'
     121 [ -  - ][ -  - ]:          0 :                 << p << std::endl;
     122                 :            :   }
     123                 :        726 : }
     124                 :            : void
     125                 :        726 : PDFWriter::extents( const UniPDF& pdf,
     126                 :            :                     const std::vector< tk::real >& uext,
     127                 :            :                     std::size_t& nbi,
     128                 :            :                     tk::real& min,
     129                 :            :                     tk::real& max,
     130                 :            :                     tk::real& binsize,
     131                 :            :                     std::array< long, 2*UniPDF::dim >& ext,
     132                 :            :                     std::vector< tk::real >& outpdf ) const
     133                 :            : // *****************************************************************************
     134                 :            : //  Query extents and other metadata of univariate PDF sample space
     135                 :            : //! \details Query and optionally override number of bins and minimum of sample
     136                 :            : //!    space if user-specified extents were given and copy probabilities from
     137                 :            : //!    pdf to an array for output for plotting univariate PDF.
     138                 :            : //! \param[in] pdf Univariate PDF object
     139                 :            : //! \param[in] uext User-specified extents of sample space
     140                 :            : //! \param[inout] nbi Number of bins
     141                 :            : //! \param[inout] min Minimum value of sample space
     142                 :            : //! \param[inout] max Maximum value of sample space
     143                 :            : //! \param[inout] binsize Bin size
     144                 :            : //! \param[inout] ext Extents of sample space
     145                 :            : //! \param[inout] outpdf PDF ready to be written out to file
     146                 :            : // *****************************************************************************
     147                 :            : {
     148                 :        726 :   assertSampleSpaceExtents< 1 >( uext );
     149                 :            : 
     150                 :            :   // Query bin size and extents of sample space from PDF
     151                 :        726 :   binsize = pdf.binsize();
     152                 :        726 :   ext = pdf.extents();
     153                 :            : 
     154                 :            :   // Compute number of bins of sample space (min bins: 1)
     155 [ -  + ][ -  - ]:        726 :   Assert( ext[1] >= ext[0], "Wrong extents in PDFWriter::extents" );
         [ -  - ][ -  - ]
     156                 :        726 :   nbi = static_cast< std::size_t >( ext[1] - ext[0] + 1 );
     157                 :            : 
     158                 :            :   // Compute minimum and maximum of sample space
     159                 :        726 :   min = binsize * static_cast< tk::real >( ext[0] );
     160                 :        726 :   max = binsize * static_cast< tk::real >( ext[1] );
     161                 :            : 
     162                 :            :   // Override number of bins and minimum if user-specified extents were given,
     163                 :            :   // and copy probabilities from pdf to an array for output
     164         [ -  + ]:        726 :   if (!uext.empty()) {
     165                 :            :     // Override number of bins by that based on user-specified extents
     166 [ -  - ][ -  - ]:          0 :     Assert( uext[1] >= uext[0],
         [ -  - ][ -  - ]
     167                 :            :             "Wrong user-defined extents in PDFWriter::extents" );
     168                 :          0 :     nbi = static_cast< std::size_t >(
     169                 :          0 :             std::lround( (uext[1] - uext[0]) / binsize ) );
     170                 :            :     // Override extents
     171                 :          0 :     min = uext[0];
     172                 :          0 :     max = uext[1];
     173                 :            : 
     174                 :            :     // Size output pdf to user-requested dimensions to overridden nbi and
     175                 :            :     // initialize output probabilities to zero
     176         [ -  - ]:          0 :     outpdf = std::vector< tk::real >( nbi, 0.0 );
     177                 :            : 
     178                 :            :     // Fill requested region of pdf to be output from computed pdf
     179         [ -  - ]:          0 :     for (const auto& p : pdf.map()) {
     180                 :            :       // Compute (i.e., shift) bin indices relative to user-requested extents
     181                 :          0 :       const auto bin = p.first - std::lround( uext[0] / binsize );
     182                 :            :       // Only copy probability value if shifted bin indices fall within
     183                 :            :       // user-requested extents (lower inclusive, upper exclusive)
     184 [ -  - ][ -  - ]:          0 :       if (bin >= 0 && bin < std::lround( (uext[1] - uext[0]) / binsize )) {
                 [ -  - ]
     185 [ -  - ][ -  - ]:          0 :         Assert( static_cast<std::size_t>(bin) < nbi,
         [ -  - ][ -  - ]
     186                 :            :                 "Bin overflow in user-specified-extent-based bin "
     187                 :            :                 "calculation of univariate PDF extents." );
     188                 :            :         // Copy normalized probability to output pdf
     189                 :          0 :         outpdf[ static_cast<std::size_t>(bin) ] =
     190                 :          0 :           p.second / binsize / static_cast<tk::real>(pdf.nsample());
     191                 :            :       }
     192                 :            :     }
     193                 :            :   }
     194                 :        726 : }

Generated by: LCOV version 1.16