clearer names for actions, and infer actions better
[monitor.git] / statistics / functions.r
1 slices <- function (x, components=FALSE) 
2 {
3     m<-x$memsize;
4     d<-x$disksize/250;
5     c<-x$cpuspeed;
6     r<-x$numcores;
7     if ( components ) {
8         a<-c(m,d,c*r);
9     } else {
10         a<-(m+d+c*r);
11     }
12     return(a/2);
13 }
14
15 slices_2 <- function (x, components=FALSE) 
16 {
17     # Define an ideal, then scale each measurement relative to the ideal.
18     # If it matches it will be more or less than 1
19     # does this scale (up or down) linearly, and why not?
20
21     # 4, 2.4x2, 1000; 4, 3.2x1, 320; 1, 2.4x1, 160
22     ideal_m <- 3.4;             # GB
23     ideal_c <- 2.4;             # GHz 
24     ideal_d <- 450;             # GB
25     ideal_r <- 2;
26
27     m<-x$memsize/ideal_m;
28     d<-x$disksize/ideal_d;
29     c<-x$cpuspeed/ideal_c;
30     r<-x$numcores/ideal_r;
31     # ideal is 1
32
33     if ( components ) {
34         a<-c(m,d,c*r);
35     } else {
36         a<-(m+d+c*r);
37     }
38
39     return (a/3*5);
40 }
41
42 slices_3 <- function (x, components=FALSE) 
43 {
44     # Define an ideal, then scale each measurement relative to the ideal.
45     # If it matches it will be more or less than 1
46     # does this scale (up or down) linearly, and why not?
47
48     # 4, 2.4x2, 1000; 4, 3.2x1, 320; 1, 2.4x1, 160
49     ideal_m <- 3.4; #GB
50     ideal_c <- 2.4; #GHz
51     ideal_d <- 450;     #GB
52     ideal_r <- 2;
53         ideal_bw <- 100000;      #Kbps
54
55     m<-x$memsize/ideal_m;
56     d<-x$disksize/ideal_d;
57     c<-x$cpuspeed/ideal_c;
58     r<-x$numcores/ideal_r;
59     b<-log(x$bwlimit)/log(ideal_bw);
60     # ideal is 1
61
62     if ( components ) {
63         a<-c(m,d,c*r,b);
64     } else {
65         a<-(m+d+c*r+b);
66     }
67
68     return (a/4*5);
69 }
70
71 slices_4 <- function (x, components=FALSE) 
72 {
73     # Define an ideal, then scale each measurement relative to the ideal.
74     # If it matches it will be more or less than 1
75     # does this scale (up or down) linearly, and why not?
76
77     # 4, 2.4x2, 1000; 4, 3.2x1, 320; 1, 2.4x1, 160
78     ideal_m <- 3.4; #GB
79     ideal_c <- 2.4; #GHz
80     ideal_d <- 450;     #GB
81     ideal_r <- 2;
82         ideal_bw <- 100000;      #Kbps
83         ideal_pcu <- 1;
84
85     m<-x$memsize/ideal_m;
86     d<-x$disksize/ideal_d;
87     c<-x$cpuspeed/ideal_c;
88     r<-x$numcores/ideal_r;
89     b<-log(x$bwlimit)/log(ideal_bw);
90         p<-x$pcustatus/ideal_pcu;
91     # ideal is 1
92
93     if ( components ) {
94         a<-c(m,d,c*r,b,p);
95     } else {
96         a<-(m+d+c*r+b+p);
97     }
98
99     return (a/5*5);     # I know. Preserved for clarity and consistency with earlier examples
100 }
101
102 index_of_bin <- function (h, value)
103 {
104     index <- 0;
105
106     for (i in sequence(length(h$breaks))) 
107     {
108         # first bin
109
110         if ( value < h$breaks[1] )
111         {
112             index <- 1;
113             break;
114         } 
115
116         # last bin
117
118         if ( i == length(h$breaks) )
119         {
120             # end of line
121             index <- i;
122             break;
123         } 
124
125         # all other bins
126
127         if ( value > h$breaks[i] && value <= h$breaks[i+1] )
128         {
129             index <- i+1;
130             break;
131         } 
132     }
133     if ( index == 0 ) {
134         warning("index == 0, no bin assigned for value: ", value);
135     }
136
137     return (index);
138 }
139
140 start_image <- function (name, width=480, height=480)
141 {
142     png(name, width=width, height=height);
143 }
144
145 end_image <- function ()
146 {
147     dev.off()
148 }
149
150
151 plot_rt_hist <- function (t, imagename=0)
152 {
153     d2 <- (t$lastreply - t$start)
154     std_dev <- sd(log(d2))
155     m <- mean(log(d2))
156     print(sprintf("mean: %s, stddev: %s\n", m, std_dev));
157
158     if ( imagename != 0 ) { start_image(imagename) }
159
160     h<-hist(log(d2), 
161         xlab="Hours between ticket creation and final reply", 
162         main="Time to Final Reply for RT Tickets", axes=FALSE)
163     
164     a<-exp(h$breaks)/(60*60)    # convert units from log(secs) to hours
165     axis(1,labels=signif(a,2), at=h$breaks)
166     axis(2)
167
168     x<-seq(min(h$breaks),max(h$breaks),length=500)
169     y<-dnorm(x,mean=m, sd=std_dev)
170
171     # scale y to the size of h's 'counts' vector rather than the density function
172     lines(x,y*max(h$counts)/max(y))
173     if ( imagename != 0 ) { end_image() }
174 }
175
176 year_hist <- function (t, year, from, to, max, type="week", title="Histogram for Tickets in", fmt="%b-%d")
177 {
178     dates <-seq(as.Date(from), as.Date(to), type)
179     months <- format(dates, fmt)
180     hbreaks<-unclass(as.POSIXct(dates))
181     h<-hist(t$start, breaks=hbreaks, plot=FALSE)
182     main<-sprintf(paste(title, "%s: MEAN %s\n"), year, mean(h$counts))
183     print(main);
184     print(h$counts);
185     if ( max == 0 ) {
186         max = max(h$counts)
187     }
188     plot(h, ylim=c(0,max), main=main, axes=FALSE)
189     axis(1, labels=months, at=hbreaks)
190     axis(2)
191     abline(mean(h$counts), 0, col='grey')
192     #qqnorm(h$counts)
193     #qqline(h$counts)
194     return (h);
195 }
196
197
198 source("myImagePlot.R")
199 reboot_image <- function (t, year, from, to, max=0, type="week", title="")
200 {
201     dates <-seq(as.Date(from), as.Date(to), type)
202     months <- format(dates, "%b-%d")
203     hbreaks<-unclass(as.POSIXct(dates))
204
205     rows <- NULL
206     image <- matrix(data=0, nrow=max(as.numeric(t$hostname)), ncol=length(hbreaks))
207     #image <- matrix(data=0, nrow=length(unique(t$hostname)), ncol=length(hbreaks))
208
209     #for ( d in hbreaks )
210     for ( i in seq(1, length(hbreaks)) )
211     {
212         # find the range : d plus a day
213         d <- hbreaks[i]
214         d_end <- d+60*60*24
215         # find unique hosts in this day range
216         t_sub <- t[which(t$start > d & t$start <= d_end),]
217         unique_hosts <- unique(t_sub$hostname)
218         if (length(unique_hosts) == 0 ) { next }
219
220         for ( host in unique_hosts ) 
221         {
222             image[host,i] <- 1
223         }
224     }
225
226     myImagePlot(image, xLabels=months, yLabels=c(""), title=title)
227
228             #found <- 0
229             #for ( block in blocks )
230             #{
231                 #print(sprintf("date: %s, block: -%s, %s\n", d, block, host));
232                 #print(sprintf("row: %s\n", row));
233                 # find the range : 'block' days ago to 'd'
234             #    d_back <- d - 60*60*24 * block
235             #    t_back_sub <- t[which(t$start > d_back & t$start <= d),]
236             #    u <- unique(t_back_sub$hostname)
237             #    if ( length(u[u==host]) >= 1) 
238             #    {
239     #       #        add to block_count and go to next host.
240             #        found <- 1
241             #        i <- as.character(block)
242             #        row[i] <- row[i] + 1
243             #        break
244             #    }
245             #}
246             #if ( found == 0 )
247             #{
248             #    # no range found
249             #    row['0'] <- row['0'] + 1
250             #}
251         #}
252         #rows <- rbind(rows, c('start'=d, row))
253
254     #rows <- data.frame(rows)
255
256     #if ( max == 0 ) {
257     #    max = max(rows['0'])
258     #}
259     #main<-sprintf(paste(title, "%s: MEAN %s\n"), year, mean(rows$reboots))
260     #print(main);
261     #barplot(rows$reboots, ylim=c(0,max), main=main, axes=FALSE, space=0)
262     ##plot(h, ylim=c(0,max), main=main, axes=FALSE)
263     #axis(1, labels=months, at=seq(1,length(hbreaks)))
264     #axis(2)
265     #abline(mean(rows$reboots), 0, col='grey')
266     #qqnorm(h$counts)
267     #qqline(h$counts)
268     return (image);
269 }
270
271 add_year <- function (t)
272 {
273     t$year <- c(0)  # assign new column with zero value initially
274     for ( i in 1:length(t$start) )
275     {
276         d <- as.POSIXlt(t$start[i], origin="1970-01-01")
277         year <- d$year + 1900 # as.numeric(format(d, "%Y"))
278         t$year[i] <- year
279     }
280     return (t);
281 }
282
283 add_timestamp <- function (t)
284 {
285     t$start <- c(0)  # assign new column with zero value initially
286     for ( i in 1:length(t$date) )
287     {
288         tstamp <-unclass(as.POSIXct(t$date[i], origin="1970-01-01"))[1]
289         t$start[i] <- tstamp
290     }
291     return (t);
292 }
293
294 convert_datestr <- function (t, format)
295 {
296     t$start <- c(0)  # assign new column with zero value initially
297     for ( i in 1:length(t$Date) )
298     {
299         tstamp <-unclass(as.POSIXct(strptime(t$Date[i], format)))[1]
300         t$start[i] <- tstamp
301     }
302     return (t);
303 }
304
305 abline_at_date <- function (date, col='black', lty=1, format="%Y-%m-%d", height=0)
306 {
307     ts <-unclass(as.POSIXct(date, format=format, origin="1970-01-01"))[1]
308     if ( height == 0 )
309     {
310         abline(v=ts, col=col, lty=lty)
311     } else {
312         lines(c(ts,ts),c(0,height), col=col, lty=lty)
313     }
314     return (ts);
315 }
316
317 tstamp <- function (date, format="%Y-%m-%d")
318 {
319     ts <- unclass(as.POSIXct(date, format=format, origin="1970-01-01"))[1]
320     return (ts)
321 }
322
323 lowess_smooth <- function (x, y, delta=(60*60*24), f=0.02)
324 {
325     a<-lowess(x, y, delta=delta, f=f)
326     return (a);
327 }
328
329 in_list <- function ( str, str_list )
330 {
331     for ( f in str_list )
332     {
333         if ( str == f )
334         {
335             return (TRUE);
336         }
337     }
338     return (FALSE);
339 }
340
341 col2hex <- function  (colorname, alpha=1)
342 {
343     hex = "FFFFFFFF";
344     c_rgb <- col2rgb(colorname)
345     c_rgb <- c_rgb / 255
346     hex <- rgb(c_rgb[1,1], c_rgb[2,1], c_rgb[3,1], alpha)
347     return (hex);
348 }
349
350 printf <- function (...)
351 {
352     return(print(sprintf(...)));
353 }
354
355 time_graph_setup <- function (from, to)
356 {
357     # find 'type' range of days
358     xlim <- c(tstamp(from, format="%Y/%m/%d"), tstamp(to, format="%Y/%m/%d"))
359
360     begin_date <- as.Date(from)
361     end_date <- as.Date(to)
362
363     begin_day <- as.numeric(format(begin_date, "%j"))
364     end_day <- as.numeric(format(end_date, "%j"))
365     print(begin_day)
366
367     date_days <-seq(as.Date(from), as.Date(to), 'day')
368     date_weeks <-seq(as.Date(from), as.Date(to), 'week')
369     date_months <-seq(as.Date(from), as.Date(to), 'month')
370     date_years <-seq(as.Date(from), as.Date(to), 'year')
371
372     day_str <- format(date_months, "%a")
373     day_ts <- unclass(as.POSIXct(date_days))
374
375     week_str <- format(date_months, "%W")
376     week_ts <- unclass(as.POSIXct(date_weeks))
377
378     month_str <- format(date_months, "%b")
379     month_ts <- unclass(as.POSIXct(date_months))
380
381     year_str <- format(date_years, "%Y")
382     year_ts <- unclass(as.POSIXct(date_years))
383     print(year_ts)
384     year_ts_before <- year_ts
385
386     l <- length(year_ts)
387     print(l)
388     if ( l == 1 ) {
389         # center year between begin_day and end_day
390         print("one year!")
391         year_ts[1] <- (xlim[1] + xlim[2]) / 2.0
392     } else 
393     {
394         print("multitple years!")
395         # center first year between start day and last day of that year.
396         print(year_ts)
397         year_ts[1] <- year_ts[1] + ((365 - begin_day)/2.0)*60*60*24
398         print(year_ts)
399         year_ts[l] <- year_ts[l] + ( -begin_day + end_day/2.0)*60*60*24
400         print(year_ts)
401         if ( l > 2 ) {
402             year_ts <- c(year_ts[1], year_ts[seq(2,l-1)] + (180 - begin_day)*60*60*24, year_ts[l])
403         }
404         print(year_ts)
405     }
406     print(year_ts - year_ts_before)
407         
408     return (list(xlim=xlim, day_str=day_str, day_ts=day_ts,
409                  week_str=week_str, week_ts=week_ts, 
410                  month_str=month_str, month_ts=month_ts, 
411                  year_str=year_str, year_ts=year_ts))
412 }
413
414 planetlab_releases <- function (height) 
415 {
416     h = height
417     tstamp_20040412 <-abline_at_date("2004-04-12", col='white', lty=0, height=h)
418     tstamp_20041112 <-abline_at_date("2004-11-12", col='white', lty=3, height=h)
419     tstamp_20050301 <-abline_at_date("2005-03-01", col='grey60', lty=3, height=h)
420     tstamp_20050615 <-abline_at_date("2005-06-15", col='white',  lty=0, height=h)
421     tstamp_20051001 <-abline_at_date("2005-10-01", col='grey60', lty=3, height=h)
422     tstamp_20060519 <-abline_at_date("2006-05-19", col='grey60', lty=3, height=h)
423     tstamp_20070228 <-abline_at_date("2007-02-28", col='grey60', lty=3, height=h)
424     tstamp_20070501 <-abline_at_date("2007-05-01", col='white',  lty=0, height=h)
425     tstamp_20071021 <-abline_at_date("2007-10-21", col='grey60', lty=3, height=h)
426     tstamp_20080601 <-abline_at_date("2008-06-01", col='grey60', lty=3, height=h)
427     tstamp_20080815 <-abline_at_date("2008-08-15", col='white',  lty=0, height=h)
428     tstamp_20090501 <-abline_at_date("2009-05-01", col='grey60', lty=3, height=h)
429     tstamp_20100201 <-abline_at_date("2010-02-01", col='white',  lty=0, height=h)
430     tstamp_20100628 <-abline_at_date("2010-06-28", col='white', lty=3, height=h)
431     tstamp_20110222 <-abline_at_date("2011-02-22", col='grey60', lty=3, height=h)
432     # I think 5.0 was released 02/22/2011... not 03-09
433
434     text(x=c(tstamp_20040412,
435             tstamp_20041112,
436             tstamp_20050301,
437             tstamp_20050615,
438             tstamp_20051001,
439             tstamp_20060519,
440             tstamp_20070228,
441             tstamp_20071021,
442             tstamp_20080601,
443             tstamp_20090501,
444             tstamp_20100628,
445             tstamp_20110222),
446          y=c(h-h*0.05),
447          #labels=c('Release', '3.0', '3.1', '', '3.2', '3.3', '4.0', '4.1', '4.2', '4.3')) 
448          labels=c('', '', '3.1', '', '3.2', '3.3', '4.0', '4.1', '4.2', '4.3', '', '5.0')) 
449     text(x=c(tstamp_20050301), y=c(h), labels=c("Releases"))
450 }
451
452 plc_releases <- function (height) 
453 {
454     h = height
455     tstamp_pre <-abline_at_date("2004-10-01", col='grey60', lty=3, height=h)
456     tstamp_3_1 <-abline_at_date("2005-03-01", col='grey60', lty=3, height=h)
457     tstamp_3_2 <-abline_at_date("2005-10-01", col='grey60', lty=3, height=h)
458     tstamp_3_3 <-abline_at_date("2006-05-19", col='grey60', lty=3, height=h)
459     tstamp_4_0 <-abline_at_date("2007-02-28", col='grey60', lty=3, height=h)
460     tstamp_4_1 <-abline_at_date("2007-10-21", col='grey60', lty=3, height=h)
461     tstamp_4_2 <-abline_at_date("2008-06-01", col='grey60', lty=3, height=h)
462     tstamp_4_3 <-abline_at_date("2009-05-01", col='grey60', lty=3, height=h)
463     tstamp_5_0 <-abline_at_date("2011-02-22", col='grey60', lty=3, height=h)
464
465     text(x=c(tstamp_3_1,
466             tstamp_3_2,
467             tstamp_3_3,
468             tstamp_4_0,
469             tstamp_4_1,
470             tstamp_4_2,
471             tstamp_4_3,
472             tstamp_5_0),
473          y=c(h-h*0.05),
474          labels=c('3.1', '3.2', '3.3', '4.0', '4.1', '4.2', '4.3', '5.0')) 
475     text(x=c(tstamp_pre), y=c(h), labels=c("Releases"))
476 }