Taxon Framework Relationship error

How do I find the internal taxon this error is referring to?

OK, found it from the page with appropriate filter.

You shouldn’t be creating a framework for a taxon with a different external taxon name than the internal taxon…? If POWO has the taxon set as a synonym, you should make a taxon change and add the TFR to the proper name.


I accept your reply but the issue here appears to be iNat users’ unwillingness to accept the taxonomy currently promoted by POWO. See here for a discussion of the differences in opinion.

There is a lot of information in that flag lol… either way, the external and internal taxon names should generally be the same… The only reason it would be different is if you are creating a deviation of a certain type. I would check with the curators involved in the flag before creating a framework relationship.

It looks properly set up, but it is a duplicate so you would have to delete or change the old one.

I’ve never seen such a complex tree before so I’m not sure exactly how it works, but it looks like you’re trying to add a relationship for something that already is in the system.

Wow, that is certainly complex.

Shouldn’t each species have its own relationship rather than being in this huge one?
E.g. since Lobivia aurea goes with Echinopsis aurea, there should be a simple deviation relationship that just has L. aurea > E. aurea. Right now if I click on the Taxonomy Details button on the species page of any of these species, it goes to this whole thing.

There are only two small things I don’t understand here:

  1. All cactus taxonomy.
  2. iNat’s taxonomic inner workings.

Other than that, this is all perfectly clear…but, boy, does my head hurt. ;-)

1 Like

Maybe because the deviation is at the subfamily level it’s easier to make one than a bunch for all the species? I don’t know a ton about this but @loarie made it so I assume it’s done well.

This isn’t exactly the inner workings but here’s more info on frameworks:

You can find it by searching on Taxon Framework (Tracheophyta) and the External Taxon name (Echinopsis formosa korethroides) on the taxon framework relationships index page

As an aside, I personally think taxon framework relationships work great for managing a small number of minor deviations from a reference (e.g. like these Reptile examples) But I realize that they become a huge headache and way too fragile and confusing if they become too extensive and complex like the cactus one in question

To me this is an indication that the gap between the external reference and iNat is to great to be spanned by fragile little taxon framework relationship bridges and we should either:

  1. come up with a new reference
  2. work with the reference to change
  3. just agree to tolerate the reference even if its not exactly what we want

Probably not a coincidence that Cactus are the textbook example of this too-large-a-gap issue. Of those three options, my preference would be (2). POWO has indicated that were a leader to step forward and get a few key stakeholders on board to propose a new global list everyone could live with they could update. But I realize that’s a good chunk of work, and it might not be worth waiting for such a leader to step forward…

1 Like

The huge horticultural interest in cacti has indeed created many differences of opinion regarding their taxonomy. Hence the extensive discussion in the flag I linked earlier. The TFR created by @loarie was built through discussions between the two of us over a couple of weeks but now needs some additional work to accommodate recent additions to iNaturalist’s internal taxonomy. Continuing to add to this TFR is obviously not sustainable and we do need to find an alternative. I agree with Scott that the best way forward is to work with POWO as in his option 2. To that end I have now offered to lead that process. The project will take time to show results and we will need users to submit serious proposals for many genera but hopefully we can eventually persuade POWO to update their cactus taxonomy to the benefit of both parties.

As a start to this project I’d like to get a handle on what TFRs are currently defined for Cactaceae. Is there any way I can download all active TFRs for decedents of Cactaceae as a CSV file?
I can query them using the TFR index page with “Cactaceae” as the external taxon as here:

but the equivalent query with “Cactaceae” moved to internal taxon fails, I get all TFRs under Trachaeophyta!

@pisum Can this be done through an API call?

as far as i can tell, the TFR page does not seem to be calling an API in any way to get data. so i assume it’s hitting the database directly. in other words, it’s unlikely you could get this data via API requests.

You can use the taxon_id instead:

But to download the data of all 1896 TFRs covering iNat’s Cactaceae taxa, I agree you’d have to scrape the pages.

Found a method:

Extract “taxon.txt” and filter on column 5 for “Cactaceae\t” with output to TSV file using FINDSTR in windows cmd shell
Import into Excel (or similar) database and export as CSV
Import into SQLite database

Maybe I misunderstood what you were looking for, but those aren’t TFRs, those are just POWO’s names. Any “not external” TFR will have no representation in that list.

I agree it’s one half of the TFR. I hope to get the iNat half using the API /taxa endpoint (21 pages), converting json to csv online, importing to SQLite and linking the two tables on genus+species+infra :crossed_fingers:

I scraped the TFR data:

import pandas as pd
import requests
import csv
import time

with open('cactus_tfrs.csv', encoding='utf-8', mode='w+', newline='') as fileout:
    csvwriter = csv.writer(fileout, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    csvwriter.writerow(["match type", "iNat taxa", "POWO taxa"])
    for i in range(1,65):
            r = requests.get("" + str(i))
            df_list = pd.read_html(r.text) # parse all the tables on the page to a list of dataframes
            for df in df_list:
                # write the match type, then the iNat taxa, then the POWO taxa
                csvwriter.writerow([df.iloc[0,1], ';'.join(df.iloc[:,0].dropna().tolist()), ';'.join(df.iloc[:,2].dropna().tolist())])
            print("error on page " + str(i))

Wonderful, thank you very much. I eventually realized that my approach would only give me potential matches rather than actual matches with no other match types. Scraping the query output was going to be my next task but I’m no way near as proficient in python as you. I’d no doubt have taken a far less efficient route.

Thank you.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.