Exemplo n.º 1
0
// PostAnnotate happens after everything is done.
func (a *Annotator) PostAnnotate(chrom string, start int, end int, info interfaces.Info, prefix string) error {
	var e, err error
	vals := make([]interface{}, 0, 2)
	fields := make([]string, 0, 2)
	missing := make([]string, 0, 2)
	var val interface{}
	for i := range a.PostAnnos {
		post := a.PostAnnos[i]
		vals = vals[:0]
		fields = fields[:0]
		missing = missing[:0]
		// lua code
		if post.code != "" {
			for _, field := range post.Fields {
				val, e = info.Get(field)
				if val != nil {
					vals = append(vals, val)
					fields = append(fields, field)
				} else {
					missing = append(missing, field)
				}
				if e != nil {
					err = e
				}
			}
			// we need to try even if it didn't get all values.
			if len(vals) == 0 && len(post.Fields) > 0 {
				continue
			}

			k := 0
		out:
			// could also use fanIn where all channels send to a single
			// channel and pull from that.
			for {
				select {
				case k = <-post.mus[0]:
					break out
				case k = <-post.mus[1]:
					break out
				case k = <-post.mus[2]:
					break out
				case k = <-post.mus[3]:
					break out
				case k = <-post.mus[4]:
					break out
				case k = <-post.mus[5]:
					break out
				case k = <-post.mus[6]:
					break out
				case k = <-post.mus[7]:
					break out
				default:
				}
			}

			for i, val := range vals {
				post.Vms[k].SetGlobal(fields[i], val)
			}
			post.Vms[k].SetGlobal("chrom", chrom)
			post.Vms[k].SetGlobal("start", start)
			post.Vms[k].SetGlobal("stop", end)

			// need to unset missing values so we don't use those
			// from previous run.
			for _, miss := range missing {
				post.Vms[k].SetGlobal(miss, nil)
			}
			value, e := post.Vms[k].Run(post.code)
			post.mus[k] <- k
			if value == nil {
				if e != nil {
					code := post.code
					if len(code) > 40 {
						code = code[:37] + "..."
					}
					log.Printf("ERROR: in lua postannotation at %s:%d for %s.\n%s\nempty values were: %+v\nvalues were: %+v\ncode is: %s", chrom, start+1, post.Name, e, missing, vals, code)
				}
				continue
			}
			if e != nil {
				err = e
			}
			val := fmt.Sprintf("%v", value)
			if post.Type == "Flag" {
				if !(strings.ToLower(val) == "false" || val == "0" || val == "") {
					e := info.Set(post.Name, true)
					if e != nil {
						err = e
					}
				}

			} else {
				if e := info.Set(prefix+post.Name, val); e != nil {
					err = e
				}
			}

		} else {
			// built in function.
			// re-use vals
			var e error
			for _, field := range post.Fields {
				// ignore error when field isnt found. we expect that to occur a lot.
				val, e = info.Get(field)
				if val != nil {
					vals = append(vals, val)
				} else {
					if e != nil {
						err = e
					}
				}
			}
			// run this as long as we found any of the values.
			if len(vals) != 0 {
				fn := Reducers[post.Op]
				info.Set(prefix+post.Name, fn(vals))
			}
		}

	}
	return err
}
Exemplo n.º 2
0
func (a *Annotator) PostAnnotate(info interfaces.Info) error {
	var err error
	vals := make([]interface{}, 0, 2)
	for i := range a.PostAnnos {
		post := a.PostAnnos[i]
		// built in function
		vals = vals[:0]
		if post.code != "" {
			for _, field := range post.Fields {
				val, _ := info.Get(field)
				// ignore the error as it means the field is not present.
				if val != nil {
					vals = append(vals, val)
				}
			}
			if len(vals) != len(post.Fields) {
				continue
			}
			post.mu.Lock()
			for i, val := range vals {
				post.Vm.SetGlobal(post.Fields[i], val)
			}
			value, e := post.Vm.Run(post.code)
			post.mu.Unlock()
			if e != nil {
				err = e
			}
			val := fmt.Sprintf("%v", value)
			if post.Type == "Flag" {
				if !(strings.ToLower(val) == "false" || val == "0" || val == "") {
					e := info.Set(post.Name, true)
					if e != nil {
						err = e
					}
				}

			} else {
				if e := info.Set(post.Name, val); e != nil {
					err = e
				}
			}

		} else {
			// built in function.
			// re-use vals
			for _, field := range post.Fields {
				// ignore error when field isnt found. we expect that to occur a lot.
				val, _ := info.Get(field)
				if val != nil {
					vals = append(vals, val)
				}
			}
			if len(vals) == len(post.Fields) {
				fn := Reducers[post.Op]
				info.Set(post.Name, fn(vals))
			}
		}

	}
	return err
}