/// <summary> /// Reads the particles and distributes them on the dictionaries /// </summary> /// <param name="shapefilename"></param> public IEnumerable <Particle> ReadParticleFile(string shapefilename, Func <DBFReader, int, SinkType, bool> ExcludeThis, bool DrainToBoundaryOption) { List <int> RedoxedParticles = new List <int>(); Dictionary <int, Particle> NonRedoxedParticles = new Dictionary <int, Particle>(); NewMessage("Reading particles from: " + shapefilename); int k = 0; using (DBFReader sr = new DBFReader(shapefilename)) { try { for (int i = 0; i < sr.NoOfEntries; i++) { int id = sr.ReadInt(i, "ID"); SinkType sinktype = (SinkType)Enum.Parse(typeof(SinkType), sr.ReadString(i, "SinkType")); if (sinktype == SinkType.Active_cell) //Do not create a new particle { RedoxedParticles.Add(id); } else if (ExcludeThis != null && ExcludeThis(sr, i, sinktype)) { k++; } else { Particle p = new Particle(); p.Registration = sr.ReadInt(i, "Registrati"); p.XStart = sr.ReadDouble(i, "X-Birth"); p.YStart = sr.ReadDouble(i, "Y-Birth"); p.ZStart = sr.ReadDouble(i, "Z-Birth"); p.X = sr.ReadDouble(i, "X-Reg"); p.Y = sr.ReadDouble(i, "Y-Reg"); p.Z = sr.ReadDouble(i, "Z-Reg"); p.TravelTime = sr.ReadDouble(i, "TravelTime"); p.SinkType = sinktype; NonRedoxedParticles.Add(id, p); if (DrainToBoundaryOption && p.SinkType == SinkType.Drain_to_Boundary) { p.X = p.XStart; p.Y = p.YStart; p.Z = p.ZStart; p.Registration = 0; } } } } catch (Exception e) { NewMessage("Error reading data"); } } int nosink = 0; //Set the registration on all particles that have be redoxed foreach (var pid in RedoxedParticles) { if (NonRedoxedParticles.ContainsKey(pid)) { NonRedoxedParticles[pid].Registration = 1; } else { nosink++; } } NewMessage("Excluded: " + k + " particles."); return(NonRedoxedParticles.Values); }
public override void Initialize(DateTime Start, DateTime End, IEnumerable <Catchment> Catchments) { base.Initialize(Start, End, Catchments); //Source, Catchment Dictionary <string, int> Sources = new Dictionary <string, int>(); Dictionary <string, XYPoint> PointSources = new Dictionary <string, XYPoint>(); List <XYPoint> points = new List <XYPoint>(); //Read in the points using (ShapeReader sr = new ShapeReader(ShapeFile.FileName)) { foreach (var gd in sr.GeoData) { XYPoint xp = gd.Geometry as XYPoint; if (!PointSources.ContainsKey(gd.Data[ShapeFile.ColumnNames[0]].ToString())) //Some sources are listed multiple times { if (gd.Data[ShapeFile.ColumnNames[1]].ToString() == "land") { PointSources.Add(gd.Data[ShapeFile.ColumnNames[0]].ToString(), gd.Geometry as XYPoint); } } } } NewMessage("Distributing sources in catchments"); //Distribute points on catchments Parallel.ForEach(PointSources, (p) => { foreach (var c in Catchments) { if (c.Geometry.Contains(p.Value.X, p.Value.Y)) { //if (c.CoastalZones.Any(co=>co.Contains(p.Value.X, p.Value.Y))) lock (Lock) Sources.Add(p.Key, c.ID); break; } } }); NewMessage(PointSources.Count + " point sources distributed on " + Sources.Values.Distinct().Count().ToString() + " catchments"); Dictionary <string, int> entries = new Dictionary <string, int>(); foreach (var source in Sources.Keys) { entries.Add(source, 0); } NewMessage("Reading outlet data"); //Read source data and distrubute on catchments using (DBFReader dbf = new DBFReader(DBFFile.FileName)) { int k = 0; for (int i = 0; i < dbf.NoOfEntries; i++) { string id = dbf.ReadString(i, DBFFile.ColumnNames[0]).Trim(); int year = dbf.ReadInt(i, DBFFile.ColumnNames[1]); double value = dbf.ReadDouble(i, DBFFile.ColumnNames[2]); int catchid; if (Sources.TryGetValue(id, out catchid)) { entries[id] += 1; Dictionary <int, double> timevalues; if (!YearlyData.TryGetValue(catchid, out timevalues)) { timevalues = new Dictionary <int, double>(); YearlyData.Add(catchid, timevalues); } if (timevalues.ContainsKey(year)) { timevalues[year] += value; } else { if (year >= Start.Year) //This also removes some -99 years { timevalues.Add(year, value); } } } else { //if we have outlet data but no source placed k++; } } NewMessage(k + " time series entries have no points"); } foreach (var c in YearlyData.Values) { foreach (var val in c.ToList()) { c[val.Key] = val.Value / ((DateTime.DaysInMonth(val.Key, 2) + 337.0) * 86400.0); } } NewMessage(entries.Values.Count(v => v == 0) + " points have no time series data"); NewMessage("Initialized"); }