Replace old charting curves with new version
This commit is contained in:
@@ -6,7 +6,7 @@ using LeafWeb.Core.Utility;
|
||||
|
||||
namespace LeafWeb.Core.Charter
|
||||
{
|
||||
public class CurveDataConverter
|
||||
public static class CurveDataConverter
|
||||
{
|
||||
public static IEnumerable<CurveData> Convert(IEnumerable<CntrlComparison> cntrlComparison)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ namespace LeafWeb.Core.Charter
|
||||
curveData.EstimatedCndEstimatedCmp = paramSet;
|
||||
}
|
||||
|
||||
// Check all data is present
|
||||
// guarantee all data is present
|
||||
if (curveData.FixedCndFixedCmp == null)
|
||||
throw new ArgumentException(
|
||||
$"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName<CurveData>(c=>c.FixedCndFixedCmp)}");
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace LeafWeb.Core.CharterOld
|
||||
{
|
||||
public class CurveData
|
||||
{
|
||||
private readonly string _curveId;
|
||||
|
||||
public string CurveId => _curveId;
|
||||
|
||||
// 1
|
||||
public CurveParamSet FixedCndFixedCmp { get; }
|
||||
|
||||
// 2
|
||||
public CurveParamSet FixedCndEstimatedCmp { get; }
|
||||
|
||||
// 3
|
||||
public CurveParamSet EstimatedCndFixedCmp { get; }
|
||||
|
||||
// 4
|
||||
public CurveParamSet EstimatedCndEstimatedCmp { get; }
|
||||
|
||||
|
||||
public CurveData(TextReader sr, ref int lineNbr)
|
||||
{
|
||||
// For each curve in the output file there are four sets of data.
|
||||
|
||||
FixedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId);
|
||||
|
||||
FixedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId);
|
||||
|
||||
EstimatedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId);
|
||||
|
||||
EstimatedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace LeafWeb.Core.CharterOld
|
||||
{
|
||||
public class CurveDataList
|
||||
{
|
||||
// Each element will be a PiscalCurve element that contains
|
||||
// all of the output data for one curve.
|
||||
public List<CurveData> CurveData { get; }
|
||||
|
||||
public CurveDataList()
|
||||
{
|
||||
CurveData = new List<CurveData>();
|
||||
}
|
||||
|
||||
public bool ReadFromStream(StreamReader sr)
|
||||
{
|
||||
// Skip the first two lines.
|
||||
sr.ReadLine();
|
||||
sr.ReadLine();
|
||||
var lineNbr = 2;
|
||||
|
||||
// Now, there should be one or more rows, delimited by a row that has
|
||||
// CO2i in the first field. Read in all of these rows. The first field
|
||||
// in each row is the curve ID (input filename).
|
||||
|
||||
var more = true;
|
||||
while (more)
|
||||
{
|
||||
var curve = new CurveData(sr, ref lineNbr);
|
||||
|
||||
CurveData.Add(curve);
|
||||
|
||||
if (sr.EndOfStream)
|
||||
more = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using LeafWeb.Core.Utility;
|
||||
|
||||
namespace LeafWeb.Core.CharterOld
|
||||
{
|
||||
public class CurveParamSet
|
||||
{
|
||||
public List<XyPoint> AnetMeasChloro1Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2c, for PointLimitType=1
|
||||
public List<XyPoint> AnetMeasChloro2Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2c, for PointLimitType=2
|
||||
public List<XyPoint> AnetMeasChloro3Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2c, for PointLimitType=3
|
||||
public List<XyPoint> AnetMeasInter1Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2i, for PointLimitType=1
|
||||
public List<XyPoint> AnetMeasInter2Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2i, for PointLimitType=2
|
||||
public List<XyPoint> AnetMeasInter3Data { get; } = new List<XyPoint>(); // y=AnetMeas column, x=PCO2i, for PointLimitType=3
|
||||
|
||||
public List<XyPoint> AcChloroData { get; } = new List<XyPoint>();
|
||||
public List<XyPoint> AjChloroData { get; } = new List<XyPoint>();
|
||||
public List<XyPoint> AtChloroData { get; } = new List<XyPoint>();
|
||||
public List<XyPoint> AcInterData { get; } = new List<XyPoint>();
|
||||
public List<XyPoint> AjInterData { get; } = new List<XyPoint>();
|
||||
public List<XyPoint> AtInterData { get; } = new List<XyPoint>();
|
||||
|
||||
public CurveParamSet(TextReader sr, ref int lineNbr, ref string curveId)
|
||||
{
|
||||
bool curveIdSet = false, doneWithAnet = false;
|
||||
string line;
|
||||
List<string> phrases;
|
||||
|
||||
while (!doneWithAnet)
|
||||
{
|
||||
lineNbr++;
|
||||
line = sr.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
throw new ParseException("Unexpected end-of-file at line " + lineNbr);
|
||||
}
|
||||
|
||||
phrases = SplitCsvLine(line);
|
||||
|
||||
var firstField = phrases[0];
|
||||
if (firstField.Equals("CO2i"))
|
||||
{
|
||||
doneWithAnet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The fields on the line:
|
||||
// Column Name
|
||||
// 0 CurveID
|
||||
// 1 ChlFlUse
|
||||
// 2 FitGi
|
||||
// 3 FitGamma
|
||||
// 4 FitKco
|
||||
// 5 FitRd
|
||||
// 6 FitAlpha
|
||||
// 7 LimitCombina
|
||||
// 8 PCO2i
|
||||
// 9 PCO2c
|
||||
// 10 AnetMeas
|
||||
// 11 AnetCal
|
||||
// 12 weitedrms
|
||||
// 13 PointLimitType
|
||||
|
||||
if (!curveIdSet)
|
||||
{
|
||||
curveId = firstField;
|
||||
curveIdSet = true;
|
||||
}
|
||||
var xyPoint1 = new XyPoint(phrases[9], phrases[10]); // AnetMeas(y), PCO2c(x)
|
||||
var xyPoint2 = new XyPoint(phrases[8], phrases[10]);
|
||||
var pointLimitType = int.Parse(phrases[13]);
|
||||
switch (pointLimitType)
|
||||
{
|
||||
case 1:
|
||||
AnetMeasChloro1Data.Add(xyPoint1);
|
||||
AnetMeasInter1Data.Add(xyPoint2);
|
||||
break;
|
||||
case 2:
|
||||
AnetMeasChloro2Data.Add(xyPoint1);
|
||||
AnetMeasInter2Data.Add(xyPoint2);
|
||||
break;
|
||||
case 3:
|
||||
AnetMeasChloro3Data.Add(xyPoint1);
|
||||
AnetMeasInter3Data.Add(xyPoint2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The next set of lines will have three pairs of x,y-coordinates to save.
|
||||
// A blank line signals the end of the data.
|
||||
|
||||
var moreData = true;
|
||||
while (moreData)
|
||||
{
|
||||
// The fields on the line:
|
||||
// Column Name
|
||||
// 0 CO2i
|
||||
// 1 CO2cc
|
||||
// 2 Ac
|
||||
// 3 CO2cj
|
||||
// 4 Aj
|
||||
// 5 CO2ct
|
||||
// 6 At
|
||||
|
||||
lineNbr++;
|
||||
line = sr.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
throw new ParseException("Unexpected end-of-file at line " + lineNbr);
|
||||
}
|
||||
|
||||
if (line.Length == 0)
|
||||
moreData = false;
|
||||
else
|
||||
{
|
||||
phrases = SplitCsvLine(line);
|
||||
var xyPoint1 = new XyPoint(phrases[1],phrases[2]); // Ac(y),CO2cc(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AcChloroData.Add(xyPoint1);
|
||||
xyPoint1 = new XyPoint(phrases[3], phrases[4]); // Aj(y),CO2cj(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AjChloroData.Add(xyPoint1);
|
||||
xyPoint1 = new XyPoint(phrases[5], phrases[6]); // At(y),CO2ct(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AtChloroData.Add(xyPoint1);
|
||||
|
||||
xyPoint1 = new XyPoint(phrases[0], phrases[2]); // Ac(y),CO2i(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AcInterData.Add(xyPoint1);
|
||||
xyPoint1 = new XyPoint(phrases[0], phrases[4]); // Aj(y),CO2i(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AjInterData.Add(xyPoint1);
|
||||
xyPoint1 = new XyPoint(phrases[0], phrases[6]); // At(y),CO2i(x)
|
||||
if (xyPoint1.YIsInRange(-20.0, 50.0))
|
||||
AtInterData.Add(xyPoint1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method assumes that the argument is a comma-, blank-, or
|
||||
/// tab-separated set of strings. It returns an ArrayList of those
|
||||
/// quantities. Consecutive commas will be returned as an empty string,
|
||||
/// but all empty strings at the end of the line will be thrown away.
|
||||
/// </summary>
|
||||
/// <param name="line"></param>
|
||||
/// <returns></returns>
|
||||
private static List<string> SplitCsvLine(string line)
|
||||
{
|
||||
int i;
|
||||
var separator = new [] {',', ' ', '\t'};
|
||||
var phrases = line.Split(separator);
|
||||
|
||||
var retPhrases = new List<string>();
|
||||
for (i = 0; i < phrases.Length; i++)
|
||||
{
|
||||
var phrase = phrases[i].Trim();
|
||||
if (phrase.Length > 0)
|
||||
retPhrases.Add(phrase);
|
||||
}
|
||||
|
||||
return retPhrases;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace LeafWeb.Core.CharterOld
|
||||
{
|
||||
public class XyPoint
|
||||
{
|
||||
public XyPoint(string x, string y)
|
||||
{
|
||||
X = double.Parse(x);
|
||||
Y = double.Parse(y);
|
||||
}
|
||||
|
||||
public double X { get; private set; }
|
||||
|
||||
public double Y { get; private set; }
|
||||
|
||||
public bool YIsInRange(double lowEnd, double highEnd)
|
||||
{
|
||||
return (Y >= lowEnd) && (Y <= highEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,15 +63,11 @@
|
||||
<Compile Include="Models\CntrlComparison.cs" />
|
||||
<Compile Include="Models\CntrlComparisonFittingInfo.cs" />
|
||||
<Compile Include="Models\CntrlComparisonPhotosyntheticInfo.cs" />
|
||||
<Compile Include="CharterOld\CurveDataList.cs" />
|
||||
<Compile Include="CharterOld\CurveData.cs" />
|
||||
<Compile Include="CharterOld\CurveParamSet.cs" />
|
||||
<Compile Include="Models\LeafInput.cs" />
|
||||
<Compile Include="Models\LeafInputData.cs" />
|
||||
<Compile Include="Models\LeafInputFile.cs" />
|
||||
<Compile Include="Models\LeafInputPhotosynthetic.cs" />
|
||||
<Compile Include="Models\LeafInputSite.cs" />
|
||||
<Compile Include="CharterOld\XYPoint.cs" />
|
||||
<Compile Include="Utility\BoolTypeConverter.cs" />
|
||||
<Compile Include="Parsers\CntrlComparisonParser.cs" />
|
||||
<Compile Include="Parsers\CsvParserBase.cs" />
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace LeafWeb.Core.Parsers
|
||||
throw new FileNotFoundException($"Cannot find file '{csvFile.Name}'");
|
||||
|
||||
_reader = File.OpenText(csvFile.FullName);
|
||||
var csvConfiguration = new CsvConfiguration { HasHeaderRecord = false, IgnoreBlankLines = false};
|
||||
var csvConfiguration = new CsvConfiguration { HasHeaderRecord = false, IgnoreBlankLines = false, IgnoreReadingExceptions = true};
|
||||
CsvReader = new CsvReader(_reader, csvConfiguration);
|
||||
}
|
||||
|
||||
@@ -29,16 +29,7 @@ namespace LeafWeb.Core.Parsers
|
||||
if (!CsvReader.Read())
|
||||
return null;
|
||||
|
||||
// put all the values from this row into an array
|
||||
var values = new List<string>();
|
||||
var index = 0;
|
||||
string value;
|
||||
while (CsvReader.TryGetField(index, out value))
|
||||
{
|
||||
values.Add(value);
|
||||
index++;
|
||||
}
|
||||
return values.ToArray();
|
||||
return CsvReader.CurrentRecord;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -8,6 +9,26 @@ using Fasterflect;
|
||||
|
||||
namespace LeafWeb.Core.Utility
|
||||
{
|
||||
public static class MemoizationExtensions
|
||||
{
|
||||
static Func<A, R> ThreadsafeMemoize<A, R>(this Func<A, R> f)
|
||||
{
|
||||
var cache = new ConcurrentDictionary<A, R>();
|
||||
|
||||
return argument => cache.GetOrAdd(argument, f);
|
||||
}
|
||||
//static Func<A, B, R> ThreadsafeMemoize<A, B, R>(this Func<A, B, R> f)
|
||||
//{
|
||||
// var cache = new ConcurrentDictionary<A, ConcurrentDictionary<B,R>>();
|
||||
|
||||
// return (a, b) =>
|
||||
// {
|
||||
|
||||
// return cache.GetOrAdd(a, new ConcurrentDictionary<B, R>()).GetOrAdd(b, f);
|
||||
|
||||
// };
|
||||
//}
|
||||
}
|
||||
public static class ReflectionExtensions
|
||||
{
|
||||
public static string GetPropertyDisplayName<T>(Expression<Func<T, object>> propertyExpression)
|
||||
|
||||
Reference in New Issue
Block a user