Projekt

Obecné

Profil

Stáhnout (10.7 KB) Statistiky
| Větev: | Tag: | Revize:
1
//
2
// Author: A. Konig
3
//
4

    
5
using ServerApp.Parser.InputData;
6
using ServerApp.Parser.OutputInfo;
7
using System;
8
using System.Collections.Generic;
9
using System.IO;
10

    
11
namespace ServerApp.Parser.Parsers
12
{
13
    /// <summary>
14
    /// Class parsing weather files into instances of WeatherInfo divided by given time interval
15
    /// Data parsed from 7am (included) to 18pm (included)
16
    /// </summary>
17
    /// <author>A. Konig</author>
18
    public class WeatherParser
19
    {
20

    
21
        /// <summary> Datafile loader  </summary>
22
        IDataLoader loader;
23

    
24
        /// <summary>
25
        /// Constructor
26
        /// </summary>
27
        /// <param name="loader">Datafile loader</param>
28
        public WeatherParser(IDataLoader loader)
29
        {
30
            this.loader = loader;
31
        }
32

    
33
        /// <summary>
34
        /// Parses weather data to WeatherInfo instances
35
        /// Data parsed from 7am (included) to 18pm (included)
36
        /// </summary>
37
        /// <param name="weatherFiles">Paths to files with weather data files</param>
38
        /// <param name="endTime">End time of related data</param>
39
        /// <param name="startTime">Start time of related data</param>
40
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
41
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
42
        /// <returns></returns>
43
        public List<WeatherInfo> ParseWeatherData(List<string> weatherFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
44
        {
45
            List<WeatherInfo> list = new List<WeatherInfo>();
46

    
47
            if (weatherFiles == null || interval <= 0)
48
                return list;
49

    
50
            string current = "";
51
            try
52
            {
53
                // get all files in folder
54
                foreach (string fileName in weatherFiles)
55
                {
56
                    current = fileName;
57

    
58
                    if (!File.Exists(fileName))
59
                        continue;
60

    
61
                    // parse as one instance per day
62
                    List<WeatherInfo> loadedData = null;
63
                    if (wholeDay)
64
                        loadedData = ProcessOneWeatherFileAsDays(fileName, startTime, endTime);
65
                    // parse according to interval
66
                    else
67
                    {
68
                        loadedData = ProcessOneWeatherFileAsIntervals(fileName, interval, startTime, endTime);
69
                    }
70

    
71
                    list.AddRange(loadedData);
72
                }
73
            } catch
74
            {
75
                Console.WriteLine("Incorrect Weather input file " + current);
76
            }
77

    
78
            return list;
79
        }
80

    
81
        /// <summary>
82
        /// Parses data from one data file as one instance per day
83
        /// </summary>
84
        /// <param name="path">Path ti file</param>
85
        /// <param name="endTime">End time of related data</param>
86
        /// <param name="startTime">Start time of related data</param>
87
        /// <returns>List with WeatherInfo instances</returns>
88
        private List<WeatherInfo> ProcessOneWeatherFileAsDays(string path, DateTime startTime, DateTime endTime)
89
        {
90
            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
91

    
92
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
93
            if (list == null || list.Count == 0)
94
                return weatherInfo;
95

    
96
            // array with data [temp, rain, wind, lum]
97
            double[] recordedAmount = new double[4];
98
            // min/max hour taken into account
99
            int[] minmaxHour = new int[] { 7, 18 };
100
            // interval length
101
            int range = minmaxHour[1] - minmaxHour[0];
102

    
103
            // first day
104
            DateTime lastStartDay = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
105
            // number of values in day
106
            int values = 0, weatherValues = 0;
107
            for (int i = 0; i < list.Count; i++)
108
            {
109
                int currHour = list[i].dateTime.Hour;
110
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
111
                    continue;
112

    
113
                // start of new day -> make a new instance
114
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
115
                if (!date.Equals(lastStartDay))
116
                {
117
                    WeatherInfo dayInfo = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / weatherValues, range); 
118
                    weatherInfo.Add(dayInfo);
119

    
120
                    recordedAmount = new double[4];
121
                    lastStartDay = date;
122
                    values = 0;
123
                    weatherValues = 0;
124
                }
125

    
126
                // if not in allowed time window -> discard
127
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
128
                {
129
                    continue;
130
                }
131

    
132
                // aggregate data
133
                recordedAmount[0] += list[i].temp;
134
                recordedAmount[1] += list[i].rain;
135
                recordedAmount[2] += list[i].wind;
136

    
137
                if (ValueToConditions.TransferLuxToConditions(list[i].lum * 1000) != WeatherConditions.Dark)
138
                {
139
                    recordedAmount[3] += list[i].lum * 1000; weatherValues++;
140
                }
141

    
142
                values++;
143
            }
144

    
145
            // data from last day
146
            if (values != 0)
147
            {
148
                WeatherInfo dayInfo2 = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / weatherValues, range);
149
                weatherInfo.Add(dayInfo2);
150
            }
151

    
152
            return weatherInfo;
153
        }
154

    
155
        /// <summary>
156
        /// Parses data from one data file as one instance per interval length
157
        /// </summary>
158
        /// <param name="path">Path to file</param>
159
        /// <param name="interval">Interval length</param>
160
        /// <param name="endTime">End time of related data</param>
161
        /// <param name="startTime">Start time of related data</param>
162
        /// <returns>List with ActivityInfo instances</returns>
163
        private List<WeatherInfo> ProcessOneWeatherFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
164
        {
165
            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
166

    
167
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
168
            if (list == null || list.Count == 0)
169
                    return weatherInfo;
170

    
171
            // min/max hour taken into account
172
            int[] minmaxHour = new int[] { 7, 18 };
173
            int range = minmaxHour[1] - minmaxHour[0];
174

    
175
            if (interval > range)
176
                return null;
177

    
178
            int indices = (int)Math.Ceiling(range / (double)interval);
179
            int[] to = new int[indices];
180
            double[][] data = new double[indices][];
181
            int[] count = new int[indices];
182
            for (int i = 0; i < to.Length; i++)
183
            {
184
                to[i] = minmaxHour[0] + interval * (i + 1);
185
                data[i] = new double[4];
186
                count[i] = 0;
187
            }
188

    
189
            // first day
190
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
191
            int index;
192
            for (int i = 0; i < list.Count; i++)
193
            {
194
                int currHour = list[i].dateTime.Hour;
195
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
196
                    continue;
197

    
198
                // start of the day -> make an instance
199
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, list[i].dateTime.Hour, 0, 0);
200

    
201
                // end of the day
202
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
203
                {
204
                    // note down all aggregated data
205
                    for (int k = 0; k < to.Length; k++)
206
                    {
207
                        int raincount = 0;
208
                        double rainval = 0;;
209
                        for (int l = 0; l <= k; l++)
210
                        {
211
                            raincount += count[l];
212
                            rainval += data[l][1];
213
                        }
214

    
215
                        DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
216

    
217
                        WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
218
                        if (count[k] != 0)
219
                            weatherInfo.Add(intervalInfo);
220

    
221
                    }
222

    
223
                    lastStartTime = date;
224
                    count = new int[indices];
225
                    for (int l = 0; l < data.Length; l++)
226
                    {
227
                        data[l] = new double[4];
228
                        count[l] = 0;
229
                    }
230
                }
231

    
232
                // if not in allowed time window -> discard
233
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
234
                    continue;
235

    
236
                // find index for current instance
237
                index = 0;
238
                for (int k = 1; k < to.Length; k++)
239
                {
240
                    if (to[k] > list[i].dateTime.Hour && to[k - 1] <= list[i].dateTime.Hour)
241
                    {
242
                        index = k;
243
                        break;
244
                    }
245
                }
246

    
247
                // aggregate data
248
                data[index][0] += list[i].temp;
249
                data[index][1] += list[i].rain;
250
                data[index][2] += list[i].wind;
251
                data[index][3] += list[i].lum * 1000;
252
                count[index]++;
253

    
254
            }
255

    
256
            for (int k = 0; k < to.Length; k++)
257
            {
258
                int raincount = 0;
259
                double rainval = 0; ;
260
                for (int l = 0; l <= k; l++)
261
                {
262
                    raincount += count[l];
263
                    rainval += data[l][1];
264
                }
265

    
266
                DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
267

    
268
                WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
269
                if (count[k] != 0)
270
                    weatherInfo.Add(intervalInfo);
271
            }
272

    
273
            return weatherInfo;
274
        }
275
    }
276

    
277
}
(6-6/6)