public void SetMasterSpectra(MasterSpectra masterSpectra)
 {
     m_MasterSpectra = masterSpectra;
 }
        public void NextFrame(int frameNo, MovementType movementType, bool isLastFrame, AstroImage astroImage, int firstFrameInIntegrationPeriod, string fileName)
        {
            m_CurrentFrameNo = frameNo;

            if (m_OperationState == SpectroscopyState.RunningMeasurements)
            {
                if (m_FirstMeasuredFrame == null)
                {
                    m_FirstMeasuredFrame = m_CurrentFrameNo;
                    if (m_VideoController.HasEmbeddedTimeStamps()) m_FirstFrameTimeStamp = m_VideoController.GetCurrentFrameTime();
                    else if (m_VideoController.HasSystemTimeStamps()) m_FirstFrameTimeStamp = m_VideoController.GetCurrentFrameTime();
                    m_FrameBitmapPixels = astroImage.Pixelmap.DisplayBitmapPixels;
                }

                m_Tracker.NextFrame(frameNo, astroImage);
                if (m_Tracker.IsTrackedSuccessfully)
                {
                    TrackedObject trackedStar = m_Tracker.TrackedStar;
                    SelectedStar = trackedStar.Center;

                    m_Reader = new SpectraReader(astroImage, SelectedStarBestAngle, m_SpectroscopyController.SpectraReductionContext.PixelValueCoefficient);

                    Spectra thisFrameSpectra = m_Reader.ReadSpectra(
                        trackedStar.ThisFrameX,
                        trackedStar.ThisFrameY,
                        m_SpectroscopyController.SpectraReductionContext.MeasurementAreaWing,
                        m_SpectroscopyController.SpectraReductionContext.BackgroundAreaWing,
                        m_SpectroscopyController.SpectraReductionContext.BackgroundAreaGap,
                        m_SpectroscopyController.SpectraReductionContext.BackgroundMethod);

                    thisFrameSpectra.ZeroOrderFWHM = trackedStar.PSFFit != null ? (float)trackedStar.PSFFit.FWHM : float.NaN;

                    m_AllFramesSpectra.Add(thisFrameSpectra);
                }

                if (isLastFrame || m_CancelMeasurementsRequested || m_AllFramesSpectra.Count >= m_SpectroscopyController.SpectraReductionContext.FramesToMeasure)
                {
                    m_FramePlayer.Stop();

                    m_MasterSpectra = m_SpectroscopyController.ComputeResult(
                        m_AllFramesSpectra,
                        m_SpectroscopyController.SpectraReductionContext.FrameCombineMethod,
                        m_SpectroscopyController.SpectraReductionContext.UseFineAdjustments,
                        m_SpectroscopyController.SpectraReductionContext.AlignmentAbsorptionLinePos);

                    m_AllFramesSpectra.Clear();

                    m_MasterSpectra.MeasurementInfo = m_SpectroscopyController.GetMeasurementInfo();
                    m_MasterSpectra.MeasurementInfo.FirstMeasuredFrame = m_FirstMeasuredFrame.Value;
                    m_MasterSpectra.MeasurementInfo.LastMeasuredFrame = m_CurrentFrameNo;
                    m_MasterSpectra.MeasurementInfo.FirstFrameTimeStamp = m_FirstFrameTimeStamp;
                    if (m_VideoController.HasEmbeddedTimeStamps())
                        m_MasterSpectra.MeasurementInfo.LastFrameTimeStamp = m_VideoController.GetCurrentFrameTime();
                    else if (m_VideoController.HasSystemTimeStamps())
                        m_MasterSpectra.MeasurementInfo.LastFrameTimeStamp = m_VideoController.GetCurrentFrameTime();

                    FrameStateData frameStatus = m_VideoController.GetCurrentFrameState();
                    m_MasterSpectra.MeasurementInfo.Gain = frameStatus.Gain;
                    m_MasterSpectra.MeasurementInfo.ExposureSeconds = m_SpectroscopyController.SpectraReductionContext.ExposureSeconds;

                    m_MasterSpectra.MeasurementInfo.FrameBitmapPixels = m_FrameBitmapPixels;

                    m_SpectroscopyController.PopulateMasterSpectraObservationDetails(m_MasterSpectra);

                    m_OperationState = SpectroscopyState.DisplayingMeasurements;
                    m_ControlPanel.MeasurementsFinished();
                    DisplaySpectra();
                }

                Application.DoEvents();
            }
        }
Beispiel #3
0
        private void DoNewMasterSpectraReduction()
        {
            MasterSpectra newSpectraReduction =
                m_SpectroscopyController.ComputeResult(m_Spectra.RawMeasurements,
                    m_Spectra.MeasurementInfo.FrameCombineMethod,
                    m_Spectra.MeasurementInfo.UseFineAdjustments,
                    m_Spectra.MeasurementInfo.AlignmentAbsorptionLinePos,
                    hsbSlidingWindow.Value + 1,
                    50);

            newSpectraReduction.RawMeasurements.Clear();
            newSpectraReduction.RawMeasurements.AddRange(m_Spectra.RawMeasurements);
            newSpectraReduction.MeasurementInfo = m_Spectra.MeasurementInfo;
            newSpectraReduction.Calibration = m_Spectra.Calibration;

            m_Spectra = newSpectraReduction;
            m_StateManager.SetMasterSpectra(newSpectraReduction);
            PlotSpectra();
        }
Beispiel #4
0
 public SpectraCalibrator(MasterSpectra masterSpectra)
 {
     m_MasterSpectra         = masterSpectra;
     m_WavelengthCalibration = null;
     Reset();
 }
Beispiel #5
0
        public static void Save(string fileName, SpectraFileHeader header, MasterSpectra data)
        {
            using (FileStream fileStr = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            using (DeflateStream deflateStream = new DeflateStream(fileStr, CompressionMode.Compress, true))
            using (BinaryWriter writer = new BinaryWriter(deflateStream))
            {
                writer.Write(SPECTRA_FILE_VERSION);

                header.WriteTo(writer);

                if (data != null)
                {
                    ThreadingHelper.RunTaskWaitAndDoEvents(
                        delegate()
                            {
                                data.WriteTo(writer);
                            },
                            150);
                }

                writer.Flush();
                deflateStream.Flush();
            }
        }
Beispiel #6
0
        internal void SetMasterSpectra(MasterSpectra masterSpectra, string fileName)
        {
            m_Spectra = masterSpectra;
            m_StateManager.SetMasterSpectra(masterSpectra);
            hsbSlidingWindow.Minimum = 0;
            hsbSlidingWindow.Maximum = Math.Max(1, m_Spectra.RawMeasurements.Count - 50);
            hsbSlidingWindow.Value = 0;

            if (masterSpectra.ProcessingInfo.GaussianBlur10Fwhm.HasValue)
                m_StateManager.ApplyGaussianBlur(masterSpectra.ProcessingInfo.GaussianBlur10Fwhm.Value / 10.0f);

            if (masterSpectra.IsCalibrated())
            {
                SpectraCalibrator calibrator = m_SpectroscopyController.GetSpectraCalibrator();
                calibrator.Reset();

                if (calibrator.LoadCalibration(masterSpectra.Calibration))
                    m_StateManager.ChangeState<SpectraViewerStateCalibrated>();
            }
            else if (m_SpectroscopyController.HasCalibratedConfiguration())
            {
                if (m_SpectroscopyController.ScaleSpectraByZeroOrderImagePosition())
                    m_StateManager.ChangeState<SpectraViewerStateCalibrated>();
            }

            if (fileName != null)
                Text = string.Format("Spectra Viewer - {0}", Path.GetFileName(fileName));
            else
                Text = "Spectra Viewer";
        }
        internal void PopulateMasterSpectraObservationDetails(MasterSpectra spectra)
        {
            var dict = m_VideoController.GetVideoFileTags();

            float lng = float.NaN;
            float lat = float.NaN;
            float ra = float.NaN;
            float dec = float.NaN;
            DateTime? centralTime = null;

            if (spectra.ObservationInfo == null) spectra.ObservationInfo = new ObservationInfo();
            spectra.ObservationInfo.Reset();

            if (dict.ContainsKey("Longitude"))
            {
                if (float.TryParse(dict["Longitude"], NumberStyles.Float, CultureInfo.InvariantCulture, out lng))
                    spectra.ObservationInfo.AddProperty("Longitude", lng.ToString("0.0000", CultureInfo.InvariantCulture));
            }
            if (dict.ContainsKey("Latitude"))
            {
                if (float.TryParse(dict["Latitude"], NumberStyles.Float, CultureInfo.InvariantCulture, out lat))
                    spectra.ObservationInfo.AddProperty("Latitude", lat.ToString("0.0000", CultureInfo.InvariantCulture));
            }
            if (dict.ContainsKey("RA"))
            {
                if (float.TryParse(dict["RA"], NumberStyles.Float, CultureInfo.InvariantCulture, out ra))
                    spectra.ObservationInfo.AddProperty("RA", ra.ToString("0.0000", CultureInfo.InvariantCulture), "hours");
            }
            if (dict.ContainsKey("DEC"))
            {
                if (float.TryParse(dict["DEC"], NumberStyles.Float, CultureInfo.InvariantCulture, out dec))
                    spectra.ObservationInfo.AddProperty("DEC", dec.ToString("0.0000", CultureInfo.InvariantCulture), "degrees");
            }
            if (spectra.MeasurementInfo.FirstFrameTimeStamp.HasValue && spectra.MeasurementInfo.LastFrameTimeStamp.HasValue)
            {
                centralTime = new DateTime((spectra.MeasurementInfo.FirstFrameTimeStamp.Value.Ticks + spectra.MeasurementInfo.LastFrameTimeStamp.Value.Ticks) / 2);
                double jd = JulianDayHelper.JDUtcAtDate(centralTime.Value);
                spectra.ObservationInfo.AddProperty("JD", jd.ToString("0.00000", CultureInfo.InvariantCulture), "UT");
            }

            if (!float.IsNaN(lng) && !float.IsNaN(lat) && !float.IsNaN(ra) && !float.IsNaN(dec) && centralTime.HasValue)
            {
                var extCalc = new AtmosphericExtinctionCalculator(ra, dec, lng, lat, 0);
                double airMass;
                double altitudeDeg;
                extCalc.CalculateExtinction(centralTime.Value, out altitudeDeg, out airMass);

                spectra.ObservationInfo.AddProperty("X", airMass.ToString("0.000", CultureInfo.InvariantCulture), "air mass");
            }

            if (!float.IsNaN(spectra.ZeroOrderFWHM)) spectra.ObservationInfo.AddProperty("FWHM", spectra.ZeroOrderFWHM.ToString("0.00"), "zero order image FWHM");

            if (!float.IsNaN(spectra.MeasurementInfo.Gain)) spectra.ObservationInfo.AddProperty("Gain", spectra.MeasurementInfo.Gain.ToString("0.0", CultureInfo.InvariantCulture), "dB");
            if (!float.IsNaN(spectra.MeasurementInfo.ExposureSeconds)) spectra.ObservationInfo.AddProperty("Exposure", spectra.MeasurementInfo.ExposureSeconds.ToString("0.000", CultureInfo.InvariantCulture), "sec");

            if (dict.ContainsKey("ObjectName")) spectra.ObservationInfo.AddProperty("Target", dict["ObjectName"]);
            if (dict.ContainsKey("Instrument")) spectra.ObservationInfo.AddProperty("Camera", dict["Instrument"]);
            if (dict.ContainsKey("Telescope")) spectra.ObservationInfo.AddProperty("Telescope", dict["Telescope"]);
            if (dict.ContainsKey("Recorder")) spectra.ObservationInfo.AddProperty("Recorder", dict["Recorder"]);
            if (dict.ContainsKey("Observer")) spectra.ObservationInfo.AddProperty("Observer", dict["Observer"]);

            if (spectra.IsCalibrated())
            {
                if (spectra.Calibration.PolynomialOrder == 1)
                    spectra.ObservationInfo.AddProperty("WavelengthCalibration", string.Format("1-st order[{0},{1}]", spectra.Calibration.A, spectra.Calibration.B));
                else if (spectra.Calibration.PolynomialOrder == 2)
                    spectra.ObservationInfo.AddProperty("WavelengthCalibration", string.Format("2-nd order[{0},{1},{2}]", spectra.Calibration.A, spectra.Calibration.B, spectra.Calibration.C));
                else if (spectra.Calibration.PolynomialOrder == 3)
                    spectra.ObservationInfo.AddProperty("WavelengthCalibration", string.Format("3-rd order[{0},{1},{2},{3}]", spectra.Calibration.A, spectra.Calibration.B, spectra.Calibration.C, spectra.Calibration.D));
                else if (spectra.Calibration.PolynomialOrder == 4)
                    spectra.ObservationInfo.AddProperty("WavelengthCalibration", string.Format("4-th order[{0},{1},{2},{3},{4}]", spectra.Calibration.A, spectra.Calibration.B, spectra.Calibration.C, spectra.Calibration.D, spectra.Calibration.E));

                spectra.ObservationInfo.AddProperty("Dispersion", spectra.Calibration.Dispersion.ToString("0.00", CultureInfo.InvariantCulture), "A/pix");
            }
        }
        internal string ExportToDat(MasterSpectra spectra)
        {
            SpectraCalibrator calibrator = GetSpectraCalibrator();
            var bld = new StringBuilder();

            AddDatExportHeader(bld, spectra);

            foreach (SpectraPoint point in spectra.Points)
            {
                float wavelength = calibrator.ResolveWavelength(point.PixelNo);
                if (wavelength < 0) continue;
                bld.AppendFormat("{0}\t{1}\r\n", wavelength, point.RawValue);
            }

            return bld.ToString();
        }
        internal void DisplaySpectra(MasterSpectra masterSpectra, TangraConfig.PersistedConfiguration configuration, TangraConfig.SpectraViewDisplaySettings displaySettings, string fileName = null)
        {
            EnsureViewSpectraForm(displaySettings);

            m_CurrentSpectra = masterSpectra;
            m_Configuration = configuration;
            m_SpectraCalibrator = new SpectraCalibrator(masterSpectra);

            m_ViewSpectraForm.SetMasterSpectra(masterSpectra, fileName);
            m_ViewSpectraForm.StartPosition = FormStartPosition.CenterParent;
            m_ViewSpectraForm.Show(m_MainFormView);
        }
        internal MasterSpectra ComputeResult(
            List<Spectra> allFramesSpectra, 
            PixelCombineMethod frameCombineMethod, 
            bool useFineAdjustments, 
            int? alignmentAbsorptionLinePos,
            int startingFrameIndex = 1,
            int? frameCountToProcess = null)
        {
            var masterSpectra = new MasterSpectra();

            if (allFramesSpectra.Count > 0)
            {
                masterSpectra.ZeroOrderPixelNo = allFramesSpectra[0].ZeroOrderPixelNo;
                masterSpectra.ZeroOrderFWHM = allFramesSpectra[0].ZeroOrderFWHM;
                masterSpectra.SignalAreaWidth = allFramesSpectra[0].SignalAreaWidth;
                masterSpectra.BackgroundAreaHalfWidth = allFramesSpectra[0].BackgroundAreaHalfWidth;
                masterSpectra.BackgroundAreaGap = allFramesSpectra[0].BackgroundAreaGap;
                masterSpectra.MaxPixelValue = allFramesSpectra[0].MaxPixelValue;
                masterSpectra.MaxSpectraValue = allFramesSpectra[0].MaxSpectraValue;
                for (int i = 0; i < allFramesSpectra[0].Points.Count; i++)
                    masterSpectra.Points.Add(new SpectraPoint(allFramesSpectra[0].Points[i]));

                int pixelArrWidth = allFramesSpectra[0].Pixels.GetLength(0);
                int pixelArrHeight = allFramesSpectra[0].Pixels.GetLength(1);

                masterSpectra.InitialisePixelArray(pixelArrWidth);
                masterSpectra.CombinedMeasurements = 1;

                var originalMasterPoints = new List<SpectraPoint>();
                originalMasterPoints.AddRange(masterSpectra.Points);

                if (frameCountToProcess == null && startingFrameIndex == 1)
                    frameCountToProcess = allFramesSpectra.Count;

                if (frameCombineMethod == PixelCombineMethod.Average)
                {
                    float fwhmSum = 0;
                    int fwhmCount = 0;

                    for (int i = startingFrameIndex; i < startingFrameIndex + frameCountToProcess - 1; i++)
                    {
                        if (i < 0 || i > allFramesSpectra.Count - 1) continue;

                        Spectra nextSpectra = allFramesSpectra[i];
                        masterSpectra.RawMeasurements.Add(nextSpectra);
                        if (!float.IsNaN(nextSpectra.ZeroOrderFWHM))
                        {
                            fwhmSum += nextSpectra.ZeroOrderFWHM;
                            fwhmCount++;
                        }

                        int nextSpectraFirstPixelNo = nextSpectra.Points[0].PixelNo;
                        int deltaIndex = nextSpectra.ZeroOrderPixelNo - masterSpectra.ZeroOrderPixelNo + masterSpectra.Points[0].PixelNo - nextSpectraFirstPixelNo;

                        int lineAlignOffset = 0;
                        if (alignmentAbsorptionLinePos.HasValue)
                        {
                            int roughLinePos = deltaIndex + alignmentAbsorptionLinePos.Value;
                            List<SpectraPoint> pointsInRegion = nextSpectra.Points.Where(x => Math.Abs(x.PixelNo - roughLinePos) < 10).ToList();
                            float[] arrPixelNo = pointsInRegion.Select(x => (float)x.PixelNo).ToArray();
                            float[] arrPixelValues = pointsInRegion.Select(x => x.RawValue).ToArray();
                            Array.Sort(arrPixelValues, arrPixelNo);
                            lineAlignOffset = (int)arrPixelNo[0] - roughLinePos;
                        }

                        int bestOffset = 0;

                        if (useFineAdjustments)
                        {
                            float bestOffsetValue = float.MaxValue;

                            for (int probeOffset = -2; probeOffset <= 2; probeOffset++)
                            {
                                float currOffsetValue = 0;
                                for (int j = 0; j < masterSpectra.Points.Count; j++)
                                {
                                    int indexNextSpectra = deltaIndex + j + probeOffset + lineAlignOffset;
                                    if (indexNextSpectra >= 0 && indexNextSpectra < nextSpectra.Points.Count)
                                    {
                                        currOffsetValue += Math.Abs(originalMasterPoints[j].RawValue - nextSpectra.Points[indexNextSpectra].RawValue);
                                    }
                                }

                                if (currOffsetValue < bestOffsetValue)
                                {
                                    bestOffsetValue = currOffsetValue;
                                    bestOffset = probeOffset;
                                }
                            }
                        }

                        for (int j = 0; j < masterSpectra.Points.Count; j++)
                        {
                            int indexNextSpectra = deltaIndex + j + bestOffset + lineAlignOffset;
                            if (indexNextSpectra >= 0 && indexNextSpectra < nextSpectra.Points.Count)
                            {
                                masterSpectra.Points[j].RawValue += nextSpectra.Points[indexNextSpectra].RawValue;
                                masterSpectra.Points[j].RawSignal += nextSpectra.Points[indexNextSpectra].RawSignal;
                                masterSpectra.Points[j].RawSignalPixelCount += nextSpectra.Points[indexNextSpectra].RawSignalPixelCount;

                                for (int h = 0; h < pixelArrHeight; h++)
                                {
                                    masterSpectra.Pixels[j, h] += nextSpectra.Pixels[indexNextSpectra, h];
                                }
                            }
                        }
                    }

                    masterSpectra.ZeroOrderFWHM = fwhmSum / fwhmCount;

                    // Normalize per row width
                    for (int i = 0; i < masterSpectra.Points.Count; i++)
                    {
                        if (Math.Abs(masterSpectra.Points[i].RawSignalPixelCount) < 0.0001)
                        {
                            masterSpectra.Points[i].RawValue = 0;
                            for (int h = 0; h < pixelArrHeight; h++) masterSpectra.Pixels[i, h] = 0;
                        }
                        else
                        {
                            masterSpectra.Points[i].RawValue = masterSpectra.Points[i].RawValue * masterSpectra.SignalAreaWidth / masterSpectra.Points[i].RawSignalPixelCount;
                            for (int h = 0; h < pixelArrHeight; h++) masterSpectra.Pixels[i, h] /= masterSpectra.Points[i].RawSignalPixelCount;
                        }

                    }
                }
                else if (frameCombineMethod == PixelCombineMethod.Median)
                {
                    var valueLists = new List<float>[masterSpectra.Points.Count];
                    for (int j = 0; j < masterSpectra.Points.Count; j++) valueLists[j] = new List<float>();

                    var signalLists = new List<float>[masterSpectra.Points.Count];
                    for (int j = 0; j < masterSpectra.Points.Count; j++) signalLists[j] = new List<float>();

                    var fwhmList = new List<float>();
                    for (int j = 0; j < masterSpectra.Points.Count; j++) fwhmList.Add(float.NaN);

                    for (int i = startingFrameIndex; i < startingFrameIndex + frameCountToProcess - 1; i++)
                    {
                        if (i < 0 || i > allFramesSpectra.Count - 1) continue;

                        Spectra nextSpectra = allFramesSpectra[i];
                        masterSpectra.RawMeasurements.Add(nextSpectra);

                        int nextSpectraFirstPixelNo = nextSpectra.Points[0].PixelNo;
                        int deltaIndex = nextSpectra.ZeroOrderPixelNo - masterSpectra.ZeroOrderPixelNo + masterSpectra.Points[0].PixelNo - nextSpectraFirstPixelNo;

                        int lineAlignOffset = 0;
                        if (alignmentAbsorptionLinePos.HasValue)
                        {
                            int roughLinePos = deltaIndex + alignmentAbsorptionLinePos.Value;
                            List<SpectraPoint> pointsInRegion = nextSpectra.Points.Where(x => Math.Abs(x.PixelNo - roughLinePos) < 10).ToList();
                            float[] arrPixelNo = pointsInRegion.Select(x => (float)x.PixelNo).ToArray();
                            float[] arrPixelValues = pointsInRegion.Select(x => x.RawValue).ToArray();
                            Array.Sort(arrPixelValues, arrPixelNo);
                            lineAlignOffset = (int)arrPixelNo[0] - roughLinePos;
                        }

                        int bestOffset = 0;

                        if (useFineAdjustments)
                        {
                            float bestOffsetValue = float.MaxValue;

                            for (int probeOffset = -2; probeOffset <= 2; probeOffset++)
                            {
                                float currOffsetValue = 0;
                                for (int j = 0; j < masterSpectra.Points.Count; j++)
                                {
                                    int indexNextSpectra = deltaIndex + j + probeOffset + lineAlignOffset;
                                    if (indexNextSpectra >= 0 && indexNextSpectra < nextSpectra.Points.Count)
                                    {
                                        currOffsetValue += Math.Abs(originalMasterPoints[j].RawValue - nextSpectra.Points[indexNextSpectra].RawValue);
                                    }
                                }

                                if (currOffsetValue < bestOffsetValue)
                                {
                                    bestOffsetValue = currOffsetValue;
                                    bestOffset = probeOffset;
                                }
                            }
                        }

                        for (int j = 0; j < masterSpectra.Points.Count; j++)
                        {
                            fwhmList[j] = nextSpectra.ZeroOrderFWHM;

                            int indexNextSpectra = deltaIndex + j + bestOffset + lineAlignOffset;
                            if (indexNextSpectra >= 0 && indexNextSpectra < nextSpectra.Points.Count)
                            {
                                valueLists[j].Add(nextSpectra.Points[indexNextSpectra].RawValue);
                                signalLists[j].Add(nextSpectra.Points[indexNextSpectra].RawValue);

                                for (int h = 0; h < pixelArrHeight; h++)
                                {
                                    masterSpectra.Pixels[j, h] += nextSpectra.Pixels[indexNextSpectra, h];
                                }
                            }
                        }
                    }

                    fwhmList.Sort();
                    masterSpectra.ZeroOrderFWHM = fwhmList.Count == 0 ? float.NaN : fwhmList[fwhmList.Count / 2];

                    for (int i = 0; i < masterSpectra.Points.Count; i++)
                    {
                        valueLists[i].Sort();
                        signalLists[i].Sort();

                        masterSpectra.Points[i].RawValue = valueLists[i].Count == 0 ? 0 : valueLists[i][valueLists[i].Count / 2];
                        masterSpectra.Points[i].RawSignal = signalLists[i].Count == 0 ? 0 : signalLists[i][signalLists[i].Count / 2];
                        masterSpectra.Points[i].RawSignalPixelCount = signalLists[i].Count;

                        if (Math.Abs(masterSpectra.Points[i].RawSignalPixelCount) < 0.0001)
                            for (int h = 0; h < pixelArrHeight; h++) masterSpectra.Pixels[i, h] = 0;
                        else
                            for (int h = 0; h < pixelArrHeight; h++) masterSpectra.Pixels[i, h] /= masterSpectra.Points[i].RawSignalPixelCount;
                    }
                }
            }

            return masterSpectra;
        }
        internal void AddDatExportHeader(StringBuilder output, MasterSpectra spectra)
        {
            if (spectra.ObservationInfo.IsEmpty)
                PopulateMasterSpectraObservationDetails(spectra);

            string[] propNames = spectra.ObservationInfo.GetPropertyNames();

            foreach (string name in propNames)
            {
                string value = spectra.ObservationInfo.GetProperty(name);
                string comment = spectra.ObservationInfo.GetPropertyComment(name);

                if (!string.IsNullOrEmpty(comment))
                    output.AppendFormat("# {0}={1} #{2}\r\n", name, value, comment);
                else
                    output.AppendFormat("# {0}={1}\r\n", name, value);
            }
            output.AppendLine();
        }