func classbReport(c appengine.Context, s, e time.Time, opt ReportOptions) ([]ReportRow, ReportMetadata, error) { fdb := fdb.FlightDB{C: c} maybeMemcache(&fdb, e) tags := []string{ flightdb.KTagReliableClassBViolation, flightdb.KTagLocalADSBClassBViolation, } meta := ReportMetadata{} h := histogram.Histogram{} // Only use it for the stats rows := []ReportRow{} seen := map[string]bool{} // Because we do two passes, we might see same flight twice. metars, err := metar.FetchFromNOAA(urlfetch.Client(c), "KSFO", s.Add(-6*time.Hour), e.Add(6*time.Hour)) if err != nil { return rows, meta, err } reportFunc := func(f *flightdb.Flight) { if _, exists := seen[f.UniqueIdentifier()]; exists { return } else { seen[f.UniqueIdentifier()] = true } bestTrack := "FA" if f.HasTag(flightdb.KTagLocalADSBClassBViolation) { bestTrack = "ADSB" } _, cbt := f.SFOClassB(bestTrack, metars) tmpRows := []ReportRow{} seq := 0 for _, cbtp := range cbt { if cbtp.A.IsViolation() { fClone := f.ShallowCopy() tmpRows = append(tmpRows, CBRow{seq, flight2Url(*fClone), *fClone, cbtp.TP, cbtp.A}) seq++ } } if len(tmpRows) == 0 { return } worstCBRow := tmpRows[0].(CBRow) if seq > 0 { // Select the worst row n, belowBy := 0, 0.0 for i, row := range tmpRows { if row.(CBRow).A.BelowBy > belowBy { n, belowBy = i, row.(CBRow).A.BelowBy } } worstCBRow = tmpRows[n].(CBRow) worstCBRow.Seq = 0 // fake this out for the webpage } if opt.ClassB_LocalDataOnly && !f.HasTag(flightdb.KTagLocalADSBClassBViolation) { meta["[C] -- Skippped; not local - "+worstCBRow.TP.LongSource()]++ } else { meta["[C] -- Detected via "+worstCBRow.TP.LongSource()]++ h.Add(histogram.ScalarVal(worstCBRow.A.BelowBy)) if opt.ClassB_OnePerFlight { rows = append(rows, worstCBRow) } else { rows = append(rows, tmpRows...) } } } // Need to do multiple passes, because of tagA-or-tagB sillness // In each case, limit to SERFR1 flights for _, tag := range tags { theseTags := []string{tag, flightdb.KTagSERFR1} if err := fdb.IterWith(fdb.QueryTimeRangeByTags(theseTags, s, e), reportFunc); err != nil { return nil, nil, err } } if n, err := fdb.CountTimeRangeByTags([]string{flightdb.KTagSERFR1}, s, e); err != nil { return nil, nil, err } else { meta["[A] Total SERFR1 Flights"] = float64(n) } if stats, valid := h.Stats(); valid { meta["[B] Num violating flights"] = float64(stats.N) meta["[D] Mean violation below Class B floor"] = float64(int(stats.Mean)) meta["[D] Stddev"] = float64(int(stats.Stddev)) } else { meta["[B] Num violating flights"] = 0.0 } return rows, meta, nil }