using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.IO; using WebApplication3.Models; using System.Globalization; using Microsoft.VisualBasic.FileIO; namespace WebApplication3.Clases { public class Parser { public WellData[] ParseWellData(string textFile) { if (File.Exists(textFile)) { StreamReader file = new StreamReader(textFile); //WellData[] wellData = null; List wellDataList = null; WellData wellData = null; string ln; int cont = 0; int index = 0; bool intervalSkipped = false; int finalBloque = 0; string[] values; while ((ln = file.ReadLine()) != null) { if (wellData == null) { //wellData = new WellData[int.Parse(ln)]; wellDataList = new List(int.Parse(ln)); wellData = new WellData(); cont++; continue; } if (!intervalSkipped) { switch (cont) { case 1: //wellData[index].ActiveFlag = (ln == "0") ? false : true; wellData.ActiveFlag = ln != "0"; break; case 2: //wellData[index].WellName = ln; wellData.WellName = ln; break; case 3: //wellData[index].X = double.Parse(ln); wellData.X = ln; break; case 4: //wellData[index].Y = double.Parse(ln); wellData.Y = ln; break; case 5: //wellData[index].ZMin = ln; values = ln.Split(" "); wellData.ZMin = values[0].Replace(".", ","); break; case 6: //wellData[index].ZMax = ln; values = ln.Split(" "); wellData.ZMax = values[0].Replace(".", ","); break; case 7: //wellData[index].ScreenIntervals = int.Parse(ln); wellData.ScreenIntervals = int.Parse(ln); //cont += (wellData[index].ScreenIntervals * 2) - 1; intervalSkipped = true; //leemos tantas lineas hay como intervalos de pantalla (al ser 2 parametros por cada intervalo es nIntervalos * 2 List linesAux = new(); for (int i = 0; i < wellData.ScreenIntervals * 2; i++) { linesAux.Add(file.ReadLine()); cont++; } wellData.Bot = linesAux[0]; wellData.Top = linesAux[1]; break; default: break; } } else { //if (wellData[index].PumpPeriods == 0) if (wellData.PumpPeriods == 0) { //wellData[index].PumpPeriods = int.Parse(ln); wellData.PumpPeriods = int.Parse(ln); //se calcula en que linea termina el bloque del pozo //finalBloque = cont + wellData[index].PumpPeriods + 1; finalBloque = cont + 1 + wellData.PumpPeriods * 3; } else { TimeSerieInterno ts = new TimeSerieInterno(); //string aux = ""; //Rate rate = new Rate(); ts.Hora = ln; //rate.StartTime = float.Parse(ln.Replace('.', ',')); ln = file.ReadLine(); ts.HoraEnd = ln; cont++; //if(cont == finalBloque - 1) //{ // aux = ln; //} ln = file.ReadLine(); cont++; //Separamos la cadena por " " //TODO -> igual es un \t string[] exploded = ln.Split(" "); //Solo nos interesa el primer valor string value = exploded[0].Replace('.', ','); ts.Valor = value; ts.Info = ln.Replace(exploded[0] + ' ', ""); //rate.Value = double.Parse(value); //wellData[index].Rates.Add(rate); wellData.Rates.Add(ts); //if(aux != "") //{ // ts = new TimeSerieInterno(); // ts.Hora = aux; // ts.Valor = value; // ts.Info = ln.Replace(exploded[0] + ' ', ""); // wellData.Rates.Add(ts); //} } } cont++; //hemos llegado al final del primer bloque de pozo, preparamos para el siguiente if (finalBloque == cont) { intervalSkipped = false; index++; wellDataList.Add(wellData); wellData = new WellData(); cont = 1; } } file.Close(); return wellDataList.ToArray(); } return null; } public RechargeData[] ParseRechargeData(string textFile,out string recharge_geometry) { List recharges = new List(); RechargeData rechargeData = null; TimeSerieInterno timeSerie; string rechargeProperty=""; recharge_geometry = ""; if (File.Exists(textFile)) { Console.WriteLine("File exist"); string text = File.ReadAllText(textFile); string[] data = text.Split("\r\n\r\n"); int layers = int.Parse(data[0][0].ToString()); int blankLinePerBlock = layers + 1; int rechargeBlockInex = blankLinePerBlock * 2; Console.WriteLine(data[rechargeBlockInex]); string[] explode = data[rechargeBlockInex].Split("\r\n"); for (int i = 1; i < explode.Length; i++) { string[] values = explode[i].Split(" ", StringSplitOptions.RemoveEmptyEntries); //Si hay cambio de propiedad se crea otro RechargeData if (rechargeProperty != values[0]) { if (rechargeProperty != "") { recharges.Add(rechargeData); } rechargeData = new RechargeData(); rechargeData.Nombre = "Recarga_" + values[0]; rechargeProperty = values[0]; //Al hacer el cambio i += 2; values = explode[i].Split(" ", StringSplitOptions.RemoveEmptyEntries); } timeSerie = new TimeSerieInterno(); timeSerie.Hora = values[2]; timeSerie.HoraEnd = values[3]; timeSerie.Valor = values[1]; timeSerie.Info = values[4] + " " + values[5]; rechargeData.Rates.Add(timeSerie); ////se anyade el ultimo registro de tiempo ya que solo nos quedamos con la primera marca de tiempo de cada linea //if(i == explode.Length - 1) //{ // timeSerie = new TimeSerieInterno(); // timeSerie.Hora = values[3]; // timeSerie.Valor = values[1]; // timeSerie.Info = values[4] + " " + values[5]; // rechargeData.Rates.Add(timeSerie); //} } recharge_geometry = data[rechargeBlockInex + layers]; //Se anyade la ultima instancia de rechargeData ya que no se produce cambio en la ultima iteracion del bucle recharges.Add(rechargeData); return recharges.ToArray(); } else { Console.WriteLine("File does not exist"); } return null; } public List ParseInFile(string textFile) { Console.WriteLine("File exist"); string text = File.ReadAllText(textFile); List lines = new(); List aux = new(); //Introducimos todas las lineas aux.AddRange(text.Split("\r\n").ToList()); //Se eliminan las referencias a ficheros que no son validos para el modelo aux.RemoveAll(x => x.Contains("WHS") || x.Contains("NDC") || x.Contains("CLB") || x == ""); List units = new(); foreach (string row in aux) { if (!aux.Contains("LIST")) { string[] rowSplit = row.Split(" ", StringSplitOptions.RemoveEmptyEntries); units.Add(rowSplit[1]); } } foreach (string row in aux) { string[] rowSplit = row.Split(" ", StringSplitOptions.RemoveEmptyEntries); Console.WriteLine(rowSplit); if (rowSplit[0] == "LIST" && int.Parse(rowSplit[1]) < 10) { if (!units.Contains("11")) { rowSplit[1] = "11"; } else if (!units.Contains("12")) { rowSplit[1] = "12"; } else if (!units.Contains("13")) { rowSplit[1] = "13"; } else if (!units.Contains("14")) { rowSplit[1] = "14"; } } //Se tiene que parsear la 3a parte del string porque contiene la ruta absoluta del ordenador donde se han originado los ficheros List ficheroSplit = rowSplit[2].Split("\\").ToList(); rowSplit[2] = ficheroSplit.Last(); lines.Add(rowSplit[0] + " " + rowSplit[1] + " " + rowSplit[2]); } return lines; } public ZoneBalance[] ParseZonesBalance(string textFile) { List zonesOutput = new List(); string text = File.ReadAllText(textFile); string[] data = text.Split(" test \r\n \r\n", StringSplitOptions.RemoveEmptyEntries); List data_aux = data[1].Split("\r\n").ToList(); string zones = data_aux.Find(x => x.Contains("zones")); int index = data_aux.IndexOf(zones); string[] zone_names = data_aux[index + 1].Split(" ", StringSplitOptions.RemoveEmptyEntries); int zonesConectionPerZone = zone_names.Length - 1; Logger logger = Logger.GetInstance(); for (int z = 2; z < data.Length; z++) { List balanceData = data[z].Split("\r\n", StringSplitOptions.RemoveEmptyEntries).ToList(); ZoneBalance zoneBalance = new ZoneBalance(); string storage, constantHead, drains, recharge, total, percentDisparity; string auxFind, auxSplit, zoneConnectionLine; string[] split; split = balanceData[0].Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries); zoneBalance.Zone = split[4]; zoneBalance.StressPeriod = int.Parse(split[12]); #region IN //buscamos el indice en el cual empieza el bloque de los datos de salida auxFind = balanceData.Find(x => x.Contains("IN:")); index = balanceData.IndexOf(auxFind); //el primer dado del bloque se encuentra 2 indices despues del obtenido index += 2; auxSplit = balanceData[index].Split("STORAGE =")[1]; storage = auxSplit; index++; auxSplit = balanceData[index].Split("CONSTANT HEAD =")[1].Trim(); constantHead = auxSplit; index++; auxSplit = balanceData[index].Split("DRAINS =")[1].Trim(); drains = auxSplit; index++; auxSplit = balanceData[index].Split("RECHARGE =")[1].Trim(); recharge = auxSplit; index++; //Zone connections for (int i = index; i < index + zonesConectionPerZone; i++) { zoneConnectionLine = balanceData[i].Trim(); split = zoneConnectionLine.Split("to"); ZoneConnection zoneConnection = new ZoneConnection(); zoneConnection.From = split[0].Split("Zone")[1].Trim(); zoneConnection.To = split[1].Split("=")[0].Trim(); zoneConnection.Value = split[1].Split("=")[1].Trim(); zoneBalance.In.ZoneConnections.Add(zoneConnection); } //Para el total hay que buscar el indice porque al haber fluctuacion entre zonas no podemos saber el indice fijo de la linea donde se encuentra de forma directa auxFind = balanceData.Find(x => x.Contains("Total IN")); index = balanceData.IndexOf(auxFind); auxSplit = balanceData[index].Split("Total IN =")[1].Trim(); total = auxSplit; zoneBalance.In.Storage = storage; zoneBalance.In.ConstantHead = constantHead; zoneBalance.In.Drains = drains; zoneBalance.In.Recharge = recharge; zoneBalance.In.Total = total; #endregion #region OUT //buscamos el indice en el cual empieza el bloque de los datos de salida auxFind = balanceData.Find(x => x.Contains("OUT:")); index = balanceData.IndexOf(auxFind); //el primer dado del bloque se encuentra 2 indices despues del obtenido index += 2; auxSplit = balanceData[index].Split("STORAGE =")[1]; storage = auxSplit; index++; auxSplit = balanceData[index].Split("CONSTANT HEAD =")[1].Trim(); constantHead = auxSplit; index++; auxSplit = balanceData[index].Split("DRAINS =")[1].Trim(); drains = auxSplit; index++; auxSplit = balanceData[index].Split("RECHARGE =")[1].Trim(); recharge = auxSplit; index++; //Zone connections for (int i = index; i < index + zonesConectionPerZone; i++) { zoneConnectionLine = balanceData[i].Trim(); split = zoneConnectionLine.Split("to"); ZoneConnection zoneConnection = new ZoneConnection(); zoneConnection.From = split[0].Split("Zone")[1].Trim(); zoneConnection.To = split[1].Split("=")[0].Trim(); zoneConnection.Value = split[1].Split("=")[1].Trim(); zoneBalance.Out.ZoneConnections.Add(zoneConnection); } //Para el total hay que buscar el indice porque al haber fluctuacion entre zonas no podemos saber el indice fijo de la linea donde se encuentra de forma directa auxFind = balanceData.Find(x => x.Contains("Total OUT")); index = balanceData.IndexOf(auxFind); auxSplit = balanceData[index].Split("Total OUT =")[1].Trim(); total = auxSplit; zoneBalance.Out.Storage = storage; zoneBalance.Out.ConstantHead = constantHead; zoneBalance.Out.Drains = drains; zoneBalance.Out.Recharge = recharge; zoneBalance.Out.Total = total; #endregion auxFind = balanceData.Find(x => x.Contains("IN - OUT")); index = balanceData.IndexOf(auxFind); auxSplit = balanceData[index].Split("IN - OUT = ")[1].Trim(); total = auxSplit; auxFind = balanceData.Find(x => x.Contains("Percent Discrepancy = ")); index = balanceData.IndexOf(auxFind); auxSplit = balanceData[index].Split("Percent Discrepancy = ")[1].Trim(); percentDisparity = auxSplit; zoneBalance.TotalInOut = total; zoneBalance.PercentDiscrepancy = percentDisparity; zonesOutput.Add(zoneBalance); } return zonesOutput.ToArray(); } public ZoneBalance[] ParseWholeModelBalance(string textfile) { string text = File.ReadAllText(textfile); string[] data = text.Split(" DRAWDOWN WILL BE SAVED ON UNIT 151 AT END OF TIME STEP 10, STRESS PERIOD", StringSplitOptions.RemoveEmptyEntries); List zoneBalances = new List(); for (int i = 1; i < data.Length; i++) { ZoneBalance cummulative = new ZoneBalance(); ZoneBalance current = new ZoneBalance(); cummulative.Zone = "Zone 0"; cummulative.StressPeriod = i; cummulative.Type = 1; current.Zone = "Zone 0"; current.StressPeriod = i; current.Type = 2; List data_aux = data[i].Split("\r\n", StringSplitOptions.RemoveEmptyEntries).ToList(); string[] split = data_aux[2].Split("STRESS PERIOD", StringSplitOptions.RemoveEmptyEntries); #region IN split = data_aux[8].Split("STORAGE =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.Storage = split[1].Trim(); current.In.Storage = split[2].Trim(); split = data_aux[9].Split("CONSTANT HEAD =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.ConstantHead = split[1].Trim(); current.In.ConstantHead = split[2].Trim(); if (data_aux[10].Contains("DRAINS")) { split = data_aux[10].Split("DRAINS =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.Drains = split[1].Trim(); current.In.Drains = split[2].Trim(); } else { split = data_aux[10].Split("WELLS =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.Wells = split[1].Trim(); current.In.Wells = split[2].Trim(); } split = data_aux[11].Split("RECHARGE =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.Recharge = split[1].Trim(); current.In.Recharge = split[2].Trim(); split = data_aux[13].Split("TOTAL IN =", StringSplitOptions.RemoveEmptyEntries); cummulative.In.Total = split[1].Trim(); current.In.Total = split[2].Trim(); #endregion #region OUT split = data_aux[16].Split("STORAGE =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.Storage = split[1].Trim(); current.Out.Storage = split[2].Trim(); split = data_aux[17].Split("CONSTANT HEAD =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.ConstantHead = split[1].Trim(); current.Out.ConstantHead = split[2].Trim(); if (data_aux[18].Contains("DRAINS")) { split = data_aux[18].Split("DRAINS =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.Drains = split[1].Trim(); current.Out.Drains = split[2].Trim(); } else { split = data_aux[18].Split("WELLS =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.Wells = split[1].Trim(); current.Out.Wells = split[2].Trim(); } split = data_aux[19].Split("RECHARGE =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.Recharge = split[1].Trim(); current.Out.Recharge = split[2].Trim(); split = data_aux[21].Split("TOTAL OUT =", StringSplitOptions.RemoveEmptyEntries); cummulative.Out.Total = split[1].Trim(); current.Out.Total = split[2].Trim(); #endregion split = data_aux[22].Split("IN - OUT =", StringSplitOptions.RemoveEmptyEntries); cummulative.TotalInOut = split[1].Trim(); current.TotalInOut = split[2].Trim(); split = data_aux[23].Split("PERCENT DISCREPANCY =", StringSplitOptions.RemoveEmptyEntries); cummulative.PercentDiscrepancy = split[1].Trim(); current.PercentDiscrepancy = split[2].Trim(); zoneBalances.Add(cummulative); zoneBalances.Add(current); } return zoneBalances.ToArray(); } public List ParseBinaryFile(string file, uint? simulacionId) { List piezometria = new List(); Logger.WriteLog("Parseando fichero binario"); if (File.Exists(file)) { try { using (FileStream fs = new FileStream(file, FileMode.Open)) using (BinaryReader brr = new BinaryReader(fs)) { Logger.WriteLog("Fichero existente y abierto"); while (fs.Length != fs.Position) // This will throw an exception for non-seekable streams (stream.CanSeek == false), but filestreams are seekable so it's OK here { Piezometria p = new(); p.IdSimulacion = simulacionId; int KSTP = brr.ReadInt32(); int KPER = brr.ReadInt32(); var PERTIM = brr.ReadSingle(); var TOTIM = brr.ReadSingle(); char[] auxDESC = brr.ReadChars(16); string DESC = new(auxDESC); int NCOL = brr.ReadInt32(); int NROW = brr.ReadInt32(); int ILAY = brr.ReadInt32(); p.Layer = ILAY; p.StressPeriod = KPER; p.Rows = NROW; p.Columns = NCOL; List values = new(); for (int i = 0; i < NROW * NCOL; i++) { values.Add(brr.ReadSingle()); } int c = 1; string original = ""; string convertida = ""; foreach (float v in values) { if (c < NCOL) { original += v + " "; //Check for range + color conversion //convertida += Constants.piezometry_conversion[v.ToString()] + ","; } else if (c == NCOL) { //Add \n to the string original += "\n"; //convertida += "\n"; c = 0; } c++; } p.Original = original; p.Convertida = convertida; piezometria.Add(p); } Logger.WriteLog("Ya se ha leido el fichero"); } }catch(Exception ex) { Logger.WriteLog(ex.Message); Logger.WriteLog(ex.InnerException.Message); } } return piezometria; } public void GetGeolocalizationFromFile(string file,out string worldX,out string worldY, out string angle, out string length, out string height) { string[] world_origin_x, world_origin_y, modelAngle, modelLength, modelHeight; worldX = worldY = angle = length = height = ""; string text = File.ReadAllText(file); List data = text.Split("\r\n", StringSplitOptions.RemoveEmptyEntries).ToList(); //string geolocationData = data[2]; string geolocation_line = data.Find(x => x.Contains(" geolocation_data = geolocation_line.Split(" ", StringSplitOptions.RemoveEmptyEntries).ToList(); string wox = geolocation_data.Find(x => x.Contains("World_Origin_X=")); if(wox != null) { world_origin_x = wox.Split("World_Origin_X=", StringSplitOptions.RemoveEmptyEntries); worldX = world_origin_x[0].Replace("\"", string.Empty); } string woy = geolocation_data.Find(x => x.Contains("World_Origin_Y=")); if (wox != null) { world_origin_y = woy.Split("World_Origin_Y=", StringSplitOptions.RemoveEmptyEntries); worldY = world_origin_y[0].Replace("\"", string.Empty); } string magl = geolocation_data.Find(x => x.Contains("Angle=")); if (magl != null) { modelAngle = magl.Split("Angle=", StringSplitOptions.RemoveEmptyEntries); angle = modelAngle[0].Replace("\"", string.Empty); } string mlgth = geolocation_data.Find(x => x.Contains("Length=")); if (mlgth != null) { modelLength = mlgth.Split("Length=", StringSplitOptions.RemoveEmptyEntries); length = modelLength[0].Replace("\"", string.Empty); } string mhei = geolocation_data.Find(x => x.Contains("Height=")); if (mhei != null) { modelHeight = mhei.Split("Height=", StringSplitOptions.RemoveEmptyEntries); height = modelHeight[0].Replace("\"", string.Empty); height = height.Replace("/>", string.Empty); } } public WellData[] parseWellCSV(string file) { List wellsData = new(); WellData wellData = null; using (TextFieldParser csvParser = new TextFieldParser(file)) { csvParser.CommentTokens = new string[] { "#" }; csvParser.SetDelimiters(new string[] { "," }); csvParser.HasFieldsEnclosedInQuotes = true; // Skip the row with the column names csvParser.ReadLine(); string wellName = ""; string[] aux = Array.Empty(); TimeSerieInterno tsInterno; int pumpPeriods = 0; while (!csvParser.EndOfData) { // Read current line fields, pointer moves to the next line. string[] fields = csvParser.ReadFields(); if (wellName != fields[0]) { if (wellName == "") { aux = new string[fields.Length]; } else { wellData.PumpPeriods = pumpPeriods; wellsData.Add(wellData); tsInterno = new(); tsInterno.Hora = aux[11]; tsInterno.Valor = aux[12]; wellData.Rates.Add(tsInterno); pumpPeriods = 0; } wellData = new(); wellData.WellName = fields[0]; wellData.X = fields[1]; wellData.Y = fields[2]; wellData.Top = fields[5]; wellData.Bot = fields[6]; wellData.ZMin = fields[4]; wellData.ZMax = fields[3]; wellData.ScreenIntervals = 1; //wellData.ZMin = ""; //wellData.ZMax = ""; wellData.ActiveFlag = false; wellName = fields[0]; } tsInterno = new (); tsInterno.Hora = fields[10]; tsInterno.Valor = fields[12]; wellData.Rates.Add(tsInterno); fields.CopyTo(aux, 0); pumpPeriods++; } wellData.PumpPeriods = pumpPeriods; tsInterno = new(); tsInterno.Hora = aux[11]; tsInterno.Valor = aux[12]; wellData.Rates.Add(tsInterno); wellsData.Add(wellData); } return wellsData.ToArray(); } public RechargeData[] parseRechargeCSV(string file) { List rechargeDatas = new(); RechargeData rechargeData = new(); TimeSerieInterno ts; string[] aux = Array.Empty(); using (TextFieldParser csvParser = new TextFieldParser(file)) { csvParser.CommentTokens = new string[] { "#" }; csvParser.SetDelimiters(new string[] { "," }); csvParser.HasFieldsEnclosedInQuotes = true; // Skip the row with the column names csvParser.ReadLine(); while (!csvParser.EndOfData) { // Read current line fields, pointer moves to the next line. string[] fields = csvParser.ReadFields(); if(rechargeData.Nombre == null) { rechargeData.Nombre = fields[0]; aux = new string[fields.Length]; } ts = new(); ts.Valor = fields[3]; ts.Hora = fields[1]; //ts.HoraEnd = fields[2]; rechargeData.Rates.Add(ts); fields.CopyTo(aux, 0); } ts = new(); ts.Valor = aux[3]; ts.Hora = aux[2]; //ts.HoraEnd = fields[2]; rechargeData.Rates.Add(ts); rechargeDatas.Add(rechargeData); } return rechargeDatas.ToArray(); } public PiezometerData[] parsePiezometerCSV(string file) { List piezometerDatas = new(); PiezometerData piezometerData = null; TimeSerieInterno ts; string[] aux = Array.Empty(); string piezometerName = ""; using (TextFieldParser csvParser = new TextFieldParser(file)) { csvParser.CommentTokens = new string[] { "#" }; csvParser.SetDelimiters(new string[] { "," }); csvParser.HasFieldsEnclosedInQuotes = true; // Skip the row with the column names csvParser.ReadLine(); while (!csvParser.EndOfData) { // Read current line fields, pointer moves to the next line. string[] fields = csvParser.ReadFields(); if (piezometerName != fields[0]) { if(piezometerName == "") { aux = new string[fields.Length]; }else { } piezometerData = new(); piezometerData.Name = fields[0]; piezometerData.X = fields[1]; piezometerData.Y = fields[2]; piezometerData.Z = fields[3]; piezometerData.Prof = fields[4]; piezometerData.Screen_top = fields[5]; piezometerData.Screen_bot = fields[6]; } ts = new(); ts.DateIn = fields[8]; ts.Hora = fields[9]; ts.Valor = fields[10]; piezometerData.Rates.Add(ts); //fields.CopyTo(aux, 0); } } return piezometerDatas.ToArray(); } public bool ModflowError(string file) { string text = File.ReadAllText(file).ToLower(); if (!text.Contains("error")) { return false; } return true; } } }