public Spectra ReadSpectra(float x0, float y0, int halfWidth, int bgHalfWidth, int bgGap, PixelCombineMethod bgMethod) { var rv = new Spectra() { SignalAreaWidth = 2 * halfWidth, BackgroundAreaHalfWidth = bgHalfWidth, BackgroundAreaGap = bgGap, MaxPixelValue = m_Image.Pixelmap.MaxSignalValue }; int xFrom = int.MaxValue; int xTo = int.MinValue; // Find the destination pixel range at the destination horizontal PointF p1 = m_Mapper.GetDestCoords(x0, y0); rv.ZeroOrderPixelNo = (int)Math.Round(p1.X); for (float x = p1.X - m_Mapper.MaxDestDiagonal; x < p1.X + m_Mapper.MaxDestDiagonal; x++) { PointF p = m_Mapper.GetSourceCoords(x, p1.Y); if (m_SourceVideoFrame.Contains(p)) { int xx = (int)x; if (xx < xFrom) { xFrom = xx; } if (xx > xTo) { xTo = xx; } } } m_BgValues = new float[xTo - xFrom + 1]; m_BgPixelCount = new uint[xTo - xFrom + 1]; m_BgValuesList = new List <float> [xTo - xFrom + 1]; rv.InitialisePixelArray(xTo - xFrom + 1); // Get all readings in the range for (int x = xFrom; x <= xTo; x++) { var point = new SpectraPoint(); point.PixelNo = x; point.RawSignalPixelCount = 0; for (int z = -halfWidth; z <= halfWidth; z++) { PointF p = m_Mapper.GetSourceCoords(x, p1.Y + z); int xx = (int)Math.Round(p.X); int yy = (int)Math.Round(p.Y); if (m_SourceVideoFrame.Contains(xx, yy)) { float sum = 0; int numPoints = 0; for (float kx = -0.4f; kx < 0.5f; kx += 0.2f) { for (float ky = -0.4f; ky < 0.5f; ky += 0.2f) { p = m_Mapper.GetSourceCoords(x + kx, p1.Y + ky + z); int xxx = (int)Math.Round(p.X); int yyy = (int)Math.Round(p.Y); if (m_SourceVideoFrame.Contains(xxx, yyy)) { sum += (m_Image.Pixelmap[xxx, yyy] * m_PixelValueCoeff); numPoints++; } } } float destPixVal = (sum / numPoints); point.RawValue += destPixVal; point.RawSignalPixelCount++; rv.Pixels[x - xFrom, z + bgHalfWidth + bgGap + halfWidth - 1] = destPixVal; } } point.RawSignal = point.RawValue; rv.Points.Add(point); #region Reads background if (bgMethod == PixelCombineMethod.Average) { ReadAverageBackgroundForPixelIndex(halfWidth, bgHalfWidth, bgGap, x, p1.Y, x - xFrom); } else if (bgMethod == PixelCombineMethod.Median) { ReadMedianBackgroundForPixelIndex(halfWidth, bgHalfWidth, bgGap, x, p1.Y, x - xFrom); } #endregion } // Apply background for (int i = 0; i < rv.Points.Count; i++) { SpectraPoint point = rv.Points[i]; if (bgMethod == PixelCombineMethod.Average) { point.RawBackgroundPerPixel = GetAverageBackgroundValue(point.PixelNo, xFrom, xTo, bgHalfWidth); } else if (bgMethod == PixelCombineMethod.Median) { point.RawBackgroundPerPixel = GetMedianBackgroundValue(point.PixelNo, xFrom, xTo, bgHalfWidth); } for (int z = -halfWidth - bgGap - bgHalfWidth + 1; z < -halfWidth - bgGap; z++) { rv.Pixels[i, z + bgHalfWidth + bgGap + halfWidth - 1] = point.RawBackgroundPerPixel; } for (int z = halfWidth + bgGap + 1; z < halfWidth + bgGap + bgHalfWidth + 1; z++) { rv.Pixels[i, z + bgHalfWidth + bgGap + halfWidth - 1] = point.RawBackgroundPerPixel; } point.RawValue -= point.RawBackgroundPerPixel * point.RawSignalPixelCount; if (point.RawValue < 0 && !TangraConfig.Settings.Spectroscopy.AllowNegativeValues) { point.RawValue = 0; } } rv.MaxSpectraValue = (uint)Math.Ceiling(rv.Points.Where(x => x.PixelNo > rv.ZeroOrderPixelNo + 20).Select(x => x.RawValue).Max()); return(rv); }
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); }
public Spectra ReadSpectra(float x0, float y0, int halfWidth, int bgHalfWidth, int bgGap, PixelCombineMethod bgMethod) { var rv = new Spectra() { SignalAreaWidth = 2 * halfWidth, BackgroundAreaHalfWidth = bgHalfWidth, BackgroundAreaGap = bgGap, MaxPixelValue = m_Image.Pixelmap.MaxSignalValue }; int xFrom = int.MaxValue; int xTo = int.MinValue; // Find the destination pixel range at the destination horizontal PointF p1 = m_Mapper.GetDestCoords(x0, y0); rv.ZeroOrderPixelNo = (int)Math.Round(p1.X); for (float x = p1.X - m_Mapper.MaxDestDiagonal; x < p1.X + m_Mapper.MaxDestDiagonal; x++) { PointF p = m_Mapper.GetSourceCoords(x, p1.Y); if (m_SourceVideoFrame.Contains(p)) { int xx = (int) x; if (xx < xFrom) xFrom = xx; if (xx > xTo) xTo = xx; } } m_BgValues = new float[xTo - xFrom + 1]; m_BgPixelCount = new uint[xTo - xFrom + 1]; m_BgValuesList = new List<float>[xTo - xFrom + 1]; rv.InitialisePixelArray(xTo - xFrom + 1); // Get all readings in the range for (int x = xFrom; x <= xTo; x++) { var point = new SpectraPoint(); point.PixelNo = x; point.RawSignalPixelCount = 0; for (int z = -halfWidth; z <= halfWidth; z++) { PointF p = m_Mapper.GetSourceCoords(x, p1.Y +z); int xx = (int)Math.Round(p.X); int yy = (int)Math.Round(p.Y); if (m_SourceVideoFrame.Contains(xx, yy)) { float sum = 0; int numPoints = 0; for (float kx = -0.4f; kx < 0.5f; kx+=0.2f) for (float ky = -0.4f; ky < 0.5f; ky += 0.2f) { p = m_Mapper.GetSourceCoords(x + kx, p1.Y + ky + z); int xxx = (int)Math.Round(p.X); int yyy = (int)Math.Round(p.Y); if (m_SourceVideoFrame.Contains(xxx, yyy)) { sum += (m_Image.Pixelmap[xxx, yyy] * m_PixelValueCoeff); numPoints++; } } float destPixVal = (sum/numPoints); point.RawValue += destPixVal; point.RawSignalPixelCount++; rv.Pixels[x - xFrom, z + bgHalfWidth + bgGap + halfWidth - 1] = destPixVal; } } point.RawSignal = point.RawValue; rv.Points.Add(point); #region Reads background if (bgMethod == PixelCombineMethod.Average) { ReadAverageBackgroundForPixelIndex(halfWidth, bgHalfWidth, bgGap, x, p1.Y, x - xFrom); } else if (bgMethod == PixelCombineMethod.Median) { ReadMedianBackgroundForPixelIndex(halfWidth, bgHalfWidth, bgGap, x, p1.Y, x - xFrom); } #endregion } // Apply background for (int i = 0; i < rv.Points.Count; i++) { SpectraPoint point = rv.Points[i]; if (bgMethod == PixelCombineMethod.Average) { point.RawBackgroundPerPixel = GetAverageBackgroundValue(point.PixelNo, xFrom, xTo, bgHalfWidth); } else if (bgMethod == PixelCombineMethod.Median) { point.RawBackgroundPerPixel = GetMedianBackgroundValue(point.PixelNo, xFrom, xTo, bgHalfWidth); } for (int z = -halfWidth - bgGap - bgHalfWidth + 1; z < -halfWidth - bgGap; z++) rv.Pixels[i, z + bgHalfWidth + bgGap + halfWidth - 1] = point.RawBackgroundPerPixel; for (int z = halfWidth + bgGap + 1; z < halfWidth + bgGap + bgHalfWidth + 1; z++) rv.Pixels[i, z + bgHalfWidth + bgGap + halfWidth - 1] = point.RawBackgroundPerPixel; point.RawValue -= point.RawBackgroundPerPixel * point.RawSignalPixelCount; if (point.RawValue < 0 && !TangraConfig.Settings.Spectroscopy.AllowNegativeValues) point.RawValue = 0; } rv.MaxSpectraValue = (uint)Math.Ceiling(rv.Points.Where(x => x.PixelNo > rv.ZeroOrderPixelNo + 20).Select(x => x.RawValue).Max()); return rv; }
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; }