diff --git a/src/file_io.cpp b/src/file_io.cpp
index 626c517ecf79765f22be632466c359a910715227..5bbe81a739233adfd98cf60ee617bb2a728a3aed 100644
--- a/src/file_io.cpp
+++ b/src/file_io.cpp
@@ -17,7 +17,7 @@
 #include "gar.h"
 #include "myexception.h"
 #include "file_io.h"
-#include "../yaml/include/yaml.h"
+#include "yamc.h"
 
 using namespace std;
 
@@ -26,17 +26,6 @@ namespace NFileIO {
     void Load_01( FILE *F_in, string flong );
     void LoadScan_01( FILE *F_in, CScan* sout, int nz );
     void Load_96( FILE *F_in, string flong );
-    yaml_parser_t parser;
-    yaml_event_t  event;
-    string last_valid;
-    void y_next();
-    void y_done();
-    void y_checktype( int type, string errmsg );
-    void y_checkvalue( string value );
-    void y_skipvalues( int repet );
-    bool y_scalar_from_seq( string seqname, string *ret );
-    string y_getscalar( string scalarname );
-    bool y_getCoord( string label, CCoord *co );
 }
 
 //! Load file in current or legacy format.
@@ -84,94 +73,6 @@ void NFile::Load(void)
     }
 }
 
-void NFileIO::y_next()
-{
-    if( !yaml_parser_parse( &parser, &event) )
-        throw string( "Invalid input? Last valid entry was \"" ) + 
-            last_valid + "\"";
-}
-
-void NFileIO::y_done()
-{
-    yaml_event_delete( &event);
-}
-
-void NFileIO::y_checktype( int type, string errmsg )
-{
-    y_next();
-    if( event.type != type )
-        throw errmsg;
-    if( event.type == YAML_SCALAR_EVENT )
-        last_valid = (const char*)event.data.scalar.value;
-    y_done();
-}
-
-void NFileIO::y_checkvalue( string value )
-{
-    y_next();
-    if( event.type != YAML_SCALAR_EVENT )
-        throw string("No scalar while expecting ") + value;
-    if( strcmp((const char*)event.data.scalar.value, value.c_str()) )
-        throw string("Found ") + (const char*)event.data.scalar.value +
-            " instead of " + value;
-    last_valid = (const char*)event.data.scalar.value;
-    y_done();
-}
-
-void NFileIO::y_skipvalues( int repet )
-{
-    for( int i=0; i<repet; ++i ){
-        y_checktype( YAML_SCALAR_EVENT, string( "skip " ) +  strg(repet) );
-    }
-}
-
-bool NFileIO::y_scalar_from_seq( string seqname, string *ret )
-{
-    y_next();
-    if( event.type == YAML_SEQUENCE_END_EVENT )
-        return false;
-    if( event.type != YAML_SCALAR_EVENT )
-        throw string( "NO scalar in sequence " ) + seqname +
-            "; last valid entry was \"" + last_valid + "\"";
-    *ret = (const char*)event.data.scalar.value;
-    last_valid = (const char*)event.data.scalar.value;
-    y_done();
-    return true;
-}
-
-string NFileIO::y_getscalar( string scalarname )
-{
-    string ret;
-    y_next();
-    if( event.type != YAML_SCALAR_EVENT )
-        throw string( "NO scalar " ) + scalarname +
-            "; last valid entry was \"" + last_valid + "\"";
-    ret = (const char*)event.data.scalar.value;
-    y_done();
-    return ret;
-}
-
-bool NFileIO::y_getCoord( string label, CCoord *co )
-{
-    y_next();
-    if( event.type == YAML_MAPPING_END_EVENT )
-        return false;
-    if( event.type != YAML_SCALAR_EVENT )
-        throw string( "inconsistency where " + label + " expected" );
-    if( strcmp((const char*)event.data.scalar.value, label.c_str()) )
-        throw string("Found ") + (const char*)event.data.scalar.value +
-            " instead of " + label;
-    last_valid = (const char*)event.data.scalar.value;
-    y_done();
-    y_checktype( YAML_MAPPING_START_EVENT, label + ": no map\n" );
-    y_checkvalue( "name" );
-    co->name = y_getscalar( label + ".name" );
-    y_checkvalue( "unit" );
-    co->unit = y_getscalar( label + ".unit" );
-    y_checktype( YAML_MAPPING_END_EVENT, label + ": no end of map\n" );
-    return true;
-}
-
 //! Load a YAML file in y08 format.
 void NFileIO::Load_08( FILE *F_in, string flong )
 {
@@ -181,89 +82,83 @@ void NFileIO::Load_08( FILE *F_in, string flong )
     COld old;
     CCoord co;
     CScan sout;
+    CYamlRead y( F_in );
 
     mystd::fname_divide( flong, &fdir, &fshort, &fext);
 
-    memset( &parser, 0, sizeof(parser) );
-    memset( &event, 0, sizeof(event) );
-    if (!yaml_parser_initialize( &parser ))
-        throw string("Could not initialize the parser object");
-    yaml_parser_set_input_file( &parser, F_in );
-    last_valid = "START";
-
-    y_checktype( YAML_STREAM_START_EVENT, "no stream\n" );
-    y_checktype( YAML_DOCUMENT_START_EVENT, "no document\n" );
-    y_checktype( YAML_MAPPING_START_EVENT, "main: no map\n" );
-
-    y_checkvalue( "Meta" );
-    y_checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" );
-    y_checkvalue( "format" );
-    y_checkvalue( "frida/y08 for yaml1" );
-    y_skipvalues( 2 );
-    y_checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" );
-
-    y_checkvalue( "History" );
-    y_checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" );
-    while( y_scalar_from_seq( "history", &lin ) ){
+    y.checktype( YAML_STREAM_START_EVENT, "no stream\n" );
+    y.checktype( YAML_DOCUMENT_START_EVENT, "no document\n" );
+    y.checktype( YAML_MAPPING_START_EVENT, "main: no map\n" );
+
+    y.checkvalue( "Meta" );
+    y.checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" );
+    y.checkvalue( "format" );
+    y.checkvalue( "frida/y08 for yaml1" );
+    y.skipvalues( 2 );
+    y.checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" );
+
+    y.checkvalue( "History" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" );
+    while( y.scalar_from_seq( "history", &lin ) ){
         old.lDoc.push_back(lin);
     }
 
-    y_checkvalue( "Coord" );
-    y_checktype( YAML_MAPPING_START_EVENT, "Coord: no map\n" );
-    if( !y_getCoord( "x", &(old.xco) ) )
+    y.checkvalue( "Coord" );
+    y.checktype( YAML_MAPPING_START_EVENT, "Coord: no map\n" );
+    if( !y.getCoord( "x", &(old.xco) ) )
         throw string( "no x coord" );
-    if( !y_getCoord( "y", &(old.xco) ) )
+    if( !y.getCoord( "y", &(old.xco) ) )
         throw string( "no y coord" );
     iz=0;
-    while( y_getCoord( "z"+strg(iz), &(co) ) ){
+    while( y.getCoord( "z"+strg(iz), &(co) ) ){
         old.ZCo.push_back( co );
         ++iz;
     }
-    if( event.type != YAML_MAPPING_END_EVENT )
+    if( y.event.type != YAML_MAPPING_END_EVENT )
         throw string( "Coord: no end of map" );
-    y_done();
+    y.done();
 
-    y_checkvalue( "Param" );
-    y_checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" );
+    y.checkvalue( "Param" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" );
     while( true ){
-        y_next();
-        if( event.type == YAML_SEQUENCE_END_EVENT )
+        y.next();
+        if( y.event.type == YAML_SEQUENCE_END_EVENT )
             break;
-        if( event.type != YAML_MAPPING_START_EVENT )
+        if( y.event.type != YAML_MAPPING_START_EVENT )
             throw string ( "Param: no map" );
-        y_done();
-        y_checkvalue( "name" );
-        co.name = y_getscalar( "param.name" );
-        y_checkvalue( "unit" );
-        co.unit = y_getscalar( "param(" + co.name + ").unit" );
-        y_checkvalue( "value" );
-        val = y_getscalar( "param(" + co.name + ").value" );
+        y.done();
+        y.checkvalue( "name" );
+        co.name = y.getscalar( "param.name" );
+        y.checkvalue( "unit" );
+        co.unit = y.getscalar( "param(" + co.name + ").unit" );
+        y.checkvalue( "value" );
+        val = y.getscalar( "param(" + co.name + ").value" );
         if( mystd::any2dbl( val, &num ) )
             throw string( "param(" ) + co.name + "): invalid value " + val;
         old.RPar.push_back( CParam( co, num ) );
-        y_checktype( YAML_MAPPING_END_EVENT, "Param "+co.name+": no eom\n" );
+        y.checktype( YAML_MAPPING_END_EVENT, "Param "+co.name+": no eom\n" );
     }
-    y_done();
+    y.done();
 
-    y_checkvalue( "Tables" );
-    y_checktype( YAML_SEQUENCE_START_EVENT, "Tables: no seq\n" );
+    y.checkvalue( "Tables" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "Tables: no seq\n" );
     while( true ){
-        y_next();
-        if( event.type == YAML_SEQUENCE_END_EVENT )
+        y.next();
+        if( y.event.type == YAML_SEQUENCE_END_EVENT )
             break;
-        if( event.type != YAML_MAPPING_START_EVENT )
+        if( y.event.type != YAML_MAPPING_START_EVENT )
             throw string ( "Tables: no map" );
-        y_done();
+        y.done();
         sout.Clear();
         for( iz=0; iz<old.ZCo.size(); ++iz ){
-            y_checkvalue( "z" + strg(iz) );
-            val = y_getscalar( "z" + strg(iz) + ".value" );
+            y.checkvalue( "z" + strg(iz) );
+            val = y.getscalar( "z" + strg(iz) + ".value" );
             if( mystd::any2dbl( val, &num ) )
                 throw "z" + strg(iz) + ": invalid value " + val;
             sout.z.push_back( num );
         }
-        y_checkvalue( "xy" );
-        val = y_getscalar( "xy core data" );
+        y.checkvalue( "xy" );
+        val = y.getscalar( "xy core data" );
         double v,w;
         string res;
         while( val != "" ) {
@@ -274,12 +169,12 @@ void NFileIO::Load_08( FILE *F_in, string flong )
             val = res;
         };
         old.VS.push_back( sout );
-        y_checktype( YAML_MAPPING_END_EVENT, "Table: no eom\n" );
+        y.checktype( YAML_MAPPING_END_EVENT, "Table: no eom\n" );
     }
-    y_done();
-    
-    yaml_parser_delete( &parser );
+    y.done();
 
+    old.name = fshort;
+    old.lDoc.push_back( "`loaded as " + flong );
     old.as_on_disk = true;
     NOlm::OloAdd(&old);
 }
diff --git a/src/frida2.cpp b/src/frida2.cpp
index 2b328c2ff36da125b64d08cf12a3c5b6be5bf340..e874e6ade4464fc8f79ff9d6c30e2abb7de8efcd 100644
--- a/src/frida2.cpp
+++ b/src/frida2.cpp
@@ -359,17 +359,22 @@ int main()
             printf( "total time now %g\n", time_total );
 
 	} else if (cmd == "r") {
-            cout << "read RSSM data (rold for old/internal formats):\n"
+            cout << "read RSSM data (rold for list of old-format commands):\n"
+                "  ry   load energy spectra\n"
+                "  ry2  load also spectra for open state\n"
+                "  ry4  load also chopper histograms\n"
+                "  ry8  load spectra for two directions separately\n"
+                "  ryd  load only spectra for two directions\n";
+
+	} else if (cmd == "rold") {
+            cout << "read old/internal RSSM data files:\n"
                 "  rx   load energy spectra\n"
                 "  rx2  load also spectra for open state\n"
                 "  rx4  load also chopper histograms\n"
                 "  rx8  load spectra for two directions separately\n"
                 "  rxd  load only spectra for two directions\n"
                 "  rs   load series of energy spectra\n"
-                "  rs2  load also spectra for open state\n";
-
-	} else if (cmd == "rold") {
-            cout << "read old/internal RSSM data files:\n"
+                "  rs2  load also spectra for open state\n"
                 "  rdc  load dopp, chop from stream\n"
                 "  rda  analyse dopp\n"
                 "  rca  analyse chop\n"
@@ -385,20 +390,31 @@ int main()
                 "  rx0t load from xml v0, two directions separately\n"
                 "  rh   load from Drochner histogram\n";
 
+	} else if (cmd == "ry") {
+            NRSSM::ReadScan( 5, 0 );
+	} else if (cmd == "ry2") {
+            NRSSM::ReadScan( 5, 1 );
+	} else if (cmd == "ry4") {
+            NRSSM::ReadScan( 5, 3 );
+	} else if (cmd == "ry8") {
+            NRSSM::ReadScan( 5, 7 );
+	} else if (cmd == "ryd") {
+            NRSSM::ReadScan( 5, 12 );
+
 	} else if (cmd == "rx") {
-            NRSSM::ReadScan( 0 );
+            NRSSM::ReadScan( 2, 0 );
 	} else if (cmd == "rx2") {
-            NRSSM::ReadScan( 1 );
+            NRSSM::ReadScan( 2, 1 );
 	} else if (cmd == "rx4") {
-            NRSSM::ReadScan( 3 );
+            NRSSM::ReadScan( 2, 3 );
 	} else if (cmd == "rx8") {
-            NRSSM::ReadScan( 7 );
+            NRSSM::ReadScan( 2, 7 );
 	} else if (cmd == "rxd") {
-            NRSSM::ReadScan( 12 );
+            NRSSM::ReadScan( 2, 12 );
 	} else if (cmd == "rs") {
-            NRSSM::ReadSeries( 0 );
+            NRSSM::ReadSeries( 2, 0 );
 	} else if (cmd == "rs2") {
-            NRSSM::ReadSeries( 1 );
+            NRSSM::ReadSeries( 2, 1 );
 
 	} else if (cmd == "rdc") {
             NR_Stream::Stream2DoppChop();
diff --git a/src/rssm.cpp b/src/rssm.cpp
index 8404d6ee0b9ed739152b9d612bea49b7a89ac291..af27231c2e83c4ea5160f80ec1afdd95a99430e7 100644
--- a/src/rssm.cpp
+++ b/src/rssm.cpp
@@ -20,18 +20,20 @@
 #include "asi.h"
 #include "gar.h"
 #include "rssm.h"
+#include "yamc.h"
 
 using namespace std;
 
 class RssmRawFile {
  public:
-    int ReadRaw( string fnam );
+    int RdRawXml( string fnam );
+    void RdRawYam( FILE *F_in );
     double daq_time_step;
     time_t measured_from;
     time_t measured_until;
     int    measured_at;
     double measured_during;
-    bool incremental;
+    bool   incremental;
     vector<double> rawdata[6];
     vector<double> angles;
     double temp0, temp1;
@@ -40,7 +42,150 @@ class RssmRawFile {
 };
 
 // Read raw data file, store contents as class variables
-int RssmRawFile::ReadRaw( string fnam )
+void RssmRawFile::RdRawYam( FILE *F_in )
+{
+    COld old;
+    string lin, key, val;
+    CCoord co;
+    CScan sout;
+    int iz;
+    double num;
+    
+    daq_time_step=0;
+    angles.clear();
+
+    CYamlRead y( F_in );
+
+    old.as_on_disk = true;
+    NOlm::OloAdd(&old);
+    
+    y.checktype( YAML_STREAM_START_EVENT, "no stream\n" );
+    y.checktype( YAML_DOCUMENT_START_EVENT, "no document\n" );
+    y.checktype( YAML_MAPPING_START_EVENT, "main: no map\n" );
+
+    y.checkvalue( "Meta" );
+    y.checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" );
+    y.checkvalue( "format" );
+    val = y.getscalar( "format" );
+    if( strncmp( val.c_str(), "acq5.0 for yaml1", 16 ) )
+        throw( string("Unexpected format") );
+    y.skipvalues( 2 );
+    y.checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" );
+
+    y.checkvalue( "History" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" );
+    y.checktype( YAML_MAPPING_START_EVENT, "History: meas: no map\n" );
+    y.checkvalue( "measured on SPHERES" );
+    old.lDoc.push_back( "measured on SPHERES" );
+    y.checktype( YAML_MAPPING_START_EVENT, "History: meas: meas: no map\n" );
+    while( true ){
+        y.next();
+        if( y.event.type == YAML_MAPPING_END_EVENT ){
+            y.done();
+            break;
+        }
+        if( y.event.type != YAML_SCALAR_EVENT )
+            throw string( "No scalar key in Hist:meas "
+                          "; last valid entry was \"" + y.last_valid + "\"" );
+        key = (const char*)y.event.data.scalar.value;
+        y.last_valid = key;
+        y.done();
+        y.next();
+        if( y.event.type != YAML_SCALAR_EVENT )
+            throw string( "No scalar value in Hist:meas "
+                          "; last valid entry was \"" + y.last_valid + "\"" );
+        val = (const char*)y.event.data.scalar.value;
+        y.last_valid = val;
+        y.done();
+        old.lDoc.push_back( "  " + key + ": " + val );
+        if        ( key=="incremental" ){
+            if      ( val=="true" )
+                incremental = true;
+            else if ( val=="false" )
+                incremental = false;
+            else
+                throw "Invalid value of 'incremental'";
+        } else if ( key=="until" ){
+            char date_string[24];
+            sscanf( val.c_str(), "%24c", date_string );
+            struct tm date_broken;
+            strptime( date_string, "%F %A %H:%M:%S", &date_broken );
+            measured_until = mktime( &date_broken );
+        }
+    }
+    y.checktype( YAML_MAPPING_END_EVENT, "History: meas: no end of map\n" );
+    while( y.scalar_from_seq( "history", &lin ) ){
+        old.lDoc.push_back(lin);
+    }
+
+    y.checkvalue( "Param" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" );
+    while( true ){
+        y.next();
+        if( y.event.type == YAML_SEQUENCE_END_EVENT )
+            break;
+        if( y.event.type != YAML_MAPPING_START_EVENT )
+            throw string( "Param: no map; last entry was " + y.last_valid );
+        y.done();
+        key = y.getscalar( "Param: name or note" );
+        if( key=="note" ){
+            y.skipvalues( 1 );
+            y.checktype( YAML_MAPPING_END_EVENT, "Param: no end of note" );
+            continue;
+        }
+        if( key!="name" )
+            throw string( "Param entry starting neither with note, "
+                          "nor with name" );
+        co.name = y.getscalar( "param.name" );
+        if ( co.name=="daq_time_step" ){
+            // useful double value
+            y.checkvalue( "unit" );
+            co.unit = y.getscalar( "param(" + co.name + ").unit" );
+            y.checkvalue( "value" );
+            val = y.getscalar( "param(" + co.name + ").value" );
+            if( mystd::any2dbl( val, &num ) )
+                throw string( "param(" ) + co.name + "): invalid value " + val;
+            old.RPar.push_back( CParam( co, num ) );
+            y.checktype( YAML_MAPPING_END_EVENT,
+                         "Param "+co.name+": no eom\n" );
+            if( co.name=="daq_time_step" )
+                daq_time_step = num;
+        } else {
+            // no useful value
+            while( true ){
+                y.next();
+                if( y.event.type == YAML_MAPPING_END_EVENT )
+                    break;
+                y.done();
+            }
+        }
+    }
+    y.done();
+
+    y.checkvalue( "Detectors" );
+    y.checktype( YAML_MAPPING_START_EVENT, "Detectors: no map\n" );
+    y.checkvalue( "note" );
+    y.skipvalues( 1 );
+    y.checkvalue( "angles" );
+    y.checktype( YAML_SEQUENCE_START_EVENT, "Dets:angles: no seq\n" );
+    while( true ){
+        y.next();
+        if( y.event.type == YAML_SEQUENCE_END_EVENT )
+            break;
+        if( y.event.type != YAML_SCALAR_EVENT )
+            throw string ( "Dets:angles: no scalar" );
+        val = (const char*)y.event.data.scalar.value;
+        y.done();
+        if( mystd::any2dbl( val, &num ) )
+            throw "Dets:angles: invalid value " + val;
+    }
+    y.done();
+ 
+    key = y.getscalar( "Note ?" )
+}    
+
+// Read raw data file, store contents as class variables
+int RssmRawFile::RdRawXml( string fnam )
 {
     xmlChar *key, *val, *txt, *syntax, *outform, *format, *axis,
         *contents, *categ, *txt1, *txt2;
@@ -257,8 +402,11 @@ int RssmRawFile::ReadRaw( string fnam )
     return 0;
 }    
 
-void NRSSM::ReadScan( int flag )
+void NRSSM::ReadScan( int format, int flag )
 
+// format values:
+//    2 acq2-4 xml
+//    5 acq5   yaml
 // flag values (to be OR'ed):
 //    1 save also open
 //    2 save also chop histo
@@ -269,9 +417,31 @@ void NRSSM::ReadScan( int flag )
     string file_f, name;
     file_f = wask("Read SPHERES data from xml file");
     RssmRawFile R;
-    int ret = R.ReadRaw( file_f );
-    if( ret==1 )
-        fprintf( stderr, "Data file not parsed successfully.\n" );
+    int ret;
+    FILE *F_in;
+
+    if        ( format==2 ){
+        ret = R.RdRawXml( file_f );
+        if( ret==1 )
+            fprintf( stderr, "Data file not found, or failed to parse.\n" );
+    } else if ( format==5 ){
+        if( !(F_in = fopen(file_f.c_str(), "r")) ) {
+            cerr << "Cannot read " << file_f << "\n";
+            return;
+        }
+        try{
+            R.RdRawYam( F_in );
+        }
+        catch( string &e) {
+            cerr << "Cannot read " << file_f << ":\n";
+            cerr << e << endl;
+            if (F_in) fclose(F_in);
+            return;
+        }
+    } else {
+        printf( "invalid format" );
+        return;
+    }
     if( ret )
         return;
 
@@ -413,8 +583,10 @@ void NRSSM::ReadScan( int flag )
 }
 
 
-void NRSSM::ReadSeries( int flag )
+void NRSSM::ReadSeries( int format, int flag )
 
+// format values:
+//    as above
 // flag values (to be OR'ed):
 //    1 save also open
 
@@ -429,13 +601,31 @@ void NRSSM::ReadSeries( int flag )
     fser = wask("Read SPHERES data from series");
     for( isub=0; ; ++isub ){
         RR.push_back( RssmRawFile() );
-        ret = RR.back().ReadRaw( fser+"c"+strg(isub) );
-        if( ret==1 ){
-            printf( "ignore the above warning\n" );
-            RR.pop_back();
-            break;
-        }
-        if( ret )
+        if       ( format==2 ) {
+            ret = RR.back().RdRawXml( fser+"c"+strg(isub) );
+            if( ret==1 ){
+                printf( "ignore the above warning\n" );
+                RR.pop_back();
+                break;
+            }
+        } else if( format==5 ) {
+            string fnam = fser+"c"+strg(isub);
+            FILE *F_in;
+            if( !(F_in = fopen( fnam.c_str(), "r" ) ) )
+                break;
+            try{ 
+                RR.back().RdRawYam( F_in );
+            }
+            catch(exception& e) {
+                cerr << e.what() << endl;
+                if (F_in) fclose(F_in);
+                return;
+            }
+        } else {
+            printf( "invalid format" );
+            return;
+        } 
+        if ( ret )
             return;
     }
     int nsub = RR.size();
diff --git a/src/rssm.h b/src/rssm.h
index 99b2eb2e0bdc4b6ee0b219653fa610953071ee3e..c50e37b08228631bd0a00c7a3439d62eef533c77 100644
--- a/src/rssm.h
+++ b/src/rssm.h
@@ -1,4 +1,4 @@
 namespace NRSSM {
-	void ReadScan( int flag );
-	void ReadSeries( int flag );
+    void ReadScan( int format, int flag );
+    void ReadSeries( int format, int flag );
 };
diff --git a/src/yamc.cpp b/src/yamc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3d8d9f52fd0bedd8feb361e7a4cc72cc9aba170e
--- /dev/null
+++ b/src/yamc.cpp
@@ -0,0 +1,141 @@
+//**************************************************************************//
+//* FRIDA: fast reliable interactive data analysis                         *//
+//* (C) Joachim Wuttke 1990-, v2(C++) 2001-                                *//
+//* http://frida.sourceforge.net                                           *//
+//* yamc.cpp                                                               *//
+//* read YAML data files, using libyaml                                    *//
+//**************************************************************************//
+
+#include <string>
+using namespace std;
+#include "coord.h"
+#include "yamc.h"
+#include "mystd.h"
+
+CYamlRead::CYamlRead( FILE *F_in )
+{
+    memset( &parser, 0, sizeof(parser) );
+    memset( &event, 0, sizeof(event) );
+    if (!yaml_parser_initialize( &parser ))
+        throw string("Could not initialize the parser object");
+    yaml_parser_set_input_file( &parser, F_in );
+    last_valid = "START";
+}
+
+CYamlRead::~CYamlRead()
+{
+    yaml_parser_delete( &parser );
+}
+
+void CYamlRead::next()
+{
+    if( !yaml_parser_parse( &parser, &event) )
+        throw string( "Invalid input? Last valid entry was \"" ) + 
+            last_valid + "\"";
+}
+
+void CYamlRead::done()
+{
+    yaml_event_delete( &event);
+}
+
+void CYamlRead::checktype( int type, string errmsg )
+{
+    next();
+    if( event.type != type )
+        throw errmsg;
+    if( event.type == YAML_SCALAR_EVENT )
+        last_valid = (const char*)event.data.scalar.value;
+    done();
+}
+
+void CYamlRead::checkvalue( string value )
+{
+    next();
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string("No scalar while expecting ") + value;
+    if( strcmp((const char*)event.data.scalar.value, value.c_str()) )
+        throw string("Found ") + (const char*)event.data.scalar.value +
+            " instead of " + value;
+    last_valid = (const char*)event.data.scalar.value;
+    done();
+}
+
+void CYamlRead::skipvalues( int repet )
+{
+    for( int i=0; i<repet; ++i ){
+        checktype( YAML_SCALAR_EVENT, string( "skip " ) +  strg(repet) );
+    }
+}
+
+bool CYamlRead::scalar_from_seq( string seqname, string *ret )
+{
+    next();
+    if( event.type == YAML_SEQUENCE_END_EVENT ){
+        done();
+        return false;
+    }
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string( "No scalar in sequence " ) + seqname +
+            "; last valid entry was \"" + last_valid + "\"";
+    *ret = (const char*)event.data.scalar.value;
+    last_valid = (const char*)event.data.scalar.value;
+    done();
+    return true;
+}
+
+bool CYamlRead::line_from_map( string mapname, string *ret )
+{
+    next();
+    if( event.type == YAML_MAPPING_END_EVENT ){
+        done();
+        return false;
+    }
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string( "No scalar key in mapping " ) + mapname +
+            "; last valid entry was \"" + last_valid + "\"";
+    *ret = (const char*)event.data.scalar.value;
+    done();
+    next();
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string( "No scalar value in mapping " ) + mapname +
+            "; last valid entry was \"" + last_valid + "\"";
+    *ret += string(": ") + (const char*)event.data.scalar.value;
+    last_valid = (const char*)event.data.scalar.value;
+    done();
+    return true;
+}
+
+string CYamlRead::getscalar( string scalarname )
+{
+    string ret;
+    next();
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string( "No scalar " ) + scalarname +
+            "; last valid entry was \"" + last_valid + "\"";
+    ret = (const char*)event.data.scalar.value;
+    done();
+    return ret;
+}
+
+bool CYamlRead::getCoord( string label, CCoord *co )
+{
+    next();
+    if( event.type == YAML_MAPPING_END_EVENT )
+        return false;
+    if( event.type != YAML_SCALAR_EVENT )
+        throw string( "inconsistency where " + label + " expected" );
+    if( strcmp((const char*)event.data.scalar.value, label.c_str()) )
+        throw string("Found ") + (const char*)event.data.scalar.value +
+            " instead of " + label;
+    last_valid = (const char*)event.data.scalar.value;
+    done();
+    checktype( YAML_MAPPING_START_EVENT, label + ": no map\n" );
+    checkvalue( "name" );
+    co->name = getscalar( label + ".name" );
+    checkvalue( "unit" );
+    co->unit = getscalar( label + ".unit" );
+    checktype( YAML_MAPPING_END_EVENT, label + ": no end of map\n" );
+    return true;
+}
+
diff --git a/src/yamc.h b/src/yamc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0fef933d94f00557a229ee94cd131a12f0bc1f1c
--- /dev/null
+++ b/src/yamc.h
@@ -0,0 +1,27 @@
+//**************************************************************************//
+//* FRIDA: fast reliable interactive data analysis                         *//
+//* (C) Joachim Wuttke 1990-, v2(C++) 2001-                                *//
+//* http://frida.sourceforge.net                                           *//
+//* yamc.h                                                                 *//
+//* read YAML data files, using libyaml                                    *//
+//**************************************************************************//
+
+#include "../yaml/include/yaml.h"
+
+class CYamlRead {
+ public:
+    yaml_parser_t parser;
+    yaml_event_t  event;
+    string last_valid;
+    CYamlRead( FILE *F_in );
+    ~CYamlRead();
+    void next();
+    void done();
+    void checktype( int type, string errmsg );
+    void checkvalue( string value );
+    void skipvalues( int repet );
+    bool scalar_from_seq( string seqname, string *ret );
+    bool line_from_map( string mapname, string *ret );
+    string getscalar( string scalarname );
+    bool getCoord( string label, CCoord *co );
+};