tstYieldResourceIO.cpp
  ./Core/io/tests/tstYieldResourceIO.cpp
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <istream>
#include <string>
#include <vector>
#include "Origen/Core/io/YieldResourceIO.h"
#include "ScaleData/Core/Utils.h"
#include "ScaleFileUtils/FileUtils.h"
#include "Nemesis/gtest/nemesis_gtest.hh"
#include "Origen/Core/fn/print.h"
#include "Origen/Core/TestPaths.h"
#include "Origen/Core/io/STab1Reader.h"
#include "Origen/Core/io/STab1Writer.h"
namespace Origen
{
namespace test
{
// extended writer for testing
{
  public:
    {
        std::string line;
        STab1Writer::setRealValue( &line, value, 1 );
        line.resize( 11 );
        return line;
    }
};
#define SEXPECT_EQ( a, b ) EXPECT_EQ( a, STab1Writer::as_string( b ) )
TEST( Ampx, FloatWriting )
{
    // positive numbers with exponents
    SEXPECT_EQ( " 1.0000-100", 1e-100 );
    SEXPECT_EQ( " 1.00000-99", 1e-99 );
    SEXPECT_EQ( " 1.00000-10", 1e-10 );
    SEXPECT_EQ( " 1.000000-9", 1e-9 );
    SEXPECT_EQ( " 1.000000-8", 1e-8 );
    SEXPECT_EQ( " 1.000000-7", 1e-7 );
    SEXPECT_EQ( " 1.000000-6", 1e-6 );
    SEXPECT_EQ( " 1.000000-5", 1e-5 );
    SEXPECT_EQ( " 1.000000-4", 1e-4 );
    SEXPECT_EQ( " 1.000000-3", 1e-3 );
    SEXPECT_EQ( " 1.000000-2", 1e-2 );
    SEXPECT_EQ( " 1.000000-1", 1e-1 );
    SEXPECT_EQ( " 1.000000-0", 1e+0 );
    SEXPECT_EQ( " 1.000000+1", 1e+1 );
    SEXPECT_EQ( " 1.000000+2", 1e+2 );
    SEXPECT_EQ( " 1.000000+3", 1e+3 );
    SEXPECT_EQ( " 1.000000+4", 1e+4 );
    SEXPECT_EQ( " 1.000000+5", 1e+5 );
    SEXPECT_EQ( " 1.000000+6", 1e+6 );
    SEXPECT_EQ( " 1.000000+7", 1e+7 );
    SEXPECT_EQ( " 1.000000+8", 1e+8 );
    SEXPECT_EQ( " 1.000000+9", 1e+9 );
    SEXPECT_EQ( " 1.00000+10", 1e+10 );
    SEXPECT_EQ( " 1.00000+99", 1e+99 );
    SEXPECT_EQ( " 1.0000+100", 1e+100 );
    SEXPECT_EQ( " 1.0000+200", 1e+200 );
    // negative numbers with exponents
    SEXPECT_EQ( "-1.0000-200", -1e-200 );
    SEXPECT_EQ( "-1.0000-100", -1e-100 );
    SEXPECT_EQ( "-1.00000-99", -1e-99 );
    SEXPECT_EQ( "-1.00000-10", -1e-10 );
    SEXPECT_EQ( "-1.000000-9", -1e-9 );
    SEXPECT_EQ( "-1.000000-8", -1e-8 );
    SEXPECT_EQ( "-1.000000-7", -1e-7 );
    SEXPECT_EQ( "-1.000000-6", -1e-6 );
    SEXPECT_EQ( "-1.000000-5", -1e-5 );
    SEXPECT_EQ( "-1.000000-4", -1e-4 );
    SEXPECT_EQ( "-1.000000-3", -1e-3 );
    SEXPECT_EQ( "-1.000000-2", -1e-2 );
    SEXPECT_EQ( "-1.000000-1", -1e-1 );
    SEXPECT_EQ( "-1.000000-0", -1e+0 );
    SEXPECT_EQ( "-1.000000+1", -1e+1 );
    SEXPECT_EQ( "-1.000000+2", -1e+2 );
    SEXPECT_EQ( "-1.000000+3", -1e+3 );
    SEXPECT_EQ( "-1.000000+4", -1e+4 );
    SEXPECT_EQ( "-1.000000+5", -1e+5 );
    SEXPECT_EQ( "-1.000000+6", -1e+6 );
    SEXPECT_EQ( "-1.000000+7", -1e+7 );
    SEXPECT_EQ( "-1.000000+8", -1e+8 );
    SEXPECT_EQ( "-1.000000+9", -1e+9 );
    SEXPECT_EQ( "-1.00000+10", -1e+10 );
    SEXPECT_EQ( "-1.00000+99", -1e+99 );
    SEXPECT_EQ( "-1.0000+100", -1e+100 );
    SEXPECT_EQ( "-1.0000+200", -1e+200 );
    // other numbers
    SEXPECT_EQ( " 1.100000-0", 1.1e+0 );
    SEXPECT_EQ( " 1.23456+10", 1.23456e+10 );
    SEXPECT_EQ( "-1.23456+10", -1.23456e+10 );
    SEXPECT_EQ( " 5.555555-0", 5.5555555 );
    SEXPECT_EQ( " 5.555556-0", 5.55555555 );
}
class YieldResourceIO_F : public ::testing::Test
{
  protected:
    ScaleUtils::IO::DB opts;
};
TEST_F( YieldResourceIO_F, Basic )
{
    // get yields resource
    io.load( yr, yields_filepath, opts );
    EXPECT_TRUE( opts.numError() == 0 );
    // Check the yield resource for correctness.
    std::vector<std::string> errors;
    bool pass = yr.check( errors );
    opts.appendErrorStack( &errors );
    EXPECT_TRUE( pass ) << opts.dumpErrorStack();
    // dump it out for inspection
    if( !pass )
    {
        std::cout << "Error in yields: dumping yield table"
                  << " output to yields.txt" << std::endl;
        std::ofstream ofs( "yields.txt" );
        printYields( yr, ofs );
        ofs.close();
    }
    EXPECT_EQ( 30, yr.num_fissionables() );
    EXPECT_TRUE( yr.has_fissionable( 92235 ) )
        << "must have U-235 as a parent fissionable nuclide";
    EXPECT_EQ( 1151, yr.num_fps( 92235 ) )
        << "number of fission products for U-235";
    const YieldParent* u235_ptr = yr.fissionable( 92235 );
    EXPECT_TRUE( u235_ptr != nullptr );
    const YieldParent& u235 = *u235_ptr;
    EXPECT_TRUE( u235.has_fp( 54135 ) );
    int i_xe135 = u235.fp_index( 54135 );
    EXPECT_TRUE( i_xe135 != -1 );
    // get yields and energies for Xe-135
    std::vector<double> energies, yields;
    u235.get_energies( &energies );
    for( size_t j = 0; j < energies.size(); j++ )
    {
        yields.push_back( u235.data_at( j ).yield_at( i_xe135 ) );
        // std::cout << energies[j] << ": "<< yields[j]<<std::endl;
    }
    EXPECT_FLOAT_EQ( 0.0253, energies[0] );
    EXPECT_FLOAT_EQ( 2e6, energies[1] );
    EXPECT_FLOAT_EQ( 1.4e7, energies[2] );
    EXPECT_FLOAT_EQ( 0.00079801498, yields[0] );
    EXPECT_FLOAT_EQ( 0.0011961, yields[1] );
    EXPECT_FLOAT_EQ( 0.0045401901, yields[2] );
    double my_energy = 1e6;
    std::vector<double> yield_list;
    std::vector<int> fp_list;
    u235.get_interp_yields( &yield_list, my_energy );
    u235.get_fp_ids( &fp_list );
    EXPECT_EQ( 54135, fp_list[i_xe135] ) << "U-235 fp ids are consistent";
    double by_hand = yields[0] + ( yields[1] - yields[0] ) *
                                     ( my_energy - energies[0] ) /
                                     ( energies[1] - energies[0] );
    EXPECT_FLOAT_EQ( by_hand, yield_list[i_xe135] )
        << "U-235 by hand and set yield interpolation are same";
}
// Check that we fail properly when trying to load a different type of file.
TEST_F( YieldResourceIO_F, WrongTextFormat )
{
    bool pass = io.load( yr, decay_filepath, opts );
    EXPECT_FALSE( pass );
    EXPECT_EQ( 3, opts.numError() ) << opts.writeErrorStack();
    if( opts.numError() == 3 )
    {
        auto e = opts.errorStack();
        EXPECT_EQ( "premature end of file with format='stab1'", e[0] );
        EXPECT_EQ( "file is not ENDF-formatted yield data with format='ampx'",
                   e[1] );
        EXPECT_EQ( "tried to load formats: (stab1|ampx) and failed", e[2] );
    }
    opts.clearErrorStack();
}
// Test loading using AMPX data.
TEST_F( YieldResourceIO_F, AmpxLoadingAndErrorCatching )
{
    // load with defaults and check that we got endf
    bool pass = io.load( yr, endfyields_filepath, opts );
    EXPECT_TRUE( pass ) << opts;
    EXPECT_EQ( "ampx", opts.get<std::string>( "loadedFileFormat", "" ) );
    EXPECT_EQ( "endf", opts.get<std::string>( "ampxFormat", "" ) );
    opts.clearErrorStack();
    // try with gnd format
    yr.clear();
    opts.set<std::string>( "fileFormat", "ampx" );
    opts.set<std::string>( "ampxFormat", "gnd" );
    pass = io.load( yr, endfyields_filepath, opts );
    EXPECT_FALSE( pass ) << opts;
    opts.clearErrorStack();
}
TEST( YieldResourceIO, IntenseRoundTrip )
{
    // list of possible formats
    std::vector<std::string> fmts{"stab1"};
    // Andrew, need to work to enable this line
    // std::vector<std::string> fmts{"stab1","ampx"};
    for( auto fmt1 : fmts )
    {
        for( auto fmt2 : fmts )
        {
            ScaleUtils::IO::DB opts;
            // read it in whatever format it exists
            ASSERT_TRUE( yr1 != nullptr ) << opts.writeErrorStack();
            // write it to format 1
            opts.set<std::string>( "fileFormat", fmt1 );
            ASSERT_TRUE( status1 ) << opts.writeErrorStack();
            // read it again (with automatic format finding)
            // this is the first thing to compare
            opts.remove<std::string>( "fileFormat" );
            ASSERT_TRUE( yr1 != nullptr ) << opts.writeErrorStack();
            // write it, now to format 2
            opts.set<std::string>( "fileFormat", fmt2 );
            ASSERT_TRUE( status2 ) << opts.writeErrorStack();
            // finally read it from format 2
            // this is the second thing to compare
            ASSERT_TRUE( yr2 != nullptr ) << opts.writeErrorStack();
            // compare resources by using the JSON string dump as a middle man
            std::vector<std::string> content( 2 );
            content[0] = yr1->to_string();
            content[1] = yr2->to_string();
            std::vector<std::string> file( 2 );
            file[0] = "out1." + fmt1 + ".json";
            file[1] = "out2." + fmt2 + ".json";
            bool print_contents =
                false;  // can change to true to get print out anyway
            if( content[0] != content[1] )
            {
                print_contents = true;
                EXPECT_TRUE( content[0] == content[1] )
                    << "compare content of " << file[0] << " and " << file[1]
                    << " for differences!";
            }
            if( print_contents )
            {
                for( auto i : {0, 1} )
                {
                    std::ofstream ofs( file[i] );
                    ofs << content[i];
                }
            }
        }  // end fmt2 loop
    }      // end fmt1 loop
}
TEST( YieldResourceJobs, Rebaseline )
{
    bool rebaseline = false;
    if( rebaseline )
    {
        // get yields resource
        ScaleUtils::IO::DB opts;
        opts.set<std::string>( "fileFormat", "stab1" );
        SP_YieldResource yr( loadYieldResource( yields_filepath, opts ) );
        ASSERT_TRUE( yr != nullptr );
        // Print the yield resource.
        // When you need to rebaseline, do the following externally:
        //   diff yields.in.txt yields.in.gold
        std::ofstream ofs( "yields.txt" );
        printYields( *yr, ofs );
        std::ofstream ofs2( "yields.in.txt" );
        std::ofstream ofs3( "yields.en.txt" );
        printYieldEnergies( *yr, ofs3 );
    }
}
TEST( YieldResourceJobs, ExperimentalCumulativeYields )
{
    // load another
    bool experimental_cumulative_yields = false;
    if( experimental_cumulative_yields )
    {
        ScaleUtils::IO::DB opts;
        opts.set<std::string>( "fileFormat", "stab1" );
            "/Users/ww5/pkg/scale_tip/packages/Origen/Core/io/tests/"
            "origen.revXX.e70.cyields.data",
            opts ) );
        std::cout << opts.toString();
        std::ofstream ofs( "cyields.txt" );
        printYields( *yr, ofs );
        std::ofstream ofs2( "cyields.in.txt" );
        printInterpolatedYields( *yr, 92235, 1.4e6, INTERP_LINLIN, ofs2 );
        std::ofstream ofs3( "cyields.en.txt" );
        printYieldEnergies( *yr, ofs3 );
    }
}
}  // namespace test
}  // namespace Origen
 
          
          
 1.8.10
 1.8.10