using System; using System.Collections.Generic; using System.Linq; using LeafWeb.Core.Models; using LeafWeb.Core.Utility; namespace LeafWeb.Core.Charter { public class CurveDataConverter { public static IEnumerable Convert(IEnumerable cntrlComparison) { var comparisonGroups = from comparison in cntrlComparison group comparison by comparison.CurveID into curves select new { CurveID = curves.Key, FitType = from curve in curves group curve by new {curve.FitGi, curve.FitGammaStar} into grp select new { grp.Key.FitGi, grp.Key.FitGammaStar, Comparison = grp.SingleOrDefault() } }; foreach (var comparisonGroup in comparisonGroups) { if (comparisonGroup.FitType.Count() != 4) throw new ArgumentException( $"{comparisonGroup.CurveID} should have 4 data sets, only has {comparisonGroup.FitType.Count()}"); var curveData = new CurveData {CurveId = comparisonGroup.CurveID}; foreach (var fitType in comparisonGroup.FitType) { var paramSet = ConvertParamSet(fitType.Comparison); // fixed = not fitted // estimated = fitted // gi = internal conductance = "Cnd" // gammastar = chloroplastic CO2 partial pressure photocompensation point = "Cmp" // put each comparison into the correct curve location if (!fitType.FitGi && !fitType.FitGammaStar) curveData.FixedCndFixedCmp = paramSet; else if (!fitType.FitGi && fitType.FitGammaStar) curveData.FixedCndEstimatedCmp = paramSet; else if (fitType.FitGi && !fitType.FitGammaStar) curveData.EstimatedCndFixedCmp = paramSet; else if (fitType.FitGi && fitType.FitGammaStar) curveData.EstimatedCndEstimatedCmp = paramSet; } // Check all data is present if (curveData.FixedCndFixedCmp == null) throw new ArgumentException( $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.FixedCndFixedCmp)}"); if (curveData.FixedCndEstimatedCmp == null) throw new ArgumentException( $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.FixedCndEstimatedCmp)}"); if (curveData.EstimatedCndFixedCmp == null) throw new ArgumentException( $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.EstimatedCndFixedCmp)}"); if (curveData.EstimatedCndEstimatedCmp == null) throw new ArgumentException( $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.EstimatedCndEstimatedCmp)}"); yield return curveData; } } private static CurveParamSet ConvertParamSet(CntrlComparison comparison) { var curveParamSet = new CurveParamSet(); foreach (var fittingInfo in comparison.FittingInfo) { Set(curveParamSet, fittingInfo); } foreach (var photosyntheticInfo in comparison.PhotosyntheticInfo) { Set(curveParamSet, photosyntheticInfo); } return curveParamSet; } private static void Set(CurveParamSet paramSet, CntrlComparisonPhotosyntheticInfo item) { AddXyIfInRange(item.CO2cc, item.Ac, paramSet.AcChloroData.Add); // Ac(y),CO2cc(x) AddXyIfInRange(item.CO2cj, item.Aj, paramSet.AjChloroData.Add); // Aj(y),CO2cj(x) AddXyIfInRange(item.CO2ct, item.At, paramSet.AtChloroData.Add); // At(y),CO2ct(x) AddXyIfInRange(item.CO2i, item.Ac, paramSet.AcInterData.Add); // Ac(y),CO2i(x) AddXyIfInRange(item.CO2i, item.Aj, paramSet.AjInterData.Add); // Aj(y),CO2i(x) AddXyIfInRange(item.CO2i, item.At, paramSet.AtInterData.Add); // Aj(y),CO2i(x) } private static void AddXyIfInRange(double x, double y, Action set) { var xyPoint = new XyPoint(x, y); if (xyPoint.YIsInRange(-20.0, 50.0)) set(xyPoint); } private static void Set(CurveParamSet paramSet, CntrlComparisonFittingInfo fittingInfo) { var xyPoint1 = new XyPoint(fittingInfo.PCO2c, fittingInfo.AnetMeas); // AnetMeas(y), PCO2c(x) var xyPoint2 = new XyPoint(fittingInfo.PCO2i, fittingInfo.AnetMeas); switch (fittingInfo.PointLimitType) { case 1: paramSet.AnetMeasChloro1Data.Add(xyPoint1); paramSet.AnetMeasInter1Data.Add(xyPoint2); break; case 2: paramSet.AnetMeasChloro2Data.Add(xyPoint1); paramSet.AnetMeasInter2Data.Add(xyPoint2); break; case 3: paramSet.AnetMeasChloro3Data.Add(xyPoint1); paramSet.AnetMeasInter3Data.Add(xyPoint2); break; } } } }