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.