// DataIO_Std::Read_Mat3x3() int DataIO_Std::Read_Mat3x3(std::string const& fname, DataSetList& datasetlist, std::string const& dsname) { // Buffer file BufferedLine buffer; if (buffer.OpenFileRead( fname )) return 1; mprintf("\tAttempting to read 3x3 matrix data.\n"); // Skip comments const char* linebuffer = buffer.Line(); while (linebuffer != 0 && linebuffer[0] == '#') linebuffer = buffer.Line(); // Check that number of columns (9) is correct. int ntokens = buffer.TokenizeLine( SEPARATORS ); if (ntokens < 1) { mprinterr("Error: Could not tokenize line.\n"); return 1; } int ncols = ntokens; bool hasIndex; if (ncols == 9) hasIndex = false; else if (ncols == 10) { hasIndex = true; mprintf("Warning: Not reading 3x3 matrix data indices.\n"); } else { mprinterr("Error: Expected 9 columns of 3x3 matrix data, got %i.\n", ncols); return 1; } // Create data set DataSet_Mat3x3* ds = new DataSet_Mat3x3(); if (ds == 0) return 1; ds->SetMeta( dsname ); // Read 3x3 matrix data double mat[9]; std::fill(mat, mat, 0.0); size_t ndata = 0; while (linebuffer != 0) { if (hasIndex) ntokens = sscanf(linebuffer, "%*f %lf %lf %lf %lf %lf %lf %lf %lf %lf", mat, mat+1, mat+2, mat+3, mat+4, mat+5, mat+6, mat+7, mat+8); else ntokens = sscanf(linebuffer, "%lf %lf %lf %lf %lf %lf %lf %lf %lf", mat, mat+1, mat+2, mat+3, mat+4, mat+5, mat+6, mat+7, mat+8); if (ntokens != 9) { mprinterr("Error: In 3x3 matrix file, line %i: expected 9 values, got %i\n", buffer.LineNumber(), ntokens); break; } ds->Add( ndata++, mat ); linebuffer = buffer.Line(); } return (datasetlist.AddOrAppendSets("", DataSetList::Darray(), DataSetList::DataListType(1, ds))); }
// DataIO_Mdout::ReadData() int DataIO_Mdout::ReadData(FileName const& fname, DataSetList& datasetlist, std::string const& dsname) { mprintf("\tReading from mdout file: %s\n", fname.full()); BufferedLine buffer; if (buffer.OpenFileRead( fname )) return 1; const char* ptr = buffer.Line(); if (ptr == 0) { mprinterr("Error: Nothing in MDOUT file: %s\n", fname.full()); return 1; } // ----- PARSE THE INPUT SECTION ----- int imin = -1; // imin for this file const char* Trigger = 0; // Trigger for storing energies, must be 8 chars long. int frame = 0; // Frame counter for this file double dt = 1.0; // Timestep for this file (MD) double t0 = 0.0; // Initial time for this file (MD) int ntpr = 1; // Value of ntpr int irest = 0; // Value of irest while ( ptr != 0 && strncmp(ptr, " 2. CONTROL DATA", 20) != 0 ) ptr = buffer.Line(); if (ptr == 0) return EOF_ERROR(); // Determine whether this is dynamics or minimization, get dt ptr = buffer.Line(); // Dashes ptr = buffer.Line(); // Blank ptr = buffer.Line(); // title line while ( strncmp(ptr, " 3. ATOMIC", 13) != 0 ) { ArgList mdin_args( ptr, " ,=" ); // Remove commas, equal signs // Scan for stuff we want //mprintf("DEBUG:\tInput[%i] %s", mdin_args.Nargs(), mdin_args.ArgLine()); for (int col=0; col < mdin_args.Nargs(); col += 2) { int col1 = col + 1; if (mdin_args[col] == "imin") { imin = convertToInteger( mdin_args[ col1 ] ); if (debug_ > 0) mprintf("\t\tMDIN: imin is %i\n", imin); // Set a trigger for printing. For imin5 this is the word minimization. // For imin0 or imin1 this is NSTEP. if (imin==0) Trigger = " NSTEP ="; else if (imin==1) Trigger = " NSTEP"; else if (imin==5) Trigger = "minimiza"; // Since imin0 and imin1 first trigger has no data, set frame 1 lower. if (imin==1 || imin==0) frame = -1; } else if (mdin_args[col] == "dt") { dt = convertToDouble( mdin_args[ col1 ] ); if (debug_ > 0) mprintf("\t\tMDIN: dt is %f\n", dt); } else if (mdin_args[col] == "t") { t0 = convertToDouble( mdin_args[ col1 ] ); if (debug_ > 0) mprintf("\t\tMDIN: t is %f\n", t0); } else if (mdin_args[col] == "ntpr") { ntpr = convertToInteger( mdin_args[ col1 ] ); if (debug_ > 0) mprintf("\t\tMDIN: ntpr is %i\n", ntpr); } else if (mdin_args[col] == "irest") { irest = convertToInteger( mdin_args[ col1 ] ); if (debug_ > 0) mprintf("\t\tMDIN: irest is %i\n", irest); } } ptr = buffer.Line(); if (ptr == 0) return EOF_ERROR(); } if (Trigger == 0) { mprinterr("Error: Could not determine whether MDOUT is md, min, or post-process.\n"); return 1; } // ----- PARSE THE ATOMIC ... SECTION ----- while ( ptr != 0 && strncmp(ptr, " 4. RESULTS", 14) != 0 ) { ptr = buffer.Line(); // If run is a restart, set the initial time value. if (irest == 1) { if (strncmp(ptr, " begin time", 11) == 0) { sscanf(ptr, " begin time read from input coords = %lf", &t0); if (debug_ > 0) mprintf("\t\tMD restart initial time= %f\n", t0); } } } if (ptr == 0) return EOF_ERROR(); // ----- PARSE THE RESULTS SECTION ----- bool finalE = false; int nstep; int minStep = 0; // For imin=1 only if (irest == 0) nstep = 0; else nstep = ntpr; double Energy[N_FIELDTYPES]; std::fill( Energy, Energy+N_FIELDTYPES, 0.0 ); std::vector<bool> EnergyExists(N_FIELDTYPES, false); DataSetList::Darray TimeVals; DataSetList::DataListType inputSets(N_FIELDTYPES, 0); Sarray Name(2); double time = 0.0; while (ptr != 0) { // Check for end of imin 0 or 1 run; do not record Average and Stdevs if ( (imin == 1 && (strncmp(ptr, " FINAL", 25) == 0 || strncmp(ptr, " 5. TIMINGS", 14) == 0 )) || (imin == 0 && strncmp(ptr, " A V", 9) == 0)) finalE = true; // Check for '| TI region 2' to prevent reading duplicate energies if ( strncmp(ptr, "| TI region 2", 14) == 0 ) { while (ptr != 0 && !(ptr[0] == ' ' && ptr[1] == '-')) ptr = buffer.Line(); if (ptr == 0) return EOF_ERROR(); } // Record set for energy post-processing if (imin == 5 && strncmp(ptr, "minimizing", 10) == 0) nstep = atoi( ptr + 22 ); // MAIN OUTPUT ROUTINE // If the trigger has been reached print output. // For imin0 and imin1 the first trigger will have no data. // If the end of the file has been reached print then exit. if ( strncmp(ptr, Trigger, 8) == 0 || finalE ) { if (frame > -1) { // Store all energies present. for (int i = 0; i < (int)N_FIELDTYPES; i++) { if (EnergyExists[i]) { if (inputSets[i] == 0) { MetaData md( dsname, Enames[i] ); md.SetLegend( dsname + "_" + Enames[i] ); inputSets[i] = new DataSet_double(); inputSets[i]->SetMeta( md ); } // Since energy terms can appear and vanish over the course of the // mdout file, resize if necessary. if (frame > (int)inputSets[i]->Size()) ((DataSet_double*)inputSets[i])->Resize( frame ); ((DataSet_double*)inputSets[i])->AddElement( Energy[i] ); } } TimeVals.push_back( time ); nstep += ntpr; } frame++; if (finalE) break; } // Check for NSTEP in minimization or post-processing. Values will be // on the next line. NOTE: NSTEP means something different for imin=5. if ((imin == 1 || imin == 5) && strncmp(ptr, " NSTEP", 8) == 0) { ptr = buffer.Line(); // Get next line //sscanf(ptr, " %6lf %13lE %13lE %13lE", Energy+NSTEP, Energy+EPtot, Energy+RMS, Energy+GMAX); sscanf(ptr, " %i %lE %lE %lE", &minStep, Energy+EPtot, Energy+RMS, Energy+GMAX); EnergyExists[EPtot] = true; EnergyExists[RMS] = true; EnergyExists[GMAX] = true; ptr = buffer.Line(); } // Tokenize line, scan through until '=' is reached; value after is target. int ntokens = buffer.TokenizeLine(" "); if (ntokens > 0) { int nidx = 0; Name[0].clear(); Name[1].clear(); for (int tidx = 0; tidx < ntokens; tidx++) { const char* tkn = buffer.NextToken(); if (tkn[0] == '=') { FieldType Eindex = getEindex(Name); tkn = buffer.NextToken(); ++tidx; if (tkn == 0) mprintf("Warning: No numerical value, line %i column %i. Skipping.\n", buffer.LineNumber(), tidx+1); else if (tkn[0] == '*' || tkn[0] == 'N') // Assume if number begins with N it is NaN mprintf("Warning: Numerical overflow detected, line %i column %i. Skipping.\n", buffer.LineNumber(), tidx+1); else { if (Eindex != N_FIELDTYPES) { Energy[Eindex] = atof( tkn ); EnergyExists[Eindex] = true; } } nidx = 0; Name[0].clear(); Name[1].clear(); } else { if (nidx > 1) break; // Two tokens, no '=' found. Not an E line. Name[nidx++].assign( tkn ); } } } // Set time switch (imin) { case 5: time = (double)nstep + t0; break; case 1: time = (double)minStep + t0; break; case 0: time = ((double)nstep * dt) + t0; break; } // Read in next line ptr = buffer.Line(); } mprintf("\t%i frames\n", frame); buffer.CloseFile(); std::string Xlabel; if (imin == 5) Xlabel.assign("Set"); else if (imin == 1) Xlabel.assign("Nstep"); else Xlabel.assign("Time"); // imin == 0 if (datasetlist.AddOrAppendSets( Xlabel, TimeVals, inputSets )) return 1; return 0; }
int DataIO_XVG::ReadData(FileName const& fname, DataSetList& datasetlist, std::string const& dsname) { std::vector<std::string> Legends; BufferedLine infile; if (infile.OpenFileRead( fname )) return 1; const char* ptr = infile.Line(); if (ptr == 0) return 1; // Skip any comments while (ptr != 0 && ptr[0] == '#') ptr = infile.Line(); // Try to get set legends while (ptr != 0 && ptr[0] == '@') { ArgList line(ptr, " \t"); if (line.Nargs() > 3 && line[1][0] == 's') { std::string legend = line.GetStringKey("legend"); if (!legend.empty()) { // Spaces will cause issues with data set selection. for (std::string::iterator s = legend.begin(); s != legend.end(); ++s) if (*s == ' ') *s = '_'; Legends.push_back( legend ); } } ptr = infile.Line(); } if (Legends.empty()) { mprinterr("Error: No set legends found in XVG file.\n"); return 1; } if (ptr == 0) { mprinterr("Error: No data in XVG file.\n"); return 1; } // Create 1 data set for each legend DataSetList::DataListType inputSets; for (unsigned int i = 0; i != Legends.size(); i++) { MetaData md( dsname, i ); md.SetLegend( Legends[i] ); DataSet_double* ds = new DataSet_double(); if (ds == 0) return 1; ds->SetMeta( md ); inputSets.push_back( ds ); } mprintf("\t%s has %zu columns of data.\n", fname.base(), inputSets.size()); // Should now be positioned at first line of data. Assume first column is time values. DataSetList::Darray Xvals; int expectedCols = (int)inputSets.size() + 1; while (ptr != 0) { int ncols = infile.TokenizeLine(" \t"); if (ncols != expectedCols) mprinterr("Error: Line %i: %i columns != expected # cols %i\n", infile.LineNumber(), ncols, expectedCols); else { Xvals.push_back( atof( infile.NextToken() ) ); for (unsigned int i = 0; i != inputSets.size(); i++) ((DataSet_double*)inputSets[i])->AddElement( atof( infile.NextToken() ) ); } ptr = infile.Line(); } infile.CloseFile(); return (datasetlist.AddOrAppendSets( "", Xvals, inputSets )); }
// DataIO_Std::Read_Vector() int DataIO_Std::Read_Vector(std::string const& fname, DataSetList& datasetlist, std::string const& dsname) { // Buffer file BufferedLine buffer; if (buffer.OpenFileRead( fname )) return 1; mprintf("\tAttempting to read vector data.\n"); // Skip comments const char* linebuffer = buffer.Line(); while (linebuffer != 0 && linebuffer[0] == '#') linebuffer = buffer.Line(); // Determine format. Expect 3 (VXYZ), 6 (VXYZ OXYZ), or // 9 (VXYZ OXYZ VXYZ+OXYZ) values, optionally with indices. int ntokens = buffer.TokenizeLine( SEPARATORS ); int ncols = ntokens; // Number of columns of vector data. int nv = 0; // Number of columns to actually read from (3 or 6). bool hasIndex; if (ntokens < 1) { mprinterr("Error: Could not tokenize line.\n"); return 1; } if (ncols == 3 || ncols == 6 || ncols == 9) hasIndex = false; else if (ncols == 4 || ncols == 7 || ncols == 10) { hasIndex = true; mprintf("Warning: Not reading vector data indices.\n"); } else { mprinterr("Error: Expected 3, 6, or 9 columns of vector data, got %i.\n", ncols); return 1; } if (ncols >= 6) { nv = 6; mprintf("\tReading vector X Y Z and origin X Y Z values.\n"); } else { nv = 3; mprintf("\tReading vector X Y Z values.\n"); } // Create set DataSet_Vector* ds = new DataSet_Vector(); if (ds == 0) return 1; ds->SetMeta( dsname ); // Read vector data double vec[6]; std::fill(vec, vec+6, 0.0); size_t ndata = 0; while (linebuffer != 0) { if (hasIndex) ntokens = sscanf(linebuffer, "%*f %lf %lf %lf %lf %lf %lf", vec, vec+1, vec+2, vec+3, vec+4, vec+5); else ntokens = sscanf(linebuffer, "%lf %lf %lf %lf %lf %lf", vec, vec+1, vec+2, vec+3, vec+4, vec+5); if (ntokens != nv) { mprinterr("Error: In vector file, line %i: expected %i values, got %i\n", buffer.LineNumber(), nv, ntokens); break; } ds->Add( ndata++, vec ); linebuffer = buffer.Line(); } return (datasetlist.AddOrAppendSets("", DataSetList::Darray(), DataSetList::DataListType(1, ds))); }
// DataIO_Std::Read_1D() int DataIO_Std::Read_1D(std::string const& fname, DataSetList& datasetlist, std::string const& dsname) { ArgList labels; bool hasLabels = false; // Buffer file BufferedLine buffer; if (buffer.OpenFileRead( fname )) return 1; // Read the first line. Attempt to determine the number of columns const char* linebuffer = buffer.Line(); if (linebuffer == 0) return 1; int ntoken = buffer.TokenizeLine( SEPARATORS ); if ( ntoken == 0 ) { mprinterr("Error: No columns detected in %s\n", buffer.Filename().full()); return 1; } // Try to skip past any comments. If line begins with a '#', assume it // contains labels. bool isCommentLine = true; const char* ptr = linebuffer; while (isCommentLine) { // Skip past any whitespace while ( *ptr != '\0' && isspace(*ptr) ) ++ptr; // Assume these are column labels until proven otherwise. if (*ptr == '#') { labels.SetList(ptr+1, SEPARATORS ); if (!labels.empty()) { hasLabels = true; // If first label is Frame assume it is the index column if (labels[0] == "Frame" && indexcol_ == -1) indexcol_ = 0; } linebuffer = buffer.Line(); ptr = linebuffer; if (ptr == 0) { mprinterr("Error: No data found in file.\n"); return 1; } } else // Not a recognized comment character, assume data. isCommentLine = false; } // Special case: check if labels are '#F1 F2 <name> [nframes <#>]'. If so, assume // this is a cluster matrix file. if ((labels.Nargs() == 3 || labels.Nargs() == 5) && labels[0] == "F1" && labels[1] == "F2") { mprintf("Warning: Header format '#F1 F2 <name>' detected, assuming cluster pairwise matrix.\n"); return IS_ASCII_CMATRIX; } // Column user args start from 1 if (indexcol_ > -1) mprintf("\tUsing column %i as index column.\n", indexcol_ + 1); // Should be at first data line. Tokenize the line. ntoken = buffer.TokenizeLine( SEPARATORS ); // If # of data columns does not match # labels, clear labels. if ( !labels.empty() && ntoken != labels.Nargs() ) { labels.ClearList(); hasLabels = false; } // Index column checks if (indexcol_ != -1 ) { if (indexcol_ >= ntoken) { mprinterr("Error: Specified index column %i is out of range (%i columns).\n", indexcol_+1, ntoken); return 1; } if (!onlycols_.Empty() && !onlycols_.InRange(indexcol_)) { mprinterr("Error: Index column %i specified, but not in given column range '%s'\n", indexcol_+1, onlycols_.RangeArg()); return 1; } } // Determine the type of data stored in each column. Assume numbers should // be read with double precision. MetaData md( dsname ); DataSetList::DataListType inputSets; unsigned int nsets = 0; for (int col = 0; col != ntoken; ++col) { std::string token( buffer.NextToken() ); if (!onlycols_.Empty() && !onlycols_.InRange( col )) { mprintf("\tSkipping column %i\n", col+1); inputSets.push_back( 0 ); } else { md.SetIdx( col+1 ); if (hasLabels) md.SetLegend( labels[col] ); if ( col == indexcol_ ) { // Always save the index column as floating point inputSets.push_back( new DataSet_double() ); } else if (validInteger(token)) { // Integer number inputSets.push_back( datasetlist.Allocate(DataSet::INTEGER) ); } else if (validDouble(token)) { // Floating point number inputSets.push_back( new DataSet_double() ); } else { // Assume string. Not allowed for index column. if (col == indexcol_) { mprintf("Warning: '%s' index column %i has string values. No indices will be read.\n", buffer.Filename().full(), indexcol_+1); indexcol_ = -1; } inputSets.push_back( new DataSet_string() ); } inputSets.back()->SetMeta( md ); nsets++; } } if (inputSets.empty() || nsets == 0) { mprinterr("Error: No data detected.\n"); return 1; } // Read in data while (linebuffer != 0) { if ( buffer.TokenizeLine( SEPARATORS ) != ntoken ) { PrintColumnError(buffer.LineNumber()); break; } // Convert data in columns for (int i = 0; i < ntoken; ++i) { const char* token = buffer.NextToken(); if (inputSets[i] != 0) { if (inputSets[i]->Type() == DataSet::DOUBLE) ((DataSet_double*)inputSets[i])->AddElement( atof(token) ); else if (inputSets[i]->Type() == DataSet::INTEGER) ((DataSet_integer*)inputSets[i])->AddElement( atoi(token) ); else ((DataSet_string*)inputSets[i])->AddElement( std::string(token) ); } } //Ndata++; linebuffer = buffer.Line(); } buffer.CloseFile(); mprintf("\tDataFile %s has %i columns, %i lines.\n", buffer.Filename().full(), ntoken, buffer.LineNumber()); // Create list containing only data sets. DataSetList::DataListType mySets; DataSet_double* Xptr = 0; for (int idx = 0; idx != (int)inputSets.size(); idx++) { if (inputSets[idx] != 0) { if ( idx != indexcol_ ) mySets.push_back( inputSets[idx] ); else Xptr = (DataSet_double*)inputSets[idx]; } } mprintf("\tRead %zu data sets.\n", mySets.size()); std::string Xlabel; if (indexcol_ != -1 && indexcol_ < labels.Nargs()) Xlabel = labels[indexcol_]; if (Xptr == 0) datasetlist.AddOrAppendSets(Xlabel, DataSetList::Darray(), mySets); else { datasetlist.AddOrAppendSets(Xlabel, Xptr->Data(), mySets); delete Xptr; } return 0; }