Projekt

Obecné

Profil

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

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

    
12
namespace ServerApp.Parser.Parsers
13
{
14
    /// <summary>
15
    /// Class parsing jis files into instances of ActivityInfo divided by given time interval
16
    /// Data parsed from 7am (included) to 18pm (included)
17
    /// </summary>
18
    /// <author>A. Konig</author>
19
    public class JisParser
20
    {
21
        /// <summary> Logger </summary>
22
        private static readonly ILog _log = LogManager.GetLogger(typeof(JisParser));
23

    
24
        /// <summary> Datafile loader  </summary>
25
        IDataLoader loader;
26

    
27
        /// <summary>
28
        /// Constructor
29
        /// </summary>
30
        /// <param name="loader">Datafile loader</param>
31
        public JisParser(IDataLoader loader)
32
        {
33
            this.loader = loader;
34
        }
35

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

    
50
            if (jisFiles == null || interval <= 0)
51
                return list;
52

    
53
            string current = "";
54
            try
55
            {
56
                // parse all files
57
                foreach (string fileName in jisFiles)
58
                {
59
                    current = fileName;
60

    
61
                    if (!File.Exists(fileName))
62
                        continue;
63

    
64
                    // parse as one instance per day
65
                    List<ActivityInfo> loadedData = null;
66
                    if (wholeDay)
67
                        loadedData = ProcessOneJisFileAsDays(fileName, startTime, endTime);
68
                    // parse by interval length
69
                    else
70
                        loadedData = ProcessOneJisFileAsIntervals(fileName, interval, startTime, endTime);
71

    
72
                    list.AddRange(loadedData);
73
                }
74
            }
75
            catch
76
            {
77
                _log.Error("Incorrect jis input file " + current);
78
            }
79

    
80
            return list;
81
        }
82

    
83
        /// <summary>
84
        /// Parses data from one data file as one instance per day
85
        /// </summary>
86
        /// <param name="path">Path to file</param>
87
        /// <param name="endTime">End time of related data</param>
88
        /// <param name="startTime">Start time of related data</param>
89
        /// <returns>List with ActivityInfo instances</returns>
90
        private List<ActivityInfo> ProcessOneJisFileAsDays(string path, DateTime startTime, DateTime endTime)
91
        {
92
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
93
            
94
            List<JisInstance> list =  loader.LoadJisFile(path);
95
            if (list == null || list.Count == 0)
96
                return jisInfo;
97

    
98
            // data for each faculty
99
            int[] recordedAmount = new int[TagInfo.buildings.Length];
100
            // min/max hour taken into account
101
            int[] minmaxHour = new int[] { 7, 18 };
102
            // interval length
103
            int range = minmaxHour[1] - minmaxHour[0];
104

    
105
            // first day
106
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 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 the day -> make an instance
114
                string place = list[i].placeTag;
115
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
116
                if (!date.Equals(lastStartTime)) 
117
                {
118
                    // data for each faculty separate
119
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
120
                    {
121
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartTime, range);
122
                        if (recordedAmount[k] != 0)
123
                            jisInfo.Add(dayInfo);
124
                    }
125

    
126
                    recordedAmount = new int[TagInfo.buildings.Length];
127
                    lastStartTime = date;
128
                }
129

    
130
                // if not in allowed time window -> discard
131
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
132
                    continue;
133

    
134
                // aggregate data
135
                if (TagInfo.jisPlaces.ContainsKey(place))
136
                {
137
                    int index = TagInfo.jisPlaces[place];
138
                    if (index == -1)
139
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
140
                            recordedAmount[l] += list[i].amount;
141
                    else
142
                        recordedAmount[index] += list[i].amount;
143

    
144
                }
145
                else
146
                {
147
                    _log.Warn("Unknown code " + list[i].placeTag);
148
                }
149

    
150
            }
151

    
152
            // last day
153
            for (int k = 0; k < TagInfo.buildings.Length; k++)
154
            {
155
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartTime, range);
156
                if (recordedAmount[k] != 0)
157
                    jisInfo.Add(dayInfo);
158
            }
159

    
160
            return jisInfo;
161
        }
162

    
163
        /// <summary>
164
        /// Parses data from one data file as instance per interval length in a day
165
        /// </summary>
166
        /// <param name="path">Path ti file</param>
167
        /// <param name="interval">Interval length</param>
168
        /// <param name="endTime">End time of related data</param>
169
        /// <param name="startTime">Start time of related data</param>
170
        /// <returns>List with ActivityInfo instances</returns>
171
        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
172
        {
173
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
174

    
175
            List<JisInstance> list = loader.LoadJisFile(path);
176
            if (list == null || list.Count == 0)
177
                return jisInfo;
178

    
179
            // data for each faculty
180
            int[] recordedAmount = new int[TagInfo.buildings.Length];
181
            // min/max hour taken into account
182
            int[] minmaxHour = new int[] { 7, 18 };
183
            int range = minmaxHour[1] - minmaxHour[0];
184

    
185
            if (interval > range)
186
                return null;
187

    
188
            int indices = (int) Math.Ceiling(range / (double)interval);
189
            int[] to = new int[indices];
190
            for (int i = 0; i < to.Length; i++) 
191
                to[i] = minmaxHour[0] + interval * (i+1);
192

    
193
            // first day
194
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
195
            int endtime = to[0];
196
            int startingTime = minmaxHour[0];
197
            int index = 0;
198
            for (int i = 0; i < list.Count; i++)
199
            {
200
                int currHour = list[i].dateTime.Hour;
201
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
202
                    continue;
203

    
204
                // start of the day -> make an instance
205
                string place = list[i].placeTag;
206
                bool trigger = false;
207
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, list[i].dateTime.Hour, 0, 0);
208

    
209
                // end of the day
210
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
211
                {
212
                    trigger = true;
213
                    index = 0;
214
                }
215

    
216
                // end of interval period
217
                if ( date.Hour >= endtime || trigger) 
218
                {
219
                    // start time of last interval
220
                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
221

    
222
                    // find end and start time
223
                    if (!trigger)
224
                        index++;
225
                    while (date.Hour >= to[index])
226
                        index++;
227

    
228
                    endtime = to[index];
229
                    if (index == 0)
230
                        startingTime = minmaxHour[0];
231
                    else
232
                        startingTime = to[index - 1];
233

    
234
                    // data for each faculty separate
235
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
236
                    {
237
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], stTime, interval);
238
                        if (recordedAmount[k] != 0)
239
                            jisInfo.Add(dayInfo);
240
                    }
241

    
242
                    recordedAmount = new int[TagInfo.buildings.Length];
243
                    lastStartTime = date;
244
                }
245

    
246
                // if not in allowed time window -> discard
247
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
248
                    continue;
249

    
250
                // aggregate data
251
                if (TagInfo.jisPlaces.ContainsKey(place))
252
                {
253
                    int faculty = TagInfo.jisPlaces[place];
254
                    if (faculty == -1)
255
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
256
                            recordedAmount[l] += list[i].amount;
257
                    else
258
                        recordedAmount[faculty] += list[i].amount;
259

    
260
                }
261
                else
262
                {
263
                    _log.Warn("Unknown code " + list[i].placeTag);
264
                }
265

    
266
            }
267

    
268
            // last day
269
            DateTime startT = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
270
            for (int k = 0; k < TagInfo.buildings.Length; k++)
271
            {
272
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], startT, interval);
273
                if (recordedAmount[k] != 0)
274
                    jisInfo.Add(dayInfo);
275
            }
276

    
277
            return jisInfo;
278
        }
279
    }
280
}
(3-3/6)