New conversion complete

This commit is contained in:
2015-12-07 12:38:58 -05:00
parent 5b85662bdb
commit 50ae6cb52c
25 changed files with 815 additions and 281 deletions
+10 -26
View File
@@ -1,37 +1,21 @@
using System.IO;
using System.ComponentModel;
namespace LeafWeb.Core.Charter
{
public class CurveData
{
private readonly string _curveId;
public string CurveId { get; set; }
public string CurveId => _curveId;
[DisplayName("Internal conductance fixed, compensation point and M-M constants fixed")]
public CurveParamSet FixedCndFixedCmp { get; set; }
// 1
public CurveParamSet FixedCndFixedCmp { get; }
// 2
public CurveParamSet FixedCndEstimatedCmp { get; }
[DisplayName("Internal conductance fixed, compensation point and M-M constants estimated")]
public CurveParamSet FixedCndEstimatedCmp { get; set; }
// 3
public CurveParamSet EstimatedCndFixedCmp { get; }
[DisplayName("Internal conductance estimated, compensation point and M-M constants fixed")]
public CurveParamSet EstimatedCndFixedCmp { get; set; }
// 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);
}
[DisplayName("Internal conductance estimated, compensation point and M-M constants estimated")]
public CurveParamSet EstimatedCndEstimatedCmp { get; set; }
}
}
+128
View File
@@ -0,0 +1,128 @@
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<CurveData> Convert(IEnumerable<CntrlComparison> 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<CurveData>(c=>c.FixedCndFixedCmp)}");
if (curveData.FixedCndEstimatedCmp == null)
throw new ArgumentException(
$"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName<CurveData>(c=>c.FixedCndEstimatedCmp)}");
if (curveData.EstimatedCndFixedCmp == null)
throw new ArgumentException(
$"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName<CurveData>(c=>c.EstimatedCndFixedCmp)}");
if (curveData.EstimatedCndEstimatedCmp == null)
throw new ArgumentException(
$"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName<CurveData>(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.AcInterData.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<XyPoint> 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;
}
}
}
}
-42
View File
@@ -1,42 +0,0 @@
using System.Collections.Generic;
using System.IO;
namespace LeafWeb.Core.Charter
{
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;
}
}
}
-145
View File
@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.IO;
using LeafWeb.Core.Utility;
namespace LeafWeb.Core.Charter
{
@@ -19,148 +17,5 @@ namespace LeafWeb.Core.Charter
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;
}
}
}
+6 -6
View File
@@ -2,16 +2,16 @@
{
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 XyPoint(double x, double y)
{
X = x;
Y = y;
}
public bool YIsInRange(double lowEnd, double highEnd)
{
return (Y >= lowEnd) && (Y <= highEnd);