diff --git a/TODO b/TODO index 426fa24f8cefcee88b9694b968e21f2a50d94a60..7888754d828ec1a9861d7066dab881e757c545e2 100644 --- a/TODO +++ b/TODO @@ -1,17 +1,17 @@ == Todo at once == -allow fit if curve has less slices than data? -prevent fits for slices with m/ set; allow global fits for the remaining slices -parallelize global fits +or+: value does not arrive! cp: table header placement, correct 1-R^2 store status cg, cx of curve files + == To investigate == boost::format -> cppformat ? + == Current refactoring (everything becomes an object) == simplfy tree_ and curve_ calls @@ -119,6 +119,7 @@ distribution - include wupscat, wupsbb - rewrite wupscat in bash instead of ruby + == PROJECTS == detailed balance @@ -142,6 +143,8 @@ convolution with function coord name algebra +parallelize global fits + == WAITING FOR CLUE == diff --git a/pub/lib/commands.cpp b/pub/lib/commands.cpp index 1b0057dbbc850f39d7be6e8a304db807d0a821b6..3679215b7b98db054a9dd9b3e8c5d2f8df11b3e4 100644 --- a/pub/lib/commands.cpp +++ b/pub/lib/commands.cpp @@ -275,6 +275,10 @@ bool frida_command( string cmd ) NFileOut::save( "y08" ); } else if (cmd == "fso") { NFileOut::save( "y08", true ); + } else if (cmd == "fS") { + NFileOut::save( "yda" ); + } else if (cmd == "fSo") { + NFileOut::save( "yda", true ); } else if (cmd == "fe1") { NFileOut::save( "csv" ); } else if (cmd == "fe2") { diff --git a/pub/lib/file_out.cpp b/pub/lib/file_out.cpp index a68dc0510b104befb5a9f61cba244d4d1f3022b7..3d201e31b18710acd9c3c09b4b3f267e536c6e89 100644 --- a/pub/lib/file_out.cpp +++ b/pub/lib/file_out.cpp @@ -7,9 +7,12 @@ //! \file file_out.cpp //! \brief NFileOut: write files. +#include <iostream> // for debugging #include <cmath> #include <string> #include <vector> +#include <fstream> +#include <yaml-cpp/yaml.h> #include "../trivia/yaml_out.hpp" #include "../readplus/ask.hpp" @@ -22,6 +25,7 @@ #include "file_out.hpp" namespace NFileOut { + void save_yda( std::ofstream& ofs, POlo f ); void save_y08( FILE *file, POlo f ); void save_csv( FILE *file, POlo f ); void save_tab( FILE *file, POlo f ); @@ -33,7 +37,6 @@ namespace NFileOut { void NFileOut::save( string fmt, bool allow_overwrite ) { string outfnam; - FILE *file; NOlm::IterateO iter; POlo f; while( (f=iter()) ) { @@ -47,28 +50,148 @@ void NFileOut::save( string fmt, bool allow_overwrite ) f->lDoc.push_back( "fs " + outfnam + " # " + triv::time2strg( time(0) ) ); // prevent unintended overwriting if( !allow_overwrite ){ + FILE *file; if ( (file = fopen(outfnam.c_str(), "r")) ) { fclose(file); throw "file "+outfnam+" exists, use fso to overwrite"; } } // save file - if ( !(file = fopen(outfnam.c_str(), "w")) ) - throw "cannot write to file " + outfnam; - if( fmt=="y08"){ - save_y08( file, f ); - } else if( fmt=="csv" ) { - save_csv( file, f ); - } else if( fmt=="tab" ) { - save_tab( file, f ); - } else - throw "Unknown format "+fmt; - fclose(file); + if( fmt=="yda"){ + std::ofstream ofs; + ofs.open( outfnam, std::ofstream::out ); + save_yda( ofs, f ); + ofs.close(); + } else { + FILE *file; + if ( !(file = fopen(outfnam.c_str(), "w")) ) + throw "cannot write to file " + outfnam; + if( fmt=="y08" ) { + save_y08( file, f ); + } else if( fmt=="csv" ) { + save_csv( file, f ); + } else if( fmt=="tab" ) { + save_tab( file, f ); + } else + throw "BUG: Unknown format "+fmt; + fclose(file); + } f->as_on_disk = true; } } +//! Writes a file in format y15. + +void NFileOut::save_yda( std::ofstream& ofs, POlo f ) +{ + POld fd = P2D( f ); + POlc fc = P2C( f ); + + YAML::Emitter out; + out << YAML::BeginMap; + + out << YAML::Key << "Meta" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "format" << YAML::Value << "frida/y15 for yaml1.2"; + out << YAML::Key << "type" << YAML::Value << ( fd ? "generic tabular data" : "frida2 curve" ); + out << YAML::EndMap; + + out << YAML::Key << "History" << YAML::Value << YAML::BeginSeq; + for ( string lin: f->lDoc ) + out << lin; + out << YAML::EndSeq; + + out << YAML::Key << "Coord" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "x" << YAML::Value << YAML::Flow << YAML::BeginMap << + YAML::Key << "name" << YAML::Value << f->xco.name << + YAML::Key << "unit" << YAML::Value << f->xco.unit << YAML::EndMap; + out << YAML::Key << "y" << YAML::Value << YAML::Flow << YAML::BeginMap << + YAML::Key << "name" << YAML::Value << f->yco.name << + YAML::Key << "unit" << YAML::Value << f->yco.unit << YAML::EndMap; + out << YAML::Key << "z" << YAML::Value << YAML::BeginSeq; + for ( auto& zco: f->ZCo ) + out << YAML::Flow << YAML::BeginMap << + YAML::Key << "name" << YAML::Value << zco.name << + YAML::Key << "unit" << YAML::Value << zco.unit << YAML::EndMap; + out << YAML::EndSeq; + out << YAML::EndMap; + + out << YAML::Key << "RPar" << YAML::Value << YAML::BeginSeq; + for ( auto& rpar: f->RPar ) + out << YAML::BeginMap << + YAML::Key << "name" << YAML::Value << rpar.Co.name << + YAML::Key << "unit" << YAML::Value << rpar.Co.unit << + YAML::Key << "val" << YAML::Value << rpar.val << + YAML::Key << "stdv" << YAML::Value << rpar.dval << YAML::EndMap; + out << YAML::EndSeq; + + if( fc ) { + out << YAML::Key << "Curve" << YAML::Value << YAML::BeginMap; + + out << YAML::Key << "expr" << YAML::Value << fc->expr; + out << YAML::Key << "weighing" << YAML::Value << COlc::wgtNames[fc->weighing]; + out << YAML::Key << "chi2" << YAML::Value << fc->chi2; + + out << YAML::EndMap; + } + + out << YAML::Key << "Slices" << YAML::Value << YAML::BeginSeq; + for( size_t j=0; j<f->V.size(); ++j ) { + out << YAML::BeginMap; + out << YAML::Key << "j" << YAML::Value << j; + RSlice s = f->V[j]; + out << YAML::Key << "z" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( auto& z: s->z ) { + out << YAML::BeginMap; + if( auto pz = PCAST<const CObjNum>(z) ) { + out << YAML::Key << "val" << YAML::Value << pz->to_r(); + if( auto pdz = PCAST<const CObjEnu>(z) ) + out << YAML::Key << "stdv" << YAML::Value << pdz->to_dr(); + } else + out << YAML::Key << "string" << YAML::Value << z->to_s(); + out << YAML::EndMap; + } + out << YAML::EndSeq; + if ( fd ) { + RSpec sd = PCAST<const CSpec>(s); + out << YAML::Key << "x" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( double v: sd->x ) + out << v; + out << YAML::EndSeq; + + out << YAML::Key << "y" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( double v: sd->y ) + out << v; + out << YAML::EndSeq; + + if( sd->has_dy() ) { + out << YAML::Key << "dy" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( double v: sd->dy ) + out << v; + out << YAML::EndSeq; + } + } else { + RCurve sc = PCAST<const CCurve>(s); + out << YAML::Key << "p" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( double v: sc->P ) + out << v; + out << YAML::EndSeq; + + out << YAML::Key << "attr" << YAML::Value << YAML::Flow << YAML::BeginSeq; + for( char v: sc->ParAttr ) + out << v; + out << YAML::EndSeq; + + out << YAML::Key << "fitOutcome" << YAML::Value << sc->fitOutcome; + out << YAML::Key << "fitChi2" << YAML::Value << sc->fitChi2; + out << YAML::Key << "fitR2" << YAML::Value << sc->fitR2; + } + out << YAML::EndMap; + } + ofs << out.c_str(); // https://github.com/jbeder/yaml-cpp/issues/337 +} + + //! Writes a file in format y08. void NFileOut::save_y08( FILE *file, POlo f ) diff --git a/pub/lib/olf.cpp b/pub/lib/olf.cpp index bf52843703252123b17a4e7af815ff58a3ec72a0..0cd8f596bc114ea918215e4cc31c8170aaeeb192 100644 --- a/pub/lib/olf.cpp +++ b/pub/lib/olf.cpp @@ -328,6 +328,7 @@ bool COld::has_nonzero_dy() const //* class COlc - interactive initialization //************************************************************************************************** +string COlc::wgtNames[] = { "lin", "log", "var", "varc", "vard" }; //! Prompt for curve description, and initialize things. diff --git a/pub/lib/olf.hpp b/pub/lib/olf.hpp index 99b865098aea7fbfca1fa19d3baafbc3316b6377..47e78e557c85ce93e894f559adcb65d69c783364 100644 --- a/pub/lib/olf.hpp +++ b/pub/lib/olf.hpp @@ -96,6 +96,7 @@ public: int kconv; ///< Index of resolution file to convolve with. enum TWgt { _LIN, _LOG, _VAR, _VARC, _VARD } weighing; ///< Weight mode for fitting. + static string wgtNames[]; bool plot_to_grid; ///< Use grid from file 'kd' ? string range_expr; ///< Restricts points to be fitted. RNode range_T; ///< Parsed range_expr.