Created
May 4, 2012 07:56
-
-
Save neggert/2593138 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_seu_logs() | |
# get the portion of the logs relevant to the seu | |
logs = [] | |
Dir['**/PixelFEDSupervisor_*.log'].each do |path| | |
contents = File.read(path) | |
regex = /Message : Detected soft error using FED channel monitoring(.*?)Message : New state is:Running/m | |
matches = contents.scan(regex) | |
if (matches != nil) | |
(0..matches.size-1).each do |i| | |
logs << matches[i][0] | |
end | |
end | |
end | |
return logs | |
end | |
def get_seu_channel( seulogstring) | |
# get the SEU channel from the log text | |
regex = /A disabled channel found in FED (?<fed>\d{2}) mask bits: (?<N>\h+) (?<NC>\h+) (?<SC>\h+) (?<S>\h+) expected (?<Ne>\h+) (?<NCe>\h+) (?<SCe>\h+) (?<Se>\h+)/ | |
offset = 0 | |
fed = 0 | |
channel = -1 | |
seulogstring.split("\n").each do |line| | |
data = seulogstring.match(regex) | |
if (data != nil) | |
# find the mismatch | |
if (data[:N] != data[:Ne]) | |
mask = data[:N].hex ^ data[:Ne].hex | |
offsset = 0 | |
elsif (data[:NC] != data[:NCe]) | |
mask = data[:NC].hex ^ data[:NCe].hex | |
offsset = 9 | |
elsif (data[:SC] != data[:SCe]) | |
mask = data[:SC].hex ^ data[:SCe].hex | |
offsset = 18 | |
elsif (data[:S] != data[:Se]) | |
mask = data[:S].hex ^ data[:Se].hex | |
offsset = 27 | |
end | |
fed = data[:fed] | |
channel = offset + get_channels_from_word(mask) | |
end | |
end | |
return fed, channel | |
end | |
def get_channels_from_word( hex ) | |
# note, this assumes only 1 entry is 1 | |
(0..8).each do |i| | |
if ((hex >> i) % 2 == 1) | |
return i+1 | |
end | |
end | |
end | |
def get_time( string ) | |
# parse the string and get the timestamp at the beginning | |
if (/\A\s*?(?<day>\d{2})\s(?<month>\w*?)\s(?<year>\d{4})\s(?<hour>\d{2}):(?<min>\d{2}):(?<sec>\d{2}\.\d*)/ =~ string) | |
Time.local(year, month, day, hour, min, sec) | |
else | |
false | |
end | |
end | |
def get_start_time( seu_log_string) | |
# get the first timestamp in the SEU log | |
seu_log_string.split("\n").each do | line | | |
time = get_time( line ) | |
if (time) | |
return time | |
end | |
end | |
return false | |
end | |
def get_end_time( seu_log_string) | |
# get the last timestamp in the SEU log | |
seu_log_string.split("\n").reverse.each do | line | | |
time = get_time( line ) | |
if (time) | |
return time | |
end | |
end | |
return false | |
end | |
def get_run_with_times() | |
# get the times runs started and stopped | |
starttimes = [] | |
stoptimes = [] | |
runs = [] | |
outarray = [] | |
Dir['**/PixelSupervisor.log'].each do |path| | |
begin | |
File.open(path) do |f| | |
f.readlines.each do |line| | |
if (/\s\-\sStart Run (?<run>\d*)/ =~ line) | |
starttimes << get_time(line) | |
runs << run | |
elsif (/\s\-\sEntering transition STOP/ =~ line) | |
stoptimes << get_time(line) | |
end | |
end | |
end | |
rescue ArgumentError | |
# puts "Error parsing file #{path}" | |
next | |
end | |
end | |
# figure out which stop times correspond to which stop times | |
(0..starttimes.count-1).each do |i| | |
possible_end_times = [] | |
if (i == starttimes.count-1) | |
possible_end_times = stoptimes.select{ |item| item > starttimes[i]} | |
else | |
possible_end_times = stoptimes.select{ |item| item > starttimes[i] and item < starttimes[i+1]} | |
end | |
if (possible_end_times.count > 0) | |
#possible_end_times.sort! | |
end_time = possible_end_times[0] | |
out = {:start => starttimes[i], :end => end_time, :run => runs[i]} | |
outarray << out | |
end | |
end | |
return outarray | |
end | |
def get_seu_run( seulogstring ) | |
# get the run number the SEU occured in | |
seutime = get_time(seulogstring) | |
get_run_with_times().each do |run| | |
if ((run[:start] < seutime) and (seutime < run[:end])) | |
return run[:run] | |
end | |
end | |
return nil | |
end | |
require 'mechanize' | |
require 'highline/import' | |
class WBMScraper | |
def initialize() | |
@agent = Mechanize.new | |
end | |
def login!() | |
@page = @agent.get("https://cmswbm.web.cern.ch/cmswbm/cmsdb/servlet/RunSummary") | |
if (@page.title =~ /CERN Authentication v2/) | |
# we need to login | |
loginform = @page.form('aspnetForm') | |
puts "Login to retrieve run info from WBM" | |
username = ask("CERN User Name: ") | |
userpw = ask("CERN Password (this will not be stored): ") { |q| q.echo = false } | |
loginform['ctl00$ContentPlaceHolder1$txtFormsLogin'] = username | |
loginform['ctl00$ContentPlaceHolder1$txtFormsPassword'] = userpw | |
loginform.checkbox_with(:name=>'ctl00$ContentPlaceHolder1$chkRememberLogin').check | |
@page = @agent.submit(loginform, loginform.buttons.first) | |
# click through the login page | |
@page = @agent.submit(@page.form('hiddenform'), @page.form('hiddenform').buttons.first) | |
end | |
checkpage!() | |
end | |
def checkpage!() | |
if (not (@page.title =~ /CMS RunSummary/)) | |
raise 'Page title is not \'CMS RunSumarry\'. It is #{@page.title}' | |
end | |
end | |
def run_was_good?( run ) | |
@page = @agent.get("https://cmswbm.web.cern.ch/cmswbm/cmsdb/servlet/RunSummary?RUN=#{run}") | |
# click on the fill report | |
link = @page.links_with(:href=>/FillReport/)[0] | |
if (link == nil) | |
return false # no run in RunSummary | |
end | |
@page = link.click | |
# now use a regex to try to find the start time of stable beams | |
regexp = /BeginTime \(stable\)<\/th><td><a href=".*?">.*?<\/a><\/td><\/tr>/ | |
if ( regexp =~ @page.content ) | |
return true | |
else | |
# if we couldn't find it, there were no stable beams | |
return false | |
end | |
end | |
end | |
class Seu | |
attr_accessor :starttime, :stoptime, :run, :fed, :channel, :stable | |
def initialize( starttime, stoptime, run, fed, channel, stable) | |
# do some validation | |
raise ArgumentError, 'Invalid fed, channel, or run' unless (fed != 0 and channel != -1 and run != nil) | |
@starttime = starttime | |
@stoptime = stoptime | |
@run = run | |
@fed = fed | |
@channel = channel | |
@stable = stable | |
end | |
def to_s | |
"#{@starttime} - #{elapsed_sec}s Run: #{@run} FED: #{@fed}, channel #{@channel} StableBeam: #{@stable}" | |
end | |
def elapsed_sec | |
@stoptime - @starttime | |
end | |
end | |
s = WBMScraper.new | |
s.login!() | |
get_seu_logs().each do | seulog | | |
starttime = get_start_time(seulog) | |
stoptime = get_end_time(seulog) | |
run = get_seu_run(seulog) | |
fed, channel = get_seu_channel(seulog) | |
stable = s.run_was_good?( run) | |
begin | |
seu = Seu.new(starttime, stoptime, run, fed, channel, stable) | |
rescue ArgumentError | |
next # go to next seu | |
end | |
puts seu | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment