private string GenerateProgramVersionAndAgencyInfo(RinexType version) { // program, agency, date of generation string fileCreationDate = ""; switch (version) { case RinexType.Version3: fileCreationDate = DateTime.UtcNow.ToString("yyyyMMdd HHmmss") + " UTC"; break; case RinexType.Version2: case RinexType.Bipm: case RinexType.Cctf: fileCreationDate = DateTime.UtcNow.ToString("dd-MMM-yy HH:mm", CultureInfo.InvariantCulture).ToUpper(); break; case RinexType.Unknown: break; } return(string.Format("{0}{1}{2}PGM / RUN BY / DATE", RinexTools.Consolidate(ProgramName), RinexTools.Consolidate(AgencyName), RinexTools.Consolidate(fileCreationDate) )); }
public MeteoSensorDescription(string observationType, string model, string type, double accuracy) { this.observationType = observationType.Trim().ToUpper(); if (observationType.Length > 4) { this.observationType = unknownObservation; } this.model = RinexTools.Consolidate(model); this.type = RinexTools.Consolidate(type); this.accuracy = accuracy; }
public string GetObservationType(RinexType version) { switch (version) { case RinexType.Unknown: return(unknownObservation); case RinexType.Version3: case RinexType.Version2: case RinexType.Bipm: if (observationType.Length != 2) { return(unknownObservation); } return(observationType); case RinexType.Cctf: return(RinexTools.Consolidate(observationType, 4)); } return(unknownObservation); // this can not happen }
private string GenerateLabNameInfo(RinexType version) { string returnString = ""; switch (version) { case RinexType.Version3: case RinexType.Version2: returnString = RinexTools.Consolidate(AgencyName, 60) + "LAB NAME"; break; case RinexType.Bipm: case RinexType.Cctf: returnString = RinexTools.Consolidate(bipmStationCode, 60) + "LAB NAME"; break; case RinexType.Unknown: returnString = RinexTools.Consolidate("< UNDEFINED >", 60) + "LAB NAME"; break; } return(returnString); }
static void Main(string[] args) { // check command line parameters on provided filename/date if (args.Length < 1) { ConsoleUI.ErrorExit("No filename given", 1); } Settings settings = new Settings(); if (settings.Verbatim) { ConsoleUI.BeVerbatim(); } else { ConsoleUI.BeSilent(); } ConsoleUI.Welcome(); // query settings on Rinex output file type // actually RinexType.Cctf is the current standard RinexType rinexType = RinexType.Unknown; string rinexTypeFromSettings = settings.RinexType.ToUpper().Trim(); if (rinexTypeFromSettings == "BIPM") { rinexType = RinexType.Bipm; } if (rinexTypeFromSettings == "CCTF") { rinexType = RinexType.Cctf; } if (rinexTypeFromSettings == "VERSION2") { rinexType = RinexType.Version2; } if (rinexTypeFromSettings == "VERSION3") { rinexType = RinexType.Version3; } #region File name handling string baseFileName = Path.GetFileNameWithoutExtension(args[0]); string evaInputFileName = Path.ChangeExtension(baseFileName, ".TXT"); string vaisalaInputFileName = Path.ChangeExtension($"Vaisala_Data_{baseFileName}", ".txt"); string evaInputPath = Path.Combine(settings.EvaInputDirectory, evaInputFileName); string vaisalaInputPath = Path.Combine(settings.VaisalaInputDirectory, vaisalaInputFileName); DateTime dateToProcess = DateTime.UtcNow; // just to initialize the type // estimate the date (the day) from the base file name and construct the output file name try { dateToProcess = DateTime.ParseExact(baseFileName, "yyyyMMdd", CultureInfo.InvariantCulture); } catch (Exception) { ConsoleUI.ErrorExit("Filename syntax invalid", 2); } string rinexOutputFileName = RinexTools.RinexFileName(dateToProcess, rinexType); string rinexOutputPath = Path.Combine(settings.OutputDirectory, rinexOutputFileName); #endregion // load outdoor data file // this data is mandatory, without this file we can exit EvaDataLog evaDataLog = new EvaDataLog($"file: {evaInputPath}"); try { StreamReader hFile = File.OpenText(evaInputPath); ConsoleUI.ReadingFile(evaInputFileName); string line; while ((line = hFile.ReadLine()) != null) { evaDataLog.NewEntry(line); } hFile.Close(); ConsoleUI.Done(); } catch (Exception ex) { ConsoleUI.ErrorExit($"Error reading input: {ex.Message}", 3); } // load indoor data file (if in CCTF mode) VaisalaDataLog vaisalaDataLog = new VaisalaDataLog($"file: {vaisalaInputPath}"); if (rinexType == RinexType.Cctf) { try { StreamReader hFile = File.OpenText(vaisalaInputPath); ConsoleUI.ReadingFile(vaisalaInputFileName); string line; while ((line = hFile.ReadLine()) != null) { vaisalaDataLog.NewEntry(line); } hFile.Close(); ConsoleUI.Done(); } catch (Exception ex) { ConsoleUI.WriteLine($"There was a problem opening {vaisalaInputFileName}"); ConsoleUI.WriteLine($" - {ex.Message}"); ConsoleUI.WriteLine($" - Missing values substituded by {vaisalaDataLog.GetPodForDate(DateTime.UtcNow).Temperature}"); } } // extract relevant data in a new object ConsoleUI.StartOperation("Collating data"); SensorDataLog sensorDataLog = new SensorDataLog($"outdoor: {evaDataLog.Title}, indoor: {vaisalaDataLog.Title}"); foreach (var edp in evaDataLog.GetData()) { if (rinexType == RinexType.Cctf) { VaisalaDataPod vdp = vaisalaDataLog.GetPodForDate(edp.TimeStamp); sensorDataLog.NewEntry(edp.TimeStamp, edp.Temperature1, edp.RelativeHumidity, edp.AbsolutePressure, vdp.Temperature, vdp.RelativeHumidity); } else { sensorDataLog.NewEntry(edp.TimeStamp, edp.Temperature1, edp.RelativeHumidity, edp.AbsolutePressure); } } // prepare meta data SensorMetaData sensorMetaData = new SensorMetaData(rinexType); sensorMetaData.ProgramName = ConsoleUI.Title + " V" + ConsoleUI.Version; sensorMetaData.AddComment("External sensor located close to GNSS antenna"); sensorMetaData.AddComment($"Input file name: {evaInputFileName}"); sensorMetaData.AddComment($"Internal sensor data file: {vaisalaInputFileName}"); ConsoleUI.Done(); // finaly write the output file try { StreamWriter outFile = new StreamWriter(rinexOutputPath); ConsoleUI.WritingFile(rinexOutputFileName); outFile.Write(sensorMetaData.ToRinex()); outFile.Write(sensorDataLog.ToRinex(dateToProcess)); outFile.Close(); ConsoleUI.Done(); } catch (Exception ex) { ConsoleUI.ErrorExit($"Error writing output: {ex.Message}", 4); } ConsoleUI.WriteLine(""); }
/// <summary> /// Generates the file header. AddComment() must be called in advance. /// </summary> /// <returns>A single string representing the file header.</returns> public string ToRinex() { if (meteoSensorDescriptions.Length < 3) { return(string.Empty); } StringBuilder sb = new StringBuilder(); AddSensorPositionToComments(version); sb.AppendLine(GenerateVersionHeaderInfo(version)); sb.AppendLine(GenerateProgramVersionAndAgencyInfo(version)); // marker switch (version) { case RinexType.Version3: case RinexType.Version2: sb.AppendLine(RinexTools.Consolidate(StationName, 60) + "MARKER NAME"); if (!string.IsNullOrWhiteSpace(StationNumber)) { sb.AppendLine(RinexTools.Consolidate(StationNumber, 60) + "MARKER NUMBER"); } break; case RinexType.Bipm: case RinexType.Cctf: case RinexType.Unknown: break; } foreach (var s in Comments) { sb.AppendLine(RinexTools.Consolidate(s, 60) + "COMMENT"); } sb.AppendLine(GenerateLabNameInfo(version)); // sensor info // sb.AppendLine(" 3 TD HR PR # / TYPES OF OBSERV"); string typeOfObs = string.Format("{0,6}", meteoSensorDescriptions.Length); foreach (var sensor in meteoSensorDescriptions) { typeOfObs += string.Format(" {0,4}", sensor.GetObservationType(version)); } sb.AppendLine(typeOfObs.PadRight(60, ' ') + "# / TYPES OF OBSERV"); foreach (var sensor in meteoSensorDescriptions) { sb.AppendLine(sensor.ToRinex(version)); } // sensor position (not for BIPM / CCTF files) switch (version) { case RinexType.Version3: case RinexType.Version2: sb.AppendLine(string.Format(CultureInfo.InvariantCulture.NumberFormat, "{0,14:0.0000}{1,14:0.0000}{2,14:0.0000}{3,14:0.0000} PR SENSOR POS XYZ/H", PositionX, PositionY, PositionZ, PositionH)); break; case RinexType.Bipm: case RinexType.Cctf: case RinexType.Unknown: break; } sb.AppendLine(new string(' ', 60) + "END OF HEADER"); return(sb.ToString()); }