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 : : const auto& vars = info.vars; 62 : : const auto& it = info.it; 63 : : const auto& time = info.time; 64 : : 65 : : assertSampleSpaceDimensions< 1 >( vars ); 66 : : 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 : : 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 : : << "# Univariate PDF: " << name << '(' << vars[0] << ')' << '\n' 81 : : << "# -----------------------------------------------\n" 82 [ + - ][ + - ]: 2178 : << "# Numeric precision: " << m_outFile.precision() << '\n' [ + - ][ + - ] 83 [ + - ]: 726 : << "# Bin size: " << binsize << '\n' 84 [ + - ][ + - ]: 1452 : << "# Number of bins estimated: " << ext[1] - ext[0] + 1 [ + - ] 85 : : << '\n' 86 [ + - ]: 726 : << "# Number of bins output: " << nbi << '\n' 87 [ + - ][ + - ]: 1452 : << "# 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 : : << "# gnuplot> set xlabel \"" << vars[0] << "\"\n" 96 : : << "# gnuplot> set ylabel \"" << name << "(" << vars[0] << ")\"\n" 97 [ + - ]: 726 : << "# gnuplot> plot "; 98 [ - + ][ - - ]: 726 : if (!uext.empty()) m_outFile << "[" << uext[0] << ':' << uext[1] << "] "; [ - - ][ - - ] [ - - ] 99 : : m_outFile << "\"" << m_filename << "\" with points\n#\n" 100 : : << "# Gnuplot one-liner for quick copy-paste\n" 101 : : << "# -----------------------------------------------\n" 102 : : << "# set grid; unset key; set xlabel \"" << vars[0] 103 : : << "\"; set ylabel \"" << name << "(" << vars[0] 104 [ + - ]: 726 : << ")\"; plot"; 105 [ - + ][ - - ]: 726 : if (!uext.empty()) m_outFile << " [" << uext[0] << ':' << uext[1] << "]"; [ - - ][ - - ] [ - - ] 106 : : m_outFile << " \"" << m_filename << "\" w p\n#\n" 107 : : << "# 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 : : << std::endl; 117 : : } else { // If user-specified sample space extents, output outpdf array 118 : : 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 : : 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 : : 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 : : 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 : : 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 : }