Commit d5525a87 authored by Francesco Carraro's avatar Francesco Carraro
Browse files

working on continuum removal...

parent 823f46f4
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ namespace INAF.Apps.Uwp.SLabDataManager
            Ioc.Default.ConfigureServices(
                new ServiceCollection()
                /* singletons */
                .AddSingleton<CustomAnnotationsRepository>()
                .AddSingleton<CustomLinesAnnotationsRepository>()
                .AddSingleton<SelectedRefBand>()
                .AddSingleton<SpectrumAlignmentConfigModel>()
                .AddSingleton<SpectrumChartOptionsModel>()
@@ -121,10 +121,11 @@ namespace INAF.Apps.Uwp.SLabDataManager
                .AddTransient<RemoteOperationsManager>()
                .AddTransient<RemoteOperationsXmlReader>()
                .AddTransient<SpectrumModelFactory>()
                .AddTransient<SpectrumProcessingHelper>()
                .AddTransient<SpectrumReader>()
                .AddTransient<XmlHelper>()
                /* view models */
                .AddTransient<ChartViewModel>()
                .AddSingleton<ChartViewModel>()
                .AddTransient<LoginViewModel>()
                .AddTransient<LoginCheckViewModel>()
                .AddSingleton<MainViewModel>()
+58 −211
Original line number Diff line number Diff line
using INAF.Apps.Uwp.SLabDataManager.Extensions;
using INAF.Apps.Uwp.SLabDataManager.Helpers;
using INAF.Apps.Uwp.SLabDataManager.Helpers;
using INAF.Apps.Uwp.SLabDataManager.Models;
using INAF.Libraries.NetStandard.ScienceModels.Extensions;
using INAF.Libraries.NetStandard.ScienceModels.Spectra;
@@ -19,13 +18,9 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
{
    public class SpectraContainer : ObservableObject
    {
        private readonly Logger logger;

        public SpectraContainer(IServiceProvider serviceProvider,
                                Logger logger)
        {
            this.logger = logger;

            SpectrumAlignmentConfig = serviceProvider.GetRequiredService<SpectrumAlignmentConfigModel>();

            SelectedRefBand = serviceProvider.GetRequiredService<SelectedRefBand>();
@@ -42,19 +37,8 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
        }

        #region properties
        public string DialogMessage { get; private set; }

        public DialogMessageType DialogMessageType { get; private set; }

        public bool IsAlignedSpectrumSaved { get; set; }

        private bool isDialogRequired;
        public bool IsDialogRequired
        {
            get { return isDialogRequired; }
            set { SetProperty(ref isDialogRequired, value); }
        }

        private bool isAnySummaryUpdated;
        public bool IsAnySummaryUpdated
        {
@@ -62,8 +46,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            set { SetProperty(ref isAnySummaryUpdated, value); }
        }

        public bool IsSpectrumAligned { get; set; }

        private bool isAnySpectrumLoaded;
        public bool IsAnySpectrumLoaded
        {
@@ -86,7 +68,19 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            }
        }

        public SelectedRefBand SelectedRefBand { get; private set; }
        private bool isSpectrumAligned;
        public bool IsSpectrumAligned
        {
            get { return isSpectrumAligned; }
            set { SetProperty(ref isSpectrumAligned, value); }
        }

        private bool isSpectrumContinuumRemoved;
        public bool IsSpectrumContinuumRemoved
        {
            get { return isSpectrumContinuumRemoved; }
            set { SetProperty(ref isSpectrumContinuumRemoved, value); }
        }

        private ObservableCollection<SpectrumModel> spectra;
        public ObservableCollection<SpectrumModel> Spectra
@@ -95,6 +89,10 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            private set { SetProperty(ref spectra, value); }
        }

        public SelectedRefBand SelectedRefBand { get; private set; }

        public SpectrumAlignmentConfigModel SpectrumAlignmentConfig { get; private set; }

        private ObservableCollection<SpectrumSummaryModel> summaries;
        public ObservableCollection<SpectrumSummaryModel> Summaries
        {
@@ -102,8 +100,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            private set { SetProperty(ref summaries, value); }
        }

        public SpectrumAlignmentConfigModel SpectrumAlignmentConfig { get; private set; }

        #region spectrums min/max
        private AxisBoundariesModel xAxisBoundaries;
        public AxisBoundariesModel XAxisBoundaries
@@ -146,42 +142,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            Spectra.Clear();
        }

        private async Task<(double xMin, double xMax, double yMin, double yMax)> getSpectrumAxesBoundariesAsync()
        {
            List<Task> tasks = new List<Task>();

            double xMin = 0d;
            double xMax = 0d;
            double yMin = 0d;
            double yMax = 0d;
            tasks.Add(Task.Run(() =>
            {
                List<double> xvalues = new List<double>();
                foreach (var spectrum in spectra)
                    xvalues.AddRange(spectrum.Elements.Select(x => x.X));

                (double xMin, double xMax) xresult = xvalues.GetBoundaries();
                xMin = xresult.xMin;
                xMax = xresult.xMax;
            }));
            tasks.Add(Task.Run(() =>
            {
                List<double> yvalues = new List<double>();
                foreach (var spectrum in spectra)
                    yvalues.AddRange(spectrum.Elements.Select(x => x.Y));

                (double yMin, double yMax) yresult = yvalues.GetBoundaries();
                yMin = yresult.yMin;
                yMax = yresult.yMax;
            }));

            await Task.WhenAll(tasks);

            System.Diagnostics.Debug.WriteLine($"x: [{xMin},{xMax}], y: [{yMin},{yMax}]");

            return (xMin, xMax, yMin, yMax);
        }

        private void init()
        {
            Spectra = new ObservableCollection<SpectrumModel>();
@@ -253,6 +213,11 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
            spectrum.PropertyChanged += Spectrum_PropertyChanged;
        }

        public bool isAnySpectrumOfType(SpectrumType spectrumType)
        {
            return Spectra.Any(x => x.Type == spectrumType);
        }

        public void removeAlignedSpectrum()
        {
            removeSpectrumOfTypeAsync(SpectrumType.Aligned);
@@ -266,7 +231,7 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
        }
        #endregion

        private void addSpectrum(SpectrumModel spectrum)
        public void addSpectrum(SpectrumModel spectrum)
        {
            spectrum.setColor();
            Spectra.Add(spectrum);
@@ -323,174 +288,56 @@ namespace INAF.Apps.Uwp.SLabDataManager.Charts
        #endregion

        #region boundaries
        private async Task setBoundariesAsync()
        {
            (double xMin, double xMax, double yMin, double yMax) result = await getSpectrumAxesBoundariesAsync();

            XAxisBoundaries = new AxisBoundariesModel("x", result.xMin, result.xMax, spectra[0].Elements[0].MeasureUnit);
            YAxisBoundaries = new AxisBoundariesModel("y", result.yMin, result.yMax);
        }

        public async Task updateBoundariesAsync()
        {
            (double xMin, double xMax, double yMin, double yMax) result = await getSpectrumAxesBoundariesAsync();

            XAxisBoundaries.updateAxisBoundaries(result.xMin, result.xMax);
            YAxisBoundaries.updateAxisBoundaries(result.yMin, result.yMax);
        }
        #endregion

        #region alignment
        private SpectrumModel createAlignedSpectrum()
        {
            var aligningSpectrum = (SpectrumModel)tryGetSpectrumOfType(SpectrumType.Raw).Clone();
            aligningSpectrum.setType(SpectrumType.Aligned);
            aligningSpectrum.updateTitle();
            return aligningSpectrum;
        }

        public async Task alignRawSpectrumAsync()
        {
            IsDialogRequired = false;
            DialogMessage = string.Empty;

            SpectrumModel alignedSpectrum = null;

            string exMsg = string.Empty;
            await Task.Run(() =>
            {
                try
                {
                    alignedSpectrum = createAlignedSpectrum();

                    /* try to retrieve the ref white max value for normalizing raw spectrum during alignment process */
                    double refWhiteMaxY = 1d;
                    var refWhiteSpectrum = tryGetSpectrumOfType(SpectrumType.RefWhite);
                    if (refWhiteSpectrum == null)
                    {
                        UpdateUIHelper.UpdateUIAsync(() =>
        private async Task<(double xMin, double xMax, double yMin, double yMax)> getSpectrumAxesBoundariesAsync()
        {
                            DialogMessageType = DialogMessageType.Warning;
                            DialogMessage = "RefWhiteSpectrumNotAvailable".GetText();
                            IsDialogRequired = true;
                        });
                    }
                    else
                        refWhiteMaxY = refWhiteSpectrum.Elements.Max(x => x.Y);
            List<Task> tasks = new List<Task>();

                    /* try to retrieve ref spectrum for normalizing raw spectrum during alignment process */
                    var refSpectrum = tryGetSpectrumOfType(SpectrumType.Ref);
                    if (refSpectrum == null)
                    {
                        UpdateUIHelper.UpdateUIAsync(() =>
            double xMin = 0d;
            double xMax = 0d;
            double yMin = 0d;
            double yMax = 0d;
            tasks.Add(Task.Run(() =>
            {
                            DialogMessageType = DialogMessageType.Warning;
                            DialogMessage = "NoNormalizationAvailableMessage".GetText();
                            IsDialogRequired = true;
                        });
                    }
                List<double> xvalues = new List<double>();
                foreach (var spectrum in spectra)
                    xvalues.AddRange(spectrum.Elements.Select(x => x.X));

                    /* normalize spectrum, if possible */
                    if (refWhiteSpectrum != null && refSpectrum != null)
                (double xMin, double xMax) xresult = xvalues.GetBoundaries();
                xMin = xresult.xMin;
                xMax = xresult.xMax;
            }));
            tasks.Add(Task.Run(() =>
            {
                        multiplyByRef(ref alignedSpectrum,
                                      refWhiteMaxY,
                                      refSpectrum);
                    }

                    /* retrieve the reference segment and calculate the mean values at the borders of the segment for aligning other segments */
                    var refLowSeparator = SpectrumAlignmentConfig.WavelengthSeparators.FirstOrDefault(x => x.CurrentValue >= SelectedRefBand.XMin && x.CurrentValue <= SelectedRefBand.XMax);
                    var refHighSeparator = SpectrumAlignmentConfig.WavelengthSeparators.FirstOrDefault(x => x.CurrentValue > refLowSeparator.CurrentValue);

                    var refSegment = alignedSpectrum.GetCenterSegmentElements(refLowSeparator.CurrentValue, refHighSeparator.CurrentValue);

                    double refSegmentLeftMean = refSegment.GetSegmentLeftMeanValue(SpectrumAlignmentConfig.NumOfPointsForAlignment);
                    double refSegmentRightMean = refSegment.GetSegmentRightMeanValue(SpectrumAlignmentConfig.NumOfPointsForAlignment);
                List<double> yvalues = new List<double>();
                foreach (var spectrum in spectra)
                    yvalues.AddRange(spectrum.Elements.Select(x => x.Y));

                (double yMin, double yMax) yresult = yvalues.GetBoundaries();
                yMin = yresult.yMin;
                yMax = yresult.yMax;
            }));

                    /* retrieve segments on the left of selected one for later alignment */
                    alignLeftSide(ref alignedSpectrum,
                                  refLowSeparator,
                                  refSegmentLeftMean);
            await Task.WhenAll(tasks);

                    /* retrieve segments on the right of the selected one for later alignment */
                    alignRightSide(ref alignedSpectrum,
                                   refHighSeparator,
                                   refSegmentRightMean);
                }
                catch (Exception ex)
                {
                    logger.Write<SpectraContainer>($"{nameof(alignRawSpectrumAsync)} - ex: {ex.Message}", Serilog.Events.LogEventLevel.Error);
                    exMsg = ex.Message;
                }
            });
            System.Diagnostics.Debug.WriteLine($"x: [{xMin},{xMax}], y: [{yMin},{yMax}]");

            if (string.IsNullOrEmpty(exMsg))
            {
                IsSpectrumAligned = true;
                addSpectrum(alignedSpectrum);
            }
            else
            {
                DialogMessage = exMsg;
                IsDialogRequired = true;
            }
            return (xMin, xMax, yMin, yMax);
        }

        private void alignLeftSide(ref SpectrumModel aligningSpectrum,
                                   WavelengthModel refLowSeparator,
                                   double refSegmentLeftMean)
        {
            var leftSeparators = SpectrumAlignmentConfig.WavelengthSeparators
                                                               .Where(x => x.MinValue < refLowSeparator.MinValue)
                                                               .OrderByDescending(x => x.MinValue);
            double rightSeparatorCurrentValue = refLowSeparator.CurrentValue;
            double refLeftValue = refSegmentLeftMean;
            foreach (var leftSeparator in leftSeparators)
        private async Task setBoundariesAsync()
        {
                var elements = aligningSpectrum
                                .GetLeftSegmentElements(leftSeparator.CurrentValue, rightSeparatorCurrentValue)
                                .FixLeftSegment(refLeftValue, SpectrumAlignmentConfig.NumOfPointsForAlignment);

                aligningSpectrum.UpdateElements(elements);

            (double xMin, double xMax, double yMin, double yMax) result = await getSpectrumAxesBoundariesAsync();

                rightSeparatorCurrentValue = leftSeparator.CurrentValue;
                refLeftValue = elements.GetSegmentLeftMeanValue(SpectrumAlignmentConfig.NumOfPointsForAlignment);
            }
            XAxisBoundaries = new AxisBoundariesModel("x", result.xMin, result.xMax, spectra[0].Elements[0].MeasureUnit);
            YAxisBoundaries = new AxisBoundariesModel("y", result.yMin, result.yMax);
        }

        private void alignRightSide(ref SpectrumModel aligningSpectrum,
                                    WavelengthModel refHighSeparator,
                                    double refSegmentRightMean)
        {
            var rightSeparators = SpectrumAlignmentConfig.WavelengthSeparators.Where(x => x.MinValue > refHighSeparator.MinValue);
            double leftSeparatorCurrentValue = refHighSeparator.CurrentValue;
            double refRightValue = refSegmentRightMean;
            foreach (var rightSeparator in rightSeparators)
        public async Task updateBoundariesAsync()
        {
                var elements = aligningSpectrum
                                .GetRightSegmentElements(leftSeparatorCurrentValue, rightSeparator.CurrentValue)
                                .FixRightSegment(refRightValue, SpectrumAlignmentConfig.NumOfPointsForAlignment);

                aligningSpectrum.UpdateElements(elements);

                leftSeparatorCurrentValue = rightSeparator.CurrentValue;
                refRightValue = elements.GetSegmentRightMeanValue(SpectrumAlignmentConfig.NumOfPointsForAlignment);
            }
        }
            (double xMin, double xMax, double yMin, double yMax) result = await getSpectrumAxesBoundariesAsync();

        private void multiplyByRef(ref SpectrumModel aligningSpectrum,
                                   double refWhiteMaxY,
                                   SpectrumModel refSpectrum)
        {
            aligningSpectrum.Elements
                                .AsParallel()
                                .ForAll(x =>
                                {
                                    var refElement = refSpectrum.Elements.FirstOrDefault(y => y.X == x.X);
                                    x.updateY(x.Y * refElement.Y / refWhiteMaxY);
                                });
            XAxisBoundaries.updateAxisBoundaries(result.xMin, result.xMax);
            YAxisBoundaries.updateAxisBoundaries(result.yMin, result.yMax);
        }
        #endregion
    }
+26 −0
Original line number Diff line number Diff line
@@ -2,17 +2,43 @@
using INAF.Apps.Uwp.SLabDataManager.Helpers;
using INAF.Apps.Uwp.SLabDataManager.Models;
using INAF.Libraries.NetStandard.Extensions;
using INAF.Libraries.NetStandard.ScienceModels.Extensions;
using Microsoft.Toolkit.Mvvm.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using Telerik.Charting;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using static INAF.Libraries.NetStandard.SLabCommonModels.Enums.Enums;

namespace INAF.Apps.Uwp.SLabDataManager.Converters
{
    public sealed class IsSpectrumAvailablelWithParameterConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            try
            {
                string _spectrumType = (string)parameter;
                SpectrumType spectrumType = _spectrumType.ToSpectrumType();

                SpectraContainer spectraContainer = Ioc.Default.GetService<SpectraContainer>();
                return spectraContainer.isAnySpectrumOfType(spectrumType);
            }
            catch (Exception)
            {
                return false;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

    public sealed class ChartDataPointConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
+19 −6
Original line number Diff line number Diff line
@@ -13,17 +13,17 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart
{
    public sealed class ChartAnnotationsHelper
    {
        private readonly CustomAnnotationsRepository customAnnotationsRepository;
        private readonly CustomLinesAnnotationsRepository customAnnotationsRepository;
        private readonly Logger logger;

        public ChartAnnotationsHelper(CustomAnnotationsRepository customAnnotationsRepository,
        public ChartAnnotationsHelper(CustomLinesAnnotationsRepository customAnnotationsRepository,
                                      Logger logger)
        {
            this.customAnnotationsRepository = customAnnotationsRepository;
            this.logger = logger;
        }

        public void addOrRemoveTappedPoint(RadCartesianChart chart,
        public void addOrRemoveTappedPointForContinuum(RadCartesianChart chart,
                                                       Point mousePosition,
                                                       DataTemplate tappedPointTemplate)
        {
@@ -33,7 +33,9 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart
            System.Diagnostics.Debug.WriteLine($"point: {point.Item1}, {point.Item2}");

            /* if a point in selected position already exists, then remove it... */
            var existantItem = chart.Annotations.FirstOrDefault(x => x is CartesianCustomAnnotation && Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) >= ((double)point.Item1 - 12d) && (Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) <= (double)point.Item1 + 12));
            var existantItem = chart.Annotations.FirstOrDefault(x => x is CartesianCustomAnnotation &&
                                                                (Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) >= ((double)point.Item1 - 12d)) &&
                                                                (Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) <= ((double)point.Item1 + 12d)));
            if (existantItem != null)
                chart.Annotations.Remove(existantItem);
            else
@@ -113,5 +115,16 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart
                logger.Write<ChartAnnotationsHelper>($"{nameof(tryCreateLines)} - ex: {ex.Message}", Serilog.Events.LogEventLevel.Error);
            }
        }

        public void removePointsForContinuum(RadCartesianChart chart)
        {
            int annotationsNum = chart.Annotations.Count();
            for (int i = annotationsNum - 1; i >= 0; i--)
            {
                if (chart.Annotations.ElementAt(i).GetType() == typeof(CartesianCustomAnnotation) ||
                    chart.Annotations.ElementAt(i).GetType() == typeof(CartesianCustomLineAnnotation))
                    chart.Annotations.Remove(chart.Annotations.ElementAt(i));
            }
        }
    }
}
+25 −2
Original line number Diff line number Diff line
using INAF.Libraries.NetStandard.ScienceModels.Lines;
using System.Collections.Generic;
using System.Linq;

namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart
{
    public class CustomAnnotationsRepository
    public class CustomLinesAnnotationsRepository
    {
        public CustomAnnotationsRepository()
        public CustomLinesAnnotationsRepository()
        {
            CustomLineAnnotations = new List<StraightLineModel>();
        }
@@ -15,11 +16,33 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart
        public void add(StraightLineModel annotation)
        {
            CustomLineAnnotations.Add(annotation);
            CustomLineAnnotations = CustomLineAnnotations
                                        .OrderBy(t => t.P1.X)
                                        .ToList();
        }

        public void clear()
        {
            CustomLineAnnotations.Clear();
        }

        public StraightLineModel getLine(double x)
        {
            var line = CustomLineAnnotations.FirstOrDefault(t => x >= t.P1.X && x <= t.P2.X);
            if (line == null)
            {
                if (x < CustomLineAnnotations.First().P1.X)
                    line = CustomLineAnnotations.First();
                else if (x > CustomLineAnnotations.Last().P2.X)
                    line = CustomLineAnnotations.Last();
            }

            return line;
        }

        public bool isAnyLineAvailable()
        {
            return CustomLineAnnotations.Count >= 1;
        }
    }
}
Loading