From 2d4076c19b84195622040b39ef60931c7ec103d0 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Wed, 11 Jan 2017 10:16:17 +0100 Subject: [PATCH] Revert "Remove loaders for old formats 96 and 01." This reverts commit bf40c65f1144753631ce10a8e05bb7603629a00a. --- pub/lib/coord.cpp | 24 ++++ pub/lib/coord.hpp | 4 +- pub/lib/file_in.cpp | 313 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 332 insertions(+), 9 deletions(-) diff --git a/pub/lib/coord.cpp b/pub/lib/coord.cpp index f216cfdd..34ead200 100644 --- a/pub/lib/coord.cpp +++ b/pub/lib/coord.cpp @@ -127,6 +127,30 @@ string CCoord::str_ps() const // two blanks instead of one, and no unit "" return name + ( unit!="" ? (" (" + unit + ")") : ""); } +//! Parse old a01 format. + +string CCoord::load_a01(string in) +{ + string::size_type t1, t2; + if(!in.size()) { + name = ""; + unit = ""; + return ""; + } + if ((t1 = in.find('\t'))==string::npos) { + name = in; + unit = ""; + return ""; + } + name = in.substr(0,t1); + if ((t2 = in.find('\t', t1+1))==string::npos) { + unit = in.substr(t1+1); + return ""; + } + unit = in.substr(t1+1,t2-t1); + return in.substr(t2+1); +} + //************************************************************************************************** //* outside CCoord //************************************************************************************************** diff --git a/pub/lib/coord.hpp b/pub/lib/coord.hpp index 05ef97c3..10ec7f4b 100644 --- a/pub/lib/coord.hpp +++ b/pub/lib/coord.hpp @@ -28,6 +28,8 @@ class CCoord { string str_std() const; string str_compact( int maxlen=0 ) const; string str_ps() const; + string to_a01() const; + string load_a01(string); //! Has this instance nonvoid contents? bool defined() { return name!=""; } @@ -54,4 +56,4 @@ class CParam { //! Creates instance with fully given, partly unparsed contents. CParam( string _name, string _unit="", double _val=0, double _dval=0 ) : Co( CCoord(_name, _unit) ), val(_val), dval(_dval) {} -}; +}; \ No newline at end of file diff --git a/pub/lib/file_in.cpp b/pub/lib/file_in.cpp index c57ffa10..369a2e10 100644 --- a/pub/lib/file_in.cpp +++ b/pub/lib/file_in.cpp @@ -10,6 +10,7 @@ #include "defs.hpp" #include <fstream> +#include <string.h> #include <yaml-cpp/yaml.h> @@ -26,6 +27,10 @@ namespace NFileIn { void Load_yda( std::ifstream& F_in, string fnam ); + void Load_08( std::ifstream& F_in, string flong ); + void Load_01( FILE *F_in, string flong ); + void LoadSpec_01( FILE *F_in, PSpec& sout, int nz ); + void Load_96( FILE *F_in, string flong ); } @@ -34,19 +39,30 @@ namespace NFileIn { void NFileIn::load(void) { string pattern = sask( "Load file(s)" ); - vector<string> fNames = triv::glob_file_list( pattern, "yda y08" ); + vector<string> fNames = triv::glob_file_list( pattern, "yda y08 a01 i96" ); for( string fnam: fNames ) { try{ string fdir, fshort, fext; triv::fname_divide( fnam, &fdir, &fshort, &fext); - if ( !(fext=="y08" || fext=="yda") ) + if ( fext=="y08" || fext=="yda" ) { + std::ifstream FS (fnam.c_str(), std::ios_base::in); + if( FS.fail() ) + throw string("cannot open file"); + cout << ".. loading file " << fnam << "\n"; + Load_yda( FS, fshort ); + FS.close(); + } else if ( fext=="a01" || fext=="i96" ) { + FILE *F_in; + if( !(F_in = fopen(fnam.c_str(), "r")) ) + throw "cannot open file " + fnam; + if ( fext=="a01" ) { + Load_01( F_in, fnam.c_str() ); + } else if ( fext=="i96" ) { + Load_96( F_in, fnam.c_str() ); + } + fclose( F_in ); + } else throw "unknown extension " + fext; - std::ifstream FS (fnam.c_str(), std::ios_base::in); - if( FS.fail() ) - throw string("cannot open file"); - cout << ".. loading file " << fnam << "\n"; - Load_yda( FS, fshort ); - FS.close(); } catch(string& ex) { throw "Cannot load " + fnam + ": " + ex; @@ -337,3 +353,284 @@ void NFileIn::Load_yda(std::ifstream& FS, string fnam) fout->as_on_disk = true; SMem::instance()->mem_store( move(fout) ); } + + +//! Load a .a01 formatted file. + +void NFileIn::Load_01( FILE *F_in, string flong ) +{ + string lin, key, val, fdir, fshort, fext; + int iz, nj=0, j; + CCoord co; + POld fout( new COld ); + + triv::fname_divide( flong, &fdir, &fshort, &fext); + + if ( triv::freadln(F_in, &lin)<=0 ) + throw "file empty or starting with empty line"; + if ( lin!=string("ASCII-01 JWu") ) + throw ".a01 file starts with illegal header [" + lin + "]"; + + if ( triv::freadln(F_in, &lin)<=0 || lin.length()<5 || + lin.substr(0,4)!=string("typ ") ) + throw "no valid typ line"; + if ( lin.substr(4)=="D" ) { + // ok + } else if ( lin.substr(4)=="C" ) { + throw "reading curve files not implemented"; + } else { + throw "invalid type [" + lin.substr(4) + "]"; + } + + while (1) { // loop over input lines + if ( !triv::freadln(F_in, &lin) ) + throw "unexpected end-of-file"; + + // regular exit when "eof" is reached: + if ( lin=="eof" ) { + fout->as_on_disk = true; + SMem::instance()->mem_store( move(fout) ); + return; + } + + if ( lin.size() < 4 ) + throw "incomplete line"; + + key = lin.substr(0,4); + val = lin.substr(4); + + if (key=="fil ") { + if (val!=fshort) { + cout << "warning: file '" << fshort << + "' renamed from '" << val << "'\n"; + } + fout->name = fshort; + } else if (key=="doc ") { + fout->lDoc.push_back(val); + } else if (key=="x ") { + fout->xco.load_a01(val); + } else if (key=="y ") { + fout->yco.load_a01(val); + } else if (lin[0]=='z') { + if ( sscanf(lin.substr(1,3).c_str(), "%i", &iz)!=1 ) + throw "z coordinates must be numbered"; + if ( iz!=fout->ZCo.size() ) + throw "z coordinates must be sorted"; + co.load_a01(val); + fout->ZCo.push_back(co); + } else if (lin.substr(0,4)=="rpa ") { + string in = lin.substr(4); + int ji = in.find_first_not_of(" \t"); + double dval; + if( ji>=20 || !triv::any2dbl( in.substr(ji,20), &dval ) ) + throw "invalid rpa line\n"; + fout->RPar.push_back( CParam( CCoord(), dval ) ); + throw "a01 file contains rpa section. " + "Check the source code preceeding this error message. " + "It is possibly broken. If not, remove this exception."; + } else if (key=="#j ") { + if ( sscanf(val.c_str(), "%i", &nj)!=1 ) + throw "after key #j no no. of spectra"; + } else if (key=="scn ") { + if ( sscanf(val.c_str(), "%i", &j)!=1 ) { + cout << "warning: number of spectra not given\n"; + } else if ( j!=fout->nJ() ) { + cout << "warning: spec " << fout->nJ() << + " has label " << j << "\n"; + } + PSpec sout( new CSpec ); + LoadSpec_01( F_in, sout, fout->nZ() ); + fout->V.push_back( move(sout) ); + } else { + throw "Unexpected key [" + key + "]"; + } + } +} + + +//! Load a spectrum from a .a01 formatted files. + +void NFileIn::LoadSpec_01( FILE *F_in, PSpec& sout, int nz ) +{ + int err; + int i, m, n; + char lab[4]; + double v, w; + + // get z values: + if ((err=fscanf(F_in, "%4c%i\n", lab, &m))!=2) + throw "expecting Z head line, found " + S(err) + " entries"; + if (strncmp(lab, "Z ", 4)) + throw "found [" + string(lab) + "] in Z head line"; + if (m!=nz) + throw "found " + S(m) + " Z entries, expecting " + S(nz); + for ( i=0; i<nz; ++i ) { + if ((err=fscanf(F_in, "%lg\n", &v))!=1) + throw "expecting z value, found " + S(err) + " entries"; + sout->z.push_back( PObjDbl( new CObjDbl( v ) ) ); + } + + // get xy values: + if ( (err=fscanf(F_in, "%4c%i\n", lab, &n))!=2 ) + throw "expecting XY head line, found " + S(err) + " entries"; + if (strncmp(lab, "XY ", 4) ) + throw "found [" + string(lab) + "] in XY head line"; + + for (i=0; i<n; i++) { + if ((err=fscanf(F_in, "%lg %lg\n", &v, &w))!=2) { + throw "expecting xy pair, found S(err) entries"; + } + sout->push_xy(v, w); + } +} + + +//! Load a .i96 formatted file. + +void NFileIn::Load_96( FILE *F_in, string flong ) +{ + string lin, key, val, fdir, fshort, fext; + double r0, r1, r2; + int n, nspec, ival; + POld fout( new COld ); + CCoord co; + PSpec sout; + + triv::fname_divide( flong, &fdir, &fshort, &fext); + fout->name = fshort; + + if ( !triv::freadln(F_in, &lin) ) + throw "file empty or starting with empty line"; + if ( lin!=string("ASCII-96") ) + throw ".i96 file starts with illegal header [" + lin + "]"; + + if ( !triv::freadln(F_in, &lin) || lin.length()<9 || + lin.substr(0,9)!=string("(a24,a56)") ) + throw "no valid intro to block 2"; + + if ( !triv::freadln(F_in, &lin) || lin.length()<24 || + lin.substr(0,3)!=string("fil") ) + throw "tag 'fil' not found in block 2"; + if ( triv::strip(lin.substr(24))!=fshort ) { + cout << "warning: i96 file '" << fshort << + "' renamed from '" << lin.substr(24) << "'\n"; + } + + if ( !triv::freadln(F_in, &lin) || lin.length()<24 || + lin.substr(0,3)!=string("tit") ) + throw "tag 'tit' not found in block 2"; + fout->lDoc.push_back( triv::strip(lin.substr(24)) ); + + while( !triv::freadln(F_in, &lin) && lin.length()>=24 && + lin.substr(0,3)==string("doc") ) + fout->lDoc.push_back( triv::strip(lin.substr(24)) ); + + if( lin.substr(0,3)!=string("dir") ) + throw "tag 'dir' not found in block 2"; + + while ( triv::freadln(F_in, &lin) && + !( lin.length()>=6 && + lin.substr(0,6)==string("&eob 2") ) ) + ; + + if ( !triv::freadln(F_in, &lin) ) + throw "missed &eob 3"; + + if( lin.length()<9 || lin.substr(0,9)!=string("(a24,i16)") ) + throw "no valid intro to block 3"; + + while ( !triv::freadln(F_in, &lin) && + !( lin.length()>=6 && + lin.substr(0,6)==string("&eob 3") ) ) + ; + + if ( !triv::freadln(F_in, &lin) ) + throw "missed &eob 3"; + + if ( lin.length()<16 || lin.substr(0,16)!=string("(a24,a24,g20.10)") ) + throw "no valid intro to block 4"; + + while ( !triv::freadln(F_in, &lin) && lin.length()>=48 && + lin.substr(0,4)!=string("&eob") ){ + if( sscanf( lin.substr(48).c_str(), "%lg", &r0 )!=1 ) + throw "no real value in rpar line"; + fout->RPar.push_back( + CParam( lin.substr(0,24), lin.substr(24,24), r0 ) ); + } + + if( lin.substr(0,6)!=string("&eob 4") ) + throw "no valid eob 4"; + + if ( !triv::freadln(F_in, &lin) || lin.length()<9 || + lin.substr(0,12)!=string("(a4,a24,a24)") ) + throw "no valid intro to block 5"; + + if ( !triv::freadln(F_in, &lin) || lin.length()<28 || + lin.substr(0,1)!=string("x") ) + throw "no x coordinate"; + fout->xco = CCoord( triv::strip(lin.substr(4,24)), + triv::strip(lin.substr(28,24)) ); + + if ( !triv::freadln(F_in, &lin) || lin.length()<28 || + lin.substr(0,1)!=string("y") ) + throw "no y coordinate"; + fout->yco = CCoord( triv::strip(lin.substr(4,24)), + triv::strip(lin.substr(28,24)) ); + + if ( !triv::freadln(F_in, &lin) || lin.length()<28 || + lin.substr(0,1)!=string("z") ) + throw "no z coordinate"; + fout->ZCo.push_back( CCoord( triv::strip(lin.substr(4,24)), + triv::strip(lin.substr(28,24)) ) ); + + if ( !triv::freadln(F_in, &lin) || lin.length()<6 || + lin.substr(0,6)!=string("&eob 5") ) + throw "no valid eob 5"; + + if ( !triv::freadln(F_in, &lin) || lin.length()<5 || + lin.substr(0,5)!=string("(a80)") ) + throw "no valid intro to block 6"; + + while ( triv::freadln(F_in, &lin)>0 && + !( lin.length()>=6 && + lin.substr(0,6)==string("&eob 6") ) ) + fout->lDoc.push_back( lin ); + + if ( !triv::freadln(F_in, &lin) ) + throw "missed &eob 6"; + for( int i=1; i<3; ++i ) + if ( !triv::freadln(F_in, &lin) ) + throw "no valid intro to block 7"; + + if ( !triv::freadln(F_in, &lin) || + sscanf( lin.c_str(), "%i %i", &nspec, &ival )!=2 ) + throw "no nspec or 2nd arg in intro to block 7"; + + for( int j=0; j<nspec; ++j ){ + sout = PSpec( new CSpec ); + if ( !triv::freadln(F_in, &lin) || lin.length()<10 || + lin.substr(0,9)!=string("&spectrum") || + sscanf( lin.substr(10).c_str(), "%i", &ival )!=1 || + ival!=j+1 ) + throw "no valid intro to spectrum"; + + if ( !triv::freadln(F_in, &lin) || + sscanf( lin.c_str(), "%i %lg", &n, &r0 )!=2 ) + throw "no valid header in spectrum"; + sout->z.push_back( PObjDbl( new CObjDbl( r0 ) ) ); + + for( int i=0; i<n; ++i ){ + if ( !F_in || !triv::freadln(F_in, &lin) ) + throw "i96: failed to read data line " + + S(i) + " of " + S(n); + if ( sscanf( lin.c_str(), "%lg %lg %lg", &r0, &r1, &r2 )!=3 ) + throw "i96: bad data line: '" + lin + "'"; + sout->push_xy(r0, r1); + } + + fout->V.push_back( move(sout) ); + } + + fout->as_on_disk = true; + SMem::instance()->mem_store( move(fout) ); +} -- GitLab