private void InitializeReaderAndValues() { // Get rid of bogus variables variables = variables.Where(v => !String.IsNullOrWhiteSpace(v)).ToArray(); // Filename by convention string logPath = Path.Combine( DatabaseDriver.GetSessionDirectory(session), "residual-" + Norm + ".txt"); reader = new StreamReader(new FileStream( logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); // Read the zeroth line ==> header string headerline = reader.ReadLine(); string[] headerParts = headerline.Split(new char[] { '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < headerParts.Length; i++) { headerParts[i] = headerParts[i].TrimStart('\t', ' ').TrimEnd('\t', ' '); // remove leading and trailing whitespaces } // This specifies the column numbers we need to parse in each line. columnIndices = new List <int> { 0 }; // always extract the iteration number // Determine columnIndices: if (variables.Length == 0) { // No variables specified => use all columns columnIndices = Enumerable.Range(0, headerParts.Length).ToArray(); } else { //columnIndices = new int[variables.Length + 1]; //+1 because of iteration numbers // Compare headerParts to variables and receive the column // indices we need to parse. for (int i = 0; i < variables.Length; i++) // Loop over variables { string variable = variables[i]; // FindAll is useful if someone just wants to see all // the residuals that contain "u", e.g. "u_1", "u_2", ... int[] foundIndices = Array.FindAll(headerParts, col => col.Contains(variable)) .Select(entry => Array.IndexOf(headerParts, entry)) .ToArray(); foreach (int idx in foundIndices) { // index cannot be first column or nonexisting if (idx > 0) { columnIndices.Add(idx); } else { throw new ArgumentException("Invalid variable identifiers detected."); } } } } // Get rid of double entries columnIndices = columnIndices.Distinct().ToList(); // Overwrite this so we see the proper names of the variables used, // excluding the iteration number variables = columnIndices.Where(idx => idx > 0) .Select(idx => headerParts[idx]).ToArray(); // Initialize data fields, now that we know the number of variables Values = new Dictionary <string, IList <double> >(); Values.Add(headerParts[0], new List <double>()); for (int i = 1; i < columnIndices.Count; i++) { Values.Add(variables[i - 1], new List <double>()); } }