예제 #1
0
        /// <summary>
        /// Return copy of the curve filtered according to the filter settings (shorter by double the filter size)
        /// </summary>
        public double[] GetFilteredYs(double[] curve)
        {
            if (curve == null)
            {
                return(null);
            }
            double[] filteredValues = ImageDataTools.GaussianFilter1d(curve, filterPx);
            int      padPoints      = filterPx * 2 + 1;

            double[] filteredYs = new double[curve.Length - 2 * padPoints];
            Array.Copy(filteredValues, padPoints, filteredYs, 0, filteredYs.Length);
            return(filteredYs);
        }
예제 #2
0
        /// <summary>
        /// Set the structure bounds around the brightest structure in the image.
        /// The 1D projected image of the green channel is used.
        /// Boundaries are placed where intensity drops to half the distance between the peak and the noise floor.
        /// Noise floor is defined as the 20-percentile of the 1D projected image.
        /// </summary>
        public void AutoStructure()
        {
            // determine the brightest column
            double[] columnIntensities = ImageDataTools.GetAverageLeftright(imgG);
            double   brightestValue    = 0;
            int      brightestIndex    = 0;

            for (int i = 0; i < columnIntensities.Length; i++)
            {
                if (columnIntensities[i] > brightestValue)
                {
                    brightestValue = columnIntensities[i];
                    brightestIndex = i;
                }
            }
            Log($"Brightest structure (G): {brightestValue} AFU at {brightestIndex}px");

            // determine the 20-percentile brightness (background fluorescence)
            double[] sortedIntensities = new double[columnIntensities.Length];
            Array.Copy(columnIntensities, sortedIntensities, columnIntensities.Length);
            Array.Sort(sortedIntensities);
            double noiseFloor = sortedIntensities[(int)(sortedIntensities.Length * .2)];

            Log($"Noise floor (G): {noiseFloor} AFU");

            // intensity cut-off is half-way to the noise floor
            double peakAboveNoise = brightestValue - noiseFloor;
            double cutOff         = (peakAboveNoise * .5) + noiseFloor;

            Log($"Cut-off (G): {cutOff} AFU");

            // start both structures at the brighest point, then walk away
            structure1 = brightestIndex;
            structure2 = brightestIndex;
            while (columnIntensities[structure1] > cutOff && structure1 > 0)
            {
                structure1--;
            }
            while (columnIntensities[structure2] > cutOff && structure2 < columnIntensities.Length - 1)
            {
                structure2++;
            }

            Log($"Automatic structure: {structure1}px - {structure2}px");
        }
예제 #3
0
        /// <summary>
        /// This is the primary analysis method for delta green and delta green over red calculations
        /// </summary>
        public void GenerateAnalysisCurves()
        {
            // determine mean pixel intensity over time between the structure markers
            var(structureIndex1, structureIndex2) = GetValidStructure(structure1, structure2);
            curveG = ImageDataTools.GetAverageTopdown(imgG, structureIndex1, structureIndex2);
            curveR = ImageDataTools.GetAverageTopdown(imgR, structureIndex1, structureIndex2);

            // create a dG channel by baseline subtracting just the green channel
            var(baselineIndex1, baselineIndex2) = GetValidBaseline(baseline1, baseline2);
            curveDeltaG = CreateBaselineSubtractedCurve(curveG, baselineIndex1, baselineIndex2);

            // create a d(G/R) curve by finding the G/R ratio then baseline subtracting that
            if (isRatiometric)
            {
                curveGoR      = CreateRatioCurve(curveG, curveR);
                curveDeltaGoR = CreateBaselineSubtractedCurve(curveGoR, baselineIndex1, baselineIndex2);
            }
        }
예제 #4
0
        /// <summary>
        /// Multi-scan linescans have multiple frames.
        /// Call this to load data for a specific frame.
        /// </summary>
        public void SetFrame(int frameNumber)
        {
            // error checking
            if (!isValid)
            {
                return;
            }
            int frameCount = Math.Max(pathsDataG.Length, pathsDataR.Length);

            if (frameNumber >= frameCount)
            {
                Log($"frame {frameNumber} cannot be called (max frame {frameCount - 1})");
                return;
            }

            // load data bitmaps and create ratio if needed
            if (pathsDataG.Length > 0)
            {
                imgG     = new ImageData(pathsDataG[frameNumber]);
                bmpDataG = imgG.GetBmpDisplay();
            }

            if (pathsDataR.Length > 0)
            {
                imgR     = new ImageData(pathsDataR[frameNumber]);
                bmpDataR = imgR.GetBmpDisplay();
            }

            if (bmpDataG != null && bmpDataR != null)
            {
                bmpDataM = ImageDataTools.Merge(imgR, imgG, imgR);

                double[] dataM = new double[imgG.data.Length];
                for (int i = 0; i < dataM.Length; i++)
                {
                    dataM[i] = imgG.data[i] / imgR.data[i];
                }
                imgM = new ImageData(dataM, imgG.width, imgG.height);
            }
        }
예제 #5
0
        public void UpdateGraphs(bool skipUpdatesIfBusy = true)
        {
            // use pretty colors
            Color blue               = System.Drawing.ColorTranslator.FromHtml("#1f77b4");
            Color lightBlue          = System.Drawing.ColorTranslator.FromHtml("#a2d1f2");
            Color red                = System.Drawing.ColorTranslator.FromHtml("#d62728");
            Color lightRed           = System.Drawing.ColorTranslator.FromHtml("#e63738");
            Color green              = System.Drawing.ColorTranslator.FromHtml("#2ca02c");
            Color lightGreen         = System.Drawing.ColorTranslator.FromHtml("#98df8a");
            Color colorBaselineMarks = System.Drawing.ColorTranslator.FromHtml("#666666");
            Color colorPeak          = System.Drawing.ColorTranslator.FromHtml("#d62728");
            Color colorZero          = System.Drawing.ColorTranslator.FromHtml("#000000");

            if (!lsFolder.isValid)
            {
                return;
            }

            if (skipUpdatesIfBusy && busyUpdating)
            {
                return;
            }
            else
            {
                busyUpdating = true;
            }

            // do the analysis
            lsFolder.GenerateAnalysisCurves();

            // update the structure profile plot
            double[] columnPixelIndices = new double[lsFolder.imgG.width];
            for (int i = 0; i < columnPixelIndices.Length; i++)
            {
                columnPixelIndices[i] = i;
            }
            formsPlot2.plt.Clear();
            if ((cbR.Enabled && cbR.Checked))
            {
                double[] columnBrightnessR = ImageDataTools.GetAverageLeftright(lsFolder.imgR);
                formsPlot2.plt.PlotScatter(columnPixelIndices, columnBrightnessR, markerSize: 0, color: red);
            }
            if ((cbG.Enabled && cbG.Checked))
            {
                double[] columnBrightnessG = ImageDataTools.GetAverageLeftright(lsFolder.imgG);
                formsPlot2.plt.PlotScatter(columnPixelIndices, columnBrightnessG, markerSize: 0, color: green);
            }
            formsPlot2.plt.AxisAuto(0, .1);
            formsPlot2.plt.PlotVLine(lsFolder.structure1, color: Color.Black);
            formsPlot2.plt.PlotVLine(lsFolder.structure2, color: Color.Black);

            // update styling before the render
            formsPlot2.plt.YLabel("Intensity");
            formsPlot2.plt.XLabel("Position (pixel number)");
            formsPlot2.Render();

            // update the time series plot
            curveToCopy = null;
            formsPlot1.plt.Clear();
            if (cbRatio.Checked && cbRatio.Enabled)
            {
                if (cbDelta.Enabled && cbDelta.Checked)
                {
                    curveToCopy = lsFolder.GetFilteredYs(lsFolder.curveDeltaGoR);
                    formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveDeltaGoR, color: lightBlue, lineWidth: 0, markerSize: 2);
                    formsPlot1.plt.PlotScatter(lsFolder.GetFilteredXs(), curveToCopy, markerSize: 0, color: blue, lineWidth: 2);

                    formsPlot1.plt.PlotVLine(lsFolder.baseline1 * lsFolder.scanLinePeriod, color: colorBaselineMarks, lineWidth: 2);
                    formsPlot1.plt.PlotVLine(lsFolder.baseline2 * lsFolder.scanLinePeriod, color: colorBaselineMarks, lineWidth: 2);
                    formsPlot1.plt.PlotHLine(0, color: colorZero, lineWidth: 2);
                    formsPlot1.plt.PlotHLine(curveToCopy.Max(), color: colorPeak, lineWidth: 2);

                    formsPlot1.plt.YLabel("Delta G/R (%)");
                }
                else
                {
                    curveToCopy = lsFolder.GetFilteredYs(lsFolder.curveGoR);
                    formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveGoR, color: lightBlue, lineWidth: 0, markerSize: 2);
                    formsPlot1.plt.PlotScatter(lsFolder.GetFilteredXs(), curveToCopy, markerSize: 0, color: blue, lineWidth: 2);
                    formsPlot1.plt.YLabel("G/R (%)");
                    formsPlot1.plt.PlotHLine(curveToCopy.Max(), color: colorPeak, lineWidth: 2);
                }
            }
            else if ((cbR.Checked && cbR.Enabled) && (cbG.Checked && cbG.Enabled))
            {
                formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveG, markerSize: 0, color: green);
                formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveR, markerSize: 0, color: red);
                formsPlot1.plt.YLabel("G and R (AFU)");
            }
            else if (cbR.Checked && cbR.Enabled)
            {
                formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveR, markerSize: 0, color: red);
                formsPlot1.plt.YLabel("R (AFU)");
            }
            else if (cbG.Checked && cbG.Enabled)
            {
                if (cbDelta.Enabled && cbDelta.Checked)
                {
                    curveToCopy = lsFolder.GetFilteredYs(lsFolder.curveDeltaG);
                    formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveDeltaG, lineWidth: 0, color: lightGreen, markerSize: 2);
                    formsPlot1.plt.PlotScatter(lsFolder.GetFilteredXs(), curveToCopy, markerSize: 0, color: green, lineWidth: 2);

                    formsPlot1.plt.PlotVLine(lsFolder.baseline1 * lsFolder.scanLinePeriod, color: colorBaselineMarks, lineWidth: 2);
                    formsPlot1.plt.PlotVLine(lsFolder.baseline2 * lsFolder.scanLinePeriod, color: colorBaselineMarks, lineWidth: 2);
                    formsPlot1.plt.PlotHLine(0, color: colorZero, lineWidth: 2);
                    formsPlot1.plt.PlotHLine(curveToCopy.Max(), color: colorPeak, lineWidth: 2);

                    formsPlot1.plt.YLabel("Delta G (%)");
                }
                else
                {
                    curveToCopy = lsFolder.GetFilteredYs(lsFolder.curveG);
                    formsPlot1.plt.PlotScatter(lsFolder.timesMsec, lsFolder.curveG, lineWidth: 0, color: lightGreen, markerSize: 2);
                    formsPlot1.plt.PlotScatter(lsFolder.GetFilteredXs(), curveToCopy, markerSize: 0, color: green, lineWidth: 2);
                    formsPlot1.plt.PlotHLine(curveToCopy.Max(), color: colorPeak, lineWidth: 2);
                    formsPlot1.plt.YLabel("G (AFU)");
                }
            }
            formsPlot1.plt.AxisAuto(.05, .1);

            // make ticks smaller than typical
            var tickFont = new Font(FontFamily.GenericMonospace, (float)10.0);

            //formsPlot1.plt.Ticks(font: tickFont);
            //formsPlot2.plt.Ticks(font: tickFont);

            // update styling before the render
            formsPlot1.plt.XLabel("Time (milliseconds)");
            formsPlot1.Render();

            // update peak label
            if (curveToCopy == null)
            {
                lblPeak.Text = $"";
            }
            else
            {
                lblPeak.Text = $"{Math.Round(curveToCopy.Max(), 2)}%";
            }

            Application.DoEvents();
            busyUpdating = false;
        }