Website/lib/nsfconflicts.rb

170 lines
5.0 KiB
Ruby

require "rubygems"
require "prawn"
require "prawn/measurement_extensions"
require "util.rb"
class NSFConflicts
include Text
## The NSF considers collaborators from within the past 48 months
## Be conservative and add a few extra days in
## Track this in seconds (because time deltas are given in seconds)
@@time_to_consider_collabs = 60*60*24*365.25*2
def initialize(me, data)
@me = me
@data = data
@meta =
@data["people"].
merge(
@data["lab/members"].
map { |k,m|
[k, {
"institution" => "University at Buffalo",
"email" => "#{m["ubit"]}@buffalo.edu"
}.merge(m)]
}.to_h
).merge(
@data["lab/alumni"].
map { |k,m|
[k, {
"name" => k,
"institution" => m["company"],
"email" => "#{m["ubit"]}@buffalo.edu"
}.merge(m)]
}.to_h
)
@shortname = full_details(@me)["ubit"]
@my_data = @data["cv"][@shortname]
end
def grant_co_pis
@data["cv/okennedy/grants"].
where { |grant|
case grant["status"]
when "accepted", "submitted", "completed" then true
when "rejected", "retired" then false
else raise "Unknown grant status #{grant["status"]} for #{grant["title"]}"
end
}.
where { |grant| Time.now - to_date(grant["end"]) < @@time_to_consider_collabs }.
map do |grant|
co_pis = grant.fetch("copis", [])
grant.fetch("collaborative", []).each do |inst|
co_pis = co_pis + inst["pis"]
end
last_active = to_date(grant["end"])
last_active = Time.now if last_active > Time.now
co_pis.flatten.map { |name| [name, "#{last_active.year}-#{last_active.month}-#{last_active.day}"] }
end.
flatten(1)
end
def paper_coauthors
start_year = (Time.now - @@time_to_consider_collabs).year
@data["publications"].
where { |paper| paper["authors"].include? @me }.
where { |paper| paper["year"].to_i >= start_year }.
map { |paper|
paper["authors"].
where { |name| name != @me }.
map { |name| [name, "#{paper["year"].to_i}-01-01"] }
}.
flatten(1)
end
def advisors
@data["cv/#{@shortname}/education"]
.where { |inst| inst["degree"] == "PhD" }
.map { |inst| inst["Advisor"] }
end
def committee
@data["cv/#{@shortname}/education"]
.where { |inst| inst["degree"] == "PhD" }
.map { |inst| inst["Committee"] }
.flatten(1)
end
def phd_students
@data["lab/members"]
.values
.where { |person| person["status"] == "PhD" }
.map { |person| person["name"] }
end
def phd_alumni
@data["lab/alumni"]
.values
.where { |person| person["degree"] == "PhD" }
.map { |person| person["name"] }
end
def canonicalize(person)
@meta.fetch(person, {"canonical" => person})
.fetch("canonical", person)
end
def full_details(person)
return person.map { |x| full_details(x) } if person.is_a? Array
meta = @meta[person] or raise "Unknown Person: #{person}"
{
"name" => person,
"name_parts" => split_name(person)
}.merge(meta)
end
def render_name(person)
person["name_parts"].reverse.join(", ")
end
def render(target)
all_collabs = (
(grant_co_pis + paper_coauthors).map { |x| x[0] } +
(phd_students + phd_alumni + advisors + committee)
).uniq.sort
missing_collabs =
all_collabs.select { |person| not (@meta.has_key? person) }
unless missing_collabs.empty?
puts ("You are missing collaborator details. Here's a template to add to /db/people.json:")
missing_collabs.each do |collab|
puts " \"#{collab}\" : {"
puts " \"institution\" : \"\","
puts " \"updated\" : \"#{Time.now.year}\""
puts " },"
end
end
File.open(target, "w+") do |f|
f.puts("==== TABLE A ====")
f.puts("\t#{@my_data["name"]}\t#{@my_data["work"]["employer"]}")
f.puts("==== TABLE B ====")
full_details(advisors).each do |adv|
f.puts "G:\t#{render_name(adv)}\t#{adv["institution"]}\t#{adv["email"]}"
end
full_details((committee + phd_students + phd_alumni).uniq.sort).each do |stud|
f.puts "T:\t#{render_name(stud)}\t#{stud["institution"]}\t#{stud["email"]}"
end
f.puts("==== TABLE C ====")
all_collabs = (
grant_co_pis.map { |name, y| [canonicalize(name), [:grant, y]] } +
paper_coauthors.map { |name, y| [canonicalize(name), [:pub, y]] }
)
all_collabs
.my_reduce
.to_a
.sort_by { |name, collabs| render_name(full_details(name)) }
.each { |name, collabs|
categories, years = collabs.unzip
category = "C:"
category = "A:" if(categories.include? :pub)
details = full_details(name)
f.puts("#{category}\t#{render_name(details)}\t#{details["institution"]}\t#{details["email"]}\t#{years.max}")
}
end
end
end