#
# pep-proj-fishing.R, 30 Aug 26
#
# Data from:
# The SEA Data Warehouse
# https://softwareexcellencealliance.org/the-sea-data-warehouse/

library("colorspace")
library("plyr")
library("lubridate")


par(bty="l")
par(las=1)
par(pch="+")
pal_col=rainbow(2)


# Daily summary of project tasks by one person
person_daily_tasks=function(df)
{
   daily_tasks=function(df_d)
   {
   p_daily=data.frame(num_proj=length(unique(df_d$project_key)),
			total_mins=sum(df_d$time_log_delta_minutes, na.rm=TRUE))
   return(p_daily)
   }

daily_summary=ddply(df, .(time_log_start_date), daily_tasks)

return(daily_summary)
}


# Weekly summary of project tasks by one person
person_weekly_tasks=function(df)
{
   daily_tasks=function(df_d)
   {
   p_daily=data.frame(num_proj=length(unique(df_d$project_key)),
			total_mins=sum(df_d$time_log_delta_minutes, na.rm=TRUE))
   return(p_daily)
   }

weekly_summary=ddply(df, .(weeknum, year), daily_tasks)

return(weekly_summary)
}

# Monthly summary of project tasks by one person
person_monthly_tasks=function(df)
{
   daily_tasks=function(df_d)
   {
   p_daily=data.frame(num_proj=length(unique(df_d$project_key)),
			total_mins=sum(df_d$time_log_delta_minutes, na.rm=TRUE))
   return(p_daily)
   }

monthly_summary=ddply(df, .(month, year), daily_tasks)

return(monthly_summary)
}


ptb=read.csv("plan_time_block.csv.xz")
person=read.csv("csv/person.csv.xz")
proj=read.csv("csv/project.csv.xz")

ptb=subset(ptb, !is.na(person_key))

ptb$time_log_start_date=as.Date(ptb$time_log_start_date, format="%Y-%m-%d")
ptb$time_log_end_date=as.Date(ptb$time_log_end_date, format="%Y-%m-%d")

ptb$weeknum=week(ptb$time_log_start_date)
ptb$month=month(ptb$time_log_start_date)
ptb$year=year(ptb$time_log_start_date)

# Some person's not in the plan data
person=subset(person, person_key %in% ptb$person_key)
person$row_created_by_key=NULL
person$row_last_updated_by_key=NULL

# Different person keys can have the same name
# c(nrow(person), length(unique(person$person_name)))

ptb=merge(ptb, person, by = "person_key", all=TRUE)


pep_proj=data.frame(person=ptb$person_name, project=ptb$project_key)
unq_pep_proj=unique(pep_proj)

# Number of projects that a person works on
proj_per_pep=count(count(unq_pep_proj$person)$freq)

plot(proj_per_pep, log="xy", col=pal_col[2],
	xlim=c(1, 40),
	xlab="People", ylab="Projects")

pep_bounds=2:17

pep_mod=glm(log(freq) ~ log(x), data=proj_per_pep, subset=(x > 1) & (x < 18))
summary(pep_mod)

pred=predict(pep_mod, newdata=data.frame(x=pep_bounds))
lines(pep_bounds, exp(pred), col=pal_col[1])

# Number of projects having a given number of people
pep_per_proj=count(count(unq_pep_proj$project)$freq)

plot(pep_per_proj, log="y", col=pal_col[2],
	xlim=c(1, 40),
	xlab="Projects", ylab="Members")

proj_bounds=1:24

proj_mod=glm(log(freq) ~ x, data=pep_per_proj, subset=(x < 25))
summary(proj_mod)

pred=predict(proj_mod, newdata=data.frame(x=proj_bounds))
lines(proj_bounds, exp(pred), col=pal_col[1])


# How many projects did somebody work on each day
person_days=ddply(ptb, .(person_name), person_daily_tasks)
person_weeks=ddply(ptb, .(person_name), person_weekly_tasks)
person_months=ddply(ptb, .(person_name), person_monthly_tasks)

# Filter outliers
mean(subset(person_days, total_mins < 600)$total_mins)

plot(sort(person_days$total_mins), col="red",
	xaxs="i", yaxs="i",
	ylim=c(0, 550),
	xlab="Person days", ylab="Minutes worked on day")

dev.copy(dev=png, file="minutes-per-day_Warehouse.png")
dev.off()


pal_col=rainbow(3)

# There are more days than weeks, and more weeks than months,
# So normalise frequencies
num_proj_day=count(person_days$num_proj)
num_proj_day$freq=100*num_proj_day$freq/nrow(person_days)
num_proj_week=count(person_weeks$num_proj)
num_proj_week$freq=100*num_proj_week$freq/nrow(person_weeks)
num_proj_month=count(person_months$num_proj)
num_proj_month$freq=100*num_proj_month$freq/nrow(person_months)
plot(num_proj_day, log="y", col=pal_col[3],
	yaxt="n",
	yaxs="i",
	ylim=c(1e-3, 100),
	xlab="Projects", ylab="Person time interval")
axis(2, at=c(1e-2, 1e-1, 1, 10, 100), lab=c("0.01%", "0.1%", "1.0%", "10%", "100%"))

points(num_proj_week, col=pal_col[2])
points(num_proj_month, col=pal_col[1])

legend("topright", legend=c("Month", "Week", "Day"), cex=1.2,
                        fill=pal_col, border="white", bty="n")

p_bounds=1:5

# Fit to projects per day
npd_mod=glm(log(freq) ~ x, data=num_proj_day)
summary(npd_mod)

pred=predict(npd_mod)
lines(exp(pred), col=pal_col[3])

# Fit to projects per week
npd_mod=glm(log(freq) ~ x, data=num_proj_week, subset=(x <= max(p_bounds)))
summary(npd_mod)

pred=predict(npd_mod, newdata=data.frame(x=p_bounds))
lines(p_bounds, exp(pred), col=pal_col[2])

# Fit to projects per month
npd_mod=glm(log(freq) ~ x, data=num_proj_month, subset=(x <= max(p_bounds)))
summary(npd_mod)

pred=predict(npd_mod, newdata=data.frame(x=p_bounds))
lines(p_bounds, exp(pred), col=pal_col[1])

dev.copy(dev=png, file="proj-per-unit-time.png")
dev.off()

