29 #include <QtCore/QCoreApplication>
30 #include <QtCore/QDir>
31 #include <QtCore/QFileInfo>
32 #include <QtCore/QList>
33 #include <QtCore/QRegularExpression>
34 #include <QtCore/QSettings>
35 #include <QtCore/QString>
36 #include <QtCore/QStringList>
39 #if QT_VERSION >= 0x050000
40 # include <QtWidgets/QApplication>
42 # include <QtGui/QApplication>
61 void saveSettings(QSettings&,
bool shouldInvokeSystemWideWizard);
105 static int parse_opt(
int key,
char *arg,
struct argp_state *state)
122 ": parse_opt(): it is dangerous to use a string \"" + options->
altSetupName +
123 "\" as an alternative config name");
125 ": parse_opt(): you can overwrite another file (un)intentionally");
136 options->
kinds.append(str);
139 ": parse_opt(): got an unknown kind \"" + str +
"\", ignoring");
159 ": parse_opt(): the station \"" + str +
"\" is added to the process list");
162 if (strcmp(arg,
"c") == 0)
164 else if (strcmp(arg,
"m") == 0)
166 else if (strcmp(arg,
"t") == 0)
171 ": parse_opt(): unrecognized argument \"" + arg +
"\" of \"-z\" option; "
172 "expected: \"c\", \"m\" or \"t\"");
190 if (1 < state->arg_num)
197 if (state->arg_num < 1 &&
202 return ARGP_ERR_UNKNOWN;
226 return new QApplication(argc, argv);
228 return new QCoreApplication(argc, argv);
239 int main(
int argc,
char** argv)
245 QString sessionName(
"");
246 QString path2wrapperFile(
"");
247 QString wrapperFileName(
"");
248 QString userCommand(
"");
252 const QString path2SystemWideConfig(SWCONFIG
"/xdg");
254 const QString path2SystemWideConfig(
"");
260 const char* envDisplay=NULL;
270 options.
kinds.clear();
288 QCoreApplication::setOrganizationName(
origOrgName);
289 QCoreApplication::setOrganizationDomain(
origDmnName);
293 QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, path2SystemWideConfig);
297 isGuiEnabled = (envDisplay=getenv(
"DISPLAY"))!=NULL && 0<strlen(envDisplay);
299 QScopedPointer<QCoreApplication>
301 if (qobject_cast<QApplication *>(app.data()))
316 for (
int i=0; i<argc; i++)
317 userCommand += QString(argv[i]) +
" ";
324 struct argp_option argp_options[] =
326 {0, 0, 0, 0,
"General options:", 10},
327 {
"input-dir",
'd',
"STRING", 0,
328 "Use an alternative path STRING to search for input files"},
329 {
"std-locale",
'l', 0, 0,
330 "Use the standard locale"},
332 {0, 0, 0, 0,
"Configuration control:", 11},
333 {
"alt",
'a',
"STRING", 0,
334 "Use an alternative configuration STRING"},
336 {0, 0, 0, 0,
"Data processing control:", 13},
337 {
"kind",
'k',
"STRING", 0,
338 "Use only the specified by STRING kind of input. Known kinds are: log (FS log files), "
339 "cdms (files with CDMS values), "
340 "pcmt (files with PCMT values), "
341 "met (files with meteorological data). "
342 "There can be more than one \"-k\" option"},
343 {
"meteo-order",
'o',
"STRING", 0,
344 "An order of meteo parameters in /wx/ record of a log file. STRING is a string with at least 3 "
345 "characters: T (temperature), P (pressure) and H (relative humidity). The order of the chars in "
346 "STRING determines the order of data in a log file. The default is TPH. The values are case "
347 "insensitive. The argument is supposed to be used with \"-s\" option, otherwise change of the "
348 "order will affect all stations."},
349 {
"station",
's',
"STRING", 0,
350 "Use only station STRING (STRING can be either two-char station code or 8-chars station name). "
351 "There can be more than one \"-s\" option"},
352 {
"zerofy",
'z',
"CHAR", 0,
353 "Reset data type CHAR. CHAR can be \"c\" (cable calibration), "
354 "\"m\" (meteorological data) or \"t\" (tsys). There can be more than one \"-z\" option"},
356 {0, 0, 0, 0,
"Invocation of startup wizard:", 25},
357 {
"sys-wide-wizard",
'W', 0, 0,
358 "Run startup wizard for the system-wide settings"},
359 {
"wizard",
'w', 0, 0,
360 "Force call of the startup wizard"},
362 {0, 0, 0, 0,
"Operation modes:", -1},
363 {
"print-setup",
'p', 0, 0,
364 "Print set up and exit"},
365 {
"dry-mode",
'q', 0, 0,
366 "Process in a \"dry run\" mode: files will not be created, instead names of the files "
368 {
"version",
'V', 0, 0,
369 "Print program version"},
373 QString salute(
"vgosDbProcLogs is a program that extracts data from filed "
374 "system log files and stores obtained info in vgosDb database. The mandatory argument DATABASE is "
375 "a name of a database (with or without version part) or a name of wrapper file (absolute or "
376 "relative to the default path of the vgosDb files).\v");
383 QString(
"\n\nThe utility vgosDbProcLogs is a part of nuSolve package. See the datails in "
384 "\"vgosDbProcLogs User Guide\", a part of nuSolve distribution. You can get the latest version of "
385 "nuSolve at\n\t\thttps://sourceforge.net/projects/nusolve");
387 struct argp argp={argp_options,
parse_opt,
"DATABASE", salute.toLatin1()};
389 argp_parse (&argp, argc, argv, 0, 0, &options);
392 isFirstRun = options.
settings->allKeys().size()>0 ? false :
true;
398 ": using alternative config name \"" + options.
altSetupName +
"\"");
413 ": the size of meteo order string (" + QString(
"").setNum(options.
orderOfMeteo.size()) +
414 ") is less than 3; ignoring");
420 ": the meteo order string \"" + options.
orderOfMeteo +
"\" does not contain temperature tag "
421 "(T or t); ignoring");
427 ": the meteo order string \"" + options.
orderOfMeteo +
"\" does not contain pressure tag "
428 "(P or p); ignoring");
434 ": the meteo order string \"" + options.
orderOfMeteo +
"\" does not contain relative humidity "
435 "tag (H or h); ignoring");
441 ": the meteo order string \"" + options.
orderOfMeteo +
"\" contains more than one temperature "
442 "tag (T or t); ignoring");
448 ": the meteo order string \"" + options.
orderOfMeteo +
"\" contains more than one pressure tag "
449 "(P or p); ignoring");
455 ": the meteo order string \"" + options.
orderOfMeteo +
"\" contains more than one relative "
456 "humidity tag (H or h); ignoring");
463 ": the meteo order string \"" + options.
orderOfMeteo +
"\" is invalid");
480 QSettings *swSettings =
482 if (!swSettings->isWritable())
486 ": cannot write system wide config");
495 ": using an alternative config name, system wide config edit request ignored");
500 if (startup.exec() == QDialog::Rejected)
524 ": cannot run graphical application.");
534 QRegularExpression reWrapperFileName(
".*\\.(wrp|wrap)$",
535 QRegularExpression::CaseInsensitiveOption);
536 QRegularExpression reOldDbName(
"^(\\d{2}[A-Z]{3}\\d{2}[A-Z0-9]{1,2}).*");
537 QRegularExpression reNewDbName(
"^(\\d{8})-([\\S]{2,12}).*");
541 if (reWrapperFileName.match(options.
inputArg).hasMatch())
545 sessionName, version);
548 ": got a session " + sessionName +
" of version " +
549 QString(
"").setNum(version) +
" from \"" + path2wrapperFile +
"\":\"" +
550 wrapperFileName +
"\"");
555 ": cannot figure out a session from the input \"" + options.
inputArg +
"\"");
558 else if ( reOldDbName.match(options.
inputArg).hasMatch() ||
559 reNewDbName.match(options.
inputArg).hasMatch() )
563 path2wrapperFile, wrapperFileName, sessionName, version);
566 ": got a wrapper file \"" + wrapperFileName +
567 "\" from \"" + path2wrapperFile +
"\" for the session " + sessionName +
568 " of version " + QString(
"").setNum(version));
573 ": cannot figure out a session from the input \"" + options.
inputArg +
"\"");
579 ": cannot guess input data from \"" + options.
inputArg +
"\"");
596 alHistory =
new SgLogger(0,
false,
"");
597 alHistory->setIsNeedTimeMark(
false);
598 alHistory->setIsMute(
true);
617 QString sLang(
""), sLcAll(
"");
621 sLang = QString(getenv(
"LANG"));
622 setenv(
"LANG",
"C", 1);
623 if (getenv(
"LC_ALL"))
624 sLcAll = QString(getenv(
"LC_ALL"));
625 setenv(
"LC_ALL",
"C", 1);
627 ": the env.variable LANG was set to \"C\"");
629 ": the env.variable LC_ALL was set to \"C\"");
636 ": the vgosDb object has been created");
638 isOk = vgosDb->
init(path2wrapperFile, wrapperFileName);
640 ": initSessionFromOdb(): parsing of wrapper file " + path2wrapperFile +
"/" + wrapperFileName +
641 (isOk?
" complete":
" failed"));
670 ": User command: \"" + userCommand +
"\"");
672 ": Input data : " + path2wrapperFile +
"/" + wrapperFileName);
675 ") has been imported from vgosDb data set");
682 QString sStns(
"all stations");
685 sWhat +=
"cable cal";
687 sWhat +=
", meteorological";
694 sStns =
"selected station(s) ";
695 for (
int i=0; i<options.
stations.size(); i++)
696 sStns += options.
stations.at(i) +
", ";
705 ": the " + sWhat +
" were reset for " + sStns +
" of the session " + session.
getSessionCode() +
706 " (" + session.
getName() +
")");
712 ": clearing the " + sWhat +
" for " + sStns +
" of the session " + session.
getSessionCode() +
713 " (" + session.
getName() +
") failed");
723 ": import of data from station log files has " + (isOk?
"been complete":
"failed"));
732 ": export of data into vgosDb set has " + (isOk?
"been complete":
"failed"));
737 ": the elapsed time to process " + QString(
"").setNum(session.
observations().size()) +
738 " observations is: " +
interval2Str(finisEpoch - startEpoch) +
739 " (" + QString(
"").sprintf(
"%.2f", (finisEpoch - startEpoch)*86400.0) +
" sec)",
true);
745 ": no new data were acquired");
750 ": vgosDb object has been destroyed.");
756 ": import data of " + path2wrapperFile +
"/" + wrapperFileName +
" failed");
762 setenv(
"LANG", qPrintable(sLang), 1);
763 setenv(
"LC_ALL", qPrintable(sLcAll), 1);
765 ": the env.variable LANG was set to \"" + sLang +
"\"");
767 ": the env.variable LC_ALL was set to \"" + sLcAll +
"\"");
788 settings.value(
"Identities/UserName",
791 settings.value(
"Identities/UserEmailAddress",
794 settings.value(
"Identities/UserDefaultInitials",
797 settings.value(
"Identities/AcFullName",
800 settings.value(
"Identities/AcAbbreviatedName",
803 settings.value(
"Identities/AcShortAbbreviatedName",
809 settings.value(
"Setup/Path2Home",
812 settings.value(
"Setup/Path2SessionFiles",
815 settings.value(
"Setup/Path2VgosDbFiles",
818 settings.value(
"Setup/Path2MasterFiles",
821 settings.value(
"Setup/Path2AuxLogs",
824 settings.value(
"Setup/Have2SavePerSessionLog",
827 settings.value(
"Setup/UseLocalLocale",
832 settings.value(
"Logger/FileName",
833 "vgosDbProcLogs.log").toString());
836 settings.value(
"Logger/Capacity", 400).toInt());
841 logLevel = settings.value(
"Logger/LogLevel", 2).toInt();
848 int size, defaultCableSign;
849 QString stationKey(
""), rinexFileName(
"");
851 if ( (size = settings.beginReadArray(
"Setup/DefaultCableSignByStn")) )
856 for (
int i=0; i<size; ++i)
858 settings.setArrayIndex(i);
859 stationKey = settings.value(
"StationKey").toString().leftJustified(8,
' ');
860 defaultCableSign = settings.value(
"DefaultCableSign", 1).toInt();
866 ": loadSettings(): no DefaultCableSignByStn found, using default set up");
871 if ( (size = settings.beginReadArray(
"Setup/RinexFileNameByStn")) )
876 for (
int i=0; i<size; ++i)
878 settings.setArrayIndex(i);
879 stationKey = settings.value(
"StationKey").toString().leftJustified(8,
' ');
880 rinexFileName = settings.value(
"RinexFileName").toString();
886 ": loadSettings(): no RinexFileNameByStn found, using default set up");
889 if ( (size = settings.beginReadArray(
"Setup/RinexPressureOffsetByStn")) )
894 for (
int i=0; i<size; ++i)
896 settings.setArrayIndex(i);
897 stationKey = settings.value(
"StationKey").toString().leftJustified(8,
' ');
898 dP = settings.value(
"RinexPressureOffset", 0.0).toDouble();
904 ": loadSettings(): no RinexPressureOffsetByStn found, using default set up");
911 void saveSettings(QSettings& settings,
bool shouldInvokeSystemWideWizard)
914 if (!shouldInvokeSystemWideWizard)
916 settings.setValue(
"Identities/UserName",
918 settings.setValue(
"Identities/UserEmailAddress",
920 settings.setValue(
"Identities/UserDefaultInitials",
923 settings.setValue(
"Identities/AcFullName",
925 settings.setValue(
"Identities/AcAbbreviatedName",
927 settings.setValue(
"Identities/AcShortAbbreviatedName",
931 if (!shouldInvokeSystemWideWizard)
933 settings.setValue(
"Setup/Path2Home",
936 settings.setValue(
"Setup/Path2SessionFiles",
938 settings.setValue(
"Setup/Path2VgosDbFiles",
940 settings.setValue(
"Setup/Path2MasterFiles",
942 settings.setValue(
"Setup/Path2AuxLogs",
944 settings.setValue(
"Setup/Have2SavePerSessionLog",
946 settings.setValue(
"Setup/UseLocalLocale",
950 settings.setValue(
"Logger/FileName",
953 settings.setValue(
"Logger/Capacity",
955 settings.setValue(
"Logger/IsStoreInFile",
957 settings.setValue(
"Logger/IsNeedTimeMark",
961 settings.remove(
"Setup/DefaultCableSignByStn");
967 settings.setArrayIndex(idx);
968 settings.setValue(
"StationKey", it.key());
969 settings.setValue(
"DefaultCableSign", it.value());
975 settings.remove(
"Setup/RinexFileNameByStn");
981 settings.setArrayIndex(idx);
982 settings.setValue(
"StationKey", it.key());
983 settings.setValue(
"RinexFileName", it.value());
987 settings.remove(
"Setup/RinexPressureOffsetByStn");
993 settings.setArrayIndex(idx);
994 settings.setValue(
"StationKey", it.key());
995 settings.setValue(
"RinexPressureOffset", it.value());
QString interval2Str(double days)
SgVersion libraryVersion("SgLib", 0, 8, 2, "Compton Peak (rc2)", SgMJD(2023, 4, 3, 10, 59))
const QString & getAcAbbrevName() const
const QString & getAcAbbName() const
void setAcAbbrevName(const QString &)
void setAcFullName(const QString &)
const QString & getUserEmailAddress() const
void setAcAbbName(const QString &)
const QString & getMachineMachineName() const
const QString & getMachineRelease() const
const QString & getMachineNodeName() const
const QString & getUserDefaultInitials() const
const QString & getAcFullName() const
void setUserDefaultInitials(const QString &)
void setUserEmailAddress(const QString &)
void setUserName(const QString &)
const QString & getUserName() const
const QString & getMachineSysName() const
virtual void write(LogLevel, quint32, const QString &, bool=false)
bool getIsStoreInFile() const
void attachSupplementLog(const QString &name, SgLogger *auxLogger)
void setIsStoreInFile(bool isStoreInFile)
void setLogFacility(LogLevel lvl, quint32 f)
void setFileName(const QString &fileName)
void setIsNeedTimeMark(bool isNeedTimeMark)
void setDirName(const QString &dirName)
virtual void clearSpool()
void setCapacity(int capacity)
bool getIsNeedTimeMark() const
const QString & getFileName() const
void detachSupplementLog(const QString &name)
@ F_DDMonYYYY
Date: 2010 Apr 02.
QString toString(Format format=F_Verbose) const
static SgMJD currentMJD()
const SgMJD & getReleaseEpoch() const
const QString & getSoftwareName() const
QString name(NameFormat fmt=NF_Human) const
void setOperationMode(SgNetCdf::OperationMode om)
const QString & getSessionName() const
bool init(const QString path, const QString fileName)
void addHistoryRecord(const QString &, const SgMJD &t)
const QString & getName() const
const QString & getSessionCode() const
bool getDataFromVgosDb(SgVgosDb *vgosDb, bool have2LoadImmatureSession, bool guiExpected)
SgVlbiHistory & contemporaryHistory()
QList< SgVlbiObservation * > & observations()
static bool guessSessionByWrapperFileName(const QString &inputArg, const QString &path2VgosDb, QString &path2wrapperFile, QString &wrapperFileName, QString &sessionName, int &version)
static bool guessWrapperFileNameBySession(const QString &inputArg, const QString &path2VgosDb, const QString &acAbbName, QString &path2wrapperFile, QString &wrapperFileName, QString &sessionName, int &version, bool noYears=false)
void setPath2Masterfile(const QString &)
bool resetDataFromLogFiles(bool doCable, bool doMeteo, bool doTsys, const QList< QString > &stations)
bool importDataFromLogFiles(const QString &path2sessions, const QList< QString > &stations, const QList< QString > &kinds, const QMap< QString, int > *defaultCableSignByStn, const QMap< QString, QString > *rinexFileNameByStn, const QMap< QString, double > *rinexPressureOffsetByStn, bool have2overwriteAntabFile, bool reportAllTsysData, const QString &altPath2InputFiles, const QString &orderOfMeteo)
bool putDataIntoVgosDb(SgVgosDb *vgosDb)
void setPath2MasterFiles(const QString &)
SgIdentities & identities()
const QString & getPath2SessionFiles() const
void setUpBinaryIdentities(const QString &)
const QString & getPath2VgosDbFiles() const
void setUseLocalLocale(bool use)
QMap< QString, double > & rinexPressureOffsetByStn()
void setPath2Home(const QString &)
QMap< QString, int > & defaultCableSignByStn()
void setPath2SessionFiles(const QString &)
const QString & getPath2Home() const
const QString & getPath2AuxLogs() const
bool getUseLocalLocale() const
const QString & getPath2MasterFiles() const
void setPath2AuxLogs(const QString &)
QString path2(const QString &) const
void setHave2SavePerSessionLog(bool)
QMap< QString, QString > & rinexFileNameByStn()
const QMap< QString, double > & getRinexPressureOffsetByStn() const
void setPath2VgosDbFiles(const QString &)
const QMap< QString, int > & getDefaultCableSignByStn() const
const QMap< QString, QString > & getRinexFileNameByStn() const
bool getHave2SavePerSessionLog() const
static int serialNumber()
QString altPath2InputFiles
QMap< QString, int > knownKinds
bool shouldInvokeSystemWideWizard
QList< QString > stations
const QString origAppName("vgosDbProcLogs")
void loadSettings(QSettings &)
QCoreApplication * createApplication(int &argc, char *argv[], bool isGuiEnabled)
const QString origOrgName("NASA GSFC")
int main(int argc, char **argv)
const QString origDmnName("gsfc.nasa.gov")
const char * argp_program_bug_address
static int parse_opt(int key, char *arg, struct argp_state *state)
void saveSettings(QSettings &, bool shouldInvokeSystemWideWizard)
SgVersion vgosDbProcLogsVersion