Skip to content

Commit

Permalink
AQ_Sim_2D.cs Update StreamFlowsFromNWM to handle merged segments prop…
Browse files Browse the repository at this point in the history
…erly and to send output to log file

AQ_Sim_2D.cs Updated PopulateStreamNetwork to call StreamFlowsFromNWM properly with merged IDs
MultiSegForm.cs Passes merged segment list to PopulateSTreamNetwork and logs merge status after NWM linkage
  • Loading branch information
jsclough committed Jul 8, 2024
1 parent 7408b8c commit ed57739
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 18 deletions.
54 changes: 42 additions & 12 deletions Data.Simulate.AQUATOX/AQ_Sim_2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,10 @@ public double LakeFlowsFromNWM(TVolume TVol, Data.TimeSeriesOutput<List<double>>
/// </summary>
/// <param name="TVol">AQUATOX Volume object to be populated with data</param>
/// <param name="ATSO">National Water Model time-series output</param>
/// <param name="merged">Is this a segment that has been merged (for addition)</param>
/// <returns>The average retention time for the period being modeled in days</returns>
/// <exception cref="ArgumentException"></exception>
public double StreamFlowsFromNWM(TVolume TVol, Data.TimeSeriesOutput<List<double>> ATSO) // time series output must currently be in m3/s
public double StreamFlowsFromNWM(TVolume TVol, Data.TimeSeriesOutput<List<double>> ATSO, string IDStr, bool merged) // time series output must currently be in m3/s
{
double RTSum = 0;
int RTCount = 0;
Expand Down Expand Up @@ -421,8 +422,11 @@ public double StreamFlowsFromNWM(TVolume TVol, Data.TimeSeriesOutput<List<double

ITimeSeriesOutput TSO = InflowLoad.ITSI.InputTimeSeries.FirstOrDefault().Value;

KnownValLoad.list.Clear();
KnownValLoad.list.Capacity = TSO.Data.Count;
if (!merged)
{
KnownValLoad.list.Clear();
KnownValLoad.list.Capacity = TSO.Data.Count;
}

bool firstvol = true;
foreach (KeyValuePair<string, List<string>> entry in TSO.Data)
Expand All @@ -442,22 +446,29 @@ public double StreamFlowsFromNWM(TVolume TVol, Data.TimeSeriesOutput<List<double
VolCalc = (flow / velocity) * (TVol.AQTSeg.Location.Locale.SiteLength.Val) * 1000;
// known value(m3) = flow(m3/s) / velocity(m/s) * sitelength(km) * 1000 (m/km)
if (VolCalc < Consts.Tiny) VolCalc = TVol.AQTSeg.Location.Locale.SiteLength.Val * 1000; //default minimum volume (length * XSec 1 m2) for now
KnownValLoad.list.Add(date, VolCalc);

if (firstvol) TVol.InitialCond = VolCalc;
if (!merged) KnownValLoad.list.Add(date, VolCalc);
else KnownValLoad.list[date] += VolCalc;

if (firstvol)
{
if (!merged) TVol.InitialCond = VolCalc;
else TVol.InitialCond += VolCalc;
}
firstvol = false;

RTSum += VolCalc / (flow * 86400); // m3 / (m3/s * s/d) = retention time in days
RTCount++;
}

InflowLoad.Translate_ITimeSeriesInput(0, 86400, 1000); // default minimum flow of 1000 cmd for now multiplier is seconds per day
if (!merged) InflowLoad.Translate_ITimeSeriesInput(0, 86400, 1000); // default minimum flow of 1000 cmd for now multiplier is seconds per day
InflowLoad.MultLdg = 1;
// InflowLoad.Hourly = true; 12/14/22
InflowLoad.UseConstant = false;

TVol.LoadNotes1 = "Volumes from NWM using flows in m3/s";
TVol.LoadNotes2 = "NWM inflow converted from m3/d using multiplier";
if (merged) TVol.LoadNotes2 += ", " + IDStr;
else TVol.LoadNotes2 = "COMID " + IDStr;
InflowLoad.ITSI = null;

if (TVol.AQTSeg.DynVelocity == null) TVol.AQTSeg.DynVelocity = new TLoadings();
Expand Down Expand Up @@ -1568,9 +1579,10 @@ public string PopulateLakeRes(int WBComid, string setupjson, bool daily, out str
/// </summary>
/// <param name="iSeg">index of segment being set up</param>
/// <param name="setupjson">string holding the master setup record</param>
/// <param name="mergeIDs">list of segments that were merged to this one</param>
/// <param name="jsondata">a json string holding the modified AQUATOX segment</param>
/// <returns>a blank string if no error, or error details otherwise</returns>
public string PopulateStreamNetwork(int iSeg, string setupjson, out string jsondata)
public string PopulateStreamNetwork(int iSeg, string setupjson, List<string> mergeIDs, out string jsondata)
{
jsondata = "";
string comid = SN.network[iSeg][0];
Expand All @@ -1587,19 +1599,37 @@ public string PopulateStreamNetwork(int iSeg, string setupjson, out string jsond
TSI.Geometry.GeometryMetadata["waterbody"] ="false";
TSI.Source = "nwm";

TVolume tvol = Sim.AQTSeg.GetStatePointer(AllVariables.Volume, T_SVType.StV, T_SVLayer.WaterCol) as TVolume;

try
{
TimeSeriesOutput<List<double>> TSO = submitHydrologyRequest(TSI, out string errstr);
if (errstr != "") return errstr;
avgRetention.Add(iSeg, StreamFlowsFromNWM(Sim.AQTSeg.GetStatePointer(AllVariables.Volume, T_SVType.StV, T_SVLayer.WaterCol) as TVolume,TSO)); //read stream flows and log avg. retention time
double RTime = StreamFlowsFromNWM(tvol, TSO, comid, false); // add stream flows to TVol
avgRetention.Add(iSeg,RTime); //read stream flows and log avg. retention time
}
catch (Exception ex)
{
return ex.Message;
return "Error reading NWM Data for comid "+comid+": "+ ex.Message;
}

jsondata = "";
foreach (string mergeID in mergeIDs)
{
try
{
TSI.Geometry.ComID = int.Parse(mergeID);
TimeSeriesOutput<List<double>> TSO = submitHydrologyRequest(TSI, out string errstr);
if (errstr != "") return errstr;
avgRetention[iSeg] += StreamFlowsFromNWM(tvol, TSO, mergeID, true); //read stream flows and add to avg. retention time
}
catch (Exception ex)
{
return "Error reading NWM Data for merged ID " + mergeID + ": " + ex.Message;
}
}


jsondata = "";
string errmessage = Sim.SaveJSON(ref jsondata);
return errmessage;
}
Expand Down Expand Up @@ -1744,7 +1774,7 @@ public string Pass_Data(AQTSim Sim, int SrcID, int ninputs, bool passMass, ref S
tot_flows[date] = inDomainFlow + boundFlow;
}
}
previous_flows = tot_flows; //save for next segment linkage if it exists
previous_flows = tot_flows;

return "";
}
Expand Down
20 changes: 15 additions & 5 deletions GUI/GUI.AQUATOX/MultiSegForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
using static AQUATOX.AQSim_2D.AQSim_2D;
using System.Globalization;
using System.Collections.Concurrent;
using DocumentFormat.OpenXml.Bibliography;
using Utilities;

namespace GUI.AQUATOX

Expand Down Expand Up @@ -733,6 +731,7 @@ await Task.Run(() =>
if (BaseFileN == "") return;

AQT2D.baseSimJSON = File.ReadAllText(BaseFileN);
AQT2D.avgRetention = new Dictionary<int, double>();
string msj = MasterSetupJson();

for (int iSeg = 1; iSeg <= AQT2D.nSegs; iSeg++)
Expand All @@ -742,20 +741,30 @@ await Task.Run(() =>

bool in_waterbody = false;
if (AQT2D.SN.waterbodies != null)
if (AQT2D.SN.waterbodies.comid_wb != null) in_waterbody = AQT2D.NWM_Waterbody(int.Parse(comid));
if (AQT2D.SN.waterbodies.comid_wb != null) in_waterbody = AQT2D.NWM_Waterbody(int.Parse(comid));
if (in_waterbody)
{
TSafeAddToProcessLog("INPUT: " + comid + " is not modeled as a stream segment as it is part of a lake/reservoir.");
continue;
}

string errmessage = AQT2D.PopulateStreamNetwork(iSeg, msj, out string jsondata);
List<string> merged = new List<string>();
if (AQT2D.SN.merged != null)
foreach (var merge in AQT2D.SN.merged)
if (merge[1] == comid) merged.Add(merge[0]); // which other comids have been merged into this one

string errmessage = AQT2D.PopulateStreamNetwork(iSeg, msj, merged, out string jsondata);

if (errmessage == "")
{
File.WriteAllText(filen, jsondata);
TSafeAddToProcessLog("INPUT: Read Volumes and Flows and Saved JSON for " + comid);
if (merged.Count > 0)
{
TSafeAddToProcessLog("INPUT: Added to " + comid + " merged segments " + string.Join(", ", merged));
}
TSafeUpdateProgress((int)((float)iSeg / (float)AQT2D.nSegs * 100.0));

}
else
{
Expand Down Expand Up @@ -2938,8 +2947,9 @@ async private void Link_HAWQS_Click(object sender, EventArgs e)
string MetafileN = BaseDir + "disaggregation_metadata.csv";
if (File.Exists(MetafileN)) metadata = File.ReadAllText(MetafileN);
string[] metadataLines = metadata.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

AQT2D.avgRetention = new Dictionary<int, double>();
Dictionary<long, Dictionary<DateTime, HAWQSRCHRow>> HAWQSRchData = new(); //nested dictionary to allow multi-key lookup by ID then date

void AddHAWQSRchData(long longKey, DateTime dateTimeKey, HAWQSRCHRow data) //add a reach and date to the nested dictionary
{
if (!HAWQSRchData.ContainsKey(longKey)) // Check if the outer dictionary already has the long key
Expand Down
2 changes: 1 addition & 1 deletion Web.Services/Models/WSAquatoxWorkflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public string CheckDependencies(AQTSim sim)
return "Invalid Time Series Output.";
}
// Update stream discharge for current segment simulation
StreamFlowsFromNWM(sim.AQTSeg.GetStatePointer(AllVariables.Volume, T_SVType.StV, T_SVLayer.WaterCol) as TVolume, TSO); //JSC 7/1/2021.
StreamFlowsFromNWM(sim.AQTSeg.GetStatePointer(AllVariables.Volume, T_SVType.StV, T_SVLayer.WaterCol) as TVolume, TSO,"",false); //JSC 7/1/2021.
break;
default:
return "Unrecognized dependency: " + item.Key;
Expand Down

0 comments on commit ed57739

Please sign in to comment.