Beispiel #1
0
// IsInParentList search an id in the list of parents of the taxon.
func isInParentList(c *cmdapp.Command, db jdh.DB, id string, pIds []string) bool {
	args := new(jdh.Values)
	args.Add(jdh.TaxParents, id)
	pl, err := db.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	defer pl.Close()
	for {
		p := &jdh.Taxon{}
		if err := pl.Scan(p); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		for _, pid := range pIds {
			if p.Id == pid {
				return true
			}
		}
	}
	return false
}
Beispiel #2
0
func getValidParent(c *cmdapp.Command, extId string) string {
	args := new(jdh.Values)
	args.Add(jdh.TaxParents, extId)
	l, err := extDB.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	defer l.Close()
	for {
		et := &jdh.Taxon{}
		if err := l.Scan(et); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		p := taxon(c, localDB, extDBFlag+":"+et.Id)
		if len(p.Id) > 0 {
			if p.IsValid {
				return p.Id
			} else {
				return p.Parent
			}
		}
	}
	return ""
}
Beispiel #3
0
func trForceProc(c *cmdapp.Command, phy *jdh.Phylogeny) {
	txLs := list.New()
	vals := new(jdh.Values)
	vals.Add(jdh.TreTaxon, phy.Id)
	l, err := localDB.List(jdh.Trees, vals)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	for {
		var tId jdh.IdElement
		if err := l.Scan(&tId); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if len(tId.Id) == 0 {
			continue
		}
		txLs.PushBack(tId.Id)
	}
	if txLs.Len() == 0 {
		return
	}
	root := phyloNode(c, localDB, phy.Root)
	trForceNode(c, root, txLs)
}
Beispiel #4
0
func txEdVal(from *jdh.Taxon) {
	if from.IsValid {
		return
	}
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, from.Id)
	vals.Add(jdh.TaxValid, "true")
	localDB.Exec(jdh.Set, jdh.Taxonomy, vals)
}
Beispiel #5
0
func raLsRun(c *cmdapp.Command, args []string) {
	openLocal(c)
	var tax *jdh.Taxon
	if len(taxonFlag) > 0 {
		tax = taxon(c, localDB, taxonFlag)
		if len(tax.Id) == 0 {
			return
		}
	} else if len(args) > 0 {
		if len(args) > 2 {
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("too many arguments"))
			os.Exit(1)
		}
		pName := ""
		if len(args) > 1 {
			pName = args[1]
		}
		tax = pickTaxName(c, localDB, args[0], pName)
		if len(tax.Id) == 0 {
			return
		}
	} else {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong taxon name or id"))
		c.Usage()
	}
	vals := new(jdh.Values)
	if childFlag {
		vals.Add(jdh.RDisTaxonParent, tax.Id)
	} else {
		vals.Add(jdh.RDisTaxon, tax.Id)
	}
	l := rasList(c, localDB, vals)
	defer l.Close()
	ct := tax
	for {
		ras := &jdh.Raster{}
		if err := l.Scan(ras); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if machineFlag {
			fmt.Fprintf(os.Stdout, "%s\n", ras.Id)
			continue
		}
		if ras.Taxon != ct.Id {
			ct = taxon(c, localDB, ras.Taxon)
		}
		if verboseFlag {
			fmt.Fprintf(os.Stdout, "%s %s %s\t%s\t%dx%d\n", ct.Id, ct.Name, ct.Authority, ras.Id, ras.Cols, ras.Cols/2)
			continue
		}
		fmt.Fprintf(os.Stdout, "%s\t%s\t%dx%d\n", ct.Name, ras.Id, ras.Cols, ras.Cols/2)
	}
}
Beispiel #6
0
func spPopFetch(c *cmdapp.Command, tax *jdh.Taxon, prevRank, rank jdh.Rank) {
	r := tax.Rank
	if r == jdh.Unranked {
		r = prevRank
	}
	defer func() {
		l := getTaxDesc(c, localDB, tax.Id, true)
		spPopNav(c, l, r, rank)
		l = getTaxDesc(c, localDB, tax.Id, false)
		spPopNav(c, l, r, rank)
	}()
	if len(tax.Id) == 0 {
		return
	}
	if r < rank {
		return
	}
	eid := searchExtern(extDBFlag, tax.Extern)
	if len(eid) == 0 {
		return
	}
	vals := new(jdh.Values)
	vals.Add(jdh.SpeTaxon, eid)
	if geoRefFlag {
		vals.Add(jdh.SpeGeoref, "true")
	}
	l := speList(c, extDB, vals)
	for {
		spe := &jdh.Specimen{}
		if err := l.Scan(spe); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if osp := specimen(c, localDB, extDBFlag+":"+spe.Id); len(osp.Id) > 0 {
			continue
		}
		if len(spe.Catalog) > 0 {
			if osp := specimen(c, localDB, spe.Catalog); len(osp.Id) > 0 {
				exsp := searchExtern(extDBFlag, osp.Extern)
				if exsp == spe.Id {
					continue
				}
				fmt.Fprintf(os.Stderr, "specimen %s already in database as %s [duplicated in %s]\n", spe.Catalog, osp.Id, extDBFlag)
				continue
			}
		}
		addToSpecimens(c, spe, tax.Id)
	}
}
Beispiel #7
0
func trDelNode(c *cmdapp.Command) {
	vals := new(jdh.Values)
	if colpFlag {
		vals.Add(jdh.NodCollapse, nodeFlag)
	} else {
		vals.Add(jdh.KeyId, nodeFlag)
	}
	if _, err := localDB.Exec(jdh.Delete, jdh.Nodes, vals); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	localDB.Exec(jdh.Commit, "", nil)
}
Beispiel #8
0
func setNode(nod *jdh.Node, anc *trNode, data *trData) *trNode {
	trn := &trNode{
		id:     nod.Id,
		taxon:  nod.Taxon,
		parent: anc,
	}
	data.node = append(data.node, trn)
	if anc != nil {
		trn.nest = anc.nest + 1
		trn.minX = float32(trn.nest)
	}
	if len(nod.Taxon) > 0 {
		tax := taxon(cmd, localDB, nod.Taxon)
		trn.name.Text = tax.Name
		if !tax.IsValid {
			val := taxon(cmd, localDB, tax.Parent)
			nm := fmt.Sprintf("[%s syn. of %s]", tax.Name, val.Name)
			trn.name.Text = nm
		}
	}
	vals := new(jdh.Values)
	vals.Add(jdh.NodChildren, nod.Id)
	l, err := localDB.List(jdh.Nodes, vals)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", cmd.ErrStr(err))
		os.Exit(1)
	}
	for {
		desc := &jdh.Node{}
		if err := l.Scan(desc); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", cmd.ErrStr(err))
			os.Exit(1)
		}
		d := setNode(desc, trn, data)
		trn.terms += d.terms
		if trn.level <= d.level {
			trn.level = d.level + 1
		}
		trn.children = append(trn.children, d)
	}
	if len(trn.children) == 0 {
		data.terms++
		trn.terms = 1
	} else {
		sort.Sort(bySize(trn.children))
	}
	return trn
}
Beispiel #9
0
// GetTaxDesc return the list of descendants of a taxon.
func getTaxDesc(c *cmdapp.Command, db jdh.DB, id string, valid bool) jdh.ListScanner {
	args := new(jdh.Values)
	if valid {
		args.Add(jdh.TaxChildren, id)
	} else {
		args.Add(jdh.TaxSynonyms, id)
	}
	l, err := db.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	return l
}
Beispiel #10
0
func dsDelRun(c *cmdapp.Command, args []string) {
	if len(idFlag) == 0 {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong dataset id"))
		c.Usage()
	}
	openLocal(c)
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, idFlag)
	if _, err := localDB.Exec(jdh.Delete, jdh.Datasets, vals); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	localDB.Exec(jdh.Commit, "", nil)
}
Beispiel #11
0
func txEdSyn(from, to *jdh.Taxon) {
	if from.Id == "0" {
		return
	}
	if from.Id == to.Id {
		return
	}
	if (from.Parent == to.Id) && (!from.IsValid) {
		return
	}
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, from.Id)
	vals.Add(jdh.TaxSynonym, to.Id)
	localDB.Exec(jdh.Set, jdh.Taxonomy, vals)
}
Beispiel #12
0
func trViewMouse(tv sparta.Widget, e interface{}) bool {
	dt := tv.Property(sparta.Data)
	if dt == nil {
		return true
	}
	data := dt.(*trData)
	ev := e.(sparta.MouseEvent)
	switch ev.Button {
	case sparta.MouseRight:
		if !setFlag {
			return true
		}
		if data.sel == nil {
			return true
		}
		sel := trViewNearestNode(ev.Loc, data.node)
		if sel == nil {
			return true
		}
		x, y, pos := data.x, data.y, data.pos
		p := tv.Property(sparta.Parent).(sparta.Widget)
		d := p.Property(sparta.Data).(*trList)
		if sel == data.sel {
			vals := new(jdh.Values)
			vals.Add(jdh.NodCollapse, sel.id)
			localDB.Exec(jdh.Delete, jdh.Nodes, vals)
			localDB.Exec(jdh.Commit, "", nil)
		} else if !sel.isValidSis(data.sel) {
			return true
		} else {
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, data.sel.id)
			vals.Add(jdh.NodSister, sel.id)
			localDB.Exec(jdh.Set, jdh.Nodes, vals)
			localDB.Exec(jdh.Commit, "", nil)
		}
		rect := tv.Property(sparta.Geometry).(image.Rectangle)
		data = setTree(d.phyLs[d.pos], rect)
		data.x, data.y, data.pos = x, y, pos
		tv.SetProperty(sparta.Data, data)
		data.putOnScreen()
		tv.Update()
	case sparta.MouseLeft:
		data.sel = trViewNearestNode(ev.Loc, data.node)
		tv.Update()
	case -sparta.MouseWheel:
		data.pos.Y -= 5
		data.putOnScreen()
		tv.Update()
	case sparta.MouseWheel:
		data.pos.Y += 5
		data.putOnScreen()
		tv.Update()
	}
	return true
}
Beispiel #13
0
// TaxInDB returns true if a taxon is in the database.
func taxInDB(c *cmdapp.Command, db jdh.DB, name, parent string, rank jdh.Rank, valid bool) *jdh.Taxon {
	args := new(jdh.Values)
	args.Add(jdh.TaxName, name)
	if len(parent) != 0 {
		args.Add(jdh.TaxParent, parent)
	}
	if rank != jdh.Unranked {
		args.Add(jdh.TaxRank, rank.String())
	}
	l, err := db.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	defer l.Close()
	for {
		tax := &jdh.Taxon{}
		if err := l.Scan(tax); err != nil {
			if err == io.EOF {
				return nil
			}
		}
		if len(tax.Id) > 0 {
			if tax.IsValid == valid {
				return tax
			}
		}
	}
}
Beispiel #14
0
// ValsFromArgs adds values from an argument list or the stdin.
func valsFromArgs(id string, args []string) *jdh.Values {
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, id)
	if len(args) == 0 {
		in := bufio.NewReader(os.Stdin)
		for {
			tn, err := readLine(in)
			if err != nil {
				break
			}
			ln := strings.Join(tn, " ")
			if strings.Index(ln, "=") < 1 {
				continue
			}
			vals.Add(parseKeyValArg(ln))
		}
	} else {
		for _, a := range args {
			if strings.Index(a, "=") < 1 {
				continue
			}
			vals.Add(parseKeyValArg(a))
		}
	}
	return vals
}
Beispiel #15
0
func trDelRun(c *cmdapp.Command, args []string) {
	openLocal(c)
	if len(nodeFlag) > 0 {
		trDelNode(c)
		return
	}
	if len(idFlag) == 0 {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong tree or node id"))
		c.Usage()
	}
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, idFlag)
	if _, err := localDB.Exec(jdh.Delete, jdh.Trees, vals); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	localDB.Exec(jdh.Commit, "", nil)
}
Beispiel #16
0
func trLsNodes(c *cmdapp.Command) {
	vals := new(jdh.Values)
	if ancsFlag {
		vals.Add(jdh.NodParent, nodeFlag)
	} else {
		vals.Add(jdh.NodChildren, nodeFlag)
	}
	l, err := localDB.List(jdh.Nodes, vals)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	for {
		nod := &jdh.Node{}
		if err := l.Scan(nod); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if machineFlag {
			fmt.Fprintf(os.Stdout, "%s\n", nod.Id)
			continue
		}
		var tax *jdh.Taxon
		if len(nod.Taxon) > 0 {
			tax = taxon(c, localDB, nod.Taxon)
		}
		if verboseFlag {
			fmt.Fprintf(os.Stdout, "%s\t", nod.Id)
			if tax != nil {
				fmt.Fprintf(os.Stdout, "%s [id:%s]", tax.Name, tax.Id)
			}
			fmt.Fprintf(os.Stdout, "\tlen: %d\tage: %d\n", nod.Len, nod.Age)
			continue
		}
		fmt.Fprintf(os.Stdout, "%s\t", nod.Id)
		if tax != nil {
			fmt.Fprintf(os.Stdout, "%s", tax.Name)
		}
		fmt.Fprintf(os.Stdout, "\n")
	}
}
Beispiel #17
0
func txSyncRankSet(c *cmdapp.Command, tax *jdh.Taxon, rank jdh.Rank) {
	if len(tax.Id) == 0 {
		l := getTaxDesc(c, localDB, tax.Id, true)
		txSyncRankNav(c, l, rank)
		l = getTaxDesc(c, localDB, tax.Id, false)
		txSyncRankNav(c, l, rank)
		return
	}
	if (tax.Rank < rank) && (tax.Rank != jdh.Unranked) {
		l := getTaxDesc(c, localDB, tax.Id, true)
		txSyncRankNav(c, l, rank)
		l = getTaxDesc(c, localDB, tax.Id, false)
		txSyncRankNav(c, l, rank)
		return
	} else if tax.Rank == rank {
		return
	}
	eid := searchExtern(extDBFlag, tax.Extern)
	if len(eid) == 0 {
		l := getTaxDesc(c, localDB, tax.Id, true)
		txSyncRankNav(c, l, rank)
		l = getTaxDesc(c, localDB, tax.Id, false)
		txSyncRankNav(c, l, rank)
		return
	}
	pExt := txSyncRankedParent(c, eid, rank)
	if pExt == nil {
		l := getTaxDesc(c, localDB, tax.Id, true)
		txSyncRankNav(c, l, rank)
		l = getTaxDesc(c, localDB, tax.Id, false)
		txSyncRankNav(c, l, rank)
		return
	}
	// check if the potential parent is already in the database.
	p := taxon(c, localDB, extDBFlag+":"+pExt.Id)
	if len(p.Id) == 0 {
		p = txSyncAddToTaxonomy(c, pExt)
	}
	args := new(jdh.Values)
	args.Add(jdh.KeyId, tax.Id)
	args.Add(jdh.TaxParent, p.Id)
	localDB.Exec(jdh.Set, jdh.Taxonomy, args)
}
Beispiel #18
0
func spDelRun(c *cmdapp.Command, args []string) {
	openLocal(c)
	vals := new(jdh.Values)
	if len(idFlag) > 0 {
		vals.Add(jdh.KeyId, idFlag)
		if _, err := localDB.Exec(jdh.Delete, jdh.Specimens, vals); err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		localDB.Exec(jdh.Commit, "", nil)
		return
	}
	var tax *jdh.Taxon
	if len(taxonFlag) > 0 {
		tax = taxon(c, localDB, taxonFlag)
		if len(tax.Id) == 0 {
			return
		}
	} else if len(args) > 0 {
		if len(args) > 2 {
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("too many arguments"))
			os.Exit(1)
		}
		pName := ""
		if len(args) > 1 {
			pName = args[1]
		}
		tax = pickTaxName(c, localDB, args[0], pName)
		if len(tax.Id) == 0 {
			return
		}
	} else {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong specimen id or taxon name or id"))
		c.Usage()
	}
	vals.Add(jdh.SpeTaxon, tax.Id)
	if _, err := localDB.Exec(jdh.Delete, jdh.Specimens, vals); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	localDB.Exec(jdh.Commit, "", nil)
}
Beispiel #19
0
// PickTaxName search for a unique taxon name. If there are more taxons
// fullfilling the name, then it will print a list of the potential
// names and finish the program.
func pickTaxName(c *cmdapp.Command, db jdh.DB, name, parent string) *jdh.Taxon {
	args := new(jdh.Values)
	args.Add(jdh.TaxName, name)
	if len(parent) != 0 {
		args.Add(jdh.TaxParentName, parent)
	}
	l, err := db.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	var tax *jdh.Taxon
	mult := false
	for {
		ot := &jdh.Taxon{}
		if err := l.Scan(ot); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if tax == nil {
			tax = ot
			continue
		}
		if !mult {
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("ambiguos taxon name"))
			fmt.Fprintf(os.Stderr, "%s\t%s\n", tax.Id, tax.Name)
			mult = true
		}
		fmt.Fprintf(os.Stderr, "%s\t%s\n", ot.Id, ot.Name)
	}
	if mult {
		os.Exit(0)
	}
	if tax == nil {
		return &jdh.Taxon{}
	}
	return tax
}
Beispiel #20
0
func txLsRankNav(c *cmdapp.Command, db jdh.DB, id string, rank jdh.Rank) {
	args := new(jdh.Values)
	args.Add(jdh.TaxChildren, id)
	l, err := db.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	for {
		desc := &jdh.Taxon{}
		if err := l.Scan(desc); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if len(desc.Id) == 0 {
			continue
		}
		txLsRank(c, db, desc, rank)
	}
}
Beispiel #21
0
func newSpList(tax *jdh.Taxon, db jdh.DB) *spList {
	ls := &spList{
		db:  db,
		sel: -1,
		tax: tax,
	}
	if taxonRank(cmd, db, tax) < jdh.Species {
		return ls
	}
	vals := new(jdh.Values)
	vals.Add(jdh.SpeTaxon, tax.Id)
	l, err := db.List(jdh.Specimens, vals)
	if err != nil {
		return ls
	}
	for {
		spe := &jdh.Specimen{}
		if err := l.Scan(spe); err != nil {
			break
		}
		ls.spe = append(ls.spe, spe)
	}
	return ls
}
Beispiel #22
0
// TrInPickTax returns the id of a given taxon name. If there are more taxons
// fullfilling the name, then it will print a list of the potential
// names and finish the program.
func trInPickTax(name, parent string) (string, error) {
	vals := new(jdh.Values)
	vals.Add(jdh.TaxName, name)
	if len(parent) != 0 {
		vals.Add(jdh.TaxParent, parent)
	}
	rank := jdh.Unranked
	if len(rankFlag) > 0 {
		rank = jdh.GetRank(rankFlag)
		if rank != jdh.Unranked {
			vals.Add(jdh.TaxRank, rankFlag)
		}
	}
	l, err := localDB.List(jdh.Taxonomy, vals)
	if err != nil {
		return "", err
	}
	var tax *jdh.Taxon
	mult := ""
	for {
		ot := &jdh.Taxon{}
		if err := l.Scan(ot); err != nil {
			if err == io.EOF {
				break
			}
			return "", err
		}
		if tax == nil {
			tax = ot
			continue
		}
		if len(mult) == 0 {
			mult = fmt.Sprintf("ambiguos taxon name\n")
			mult += fmt.Sprintf("%s\t%s\n", tax.Id, tax.Name)
		}
		mult += fmt.Sprintf("%s\t%s\n", ot.Id, ot.Name)
	}
	if len(mult) > 0 {
		return "", errors.New(mult)
	}
	if tax == nil {
		tax = &jdh.Taxon{
			Name:    name,
			IsValid: true,
			Parent:  parent,
			Rank:    rank,
		}
		return localDB.Exec(jdh.Add, jdh.Taxonomy, tax)
	}
	return tax.Id, nil
}
Beispiel #23
0
// search for a parent of the given rank.
func txSyncRankedParent(c *cmdapp.Command, id string, rank jdh.Rank) *jdh.Taxon {
	args := new(jdh.Values)
	args.Add(jdh.TaxParents, id)
	l, err := extDB.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	defer l.Close()
	for {
		p := &jdh.Taxon{}
		if err := l.Scan(p); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if p.Rank == rank {
			return p
		}
	}
	return nil
}
Beispiel #24
0
func spInSearchNmdTaxon(c *cmdapp.Command, name, parent, txNum string, rank jdh.Rank) (bool, string) {
	args := new(jdh.Values)
	args.Add(jdh.TaxName, name)
	if len(parent) != 0 {
		args.Add(jdh.TaxParent, parent)
	}
	if rank != jdh.Unranked {
		args.Add(jdh.TaxRank, rank.String())
	}
	l, err := localDB.List(jdh.Taxonomy, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	defer l.Close()
	var tax *jdh.Taxon
	mult := false
	for {
		ot := &jdh.Taxon{}
		if err := l.Scan(ot); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if tax == nil {
			tax = ot
			continue
		}
		if !mult {
			if verboseFlag {
				fmt.Fprintf(os.Stdout, "WARNING:\t%s\t%s\tAmbiguos name\n", txNum)
				fmt.Fprintf(os.Stdout, "%s\t%s\n", tax.Id, tax.Name)
			}
			mult = true

		}
		if verboseFlag {
			fmt.Fprintf(os.Stderr, "%s\t%s\n", ot.Id, ot.Name)
		}
	}
	if mult || (tax == nil) {
		return mult, ""
	}
	return false, tax.Id
}
Beispiel #25
0
func newTxList(tax *jdh.Taxon, db jdh.DB, syns bool) *txList {
	ls := &txList{
		db:   db,
		tax:  tax,
		syns: syns,
	}
	id := ""
	if tax == nil {
		ls.tax = &jdh.Taxon{
			Id:   "0",
			Name: "root",
		}
	} else {
		id = tax.Id
	}
	vals := new(jdh.Values)
	vals.Add(jdh.TaxChildren, id)
	pl, err := db.List(jdh.Taxonomy, vals)
	if err != nil {
		return ls
	}
	for {
		d := &jdh.Taxon{}
		if err := pl.Scan(d); err != nil {
			break
		}
		ls.desc = append(ls.desc, d)
	}
	if !syns {
		return ls
	}
	vals.Reset()
	vals.Add(jdh.TaxSynonyms, id)
	pl, err = db.List(jdh.Taxonomy, vals)
	if err != nil {
		return ls
	}
	for {
		s := &jdh.Taxon{}
		if err := pl.Scan(s); err != nil {
			break
		}
		ls.desc = append(ls.desc, s)
	}
	return ls
}
Beispiel #26
0
func txEdMove(from, to *jdh.Taxon) {
	if from.Id == "0" {
		return
	}
	if (from.Id == to.Id) || (from.Parent == to.Id) {
		return
	}
	if (to.Id == "0") && (!from.IsValid) {
		return
	}
	vals := new(jdh.Values)
	vals.Add(jdh.KeyId, from.Id)
	if to.Id != "0" {
		vals.Add(jdh.TaxParent, to.Id)
	} else {
		vals.Add(jdh.TaxParent, "")
	}
	localDB.Exec(jdh.Set, jdh.Taxonomy, vals)
}
Beispiel #27
0
func raMkGetRas(c *cmdapp.Command, id string, size float64) *jdh.Raster {
	vals := new(jdh.Values)
	vals.Add(jdh.RDisTaxon, id)
	vals.Add(jdh.RDisCols, strconv.FormatInt(int64(360/size), 10))
	vals.Add(jdh.RDisSource, jdh.ExplicitPoints.String())
	l := rasList(c, localDB, vals)
	defer l.Close()
	for {
		ras := &jdh.Raster{}
		if err := l.Scan(ras); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		return ras
	}
	return &jdh.Raster{}
}
Beispiel #28
0
func trForceNode(c *cmdapp.Command, nod *jdh.Node, txLs *list.List) {
	vals := new(jdh.Values)
	vals.Add(jdh.NodChildren, nod.Id)
	l, err := localDB.List(jdh.Nodes, vals)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
		os.Exit(1)
	}
	childs := 0
	for {
		desc := &jdh.Node{}
		if err := l.Scan(desc); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		trForceNode(c, desc, txLs)
		childs++
	}
	if childs > 1 {
		return
	}
	if len(nod.Taxon) == 0 {
		return
	}
	tax := taxon(c, localDB, nod.Taxon)
	if tax.IsValid {
		return
	}
	par := taxon(c, localDB, tax.Parent)
	todel := false
	for e := txLs.Front(); e != nil; e = e.Next() {
		tId := e.Value.(string)
		if tId == par.Id {
			todel = true
			break
		}
	}
	if todel {
		fmt.Fprintf(os.Stdout, "%s: deleted\n", tax.Name)
		if !repFlag {
			vals.Reset()
			vals.Add(jdh.KeyId, nod.Id)
			localDB.Exec(jdh.Delete, jdh.Nodes, vals)
		}
		return
	}
	fmt.Fprintf(os.Stdout, "%s: changed to: %s\n", tax.Name, par.Name)
	if !repFlag {
		vals.Reset()
		vals.Add(jdh.KeyId, nod.Id)
		vals.Add(jdh.NodTaxon, par.Id)
		localDB.Exec(jdh.Set, jdh.Nodes, vals)
		txLs.PushBack(par.Id)
	}
}
Beispiel #29
0
// TrInReadTreeNode reads a tree node in parenthetical notation.
func trInReadTreeNode(in *bufio.Reader, tree, anc, pId string, taxLs map[string]string) (string, error) {
	nod := &jdh.Node{
		Tree:   tree,
		Parent: anc,
	}
	id, err := localDB.Exec(jdh.Add, jdh.Nodes, nod)
	if err != nil {
		return "", err
	}
	nod.Id = id
	last := ""
	for {
		r, _, err := in.ReadRune()
		if err != nil {
			return "", err
		}
		if unicode.IsSpace(r) {
			continue
		}
		if r == '(' {
			last, err = trInReadTreeNode(in, tree, nod.Id, pId, taxLs)
			if err != nil {
				return "", err
			}
			continue
		}
		if r == ')' {
			break
		}
		if r == ',' {
			last = ""
			continue
		}
		if r == ':' {
			if len(last) == 0 {
				return "", errors.New("unexpected ':' token")
			}
			v, err := trInNumber(in)
			if err != nil {
				return "", err
			}
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, last)
			vals.Add(jdh.NodLength, strconv.FormatUint(uint64(v), 10))
			localDB.Exec(jdh.Set, jdh.Nodes, vals)
			last = ""
			continue
		}
		// a terminal
		in.UnreadRune()
		nm, err := trInString(in)
		if err != nil {
			return "", err
		}
		tax, ok := taxLs[nm]
		if !ok {
			tax, err = trInPickTax(nm, pId)
			if err != nil {
				return "", err
			}
			taxLs[nm] = tax
		}
		term := &jdh.Node{
			Tree:   tree,
			Parent: nod.Id,
			Taxon:  tax,
		}
		last, err = localDB.Exec(jdh.Add, jdh.Nodes, term)
		if err != nil {
			return "", err
		}
	}
	return nod.Id, nil
}
Beispiel #30
0
func spGrefProc(c *cmdapp.Command, tax *jdh.Taxon, gzt geography.Gazetter) {
	defer func() {
		l := getTaxDesc(c, localDB, tax.Id, true)
		spGrefNav(c, l, gzt)
		l = getTaxDesc(c, localDB, tax.Id, false)
		spGrefNav(c, l, gzt)
	}()
	if len(tax.Id) == 0 {
		return
	}
	vals := new(jdh.Values)
	vals.Add(jdh.SpeTaxon, tax.Id)
	if !addFlag {
		vals.Add(jdh.SpeGeoref, "true")
	}
	l := speList(c, localDB, vals)
	defer l.Close()
	for {
		spe := &jdh.Specimen{}
		if err := l.Scan(spe); err != nil {
			if err == io.EOF {
				break
			}
			fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
			os.Exit(1)
		}
		if len(spe.Georef.Validation) > 0 {
			continue
		}
		if !spe.Geography.IsValid() {
			fmt.Fprintf(os.Stdout, "%s: location without valid country\n", spe.Id)
			continue
		}
		u := uint(uncertFlag)
		if u == 0 {
			if u = spe.Georef.Uncertainty; u == 0 {
				// 200 km is the maximum validation
				u = 200000
			}
		}
		if !spe.Georef.IsValid() {
			if !addFlag {
				fmt.Fprintf(os.Stdout, "%s: invalid georeference\n", spe.Id)
				continue
			}
			p, err := gzt.Locate(&spe.Geography, spe.Locality, uint(uncertFlag))
			if err != nil {
				fmt.Fprintf(os.Stdout, "%s: unable to add: %v\n", spe.Id, err)
				if verboseFlag {
					if err == geography.ErrAmbiguous {
						pts, err := gzt.List(&spe.Geography, spe.Locality, uint(uncertFlag))
						if err != nil {
							fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err))
							continue
						}
						for _, p := range pts {
							fmt.Fprintf(os.Stderr, "\t%.5f %.5f\t%d\n", p.Point.Lon, p.Point.Lat, p.Uncertainty)
						}
					}
				}
				continue
			}
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, spe.Id)
			vals.Add(jdh.GeoLonLat, strconv.FormatFloat(p.Point.Lon, 'g', -1, 64)+","+strconv.FormatFloat(p.Point.Lat, 'g', -1, 64))
			vals.Add(jdh.GeoUncertainty, strconv.FormatInt(int64(p.Uncertainty), 10))
			vals.Add(jdh.GeoSource, p.Source)
			vals.Add(jdh.GeoValidation, p.Validation)
			localDB.Exec(jdh.Set, jdh.Specimens, vals)
			continue
		}
		pts, err := gzt.List(&spe.Geography, spe.Locality, u)
		if err != nil {
			fmt.Fprintf(os.Stdout, "%s: %v\n", spe.Id, err)
			continue
		}
		if len(pts) == 0 {
			fmt.Fprintf(os.Stdout, "%s: location not found\n", spe.Id)
			continue
		}
		lon, lat := spe.Georef.Point.Lon, spe.Georef.Point.Lat
		val := false
		gr := geography.Georeference{
			Point:       geography.InvalidPoint(),
			Uncertainty: geography.EarthRadius * 10, // a distance large enough
		}
		for _, p := range pts {
			d := p.Point.Distance(lon, lat)
			if d <= u {
				val = true
				if (d + p.Uncertainty) < gr.Uncertainty {
					gr = p
					gr.Uncertainty += d
				}
			}
		}
		if val {
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, spe.Id)
			if spe.Georef.Uncertainty == 0 {
				vals.Add(jdh.GeoUncertainty, strconv.FormatInt(int64(gr.Uncertainty), 10))
			}
			vals.Add(jdh.GeoValidation, gr.Validation)
			localDB.Exec(jdh.Set, jdh.Specimens, vals)
			continue
		}
		if !corrFlag {
			fmt.Fprintf(os.Stdout, "%s: location not found\n", spe.Id)
			if verboseFlag {
				fmt.Fprintf(os.Stderr, "\t%.5f %.5f\t\t[current georeference]\n", lon, lat)
				for _, p := range pts {
					fmt.Fprintf(os.Stderr, "\t%.5f %.5f\t%d\t%d\n", p.Point.Lon, p.Point.Lat, p.Uncertainty, p.Point.Distance(lon, lat))
				}
			}
			continue
		}
		gr = geography.Georeference{
			Point:       geography.InvalidPoint(),
			Uncertainty: geography.EarthRadius * 10, // a distance large enough
		}
		val = false
		for _, p := range pts {
			// invert lon-lat
			lt, ln := lon, lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}

			// lon with wrong sign
			ln, lt = -lon, lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}

			// lat with wrong sing
			ln, lt = lon, -lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}

			// invert lon-lat, wrong sings
			lt, ln = -lon, -lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}

			// invert lon-lat, lon with wrong sing
			lt, ln = lon, -lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}

			// invert lon-lat, lat with wrong sing
			lt, ln = -lon, lat
			if geography.IsLon(ln) && geography.IsLat(lt) {
				d := p.Point.Distance(lon, lat)
				if d <= u {
					val = true
					gr = p
					gr.Point = geography.Point{Lon: ln, Lat: lt}
					gr.Uncertainty += d
					break
				}
			}
		}
		if val {
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, spe.Id)
			vals.Add(jdh.GeoLonLat, strconv.FormatFloat(gr.Point.Lon, 'g', -1, 64)+","+strconv.FormatFloat(gr.Point.Lat, 'g', -1, 64))
			vals.Add(jdh.GeoUncertainty, strconv.FormatInt(int64(gr.Uncertainty), 10))
			vals.Add(jdh.GeoSource, gr.Source)
			vals.Add(jdh.GeoValidation, gr.Validation)
			localDB.Exec(jdh.Set, jdh.Specimens, vals)
			continue
		}
		fmt.Fprintf(os.Stdout, "%s: not corrected\n", spe.Id)
		if verboseFlag {
			fmt.Fprintf(os.Stderr, "\t%.5f %.5f\t\t[current georeference]\n", lon, lat)
			for _, p := range pts {
				fmt.Fprintf(os.Stderr, "\t%.5f %.5f\t%d\t%d\n", p.Point.Lon, p.Point.Lat, p.Uncertainty, p.Point.Distance(lon, lat))
			}
		}
	}
}