private void lbAvailableFiles_SelectedIndexChanged(object sender, EventArgs e) { if (lbAvailableFiles.SelectedIndex != -1) { m_LoadingData = true; m_RovingObservatoryProvider.ResetCurrentObcLocation(); var entry = (AvailableFileEntry)lbAvailableFiles.SelectedItem; if (!ReferenceEquals(m_SelectedEntry, entry)) { m_DataProvider = new MeasurementPositionCSVProvider(entry.FilePath); m_SelectedEntry = entry; if (m_DataProvider.Unmeasurable) { MessageBox.Show(this, "This file cannot be processed by the Fast Motion Astrometry module. Please use AAV files or AVI files for no-integration videos.", "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Error); m_DataProvider = MeasurementPositionCSVProvider.Empty; lbAvailableFiles.SelectedIndex = -1; m_LoadingData = false; Recalculate(); return; } if (m_DataProvider.NumberOfMeasurements < 3) { MessageBox.Show(this, "At least 3 data points are required for the Fast Motion Astrometry module. Please use a different file.", "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Information); m_DataProvider = MeasurementPositionCSVProvider.Empty; lbAvailableFiles.SelectedIndex = -1; m_LoadingData = false; Recalculate(); return; } nudPixelsPerArcSec.ValueChanged -= nudPixelsPerArcSec_ValueChanged; nudInstDelaySec.ValueChanged -= nudInstDelaySec_ValueChanged; dtpDate.ValueChanged -= dtpDate_ValueChanged; tbxObsCode.TextChanged -= tbxObsCode_TextChanged; tbxObjectDesign.TextChanged -= tbxObjectDesign_TextChanged; nudMeaIntervals.ValueChanged -= OnChunkSizeChanged; try { tbxObjectDesign.Text = m_DataProvider.ObjectDesignation; tbxObsCode.Text = m_DataProvider.ObservatoryCode; if (!string.IsNullOrWhiteSpace(m_DataProvider.CatalogueCode)) { tbxNetCode.Text = m_DataProvider.CatalogueCode; } if (m_DataProvider.ObservationDate.HasValue && m_DataProvider.ObservationDate.Value != DateTime.MinValue) { dtpDate.Value = m_DataProvider.ObservationDate.Value; } nudInstDelaySec.Value = m_DataProvider.InstrumentalDelaySec; nudPixelsPerArcSec.Value = m_DataProvider.ArsSecsInPixel > 0 ? (decimal)m_DataProvider.ArsSecsInPixel : DEFAULT_ARCSEC_PER_PIXEL; nudMeaIntervals.Value = CalculateOptimalChunks(m_DataProvider.NumberOfMeasurements); if (cbxErrorMethod.SelectedIndex < 1 && m_DataProvider.Measurements.Count() < 10) { // For smaller number of measurements by default use a solution error of StdDev / 2 // This appears to be working better cbxErrorMethod.SelectedIndex = (int)ErrorMethod.HalfStdDev; } } finally { nudMeaIntervals.ValueChanged += OnChunkSizeChanged; nudPixelsPerArcSec.ValueChanged += nudPixelsPerArcSec_ValueChanged; nudInstDelaySec.ValueChanged += nudInstDelaySec_ValueChanged; dtpDate.ValueChanged += dtpDate_ValueChanged; tbxObsCode.TextChanged += tbxObsCode_TextChanged; tbxObjectDesign.TextChanged += tbxObjectDesign_TextChanged; } cbxContraintPattern.SelectedIndex = 0; if (m_DataProvider.NumberOfMeasurements < 12) { cbxContraintPattern.Enabled = false; MessageBox.Show(this, "At least 12 data points are required to use constraint patterns. This file doesn't have enough data points and constraint patters have been disabled.", "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { cbxContraintPattern.Enabled = true; } m_LoadingData = false; Recalculate(); } } }
public void Calculate( IMeasurementPositionProvider provider, ReductionSettings settings) { if (provider != null) { m_Chunks.Clear(); int numChunks = settings.NumberOfChunks; if (numChunks < 1) { numChunks = 1; } m_RemoveOutliers = settings.RemoveOutliers; m_OutliersSigmaThreashold = settings.OutliersSigmaThreashold; m_AllEntries = provider.Measurements.Where(x => x.TimeOfDayUTC != 0).ToList(); m_AllEntries.ForEach(x => { x.ConstraintPoint = false; x.MidConstraintPoint = false; }); double instDelayTimeOfDay = ((double)settings.InstrumentalDelaySec / SECONDS_IN_A_DAY); int defPoints = 0; int numEntriesPerChunk = m_AllEntries.Count / numChunks; int startMidConIdx = 0; switch (settings.ConstraintPattern) { case 1: case 2: defPoints = 3; numEntriesPerChunk = (m_AllEntries.Count - defPoints * 2 * numChunks) / numChunks; break; case 3: defPoints = 3; numEntriesPerChunk = (m_AllEntries.Count - defPoints * 2 * numChunks) / numChunks; startMidConIdx = (int)Math.Round((m_AllEntries.Count - defPoints * numChunks * 1.0) / 2.0); var midConstPoints = m_AllEntries.Skip(startMidConIdx).Take(defPoints * numChunks).ToList(); midConstPoints.ForEach(x => { x.ConstraintPoint = true; x.MidConstraintPoint = true; }); break; } int lastChunkFill = (m_AllEntries.Count - defPoints * numChunks - 1) - ((numChunks) * numEntriesPerChunk - 1 + defPoints * numChunks); for (int i = 0; i < numChunks; i++) { int firstId = i * numEntriesPerChunk + defPoints * numChunks; int lastId = (i + 1) * numEntriesPerChunk - 1 + defPoints * numChunks; if (lastId > (numChunks - 1) * numEntriesPerChunk + defPoints * numChunks) { lastId = m_AllEntries.Count - defPoints * numChunks - 1; } var chunkPosExtractor = new FastMotionChunkPositionExtractor(firstId, lastId); var chunkEntries = m_AllEntries.Skip(firstId).Take(lastId - firstId + 1).Where(x => !x.ConstraintPoint).ToList(); if (settings.ConstraintPattern == 1) { for (int j = 0; j < defPoints; j++) { var d1 = m_AllEntries[i * defPoints + j]; d1.ConstraintPoint = true; chunkEntries.Insert(j, d1); var d2 = m_AllEntries[(numEntriesPerChunk + defPoints) * numChunks + i * defPoints + j + lastChunkFill]; d2.ConstraintPoint = true; chunkEntries.Add(d2); } } else if (settings.ConstraintPattern == 2) { for (int j = 0; j < defPoints; j++) { var d1 = m_AllEntries[i + numChunks * j]; d1.ConstraintPoint = true; chunkEntries.Insert(j, d1); var d2 = m_AllEntries[(numEntriesPerChunk + defPoints) * numChunks + i + numChunks * j + lastChunkFill]; d2.ConstraintPoint = true; chunkEntries.Add(d2); } } else if (settings.ConstraintPattern == 3) { for (int j = 0; j < defPoints; j++) { var d1 = m_AllEntries[i + numChunks * j]; d1.ConstraintPoint = true; chunkEntries.Insert(j, d1); var d3 = m_AllEntries[(numEntriesPerChunk + defPoints) * numChunks + i + numChunks * j + lastChunkFill]; d3.ConstraintPoint = true; chunkEntries.Add(d3); } var midIdx = chunkEntries.Count / 2; for (int j = 0; j < defPoints; j++) { var d2 = m_AllEntries[startMidConIdx + i + numChunks * j]; d2.ConstraintPoint = true; chunkEntries.Insert(midIdx + j, d2); } } if (chunkEntries.Count > 2) { chunkPosExtractor.Calculate( chunkEntries.ToArray(), settings.Weighting, settings.RemoveOutliers, m_OutliersSigmaThreashold, instDelayTimeOfDay, settings.BestPositionUncertaintyArcSec, settings.FactorInPositionalUncertainty, settings.ErrorMethod, settings.SmallestReportedUncertaintyArcSec); m_Chunks.Add(chunkPosExtractor); } } } }