Changed the default behavior of msr2data for writing output-file headers.

The default (if no option is given) is now that only for newly generated or empty files the respective header will be written.
If data is appended to an existing file, it is assumed that the header also is present already!
In this case only the new data blocks are appended directly after to existing ones.
[Most probably this behavior is broken if used in a native Windows environment, however, this is not the only problem there...]

The previous option "noheader" is preserved.
It suppresses the output of the header in any case.
If new data are appended to an existing output file this is done at the end of the file---just as before!

A new option "header" has been introduced.
If this is given, the output of the header is forced---no matter if a file (probably with header) existed before or not.
Also in this case all new data (and the header) are appended at the end of the output file if it existed already.

In case both options are given, the default behavior is activated.
This commit is contained in:
Bastian M. Wojek 2011-01-30 14:23:14 +00:00
parent decd363404
commit 91b9fef9a2
4 changed files with 69 additions and 18 deletions

View File

@ -17,6 +17,7 @@ FIXED 2 little annoying problems: (i) now it is possible to zoom down to the sin
(ii) when switching between data- and difference-view, the x-range doesn't change anymore.
FIXED musrt0 crash for histogram number out of range (MUSR-157)
FIXED fixes the inadequate attempt to use log max likelihood fit for asymmetry/non-muSR fit (MUSR-148)
CHANGED the default behavior of msr2data for writing output-file headers (see svn-log 4758)
CHANGED the behavior of msr2data when non-existing files are encountered---as far as possible they should be ignored now
CHANGED less strict handling of empty FUNCTION block
CHANGED cosmetics in the y-labelling (MUSR-154)

View File

@ -59,7 +59,7 @@ using namespace boost::algorithm;
* \param value number to be written to the ASCII file
* \param width column width of the ASCII file
*/
void writeValues(ofstream &outFile, const double &value, const unsigned int &width)
void writeValues(fstream &outFile, const double &value, const unsigned int &width)
{
if (fabs(value) >= 1.0e6 || (fabs(value) < 1.0e-4 && fabs(value) > 0.0))
outFile << scientific << setprecision(width - 8);
@ -1647,7 +1647,7 @@ bool PMsr2Data::PrepareNewSortedInputFile(unsigned int tempRun) const
* \param global global mode or not
* \param counter counter used within the global mode to determine how many runs have been processed already
*/
int PMsr2Data::WriteOutput(const string &outfile, bool db, bool withHeader, bool global, unsigned int counter) const
int PMsr2Data::WriteOutput(const string &outfile, bool db, unsigned int withHeader, bool global, unsigned int counter) const
{
if (!to_lower_copy(outfile).compare("none")) {
fRunVectorIter++;
@ -1940,18 +1940,52 @@ int PMsr2Data::WriteOutput(const string &outfile, bool db, bool withHeader, bool
}
// open the DB or dat file and write the data
fstream outFile;
outFile.open(outfile.c_str(), ios::in | ios::out | ios::ate);
if (outFile.is_open()) {
if (((withHeader == 0) || (withHeader == 1)) && !fHeaderWritten) {
// Header should (not) be written explicitly, start writing at the end of the file
// This also ensures the backward compatibility to the old "noheader" option
outFile.seekp(0, ios::end);
} else {
if (!fHeaderWritten) { // File already present: assume header is present already and find the last written block
fHeaderWritten = true;
}
int size(outFile.tellg());
string s;
ofstream outFile(outfile.c_str(), ios::app);
if (!outFile) {
cerr << endl << ">> msr2data: **ERROR** The output file " << outfile << " cannot be opened! Please check!";
cerr << endl;
fRunVectorIter = fRunVector.end();
return -1;
for (int i(1); i<=size; ++i) { // find the last non-empty line -- this procedure at the moment probably breaks native Windows support
outFile.seekg(-i, ios::end);
getline(outFile, s);
if (s.empty()) {
if (i == size) {
outFile.seekp(0);
fHeaderWritten = false; // if the file contained only empty lines, default to writing the header
break;
} else {
continue;
}
} else {
outFile.seekp(0, ios::cur);
break;
}
}
}
} else {
outFile.open(outfile.c_str(), ios::out);
if (!outFile.is_open()) {
cerr << endl << ">> msr2data: **ERROR** The output file " << outfile << " cannot be opened! Please check!";
cerr << endl;
fRunVectorIter = fRunVector.end();
return -1;
}
}
if (db) {
if (withHeader && !fHeaderWritten) {
cout << endl << ">> msr2data: **INFO** Write a new DB file header to " << outfile << endl;
outFile << "TITLE" << endl;
outFile << ">>>Put your title here<<<" << endl << endl;
outFile << "Abstract" << endl;
@ -2178,6 +2212,7 @@ int PMsr2Data::WriteOutput(const string &outfile, bool db, bool withHeader, bool
maxlength += 1; // maximum length of parameter names + ' '
if (withHeader && !fHeaderWritten) {
cout << endl << ">> msr2data: **INFO** Write a new simple-ASCII file header to " << outfile << endl;
if (fDataHandler) {
for (unsigned int i(0); i < dataParamNames.size(); ++i) {

View File

@ -73,7 +73,7 @@ class PMsr2Data
bool PrepareNewInputFile(unsigned int, bool) const; // template
bool PrepareGlobalInputFile(unsigned int, const string&, unsigned int) const; // generate msr-input file for a global fit
int WriteOutput(const string&, bool, bool, bool global = false, unsigned int counter = 0) const;
int WriteOutput(const string&, bool, unsigned int, bool global = false, unsigned int counter = 0) const;
private:
bool PrepareNewSortedInputFile(unsigned int) const; // template

View File

@ -79,13 +79,13 @@ bool isNumber(const string &s)
*/
void msr2data_syntax()
{
cout << endl << "usage 1: msr2data <run> <extension> [-o<outputfile>] [data] [noheader] [nosummary] [global[+[!]]]";
cout << endl << "usage 1: msr2data <run> <extension> [-o<outputfile>] [data] [[no]header] [nosummary] [global[+[!]]]";
cout << endl << " [fit [-k] [-t] | fit-<template>[!] [-k] [-t] | msr-<template>]";
cout << endl << "usage 2: msr2data <run1> <run2> <extension> [-o<outputfile>] [data] [noheader] [nosummary] [global[+[!]]]";
cout << endl << "usage 2: msr2data <run1> <run2> <extension> [-o<outputfile>] [data] [[no]header] [nosummary] [global[+[!]]]";
cout << endl << " [fit [-k] [-t] | fit-<template>[!] [-k] [-t] | msr-<template>]";
cout << endl << "usage 3: msr2data \\[<run1> <run2> ... <runN>\\] <extension> [-o<outputfile> ] [data] [noheader] [nosummary] [global[+[!]]]";
cout << endl << "usage 3: msr2data \\[<run1> <run2> ... <runN>\\] <extension> [-o<outputfile> ] [data] [[no]header] [nosummary] [global[+[!]]]";
cout << endl << " [fit [-k] [-t] | fit-<template>[!] [-k] [-t] | msr-<template>]";
cout << endl << "usage 4: msr2data <runlist> <extension> [-o<outputfile>] [data] [noheader] [nosummary] [global[+[!]]]";
cout << endl << "usage 4: msr2data <runlist> <extension> [-o<outputfile>] [data] [[no]header] [nosummary] [global[+[!]]]";
cout << endl << " [fit [-k] [-t] | fit-<template>[!] [-k] [-t] | msr-<template>]";
cout << endl;
cout << endl << " <run>, <run1>, <run2>, ... <runN> : run numbers";
@ -93,7 +93,10 @@ void msr2data_syntax()
cout << endl << " -o<outputfile> : specify the name of the DB or column data output file; default: out.db/out.dat";
cout << endl << " if the option '-o none' is used, no output file will be written.";
cout << endl << " data : instead of to a DB file the data are written to a simple column structure";
cout << endl << " header : force writing of the file header to the output file";
cout << endl << " noheader : no file header is written to the output file";
cout << endl << " If either none or both of the header options are given, the file header will be written";
cout << endl << " if a new file is created, but not if the output file exists already!";
cout << endl << " nosummary : no additional data from the run data file is written to the output file";
cout << endl << " fit : invoke musrfit to fit the specified runs";
cout << endl << " All msr input files are assumed to be present, none is newly generated!";
@ -139,7 +142,7 @@ string msr2data_validArguments(const vector<string> &arg)
string word;
for (vector<string>::const_iterator iter(arg.begin()); iter != arg.end(); ++iter) {
if ( (!iter->compare("noheader")) || (!iter->compare("nosummary")) \
if ( (!iter->compare("header")) || (!iter->compare("noheader")) || (!iter->compare("nosummary")) \
|| (!iter->substr(0,3).compare("fit")) || (!iter->compare("-k")) || (!iter->compare("-t")) \
|| (!iter->compare("data")) || (!iter->substr(0,4).compare("msr-")) || (!iter->compare("global")) \
|| (!iter->compare("global+")) || (!iter->compare("global+!")) )
@ -186,7 +189,7 @@ string msr2data_outputfile(vector<string> &arg, bool db = true)
iterNext = iter + 1;
if (!iter->substr(0,2).compare("-o")) {
if (!iter->compare("-o")) {
if ((iterNext != arg.end()) && (iterNext->compare("noheader")) && (iterNext->compare("nosummary")) \
if ((iterNext != arg.end()) && (iterNext->compare("header")) && (iterNext->compare("noheader")) && (iterNext->compare("nosummary")) \
&& (iterNext->substr(0,3).compare("fit")) && (iterNext->compare("-k")) && (iterNext->compare("-t")) \
&& (iterNext->compare("data")) && (iterNext->substr(0,3).compare("msr")) && (iterNext->compare("global")) \
&& (iterNext->compare("global+")) && (iterNext->compare("global+!"))) {
@ -596,11 +599,23 @@ int main(int argc, char *argv[])
return status;
}
bool writeHeader(false), writeSummary(false);
bool writeSummary(false);
unsigned int writeHeader(2);
// writeHeader: 0 - no header
// 1 - write header explicitly (even if the file is present already)
// 2 - write header automatically if a new file is created and do not if the data is appended to an existing file
if (realOutput) {
// check the arguments for the "noheader" option
writeHeader = msr2data_useOption(arg, "noheader");
// check the arguments for the "header" and "noheader" options
if (!msr2data_useOption(arg, "header")) {
if (!msr2data_useOption(arg, "noheader")) {
writeHeader = 2;
} else {
writeHeader = 1;
}
} else if (!msr2data_useOption(arg, "noheader")) {
writeHeader = 0;
}
// check the arguments for the "nosummary" option
writeSummary = msr2data_useOption(arg, "nosummary");