From 4be5fa08d035c42676818db7f9707ad1fbc856e4 Mon Sep 17 00:00:00 2001 From: Reena Date: Tue, 18 Nov 2025 12:30:39 -0500 Subject: [PATCH 1/6] edited microarray and added 2 new endpoints and created efp_proxy endpoints --- .gitignore | 3 + README.md | 17 + api/__init__.py | 2 + api/__init__.py.save | 116 + api/models/bar_utils.py | 4 + api/resources/efp_proxy.py | 535 + api/resources/microarray_gene_expression.py | 239 +- config/databases/sample_data.sql | 560 + config/species_databases.json | 177 + data/efp_info/efp_species_view_info.json | 18424 ++++++++++++++++ .../gene_isoforms/example_placeholder.txt | 0 docs/efp_proxy.md | 115 + scripts/build_sqlite_mirrors.py | 159 + 13 files changed, 20350 insertions(+), 1 deletion(-) create mode 100644 api/__init__.py.save create mode 100644 api/models/bar_utils.py create mode 100644 api/resources/efp_proxy.py create mode 100644 config/databases/sample_data.sql create mode 100644 config/species_databases.json create mode 100644 data/efp_info/efp_species_view_info.json delete mode 100644 data/gene_information/gene_isoforms/example_placeholder.txt create mode 100644 docs/efp_proxy.md create mode 100755 scripts/build_sqlite_mirrors.py diff --git a/.gitignore b/.gitignore index 7e08bbb..34ddd49 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,6 @@ dmypy.json output/* !output !output/placeholder.txt + +# Local sqlite mirrors generated from MySQL dumps +config/databases/*.db diff --git a/README.md b/README.md index c354f9e..854afda 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,20 @@ [![Website Status](https://img.shields.io/website?url=http%3A%2F%2Fbar.utoronto.ca%2Fapi%2F)](http://bar.utoronto.ca/api/) ![GitHub repo size](https://img.shields.io/github/repo-size/BioAnalyticResource/BAR_API) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Documentation Status](https://readthedocs.org/projects/bar-api/badge/?version=latest)](https://bar-api.readthedocs.io/en/latest/?badge=latest) This is the official repository for the Bio-Analytic Resource API. The API documentation can be found [here](https://bar-api.readthedocs.io/en/latest/). + +## Local eFP sqlite mirrors + +The `/efp_proxy/expression/{database}/{gene_id}` endpoint first tries to query a live SQLAlchemy bind (as configured in `config/BAR_API.cfg`). When you do not have access to those remote MySQL instances, you can still exercise the API by generating local SQLite mirrors from the shipped MySQL dumps: + +```bash +# Build every mirror (takes a few minutes) +python scripts/build_sqlite_mirrors.py + +# Or only the datasets you care about +python scripts/build_sqlite_mirrors.py klepikova sample_data + +# Use --force to overwrite existing *.db files +python scripts/build_sqlite_mirrors.py klepikova --force +``` + +The script transforms the dumps in `config/databases/*.sql` into companion `*.db` files in the same directory. The eFP proxy will automatically fall back to those mirrors whenever the corresponding MySQL bind is unavailable, while production deployments continue to use the remote databases as soon as they are reachable. diff --git a/api/__init__.py b/api/__init__.py index 43164b5..f6c8ed7 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -64,6 +64,7 @@ def create_app(): from api.resources.efp_image import efp_image from api.resources.fastpheno import fastpheno from api.resources.llama3 import llama3 + from api.resources.efp_proxy import efp_proxy_ns bar_api.add_namespace(gene_information) bar_api.add_namespace(rnaseq_gene_expression) @@ -78,6 +79,7 @@ def create_app(): bar_api.add_namespace(efp_image) bar_api.add_namespace(fastpheno) bar_api.add_namespace(llama3) + bar_api.add_namespace(efp_proxy_ns) bar_api.init_app(bar_app) return bar_app diff --git a/api/__init__.py.save b/api/__init__.py.save new file mode 100644 index 0000000..ebc57da --- /dev/null +++ b/api/__init__.py.save @@ -0,0 +1,116 @@ +from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from flask_restx import Api +from flask_cors import CORS +from flask_caching import Cache +from flask_limiter import Limiter +from flask_limiter.util import get_remote_address +import os +from api.resources.efp_proxy import efp_proxy +bar_api.add_namespace(efp_proxy) + + +def create_app(): + """Initialize the app factory based on the official Flask documentation""" + bar_app = Flask(__name__) + CORS(bar_app) + + # Load configuration + if os.environ.get("CI"): + # Travis + print("We are now loading configuration.") + bar_app.config.from_pyfile(os.getcwd() + "/config/BAR_API.cfg", silent=True) + + elif os.environ.get("BAR"): + # The BAR + bar_app.config.from_pyfile(os.environ.get("BAR_API_PATH"), silent=True) + + # Load environment variables on the BAR + if bar_app.config.get("PHENIX"): + os.environ["PHENIX"] = bar_app.config.get("PHENIX") + if bar_app.config.get("PHENIX_VERSION"): + os.environ["PHENIX_VERSION"] = bar_app.config.get("PHENIX_VERSION") + if bar_app.config.get("PATH"): + os.environ["PATH"] = bar_app.config.get("PATH") + ":/usr/local/phenix-1.18.2-3874/build/bin" + else: + # The localhost + bar_app.config.from_pyfile(os.path.expanduser("~") + "/.config/BAR_API.cfg", silent=True) + + # Initialize the databases + db.init_app(bar_app) + + # Initialize the cache + cache.init_app(bar_app) + + # Initialize rate limiter + limiter.init_app(bar_app) + + # Configure the Swagger UI + bar_api = Api( + title="BAR API", + version="0.0.1", + description="API for the Bio-Analytic Resource", + ) + + # Now add routes + from api.resources.gene_information import gene_information + from api.resources.rnaseq_gene_expression import rnaseq_gene_expression + from api.resources.microarray_gene_expression import microarray_gene_expression + from api.resources.proxy import bar_proxy + from api.resources.thalemine import thalemine + from api.resources.snps import snps + from api.resources.sequence import sequence + from api.resources.gene_annotation import gene_annotation + from api.resources.interactions import itrns + from api.resources.gene_localizations import loc + from api.resources.efp_image import efp_image + from api.resources.fastpheno import fastpheno + from api.resources.llama3 import llama3 + + bar_api.add_namespace(gene_information) + bar_api.add_namespace(rnaseq_gene_expression) + bar_api.add_namespace(microarray_gene_expression) + bar_api.add_namespace(bar_proxy) + bar_api.add_namespace(thalemine) + bar_api.add_namespace(snps) + bar_api.add_namespace(sequence) + bar_api.add_namespace(gene_annotation) + bar_api.add_namespace(itrns) + bar_api.add_namespace(loc) + bar_api.add_namespace(efp_image) + bar_api.add_namespace(fastpheno) + bar_api.add_namespace(llama3) + bar_api.init_app(bar_app) + return bar_app + + +# Initialize database system +db = SQLAlchemy() + +# Initialize Redis +if os.environ.get("BAR"): + cache = Cache( + config={ + "CACHE_TYPE": "RedisCache", + "CACHE_KEY_PREFIX": "BAR_API_", + "CACHE_REDIS_HOST": os.environ.get("BAR_REDIS_HOST"), + "CACHE_REDIS_PASSWORD": os.environ.get("BAR_REDIS_PASSWORD"), + } + ) +else: + cache = Cache( + config={ + "CACHE_TYPE": "RedisCache", + "CACHE_KEY_PREFIX": "BAR_API_", + "CACHE_REDIS_HOST": "localhost", + } + ) + +# Initialize Limiter +limiter = Limiter(key_func=get_remote_address) + +# Now create the bar_app +app = create_app() + +if __name__ == "__main__": + app.run() diff --git a/api/models/bar_utils.py b/api/models/bar_utils.py new file mode 100644 index 0000000..e30ab46 --- /dev/null +++ b/api/models/bar_utils.py @@ -0,0 +1,4 @@ +# Bridge file to maintain backward compatibility with imports +from api.utils.bar_utils import BARUtils + +__all__ = ['BARUtils'] diff --git a/api/resources/efp_proxy.py b/api/resources/efp_proxy.py new file mode 100644 index 0000000..6c5a489 --- /dev/null +++ b/api/resources/efp_proxy.py @@ -0,0 +1,535 @@ +import requests +import json +import os +import traceback +from pathlib import Path +from typing import Dict, List, Optional +from collections import OrderedDict +from flask_restx import Namespace, Resource +from flask import request, has_app_context +from markupsafe import escape +from sqlalchemy import create_engine, text +from sqlalchemy.orm import Session +from sqlalchemy.exc import SQLAlchemyError +from api import db +from api.models.annotations_lookup import AtAgiLookup +from api.models.bar_utils import BARUtils + +# efp proxy namespace - provides two endpoints for gene expression data: +# 1. /values talks to the live BAR ePlant CGI +# 2. /expression reads from our local/remote databases using one shared query +efp_proxy_ns = Namespace( + 'efp Proxy', + description='Expression data retrieveal service from BAR eplant databse.', + path='/efp_proxy', +) + +# absolute path to the config/databases directory (where the sqlite mirrors live) +# centralized path keeps helper functions in sync about where mirrors live +ROOT_DIR = Path(__file__).resolve().parents[2] +DATABASE_DIR = ROOT_DIR / "config" / "databases" + +# schema catalog for every database in config/databases +# spelling out the table + column names once means every db can share the same query code +# centralizing schema knowledge avoids per-database ORM duplication +DEFAULT_SAMPLE_SCHEMA = { + "table": "sample_data", + "gene_column": "data_probeset_id", + "sample_column": "data_bot_id", + "value_column": "data_signal", +} + +# list of all mirrors that follow the default schema (sample_data/data_signal, etc.) +# adding new entries here is enough for the dynamic endpoint to pick them up +SAMPLE_DATA_DATABASES = [ + "arabidopsis_ecotypes", + "arachis", + "cannabis", + "canola_nssnp", + "dna_damage", + "embryo", + "eplant2", + "eplant_poplar", + "eplant_rice", + "eplant_soybean", + "eplant_tomato", + "fastpheno", + "germination", + "homologs_db", + "interactions_vincent_v2", + "kalanchoe", + "klepikova", + "llama3", + "phelipanche", + "physcomitrella_db", + "poplar_nssnp", + "rice_interactions", + "sample_data", + "selaginella", + "shoot_apex", + "silique", + "single_cell", + "soybean_nssnp", + "strawberry", + "striga", + "tomato_nssnp", + "tomato_sequence", + "triphysaria", +] + +# databases that store microarray probeset identifiers in data_probeset_id. +# every other db expects a normal arabidopsis gene id (AT1G01010, etc.) +# this toggle informs the dynamic query whether it needs to translate AGIs to probesets +PROBESET_DATABASES = {"sample_data"} + +# build the catalog once at import time so every request can look up its schema quickly +# precomputing avoids rebuilding dictionaries for every HTTP request +DYNAMIC_DATABASE_SCHEMAS: Dict[str, Dict[str, str]] = {} +for db_name in SAMPLE_DATA_DATABASES: + schema = DEFAULT_SAMPLE_SCHEMA.copy() + schema.update( + { + "filename": f"{db_name}.db", + "identifier_type": "probeset" if db_name in PROBESET_DATABASES else "agi", + } + ) + DYNAMIC_DATABASE_SCHEMAS[db_name] = schema + +# normalize optional samples provided via query params (supports repeated params, +# comma-delimited strings, or the legacy JSON array format) +# clients historically sent sample lists in several shapes; this keeps backward compatibility +def parse_samples_query_values(raw_values: Optional[List[str]]) -> Optional[List[str]]: + if not raw_values: + return None + + filtered = [value for value in raw_values if value] + if not filtered: + return None + + if len(filtered) > 1: + return filtered + + candidate = filtered[0].strip() + if not candidate: + return None + + # interpret JSON array strings (legacy clients sent one JSON string value) + if candidate.startswith("[") and candidate.endswith("]"): + try: + parsed = json.loads(candidate) + if isinstance(parsed, list): + return [str(item).strip() for item in parsed if isinstance(item, str) and item.strip()] + except json.JSONDecodeError: + pass + + if "," in candidate: + # support comma-separated lists (?samples=A,B,C) by splitting manually + split_values = [item.strip() for item in candidate.split(",") if item.strip()] + if split_values: + return split_values + + return [candidate] + +# fetch gene expression data from the external bar eplant api +# either use the samples passed in or auto-fill the full list before calling the CGI +def fetch_efp_data(datasource, gene_id, samples=None): + # set up the external bar api url and basic query parameters + base_url = "https://bar.utoronto.ca//eplant/cgi-bin/plantefp.cgi" + query_params = [ + ("datasource", datasource), + ("id", gene_id), + ("format", "json"), + ] + samples_applied = False # tracks whether we hinted the CGI with explicit samples + + # handle optional sample filtering parameter + # when provided, expect a list of sample ids collected from the query params + if samples: + cleaned_samples = [sample.strip() for sample in samples if isinstance(sample, str) and sample.strip()] + if cleaned_samples: + query_params.append(("samples", json.dumps(cleaned_samples))) + samples_applied = True + # no samples provided, so try to auto-load all samples for this datasource + else: + samples = get_all_samples_for_view(datasource) + if samples: + print(f"[info] auto-loaded {len(samples)} samples for datasource {datasource}") + query_params.append(("samples", json.dumps(samples))) + samples_applied = True + else: + # no metadata entry means we let the CGI decide which default samples to use + print(f"[warn] no samples found for datasource {datasource}") + + # make exactly one http get request to the bar eplant cgi (packs every sample into this call) + response = requests.get(base_url, params=query_params) + url_called = response.url + + # check if the request failed with an http error code + if not response.ok: + # propagate error status so clients see the same HTTP code the CGI returned + return {"success": False, "error": f"bar returned {response.status_code} for url {url_called}"}, response.status_code + + # attempt to parse json response and extract data array + try: + data = response.json() + if isinstance(data, dict) and "data" in data: + data = data["data"] + except Exception: + # remote endpoint occasionally emits HTML error pages—treat them as no data + data = [] + + # if no results returned with samples, retry without sample filtering + # if filtering wiped out the response, retry once without sample hints + if (not data or data == []) and samples_applied: + retry_params = [ + ("datasource", datasource), + ("id", gene_id), + ("format", "json"), + ] + retry_resp = requests.get(base_url, params=retry_params) + # even if this second call fails, we still return an empty array to the caller + retry_url = retry_resp.url + + try: + retry_data = retry_resp.json() + if isinstance(retry_data, dict) and "data" in retry_data: + retry_data = retry_data["data"] + except Exception: + # treat malformed fallback responses as empty to keep behavior predictable + retry_data = [] + + return { + "success": True, + "url_called": url_called, + "record_count": len(retry_data), + "data": retry_data, + "note": "no data returned with samples; fetched full view instead." + } + return { + "success": True, + "url_called": url_called, + "record_count": len(data) if isinstance(data, list) else 0, + "data": data # payload mirrors what the real CGI would have returned + } + +# load all available samples for a datasource using our metadata json +# includes hardcoded fallbacks for specific views when the json is missing +def get_all_samples_for_view(datasource: str): + # point at the metadata json that was scraped from the eFP site + # during tests this file lives in the repo, so os.getcwd() resolves correctly + path = os.path.join(os.getcwd(), "data/efp_info/efp_species_view_info.json") + + # check for specific datasources that need hardcoded samples + if datasource == "root_Schaefer_lab": + # this dataset is missing from the scraped metadata, so we pin a curated set + print("[info] using hardcoded fallback samples for root_Schaefer_lab") + return ["WTCHG_203594_01","WTCHG_203594_05","WTCHG_203839_04","WTCHG_203594_03","WTCHG_203594_07","WTCHG_203839_06","WTCHG_203839_01","WTCHG_203594_10","WTCHG_203839_08","WTCHG_129187_01","WTCHG_129189_01","WTCHG_129190_01","WTCHG_129187_03","WTCHG_129189_03","WTCHG_129190_03","WTCHG_129187_05","WTCHG_129189_05","WTCHG_129187_07","WTCHG_131167_01","WTCHG_125416_01","WTCHG_129190_05","WTCHG_131167_03","WTCHG_125416_03","WTCHG_129190_07","WTCHG_131167_05","WTCHG_125416_05","WTCHG_129189_07"] + + if datasource == "atgenexp_stress": + # AtGenExp stress views still rely on the JSON metadata but we keep a minimal fallback + print("[info] using fallback arabidopsis samples from json spec") + return ["AtGen_6_0011", "AtGen_6_0012", "AtGen_6_0021", "AtGen_6_0022", + "AtGen_6_0711", "AtGen_6_0712", "AtGen_6_0721", "AtGen_6_0722" + ] + + # check if metadata json file exists + if not os.path.exists(path): + # repo clones without fixtures can still run, just without auto-sample loading + print(f"[warn] metadata json not found at {path}") + return [] + + # try to load and parse the json metadata file + try: + with open(path, "r") as f: + metadata = json.load(f) + except Exception as e: + print(f"[error] unable to read json: {e}") + return [] + + # search through all species and views to find matching datasource + # the metadata format is nested (species -> views -> groups -> treatments) + for species, obj in metadata.items(): + views = obj.get("data", {}).get("views", {}) + for vname, vinfo in views.items(): + if vinfo.get("database") == datasource: + # collect all unique samples from all treatment groups + samples = [] + for group in vinfo.get("groups", {}).values(): + # each group stores multiple treatment buckets; flatten all of them + for treatment_samples in group.get("treatments", {}).values(): + samples.extend(treatment_samples) + print(f"[info] found {len(samples)} samples in json for {datasource}") + return sorted(set(samples)) + + print(f"[warn] datasource {datasource} not found in json") + return [] + +# convert arabidopsis agi gene id (like AT1G01010) to probeset id +# queries the lookup table to find the most recent mapping +def agi_to_probset(gene_id: str): + try: + # build query to find most recent probeset for this agi + subquery = ( + db.select(AtAgiLookup.probeset) + .where(AtAgiLookup.agi == gene_id.upper()) + .order_by(AtAgiLookup.date.desc()) + .limit(1) + .subquery() + ) + + sq_query = db.session.query(subquery) + if sq_query.count() > 0: + # safest pick is the newest mapping because the array design changed over time + return sq_query[0][0] + else: + return None + except Exception as e: + print(f"[error] AGI to probeset conversion failed {e}") + return None + +# dynamically query any eFP database using the schema catalog above +# this replaces dozens of per-database ORM classes with one shared query path +def query_efp_database_dynamic(database: str, gene_id: str, sample_ids=None): + try: + database = str(database) + gene_id = str(gene_id) + + # look up how this database stores genes/samples so the generic query knows which columns to use + schema = DYNAMIC_DATABASE_SCHEMAS.get(database) + if not schema: + return { + "success": False, + "error": ( + f"Database '{database}' is not supported. " + f"Select one of: {', '.join(sorted(DYNAMIC_DATABASE_SCHEMAS.keys()))}" + ), + "error_code": 400, + } + + # decide which identifier should be used for the WHERE clause + query_id = gene_id + probset_display = None # used to echo what identifier we ultimately queried with + upper_id = gene_id.upper() + is_agi_id = upper_id.startswith("AT") and "G" in upper_id + + if is_agi_id: + # reject invalid AGI formatting up front before hitting the database + if not BARUtils.is_arabidopsis_gene_valid(upper_id): + return { + "success": False, + "error": "Invalid Arabidopsis gene ID format", + "error_code": 400, + } + + if schema["identifier_type"] == "probeset": + # older microarray mirrors store probeset-only identifiers + # some microarray mirrors still store probeset ids, so translate AGIs on the fly + probset = agi_to_probset(upper_id) + if not probset: + return { + "success": False, + "error": f"Could not find probeset for gene {gene_id}", + "error_code": 404, + } + query_id = probset + probset_display = probset + print(f"[info] Converted {gene_id} to probeset {query_id} for {database}") + else: + query_id = upper_id + probset_display = upper_id + + # build the full path to the requested database file (sqlite mirror on disk) + # tests ship trimmed fixtures, but production deployments still point to MySQL binds + db_path = DATABASE_DIR / schema["filename"] + + # try the real mysql bind first; if that fails, use the sqlite mirror + engine_candidates = [] + # candidate order matters: we prefer live binds but degrade gracefully to sqlite + if has_app_context(): + try: + bound_engine = db.get_engine(bind=database) + engine_candidates.append(("sqlalchemy_bind", bound_engine, False)) + except Exception as exc: + print(f"[warn] Unable to load SQLAlchemy bind for {database}: {exc}") + + if db_path.exists(): + # mirrors are SQLite files generated via scripts/build_sqlite_mirrors.py + sqlite_engine = create_engine(f"sqlite:///{db_path}") + engine_candidates.append(("sqlite_mirror", sqlite_engine, True)) + + if not engine_candidates: + return { + "success": False, + "error": f"Database {database} is not available (no active bind or sqlite mirror).", + "error_code": 404, + } + + where_clauses = [f"{schema['gene_column']} = :gene_id"] + # always parameterize values to avoid SQL injection and to cache query plans + params = {"gene_id": query_id} + + if sample_ids: + filtered = [s for s in sample_ids if s] + if filtered: + placeholders = [] + # build `IN (:sample_0, :sample_1, ...)` dynamically to keep it safe + for idx, sample in enumerate(filtered): + key = f"sample_{idx}" + placeholders.append(f":{key}") + params[key] = sample + where_clauses.append( + f"{schema['sample_column']} IN ({', '.join(placeholders)})" + ) + + # assemble one select statement that returns every sample/value for this gene + query_sql = text( + # select statements return a flat list of {sample, value} dicts for the caller + f"SELECT {schema['sample_column']} AS sample, {schema['value_column']} AS value " + f"FROM {schema['table']} " + f"WHERE {' AND '.join(where_clauses)}" + ) + + results = None + active_source = None + last_error = None + + for source_label, engine, dispose_after in engine_candidates: + try: + with Session(engine) as session: + results = session.execute(query_sql, params).all() + active_source = source_label # track whether MySQL or SQLite satisfied the query + break + except SQLAlchemyError as exc: + last_error = f"{source_label} failed: {exc}" + print(f"[warn] {last_error}") + except Exception as exc: + last_error = f"{source_label} unexpected failure: {exc}" + print(f"[warn] {last_error}") + finally: + if dispose_after: + # SQLite engines are cheap but keeping them open leaks file handles in tests + engine.dispose() + + if results is None: + return { + "success": False, + "error": ( + f"Database query failed for {database}. " + f"{'Last error: ' + last_error if last_error else ''}" + ).strip(), + "error_code": 500, + } + + if not results: + # returning 404 keeps parity with the legacy API response for missing genes + return { + "success": False, + "error": ( + f"No expression data found for {gene_id} " + f"(query identifier: {query_id})" + ), + "error_code": 404, + } + + # normalize the payload to match the eFP json structure the frontend expects + expression_data = [{"name": row.sample, "value": str(row.value)} for row in results] + # str() coercion keeps parity with the remote CGI which serializes numbers as strings + + return { + "success": True, + "gene_id": gene_id, + "probset_id": probset_display or query_id, + "database": database, + "record_count": len(expression_data), + "data": expression_data, + } + + except Exception as e: + error_trace = traceback.format_exc() + # printing the trace means docker logs show full context without leaking to client + print(f"[error] Database query exception: {error_trace}") + return { + "success": False, + "error": f"Database query failed: {str(e)}", + "error_code": 500 + } + +# rest endpoint that proxies requests to the external bar eplant api +# supports urls like /efp_proxy/values/atgenexp_stress/AT1G01010 +@efp_proxy_ns.route("/values//") +@efp_proxy_ns.doc( + description="Proxies requests to BAR ePlant API: /efp_proxy/values/{database}/{gene_id}", + params=OrderedDict([ + ( + "database", + { + "description": "Database/datasource for arabidopsis view (e.g., atgenexp_stress)", + "in": "path", + "default": "atgenexp_stress", + }, + ), + ( + "gene_id", + { + "description": "Gene ID to query (e.g., AT1G01010)", + "in": "path", + "default": "AT1G01010", + }, + ), + ( + "samples", + { + "description": "Optional list of sample IDs (repeat ?samples=SampleA&samples=SampleB); omit to fetch all samples. Legacy JSON arrays are still accepted.", + "in": "query", + "default": "", + }, + ), + ]), +) +class EFPValues(Resource): + def get(self, database, gene_id): + # sanitize path parameters to prevent injection attacks + database = escape(database) + gene_id = escape(gene_id) + + # parse ?samples= query args once so downstream logic gets a normalized list + samples_arg = parse_samples_query_values(request.args.getlist("samples")) + + # delegate to fetch_efp_data which auto-loads samples when none provided + return fetch_efp_data(database, gene_id, samples=samples_arg) +# rest endpoint that uses the static schema catalog to query local sqlite databases +# supports urls like /efp_proxy/expression/sample_data/261585_at +@efp_proxy_ns.route("/expression//") +@efp_proxy_ns.doc( + description="Static eFP endpoint: /efp_proxy/expression/{database}/{gene_id}" +) +@efp_proxy_ns.param( + "gene_id", + "Gene ID (AGI format like AT1G01010 or probeset like 261585_at)", + _in="path", + default="AT1G01010", +) +@efp_proxy_ns.param( + "database", + "Database name (e.g., sample_data, klepikova, single_cell)", + _in="path", + default="klepikova", +) +class EFPExpression(Resource): + def get(self, database, gene_id): + # sanitize path parameters to prevent injection attacks + database = escape(database) + gene_id = escape(gene_id) + + # delegate to query_efp_database_dynamic for deterministic queries + # optional sample filtering is not exposed here yet, hence sample_ids=None + result = query_efp_database_dynamic(database, gene_id, sample_ids=None) + + # return result with appropriate http status code + if result["success"]: + return result + else: + return result, result.get("error_code", 500) + +efp_proxy_ns.add_resource(EFPValues, '/values//') +efp_proxy_ns.add_resource(EFPExpression, '/expression//') diff --git a/api/resources/microarray_gene_expression.py b/api/resources/microarray_gene_expression.py index 6a2002a..df1022c 100644 --- a/api/resources/microarray_gene_expression.py +++ b/api/resources/microarray_gene_expression.py @@ -5,7 +5,7 @@ from api.models.arabidopsis_ecotypes import SampleData as EcotypesSampleData from api.utils.bar_utils import BARUtils from api.utils.world_efp_utils import WorldeFPUtils - +import json microarray_gene_expression = Namespace( "Microarray Gene Expression", @@ -58,3 +58,240 @@ def get(self, species="", gene_id=""): return BARUtils.success_exit(final_json) else: return BARUtils.error_exit("There are no data found for the given gene") + +# endpoint made by reena +# return view and database mappings for a given species +@microarray_gene_expression.route("//databases") +class GetDatabases(Resource): + @microarray_gene_expression.param("species", _in="path", default="arabidopsis") + def get(self, species=""): + """This endpoint returns available database and view mappings for a given species""" + species = escape(species) + + species_databases = { + "actinidia": { + "Bud_Development": "actinidia_bud_development", + "Flower_Fruit_Development": "actinidia_flower_fruit_development", + "Postharvest": "actinidia_postharvest", + "Vegetative_Growth": "actinidia_vegetative_growth" + }, + "arabidopsis": { + "Abiotic_Stress": "atgenexp_stress", + "Abiotic_Stress_II": "atgenexp_stress", + "Biotic_Stress": "atgenexp_pathogen", + "Biotic_Stress_II": "atgenexp_pathogen", + "Chemical": "atgenexp_hormone", + "DNA_Damage": "dna_damage", + "Development_RMA": "atgenexp", + "Developmental_Map": "atgenexp_plus", + "Developmental_Mutants": "atgenexp_plus", + "Embryo": "embryo", + "Germination": "germination", + "Guard_Cell": "guard_cell", + "Gynoecium": "gynoecium", + "Hormone": "atgenexp_hormone", + "Klepikova_Atlas": "klepikova", + "Lateral_Root_Initiation": "lateral_root_initiation", + "Light_Series": "light_series", + "Natural_Variation": "arabidopsis_ecotypes", + "Regeneration": "meristem_db", + "Root": "root", + "Root_II": "root", + "Seed": "seed_db", + "Shoot_Apex": "shoot_apex", + "Silique": "silique", + "Single_Cell": "single_cell", + "Tissue_Specific": "atgenexp_plus" + }, + "arabidopsis seedcoat": { + "Seed_Coat": "seedcoat" + }, + "arachis": { + "Arachis_Atlas": "arachis" + }, + "barley": { + "barley_mas": "barley_mas", + "barley_rma": "barley_rma" + }, + "brachypodium": { + "Brachypodium_Atlas": "brachypodium", + "Brachypodium_Grains": "brachypodium_grains", + "Brachypodium_Spikes": "brachypodium_Bd21", + "Photo_Thermocycle": "brachypodium_photo_thermocycle" + }, + "brassica rapa": { + "Embryogenesis": "brassica_rapa" + }, + "cacao ccn": { + "Developmental_Atlas": "cacao_developmental_atlas", + "Drought_Diurnal_Atlas": "cacao_drought_diurnal_atlas" + }, + "cacao sca": { + "Developmental_Atlas": "cacao_developmental_atlas_sca", + "Drought_Diurnal_Atlas": "cacao_drought_diurnal_atlas_sca", + "Meristem_Atlas": "cacao_meristem_atlas_sca", + "Seed_Atlas": "cacao_seed_atlas_sca" + }, + "cacao tc": { + "Cacao_Infection": "cacao_infection", + "Cacao_Leaf": "cacao_leaf" + }, + "camelina": { + "Developmental_Atlas_FPKM": "camelina", + "Developmental_Atlas_TPM": "camelina_tpm" + }, + "cannabis": { + "Cannabis_Atlas": "cannabis" + }, + "canola": { + "Canola_Seed": "canola_seed" + }, + "eutrema": { + "Eutrema": "thellungiella_db" + }, + "grape": { + "grape_developmental": "grape_developmental" + }, + "kalanchoe": { + "Light_Response": "kalanchoe" + }, + "little millet": { + "Life_Cycle": "little_millet" + }, + "lupin": { + "LCM_Leaf": "lupin_lcm_leaf", + "LCM_Pod": "lupin_lcm_pod", + "LCM_Stem": "lupin_lcm_stem", + "Whole_Plant": "lupin_whole_plant" + }, + "maize": { + "Downs_et_al_Atlas": "maize_gdowns", + "Early_Seed": "maize_early_seed", + "Embryonic_Leaf_Development": "maize_embryonic_leaf_development", + "Hoopes_et_al_Atlas": "maize_buell_lab", + "Hoopes_et_al_Stress": "maize_buell_lab", + "Maize_Kernel": "maize_early_seed", + "Maize_Root": "maize_root", + "Sekhon_et_al_Atlas": "maize_RMA_linear", + "Tassel_and_Ear_Primordia": "maize_ears", + "maize_iplant": "maize_iplant", + "maize_leaf_gradient": "maize_leaf_gradient", + "maize_rice_comparison": "maize_rice_comparison" + }, + "mangosteen": { + "Aril_vs_Rind": "mangosteen_aril_vs_rind", + "Callus": "mangosteen_callus", + "Diseased_vs_Normal": "mangosteen_diseased_vs_normal", + "Fruit_Ripening": "mangosteen_fruit_ripening", + "Seed_Development": "mangosteen_seed_development", + "Seed_Germination": "mangosteen_seed_germination" + }, + "medicago": { + "medicago_mas": "medicago_mas", + "medicago_rma": "medicago_rma", + "medicago_seed": "medicago_seed" + }, + "poplar": { + "Poplar": "poplar", + "PoplarTreatment": "poplar" + }, + "potato": { + "Potato_Developmental": "potato_dev", + "Potato_Stress": "potato_stress" + }, + "rice": { + "rice_drought_heat_stress": "rice_drought_heat_stress", + "rice_leaf_gradient": "rice_leaf_gradient", + "rice_maize_comparison": "rice_maize_comparison", + "rice_mas": "rice_mas", + "rice_rma": "rice_rma", + "riceanoxia_mas": "rice_mas", + "riceanoxia_rma": "rice_rma", + "ricestigma_mas": "rice_mas", + "ricestigma_rma": "rice_rma", + "ricestress_mas": "rice_mas", + "ricestress_rma": "rice_rma" + }, + "soybean": { + "soybean": "soybean", + "soybean_embryonic_development": "soybean_embryonic_development", + "soybean_heart_cotyledon_globular": "soybean_heart_cotyledon_globular", + "soybean_senescence": "soybean_senescence", + "soybean_severin": "soybean_severin" + }, + "strawberry": { + "Developmental_Map_Strawberry_Flower_and_Fruit": "strawberry", + "Strawberry_Green_vs_White_Stage": "strawberry" + }, + "tomato": { + "ILs_Leaf_Chitwood_et_al": "tomato_ils", + "ILs_Root_Tip_Brady_Lab": "tomato_ils2", + "M82_S_pennellii_Atlases_Koenig_et_al": "tomato_s_pennellii", + "Rose_Lab_Atlas": "tomato", + "Rose_Lab_Atlas_Renormalized": "tomato_renormalized", + "SEED_Lab_Angers": "tomato_seed", + "Shade_Mutants": "tomato_shade_mutants", + "Shade_Timecourse_WT": "tomato_shade_timecourse", + "Tomato_Meristem": "tomato_meristem" + }, + "triticale": { + "triticale": "triticale", + "triticale_mas": "triticale_mas" + }, + "wheat": { + "Developmental_Atlas": "wheat", + "Wheat_Abiotic_Stress": "wheat_abiotic_stress", + "Wheat_Embryogenesis": "wheat_embryogenesis", + "Wheat_Meiosis": "wheat_meiosis" + } + } + + if species not in species_databases: + return BARUtils.error_exit("Invalid species") + + return BARUtils.success_exit({ + "species": species, + "databases": species_databases[species] + }) + + +# endpoint made by reena +# return control and sample mappings for a given species +@microarray_gene_expression.route("///samples") +class GetSamples1(Resource): + """This endpoint returns control and sample group mappings for a given species and view (or all views)""" + + @microarray_gene_expression.param("species", _in="path", default="arabidopsis") + @microarray_gene_expression.param("view", _in="path", default="Abiotic_Stress") + def get(self, species="", view=""): + """This endpoint returns control and sample group mappings for a given species and view (or all views)""" + species = escape(species.lower()) + view = escape(view) + + try: + with open("data/efp_info/efp_species_view_info.json") as f: + all_species_data = json.load(f) + except Exception as e: + return BARUtils.error_exit(f"Data file missing or invalid: {e}") + + if species not in all_species_data: + return BARUtils.error_exit("Invalid species") + + species_data = all_species_data[species]["data"] + + # if user requests all views + if view.lower() == "all": + return BARUtils.success_exit({ + "species": species, + "views": species_data["views"] + }) + + # otherwise check single view + if view not in species_data["views"]: + return BARUtils.error_exit("Invalid view for this species") + + return BARUtils.success_exit({ + "species": species, + "view": view, + "groups": species_data["views"][view]["groups"] + }) \ No newline at end of file diff --git a/config/databases/sample_data.sql b/config/databases/sample_data.sql new file mode 100644 index 0000000..e4228c2 --- /dev/null +++ b/config/databases/sample_data.sql @@ -0,0 +1,560 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1deb1+deb12u1 +-- https://www.phpmyadmin.net/ +-- +-- Host: localhost:3306 +-- Generation Time: Oct 16, 2025 at 06:44 PM +-- Server version: 8.4.6 +-- PHP Version: 8.2.29 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `atgenexp` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `sample_data` +-- + +CREATE TABLE `sample_data` ( + `sample_id` int UNSIGNED NOT NULL DEFAULT '0', + `proj_id` int UNSIGNED NOT NULL DEFAULT '0', + `sample_file_name` tinytext NOT NULL, + `data_probeset_id` varchar(30) DEFAULT NULL, + `data_signal` float NOT NULL DEFAULT '0', + `data_call` tinytext NOT NULL, + `data_p_val` float NOT NULL DEFAULT '0', + `data_bot_id` varchar(50) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `sample_data` +-- + +INSERT INTO `sample_data` (`sample_id`, `proj_id`, `sample_file_name`, `data_probeset_id`, `data_signal`, `data_call`, `data_p_val`, `data_bot_id`) VALUES +(232, 6, 'ATGE_100_A_tair.txt', '256898_at', 24.975, '', 0, 'ATGE_100_A'), +(233, 6, 'ATGE_100_B_tair.txt', '256898_at', 22.77, '', 0, 'ATGE_100_B'), +(234, 6, 'ATGE_100_C_tair.txt', '256898_at', 20.416, '', 0, 'ATGE_100_C'), +(235, 6, 'ATGE_101_A_tair.txt', '256898_at', 22.106, '', 0, 'ATGE_101_A'), +(236, 6, 'ATGE_101_B_tair.txt', '256898_at', 21.477, '', 0, 'ATGE_101_B'), +(237, 6, 'ATGE_101_C_tair.txt', '256898_at', 25.781, '', 0, 'ATGE_101_C'), +(28, 1, 'ATGE_10_A_tair.txt', '256898_at', 29.274, '', 0, 'ATGE_10_A'), +(29, 1, 'ATGE_10_B_tair.txt', '256898_at', 23.631, '', 0, 'ATGE_10_B'), +(30, 1, 'ATGE_10_C_tair.txt', '256898_at', 20.562, '', 0, 'ATGE_10_C'), +(31, 1, 'ATGE_11_A_tair.txt', '256898_at', 25.333, '', 0, 'ATGE_11_A'), +(32, 1, 'ATGE_11_B_tair.txt', '256898_at', 23.132, '', 0, 'ATGE_11_B'), +(33, 1, 'ATGE_11_C_tair.txt', '256898_at', 22.21, '', 0, 'ATGE_11_C'), +(34, 1, 'ATGE_12_A_tair.txt', '256898_at', 20.962, '', 0, 'ATGE_12_A'), +(35, 1, 'ATGE_12_B_tair.txt', '256898_at', 19.701, '', 0, 'ATGE_12_B'), +(36, 1, 'ATGE_12_C_tair.txt', '256898_at', 22.844, '', 0, 'ATGE_12_C'), +(37, 1, 'ATGE_13_A_tair.txt', '256898_at', 18.903, '', 0, 'ATGE_13_A'), +(38, 1, 'ATGE_13_B_tair.txt', '256898_at', 23.346, '', 0, 'ATGE_13_B'), +(39, 1, 'ATGE_13_C_tair.txt', '256898_at', 21.194, '', 0, 'ATGE_13_C'), +(40, 1, 'ATGE_14_A_tair.txt', '256898_at', 21.779, '', 0, 'ATGE_14_A'), +(41, 1, 'ATGE_14_B_tair.txt', '256898_at', 22.218, '', 0, 'ATGE_14_B'), +(42, 1, 'ATGE_14_C_tair.txt', '256898_at', 26.448, '', 0, 'ATGE_14_C'), +(43, 1, 'ATGE_15_A_tair.txt', '256898_at', 23.895, '', 0, 'ATGE_15_A'), +(44, 1, 'ATGE_15_B_tair.txt', '256898_at', 22.335, '', 0, 'ATGE_15_B'), +(45, 1, 'ATGE_15_C_tair.txt', '256898_at', 21.226, '', 0, 'ATGE_15_C'), +(46, 1, 'ATGE_16_A_tair.txt', '256898_at', 18.797, '', 0, 'ATGE_16_A'), +(47, 1, 'ATGE_16_B_tair.txt', '256898_at', 30.588, '', 0, 'ATGE_16_B'), +(48, 1, 'ATGE_16_C_tair.txt', '256898_at', 25.214, '', 0, 'ATGE_16_C'), +(49, 1, 'ATGE_17_A_tair.txt', '256898_at', 25.802, '', 0, 'ATGE_17_A'), +(50, 1, 'ATGE_17_B_tair.txt', '256898_at', 24.36, '', 0, 'ATGE_17_B'), +(51, 1, 'ATGE_17_C_tair.txt', '256898_at', 23.761, '', 0, 'ATGE_17_C'), +(52, 1, 'ATGE_18_A_tair.txt', '256898_at', 24.472, '', 0, 'ATGE_18_A'), +(53, 1, 'ATGE_18_B_tair.txt', '256898_at', 23.548, '', 0, 'ATGE_18_B'), +(54, 1, 'ATGE_18_C_tair.txt', '256898_at', 22.128, '', 0, 'ATGE_18_C'), +(55, 1, 'ATGE_19_A_tair.txt', '256898_at', 20.887, '', 0, 'ATGE_19_A'), +(56, 1, 'ATGE_19_B_tair.txt', '256898_at', 23.167, '', 0, 'ATGE_19_B'), +(57, 1, 'ATGE_19_C_tair.txt', '256898_at', 21.333, '', 0, 'ATGE_19_C'), +(1, 1, 'ATGE_1_A_tair.txt', '256898_at', 23.319, '', 0, 'ATGE_1_A'), +(2, 1, 'ATGE_1_B_tair.txt', '256898_at', 22.94, '', 0, 'ATGE_1_B'), +(3, 1, 'ATGE_1_C_tair.txt', '256898_at', 25.102, '', 0, 'ATGE_1_C'), +(58, 1, 'ATGE_20_A_tair.txt', '256898_at', 22.932, '', 0, 'ATGE_20_A'), +(59, 1, 'ATGE_20_B_tair.txt', '256898_at', 28.127, '', 0, 'ATGE_20_B'), +(60, 1, 'ATGE_20_C_tair.txt', '256898_at', 23.724, '', 0, 'ATGE_20_C'), +(61, 1, 'ATGE_21_A_tair.txt', '256898_at', 22.664, '', 0, 'ATGE_21_A'), +(62, 1, 'ATGE_21_B_tair.txt', '256898_at', 22.334, '', 0, 'ATGE_21_B'), +(63, 1, 'ATGE_21_C_tair.txt', '256898_at', 23.122, '', 0, 'ATGE_21_C'), +(64, 1, 'ATGE_22_A_tair.txt', '256898_at', 22.372, '', 0, 'ATGE_22_A'), +(65, 1, 'ATGE_22_B_tair.txt', '256898_at', 21.826, '', 0, 'ATGE_22_B'), +(66, 1, 'ATGE_22_C_tair.txt', '256898_at', 24.882, '', 0, 'ATGE_22_C'), +(67, 1, 'ATGE_23_A_tair.txt', '256898_at', 29.6, '', 0, 'ATGE_23_A'), +(68, 1, 'ATGE_23_B_tair.txt', '256898_at', 22.314, '', 0, 'ATGE_23_B'), +(69, 1, 'ATGE_23_C_tair.txt', '256898_at', 25.263, '', 0, 'ATGE_23_C'), +(70, 1, 'ATGE_24_A_tair.txt', '256898_at', 21.488, '', 0, 'ATGE_24_A'), +(71, 1, 'ATGE_24_B_tair.txt', '256898_at', 20.215, '', 0, 'ATGE_24_B'), +(72, 1, 'ATGE_24_C_tair.txt', '256898_at', 22.435, '', 0, 'ATGE_24_C'), +(73, 1, 'ATGE_25_A_tair.txt', '256898_at', 25.443, '', 0, 'ATGE_25_A'), +(74, 1, 'ATGE_25_B_tair.txt', '256898_at', 28.398, '', 0, 'ATGE_25_B'), +(75, 1, 'ATGE_25_C_tair.txt', '256898_at', 23.415, '', 0, 'ATGE_25_C'), +(76, 1, 'ATGE_26_A_tair.txt', '256898_at', 22.972, '', 0, 'ATGE_26_A'), +(77, 1, 'ATGE_26_B_tair.txt', '256898_at', 22.677, '', 0, 'ATGE_26_B'), +(78, 1, 'ATGE_26_C_tair.txt', '256898_at', 22.057, '', 0, 'ATGE_26_C'), +(79, 1, 'ATGE_27_A_tair.txt', '256898_at', 19.861, '', 0, 'ATGE_27_A'), +(80, 1, 'ATGE_27_B_tair.txt', '256898_at', 24.645, '', 0, 'ATGE_27_B'), +(81, 1, 'ATGE_27_C_tair.txt', '256898_at', 22.862, '', 0, 'ATGE_27_C'), +(82, 1, 'ATGE_28_A2_tair.txt', '256898_at', 22.095, '', 0, 'ATGE_28_A2'), +(83, 1, 'ATGE_28_B2_tair.txt', '256898_at', 26.735, '', 0, 'ATGE_28_B2'), +(84, 1, 'ATGE_28_C2_tair.txt', '256898_at', 22.013, '', 0, 'ATGE_28_C2'), +(85, 1, 'ATGE_29_A2_tair.txt', '256898_at', 24.188, '', 0, 'ATGE_29_A2'), +(86, 1, 'ATGE_29_B2_tair.txt', '256898_at', 20.416, '', 0, 'ATGE_29_B2'), +(87, 1, 'ATGE_29_C2_tair.txt', '256898_at', 24.202, '', 0, 'ATGE_29_C2'), +(4, 1, 'ATGE_2_A_tair.txt', '256898_at', 18.816, '', 0, 'ATGE_2_A'), +(5, 1, 'ATGE_2_B_tair.txt', '256898_at', 21.443, '', 0, 'ATGE_2_B'), +(6, 1, 'ATGE_2_C_tair.txt', '256898_at', 20.668, '', 0, 'ATGE_2_C'), +(88, 1, 'ATGE_31_A2_tair.txt', '256898_at', 24.365, '', 0, 'ATGE_31_A2'), +(89, 1, 'ATGE_31_B2_tair.txt', '256898_at', 20.899, '', 0, 'ATGE_31_B2'), +(90, 1, 'ATGE_31_C2_tair.txt', '256898_at', 19.717, '', 0, 'ATGE_31_C2'), +(91, 1, 'ATGE_32_A2_tair.txt', '256898_at', 22.92, '', 0, 'ATGE_32_A2'), +(92, 1, 'ATGE_32_B2_tair.txt', '256898_at', 20.283, '', 0, 'ATGE_32_B2'), +(93, 1, 'ATGE_32_C2_tair.txt', '256898_at', 21.962, '', 0, 'ATGE_32_C2'), +(94, 1, 'ATGE_33_A_tair.txt', '256898_at', 20.33, '', 0, 'ATGE_33_A'), +(95, 1, 'ATGE_33_B_tair.txt', '256898_at', 21.974, '', 0, 'ATGE_33_B'), +(96, 1, 'ATGE_33_C_tair.txt', '256898_at', 20.324, '', 0, 'ATGE_33_C'), +(97, 1, 'ATGE_34_A_tair.txt', '256898_at', 22.393, '', 0, 'ATGE_34_A'), +(98, 1, 'ATGE_34_B_tair.txt', '256898_at', 22.852, '', 0, 'ATGE_34_B'), +(99, 1, 'ATGE_34_C_tair.txt', '256898_at', 23.414, '', 0, 'ATGE_34_C'), +(100, 1, 'ATGE_35_A_tair.txt', '256898_at', 25.667, '', 0, 'ATGE_35_A'), +(101, 1, 'ATGE_35_B_tair.txt', '256898_at', 20.577, '', 0, 'ATGE_35_B'), +(102, 1, 'ATGE_35_C_tair.txt', '256898_at', 25.14, '', 0, 'ATGE_35_C'), +(103, 1, 'ATGE_36_A_tair.txt', '256898_at', 22.97, '', 0, 'ATGE_36_A'), +(104, 1, 'ATGE_36_B_tair.txt', '256898_at', 30.902, '', 0, 'ATGE_36_B'), +(105, 1, 'ATGE_36_C_tair.txt', '256898_at', 25.016, '', 0, 'ATGE_36_C'), +(106, 1, 'ATGE_37_A_tair.txt', '256898_at', 20.35, '', 0, 'ATGE_37_A'), +(107, 1, 'ATGE_37_B_tair.txt', '256898_at', 20.136, '', 0, 'ATGE_37_B'), +(108, 1, 'ATGE_37_C_tair.txt', '256898_at', 23.998, '', 0, 'ATGE_37_C'), +(109, 1, 'ATGE_39_A_tair.txt', '256898_at', 21.129, '', 0, 'ATGE_39_A'), +(110, 1, 'ATGE_39_B_tair.txt', '256898_at', 23.463, '', 0, 'ATGE_39_B'), +(111, 1, 'ATGE_39_C_tair.txt', '256898_at', 21.131, '', 0, 'ATGE_39_C'), +(7, 1, 'ATGE_3_A_tair.txt', '256898_at', 21.922, '', 0, 'ATGE_3_A'), +(8, 1, 'ATGE_3_B_tair.txt', '256898_at', 19.104, '', 0, 'ATGE_3_B'), +(9, 1, 'ATGE_3_C_tair.txt', '256898_at', 20.964, '', 0, 'ATGE_3_C'), +(112, 1, 'ATGE_40_A_tair.txt', '256898_at', 29.662, '', 0, 'ATGE_40_A'), +(113, 1, 'ATGE_40_B_tair.txt', '256898_at', 29.502, '', 0, 'ATGE_40_B'), +(114, 1, 'ATGE_40_C_tair.txt', '256898_at', 29.745, '', 0, 'ATGE_40_C'), +(115, 1, 'ATGE_41_A_tair.txt', '256898_at', 22.881, '', 0, 'ATGE_41_A'), +(116, 1, 'ATGE_41_B_tair.txt', '256898_at', 29.724, '', 0, 'ATGE_41_B'), +(117, 1, 'ATGE_41_C_tair.txt', '256898_at', 26.873, '', 0, 'ATGE_41_C'), +(118, 1, 'ATGE_42_B_tair.txt', '256898_at', 23.591, '', 0, 'ATGE_42_B'), +(119, 1, 'ATGE_42_C_tair.txt', '256898_at', 23.868, '', 0, 'ATGE_42_C'), +(120, 1, 'ATGE_42_D_tair.txt', '256898_at', 22.38, '', 0, 'ATGE_42_D'), +(121, 1, 'ATGE_43_A_tair.txt', '256898_at', 23.711, '', 0, 'ATGE_43_A'), +(122, 1, 'ATGE_43_B_tair.txt', '256898_at', 20.334, '', 0, 'ATGE_43_B'), +(123, 1, 'ATGE_43_C_tair.txt', '256898_at', 21.746, '', 0, 'ATGE_43_C'), +(124, 1, 'ATGE_45_A_tair.txt', '256898_at', 18.133, '', 0, 'ATGE_45_A'), +(125, 1, 'ATGE_45_B_tair.txt', '256898_at', 19.878, '', 0, 'ATGE_45_B'), +(126, 1, 'ATGE_45_C_tair.txt', '256898_at', 22.719, '', 0, 'ATGE_45_C'), +(127, 1, 'ATGE_46_A_tair.txt', '256898_at', 21.979, '', 0, 'ATGE_46_A'), +(128, 1, 'ATGE_46_B_tair.txt', '256898_at', 23.279, '', 0, 'ATGE_46_B'), +(129, 1, 'ATGE_46_C_tair.txt', '256898_at', 23.141, '', 0, 'ATGE_46_C'), +(130, 1, 'ATGE_47_A_tair.txt', '256898_at', 24.331, '', 0, 'ATGE_47_A'), +(131, 1, 'ATGE_47_B_tair.txt', '256898_at', 20.608, '', 0, 'ATGE_47_B'), +(132, 1, 'ATGE_47_C_tair.txt', '256898_at', 22.643, '', 0, 'ATGE_47_C'), +(133, 1, 'ATGE_48_A_tair.txt', '256898_at', 19.364, '', 0, 'ATGE_48_A'), +(134, 1, 'ATGE_48_B_tair.txt', '256898_at', 23.632, '', 0, 'ATGE_48_B'), +(135, 1, 'ATGE_48_C_tair.txt', '256898_at', 18.571, '', 0, 'ATGE_48_C'), +(136, 1, 'ATGE_49_A_tair.txt', '256898_at', 23.638, '', 0, 'ATGE_49_A'), +(137, 1, 'ATGE_49_B_tair.txt', '256898_at', 23.858, '', 0, 'ATGE_49_B'), +(138, 1, 'ATGE_49_C_tair.txt', '256898_at', 22.361, '', 0, 'ATGE_49_C'), +(10, 1, 'ATGE_4_A_tair.txt', '256898_at', 24.907, '', 0, 'ATGE_4_A'), +(11, 1, 'ATGE_4_B_tair.txt', '256898_at', 25.224, '', 0, 'ATGE_4_B'), +(12, 1, 'ATGE_4_C_tair.txt', '256898_at', 23.197, '', 0, 'ATGE_4_C'), +(139, 1, 'ATGE_50_A_tair.txt', '256898_at', 26.768, '', 0, 'ATGE_50_A'), +(140, 1, 'ATGE_50_B_tair.txt', '256898_at', 19.952, '', 0, 'ATGE_50_B'), +(141, 1, 'ATGE_50_C_tair.txt', '256898_at', 24.011, '', 0, 'ATGE_50_C'), +(142, 1, 'ATGE_51_A_tair.txt', '256898_at', 17.423, '', 0, 'ATGE_51_A'), +(143, 1, 'ATGE_51_B_tair.txt', '256898_at', 27.146, '', 0, 'ATGE_51_B'), +(144, 1, 'ATGE_51_C_tair.txt', '256898_at', 25.449, '', 0, 'ATGE_51_C'), +(145, 1, 'ATGE_52_A_tair.txt', '256898_at', 23.546, '', 0, 'ATGE_52_A'), +(146, 1, 'ATGE_52_B_tair.txt', '256898_at', 22.012, '', 0, 'ATGE_52_B'), +(147, 1, 'ATGE_52_C_tair.txt', '256898_at', 22.332, '', 0, 'ATGE_52_C'), +(148, 1, 'ATGE_53_A_tair.txt', '256898_at', 22.453, '', 0, 'ATGE_53_A'), +(149, 1, 'ATGE_53_B_tair.txt', '256898_at', 19.38, '', 0, 'ATGE_53_B'), +(150, 1, 'ATGE_53_C_tair.txt', '256898_at', 21.178, '', 0, 'ATGE_53_C'), +(151, 1, 'ATGE_54_A_tair.txt', '256898_at', 24.324, '', 0, 'ATGE_54_A'), +(152, 1, 'ATGE_54_B_tair.txt', '256898_at', 22.573, '', 0, 'ATGE_54_B'), +(153, 1, 'ATGE_54_C_tair.txt', '256898_at', 21.554, '', 0, 'ATGE_54_C'), +(154, 1, 'ATGE_55_A_tair.txt', '256898_at', 21.288, '', 0, 'ATGE_55_A'), +(155, 1, 'ATGE_55_B_tair.txt', '256898_at', 18.503, '', 0, 'ATGE_55_B'), +(156, 1, 'ATGE_55_C_tair.txt', '256898_at', 18.323, '', 0, 'ATGE_55_C'), +(157, 1, 'ATGE_56_A_tair.txt', '256898_at', 20.643, '', 0, 'ATGE_56_A'), +(158, 1, 'ATGE_56_B_tair.txt', '256898_at', 24.555, '', 0, 'ATGE_56_B'), +(159, 1, 'ATGE_56_C_tair.txt', '256898_at', 21.652, '', 0, 'ATGE_56_C'), +(160, 1, 'ATGE_57_A_tair.txt', '256898_at', 22.534, '', 0, 'ATGE_57_A'), +(161, 1, 'ATGE_57_B_tair.txt', '256898_at', 17.97, '', 0, 'ATGE_57_B'), +(162, 1, 'ATGE_57_C_tair.txt', '256898_at', 22.695, '', 0, 'ATGE_57_C'), +(163, 1, 'ATGE_58_A_tair.txt', '256898_at', 22.82, '', 0, 'ATGE_58_A'), +(164, 1, 'ATGE_58_B_tair.txt', '256898_at', 23.999, '', 0, 'ATGE_58_B'), +(165, 1, 'ATGE_58_C_tair.txt', '256898_at', 19.931, '', 0, 'ATGE_58_C'), +(166, 1, 'ATGE_59_A_tair.txt', '256898_at', 19.416, '', 0, 'ATGE_59_A'), +(167, 1, 'ATGE_59_B_tair.txt', '256898_at', 20.326, '', 0, 'ATGE_59_B'), +(168, 1, 'ATGE_59_C_tair.txt', '256898_at', 20.07, '', 0, 'ATGE_59_C'), +(13, 1, 'ATGE_5_A_tair.txt', '256898_at', 27.844, '', 0, 'ATGE_5_A'), +(14, 1, 'ATGE_5_B_tair.txt', '256898_at', 28.881, '', 0, 'ATGE_5_B'), +(15, 1, 'ATGE_5_C_tair.txt', '256898_at', 27.262, '', 0, 'ATGE_5_C'), +(16, 1, 'ATGE_6_A_tair.txt', '256898_at', 21.637, '', 0, 'ATGE_6_A'), +(17, 1, 'ATGE_6_B_tair.txt', '256898_at', 20.474, '', 0, 'ATGE_6_B'), +(18, 1, 'ATGE_6_C_tair.txt', '256898_at', 23.081, '', 0, 'ATGE_6_C'), +(169, 2, 'ATGE_73_A_tair.txt', '256898_at', 60.884, '', 0, 'ATGE_73_A'), +(170, 2, 'ATGE_73_B_tair.txt', '256898_at', 45.349, '', 0, 'ATGE_73_B'), +(171, 2, 'ATGE_73_C_tair.txt', '256898_at', 43.775, '', 0, 'ATGE_73_C'), +(172, 3, 'ATGE_76_A_tair.txt', '256898_at', 20.105, '', 0, 'ATGE_76_A'), +(173, 3, 'ATGE_76_B_tair.txt', '256898_at', 19.26, '', 0, 'ATGE_76_B'), +(174, 3, 'ATGE_76_C_tair.txt', '256898_at', 20.268, '', 0, 'ATGE_76_C'), +(175, 3, 'ATGE_77_D_tair.txt', '256898_at', 177.911, '', 0, 'ATGE_77_D'), +(176, 3, 'ATGE_77_E_tair.txt', '256898_at', 140.96, '', 0, 'ATGE_77_E'), +(177, 3, 'ATGE_77_F_tair.txt', '256898_at', 153.226, '', 0, 'ATGE_77_F'), +(178, 3, 'ATGE_78_D_tair.txt', '256898_at', 276.429, '', 0, 'ATGE_78_D'), +(179, 3, 'ATGE_78_E_tair.txt', '256898_at', 270.085, '', 0, 'ATGE_78_E'), +(180, 3, 'ATGE_78_F_tair.txt', '256898_at', 270.92, '', 0, 'ATGE_78_F'), +(181, 3, 'ATGE_79_A_tair.txt', '256898_at', 758.365, '', 0, 'ATGE_79_A'), +(182, 3, 'ATGE_79_B_tair.txt', '256898_at', 764.355, '', 0, 'ATGE_79_B'), +(183, 3, 'ATGE_79_C_tair.txt', '256898_at', 607.025, '', 0, 'ATGE_79_C'), +(19, 1, 'ATGE_7_A2_tair.txt', '256898_at', 31.061, '', 0, 'ATGE_7_A2'), +(20, 1, 'ATGE_7_B2_tair.txt', '256898_at', 29.927, '', 0, 'ATGE_7_B2'), +(21, 1, 'ATGE_7_C2_tair.txt', '256898_at', 32.198, '', 0, 'ATGE_7_C2'), +(184, 3, 'ATGE_81_A_tair.txt', '256898_at', 1032.1, '', 0, 'ATGE_81_A'), +(185, 3, 'ATGE_81_B_tair.txt', '256898_at', 974.35, '', 0, 'ATGE_81_B'), +(186, 3, 'ATGE_81_C_tair.txt', '256898_at', 722.403, '', 0, 'ATGE_81_C'), +(187, 3, 'ATGE_82_A_tair.txt', '256898_at', 1330.89, '', 0, 'ATGE_82_A'), +(188, 3, 'ATGE_82_B_tair.txt', '256898_at', 1143.84, '', 0, 'ATGE_82_B'), +(189, 3, 'ATGE_82_C_tair.txt', '256898_at', 1048.5, '', 0, 'ATGE_82_C'), +(190, 3, 'ATGE_83_A_tair.txt', '256898_at', 1373.16, '', 0, 'ATGE_83_A'), +(191, 3, 'ATGE_83_B_tair.txt', '256898_at', 1626.12, '', 0, 'ATGE_83_B'), +(192, 3, 'ATGE_83_C_tair.txt', '256898_at', 1205.51, '', 0, 'ATGE_83_C'), +(193, 3, 'ATGE_84_A_tair.txt', '256898_at', 1301.7, '', 0, 'ATGE_84_A'), +(194, 3, 'ATGE_84_B_tair.txt', '256898_at', 1268.13, '', 0, 'ATGE_84_B'), +(195, 3, 'ATGE_84_D_tair.txt', '256898_at', 1287.59, '', 0, 'ATGE_84_D'), +(196, 4, 'ATGE_87_A_tair.txt', '256898_at', 34.342, '', 0, 'ATGE_87_A'), +(197, 4, 'ATGE_87_B_tair.txt', '256898_at', 25.063, '', 0, 'ATGE_87_B'), +(198, 4, 'ATGE_87_C_tair.txt', '256898_at', 23.629, '', 0, 'ATGE_87_C'), +(199, 4, 'ATGE_89_A_tair.txt', '256898_at', 28.905, '', 0, 'ATGE_89_A'), +(200, 4, 'ATGE_89_B_tair.txt', '256898_at', 25.799, '', 0, 'ATGE_89_B'), +(201, 4, 'ATGE_89_C_tair.txt', '256898_at', 26.227, '', 0, 'ATGE_89_C'), +(22, 1, 'ATGE_8_A_tair.txt', '256898_at', 21.31, '', 0, 'ATGE_8_A'), +(23, 1, 'ATGE_8_B_tair.txt', '256898_at', 22.983, '', 0, 'ATGE_8_B'), +(24, 1, 'ATGE_8_C_tair.txt', '256898_at', 26.338, '', 0, 'ATGE_8_C'), +(202, 4, 'ATGE_90_A_tair.txt', '256898_at', 28.886, '', 0, 'ATGE_90_A'), +(203, 4, 'ATGE_90_B_tair.txt', '256898_at', 22.513, '', 0, 'ATGE_90_B'), +(204, 4, 'ATGE_90_D_tair.txt', '256898_at', 25.339, '', 0, 'ATGE_90_D'), +(205, 5, 'ATGE_91_A_tair.txt', '256898_at', 26.161, '', 0, 'ATGE_91_A'), +(206, 5, 'ATGE_91_B_tair.txt', '256898_at', 33.765, '', 0, 'ATGE_91_B'), +(207, 5, 'ATGE_91_C_tair.txt', '256898_at', 24.699, '', 0, 'ATGE_91_C'), +(208, 5, 'ATGE_92_A_tair.txt', '256898_at', 20.769, '', 0, 'ATGE_92_A'), +(209, 5, 'ATGE_92_B_tair.txt', '256898_at', 19.492, '', 0, 'ATGE_92_B'), +(210, 5, 'ATGE_92_C_tair.txt', '256898_at', 23.321, '', 0, 'ATGE_92_C'), +(211, 5, 'ATGE_93_A_tair.txt', '256898_at', 21.204, '', 0, 'ATGE_93_A'), +(212, 5, 'ATGE_93_B_tair.txt', '256898_at', 20.888, '', 0, 'ATGE_93_B'), +(213, 5, 'ATGE_93_C_tair.txt', '256898_at', 19.697, '', 0, 'ATGE_93_C'), +(214, 6, 'ATGE_94_A_tair.txt', '256898_at', 22.684, '', 0, 'ATGE_94_A'), +(215, 6, 'ATGE_94_B_tair.txt', '256898_at', 18.791, '', 0, 'ATGE_94_B'), +(216, 6, 'ATGE_94_C_tair.txt', '256898_at', 25.549, '', 0, 'ATGE_94_C'), +(217, 6, 'ATGE_95_A_tair.txt', '256898_at', 20.153, '', 0, 'ATGE_95_A'), +(218, 6, 'ATGE_95_B_tair.txt', '256898_at', 22.32, '', 0, 'ATGE_95_B'), +(219, 6, 'ATGE_95_C_tair.txt', '256898_at', 19.382, '', 0, 'ATGE_95_C'), +(220, 6, 'ATGE_96_A_tair.txt', '256898_at', 24.577, '', 0, 'ATGE_96_A'), +(221, 6, 'ATGE_96_B_tair.txt', '256898_at', 24.163, '', 0, 'ATGE_96_B'), +(222, 6, 'ATGE_96_C_tair.txt', '256898_at', 21.656, '', 0, 'ATGE_96_C'), +(223, 6, 'ATGE_97_A_tair.txt', '256898_at', 23.443, '', 0, 'ATGE_97_A'), +(224, 6, 'ATGE_97_B_tair.txt', '256898_at', 32.982, '', 0, 'ATGE_97_B'), +(225, 6, 'ATGE_97_C_tair.txt', '256898_at', 23.113, '', 0, 'ATGE_97_C'), +(226, 6, 'ATGE_98_A_tair.txt', '256898_at', 18.112, '', 0, 'ATGE_98_A'), +(227, 6, 'ATGE_98_B_tair.txt', '256898_at', 18.865, '', 0, 'ATGE_98_B'), +(228, 6, 'ATGE_98_C_tair.txt', '256898_at', 22.35, '', 0, 'ATGE_98_C'), +(229, 6, 'ATGE_99_A_tair.txt', '256898_at', 22.472, '', 0, 'ATGE_99_A'), +(230, 6, 'ATGE_99_B_tair.txt', '256898_at', 18.929, '', 0, 'ATGE_99_B'), +(231, 6, 'ATGE_99_C_tair.txt', '256898_at', 21.025, '', 0, 'ATGE_99_C'), +(25, 1, 'ATGE_9_A_tair.txt', '256898_at', 19.16, '', 0, 'ATGE_9_A'), +(26, 1, 'ATGE_9_B_tair.txt', '256898_at', 20.076, '', 0, 'ATGE_9_B'), +(27, 1, 'ATGE_9_C_tair.txt', '256898_at', 18.249, '', 0, 'ATGE_9_C'), +(238, 1, 'ATGE_CTRL_1.txt', '256898_at', 22.695, '', 0, 'ATGE_CTRL_1'), +(239, 2, 'ATGE_CTRL_2.txt', '256898_at', 45.349, '', 0, 'ATGE_CTRL_2'), +(240, 3, 'ATGE_CTRL_3.txt', '256898_at', 764.355, '', 0, 'ATGE_CTRL_3'), +(241, 4, 'ATGE_CTRL_4.txt', '256898_at', 25.799, '', 0, 'ATGE_CTRL_4'), +(242, 5, 'ATGE_CTRL_5.txt', '256898_at', 21.204, '', 0, 'ATGE_CTRL_5'), +(243, 6, 'ATGE_CTRL_6.txt', '256898_at', 22.35, '', 0, 'ATGE_CTRL_6'), +(244, 7, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(245, 1, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(246, 2, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(247, 3, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(248, 4, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(249, 5, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(250, 6, 'ATGE_CTRL_7.txt', '256898_at', 23.38, '', 0, 'ATGE_CTRL_7'), +(232, 6, 'ATGE_100_A_tair.txt', '261585_at', 40.381, '', 0, 'ATGE_100_A'), +(233, 6, 'ATGE_100_B_tair.txt', '261585_at', 38.924, '', 0, 'ATGE_100_B'), +(234, 6, 'ATGE_100_C_tair.txt', '261585_at', 45.384, '', 0, 'ATGE_100_C'), +(235, 6, 'ATGE_101_A_tair.txt', '261585_at', 45.453, '', 0, 'ATGE_101_A'), +(236, 6, 'ATGE_101_B_tair.txt', '261585_at', 46.756, '', 0, 'ATGE_101_B'), +(237, 6, 'ATGE_101_C_tair.txt', '261585_at', 56.027, '', 0, 'ATGE_101_C'), +(28, 1, 'ATGE_10_A_tair.txt', '261585_at', 34.245, '', 0, 'ATGE_10_A'), +(29, 1, 'ATGE_10_B_tair.txt', '261585_at', 31.474, '', 0, 'ATGE_10_B'), +(30, 1, 'ATGE_10_C_tair.txt', '261585_at', 34.903, '', 0, 'ATGE_10_C'), +(31, 1, 'ATGE_11_A_tair.txt', '261585_at', 42.623, '', 0, 'ATGE_11_A'), +(32, 1, 'ATGE_11_B_tair.txt', '261585_at', 35.904, '', 0, 'ATGE_11_B'), +(33, 1, 'ATGE_11_C_tair.txt', '261585_at', 43.596, '', 0, 'ATGE_11_C'), +(34, 1, 'ATGE_12_A_tair.txt', '261585_at', 52.228, '', 0, 'ATGE_12_A'), +(35, 1, 'ATGE_12_B_tair.txt', '261585_at', 52.518, '', 0, 'ATGE_12_B'), +(36, 1, 'ATGE_12_C_tair.txt', '261585_at', 57.394, '', 0, 'ATGE_12_C'), +(37, 1, 'ATGE_13_A_tair.txt', '261585_at', 51.739, '', 0, 'ATGE_13_A'), +(38, 1, 'ATGE_13_B_tair.txt', '261585_at', 54.454, '', 0, 'ATGE_13_B'), +(39, 1, 'ATGE_13_C_tair.txt', '261585_at', 52.688, '', 0, 'ATGE_13_C'), +(40, 1, 'ATGE_14_A_tair.txt', '261585_at', 47.443, '', 0, 'ATGE_14_A'), +(41, 1, 'ATGE_14_B_tair.txt', '261585_at', 50.258, '', 0, 'ATGE_14_B'), +(42, 1, 'ATGE_14_C_tair.txt', '261585_at', 52.03, '', 0, 'ATGE_14_C'), +(43, 1, 'ATGE_15_A_tair.txt', '261585_at', 51.741, '', 0, 'ATGE_15_A'), +(44, 1, 'ATGE_15_B_tair.txt', '261585_at', 42.861, '', 0, 'ATGE_15_B'), +(45, 1, 'ATGE_15_C_tair.txt', '261585_at', 42.363, '', 0, 'ATGE_15_C'), +(46, 1, 'ATGE_16_A_tair.txt', '261585_at', 39.8, '', 0, 'ATGE_16_A'), +(47, 1, 'ATGE_16_B_tair.txt', '261585_at', 39.519, '', 0, 'ATGE_16_B'), +(48, 1, 'ATGE_16_C_tair.txt', '261585_at', 32.046, '', 0, 'ATGE_16_C'), +(49, 1, 'ATGE_17_A_tair.txt', '261585_at', 33.467, '', 0, 'ATGE_17_A'), +(50, 1, 'ATGE_17_B_tair.txt', '261585_at', 40.691, '', 0, 'ATGE_17_B'), +(51, 1, 'ATGE_17_C_tair.txt', '261585_at', 32.821, '', 0, 'ATGE_17_C'), +(52, 1, 'ATGE_18_A_tair.txt', '261585_at', 39.243, '', 0, 'ATGE_18_A'), +(53, 1, 'ATGE_18_B_tair.txt', '261585_at', 38.52, '', 0, 'ATGE_18_B'), +(54, 1, 'ATGE_18_C_tair.txt', '261585_at', 36.813, '', 0, 'ATGE_18_C'), +(55, 1, 'ATGE_19_A_tair.txt', '261585_at', 46.638, '', 0, 'ATGE_19_A'), +(56, 1, 'ATGE_19_B_tair.txt', '261585_at', 37.881, '', 0, 'ATGE_19_B'), +(57, 1, 'ATGE_19_C_tair.txt', '261585_at', 44.174, '', 0, 'ATGE_19_C'), +(1, 1, 'ATGE_1_A_tair.txt', '261585_at', 52.337, '', 0, 'ATGE_1_A'), +(2, 1, 'ATGE_1_B_tair.txt', '261585_at', 55.727, '', 0, 'ATGE_1_B'), +(3, 1, 'ATGE_1_C_tair.txt', '261585_at', 58.336, '', 0, 'ATGE_1_C'), +(58, 1, 'ATGE_20_A_tair.txt', '261585_at', 48.156, '', 0, 'ATGE_20_A'), +(59, 1, 'ATGE_20_B_tair.txt', '261585_at', 44.951, '', 0, 'ATGE_20_B'), +(60, 1, 'ATGE_20_C_tair.txt', '261585_at', 46.198, '', 0, 'ATGE_20_C'), +(61, 1, 'ATGE_21_A_tair.txt', '261585_at', 52.249, '', 0, 'ATGE_21_A'), +(62, 1, 'ATGE_21_B_tair.txt', '261585_at', 53.534, '', 0, 'ATGE_21_B'), +(63, 1, 'ATGE_21_C_tair.txt', '261585_at', 46.752, '', 0, 'ATGE_21_C'), +(64, 1, 'ATGE_22_A_tair.txt', '261585_at', 37.821, '', 0, 'ATGE_22_A'), +(65, 1, 'ATGE_22_B_tair.txt', '261585_at', 44.587, '', 0, 'ATGE_22_B'), +(66, 1, 'ATGE_22_C_tair.txt', '261585_at', 39.54, '', 0, 'ATGE_22_C'), +(67, 1, 'ATGE_23_A_tair.txt', '261585_at', 44.942, '', 0, 'ATGE_23_A'), +(68, 1, 'ATGE_23_B_tair.txt', '261585_at', 57.975, '', 0, 'ATGE_23_B'), +(69, 1, 'ATGE_23_C_tair.txt', '261585_at', 46.029, '', 0, 'ATGE_23_C'), +(70, 1, 'ATGE_24_A_tair.txt', '261585_at', 59.727, '', 0, 'ATGE_24_A'), +(71, 1, 'ATGE_24_B_tair.txt', '261585_at', 42.46, '', 0, 'ATGE_24_B'), +(72, 1, 'ATGE_24_C_tair.txt', '261585_at', 51.902, '', 0, 'ATGE_24_C'), +(73, 1, 'ATGE_25_A_tair.txt', '261585_at', 91.477, '', 0, 'ATGE_25_A'), +(74, 1, 'ATGE_25_B_tair.txt', '261585_at', 88.99, '', 0, 'ATGE_25_B'), +(75, 1, 'ATGE_25_C_tair.txt', '261585_at', 77.726, '', 0, 'ATGE_25_C'), +(76, 1, 'ATGE_26_A_tair.txt', '261585_at', 96.714, '', 0, 'ATGE_26_A'), +(77, 1, 'ATGE_26_B_tair.txt', '261585_at', 112.594, '', 0, 'ATGE_26_B'), +(78, 1, 'ATGE_26_C_tair.txt', '261585_at', 107.16, '', 0, 'ATGE_26_C'), +(79, 1, 'ATGE_27_A_tair.txt', '261585_at', 50.453, '', 0, 'ATGE_27_A'), +(80, 1, 'ATGE_27_B_tair.txt', '261585_at', 54.974, '', 0, 'ATGE_27_B'), +(81, 1, 'ATGE_27_C_tair.txt', '261585_at', 53.615, '', 0, 'ATGE_27_C'), +(82, 1, 'ATGE_28_A2_tair.txt', '261585_at', 49.89, '', 0, 'ATGE_28_A2'), +(83, 1, 'ATGE_28_B2_tair.txt', '261585_at', 53.019, '', 0, 'ATGE_28_B2'), +(84, 1, 'ATGE_28_C2_tair.txt', '261585_at', 49.506, '', 0, 'ATGE_28_C2'), +(85, 1, 'ATGE_29_A2_tair.txt', '261585_at', 42.396, '', 0, 'ATGE_29_A2'), +(86, 1, 'ATGE_29_B2_tair.txt', '261585_at', 37.946, '', 0, 'ATGE_29_B2'), +(87, 1, 'ATGE_29_C2_tair.txt', '261585_at', 31.747, '', 0, 'ATGE_29_C2'), +(4, 1, 'ATGE_2_A_tair.txt', '261585_at', 53.824, '', 0, 'ATGE_2_A'), +(5, 1, 'ATGE_2_B_tair.txt', '261585_at', 49.372, '', 0, 'ATGE_2_B'), +(6, 1, 'ATGE_2_C_tair.txt', '261585_at', 58.824, '', 0, 'ATGE_2_C'), +(88, 1, 'ATGE_31_A2_tair.txt', '261585_at', 34.644, '', 0, 'ATGE_31_A2'), +(89, 1, 'ATGE_31_B2_tair.txt', '261585_at', 31.774, '', 0, 'ATGE_31_B2'), +(90, 1, 'ATGE_31_C2_tair.txt', '261585_at', 36.303, '', 0, 'ATGE_31_C2'), +(91, 1, 'ATGE_32_A2_tair.txt', '261585_at', 42.135, '', 0, 'ATGE_32_A2'), +(92, 1, 'ATGE_32_B2_tair.txt', '261585_at', 38.829, '', 0, 'ATGE_32_B2'), +(93, 1, 'ATGE_32_C2_tair.txt', '261585_at', 39.157, '', 0, 'ATGE_32_C2'), +(94, 1, 'ATGE_33_A_tair.txt', '261585_at', 58.708, '', 0, 'ATGE_33_A'), +(95, 1, 'ATGE_33_B_tair.txt', '261585_at', 58.464, '', 0, 'ATGE_33_B'), +(96, 1, 'ATGE_33_C_tair.txt', '261585_at', 71.332, '', 0, 'ATGE_33_C'), +(97, 1, 'ATGE_34_A_tair.txt', '261585_at', 118.77, '', 0, 'ATGE_34_A'), +(98, 1, 'ATGE_34_B_tair.txt', '261585_at', 109.626, '', 0, 'ATGE_34_B'), +(99, 1, 'ATGE_34_C_tair.txt', '261585_at', 111.278, '', 0, 'ATGE_34_C'), +(100, 1, 'ATGE_35_A_tair.txt', '261585_at', 31.006, '', 0, 'ATGE_35_A'), +(101, 1, 'ATGE_35_B_tair.txt', '261585_at', 33.485, '', 0, 'ATGE_35_B'), +(102, 1, 'ATGE_35_C_tair.txt', '261585_at', 33.748, '', 0, 'ATGE_35_C'), +(103, 1, 'ATGE_36_A_tair.txt', '261585_at', 45.657, '', 0, 'ATGE_36_A'), +(104, 1, 'ATGE_36_B_tair.txt', '261585_at', 47.517, '', 0, 'ATGE_36_B'), +(105, 1, 'ATGE_36_C_tair.txt', '261585_at', 38.679, '', 0, 'ATGE_36_C'), +(106, 1, 'ATGE_37_A_tair.txt', '261585_at', 124.287, '', 0, 'ATGE_37_A'), +(107, 1, 'ATGE_37_B_tair.txt', '261585_at', 130.565, '', 0, 'ATGE_37_B'), +(108, 1, 'ATGE_37_C_tair.txt', '261585_at', 131.209, '', 0, 'ATGE_37_C'), +(109, 1, 'ATGE_39_A_tair.txt', '261585_at', 76.302, '', 0, 'ATGE_39_A'), +(110, 1, 'ATGE_39_B_tair.txt', '261585_at', 74.594, '', 0, 'ATGE_39_B'), +(111, 1, 'ATGE_39_C_tair.txt', '261585_at', 73.302, '', 0, 'ATGE_39_C'), +(7, 1, 'ATGE_3_A_tair.txt', '261585_at', 114.219, '', 0, 'ATGE_3_A'), +(8, 1, 'ATGE_3_B_tair.txt', '261585_at', 83.193, '', 0, 'ATGE_3_B'), +(9, 1, 'ATGE_3_C_tair.txt', '261585_at', 82.511, '', 0, 'ATGE_3_C'), +(112, 1, 'ATGE_40_A_tair.txt', '261585_at', 51.747, '', 0, 'ATGE_40_A'), +(113, 1, 'ATGE_40_B_tair.txt', '261585_at', 61.548, '', 0, 'ATGE_40_B'), +(114, 1, 'ATGE_40_C_tair.txt', '261585_at', 59.865, '', 0, 'ATGE_40_C'), +(115, 1, 'ATGE_41_A_tair.txt', '261585_at', 133.719, '', 0, 'ATGE_41_A'), +(116, 1, 'ATGE_41_B_tair.txt', '261585_at', 115.805, '', 0, 'ATGE_41_B'), +(117, 1, 'ATGE_41_C_tair.txt', '261585_at', 137.062, '', 0, 'ATGE_41_C'), +(118, 1, 'ATGE_42_B_tair.txt', '261585_at', 33.334, '', 0, 'ATGE_42_B'), +(119, 1, 'ATGE_42_C_tair.txt', '261585_at', 47.967, '', 0, 'ATGE_42_C'), +(120, 1, 'ATGE_42_D_tair.txt', '261585_at', 38.576, '', 0, 'ATGE_42_D'), +(121, 1, 'ATGE_43_A_tair.txt', '261585_at', 47.903, '', 0, 'ATGE_43_A'), +(122, 1, 'ATGE_43_B_tair.txt', '261585_at', 51.672, '', 0, 'ATGE_43_B'), +(123, 1, 'ATGE_43_C_tair.txt', '261585_at', 45.295, '', 0, 'ATGE_43_C'), +(124, 1, 'ATGE_45_A_tair.txt', '261585_at', 75.959, '', 0, 'ATGE_45_A'), +(125, 1, 'ATGE_45_B_tair.txt', '261585_at', 76.152, '', 0, 'ATGE_45_B'), +(126, 1, 'ATGE_45_C_tair.txt', '261585_at', 83.896, '', 0, 'ATGE_45_C'), +(127, 1, 'ATGE_46_A_tair.txt', '261585_at', 41.599, '', 0, 'ATGE_46_A'), +(128, 1, 'ATGE_46_B_tair.txt', '261585_at', 45.929, '', 0, 'ATGE_46_B'), +(129, 1, 'ATGE_46_C_tair.txt', '261585_at', 40.279, '', 0, 'ATGE_46_C'), +(130, 1, 'ATGE_47_A_tair.txt', '261585_at', 42.036, '', 0, 'ATGE_47_A'), +(131, 1, 'ATGE_47_B_tair.txt', '261585_at', 36.566, '', 0, 'ATGE_47_B'), +(132, 1, 'ATGE_47_C_tair.txt', '261585_at', 35.6, '', 0, 'ATGE_47_C'), +(133, 1, 'ATGE_48_A_tair.txt', '261585_at', 48.577, '', 0, 'ATGE_48_A'), +(134, 1, 'ATGE_48_B_tair.txt', '261585_at', 44.809, '', 0, 'ATGE_48_B'), +(135, 1, 'ATGE_48_C_tair.txt', '261585_at', 49.144, '', 0, 'ATGE_48_C'), +(136, 1, 'ATGE_49_A_tair.txt', '261585_at', 40.271, '', 0, 'ATGE_49_A'), +(137, 1, 'ATGE_49_B_tair.txt', '261585_at', 46.926, '', 0, 'ATGE_49_B'), +(138, 1, 'ATGE_49_C_tair.txt', '261585_at', 50.22, '', 0, 'ATGE_49_C'), +(10, 1, 'ATGE_4_A_tair.txt', '261585_at', 33.114, '', 0, 'ATGE_4_A'), +(11, 1, 'ATGE_4_B_tair.txt', '261585_at', 30.879, '', 0, 'ATGE_4_B'), +(12, 1, 'ATGE_4_C_tair.txt', '261585_at', 29.785, '', 0, 'ATGE_4_C'), +(139, 1, 'ATGE_50_A_tair.txt', '261585_at', 38.778, '', 0, 'ATGE_50_A'), +(140, 1, 'ATGE_50_B_tair.txt', '261585_at', 44.319, '', 0, 'ATGE_50_B'), +(141, 1, 'ATGE_50_C_tair.txt', '261585_at', 40.772, '', 0, 'ATGE_50_C'), +(142, 1, 'ATGE_51_A_tair.txt', '261585_at', 33.923, '', 0, 'ATGE_51_A'), +(143, 1, 'ATGE_51_B_tair.txt', '261585_at', 33.082, '', 0, 'ATGE_51_B'), +(144, 1, 'ATGE_51_C_tair.txt', '261585_at', 34.86, '', 0, 'ATGE_51_C'), +(145, 1, 'ATGE_52_A_tair.txt', '261585_at', 34.338, '', 0, 'ATGE_52_A'), +(146, 1, 'ATGE_52_B_tair.txt', '261585_at', 34.979, '', 0, 'ATGE_52_B'), +(147, 1, 'ATGE_52_C_tair.txt', '261585_at', 38.975, '', 0, 'ATGE_52_C'), +(148, 1, 'ATGE_53_A_tair.txt', '261585_at', 67.364, '', 0, 'ATGE_53_A'), +(149, 1, 'ATGE_53_B_tair.txt', '261585_at', 62.851, '', 0, 'ATGE_53_B'), +(150, 1, 'ATGE_53_C_tair.txt', '261585_at', 73.057, '', 0, 'ATGE_53_C'), +(151, 1, 'ATGE_54_A_tair.txt', '261585_at', 41.44, '', 0, 'ATGE_54_A'), +(152, 1, 'ATGE_54_B_tair.txt', '261585_at', 41.534, '', 0, 'ATGE_54_B'), +(153, 1, 'ATGE_54_C_tair.txt', '261585_at', 44.434, '', 0, 'ATGE_54_C'), +(154, 1, 'ATGE_55_A_tair.txt', '261585_at', 50.473, '', 0, 'ATGE_55_A'), +(155, 1, 'ATGE_55_B_tair.txt', '261585_at', 61.742, '', 0, 'ATGE_55_B'), +(156, 1, 'ATGE_55_C_tair.txt', '261585_at', 58.424, '', 0, 'ATGE_55_C'), +(157, 1, 'ATGE_56_A_tair.txt', '261585_at', 62.186, '', 0, 'ATGE_56_A'), +(158, 1, 'ATGE_56_B_tair.txt', '261585_at', 65.999, '', 0, 'ATGE_56_B'), +(159, 1, 'ATGE_56_C_tair.txt', '261585_at', 57.886, '', 0, 'ATGE_56_C'), +(160, 1, 'ATGE_57_A_tair.txt', '261585_at', 85.726, '', 0, 'ATGE_57_A'), +(161, 1, 'ATGE_57_B_tair.txt', '261585_at', 109.283, '', 0, 'ATGE_57_B'), +(162, 1, 'ATGE_57_C_tair.txt', '261585_at', 90.843, '', 0, 'ATGE_57_C'), +(163, 1, 'ATGE_58_A_tair.txt', '261585_at', 47.377, '', 0, 'ATGE_58_A'), +(164, 1, 'ATGE_58_B_tair.txt', '261585_at', 43.296, '', 0, 'ATGE_58_B'), +(165, 1, 'ATGE_58_C_tair.txt', '261585_at', 45.597, '', 0, 'ATGE_58_C'), +(166, 1, 'ATGE_59_A_tair.txt', '261585_at', 75.557, '', 0, 'ATGE_59_A'), +(167, 1, 'ATGE_59_B_tair.txt', '261585_at', 75.161, '', 0, 'ATGE_59_B'), +(168, 1, 'ATGE_59_C_tair.txt', '261585_at', 74.937, '', 0, 'ATGE_59_C'), +(13, 1, 'ATGE_5_A_tair.txt', '261585_at', 34.251, '', 0, 'ATGE_5_A'), +(14, 1, 'ATGE_5_B_tair.txt', '261585_at', 29.408, '', 0, 'ATGE_5_B'), +(15, 1, 'ATGE_5_C_tair.txt', '261585_at', 32.975, '', 0, 'ATGE_5_C'), +(16, 1, 'ATGE_6_A_tair.txt', '261585_at', 39.185, '', 0, 'ATGE_6_A'), +(17, 1, 'ATGE_6_B_tair.txt', '261585_at', 35.076, '', 0, 'ATGE_6_B'), +(18, 1, 'ATGE_6_C_tair.txt', '261585_at', 39.947, '', 0, 'ATGE_6_C'), +(169, 2, 'ATGE_73_A_tair.txt', '261585_at', 95.871, '', 0, 'ATGE_73_A'), +(170, 2, 'ATGE_73_B_tair.txt', '261585_at', 90.027, '', 0, 'ATGE_73_B'), +(171, 2, 'ATGE_73_C_tair.txt', '261585_at', 125.789, '', 0, 'ATGE_73_C'), +(172, 3, 'ATGE_76_A_tair.txt', '261585_at', 34.741, '', 0, 'ATGE_76_A'), +(173, 3, 'ATGE_76_B_tair.txt', '261585_at', 37.868, '', 0, 'ATGE_76_B'), +(174, 3, 'ATGE_76_C_tair.txt', '261585_at', 32.302, '', 0, 'ATGE_76_C'), +(175, 3, 'ATGE_77_D_tair.txt', '261585_at', 33.22, '', 0, 'ATGE_77_D'), +(176, 3, 'ATGE_77_E_tair.txt', '261585_at', 34.52, '', 0, 'ATGE_77_E'), +(177, 3, 'ATGE_77_F_tair.txt', '261585_at', 33.328, '', 0, 'ATGE_77_F'), +(178, 3, 'ATGE_78_D_tair.txt', '261585_at', 33.212, '', 0, 'ATGE_78_D'), +(179, 3, 'ATGE_78_E_tair.txt', '261585_at', 31.655, '', 0, 'ATGE_78_E'), +(180, 3, 'ATGE_78_F_tair.txt', '261585_at', 34.786, '', 0, 'ATGE_78_F'), +(181, 3, 'ATGE_79_A_tair.txt', '261585_at', 32.77, '', 0, 'ATGE_79_A'), +(182, 3, 'ATGE_79_B_tair.txt', '261585_at', 31.542, '', 0, 'ATGE_79_B'), +(183, 3, 'ATGE_79_C_tair.txt', '261585_at', 43.563, '', 0, 'ATGE_79_C'), +(19, 1, 'ATGE_7_A2_tair.txt', '261585_at', 41.967, '', 0, 'ATGE_7_A2'), +(20, 1, 'ATGE_7_B2_tair.txt', '261585_at', 52.424, '', 0, 'ATGE_7_B2'), +(21, 1, 'ATGE_7_C2_tair.txt', '261585_at', 44.666, '', 0, 'ATGE_7_C2'), +(184, 3, 'ATGE_81_A_tair.txt', '261585_at', 43.13, '', 0, 'ATGE_81_A'), +(185, 3, 'ATGE_81_B_tair.txt', '261585_at', 46.264, '', 0, 'ATGE_81_B'), +(186, 3, 'ATGE_81_C_tair.txt', '261585_at', 43.697, '', 0, 'ATGE_81_C'), +(187, 3, 'ATGE_82_A_tair.txt', '261585_at', 47.577, '', 0, 'ATGE_82_A'), +(188, 3, 'ATGE_82_B_tair.txt', '261585_at', 55.79, '', 0, 'ATGE_82_B'), +(189, 3, 'ATGE_82_C_tair.txt', '261585_at', 47.317, '', 0, 'ATGE_82_C'), +(190, 3, 'ATGE_83_A_tair.txt', '261585_at', 49.633, '', 0, 'ATGE_83_A'), +(191, 3, 'ATGE_83_B_tair.txt', '261585_at', 46.094, '', 0, 'ATGE_83_B'), +(192, 3, 'ATGE_83_C_tair.txt', '261585_at', 48.86, '', 0, 'ATGE_83_C'), +(193, 3, 'ATGE_84_A_tair.txt', '261585_at', 51.825, '', 0, 'ATGE_84_A'), +(194, 3, 'ATGE_84_B_tair.txt', '261585_at', 56.163, '', 0, 'ATGE_84_B'), +(195, 3, 'ATGE_84_D_tair.txt', '261585_at', 46.036, '', 0, 'ATGE_84_D'), +(196, 4, 'ATGE_87_A_tair.txt', '261585_at', 52.816, '', 0, 'ATGE_87_A'), +(197, 4, 'ATGE_87_B_tair.txt', '261585_at', 41.774, '', 0, 'ATGE_87_B'), +(198, 4, 'ATGE_87_C_tair.txt', '261585_at', 40.265, '', 0, 'ATGE_87_C'), +(199, 4, 'ATGE_89_A_tair.txt', '261585_at', 42.602, '', 0, 'ATGE_89_A'), +(200, 4, 'ATGE_89_B_tair.txt', '261585_at', 32.285, '', 0, 'ATGE_89_B'), +(201, 4, 'ATGE_89_C_tair.txt', '261585_at', 34.589, '', 0, 'ATGE_89_C'), +(22, 1, 'ATGE_8_A_tair.txt', '261585_at', 32.684, '', 0, 'ATGE_8_A'), +(23, 1, 'ATGE_8_B_tair.txt', '261585_at', 33.819, '', 0, 'ATGE_8_B'), +(24, 1, 'ATGE_8_C_tair.txt', '261585_at', 37.334, '', 0, 'ATGE_8_C'), +(202, 4, 'ATGE_90_A_tair.txt', '261585_at', 49.635, '', 0, 'ATGE_90_A'), +(203, 4, 'ATGE_90_B_tair.txt', '261585_at', 39.551, '', 0, 'ATGE_90_B'), +(204, 4, 'ATGE_90_D_tair.txt', '261585_at', 39.808, '', 0, 'ATGE_90_D'), +(205, 5, 'ATGE_91_A_tair.txt', '261585_at', 41.055, '', 0, 'ATGE_91_A'), +(206, 5, 'ATGE_91_B_tair.txt', '261585_at', 44.102, '', 0, 'ATGE_91_B'), +(207, 5, 'ATGE_91_C_tair.txt', '261585_at', 41.074, '', 0, 'ATGE_91_C'), +(208, 5, 'ATGE_92_A_tair.txt', '261585_at', 45.219, '', 0, 'ATGE_92_A'), +(209, 5, 'ATGE_92_B_tair.txt', '261585_at', 42.546, '', 0, 'ATGE_92_B'), +(210, 5, 'ATGE_92_C_tair.txt', '261585_at', 46.824, '', 0, 'ATGE_92_C'), +(211, 5, 'ATGE_93_A_tair.txt', '261585_at', 162.29, '', 0, 'ATGE_93_A'), +(212, 5, 'ATGE_93_B_tair.txt', '261585_at', 170.376, '', 0, 'ATGE_93_B'), +(213, 5, 'ATGE_93_C_tair.txt', '261585_at', 161.751, '', 0, 'ATGE_93_C'), +(214, 6, 'ATGE_94_A_tair.txt', '261585_at', 170.818, '', 0, 'ATGE_94_A'), +(215, 6, 'ATGE_94_B_tair.txt', '261585_at', 144.128, '', 0, 'ATGE_94_B'), +(216, 6, 'ATGE_94_C_tair.txt', '261585_at', 163.289, '', 0, 'ATGE_94_C'), +(217, 6, 'ATGE_95_A_tair.txt', '261585_at', 156.823, '', 0, 'ATGE_95_A'), +(218, 6, 'ATGE_95_B_tair.txt', '261585_at', 158.167, '', 0, 'ATGE_95_B'), +(219, 6, 'ATGE_95_C_tair.txt', '261585_at', 161.188, '', 0, 'ATGE_95_C'), +(220, 6, 'ATGE_96_A_tair.txt', '261585_at', 49.577, '', 0, 'ATGE_96_A'), +(221, 6, 'ATGE_96_B_tair.txt', '261585_at', 51.902, '', 0, 'ATGE_96_B'), +(222, 6, 'ATGE_96_C_tair.txt', '261585_at', 53.945, '', 0, 'ATGE_96_C'), +(223, 6, 'ATGE_97_A_tair.txt', '261585_at', 50.785, '', 0, 'ATGE_97_A'), +(224, 6, 'ATGE_97_B_tair.txt', '261585_at', 53.895, '', 0, 'ATGE_97_B'), +(225, 6, 'ATGE_97_C_tair.txt', '261585_at', 50.003, '', 0, 'ATGE_97_C'), +(226, 6, 'ATGE_98_A_tair.txt', '261585_at', 188.598, '', 0, 'ATGE_98_A'), +(227, 6, 'ATGE_98_B_tair.txt', '261585_at', 211.942, '', 0, 'ATGE_98_B'), +(228, 6, 'ATGE_98_C_tair.txt', '261585_at', 165.624, '', 0, 'ATGE_98_C'), +(229, 6, 'ATGE_99_A_tair.txt', '261585_at', 184.169, '', 0, 'ATGE_99_A'), +(230, 6, 'ATGE_99_B_tair.txt', '261585_at', 171.851, '', 0, 'ATGE_99_B'), +(231, 6, 'ATGE_99_C_tair.txt', '261585_at', 164.836, '', 0, 'ATGE_99_C'), +(25, 1, 'ATGE_9_A_tair.txt', '261585_at', 127.365, '', 0, 'ATGE_9_A'), +(26, 1, 'ATGE_9_B_tair.txt', '261585_at', 134.69, '', 0, 'ATGE_9_B'), +(27, 1, 'ATGE_9_C_tair.txt', '261585_at', 151.607, '', 0, 'ATGE_9_C'), +(238, 1, 'ATGE_CTRL_1.txt', '261585_at', 47.443, '', 0, 'ATGE_CTRL_1'), +(239, 2, 'ATGE_CTRL_2.txt', '261585_at', 95.871, '', 0, 'ATGE_CTRL_2'), +(240, 3, 'ATGE_CTRL_3.txt', '261585_at', 43.563, '', 0, 'ATGE_CTRL_3'), +(241, 4, 'ATGE_CTRL_4.txt', '261585_at', 40.265, '', 0, 'ATGE_CTRL_4'), +(242, 5, 'ATGE_CTRL_5.txt', '261585_at', 45.219, '', 0, 'ATGE_CTRL_5'), +(243, 6, 'ATGE_CTRL_6.txt', '261585_at', 144.128, '', 0, 'ATGE_CTRL_6'), +(244, 7, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(245, 1, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(246, 2, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(247, 3, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(248, 4, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(249, 5, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'), +(250, 6, 'ATGE_CTRL_7.txt', '261585_at', 48.508, '', 0, 'ATGE_CTRL_7'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `sample_data` +-- +ALTER TABLE `sample_data` + ADD KEY `data_probeset_id` (`data_probeset_id`,`data_bot_id`,`data_signal`); +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/config/species_databases.json b/config/species_databases.json new file mode 100644 index 0000000..a7e3aa3 --- /dev/null +++ b/config/species_databases.json @@ -0,0 +1,177 @@ +{ + "actinidia": { + "Bud_Development": "actinidia_bud_development", + "Flower_Fruit_Development": "actinidia_flower_fruit_development", + "Postharvest": "actinidia_postharvest", + "Vegetative_Growth": "actinidia_vegetative_growth" + }, + "arabidopsis": { + "Abiotic_Stress": "atgenexp_stress", + "Abiotic_Stress_II": "atgenexp_stress", + "Biotic_Stress": "atgenexp_pathogen", + "Biotic_Stress_II": "atgenexp_pathogen", + "Chemical": "atgenexp_hormone", + "DNA_Damage": "dna_damage", + "Development_RMA": "atgenexp", + "Developmental_Map": "atgenexp_plus", + "Developmental_Mutants": "atgenexp_plus", + "Embryo": "embryo", + "Germination": "germination", + "Guard_Cell": "guard_cell", + "Gynoecium": "gynoecium", + "Hormone": "atgenexp_hormone", + "Klepikova_Atlas": "klepikova", + "Lateral_Root_Initiation": "lateral_root_initiation", + "Light_Series": "light_series", + "Natural_Variation": "arabidopsis_ecotypes", + "Regeneration": "meristem_db", + "Root": "root", + "Root_II": "root", + "Seed": "seed_db", + "Shoot_Apex": "shoot_apex", + "Silique": "silique", + "Single_Cell": "single_cell", + "Tissue_Specific": "atgenexp_plus" + }, + "arabidopsis seedcoat": { + "Seed_Coat": "seedcoat" + }, + "arachis": { + "Arachis_Atlas": "arachis" + }, + "barley": { + "barley_mas": "barley_mas", + "barley_rma": "barley_rma" + }, + "brachypodium": { + "Brachypodium_Atlas": "brachypodium", + "Brachypodium_Grains": "brachypodium_grains", + "Brachypodium_Spikes": "brachypodium_Bd21", + "Photo_Thermocycle": "brachypodium_photo_thermocycle" + }, + "brassica rapa": { + "Embryogenesis": "brassica_rapa" + }, + "cacao ccn": { + "Developmental_Atlas": "cacao_developmental_atlas", + "Drought_Diurnal_Atlas": "cacao_drought_diurnal_atlas" + }, + "cacao sca": { + "Developmental_Atlas": "cacao_developmental_atlas_sca", + "Drought_Diurnal_Atlas": "cacao_drought_diurnal_atlas_sca", + "Meristem_Atlas": "cacao_meristem_atlas_sca", + "Seed_Atlas": "cacao_seed_atlas_sca" + }, + "cacao tc": { + "Cacao_Infection": "cacao_infection", + "Cacao_Leaf": "cacao_leaf" + }, + "camelina": { + "Developmental_Atlas_FPKM": "camelina", + "Developmental_Atlas_TPM": "camelina_tpm" + }, + "cannabis": { + "Cannabis_Atlas": "cannabis" + }, + "canola": { + "Canola_Seed": "canola_seed" + }, + "eutrema": { + "Eutrema": "thellungiella_db" + }, + "grape": { + "grape_developmental": "grape_developmental" + }, + "kalanchoe": { + "Light_Response": "kalanchoe" + }, + "little millet": { + "Life_Cycle": "little_millet" + }, + "lupin": { + "LCM_Leaf": "lupin_lcm_leaf", + "LCM_Pod": "lupin_lcm_pod", + "LCM_Stem": "lupin_lcm_stem", + "Whole_Plant": "lupin_whole_plant" + }, + "maize": { + "Downs_et_al_Atlas": "maize_gdowns", + "Early_Seed": "maize_early_seed", + "Embryonic_Leaf_Development": "maize_embryonic_leaf_development", + "Hoopes_et_al_Atlas": "maize_buell_lab", + "Hoopes_et_al_Stress": "maize_buell_lab", + "Maize_Kernel": "maize_early_seed", + "Maize_Root": "maize_root", + "Sekhon_et_al_Atlas": "maize_RMA_linear", + "Tassel_and_Ear_Primordia": "maize_ears", + "maize_iplant": "maize_iplant", + "maize_leaf_gradient": "maize_leaf_gradient", + "maize_rice_comparison": "maize_rice_comparison" + }, + "mangosteen": { + "Aril_vs_Rind": "mangosteen_aril_vs_rind", + "Callus": "mangosteen_callus", + "Diseased_vs_Normal": "mangosteen_diseased_vs_normal", + "Fruit_Ripening": "mangosteen_fruit_ripening", + "Seed_Development": "mangosteen_seed_development", + "Seed_Germination": "mangosteen_seed_germination" + }, + "medicago": { + "medicago_mas": "medicago_mas", + "medicago_rma": "medicago_rma", + "medicago_seed": "medicago_seed" + }, + "poplar": { + "Poplar": "poplar", + "PoplarTreatment": "poplar" + }, + "potato": { + "Potato_Developmental": "potato_dev", + "Potato_Stress": "potato_stress" + }, + "rice": { + "rice_drought_heat_stress": "rice_drought_heat_stress", + "rice_leaf_gradient": "rice_leaf_gradient", + "rice_maize_comparison": "rice_maize_comparison", + "rice_mas": "rice_mas", + "rice_rma": "rice_rma", + "riceanoxia_mas": "rice_mas", + "riceanoxia_rma": "rice_rma", + "ricestigma_mas": "rice_mas", + "ricestigma_rma": "rice_rma", + "ricestress_mas": "rice_mas", + "ricestress_rma": "rice_rma" + }, + "soybean": { + "soybean": "soybean", + "soybean_embryonic_development": "soybean_embryonic_development", + "soybean_heart_cotyledon_globular": "soybean_heart_cotyledon_globular", + "soybean_senescence": "soybean_senescence", + "soybean_severin": "soybean_severin" + }, + "strawberry": { + "Developmental_Map_Strawberry_Flower_and_Fruit": "strawberry", + "Strawberry_Green_vs_White_Stage": "strawberry" + }, + "tomato": { + "ILs_Leaf_Chitwood_et_al": "tomato_ils", + "ILs_Root_Tip_Brady_Lab": "tomato_ils2", + "M82_S_pennellii_Atlases_Koenig_et_al": "tomato_s_pennellii", + "Rose_Lab_Atlas": "tomato", + "Rose_Lab_Atlas_Renormalized": "tomato_renormalized", + "SEED_Lab_Angers": "tomato_seed", + "Shade_Mutants": "tomato_shade_mutants", + "Shade_Timecourse_WT": "tomato_shade_timecourse", + "Tomato_Meristem": "tomato_meristem" + }, + "triticale": { + "triticale": "triticale", + "triticale_mas": "triticale_mas" + }, + "wheat": { + "Developmental_Atlas": "wheat", + "Wheat_Abiotic_Stress": "wheat_abiotic_stress", + "Wheat_Embryogenesis": "wheat_embryogenesis", + "Wheat_Meiosis": "wheat_meiosis" + } +} diff --git a/data/efp_info/efp_species_view_info.json b/data/efp_info/efp_species_view_info.json new file mode 100644 index 0000000..8ea3252 --- /dev/null +++ b/data/efp_info/efp_species_view_info.json @@ -0,0 +1,18424 @@ +{ + "actinidia": { + + "data": { + "species": "actinidia", + "views": { + "Bud_Development": { + "database": "actinidia_bud_development", + "view_name": "Bud_Development", + "groups": { + "Nov": { + "controls": [ + "Nov" + ], + "treatments": { + "bud": [ + "Nov", + "Nov_TB", + "Dec", + "Jan", + "Jan_TB", + "Feb", + "Mar", + "Mar_TB", + "Apr", + "May", + "Jun", + "Jul", + "Aug" + ] + } + } + } + }, + "Flower_Fruit_Development": { + "database": "actinidia_flower_fruit_development", + "view_name": "Flower_Fruit_Development", + "groups": { + "flower": { + "controls": [ + "flower" + ], + "treatments": { + "Floral_Bud": [ + "Flower_bud" + ], + "centre": [ + "Flower" + ], + "anther": [ + "Flower" + ], + "petal": [ + "Flower" + ], + "core": [ + "Fruit_T1", + "Fruit_T2", + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA" + ], + "cortex": [ + "Fruit_T1", + "Fruit_T2", + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA" + ], + "flesh": [ + "Fruit_T1", + "Fruit_T2", + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA" + ] + } + } + } + }, + "Postharvest": { + "database": "actinidia_postharvest", + "view_name": "Postharvest", + "groups": { + "Postharvest_Control": { + "controls": [ + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA" + ], + "treatments": { + "core": [ + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA", + "Fruit_231_DAA", + "Fruit_231_DAA_1DAH", + "Fruit_231_DAA_2DAH", + "Fruit_231_DAA_4DAH" + ], + "cortex": [ + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA", + "Fruit_231_DAA", + "Fruit_231_DAA_1DAH", + "Fruit_231_DAA_2DAH", + "Fruit_231_DAA_4DAH" + ], + "flesh": [ + "Fruit_147_DAA", + "Fruit_166_DAA", + "Fruit_182_DAA", + "Fruit_224_DAA", + "Fruit_231_DAA", + "Fruit_231_DAA_1DAH", + "Fruit_231_DAA_2DAH", + "Fruit_231_DAA_4DAH" + ] + } + } + } + }, + "Vegetative_Growth": { + "database": "actinidia_vegetative_growth", + "view_name": "Vegetative_Growth", + "groups": { + "cane": { + "controls": [ + "cane" + ], + "treatments": { + "sink_leaf": [ + "Leaf_sink" + ], + "source_leaf": [ + "Leaf_source" + ], + "shoot": [ + "Shoot" + ], + "cane": [ + "cane" + ], + "root": [ + "Root" + ] + } + } + } + } + } + } + }, + "arabidopsis": { + + "data": { + "species": "arabidopsis", + "views": { + "Abiotic_Stress": { + "database": "atgenexp_stress", + "view_name": "Abiotic_Stress", + "groups": { + "Shoot_0_Hour": { + "controls": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "treatments": { + "Control_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Cold_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Osmotic_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Salt_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Drought_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Genotoxic_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Oxidative_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "UV-B_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Wounding_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ], + "Heat_Shoot_0_Hour": [ + "AtGen_6_0011", + "AtGen_6_0012" + ] + } + }, + "Root_0_Hour": { + "controls": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "treatments": { + "Control_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Cold_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Osmotic_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Salt_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Drought_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Genotoxic_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Oxidative_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "UV-B_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Wounding_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ], + "Heat_Root_0_Hour": [ + "AtGen_6_0021", + "AtGen_6_0022" + ] + } + }, + "Shoot_After_15_Minutes": { + "controls": [ + "AtGen_6_0711", + "AtGen_6_0712" + ], + "treatments": { + "Control_Shoot_After_15_Minutes": [ + "AtGen_6_0711", + "AtGen_6_0712" + ], + "Drought_Shoot_After_15_Minutes": [ + "AtGen_6_4711", + "AtGen_6_4712" + ], + "UV-B_Shoot_After_15_Minutes": [ + "AtGen_6_7711", + "AtGen_6_7712" + ], + "Wounding_Shoot_After_15_Minutes": [ + "AtGen_6_8715", + "AtGen_6_8712" + ], + "Heat_Shoot_After_15_Minutes": [ + "AtGen_6_9711", + "AtGen_6_9712" + ] + } + }, + "Root_After_15_Minutes": { + "controls": [ + "AtGen_6_0721", + "AtGen_6_0722" + ], + "treatments": { + "Control_Root_After_15_Minutes": [ + "AtGen_6_0721", + "AtGen_6_0722" + ], + "Drought_Root_After_15_Minutes": [ + "AtGen_6_4721", + "AtGen_6_4722" + ], + "UV-B_Root_After_15_Minutes": [ + "AtGen_6_7721", + "AtGen_6_7722" + ], + "Wounding_Root_After_15_Minutes": [ + "AtGen_6_8723", + "AtGen_6_8724" + ], + "Heat_Root_After_15_Minutes": [ + "AtGen_6_9721", + "AtGen_6_9722" + ] + } + }, + "Shoot_After_30_Minutes": { + "controls": [ + "AtGen_6_0111", + "AtGen_6_0112" + ], + "treatments": { + "Control_Shoot_After_30_Minutes": [ + "AtGen_6_0111", + "AtGen_6_0112" + ], + "Cold_Shoot_After_30_Minutes": [ + "AtGen_6_1111", + "AtGen_6_1112" + ], + "Osmotic_Shoot_After_30_Minutes": [ + "AtGen_6_2111", + "AtGen_6_2112" + ], + "Salt_Shoot_After_30_Minutes": [ + "AtGen_6_3111", + "AtGen_6_3112" + ], + "Drought_Shoot_After_30_Minutes": [ + "AtGen_6_4111", + "AtGen_6_4112" + ], + "Genotoxic_Shoot_After_30_Minutes": [ + "AtGen_6_5111", + "AtGen_6_5112" + ], + "Oxidative_Shoot_After_30_Minutes": [ + "AtGen_6_6111", + "AtGen_6_6112" + ], + "UV-B_Shoot_After_30_Minutes": [ + "AtGen_6_7111", + "AtGen_6_7112" + ], + "Wounding_Shoot_After_30_Minutes": [ + "AtGen_6_8111", + "AtGen_6_8112" + ], + "Heat_Shoot_After_30_Minutes": [ + "AtGen_6_9111", + "AtGen_6_9112" + ] + } + }, + "Root_After_30_Minutes": { + "controls": [ + "AtGen_6_0121", + "AtGen_6_0122" + ], + "treatments": { + "Control_Root_After_30_Minutes": [ + "AtGen_6_0121", + "AtGen_6_0122" + ], + "Cold_Root_After_30_Minutes": [ + "AtGen_6_1121", + "AtGen_6_1122" + ], + "Osmotic_Root_After_30_Minutes": [ + "AtGen_6_2121", + "AtGen_6_2122" + ], + "Salt_Root_After_30_Minutes": [ + "AtGen_6_3121", + "AtGen_6_3122" + ], + "Drought_Root_After_30_Minutes": [ + "AtGen_6_4121", + "AtGen_6_4122" + ], + "Genotoxic_Root_After_30_Minutes": [ + "AtGen_6_5121", + "AtGen_6_5122" + ], + "Oxidative_Root_After_30_Minutes": [ + "AtGen_6_6122", + "AtGen_6_6124" + ], + "UV-B_Root_After_30_Minutes": [ + "AtGen_6_7121", + "AtGen_6_7122" + ], + "Wounding_Root_After_30_Minutes": [ + "AtGen_6_8124", + "AtGen_6_8126" + ], + "Heat_Root_After_30_Minutes": [ + "AtGen_6_9121", + "AtGen_6_9122" + ] + } + }, + "Shoot_After_1_Hour": { + "controls": [ + "AtGen_6_0211", + "AtGen_6_0212" + ], + "treatments": { + "Control_Shoot_After_1_Hour": [ + "AtGen_6_0211", + "AtGen_6_0212" + ], + "Cold_Shoot_After_1_Hour": [ + "AtGen_6_1211", + "AtGen_6_1212" + ], + "Osmotic_Shoot_After_1_Hour": [ + "AtGen_6_2211", + "AtGen_6_2212" + ], + "Salt_Shoot_After_1_Hour": [ + "AtGen_6_3211", + "AtGen_6_3212" + ], + "Drought_Shoot_After_1_Hour": [ + "AtGen_6_4211", + "AtGen_6_4212" + ], + "Genotoxic_Shoot_After_1_Hour": [ + "AtGen_6_5211", + "AtGen_6_5212" + ], + "Oxidative_Shoot_After_1_Hour": [ + "AtGen_6_6211", + "AtGen_6_6212" + ], + "UV-B_Shoot_After_1_Hour": [ + "AtGen_6_7211", + "AtGen_6_7212" + ], + "Wounding_Shoot_After_1_Hour": [ + "AtGen_6_8211", + "AtGen_6_8214" + ], + "Heat_Shoot_After_1_Hour": [ + "AtGen_6_9211", + "AtGen_6_9212" + ] + } + }, + "Root_After_1_Hour": { + "controls": [ + "AtGen_6_0221", + "AtGen_6_0222" + ], + "treatments": { + "Control_Root_After_1_Hour": [ + "AtGen_6_0221", + "AtGen_6_0222" + ], + "Cold_Root_After_1_Hour": [ + "AtGen_6_1221", + "AtGen_6_1222" + ], + "Osmotic_Root_After_1_Hour": [ + "AtGen_6_2221", + "AtGen_6_2222" + ], + "Salt_Root_After_1_Hour": [ + "AtGen_6_3221", + "AtGen_6_3222" + ], + "Drought_Root_After_1_Hour": [ + "AtGen_6_4221", + "AtGen_6_4222" + ], + "Genotoxic_Root_After_1_Hour": [ + "AtGen_6_5221", + "AtGen_6_5222" + ], + "Oxidative_Root_After_1_Hour": [ + "AtGen_6_6223", + "AtGen_6_6224" + ], + "UV-B_Root_After_1_Hour": [ + "AtGen_6_7221", + "AtGen_6_7222" + ], + "Wounding_Root_After_1_Hour": [ + "AtGen_6_8224", + "AtGen_6_8225" + ], + "Heat_Root_After_1_Hour": [ + "AtGen_6_9221", + "AtGen_6_9222" + ] + } + }, + "Shoot_After_3_Hours": { + "controls": [ + "AtGen_6_0311", + "AtGen_6_0312" + ], + "treatments": { + "Control_Shoot_After_3_Hours": [ + "AtGen_6_0311", + "AtGen_6_0312" + ], + "Cold_Shoot_After_3_Hours": [ + "AtGen_6_1311", + "AtGen_6_1312" + ], + "Osmotic_Shoot_After_3_Hours": [ + "AtGen_6_2311", + "AtGen_6_2312" + ], + "Salt_Shoot_After_3_Hours": [ + "AtGen_6_3311", + "AtGen_6_3312" + ], + "Drought_Shoot_After_3_Hours": [ + "AtGen_6_4311", + "AtGen_6_4312" + ], + "Genotoxic_Shoot_After_3_Hours": [ + "AtGen_6_5311", + "AtGen_6_5312" + ], + "Oxidative_Shoot_After_3_Hours": [ + "AtGen_6_6311", + "AtGen_6_6312" + ], + "UV-B_Shoot_After_3_Hours": [ + "AtGen_6_7311", + "AtGen_6_7312" + ], + "Wounding_Shoot_After_3_Hours": [ + "AtGen_6_8313", + "AtGen_6_8314" + ], + "Heat_Shoot_After_3_Hours": [ + "AtGen_6_9311", + "AtGen_6_9312" + ] + } + }, + "Root_After_3_Hours": { + "controls": [ + "AtGen_6_0321", + "AtGen_6_0322" + ], + "treatments": { + "Control_Root_After_3_Hours": [ + "AtGen_6_0321", + "AtGen_6_0322" + ], + "Cold_Root_After_3_Hours": [ + "AtGen_6_1321", + "AtGen_6_1322" + ], + "Osmotic_Root_After_3_Hours": [ + "AtGen_6_2321", + "AtGen_6_2322" + ], + "Salt_Root_After_3_Hours": [ + "AtGen_6_3321", + "AtGen_6_3322" + ], + "Drought_Root_After_3_Hours": [ + "AtGen_6_4321", + "AtGen_6_4322" + ], + "Genotoxic_Root_After_3_Hours": [ + "AtGen_6_5321", + "AtGen_6_5322" + ], + "Oxidative_Root_After_3_Hours": [ + "AtGen_6_6322", + "AtGen_6_6323" + ], + "UV-B_Root_After_3_Hours": [ + "AtGen_6_7321", + "AtGen_6_7322" + ], + "Wounding_Root_After_3_Hours": [ + "AtGen_6_8324", + "AtGen_6_8325" + ], + "Heat_Root_After_3_Hours": [ + "AtGen_6_9321", + "AtGen_6_9322" + ] + } + }, + "Shoot_After_4_Hours": { + "controls": [ + "AtGen_6_0811", + "AtGen_6_0812" + ], + "treatments": { + "Control_Shoot_After_4_Hours": [ + "AtGen_6_0811", + "AtGen_6_0812" + ], + "Heat_Shoot_After_4_Hours": [ + "AtGen_6_9811", + "AtGen_6_9812" + ] + } + }, + "Root_After_4_Hours": { + "controls": [ + "AtGen_6_0821", + "AtGen_6_0822" + ], + "treatments": { + "Control_Root_After_4_Hours": [ + "AtGen_6_0821", + "AtGen_6_0822" + ], + "Heat_Root_After_4_Hours": [ + "AtGen_6_9821", + "AtGen_6_9822" + ] + } + }, + "Shoot_After_6_Hours": { + "controls": [ + "AtGen_6_0411", + "AtGen_6_0412" + ], + "treatments": { + "Control_Shoot_After_6_Hours": [ + "AtGen_6_0411", + "AtGen_6_0412" + ], + "Cold_Shoot_After_6_Hours": [ + "AtGen_6_1411", + "AtGen_6_1412" + ], + "Osmotic_Shoot_After_6_Hours": [ + "AtGen_6_2411", + "AtGen_6_2412" + ], + "Salt_Shoot_After_6_Hours": [ + "AtGen_6_3411", + "AtGen_6_3412" + ], + "Drought_Shoot_After_6_Hours": [ + "AtGen_6_4411", + "AtGen_6_4412" + ], + "Genotoxic_Shoot_After_6_Hours": [ + "AtGen_6_5411", + "AtGen_6_5412" + ], + "Oxidative_Shoot_After_6_Hours": [ + "AtGen_6_6411", + "AtGen_6_6412" + ], + "UV-B_Shoot_After_6_Hours": [ + "AtGen_6_7411", + "AtGen_6_7412" + ], + "Wounding_Shoot_After_6_Hours": [ + "AtGen_6_8411", + "AtGen_6_8412" + ], + "Heat_Shoot_After_6_Hours": [ + "AtGen_6_9411", + "AtGen_6_9412" + ] + } + }, + "Root_After_6_Hours": { + "controls": [ + "AtGen_6_0421", + "AtGen_6_0422" + ], + "treatments": { + "Control_Root_After_6_Hours": [ + "AtGen_6_0421", + "AtGen_6_0422" + ], + "Cold_Root_After_6_Hours": [ + "AtGen_6_1421", + "AtGen_6_1422" + ], + "Osmotic_Root_After_6_Hours": [ + "AtGen_6_2421", + "AtGen_6_2422" + ], + "Salt_Root_After_6_Hours": [ + "AtGen_6_3421", + "AtGen_6_3422" + ], + "Drought_Root_After_6_Hours": [ + "AtGen_6_4421", + "AtGen_6_4422" + ], + "Genotoxic_Root_After_6_Hours": [ + "AtGen_6_5421", + "AtGen_6_5422" + ], + "Oxidative_Root_After_6_Hours": [ + "AtGen_6_6421", + "AtGen_6_6422" + ], + "UV-B_Root_After_6_Hours": [ + "AtGen_6_7421", + "AtGen_6_7422" + ], + "Wounding_Root_After_6_Hours": [ + "AtGen_6_8423", + "AtGen_6_8424" + ], + "Heat_Root_After_6_Hours": [ + "AtGen_6_9421", + "AtGen_6_9422" + ] + } + }, + "Shoot_After_12_Hours": { + "controls": [ + "AtGen_6_0511", + "AtGen_6_0512" + ], + "treatments": { + "Control_Shoot_After_12_Hours": [ + "AtGen_6_0511", + "AtGen_6_0512" + ], + "Cold_Shoot_After_12_Hours": [ + "AtGen_6_1511", + "AtGen_6_1512" + ], + "Osmotic_Shoot_After_12_Hours": [ + "AtGen_6_2511", + "AtGen_6_2512" + ], + "Salt_Shoot_After_12_Hours": [ + "AtGen_6_3511", + "AtGen_6_3512" + ], + "Drought_Shoot_After_12_Hours": [ + "AtGen_6_4511", + "AtGen_6_4512" + ], + "Genotoxic_Shoot_After_12_Hours": [ + "AtGen_6_5511", + "AtGen_6_5512" + ], + "Oxidative_Shoot_After_12_Hours": [ + "AtGen_6_6511", + "AtGen_6_6512" + ], + "UV-B_Shoot_After_12_Hours": [ + "AtGen_6_7511", + "AtGen_6_7512" + ], + "Wounding_Shoot_After_12_Hours": [ + "AtGen_6_8511", + "AtGen_6_8512" + ], + "Heat_Shoot_After_12_Hours": [ + "AtGen_6_9511", + "AtGen_6_9512" + ] + } + }, + "Root_After_12_Hours": { + "controls": [ + "AtGen_6_0521", + "AtGen_6_0522" + ], + "treatments": { + "Control_Root_After_12_Hours": [ + "AtGen_6_0521", + "AtGen_6_0522" + ], + "Cold_Root_After_12_Hours": [ + "AtGen_6_1521", + "AtGen_6_1522" + ], + "Osmotic_Root_After_12_Hours": [ + "AtGen_6_2521", + "AtGen_6_2522" + ], + "Salt_Root_After_12_Hours": [ + "AtGen_6_3521", + "AtGen_6_3522" + ], + "Drought_Root_After_12_Hours": [ + "AtGen_6_4521", + "AtGen_6_4522" + ], + "Genotoxic_Root_After_12_Hours": [ + "AtGen_6_5521", + "AtGen_6_5522" + ], + "Oxidative_Root_After_12_Hours": [ + "AtGen_6_6523", + "AtGen_6_6524" + ], + "UV-B_Root_After_12_Hours": [ + "AtGen_6_7521", + "AtGen_6_7522" + ], + "Wounding_Root_After_12_Hours": [ + "AtGen_6_8524", + "AtGen_6_8525" + ], + "Heat_Root_After_12_Hours": [ + "AtGen_6_9521", + "AtGen_6_9522" + ] + } + }, + "Shoot_After_24_Hours": { + "controls": [ + "AtGen_6_0611", + "AtGen_6_0612" + ], + "treatments": { + "Control_Shoot_After_24_Hours": [ + "AtGen_6_0611", + "AtGen_6_0612" + ], + "Cold_Shoot_After_24_Hours": [ + "AtGen_6_1611", + "AtGen_6_1612" + ], + "Osmotic_Shoot_After_24_Hours": [ + "AtGen_6_2611", + "AtGen_6_2612" + ], + "Salt_Shoot_After_24_Hours": [ + "AtGen_6_3611", + "AtGen_6_3612" + ], + "Drought_Shoot_After_24_Hours": [ + "AtGen_6_4611", + "AtGen_6_4612" + ], + "Genotoxic_Shoot_After_24_Hours": [ + "AtGen_6_5611", + "AtGen_6_5612" + ], + "Oxidative_Shoot_After_24_Hours": [ + "AtGen_6_6611", + "AtGen_6_6612" + ], + "UV-B_Shoot_After_24_Hours": [ + "AtGen_6_7611", + "AtGen_6_7612" + ], + "Wounding_Shoot_After_24_Hours": [ + "AtGen_6_8611", + "AtGen_6_8612" + ], + "Heat_Shoot_After_24_Hours": [ + "AtGen_6_9611", + "AtGen_6_9612" + ] + } + }, + "Root_After_24_Hours": { + "controls": [ + "AtGen_6_0621", + "AtGen_6_0622" + ], + "treatments": { + "Control_Root_After_24_Hours": [ + "AtGen_6_0621", + "AtGen_6_0622" + ], + "Cold_Root_After_24_Hours": [ + "AtGen_6_1621", + "AtGen_6_1622" + ], + "Osmotic_Root_After_24_Hours": [ + "AtGen_6_2621", + "AtGen_6_2622" + ], + "Salt_Root_After_24_Hours": [ + "AtGen_6_3621", + "AtGen_6_3622" + ], + "Drought_Root_After_24_Hours": [ + "AtGen_6_4621", + "AtGen_6_4622" + ], + "Genotoxic_Root_After_24_Hours": [ + "AtGen_6_5621", + "AtGen_6_5622" + ], + "Oxidative_Root_After_24_Hours": [ + "AtGen_6_6621", + "AtGen_6_6625" + ], + "UV-B_Root_After_24_Hours": [ + "AtGen_6_7621", + "AtGen_6_7622" + ], + "Wounding_Root_After_24_Hours": [ + "AtGen_6_8621", + "AtGen_6_8622" + ], + "Heat_Root_After_24_Hours": [ + "AtGen_6_9621", + "AtGen_6_9622" + ] + } + } + } + }, + "Abiotic_Stress_II": { + "database": "atgenexp_stress", + "view_name": "Abiotic_Stress_II", + "groups": { + "GSM491684;GSM491685;GSM491686": { + "controls": [ + "GSM491684", + "GSM491685", + "GSM491686" + ], + "treatments": { + "Water_limited_(dry),_Pre-dawn": [ + "GSM491687", + "GSM491688", + "GSM491689" + ], + "Well_watered,_pre-dawn_(control)": [ + "GSM491684", + "GSM491685", + "GSM491686" + ] + } + }, + "GSM491672;GSM491673;GSM491674": { + "controls": [ + "GSM491672", + "GSM491673", + "GSM491674" + ], + "treatments": { + "Well_watered,_Late_day_(control)": [ + "GSM491672", + "GSM491673", + "GSM491674" + ], + "Water_limited_(dry),_Late_day": [ + "GSM491675", + "GSM491676", + "GSM491677" + ] + } + }, + "GSM237280;GSM237281": { + "controls": [ + "GSM237280", + "GSM237281" + ], + "treatments": { + "Root,_non-selenate_treated_(control)": [ + "GSM237280", + "GSM237281" + ], + "Root,_Selenate_treated": [ + "GSM237282", + "GSM237283" + ] + } + }, + "GSM491666;GSM491667;GSM491668": { + "controls": [ + "GSM491666", + "GSM491667", + "GSM491668" + ], + "treatments": { + "Water_limited_(dry),_Midday": [ + "GSM491669", + "GSM491670", + "GSM491671" + ], + "Well_watered,_Midday_(control)": [ + "GSM491666", + "GSM491667", + "GSM491668" + ] + } + }, + "GSM392492;GSM392493": { + "controls": [ + "GSM392492", + "GSM392493" + ], + "treatments": { + "Shoot,_non-selenate_treated_(control)": [ + "GSM392492", + "GSM392493" + ] + } + }, + "GSM40552": { + "controls": [ + "GSM40552" + ], + "treatments": { + "Non_Stressed_(control),_Total_RNA": [ + "GSM40552" + ], + "Hypoxia_Stress,_Total_RNA": [ + "GSM40553" + ] + } + }, + "GSM40554": { + "controls": [ + "GSM40554" + ], + "treatments": { + "Non_Stressed_(control),_Polysomal_RNA": [ + "GSM40554" + ], + "Hypoxia_Stress,_Polysomal_RNA": [ + "GSM40555" + ] + } + }, + "GSM237292;GSM237293": { + "controls": [ + "GSM237292", + "GSM237293" + ], + "treatments": { + "Shoot,_non-_selenate_treated": [ + "GSM237294", + "GSM237295" + ] + } + }, + "GSM491678;GSM491679;GSM491680": { + "controls": [ + "GSM491678", + "GSM491679", + "GSM491680" + ], + "treatments": { + "Well_watered,_midnight_(control)": [ + "GSM491678", + "GSM491679", + "GSM491680" + ], + "Water_limited_(dry),_midnight": [ + "GSM491681", + "GSM491682", + "GSM491683" + ] + } + } + } + }, + "Biotic_Stress": { + "database": "atgenexp_pathogen", + "view_name": "Biotic_Stress", + "groups": { + "Botrytis_cinerea_at_18_Hours": { + "controls": [ + "CT181-1", + "CT181-2", + "CT182-1" + ], + "treatments": { + "Control_B.c._at_18_Hours": [ + "CT181-1", + "CT181-2", + "CT182-1" + ], + "Treated_B.c._at_18_Hours": [ + "BC181-1", + "BC181-2", + "BC182-1" + ] + } + }, + "Botrytis_cinerea_at_48_Hours": { + "controls": [ + "CT481-1", + "CT482-1", + "CT482-2" + ], + "treatments": { + "Control_B.c._at_48_Hours": [ + "CT481-1", + "CT482-1", + "CT482-2" + ], + "Treated_B.c._at_48_Hours": [ + "BC481-1", + "BC482-1", + "BC482-2" + ] + } + }, + "Half_Leaf_Pseudomonas_syringae_at_4_Hours": { + "controls": [ + "2505", + "2795" + ], + "treatments": { + "Control_Half_P.s_at_4_Hours": [ + "2505", + "2795" + ], + "Avirulent_Half_P.s_at_4_Hours": [ + "2504", + "2796" + ], + "Virulent_Half_P.s_at_4_Hours": [ + "2530", + "2797" + ] + } + }, + "Half_Leaf_Pseudomonas_syringae_at_8_Hours": { + "controls": [ + "2507", + "2792" + ], + "treatments": { + "Control_Half_P.s_at_8_Hours": [ + "2507", + "2792" + ], + "Avirulent_Half_P.s_at_8_Hours": [ + "2506", + "2793" + ], + "Virulent_Half_P.s_at_8_Hours": [ + "2529", + "2794" + ] + } + }, + "Half_Leaf_Pseudomonas_syringae_at_16_Hours": { + "controls": [ + "2527", + "2789" + ], + "treatments": { + "Control_Half_P.s_at_16_Hours": [ + "2527", + "2789" + ], + "Avirulent_Half_P.s_at_16_Hours": [ + "2508", + "2790" + ], + "Virulent_Half_P.s_at_16_Hours": [ + "2528", + "2791" + ] + } + }, + "Half_Leaf_Pseudomonas_syringae_at_24_Hours": { + "controls": [ + "2510", + "2786" + ], + "treatments": { + "Control_Half_P.s_at_24_Hours": [ + "2510", + "2786" + ], + "Avirulent_Half_P.s_at_24_Hours": [ + "2509", + "2787" + ], + "Virulent_Half_P.s_at_24_Hours": [ + "2526", + "2788" + ] + } + }, + "Half_Leaf_Pseudomonas_syringae_at_48_Hours": { + "controls": [ + "2512", + "2783" + ], + "treatments": { + "Control_Half_P.s_at_48_Hours": [ + "2512", + "2783" + ], + "Avirulent_Half_P.s_at_48_Hours": [ + "2511", + "2784" + ], + "Virulent_Half_P.s_at_48_Hours": [ + "2525", + "2785" + ] + } + }, + "Infiltrating_Pseudomonas_syringae_at_2_Hours": { + "controls": [ + "AtGen_A-53_33-1_REP1_ATH1", + "AtGen_A-54_33-2_REP2_ATH1", + "AtGen_A-55_33-3_REP3_ATH1" + ], + "treatments": { + "Control_P.s._at_2_Hours": [ + "AtGen_A-53_33-1_REP1_ATH1", + "AtGen_A-54_33-2_REP2_ATH1", + "AtGen_A-55_33-3_REP3_ATH1" + ], + "Virulent_P.s._at_2_Hours": [ + "AtGen_A-5_21-1_REP1_ATH1", + "AtGen_A-6_21-2_REP2_ATH1", + "AtGen_A-8_21-4_REP3_ATH1" + ], + "Avirulent_P.s._at_2_Hours": [ + "AtGen_A-17_24-1_REP1_ATH1", + "AtGen_A-18_24-2_REP2_ATH1", + "AtGen_A-19_24-3_REP3_ATH1" + ], + "Deficient_P.s._at_2_Hours": [ + "AtGen_A-29_27-1_REP1_ATH1", + "AtGen_A-30_27-2_REP2_ATH1", + "AtGen_A-31-27-3_REP3_ATH1" + ], + "Nonhost_P.s._at_2_Hours": [ + "AtGen_A-41_30-1_REP1_ATH1", + "AtGen_A-42_30-2_REP2_ATH1", + "AtGen_A-43_30-3_REP3_ATH1" + ] + } + }, + "Infiltrating_Pseudomonas_syringae_at_6_Hours": { + "controls": [ + "AtGen_A-58_34-2_REP1_ATH1", + "AtGen_A-59_34-3_REP2_ATH1", + "AtGen_A-60_34-4_REP3_ATH1" + ], + "treatments": { + "Control_P.s._at_6_Hours": [ + "AtGen_A-58_34-2_REP1_ATH1", + "AtGen_A-59_34-3_REP2_ATH1", + "AtGen_A-60_34-4_REP3_ATH1" + ], + "Virulent_P.s._at_6_Hours": [ + "AtGen_A-9_22-1_REP1_ATH1", + "AtGen_A-10_22-2_REP2_ATH1", + "AtGen_A-11_22-3_REP3_ATH1" + ], + "Avirulent_P.s._at_6_Hours": [ + "AtGen_A-21_25-1_REP1_ATH1", + "AtGen_A-23_25-3_REP2_ATH1", + "AtGen_A-24_25-4_REP3_ATH1" + ], + "Deficient_P.s._at_6_Hours": [ + "AtGen_A-33_28-1_REP1_ATH1", + "AtGen_A-34_28-2_REP2_ATH1", + "AtGen_A-35_28-3_REP3_ATH1" + ], + "Nonhost_P.s._at_6_Hours": [ + "AtGen_A-45_31-1_REP1_ATH1", + "AtGen_A-46_31-2_REP2_ATH1", + "AtGen_A-48_31-4_REP3_ATH1" + ] + } + }, + "Infiltrating_Pseudomonas_syringae_at_24_Hours": { + "controls": [ + "AtGen_A-61_35-1_REP1_ATH1", + "AtGen_A-62_35-2_REP2_ATH1", + "AtGen_A-64_35-4_REP3_ATH1" + ], + "treatments": { + "Control_P.s._at_24_Hours": [ + "AtGen_A-61_35-1_REP1_ATH1", + "AtGen_A-62_35-2_REP2_ATH1", + "AtGen_A-64_35-4_REP3_ATH1" + ], + "Virulent_P.s._at_24_Hours": [ + "AtGen_A-13_23-1_REP1_ATH1", + "AtGen_A-14_23-2_REP2_ATH1", + "AtGen_A-16_23-4_REP3_ATH1" + ], + "Avirulent_P.s._at_24_Hours": [ + "AtGen_A-25_26-1_REP1_ATH1", + "AtGen_A-26_26-2_REP2_ATH1 ", + "AtGen_A-28_26-4_REP3_ATH1" + ], + "Deficient_P.s._at_24_Hours": [ + "AtGen_A-37_29-1_REP1_ATH1", + "AtGen_A-38_29-2_REP2_ATH1", + "AtGen_A-40_29-4_REP3_ATH1" + ], + "Nonhost_P.s._at_24_Hours": [ + "AtGen_A-49_32-1_REP1_ATH1", + "AtGen_A-50_32-2_REP2_ATH1", + "AtGen_A-52_32-4_REP3_ATH1" + ] + } + }, + "Water_Controlled_Bacterial_Elicitors_at_1_Hour": { + "controls": [ + "AtGen_B-1_1-1-1_REP_1_ATH1", + "AtGen_B-15_2-1-1_REP2_ATH1", + "AtGen_B-29_3-1-1_REP3_ATH1" + ], + "treatments": { + "H2O_at_1_Hour": [ + "AtGen_B-1_1-1-1_REP_1_ATH1", + "AtGen_B-15_2-1-1_REP2_ATH1", + "AtGen_B-29_3-1-1_REP3_ATH1" + ], + "FLG22_at_1_Hour": [ + "AtGen_B-6_1-6-1_REP_1_ATH1", + "AtGen_B-20_2-6-1_REP2_ATH1", + "AtGen_B-34_3-6-1_REP3_ATH1" + ], + "HrpZ_at_1_Hour": [ + "AtGen_B-4_1-4-1_REP_1_ATH1", + "AtGen_B-18_2-4-1_REP2_ATH1", + "AtGen_B-32_3-4-1_REP3_ATH1" + ] + } + }, + "Ca+Mg_Controlled_Bacterial_Elicitors_at_1_Hour": { + "controls": [ + "AtGen_B-2_1-2-1_REP_1_ATH1", + "AtGen_B-16_2-2-1_REP2_ATH1", + "AtGen_B-30_3-2-1_REP3_ATH1" + ], + "treatments": { + "Ca+Mg_at_1_Hour": [ + "AtGen_B-2_1-2-1_REP_1_ATH1", + "AtGen_B-16_2-2-1_REP2_ATH1", + "AtGen_B-30_3-2-1_REP3_ATH1" + ], + "LPS_at_1_Hour": [ + "AtGen_B-7_1-7-1_REP_1_ATH1", + "AtGen_B-21_2-7-1_REP2_ATH1", + "AtGen_B-35_3-7-1_REP3_ATH1" + ] + } + }, + "Oomycete_Elicitors_at_1_Hour": { + "controls": [ + "AtGen_B-3_1-3-1_REP_1_ATH1", + "AtGen_B-17_2-3-1_REP2_ATH1", + "AtGen_B-31_3-3-1_REP3_ATH1" + ], + "treatments": { + "GST_at_1_Hour": [ + "AtGen_B-3_1-3-1_REP_1_ATH1", + "AtGen_B-17_2-3-1_REP2_ATH1", + "AtGen_B-31_3-3-1_REP3_ATH1" + ], + "NPP_at_1_Hour": [ + "AtGen_B-5_1-5-1_REP_1_ATH1", + "AtGen_B-19_2-5-1_REP2_ATH1", + "AtGen_B-33_3-5-1_REP3_ATH1" + ] + } + }, + "Water_Controlled_Bacterial_Elicitors_at_4_Hours": { + "controls": [ + "AtGen_B-8_1-1-4_REP_1_ATH1", + "AtGen_B-22_2-1-4_REP2_ATH1", + "AtGen_B-36_3-1-4_REP3_ATH1" + ], + "treatments": { + "H2O_at_4_Hours": [ + "AtGen_B-8_1-1-4_REP_1_ATH1", + "AtGen_B-22_2-1-4_REP2_ATH1", + "AtGen_B-36_3-1-4_REP3_ATH1" + ], + "FLG22_at_4_Hours": [ + "AtGen_B-13_1-6-4_REP1_ATH1", + "AtGen_B-27_2-6-4_REP2_ATH1", + "AtGen_B-41_3-6-4_REP3_ATH1" + ], + "HrpZ_at_4_Hours": [ + "AtGen_B-11_1-4-4_REP1_ATH1", + "AtGen_B-25_2-4-4_REP2_ATH1", + "AtGen_B-39_3-4-4_REP3_ATH1" + ] + } + }, + "Ca+Mg_Controlled_Bacterial_Elicitors_at_4_Hours": { + "controls": [ + "AtGen_B-9_1-2-4_REP_1_ATH1", + "AtGen_B-23_2-2-4_REP2_ATH1", + "AtGen_B-37_3-2-4_REP3_ATH1" + ], + "treatments": { + "Ca+Mg_at_4_Hours": [ + "AtGen_B-9_1-2-4_REP_1_ATH1", + "AtGen_B-23_2-2-4_REP2_ATH1", + "AtGen_B-37_3-2-4_REP3_ATH1" + ], + "LPS_at_4_Hours": [ + "AtGen_B-14_1-7-4_REP1_ATH1", + "AtGen_B-28_2-7-4_REP2_ATH1", + "AtGen_B-42_3-7-4_REP3_ATH1" + ] + } + }, + "Oomycete_Elicitors_at_4_Hours": { + "controls": [ + "AtGen_B-10_1-3-4_REP1_ATH1", + "AtGen_B-24_2-3-4_REP2_ATH1", + "AtGen_B-38_3-3-4_REP3_ATH1" + ], + "treatments": { + "GST_at_4_Hours": [ + "AtGen_B-10_1-3-4_REP1_ATH1", + "AtGen_B-24_2-3-4_REP2_ATH1", + "AtGen_B-38_3-3-4_REP3_ATH1" + ], + "NPP_at_4_Hours": [ + "AtGen_B-12_1-5-4_REP1_ATH1", + "AtGen_B-26_2-5-4_REP2_ATH1", + "AtGen_B-40_3-5-4_REP3_ATH1" + ] + } + }, + "Phytophthora_infestans_at_6_Hours": { + "controls": [ + "AtGen_C-1_1-C-6_REP1_ATH1", + "AtGen_C-2_2-C-6_REP2_ATH1", + "AtGen_C-3_4-C-6_REP3_ATH1" + ], + "treatments": { + "Control_P.i._at_6_Hours": [ + "AtGen_C-1_1-C-6_REP1_ATH1", + "AtGen_C-2_2-C-6_REP2_ATH1", + "AtGen_C-3_4-C-6_REP3_ATH1" + ], + "Treated_P.i._at_6_Hours": [ + "AtGen_C-10_1-Pi-6_REP1_ATH1", + "AtGen_C-11_2-Pi-6_REP2_ATH1", + "AtGen_C-12_3-Pi-6_REP3_ATH1" + ] + } + }, + "Phytophthora_infestans_at_12_Hours": { + "controls": [ + "AtGen_C-4_1-C-12_REP1_ATH1", + "AtGen_C-5_2-C-12_REP2_ATH1", + "AtGen_C-6_3-C-12_REP3_ATH1" + ], + "treatments": { + "Control_P.i._at_12_Hours": [ + "AtGen_C-4_1-C-12_REP1_ATH1", + "AtGen_C-5_2-C-12_REP2_ATH1", + "AtGen_C-6_3-C-12_REP3_ATH1" + ], + "Treated_P.i._at_12_Hours": [ + "AtGen_C-13_1-Pi-12_REP1_ATH1", + "AtGen_C-14_2-Pi-12_REP2_ATH1", + "AtGen_C-15_3-Pi-12_REP3_ATH1" + ] + } + }, + "Phytophthora_infestans_at_24_Hours": { + "controls": [ + "AtGen_C-7_1-C-24_REP1_ATH1", + "AtGen_C-8_2-C-24_REP2_ATH1", + "AtGen_C-9_3-C-24_REP3_ATH1" + ], + "treatments": { + "Control_P.i._at_24_Hours": [ + "AtGen_C-7_1-C-24_REP1_ATH1", + "AtGen_C-8_2-C-24_REP2_ATH1", + "AtGen_C-9_3-C-24_REP3_ATH1" + ], + "Treated_P.i._at_24_Hours": [ + "AtGen_C-16_1-Pi-24_REP1_ATH1", + "AtGen_C-17_2-Pi-24_REP2_ATH1", + "AtGen_C-18_3-Pi-24_REP3_ATH1" + ] + } + }, + "Erysiphe_orontii_at_6_Hours": { + "controls": [ + "JD AT+EO COL WT 06H UNINFECTED", + "JD AT+EO COL WT EXP2 06H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 6H" + ], + "treatments": { + "Control_E.o._at_6_Hours": [ + "JD AT+EO COL WT 06H UNINFECTED", + "JD AT+EO COL WT EXP2 06H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 6H" + ], + "Treated_E.o._at_6_Hours": [ + "JD AT+EO COL WT 06H INFECTED", + "JD AT+EO COL WT EXP2 06H INFECTED", + "JD AT+EO TIME EXP3 EO INF 6H" + ] + } + }, + "Erysiphe_orontii_at_12_Hours": { + "controls": [ + "JD AT+EO COL WT 12H UNINFECTED", + "JD AT+EO COL WT EXP2 12H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 12H" + ], + "treatments": { + "Control_E.o._at_12_Hours": [ + "JD AT+EO COL WT 12H UNINFECTED", + "JD AT+EO COL WT EXP2 12H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 12H" + ], + "Treated_E.o._at_12_Hours": [ + "JD AT+EO COL WT 12H INFECTED", + "JD AT+EO COL WT EXP2 12H INFECTED", + "JD AT+EO TIME EXP3 EO INF 12H" + ] + } + }, + "Erysiphe_orontii_at_18_Hours": { + "controls": [ + "JD AT+EO COL WT 18H UNINFECTED", + "JD AT+EO COL WT EXP2 18H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 18H" + ], + "treatments": { + "Control_E.o._at_18_Hours": [ + "JD AT+EO COL WT 18H UNINFECTED", + "JD AT+EO COL WT EXP2 18H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 18H" + ], + "Treated_E.o._at_18_Hours": [ + "JD AT+EO COL WT 18H INFECTED", + "JD AT+EO COL WT EXP2 18H INFECTED", + "JD AT+EO TIME EXP3 EO INF 18H" + ] + } + }, + "Erysiphe_orontii_at_24_Hours": { + "controls": [ + "JD AT+EO COL WT 24H UNINFECTED", + "JD AT+EO COL WT EXP2 24H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 24H" + ], + "treatments": { + "Control_E.o._at_24_Hours": [ + "JD AT+EO COL WT 24H UNINFECTED", + "JD AT+EO COL WT EXP2 24H UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 24H" + ], + "Treated_E.o._at_24_Hours": [ + "JD AT+EO COL WT 24H INFECTED", + "JD AT+EO COL WT EXP2 24H INFECTED", + "JD AT+EO TIME EXP3 EO INF 24H" + ] + } + }, + "Erysiphe_orontii_at_48_Hours": { + "controls": [ + "JD AT+EO COL WT 02D UNINFECTED", + "JD AT+EO COL WT EXP2 02D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 2D" + ], + "treatments": { + "Control_E.o._at_48_Hours": [ + "JD AT+EO COL WT 02D UNINFECTED", + "JD AT+EO COL WT EXP2 02D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 2D" + ], + "Treated_E.o._at_48_Hours": [ + "JD AT+EO COL WT 02D INFECTED", + "JD AT+EO COL WT EXP2 02D INFECTED", + "JD AT+EO TIME EXP3 EO INF 2D" + ] + } + }, + "Erysiphe_orontii_at_72_Hours": { + "controls": [ + "JD AT+EO COL WT 03D UNINFECTED", + "JD AT+EO COL WT EXP2 03D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 3D" + ], + "treatments": { + "Control_E.o._at_72_Hours": [ + "JD AT+EO COL WT 03D UNINFECTED", + "JD AT+EO COL WT EXP2 03D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 3D" + ], + "Treated_E.o._at_72_Hours": [ + "JD AT+EO COL WT 03D INFECTED", + "JD AT+EO COL WT EXP2 03D INFECTED", + "JD AT+EO TIME EXP3 EO INF 3D" + ] + } + }, + "Erysiphe_orontii_at_96_Hours": { + "controls": [ + "JD AT+EO COL WT 04D UNINFECTED", + "JD AT+EO COL WT EXP2 04D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 4D" + ], + "treatments": { + "Control_E.o._at_96_Hours": [ + "JD AT+EO COL WT 04D UNINFECTED", + "JD AT+EO COL WT EXP2 04D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 4D" + ], + "Treated_E.o._at_96_Hours": [ + "JD AT+EO COL WT 04D INFECTED", + "JD AT+EO COL WT EXP2 04D INFECTED", + "JD AT+EO TIME EXP3 EO INF 4D" + ] + } + }, + "Erysiphe_orontii_at_120_Hours": { + "controls": [ + "JD AT+EO COL WT 05D UNINFECTED", + "JD AT+EO COL WT EXP2 05D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 5D" + ], + "treatments": { + "Control_E.o._at_120_Hours": [ + "JD AT+EO COL WT 05D UNINFECTED", + "JD AT+EO COL WT EXP2 05D UNINFECTED", + "JD AT+EO TIME EXP3 UNINF 5D" + ], + "Treated_E.o._at_120_Hours": [ + "JD AT+EO COL WT 05D INFECTED", + "JD AT+EO COL WT EXP2 05D INFECTED", + "JD AT+EO TIME EXP3 EO INF 5D" + ] + } + } + } + }, + "Biotic_Stress_II": { + "database": "atgenexp_pathogen", + "view_name": "Biotic_Stress_II", + "groups": { + "GSM392490;GSM392491": { + "controls": [ + "GSM392490", + "GSM392491" + ], + "treatments": { + "Col_laser_microdissected,_5_d_UI,": [ + "GSM392490", + "GSM392491" + ], + "Col_laser_microdissected,_5_dpi": [ + "GSM392488", + "GSM392489" + ], + "eds16_laser_microdissected,_5_dpi": [ + "GSM392492", + "GSM392493" + ] + } + }, + "GSM392500;GSM392501": { + "controls": [ + "GSM392500", + "GSM392501" + ], + "treatments": { + "Col_whole_leaf_amplified,_5_d_UI": [ + "GSM392500", + "GSM392501" + ], + "Col_whole_leaf_amplified,_5_dpi,": [ + "GSM392498", + "GSM392499" + ], + "Col_leaf_scrape,_5_dpi": [ + "GSM392502", + "GSM392503" + ] + } + }, + "GSM554311_WT_Emwa1_0dpi_rep2": { + "controls": [ + "GSM554311_WT_Emwa1_0dpi_rep2" + ], + "treatments": { + "WT_Emwa1_0dpi_rep1+rep2": [ + "GSM554311_WT_Emwa1_0dpi_rep1", + "GSM554311_WT_Emwa1_0dpi_rep2" + ], + "WT_Emwa1_0.5dpi_rep1+rep2": [ + "GSM554312_WT_Emwa1_0.5dpi_rep2" + ], + "WT_Emwa1_2dpi_rep1+rep2": [ + "GSM554313_WT_Emwa1_2dpi_rep1", + "GSM554313_WT_Emwa1_2dpi_rep2" + ], + "WT_Emwa1_4dpi_rep1+rep2": [ + "GSM554314_WT_Emwa1_4dpi_rep1", + "GSM554314_WT_Emwa1_4dpi_rep2" + ], + "WT_Emwa1_6dpi_rep1+rep2": [ + "GSM554315_WT_Emwa1_6dpi_rep1", + "GSM554315_WT_Emwa1_6dpi_rep2" + ] + } + }, + "GSM554316_rpp4_Emwa1_0dpi_rep1;GSM554316_rpp4_Emwa1_0dpi_rep2": { + "controls": [ + "GSM554316_rpp4_Emwa1_0dpi_rep1", + "GSM554316_rpp4_Emwa1_0dpi_rep2" + ], + "treatments": { + "rpp4_Emwa1_0dpi_rep1+rep2": [ + "GSM554316_rpp4_Emwa1_0dpi_rep1", + "GSM554316_rpp4_Emwa1_0dpi_rep2" + ], + "rpp4_Emwa1_0.5dpi_rep1+rep2": [ + "GSM554317_rpp4_Emwa1_0.5dpi_rep1", + "GSM554317_rpp4_Emwa1_0.5dpi_rep2" + ], + "rpp4_Emwa1_2dpi_rep1+rep2": [ + "GSM554318_rpp4_Emwa1_2dpi_rep1", + "GSM554318_rpp4_Emwa1_2dpi_rep2" + ], + "rpp4_Emwa1_4dpi_rep1+rep2": [ + "GSM554319_rpp4_Emwa1_4dpi_rep1", + "GSM554319_rpp4_Emwa1_4dpi_rep2" + ], + "rpp4_Emwa1_6dpi_rep1+rep2": [ + "GSM554320_rpp4_Emwa1_6dpi_rep1", + "GSM554320_rpp4_Emwa1_6dpi_rep2" + ] + } + }, + "GSM157299;GSM157300;GSM157301": { + "controls": [ + "GSM157299_JPritchard_A-1_CTR_Rep1_ATH1", + "GSM157300_JPritchard_A-2_CTR_Rep2_ATH1", + "GSM157301_Pritchard_A-3_CTR_Rep3_ATH1" + ], + "treatments": { + "Control": [ + "GSM157299_JPritchard_A-1_CTR_Rep1_ATH1", + "GSM157300_JPritchard_A-2_CTR_Rep2_ATH1", + "GSM157301_Pritchard_A-3_CTR_Rep3_ATH1" + ], + "Aphid_infested": [ + "GSM157303_JPritchard_A-5_API_Rep2_ATH1", + "GSM157304_JPritchard_A-6_API_Rep3_ATH1" + ] + } + } + } + }, + "Chemical": { + "database": "atgenexp_hormone", + "view_name": "Chemical", + "groups": { + "Gibberellic_Acid_Inhibitors_at_3_Hours": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "Propiconazole_Treated_at_3_Hours": [ + "RIKEN-GODA3A2", + "RIKEN-GODA3B2" + ], + "Uniconazole_Treated_at_3_Hours": [ + "RIKEN-GODA5A2", + "RIKEN-GODA5B2" + ], + "Paclobutrazol_Treated_at_3_Hours": [ + "RIKEN-GODA11A2", + "RIKEN-GODA11B2" + ], + "Prohexadione_Treated_at_3_Hours": [ + "RIKEN-GODA13A2", + "RIKEN-GODA13B2" + ] + } + }, + "Gibberellic_Acid_Inhibitors_at_12_Hours": { + "controls": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2" + ], + "treatments": { + "Control_at_12_Hours": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2" + ], + "Propiconazole_Treated_at_12_Hours": [ + "RIKEN-GODA4A2", + "RIKEN-GODA4B2" + ], + "Uniconazole_Treated_at_12_Hours": [ + "RIKEN-GODA6A2", + "RIKEN-GODA6B2" + ], + "Paclobutrazol_Treated_at_12_Hours": [ + "RIKEN-GODA12A2", + "RIKEN-GODA12B2" + ], + "Prohexadione_Treated_at_12_Hours": [ + "RIKEN-GODA14A2", + "RIKEN-GODA14B2" + ] + } + }, + "Auxin_Inhibitors": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "2,4,6-T_Treated": [ + "RIKEN-GODA23A3", + "RIKEN-GODA23B3" + ], + "PCIB_Treated": [ + "RIKEN-GODA24A3", + "RIKEN-GODA24B3" + ], + "TIBA_Treated": [ + "RIKEN-GODA25A3", + "RIKEN-GODA25B3" + ], + "NPA_Treated": [ + "RIKEN-GODA26A3", + "RIKEN-GODA26B3" + ] + } + }, + "Brassinosteroid_Inhibitors_at_3_Hours": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "10uM_Brz220_Treated_at_3_Hours": [ + "RIKEN-GODA7A4", + "RIKEN-GODA7B4" + ], + "3uM_Brz220_Treated_at_3_Hours": [ + "RIKEN-GODA30A4", + "RIKEN-GODA30B4" + ] + } + }, + "Brassinosteroid_Inhibitors_at_12_Hours": { + "controls": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2" + ], + "treatments": { + "Control_at_12_Hours": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2" + ], + "10uM_Brz91_Treated_at_12_Hours": [ + "RIKEN-GODA10A4", + "RIKEN-GODA10B4" + ] + } + }, + "Ethylene_Inhibitors": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "10uM_AgNO3_Treated": [ + "RIKEN-GODA19A7", + "RIKEN-GODA19B7" + ], + "10uM_AVG_Treated": [ + "RIKEN-GODA20A7", + "RIKEN-GODA20B7" + ] + } + }, + "Cyclohexamide": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "10uM_CHX_Treated": [ + "RIKEN-GODA27A8", + "RIKEN-GODA27B8" + ] + } + }, + "Proteasome_Inhibitor_MG13": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "10uM_MG132_Treated": [ + "RIKEN-GODA22A9", + "RIKEN-GODA22B9" + ] + } + }, + "Photosynthesis_Inhibitor_PN08_at_3_Hours": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "1uM_PNO8_Treated_at_3_Hours": [ + "RIKEN-GODA15A5", + "RIKEN-GODA15B5" + ], + "10uM_PNO8_Treated_at_3_Hours": [ + "RIKEN-GODA29A5", + "RIKEN-GODA29B5" + ] + } + }, + "Photosynthesis_Inhibitor_PN08_at_12_Hours": { + "controls": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2" + ], + "treatments": { + "Control_at_12_Hours": [ + "RIKEN-GODA2A2", + "RIKEN-GODA2B2 " + ], + "1uM_PNO8_Treated_at_12_Hours": [ + "RIKEN-GODA16A5", + "RIKEN-GODA16B5" + ] + } + }, + "Ibuprofen,_Salycylic_Acid,_and_Daminozide": { + "controls": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A2", + "RIKEN-GODA1B2" + ], + "Ibuprofen_Treated": [ + "RIKEN-GODA17AH", + "RIKEN-GODA17BH" + ], + "Salicylic_Acid_Treated": [ + "RIKEN-GODA21AH", + "RIKEN-GODA21BH" + ], + "Daminozide_Treated": [ + "RIKEN-GODA18AH", + "RIKEN-GODA18BH" + ] + } + } + } + }, + "DNA_Damage": { + "database": "dna_damage", + "view_name": "DNA_Damage", + "groups": { + "col-0_rep1_20min_minus_Y;col-0_rep2_20min_minus_Y": { + "controls": [ + "col-0_rep1_20min_minus_Y", + "col-0_rep2_20min_minus_Y" + ], + "treatments": { + "Y+_Col-0_20min": [ + "col-0_rep1_20min_plus_Y", + "col-0_rep2_20min_plus_Y" + ], + "Y-_Col-0_20min": [ + "col-0_rep1_20min_minus_Y", + "col-0_rep2_20min_minus_Y" + ] + } + }, + "col-0_rep1_90min_minus_Y;col-0_rep2_90min_minus_Y": { + "controls": [ + "col-0_rep1_90min_minus_Y", + "col-0_rep2_90min_minus_Y" + ], + "treatments": { + "Y+_Col-0_90min": [ + "col-0_rep1_90min_plus_Y", + "col-0_rep2_90min_plus_Y" + ], + "Y-_Col-0_90min": [ + "col-0_rep1_90min_minus_Y", + "col-0_rep2_90min_minus_Y" + ] + } + }, + "col-0_rep1_3hr_minus_Y;col-0_rep2_3hr_minus_Y": { + "controls": [ + "col-0_rep1_3hr_minus_Y", + "col-0_rep2_3hr_minus_Y" + ], + "treatments": { + "Y+_Col-0_3h": [ + "col-0_rep1_3hr_plus_Y", + "col-0_rep2_3hr_plus_Y" + ], + "Y-_Col-0_3h": [ + "col-0_rep1_3hr_minus_Y", + "col-0_rep2_3hr_minus_Y" + ] + } + }, + "col-0_rep1_6hr_minus_Y;col-0_rep2_6hr_minus_Y": { + "controls": [ + "col-0_rep1_6hr_minus_Y", + "col-0_rep2_6hr_minus_Y" + ], + "treatments": { + "Y+_Col-0_6h": [ + "col-0_rep1_6hr_plus_Y", + "col-0_rep2_6hr_plus_Y" + ], + "Y-_Col-0_6h": [ + "col-0_rep1_6hr_minus_Y", + "col-0_rep2_6hr_minus_Y" + ] + } + }, + "col-0_rep1_12hr_minus_Y;col-0_rep2_12hr_minus_Y": { + "controls": [ + "col-0_rep1_12hr_minus_Y", + "col-0_rep2_12hr_minus_Y" + ], + "treatments": { + "Y+_Col-0_12h": [ + "col-0_rep1_12hr_plus_Y", + "col-0_rep2_12hr_plus_Y" + ], + "Y-_Col-0_12h": [ + "col-0_rep1_12hr_minus_Y", + "col-0_rep2_12hr_minus_Y" + ] + } + }, + "col-0_rep1_24hr_minus_Y;col-0_rep2_24hr_minus_Y": { + "controls": [ + "col-0_rep1_24hr_minus_Y", + "col-0_rep2_24hr_minus_Y" + ], + "treatments": { + "Y+_Col-0_24h": [ + "col-0_rep1_24hr_plus_Y", + "col-0_rep2_24hr_plus_Y" + ], + "Y-_Col-0_24h": [ + "col-0_rep1_24hr_minus_Y", + "col-0_rep2_24hr_minus_Y" + ] + } + }, + "sog1-1_rep1_20min_minus_Y;sog1-1_rep2_20min_minus_Y": { + "controls": [ + "sog1-1_rep1_20min_minus_Y", + "sog1-1_rep2_20min_minus_Y" + ], + "treatments": { + "Y+_sog1-1_20min": [ + "sog1-1_rep1_20min_plus_Y", + "sog1-1_rep2_20min_plus_Y" + ], + "Y-_sog1-1_20min": [ + "sog1-1_rep1_20min_minus_Y", + "sog1-1_rep2_20min_minus_Y" + ] + } + }, + "sog1-1_rep1_90min_minus_Y;sog1-1_rep2_90min_minus_Y": { + "controls": [ + "sog1-1_rep1_90min_minus_Y", + "sog1-1_rep2_90min_minus_Y" + ], + "treatments": { + "Y+_sog1-1_90min": [ + "sog1-1_rep1_90min_plus_Y", + "sog1-1_rep2_90min_plus_Y" + ], + "Y-_sog1-1_90min": [ + "sog1-1_rep1_90min_minus_Y", + "sog1-1_rep2_90min_minus_Y" + ] + } + }, + "sog1-1_rep1_3hr_minus_Y;sog1-1_rep2_3hr_minus_Y": { + "controls": [ + "sog1-1_rep1_3hr_minus_Y", + "sog1-1_rep2_3hr_minus_Y" + ], + "treatments": { + "Y+_sog1-1_3h": [ + "sog1-1_rep1_3hr_plus_Y", + "sog1-1_rep2_3hr_plus_Y" + ], + "Y-_sog1-1_3h": [ + "sog1-1_rep1_3hr_minus_Y", + "sog1-1_rep2_3hr_minus_Y" + ] + } + }, + "sog1-1_rep1_6hr_minus_Y;sog1-1_rep2_6hr_minus_Y": { + "controls": [ + "sog1-1_rep1_6hr_minus_Y", + "sog1-1_rep2_6hr_minus_Y" + ], + "treatments": { + "Y+_sog1-1_6h": [ + "sog1-1_rep1_6hr_plus_Y", + "sog1-1_rep2_6hr_plus_Y" + ], + "Y-_sog1-1_6h": [ + "sog1-1_rep1_6hr_minus_Y", + "sog1-1_rep2_6hr_minus_Y" + ] + } + }, + "sog1-1_rep1_12hr_minus_Y;sog1-1_rep2_12hr_minus_Y": { + "controls": [ + "sog1-1_rep1_12hr_minus_Y", + "sog1-1_rep2_12hr_minus_Y" + ], + "treatments": { + "Y+_sog1-1_12h": [ + "sog1-1_rep1_12hr_plus_Y", + "sog1-1_rep2_12hr_plus_Y" + ], + "Y-_sog1-1_12h": [ + "sog1-1_rep1_12hr_minus_Y", + "sog1-1_rep2_12hr_minus_Y" + ] + } + }, + "sog1-1_rep1_24hr_minus_Y;sog1-1_rep2_24hr_minus_Y": { + "controls": [ + "sog1-1_rep1_24hr_minus_Y", + "sog1-1_rep2_24hr_minus_Y" + ], + "treatments": { + "Y+_sog1-1_24h": [ + "sog1-1_rep1_24hr_plus_Y", + "sog1-1_rep2_24hr_plus_Y" + ], + "Y-_sog1-1_24h": [ + "sog1-1_rep1_24hr_minus_Y", + "sog1-1_rep2_24hr_minus_Y" + ] + } + } + } + }, + "Development_RMA": { + "database": "atgenexp", + "view_name": "Development_RMA", + "groups": { + "CTRL_7": { + "controls": [ + "ATGE_CTRL_7" + ], + "treatments": { + "1st_Node": [ + "ATGE_28_A2", + "ATGE_28_B2", + "ATGE_28_C2" + ], + "Flower_Stage_12,Stamens": [ + "ATGE_36_A", + "ATGE_36_B", + "ATGE_36_C" + ], + "Cauline_Leaf": [ + "ATGE_26_A", + "ATGE_26_B", + "ATGE_26_C" + ], + "Cotyledon": [ + "ATGE_1_A", + "ATGE_1_B", + "ATGE_1_C" + ], + "Root": [ + "ATGE_9_A", + "ATGE_9_B", + "ATGE_9_C", + "ATGE_3_A", + "ATGE_3_B", + "ATGE_3_C" + ], + "Entire_Rosette_After_Transition_to_Flowering": [ + "ATGE_23_A", + "ATGE_23_B", + "ATGE_23_C" + ], + "Flower_Stage_9": [ + "ATGE_31_A2", + "ATGE_31_B2", + "ATGE_31_C2" + ], + "Flower_Stage_10/11": [ + "ATGE_32_A2", + "ATGE_32_B2", + "ATGE_32_C2" + ], + "Flower_Stage_12": [ + "ATGE_33_A", + "ATGE_33_B", + "ATGE_33_C" + ], + "Flower_Stage_15": [ + "ATGE_39_A", + "ATGE_39_B", + "ATGE_39_C" + ], + "Flower_Stage_12,_Carpels": [ + "ATGE_37_A", + "ATGE_37_B", + "ATGE_37_C" + ], + "Flower_Stage_12,_Petals": [ + "ATGE_35_A", + "ATGE_35_B", + "ATGE_35_C" + ], + "Flower_Stage_12,_Sepals": [ + "ATGE_34_A", + "ATGE_34_B", + "ATGE_34_C" + ], + "Flower_Stage_15,_Carpels": [ + "ATGE_45_A", + "ATGE_45_B", + "ATGE_45_C" + ], + "Flower_Stage_15,_Petals": [ + "ATGE_42_B", + "ATGE_42_C", + "ATGE_42_D" + ], + "Flower_Stage_15,_Sepals": [ + "ATGE_41_A", + "ATGE_41_B", + "ATGE_41_C" + ], + "Flower_Stage_15,_Stamen": [ + "ATGE_43_A", + "ATGE_43_B", + "ATGE_43_C" + ], + "Flowers_Stage_15,_Pedicels": [ + "ATGE_40_A", + "ATGE_40_B", + "ATGE_40_C" + ], + "Leaf_1_+_2": [ + "ATGE_5_A", + "ATGE_5_B", + "ATGE_5_C" + ], + "Leaf_7,_Petiole": [ + "ATGE_19_A", + "ATGE_19_B", + "ATGE_19_C" + ], + "Leaf_7,_Distal_Half": [ + "ATGE_21_A", + "ATGE_21_B", + "ATGE_21_C" + ], + "Leaf_7,_Proximal_Half": [ + "ATGE_20_A", + "ATGE_20_B", + "ATGE_20_C" + ], + "Hypocotyl": [ + "ATGE_2_A", + "ATGE_2_B", + "ATGE_2_C" + ], + "Rosette_Leaf_2": [ + "ATGE_12_A", + "ATGE_12_B", + "ATGE_12_C" + ], + "Rosette_Leaf_4": [ + "ATGE_13_A", + "ATGE_13_B", + "ATGE_13_C" + ], + "Rosette_Leaf_6": [ + "ATGE_14_A", + "ATGE_14_B", + "ATGE_14_C" + ], + "Rosette_Leaf_8": [ + "ATGE_15_A", + "ATGE_15_B", + "ATGE_15_C" + ], + "Rosette_Leaf_10": [ + "ATGE_16_A", + "ATGE_16_B", + "ATGE_16_C" + ], + "Rosette_Leaf_12": [ + "ATGE_17_A", + "ATGE_17_B", + "ATGE_17_C" + ], + "Senescing_Leaf": [ + "ATGE_25_A", + "ATGE_25_B", + "ATGE_25_C" + ], + "Shoot_Apex,_Inflorescence": [ + "ATGE_29_A2", + "ATGE_29_B2", + "ATGE_29_C2" + ], + "Shoot_Apex,_Transition": [ + "ATGE_8_A", + "ATGE_8_B", + "ATGE_8_C" + ], + "Shoot_Apex,_Vegetative": [ + "ATGE_6_A", + "ATGE_6_B", + "ATGE_6_C" + ], + "Stem,_2nd_Internode": [ + "ATGE_27_A", + "ATGE_27_B", + "ATGE_27_C" + ], + "Mature_Pollen": [ + "ATGE_73_A", + "ATGE_73_B", + "ATGE_73_C" + ], + "Seeds_Stage_3_w/_Siliques": [ + "ATGE_76_A", + "ATGE_76_B", + "ATGE_76_C" + ], + "Seeds_Stage_4_w/_Siliques": [ + "ATGE_77_D", + "ATGE_77_E", + "ATGE_77_F" + ], + "Seeds_Stage_5_w/_Siliques": [ + "ATGE_78_D", + "ATGE_78_E", + "ATGE_78_F" + ], + "Seeds_Stage_6_w/o_Siliques": [ + "ATGE_79_A", + "ATGE_79_B", + "ATGE_79_C" + ], + "Seeds_Stage_7_w/o_Siliques": [ + "ATGE_81_A", + "ATGE_81_B", + "ATGE_81_C" + ], + "Seeds_Stage_8_w/o_Siliques": [ + "ATGE_82_A", + "ATGE_82_B", + "ATGE_82_C" + ], + "Seeds_Stage_9_w/o_Siliques": [ + "ATGE_83_A", + "ATGE_83_B", + "ATGE_83_C" + ], + "Seeds_Stage_10_w/o_Siliques": [ + "ATGE_84_A", + "ATGE_84_B", + "ATGE_84_D" + ], + "Vegetative_Rosette": [ + "ATGE_89_A", + "ATGE_89_B", + "ATGE_89_C" + ] + } + } + } + }, + "Developmental_Map": { + "database": "atgenexp_plus", + "view_name": "Developmental_Map", + "groups": { + "CTRL_7": { + "controls": [ + "ATGE_CTRL_7" + ], + "treatments": { + "Dry_seed": [ + "RIKEN-NAKABAYASHI1A", + "RIKEN-NAKABAYASHI1B" + ], + "Imbibed_seed,_24_h": [ + "RIKEN-NAKABAYASHI2A", + "RIKEN-NAKABAYASHI2B" + ], + "1st_Node": [ + "ATGE_28_A2", + "ATGE_28_B2", + "ATGE_28_C2" + ], + "Flower_Stage_12,_Stamens": [ + "ATGE_36_A", + "ATGE_36_B", + "ATGE_36_C" + ], + "Cauline_Leaf": [ + "ATGE_26_A", + "ATGE_26_B", + "ATGE_26_C" + ], + "Cotyledon": [ + "ATGE_1_A", + "ATGE_1_B", + "ATGE_1_C" + ], + "Root": [ + "ATGE_9_A", + "ATGE_9_B", + "ATGE_9_C", + "ATGE_3_A", + "ATGE_3_B", + "ATGE_3_C" + ], + "Entire_Rosette_After_Transition_to_Flowering": [ + "ATGE_23_A", + "ATGE_23_B", + "ATGE_23_C" + ], + "Flower_Stage_9": [ + "ATGE_31_A2", + "ATGE_31_B2", + "ATGE_31_C2" + ], + "Flower_Stage_10/11": [ + "ATGE_32_A2", + "ATGE_32_B2", + "ATGE_32_C2" + ], + "Flower_Stage_12": [ + "ATGE_33_A", + "ATGE_33_B", + "ATGE_33_C" + ], + "Flower_Stage_15": [ + "ATGE_39_A", + "ATGE_39_B", + "ATGE_39_C" + ], + "Flower_Stage_12,_Carpels": [ + "ATGE_37_A", + "ATGE_37_B", + "ATGE_37_C" + ], + "Flower_Stage_12,_Petals": [ + "ATGE_35_A", + "ATGE_35_B", + "ATGE_35_C" + ], + "Flower_Stage_12,_Sepals": [ + "ATGE_34_A", + "ATGE_34_B", + "ATGE_34_C" + ], + "Flower_Stage_15,_Carpels": [ + "ATGE_45_A", + "ATGE_45_B", + "ATGE_45_C" + ], + "Flower_Stage_15,_Petals": [ + "ATGE_42_B", + "ATGE_42_C", + "ATGE_42_D" + ], + "Flower_Stage_15,_Sepals": [ + "ATGE_41_A", + "ATGE_41_B", + "ATGE_41_C" + ], + "Flower_Stage_15,_Stamen": [ + "ATGE_43_A", + "ATGE_43_B", + "ATGE_43_C" + ], + "Flowers_Stage_15,_Pedicels": [ + "ATGE_40_A", + "ATGE_40_B", + "ATGE_40_C" + ], + "Leaf_1_+_2": [ + "ATGE_5_A", + "ATGE_5_B", + "ATGE_5_C" + ], + "Leaf_7,_Petiole": [ + "ATGE_19_A", + "ATGE_19_B", + "ATGE_19_C" + ], + "Leaf_7,_Distal_Half": [ + "ATGE_21_A", + "ATGE_21_B", + "ATGE_21_C" + ], + "Leaf_7,_Proximal_Half": [ + "ATGE_20_A", + "ATGE_20_B", + "ATGE_20_C" + ], + "Hypocotyl": [ + "ATGE_2_A", + "ATGE_2_B", + "ATGE_2_C" + ], + "Rosette_Leaf_2": [ + "ATGE_12_A", + "ATGE_12_B", + "ATGE_12_C" + ], + "Rosette_Leaf_4": [ + "ATGE_13_A", + "ATGE_13_B", + "ATGE_13_C" + ], + "Rosette_Leaf_6": [ + "ATGE_14_A", + "ATGE_14_B", + "ATGE_14_C" + ], + "Rosette_Leaf_8": [ + "ATGE_15_A", + "ATGE_15_B", + "ATGE_15_C" + ], + "Rosette_Leaf_10": [ + "ATGE_16_A", + "ATGE_16_B", + "ATGE_16_C" + ], + "Rosette_Leaf_12": [ + "ATGE_17_A", + "ATGE_17_B", + "ATGE_17_C" + ], + "Senescing_Leaf": [ + "ATGE_25_A", + "ATGE_25_B", + "ATGE_25_C" + ], + "Shoot_Apex,_Inflorescence": [ + "ATGE_29_A2", + "ATGE_29_B2", + "ATGE_29_C2" + ], + "Shoot_Apex,_Transition": [ + "ATGE_8_A", + "ATGE_8_B", + "ATGE_8_C" + ], + "Shoot_Apex,_Vegetative": [ + "ATGE_6_A", + "ATGE_6_B", + "ATGE_6_C" + ], + "Stem,_2nd_Internode": [ + "ATGE_27_A", + "ATGE_27_B", + "ATGE_27_C" + ], + "Mature_Pollen": [ + "ATGE_73_A", + "ATGE_73_B", + "ATGE_73_C" + ], + "Seeds_Stage_3_w/_Siliques": [ + "ATGE_76_A", + "ATGE_76_B", + "ATGE_76_C" + ], + "Seeds_Stage_4_w/_Siliques": [ + "ATGE_77_D", + "ATGE_77_E", + "ATGE_77_F" + ], + "Seeds_Stage_5_w/_Siliques": [ + "ATGE_78_D", + "ATGE_78_E", + "ATGE_78_F" + ], + "Seeds_Stage_6_w/o_Siliques": [ + "ATGE_79_A", + "ATGE_79_B", + "ATGE_79_C" + ], + "Seeds_Stage_7_w/o_Siliques": [ + "ATGE_81_A", + "ATGE_81_B", + "ATGE_81_C" + ], + "Seeds_Stage_8_w/o_Siliques": [ + "ATGE_82_A", + "ATGE_82_B", + "ATGE_82_C" + ], + "Seeds_Stage_9_w/o_Siliques": [ + "ATGE_83_A", + "ATGE_83_B", + "ATGE_83_C" + ], + "Seeds_Stage_10_w/o_Siliques": [ + "ATGE_84_A", + "ATGE_84_B", + "ATGE_84_D" + ], + "Vegetative_Rosette": [ + "ATGE_89_A", + "ATGE_89_B", + "ATGE_89_C" + ] + } + } + } + }, + "Developmental_Mutants": { + "database": "atgenexp_plus", + "view_name": "Developmental_Mutants", + "groups": { + "GSM757891;GSM757892;GSM757893": { + "controls": [ + "GSM757891", + "GSM757892", + "GSM757893" + ], + "treatments": { + "gl3_mutant": [ + "GSM1153854", + "GSM1153855", + "GSM1153856" + ], + "wer_mutant": [ + "GSM1153866", + "GSM1153867", + "GSM1153868" + ], + "ttg2_cpc_mutant": [ + "GSM1153848", + "GSM1153849", + "GSM1153850" + ], + "cow1_mutant": [ + "GSM757834", + "GSM757835", + "GSM757836" + ], + "cobl9_mutant": [ + "GSM757831", + "GSM757832", + "GSM757833" + ], + "WT_Columbia": [ + "GSM757891", + "GSM757892", + "GSM757893" + ], + "ttg2_mutant": [ + "GSM1153863", + "GSM1153864", + "GSM1153865" + ], + "wer_myb23_mutant": [ + "GSM757888", + "GSM757889", + "GSM757890" + ], + "gl2_mutant": [ + "GSM757843", + "GSM757844", + "GSM757845" + ], + "rhd6_mutant": [ + "GSM757879", + "GSM757880", + "GSM757881" + ], + "mrh2_mutant": [ + "GSM757858", + "GSM757859", + "GSM757860" + ], + "cpc_mutant": [ + "GSM1153845", + "GSM1153846", + "GSM1153847" + ], + "_rhd6_mutant_+_ACC": [ + "GSM757870", + "GSM757871", + "GSM757872" + ], + "ttg_mutant": [ + "GSM757885", + "GSM757886", + "GSM757887" + ], + "myc1_mutant": [ + "GSM757864", + "GSM757865", + "GSM757866" + ], + "cpc_try_mutant": [ + "GSM757837", + "GSM757838", + "GSM757839" + ], + "rhd6_mutant_+_IAA": [ + "GSM757873", + "GSM757874", + "GSM757875" + ], + "csld3_mutant": [ + "GSM757840", + "GSM757841", + "GSM757842" + ], + "egl3_mutant": [ + "GSM1153851", + "GSM1153852", + "GSM1153853" + ], + "try_mutant": [ + "GSM1153860", + "GSM1153861", + "GSM1153862" + ], + "rhd6_mutant_+_MS_(buffer)": [ + "GSM757876", + "GSM757877", + "GSM757878" + ], + "mrh3_mutant": [ + "GSM757861", + "GSM757862", + "GSM757863" + ], + "mrh1_mutant": [ + "GSM757855", + "GSM757856", + "GSM757857" + ], + "lrx1_mutant": [ + "GSM757852", + "GSM757853", + "GSM757854" + ], + "rhd2_mutant": [ + "GSM757867", + "GSM757868", + "GSM757869" + ], + "ire_mutant": [ + "GSM757849", + "GSM757850", + "GSM757851" + ], + "myb23_mutant": [ + "GSM1153857", + "GSM1153858", + "GSM1153859" + ], + "bhlh66_mutant": [ + "GSM757882", + "GSM757883", + "GSM757884" + ], + "gl3_egl3_mutant": [ + "GSM757846", + "GSM757847", + "GSM757848" + ] + } + }, + "ColprocessleafArd13;ColprocessleafMN3;ColprocessleafMN4;ColprocessleafMN5": { + "controls": [ + "ColprocessleafArd13", + "ColprocessleafMN3", + "ColprocessleafMN4", + "ColprocessleafMN5" + ], + "treatments": { + "gl3-sst_mutant_trichomes": [ + "DM9_sst1", + "m1DM8sstard", + "m1ssttr5_ATH1" + ], + "gl3-sst_nok-1_double_mutant_trichomes": [ + "EG_mosst1", + "EG_mosst2", + "EG_mosst3" + ], + "WT_Col-0_trichomes": [ + "ColtrichomeArd1", + "ColtrichomeArd2", + "ColtrichomeMN12", + "ColtrichomeMN13", + "ColtrichomeMN2" + ], + "gl3-sst_sim_double_mutant_trichomes": [ + "gl3_sstsimtrichomeMN1", + "gl3_sstsimtrichomeMN2" + ], + "WT_Col-0_leaves_after_trichome_removal": [ + "ColprocessleafArd13", + "ColprocessleafMN3", + "ColprocessleafMN4", + "ColprocessleafMN5" + ] + } + }, + "GSM738872_C2;GSM738873_C3;GSM738874_C4": { + "controls": [ + "GSM738872_C2", + "GSM738873_C3", + "GSM738874_C4" + ], + "treatments": { + "scrm-D_mute_whole_seedling_at_5_dpg": [ + "GSM738878_M2", + "GSM738879_M3", + "GSM738880_M4" + ], + "spch_whole_seedling_at_5_dpg": [ + "GSM738875_S2", + "GSM738876_S3", + "GSM738877_S4" + ], + "Col-0_WT_whole_seedling_at_5_dpg": [ + "GSM738872_C2", + "GSM738873_C3", + "GSM738874_C4" + ], + "scrm-D_whole_seedling_at_5_dpg": [ + "GSM738881_R2", + "GSM738882_R3", + "GSM738883_R4" + ] + } + }, + "LER1_Grotewold_082509;LER2_Grotewold_082509": { + "controls": [ + "LER1_Grotewold_082509", + "LER2_Grotewold_082509" + ], + "treatments": { + "Arabidopsis_green_tissue_wild_type_L._er_": [ + "LER1_Grotewold_082509", + "LER2_Grotewold_082509" + ], + "Arabidopsis_green_tissue_gl3_egl3_": [ + "GL3_1_Grotewold_082509", + "GL3_2_Grotewold_082509" + ] + } + }, + "Ler1_Grotewold_070109;LER2_Grotewold_070909": { + "controls": [ + "Ler1_Grotewold_070109", + "LER2_Grotewold_070909" + ], + "treatments": { + "Arabidopsis_wild_type_L._er": [ + "Ler1_Grotewold_070109", + "LER2_Grotewold_070909" + ], + "Arabidopsis_ttg2": [ + "TTG2_1_Grotewold_070909", + "TTG2_2_Grotewold_070909" + ] + } + } + } + }, + "Embryo": { + "database": "embryo", + "view_name": "Embryo", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Bent_cotyledon": [ + "bc_1", + "bc_2", + "bc_3" + ], + "Early_heart": [ + "eh_1", + "eh_2", + "eh_3" + ], + "Early_torpedo": [ + "et_1", + "et_2", + "et_3" + ], + "Globular": [ + "gl_1", + "gl_2", + "gl_3" + ], + "Late_heart": [ + "lh_1", + "lh_2", + "lh_3" + ], + "Late_torpedo": [ + "lt_1", + "lt_2", + "lt_3" + ], + "Mature_green": [ + "mg_1", + "mg_2", + "mg_3" + ], + "8-cell/16-cell": [ + "pg_1", + "pg_2", + "pg_3" + ] + } + } + } + }, + "Germination": { + "database": "germination", + "view_name": "Germination", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Twelve_Hours_S": [ + "12hS_1", + "12hS_2", + "12hS_3" + ], + "Zero_Hours": [ + "0h_1", + "0h_2", + "0h_3" + ], + "One_Hour_S": [ + "1hS_1", + "1hS_2", + "1hS_3" + ], + "Harvest": [ + "harvest_1", + "harvest_2", + "harvest_3" + ], + "Fourty_Eight_Hours_S": [ + "48hS_1", + "48hS_2", + "48hS_3" + ], + "Fourty_Eight_Hours_SL": [ + "48hSL_1", + "48hSL_2", + "48hSL_3" + ], + "Twelve_Hours_SL": [ + "12hSL_1", + "12hSL_2", + "12hSL_3" + ], + "One_Hour_SL": [ + "1hSL_1", + "1hSL_2", + "1hSL_3" + ], + "Six_Hours_SL": [ + "6hSL_1", + "6hSL_2", + "6hSL_3" + ], + "Twenty_Four_SL": [ + "24hSL_1", + "24hSL_2", + "24hSL_3" + ] + } + } + } + }, + "Guard_Cell": { + "database": "guard_cell", + "view_name": "Guard_Cell", + "groups": { + "GSM486895;GSM486896;GSM486897": { + "controls": [ + "GSM486895", + "GSM486896", + "GSM486897" + ], + "treatments": { + "agb1_guard_cells,_no_ABA": [ + "GSM486895", + "GSM486896", + "GSM486897" + ], + "agb1_guard_cells,_plus_50_uM_ABA": [ + "GSM486907", + "GSM486908", + "GSM486909" + ] + } + }, + "GSM486892;GSM486893;GSM486894": { + "controls": [ + "GSM486892", + "GSM486893", + "GSM486894" + ], + "treatments": { + "WT_Col-0_guard_cells,_no_ABA": [ + "GSM486892", + "GSM486893", + "GSM486894" + ], + "WT_Col-0_guard_cells,_plus_50_uM_ABA": [ + "GSM486904", + "GSM486905", + "GSM486906" + ] + } + }, + "GSM486916;GSM486917;GSM486918": { + "controls": [ + "GSM486916", + "GSM486917", + "GSM486918" + ], + "treatments": { + "WT_Col-0_leaf,_plus_50_uM_ABA": [ + "GSM486928", + "GSM486929", + "GSM486930" + ], + "WT_Col-0_leaf,_no_ABA": [ + "GSM486916", + "GSM486917", + "GSM486918" + ] + } + }, + "GSM738872_C2;GSM738873_C3;GSM738874_C4": { + "controls": [ + "GSM738872_C2", + "GSM738873_C3", + "GSM738874_C4" + ], + "treatments": { + "Col-0_WT_whole_seedling_at_5_dpg": [ + "GSM738872_C2", + "GSM738873_C3", + "GSM738874_C4" + ], + "scrm-D_mute_whole_seedling_at_5_dpg": [ + "GSM738878_M2", + "GSM738879_M3", + "GSM738880_M4" + ], + "spch_whole_seedling_at_5_dpg": [ + "GSM738875_S2", + "GSM738876_S3", + "GSM738877_S4" + ], + "scrm-D_whole_seedling_at_5_dpg": [ + "GSM738881_R2", + "GSM738882_R3", + "GSM738883_R4" + ] + } + }, + "JS85;JS33": { + "controls": [ + "JS85", + "JS33" + ], + "treatments": { + "Guard_cells,_with_100_uM_ABA": [ + "JS86", + "JS34" + ], + "Guard_cells,_no_ABA": [ + "JS85", + "JS33" + ] + } + }, + "GSM571891;GSM571893;GSM571895": { + "controls": [ + "GSM571891", + "GSM571893", + "GSM571895" + ], + "treatments": { + "Suspension_cell_culture,_plus_50_uM_ABA": [ + "GSM571892", + "GSM571894", + "GSM571896" + ], + "Suspension_cell_culture,_plus_5_mM_DMTU": [ + "GSM604752", + "GSM604753", + "GSM604754" + ], + "Suspension_cell_culture,_control": [ + "GSM571891", + "GSM571893", + "GSM571895" + ], + "Suspension_cell_culture,_plus_50_uM_ABA_and_5_mM_DMTU": [ + "GSM604755", + "GSM604751", + "GSM604750" + ] + } + }, + "GSM486919;GSM486920;GSM486921": { + "controls": [ + "GSM486919", + "GSM486920", + "GSM486921" + ], + "treatments": { + "agb1_leaf,_plus_50_uM_ABA": [ + "GSM486931", + "GSM486932", + "GSM486933" + ], + "agb1_leaf,_no_ABA": [ + "GSM486919", + "GSM486920", + "GSM486921" + ] + } + }, + "JS87": { + "controls": [ + "JS87" + ], + "treatments": { + "Mesophyll_cells,_with_100uM_ABA,_no_cordycepin_nor_actinomycin": [ + "JS88" + ], + "Mesophyll_cells,_no_ABA,_no_cordycepin_nor_actinomycin": [ + "JS87" + ] + } + }, + "GSM486922;GSM486923;GSM486924": { + "controls": [ + "GSM486922", + "GSM486923", + "GSM486924" + ], + "treatments": { + "gpa1_leaf,_no_ABA": [ + "GSM486922", + "GSM486923", + "GSM486924" + ], + "gpa1_leaf,_plus_50_uM_ABA": [ + "GSM486934", + "GSM486935", + "GSM486936" + ] + } + }, + "JS33": { + "controls": [ + "JS33" + ], + "treatments": { + "Guard_cells,_no_ABA,_cordycepin_and_actinomycin_added_during_protoplasting": [ + "JS33" + ], + "Guard_cells,_with_100uM_ABA,_cordycepin_and_actinomycin_added_during_protoplasting": [ + "JS34" + ] + } + }, + "GSM486898;GSM486899;GSM486900": { + "controls": [ + "GSM486898", + "GSM486899", + "GSM486900" + ], + "treatments": { + "gpa1_guard_cells,_no_ABA": [ + "GSM486898", + "GSM486899", + "GSM486900" + ], + "gpa1_guard_cells,_plus_50_uM_ABA": [ + "GSM486910", + "GSM486911", + "GSM486912" + ] + } + }, + "GSM486925;GSM486926;GSM486927": { + "controls": [ + "GSM486925", + "GSM486926", + "GSM486927" + ], + "treatments": { + "agb1_gpa1_leaf,_plus_50_uM_ABA": [ + "GSM486937", + "GSM486938", + "GSM486939" + ], + "agb1_gpa1_leaf,_no_ABA": [ + "GSM486925", + "GSM486926", + "GSM486927" + ] + } + }, + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "ML1:_Expression_data_from_epidermal_cells_isolated_using_a_ML1p::YFP-RCI2A_marker": [ + "GSM1420940_ML1Y_3", + "GSM1420939_ML1Y_2", + "GSM1420938_ML1Y_1" + ], + "FGF:_Expression_data_from_young_guard_cells_isolated_using_a_FAMAp::GFP-FAMA_marker": [ + "GSM1420949_FGF_3", + "GSM1420948_FGF_2", + "GSM1420947_FGF_1" + ], + "E1728G:_Expression_data_from_mature_guard_cells_isolated_using_a_E1728::GFP_marker": [ + "GSM1420952_E1728G_3", + "GSM1420951_E1728G_2", + "GSM1420950_E1728G_1" + ], + "SSY:_Expression_data_from_guard_cell_initials_isolated_with_a_SPCHp::SPCH-YFP_marker": [ + "GSM1420943_SSY_3", + "GSM1420942_SSY_2", + "GSM1420941_SSY_1" + ], + "MG:_Expression_data_from_committed_guard_cell_meristemoids_isolated_with_a_MUTEp::nucGFP_marker": [ + "GSM1420946_MG_3", + "GSM1420945_MG_2", + "GSM1420944_MG_1" + ] + } + }, + "JS87;JS35": { + "controls": [ + "JS87", + "JS35" + ], + "treatments": { + "Mesophyll_cells,_with_100_uM_ABA": [ + "JS88", + "JS36" + ], + "Mesophyll_cells,_no_ABA": [ + "JS87", + "JS35" + ] + } + }, + "JS85": { + "controls": [ + "JS85" + ], + "treatments": { + "Mesophyll_cells,_with_100uM_ABA,_cordycepin_and_actinomycin_added_during_protoplasting": [ + "JS36" + ], + "Guard_cells,_no_ABA,_no_cordycepin_nor_actinomycin": [ + "JS85" + ], + "Guard_cells,_with_100uM_ABA,_no_cordycepin_nor_actinomycin": [ + "JS86" + ], + "Mesophyll_cells,_no_ABA,_cordycepin_and_actinomycin_added_during_protoplasting": [ + "JS35" + ] + } + }, + "GSM486901;GSM486902;GSM486903": { + "controls": [ + "GSM486901", + "GSM486902", + "GSM486903" + ], + "treatments": { + "agb1_gpa1_guard_cells,_plus_50_uM_ABA": [ + "GSM486913", + "GSM486914", + "GSM486915" + ], + "agb1_gpa1_guard_cells,_no_ABA": [ + "GSM486901", + "GSM486902", + "GSM486903" + ] + } + } + } + }, + "Gynoecium": { + "database": "gynoecium", + "view_name": "Gynoecium", + "groups": { + "Col-0_CMM_R1;Col-0_CMM_R2;Col-0_CMM_R3": { + "controls": [ + "Col-0_CMM_R1", + "Col-0_CMM_R2", + "Col-0_CMM_R3" + ], + "treatments": { + "Col-0_Stage_7_CMM": [ + "Col-0_CMM_R1", + "Col-0_CMM_R2", + "Col-0_CMM_R3" + ], + "spt-12_Stage_7_CMM": [ + "spt-12_CMM_R1", + "spt-12_CMM_R2", + "spt-12_CMM_R3" + ] + } + }, + "Col-0_SEP_R1;Col-0_SEP_R2;Col-0_SEP_R3": { + "controls": [ + "Col-0_SEP_R1", + "Col-0_SEP_R2", + "Col-0_SEP_R3" + ], + "treatments": { + "Col-0_Stage_10_SEP": [ + "Col-0_SEP_R1", + "Col-0_SEP_R2", + "Col-0_SEP_R3" + ], + "spt-12_Stage_10_SEP": [ + "spt-12_SEP_R1", + "spt-12_SEP_R2", + "spt-12_SEP_R3" + ] + } + }, + "Col-0_PC_R1;Col-0_PC_R2;Col-0_PC_R3": { + "controls": [ + "Col-0_PC_R1", + "Col-0_PC_R2", + "Col-0_PC_R3" + ], + "treatments": { + "spt-12_Stage_7_PC": [ + "spt-12_PC_R1", + "spt-12_PC_R2", + "spt-12_PC_R3" + ], + "Col-0_Stage_7_PC": [ + "Col-0_PC_R1", + "Col-0_PC_R2", + "Col-0_PC_R3" + ] + } + }, + "Col-0_VV_R1;Col-0_VV_R2;Col-0_VV_R3": { + "controls": [ + "Col-0_VV_R1", + "Col-0_VV_R2", + "Col-0_VV_R3" + ], + "treatments": { + "Col-0_Stage_10_VV": [ + "Col-0_VV_R1", + "Col-0_VV_R2", + "Col-0_VV_R3" + ], + "spt-12_Stage_10_VV": [ + "spt-12_VV_R1", + "spt-12_VV_R2", + "spt-12_VV_R3" + ] + } + } + } + }, + "Hormone": { + "database": "atgenexp_hormone", + "view_name": "Hormone", + "groups": { + "ACC_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "ACC_Treated_at_30_Minutes": [ + "RIKEN-GODA7A", + "RIKEN-GODA7B" + ] + } + }, + "ACC_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "ACC_Treated_at_1_Hour": [ + "RIKEN-GODA15A", + "RIKEN-GODA15B" + ] + } + }, + "ACC_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "ACC_Treated_at_3_Hours": [ + "RIKEN-GODA23A", + "RIKEN-GODA23B" + ] + } + }, + "Zeatin_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "Zeatin_Treated_at_30_Minutes": [ + "RIKEN-GODA3A", + "RIKEN-GODA3B" + ] + } + }, + "Zeatin_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "Zeatin_Treated_at_1_Hour": [ + "RIKEN-GODA11A", + "RIKEN-GODA11B" + ] + } + }, + "Zeatin_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "Zeatin_Treated_at_3_Hours": [ + "RIKEN-GODA19A", + "RIKEN-GODA19B" + ] + } + }, + "IAA_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "IAA_Treated_at_30_Minutes": [ + "RIKEN-GODA2A", + "RIKEN-GODA2B" + ] + } + }, + "IAA_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "IAA_Treated_at_1_Hour": [ + "RIKEN-GODA10A", + "RIKEN-GODA10B" + ] + } + }, + "IAA_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "IAA_Treated_at_3_Hours": [ + "RIKEN-GODA18A", + "RIKEN-GODA18B" + ] + } + }, + "ABA_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "ABA_Treated_at_30_Minutes": [ + "RIKEN-GODA5A", + "RIKEN-GODA5B" + ] + } + }, + "ABA_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "ABA_Treated_at_1_Hour": [ + "RIKEN-GODA13A", + "RIKEN-GODA13B" + ] + } + }, + "ABA_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "ABA_Treated_at_3_Hours": [ + "RIKEN-GODA21A", + "RIKEN-GODA21B" + ] + } + }, + "Methyl_Jasmonate_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "MJ_Treated_at_30_Minutes": [ + "RIKEN-GODA6A", + "RIKEN-GODA6B" + ] + } + }, + "Methyl_Jasmonate_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "MJ_Treated_at_1_Hour": [ + "RIKEN-GODA14A", + "RIKEN-GODA14B" + ] + } + }, + "Methyl_Jasmonate_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "MJ_Treated_at_3_Hours": [ + "RIKEN-GODA22A", + "RIKEN-GODA22B" + ] + } + }, + "GA-3_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "GA-3_Treated_at_30_Minutes": [ + "RIKEN-GODA4A", + "RIKEN-GODA4B" + ] + } + }, + "GA-3_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "GA-3_Treated_at_1_Hour": [ + "RIKEN-GODA12A", + "RIKEN-GODA12B" + ] + } + }, + "GA-3_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "GA-3_Treated_at_3_Hours": [ + "RIKEN-GODA20A", + "RIKEN-GODA20B" + ] + } + }, + "GA-3_Mutant_at_30_Minutes": { + "controls": [ + "RIKEN-GODA25A", + "RIKEN-GODA25B" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA25A", + "RIKEN-GODA25B" + ], + "GA-3_Treated_Mutant_at_30_Minutes": [ + "RIKEN-GODA26A", + "RIKEN-GODA26B" + ] + } + }, + "GA-3_Mutant_at_1_Hour": { + "controls": [ + "RIKEN-GODA27A", + "RIKEN-GODA27B " + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA27A", + "RIKEN-GODA27B" + ], + "GA-3_Treated_Mutant_at_1_Hour": [ + "RIKEN-GODA28A", + "RIKEN-GODA28B" + ] + } + }, + "GA-3_Mutant_at_3_Hours": { + "controls": [ + "RIKEN-GODA29A", + "RIKEN-GODA29B" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA29A", + "RIKEN-GODA29B" + ], + "GA-3_Treated_Mutant_at_3_Hours": [ + "RIKEN-GODA30A", + "RIKEN-GODA30B" + ] + } + }, + "Brassinolide_at_30_Minutes": { + "controls": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA1AA", + "RIKEN-GODA1BB" + ], + "BL_Treated_at_30_Minutes": [ + "RIKEN-GODA8A", + "RIKEN-GODA8B" + ] + } + }, + "Brassinolide_at_1_Hour": { + "controls": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "treatments": { + "BL_Control_at_1_Hour": [ + "RIKEN-GODA9AA", + "RIKEN-GODA9BA" + ], + "Treated_at_1_Hour": [ + "RIKEN-GODA16A", + "RIKEN-GODA16B" + ] + } + }, + "Brassinolide_at_3_Hours": { + "controls": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA17AA", + "RIKEN-GODA17BA" + ], + "BL_Treated_at_3_Hours": [ + "RIKEN-GODA24A", + "RIKEN-GODA24B" + ] + } + }, + "Brassinolide_Mutant_at_30_Minutes": { + "controls": [ + "RIKEN-GODA31A", + "RIKEN-GODA31B" + ], + "treatments": { + "Control_at_30_Minutes": [ + "RIKEN-GODA31A", + "RIKEN-GODA31B" + ], + "BL_Treated_Mutant_at_30_Minutes": [ + "RIKEN-GODA32A", + "RIKEN-GODA32B" + ] + } + }, + "Brassinolide_Mutant_at_1_Hour": { + "controls": [ + "RIKEN-GODA33A", + "RIKEN-GODA33B" + ], + "treatments": { + "Control_at_1_Hour": [ + "RIKEN-GODA33A", + "RIKEN-GODA33B" + ], + "BL_Treated_Mutant_at_1_Hour": [ + "RIKEN-GODA34A", + "RIKEN-GODA34B" + ] + } + }, + "Brassinolide_Mutant_at_3_Hours": { + "controls": [ + "RIKEN-GODA35A", + "RIKEN-GODA35B" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-GODA35A", + "RIKEN-GODA35B" + ], + "BL_Treated_Mutant_at_3_Hours": [ + "RIKEN-GODA36A", + "RIKEN-GODA36B" + ] + } + }, + "Brassinosteroids": { + "controls": [ + "RIKEN-GODA1A-6", + "RIKEN-GODA1B-6" + ], + "treatments": { + "Control": [ + "RIKEN-GODA1A-6", + "RIKEN-GODA1B-6" + ], + "campestanol_Treated": [ + "RIKEN-GODA2A-6", + "RIKEN-GODA2B-6" + ], + "6-deoxocathasterone_Treated": [ + "RIKEN-GODA3A-6", + "RIKEN-GODA3B-6" + ], + "cathasterone_Treated": [ + "RIKEN-GODA4A-6", + "RIKEN-GODA4B-6" + ], + "6-deoxoteasterone_Treated": [ + "RIKEN-GODA5A-6", + "RIKEN-GODA5B-6" + ], + "teasterone_Treated": [ + "RIKEN-GODA6A-6", + "RIKEN-GODA6B-6" + ], + "3-dehydro-6-deoxoteasterone_Treated": [ + "RIKEN-GODA7A-6", + "RIKEN-GODA7B-6" + ], + "3-dehydroteasterone_Treated": [ + "RIKEN-GODA8A-6", + "RIKEN-GODA8B-6" + ], + "-deoxotyphasterol_Treated": [ + "RIKEN-GODA9A-6", + "RIKEN-GODA9B-6" + ], + "typhasterol_Treated": [ + "RIKEN-GODA10A-6", + "RIKEN-GODA10B-6" + ], + "6-deoxocastasterone_Treated": [ + "RIKEN-GODA11A-6", + "RIKEN-GODA11B-6" + ], + "castasterone_Treated": [ + "RIKEN-GODA12A-6", + "RIKEN-GODA12B-6" + ], + "brassinolide_Treated": [ + "RIKEN-GODA13A-6", + "RIKEN-GODA13B-6" + ] + } + }, + "Cytokinin_on_Wild-Type": { + "controls": [ + "NO.10", + "NO.11", + "NO.12" + ], + "treatments": { + "Control_Wild-Type": [ + "NO.10", + "NO.11", + "NO.12" + ], + "t-zeatin_Treated_Wild-Type": [ + "NO.19-2", + "NO.20-2", + "NO.21-2" + ] + } + }, + "Cytokinin_on_ARR22_Overexpressed": { + "controls": [ + "NO.28", + "NO.29", + "NO.30" + ], + "treatments": { + "Control_ARR22_Overexpressed": [ + "NO.28", + "NO.29", + "NO.30" + ], + "t-zeatin_Treated_ARR22_Overexpressed": [ + "NO.31", + "NO.32", + "NO.33" + ] + } + }, + "ABA_during_Seed_Imbibtion": { + "controls": [ + "RIKEN-NAKABAYASHI2A", + "RIKEN-NAKABAYASHI2B" + ], + "treatments": { + "No_Treatment": [ + "RIKEN-NAKABAYASHI1A", + "RIKEN-NAKABAYASHI1B" + ], + "Treated_with_Water": [ + "RIKEN-NAKABAYASHI2A", + "RIKEN-NAKABAYASHI2B" + ], + "Treated_with_3uM_ABA": [ + "RIKEN-NAKABAYASHI3A", + "RIKEN-NAKABAYASHI5B" + ], + "Treated_with_30uM_ABA": [ + "RIKEN-NAKABAYASHI4A", + "RIKEN-NAKABAYASHI4B" + ] + } + }, + "Giberellin_at_3_Hours": { + "controls": [ + "RIKEN-LI1A", + "RIKEN-LI1B" + ], + "treatments": { + "Control_at_3_Hours": [ + "RIKEN-LI1A", + "RIKEN-LI1B" + ], + "Giberellin_Treated_at_3_Hours": [ + "RIKEN-LI4A", + "RIKEN-LI4B" + ] + } + }, + "Giberellin_at_6_Hours": { + "controls": [ + "RIKEN-LI2A", + "RIKEN-LI2B" + ], + "treatments": { + "Control_at_6_Hours": [ + "RIKEN-LI2A", + "RIKEN-LI2B" + ], + "Giberellin_Treated_at_6_Hours": [ + "RIKEN-LI5A", + "RIKEN-LI5B" + ] + } + }, + "Giberellin_at_9_Hours": { + "controls": [ + "RIKEN-LI3A", + "RIKEN-LI3B" + ], + "treatments": { + "Control_at_9_Hours": [ + "RIKEN-LI3A", + "RIKEN-LI3B" + ], + "Giberellin_Treated_at_9_Hours": [ + "RIKEN-LI6A", + "RIKEN-LI6B" + ] + } + } + } + }, + "Klepikova_Atlas": { + "database": "klepikova", + "view_name": "Klepikova_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Silique_8": [ + "SRR3581717", + "SRR3581883" + ], + "Stigmatic_tissue": [ + "SRR3581728", + "SRR3581890" + ], + "Pod_of_the_senescent_silique_1": [ + "SRR3581736", + "SRR3581897" + ], + "Anthers_of_the_young_flower": [ + "SRR3581691", + "SRR3581857" + ], + "Dry_Seeds": [ + "SRR3581731", + "SRR3581892" + ], + "Silique_2": [ + "SRR3581708", + "SRR3581874" + ], + "Silique_4": [ + "SRR3581711", + "SRR3581877" + ], + "Silique_6": [ + "SRR3581714", + "SRR3581880" + ], + "Young_seeds_3": [ + "SRR3581721", + "SRR3581886" + ], + "Young_seeds_2": [ + "SRR3581720", + "SRR3581885" + ], + "Young_seeds_1": [ + "SRR3581719", + "SRR3581884" + ], + "Leaf_Lamina_of_the_mature_leaf": [ + "SRR3581680", + "SRR3581846" + ], + "Flowers_15-18": [ + "SRR3581701", + "SRR3581867" + ], + "Young_seeds_5": [ + "SRR3581726", + "SRR3581888" + ], + "Young_seeds_4": [ + "SRR3581724", + "SRR3581887" + ], + "Seeds_7": [ + "SRR3581715", + "SRR3581881" + ], + "Germinating_seeds_2": [ + "SRR3581733", + "SRR3581894" + ], + "Leaf_Vein_of_the_senescent_leaf": [ + "SRR3581683", + "SRR3581849" + ], + "Carpel_of_the_6th_and_7th_flowers": [ + "SRR3581730", + "SRR3581891" + ], + "Ovules_from_the_6th_and_7th_flowers": [ + "SRR3581727", + "SRR3581889" + ], + "Flower_5": [ + "SRR3581697", + "SRR3581863" + ], + "Internode": [ + "SRR3581705", + "SRR3581871" + ], + "Leaf_Petiole,_intermediate_1": [ + "SRR3581499", + "SRR3581839" + ], + "Root_Apex": [ + "SRR3581352", + "SRR3581835" + ], + "Leaf_Petiole,_intermediate_2": [ + "SRR3581639", + "SRR3581841" + ], + "Seeds_from_the_senescent_silique_1": [ + "SRR3581735", + "SRR3581896" + ], + "Flower_4": [ + "SRR3581696", + "SRR3581862" + ], + "Flower_1": [ + "SRR3581693", + "SRR3581859" + ], + "Leaf_Vein,_intermediate_2": [ + "SRR3581672", + "SRR3581842" + ], + "Flower_3": [ + "SRR3581695", + "SRR3581861" + ], + "Flower_2": [ + "SRR3581694", + "SRR3581860" + ], + "Flowers_9-11": [ + "SRR3581699", + "SRR3581865" + ], + "Leaf_Vein_of_the_mature_leaf": [ + "SRR3581679", + "SRR3581845" + ], + "Leaf_Petiole_of_the_senescent_leaf": [ + "SRR3581682", + "SRR3581848" + ], + "Leaf_Petiole_of_the_mature_leaf": [ + "SRR3581678", + "SRR3581844" + ], + "Seedling_Root": [ + "SRR3581347", + "SRR3581834" + ], + "Germinating_seeds_3": [ + "SRR3581734", + "SRR3581895" + ], + "Carpels_of_the_young_flower": [ + "SRR3581690", + "SRR3581856" + ], + "Germinating_seeds_1": [ + "SRR3581732", + "SRR3581893" + ], + "Pod_of_the_silique_5": [ + "SRR3581713", + "SRR3581879" + ], + "Pod_of_the_silique_7": [ + "SRR3581716", + "SRR3581882" + ], + "Pod_of_the_silique_1": [ + "SRR3581707", + "SRR3581873" + ], + "Senescent_internode": [ + "SRR3581738", + "SRR3581899" + ], + "Pod_of_the_silique_3": [ + "SRR3581710", + "SRR3581876" + ], + "Seeds_1": [ + "SRR3581706", + "SRR3581872" + ], + "Seeds_3": [ + "SRR3581709", + "SRR3581875" + ], + "Seeds_5": [ + "SRR3581712", + "SRR3581878" + ], + "Leaf,_mature": [ + "SRR3581681", + "SRR3581847" + ], + "Seedling_Meristem": [ + "SRR3581346", + "SRR3581831" + ], + "Seedling_Cotyledons": [ + "SRR3581345", + "SRR3581833" + ], + "Flowers_19_and_following": [ + "SRR3581702", + "SRR3581868" + ], + "Seedling_Hypocotyl": [ + "SRR3581336", + "SRR3581740" + ], + "Pedicel": [ + "SRR3581703", + "SRR3581869" + ], + "Leaf_Lamina,_intermediate_1": [ + "SRR3581591", + "SRR3581840" + ], + "Leaf_Lamina,_intermediate_2": [ + "SRR3581676", + "SRR3581843" + ], + "Axis_of_inflorescence": [ + "SRR3581704", + "SRR3581870" + ], + "Flowers_12-14": [ + "SRR3581700", + "SRR3581866" + ], + "Senescent_silique_2": [ + "SRR3581737", + "SRR3581898" + ], + "Sepals_of_the_young_flower": [ + "SRR3581692", + "SRR3581858" + ], + "Root_without_apex": [ + "SRR3581356", + "SRR3581836" + ], + "Leaf_Petiole_of_the_young_leaf": [ + "SRR3581383", + "SRR3581837" + ], + "Leaf_Lamina_of_the_young_leaf": [ + "SRR3581388", + "SRR3581838" + ], + "Flowers_6-8": [ + "SRR3581698", + "SRR3581864" + ], + "Sepals_of_the_mature_flower": [ + "SRR3581689", + "SRR3581855" + ], + "Petals_of_the_mature_flower": [ + "SRR3581688", + "SRR3581854" + ], + "Stamen_filaments_of_the_mature_flower": [ + "SRR3581687", + "SRR3581853" + ], + "Opened_anthers": [ + "SRR3581684", + "SRR3581850" + ], + "Anthers_of_the_mature_flower_(before_opening)": [ + "SRR3581686", + "SRR3581852" + ], + "Carpels_of_the_mature_flower_(before_pollination)": [ + "SRR3581685", + "SRR3581851" + ] + } + } + } + }, + "Lateral_Root_Initiation": { + "database": "lateral_root_initiation", + "view_name": "Lateral_Root_Initiation", + "groups": { + "0h_1.cel;0h_2.cel;0h_3.CEL": { + "controls": [ + "0h_1.cel", + "0h_2.cel", + "0h_3.CEL" + ], + "treatments": { + "De_Smet_J0121_2h_NAA": [ + "2h_1.cel", + "2h_2.cel" + ], + "De_Smet_J0121_NPA": [ + "0h_1.cel", + "0h_2.cel", + "0h_3.CEL" + ], + "De_Smet_J0121_6h_NAA": [ + "6h_1.cel", + "6h_2.cel" + ] + } + }, + "hyb4643.CEL;hyb4648.CEL;hyb4653.CEL": { + "controls": [ + "hyb4643.CEL", + "hyb4648.CEL", + "hyb4653.CEL" + ], + "treatments": { + "De_Rybel_Col0_6h_Naxillin": [ + "hyb4647.CEL", + "hyb4652.CEL", + "hyb4657.CEL" + ], + "De_Rybel_Col0_2h_Naxillin": [ + "hyb4645.CEL", + "hyb4650.CEL", + "hyb4655.CEL" + ], + "De_Rybel_Col0_6h_NAA": [ + "hyb4646.CEL", + "hyb4651.CEL", + "hyb4656.CEL" + ], + "De_Rybel_Col0_2h_NAA": [ + "hyb4644.CEL", + "hyb4649.CEL", + "hyb4654.CEL" + ], + "De_Rybel_Col0_NPA": [ + "hyb4643.CEL", + "hyb4648.CEL", + "hyb4653.CEL" + ] + } + }, + "GSM75516.CEL;GSM75519.CEL": { + "controls": [ + "GSM75516.CEL", + "GSM75519.CEL" + ], + "treatments": { + "Vanneste_slr-1_2h_NAA": [ + "GSM75517.CEL", + "GSM75520.CEL" + ], + "Vanneste_slr-1_NPA": [ + "GSM75516.CEL", + "GSM75519.CEL" + ], + "Vanneste_slr-1_6h_NAA": [ + "GSM75518.CEL", + "GSM75521.CEL" + ] + } + }, + "GSM75508.CEL;GSM75512.CEL": { + "controls": [ + "GSM75508.CEL", + "GSM75512.CEL" + ], + "treatments": { + "Vanneste_Col0_2h_NAA": [ + "GSM75509.CEL", + "GSM75513.CEL" + ], + "Vanneste_Col0_6h_NAA": [ + "GSM75510.CEL", + "GSM75514.CEL" + ], + "Vanneste_Col0_NPA": [ + "GSM75508.CEL", + "GSM75512.CEL" + ] + } + }, + "GSM9571.cel;GSM9572.cel;GSM9573.cel": { + "controls": [ + "GSM9571.cel", + "GSM9572.cel", + "GSM9573.cel" + ], + "treatments": { + "Okushima_Col": [ + "GSM9571.cel", + "GSM9572.cel", + "GSM9573.cel" + ], + "Okushima_Col_IAA": [ + "GSM9574.cel", + "GSM9575.cel", + "GSM9576.cel" + ] + } + }, + "GSM9583.cel;GSM9584.cel;GSM9585.cel": { + "controls": [ + "GSM9583.cel", + "GSM9584.cel", + "GSM9585.cel" + ], + "treatments": { + "Okushima_arf19-1": [ + "GSM9583.cel", + "GSM9584.cel", + "GSM9585.cel" + ], + "Okushima_arf19-1_IAA": [ + "GSM9586.cel", + "GSM9587.cel", + "GSM9588.cel" + ] + } + }, + "GSM9577.cel;GSM9578.cel;GSM9579.CEL": { + "controls": [ + "GSM9577.cel", + "GSM9578.cel", + "GSM9579.CEL" + ], + "treatments": { + "Okushima_nph4-1_IAA": [ + "GSM9580.cel", + "GSM9581.cel", + "GSM9582.cel" + ], + "Okushima_nph4-1": [ + "GSM9577.cel", + "GSM9578.cel", + "GSM9579.CEL" + ] + } + }, + "GSM9589.cel;GSM9590.cel;GSM9591.cel": { + "controls": [ + "GSM9589.cel", + "GSM9590.cel", + "GSM9591.cel" + ], + "treatments": { + "Okushima_nph4-1arf19-1_IAA": [ + "GSM9592.cel", + "GSM9593.cel", + "GSM9594.cel" + ], + "Okushima_nph4-1arf19-1": [ + "GSM9589.cel", + "GSM9590.cel", + "GSM9591.cel" + ] + } + }, + "hyb12690.CEL;hyb12694.CEL;hyb12698.CEL": { + "controls": [ + "hyb12690.CEL", + "hyb12694.CEL", + "hyb12698.CEL" + ], + "treatments": { + "Xuan_ibr3_IBA": [ + "hyb12692.CEL", + "hyb12696.CEL", + "hyb12700.CEL" + ], + "Xuan_ibr3_DMSO": [ + "hyb12690.CEL", + "hyb12694.CEL", + "hyb12698.CEL" + ] + } + }, + "hyb12689.CEL;hyb12693.CEL;hyb12697.CEL": { + "controls": [ + "hyb12689.CEL", + "hyb12693.CEL", + "hyb12697.CEL" + ], + "treatments": { + "Xuan_Col_DMSO": [ + "hyb12689.CEL", + "hyb12693.CEL", + "hyb12697.CEL" + ], + "Xuan_Col_IBA": [ + "hyb12691.CEL", + "hyb12695.CEL", + "hyb12699.CEL" + ] + } + }, + "GSM1030558;GSM1030574;GSM1030590": { + "controls": [ + "GSM1030558", + "GSM1030574", + "GSM1030590" + ], + "treatments": { + "Lewis_control_0h": [ + "GSM1030558", + "GSM1030574", + "GSM1030590" + ], + "Lewis_IAA_0h": [ + "GSM1030566", + "GSM1030582", + "GSM1030598" + ] + } + }, + "GSM1030559;GSM1030575;GSM1030591": { + "controls": [ + "GSM1030559", + "GSM1030575", + "GSM1030591" + ], + "treatments": { + "Lewis_control_0.5h": [ + "GSM1030559", + "GSM1030575", + "GSM1030591" + ], + "Lewis_IAA_0.5h": [ + "GSM1030567", + "GSM1030583", + "GSM1030599" + ] + } + }, + "GSM1030560;GSM1030576;GSM1030592": { + "controls": [ + "GSM1030560", + "GSM1030576", + "GSM1030592" + ], + "treatments": { + "Lewis_control_1h": [ + "GSM1030560", + "GSM1030576", + "GSM1030592" + ], + "Lewis_IAA_1h": [ + "GSM1030568", + "GSM1030584", + "GSM1030600" + ] + } + }, + "GSM1030561;GSM1030577;GSM1030593": { + "controls": [ + "GSM1030561", + "GSM1030577", + "GSM1030593" + ], + "treatments": { + "Lewis_control_2h": [ + "GSM1030561", + "GSM1030577", + "GSM1030593" + ], + "Lewis_IAA_2h": [ + "GSM1030569", + "GSM1030585", + "GSM1030601" + ] + } + }, + "GSM1030562;GSM1030578;GSM1030594": { + "controls": [ + "GSM1030562", + "GSM1030578", + "GSM1030594" + ], + "treatments": { + "Lewis_control_4h": [ + "GSM1030562", + "GSM1030578", + "GSM1030594" + ], + "Lewis_IAA_4h": [ + "GSM1030570", + "GSM1030586", + "GSM1030602" + ] + } + }, + "GSM1030563;GSM1030579;GSM1030595": { + "controls": [ + "GSM1030563", + "GSM1030579", + "GSM1030595" + ], + "treatments": { + "Lewis_control_8h": [ + "GSM1030563", + "GSM1030579", + "GSM1030595" + ], + "Lewis_IAA_8h": [ + "GSM1030571", + "GSM1030587", + "GSM1030603" + ] + } + }, + "GSM1030564;GSM1030580;GSM1030596": { + "controls": [ + "GSM1030564", + "GSM1030580", + "GSM1030596" + ], + "treatments": { + "Lewis_control_12h": [ + "GSM1030564", + "GSM1030580", + "GSM1030596" + ], + "Lewis_IAA_12h": [ + "GSM1030572", + "GSM1030588", + "GSM1030604" + ] + } + }, + "GSM1030565;GSM1030581;GSM1030597": { + "controls": [ + "GSM1030565", + "GSM1030581", + "GSM1030597" + ], + "treatments": { + "Lewis_control_24h": [ + "GSM1030565", + "GSM1030581", + "GSM1030597" + ], + "Lewis_IAA_24h": [ + "GSM1030573", + "GSM1030589", + "GSM1030605" + ] + } + }, + "Cortex.0hr.Mean": { + "controls": [ + "Cortex.0hr.Mean" + ], + "treatments": { + "WalkerAndGifford_Cortex_Rhizobium_00h": [ + "Cortex.0hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_01h": [ + "Cortex.Rhizobium.1hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_02h": [ + "Cortex.Rhizobium.2hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_04h": [ + "Cortex.Rhizobium.4hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_06h": [ + "Cortex.Rhizobium.6hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_08h": [ + "Cortex.Rhizobium.8hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_10h": [ + "Cortex.Rhizobium.10hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_12h": [ + "Cortex.Rhizobium.12hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_14h": [ + "Cortex.Rhizobium.14hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_16h": [ + "Cortex.Rhizobium.16hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_20h": [ + "Cortex.Rhizobium.20hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_24h": [ + "Cortex.Rhizobium.24hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_36h": [ + "Cortex.Rhizobium.36hr.Mean" + ], + "WalkerAndGifford_Cortex_Rhizobium_48h": [ + "Cortex.Rhizobium.48hr.Mean" + ] + } + }, + "Pericycle.0hr.Mean": { + "controls": [ + "Pericycle.0hr.Mean" + ], + "treatments": { + "WalkerAndGifford_Pericycle_Rhizobium_00h": [ + "Pericycle.0hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_01h": [ + "Pericycle.Rhizobium.1hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_02h": [ + "Pericycle.Rhizobium.2hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_04h": [ + "Pericycle.Rhizobium.4hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_06h": [ + "Pericycle.Rhizobium.6hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_08h": [ + "Pericycle.Rhizobium.8hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_10h": [ + "Pericycle.Rhizobium.10hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_12h": [ + "Pericycle.Rhizobium.12hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_14h": [ + "Pericycle.Rhizobium.14hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_16h": [ + "Pericycle.Rhizobium.16hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_20h": [ + "Pericycle.Rhizobium.20hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_24h": [ + "Pericycle.Rhizobium.24hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_36h": [ + "Pericycle.Rhizobium.36hr.Mean" + ], + "WalkerAndGifford_Pericycle_Rhizobium_48h": [ + "Pericycle.Rhizobium.48hr.Mean" + ] + } + }, + "Voss_1-1_0h_after-lateral-root-initiation_Rep1;Voss_1-19_0h_after-lateral-root-initiation_Rep2;Voss_1-37_0h_after-lateral-root-initiation_Rep3;Voss_1-55_0h_after-lateral-root-initiation_Rep4": { + "controls": [ + "Voss_1-1_0h_after-lateral-root-initiation_Rep1", + "Voss_1-19_0h_after-lateral-root-initiation_Rep2", + "Voss_1-37_0h_after-lateral-root-initiation_Rep3", + "Voss_1-55_0h_after-lateral-root-initiation_Rep4" + ], + "treatments": { + "VossAndBennet_control_0h": [ + "Voss_1-1_0h_after-lateral-root-initiation_Rep1", + "Voss_1-19_0h_after-lateral-root-initiation_Rep2", + "Voss_1-37_0h_after-lateral-root-initiation_Rep3", + "Voss_1-55_0h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_6h_after_bending": [ + "Voss_1-2_6h_after-lateral-root-initiation_Rep1", + "Voss_1-20_6h_after-lateral-root-initiation_Rep2", + "Voss_1-38_6h_after-lateral-root-initiation_Rep3", + "Voss_1-56_6h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_9h_after_bending": [ + "Voss_1-21_9h_after-lateral-root-initiation_Rep2", + "Voss_1-3_9h_after-lateral-root-initiation_Rep1", + "Voss_1-39_9h_after-lateral-root-initiation_Rep3", + "Voss_1-57_9h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_12h_after_bending": [ + "Voss_1-22_12h_after-lateral-root-initiation_Rep2", + "Voss_1-4_12h_after-lateral-root-initiation_Rep1", + "Voss_1-40_12h_after-lateral-root-initiation_Rep3", + "Voss_1-58_12h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_15h_after_bending": [ + "Voss_1-23_15h_after-lateral-root-initiation_Rep2", + "Voss_1-41_15h_after-lateral-root-initiation_Rep3", + "Voss_1-5_15h_after-lateral-root-initiation_Rep1", + "Voss_1-59_15h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_18h_after_bending": [ + "Voss_1-24_18h_after-lateral-root-initiation_Rep2", + "Voss_1-42_18h_after-lateral-root-initiation_Rep3", + "Voss_1-6_18h_after-lateral-root-initiation_Rep1", + "Voss_1-60_18h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_21h_after_bending": [ + "Voss_1-25_21h_after-lateral-root-initiation_Rep2", + "Voss_1-43_21h_after-lateral-root-initiation_Rep3", + "Voss_1-61_21h_after-lateral-root-initiation_Rep4", + "Voss_1-7_21h_after-lateral-root-initiation_Rep1" + ], + "VossAndBennet_24h_after_bending": [ + "Voss_1-26_24h_after-lateral-root-initiation_Rep2", + "Voss_1-44_24h_after-lateral-root-initiation_Rep3", + "Voss_1-62_24h_after-lateral-root-initiation_Rep4", + "Voss_1-8_24h_after-lateral-root-initiation_Rep1" + ], + "VossAndBennet_27h_after_bending": [ + "Voss_1-27_27h_after-lateral-root-initiation_Rep2", + "Voss_1-45_27h_after-lateral-root-initiation_Rep3", + "Voss_1-63_27h_after-lateral-root-initiation_Rep4", + "Voss_1-9_27h_after-lateral-root-initiation_Rep1" + ], + "VossAndBennet_30h_after_bending": [ + "Voss_1-10_30h_after-lateral-root-initiation_Rep1", + "Voss_1-28_30h_after-lateral-root-initiation_Rep2", + "Voss_1-46_30h_after-lateral-root-initiation_Rep3", + "Voss_1-64_30h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_33h_after_bending": [ + "Voss_1-11_33h_after-lateral-root-initiation_Rep1", + "Voss_1-29_33h_after-lateral-root-initiation_Rep2", + "Voss_1-47_33h_after-lateral-root-initiation_Rep3", + "Voss_1-65_33h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_36h_after_bending": [ + "Voss_1-12_36h_after-lateral-root-initiation_Rep1", + "Voss_1-30_36h_after-lateral-root-initiation_Rep2", + "Voss_1-48_36h_after-lateral-root-initiation_Rep3", + "Voss_1-66_36h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_39h_after_bending": [ + "Voss_1-13_39h_after-lateral-root-initiation_Rep1", + "Voss_1-31_39h_after-lateral-root-initiation_Rep2", + "Voss_1-49_39h_after-lateral-root-initiation_Rep3", + "Voss_1-67_39h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_42h_after_bending": [ + "Voss_1-14_42h_after-lateral-root-initiation_Rep1", + "Voss_1-32_42h_after-lateral-root-initiation_Rep2", + "Voss_1-50_42h_after-lateral-root-initiation_Rep3", + "Voss_1-68_42h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_45h_after_bending": [ + "Voss_1-15_45h_after-lateral-root-initiation_Rep1", + "Voss_1-33_45h_after-lateral-root-initiation_Rep2", + "Voss_1-51_45h_after-lateral-root-initiation_Rep3", + "Voss_1-69_45h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_48h_after_bending": [ + "Voss_1-16_48h_after-lateral-root-initiation_Rep1", + "Voss_1-34_48h_after-lateral-root-initiation_Rep2", + "Voss_1-52_48h_after-lateral-root-initiation_Rep3", + "Voss_1-70_48h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_51h_after_bending": [ + "Voss_1-17_51h_after-lateral-root-initiation_Rep1", + "Voss_1-35_51h_after-lateral-root-initiation_Rep2", + "Voss_1-53_51h_after-lateral-root-initiation_Rep3", + "Voss_1-71_51h_after-lateral-root-initiation_Rep4" + ], + "VossAndBennet_54h_after_bending": [ + "Voss_1-18_54h_after-lateral-root-initiation_Rep1", + "Voss_1-36_54h_after-lateral-root-initiation_Rep2", + "Voss_1-54_54h_after-lateral-root-initiation_Rep3", + "Voss_1-72_54h_after-lateral-root-initiation_Rep4" + ] + } + } + } + }, + "Light_Series": { + "database": "light_series", + "view_name": "Light_Series", + "groups": { + "LLHC_00": { + "controls": [ + "LLHC_00" + ], + "treatments": { + "Continuous_light_with_temperature_cycles,_0h": [ + "LLHC_00" + ], + "Continuous_light_with_temperature_cycles,_4h": [ + "LLHC_04" + ], + "Continuous_light_with_temperature_cycles,_8h": [ + "LLHC_08" + ], + "Continuous_light_with_temperature_cycles,_12h": [ + "LLHC_12" + ], + "Continuous_light_with_temperature_cycles,_16h": [ + "LLHC_16" + ], + "Continuous_light_with_temperature_cycles,_20h": [ + "LLHC_20" + ], + "Continuous_light_with_temperature_cycles,_24h": [ + "LLHC_24" + ], + "Continuous_light_with_temperature_cycles,_28h": [ + "LLHC_28" + ], + "Continuous_light_with_temperature_cycles,_32h": [ + "LLHC_32" + ], + "Continuous_light_with_temperature_cycles,_36h": [ + "LLHC_36" + ], + "Continuous_light_with_temperature_cycles,_40h": [ + "LLHC_40" + ], + "Continuous_light_with_temperature_cycles,_44h": [ + "LLHC_44" + ] + } + }, + "LDHC_00": { + "controls": [ + "LDHC_00" + ], + "treatments": { + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_0h": [ + "LDHC_00" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_4h": [ + "LDHC_04" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_8h": [ + "LDHC_08" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_12h": [ + "LDHC_12" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_16h": [ + "LDHC_16" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_20h": [ + "LDHC_20" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_24h": [ + "LDHC_24" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_28h": [ + "LDHC_28" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_32h": [ + "LDHC_32" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_36h": [ + "LDHC_36" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_40h": [ + "LDHC_40" + ], + "12h_light-dark_cycle_with_concommitant_temperature_cycle,_44h": [ + "LDHC_44" + ] + } + }, + "longday_00": { + "controls": [ + "longday_00" + ], + "treatments": { + "Long_day_grown_plants,_0h": [ + "longday_00" + ], + "Long_day_grown_plants,_4h": [ + "longday_04" + ], + "Long_day_grown_plants,_8h": [ + "longday_08" + ], + "Long_day_grown_plants,_12h": [ + "longday_12" + ], + "Long_day_grown_plants,_16h": [ + "longday_16" + ], + "Long_day_grown_plants,_20h": [ + "longday_20" + ], + "Long_day_grown_plants,_24h": [ + "longday_24" + ], + "Long_day_grown_plants,_28h": [ + "longday_28" + ], + "Long_day_grown_plants,_32h": [ + "longday_32" + ], + "Long_day_grown_plants,_36h": [ + "longday_36" + ], + "Long_day_grown_plants,_40h": [ + "longday_40" + ], + "Long_day_grown_plants,_44h": [ + "longday_44" + ] + } + }, + "shortday_00": { + "controls": [ + "shortday_00" + ], + "treatments": { + "Short_day_grown_plants,_0h": [ + "shortday_00" + ], + "Short_day_grown_plants,_4h": [ + "shortday_04" + ], + "Short_day_grown_plants,_8h": [ + "shortday_08" + ], + "Short_day_grown_plants,_12h": [ + "shortday_12" + ], + "Short_day_grown_plants,_16h": [ + "shortday_16" + ], + "Short_day_grown_plants,_20h": [ + "shortday_20" + ], + "Short_day_grown_plants,_24h": [ + "shortday_24" + ], + "Short_day_grown_plants,_28h": [ + "shortday_28" + ], + "Short_day_grown_plants,_32h": [ + "shortday_32" + ], + "Short_day_grown_plants,_36h": [ + "shortday_36" + ], + "Short_day_grown_plants,_40h": [ + "shortday_40" + ], + "Short_day_grown_plants,_44h": [ + "shortday_44" + ] + } + }, + "LDHH_ST_00": { + "controls": [ + "LDHH_ST_00", + "LDHH_ST_24" + ], + "treatments": { + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_0h": [ + "LDHH_ST_00", + "LDHH_ST_24" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_4h": [ + "LDHH_ST_04", + "LDHH_ST_28" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_8h": [ + "LDHH_ST_08", + "LDHH_ST_32" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_12h": [ + "LDHH_ST_12", + "LDHH_ST_36" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_16h": [ + "LDHH_ST_16", + "LDHH_ST_40" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_20h": [ + "LDHH_ST_20", + "LDHH_ST_44" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_24h": [ + "LDHH_ST_00", + "LDHH_ST_24" + ] + } + }, + "LDHH_SM_00": { + "controls": [ + "LDHH_SM_00", + "LDHH_SM_24" + ], + "treatments": { + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_0h": [ + "LDHH_SM_00", + "LDHH_SM_24" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_4h": [ + "LDHH_SM_04", + "LDHH_SM_28" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_8h": [ + "LDHH_SM_08", + "LDHH_SM_32" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_12h": [ + "LDHH_SM_12", + "LDHH_SM_36" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_16h": [ + "LDHH_SM_16", + "LDHH_SM_40" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_20h": [ + "LDHH_SM_20", + "LDHH_SM_44" + ], + "12h_light-dark_cycle,_no_temperature_cycle,_leaves_from_older_plants,_24h": [ + "LDHH_SM_00", + "LDHH_SM_24" + ] + } + }, + "LL_LLHC_00": { + "controls": [ + "LL_LLHC_00" + ], + "treatments": { + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_0h": [ + "LL_LLHC_00" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_4h": [ + "LL_LLHC_04" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_8h": [ + "LL_LLHC_08" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_12h": [ + "LL_LLHC_12" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_16h": [ + "LL_LLHC_16" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_20h": [ + "LL_LLHC_20" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_24h": [ + "LL_LLHC_24" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_28h": [ + "LL_LLHC_28" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_32h": [ + "LL_LLHC_32" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_36h": [ + "LL_LLHC_36" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_40h": [ + "LL_LLHC_40" + ], + "Circadian_experiment_-_plants_grown_under_continuous_light_with_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_44h": [ + "LL_LLHC_44" + ] + } + }, + "LL_LDHC_00": { + "controls": [ + "LL_LDHC_00" + ], + "treatments": { + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_0h": [ + "LL_LDHC_00" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_4h": [ + "LL_LDHC_04" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_8h": [ + "LL_LDHC_08" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_12h": [ + "LL_LDHC_12" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_16h": [ + "LL_LDHC_16" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_20h": [ + "LL_LDHC_20" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_24h": [ + "LL_LDHC_24" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_28h": [ + "LL_LDHC_28" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_32h": [ + "LL_LDHC_32" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_36h": [ + "LL_LDHC_36" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_40h": [ + "LL_LDHC_40" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_with_a_temperature_cycle,_then_sampled_under_continuous_light_and_constant_temperature,_44h": [ + "LL_LDHC_44" + ] + } + }, + "LL_LDHH_SH_00": { + "controls": [ + "LL_LDHH_SH_00" + ], + "treatments": { + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_0h": [ + "LL_LDHH_SH_00" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_4h": [ + "LL_LDHH_SH_04" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_8h": [ + "LL_LDHH_SH_08" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_12h": [ + "LL_LDHH_SH_12" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_16h": [ + "LL_LDHH_SH_16" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_20h": [ + "LL_LDHH_SH_20" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_24h": [ + "LL_LDHH_SH_24" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_28h": [ + "LL_LDHH_SH_28" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_32h": [ + "LL_LDHH_SH_32" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_36h": [ + "LL_LDHH_SH_36" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_40h": [ + "LL_LDHH_SH_40" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_44h": [ + "LL_LDHH_SH_44" + ] + } + }, + "LL_LDHH_AM_26": { + "controls": [ + "LL_LDHH_AM_26" + ], + "treatments": { + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_0h": [ + "LL_LDHH_AM_26" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_4h": [ + "LL_LDHH_AM_30" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_8h": [ + "LL_LDHH_AM_34" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_12h": [ + "LL_LDHH_AM_38" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_16h": [ + "LL_LDHH_AM_42" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_20h": [ + "LL_LDHH_AM_46" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_24h": [ + "LL_LDHH_AM_50" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_28h": [ + "LL_LDHH_AM_54" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_32h": [ + "LL_LDHH_AM_58" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_36h": [ + "LL_LDHH_AM_62" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_40h": [ + "LL_LDHH_AM_66" + ], + "Circadian_experiment_-_plants_grown_under_12h_light-dark_cycle_and_constant_temperature,_then_sampled_under_continuous_light_and_constant_temperature,_44h": [ + "LL_LDHH_AM_70" + ] + } + }, + "DD_DDHC_00": { + "controls": [ + "DD_DDHC_00" + ], + "treatments": { + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_0h": [ + "DD_DDHC_00" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_4h": [ + "DD_DDHC_04" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_8h": [ + "DD_DDHC_08" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_12h": [ + "DD_DDHC_12" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_16h": [ + "DD_DDHC_16" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_20h": [ + "DD_DDHC_20" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_24h": [ + "DD_DDHC_24" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_28h": [ + "DD_DDHC_28" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_32h": [ + "DD_DDHC_32" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_36h": [ + "DD_DDHC_36" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_40h": [ + "DD_DDHC_40" + ], + "Control_series_-_plants_grown_in_constant_dark_but_with_a_temperature_cycle_applied._Samples_taken_in_constant_dark_and_temperature,_44h": [ + "DD_DDHC_44" + ] + } + }, + "45_minute_AtGenExpress_set": { + "controls": [ + "AtGen_D-9_1-DS_REP1_ATH1", + "AtGen_D-25_2-DS_REP2_ATH1", + "AtGen_D-41_3-DS_REP3_ATH1" + ], + "treatments": { + "4_d_darkness_then_1_min_red_light_then_44_min_darkness": [ + "AtGen_D-11_1-PS_REP1_ATH1", + "AtGen_D-27_2-PS_REP2_ATH1", + "AtGen_D-43_3-PS_REP3_ATH1" + ], + "4_d_darkness_then_5_min_UV-A_light_then_40_min_darkness": [ + "AtGen_D-14_1-AS_REP1_ATH1", + "AtGen_D-30_2-AS_REP2_ATH1", + "AtGen_D-46_3-AS_REP3_ATH1" + ], + "4_d_darkness_then_5_min_UV-A/B_light_then_40_min_darkness": [ + "AtGen_D-15_1-US_REP1_ATH1", + "AtGen_D-47_3-US_REP3_ATH1", + "AtGen_D-31_2-US_REP2_ATH1" + ], + "4_d_darkness_then_45_min_continuous_red_light": [ + "AtGen_D-12_1-RS_REP1_ATH1", + "AtGen_D-28_2-RS_REP2_ATH1", + "AtGen_D-44_3-RS_REP3_ATH1" + ], + "4_d_darkness_then_45_min_continuous_far-red_light": [ + "AtGen_D-10_1-FS_REP1_ATH1", + "AtGen_D-42_3-FS_REP3_ATH1", + "AtGen_D-26_1-FS_REP2_ATH1" + ], + "4_d_darkness_then_45_min_continuous_blue_light": [ + "AtGen_D-13_1-BS_REP1_ATH1", + "AtGen_D-29_2-BS_REP2_ATH1", + "AtGen_D-45_3-BS_REP3_ATH1" + ], + "4_d_darkness_then_45_min_continuous_white_light": [ + "AtGen_D-16_1-WS_REP1_ATH1", + "AtGen_D-32_2-WS_REP2_ATH1", + "AtGen_D-48_3-WS_REP3_ATH1" + ], + "dark_control_44min": [ + "AtGen_D-9_1-DS_REP1_ATH1", + "AtGen_D-25_2-DS_REP2_ATH1", + "AtGen_D-41_3-DS_REP3_ATH1" + ] + } + }, + "4h_AtGenExpress_set": { + "controls": [ + "AtGen_D-33_3-DL_REP3_ATH1", + "AtGen_D-1_1-DL_REP1_ATH1", + "AtGen_D-17_2-DL_REP2_ATH1" + ], + "treatments": { + "4_d_darkness_then_1_min_red_light_then_4_h_darkness": [ + "AtGen_D-3_1-PL_REP1_ATH1", + "AtGen_D-19_2-PL_REP2_ATH1", + "AtGen_D-35_3-PL_REP3_ATH1" + ], + "4_d_darkness_then_5_min_UV-A_light_then_4_h_darkness": [ + "AtGen_D-6_1-AL_REP1_ATH1", + "AtGen_D-22_2-AL_REP2_ATH1", + "AtGen_D-38_3-AL_REP3_ATH1" + ], + "4_d_darkness_then_5_min_UV-A/B_light_then_4_h_darkness": [ + "AtGen_D-7_1-UL_REP1_ATH1", + "AtGen_D-23_2-UL_REP2_ATH1", + "AtGen_D-39_3-UL_REP3_ATH1" + ], + "4_d_darkness_then_4_h_continuous_red_light": [ + "AtGen_D-4_1-RL_REP1_ATH1", + "AtGen_D-20_2-RL_REP2_ATH1", + "AtGen_D-36_3-RL_REP3_ATH1" + ], + "4_d_darkness_then_4_h_continuous_far-red_light": [ + "AtGen_D-2_1-FL_REP1_ATH1", + "AtGen_D-18_2-FL_REP2_ATH1", + "AtGen_D-34_3-FL_REP3_ATH1" + ], + "4_d_darkness_then_4_h_continuous_blue_light": [ + "AtGen_D-5_1-BL_REP1_ATH1", + "AtGen_D-21_2-BL_REP2_ATH1", + "AtGen_D-37_3-BL_REP3_ATH1" + ], + "4_d_darkness_then_4_h_continuous_white_light": [ + "AtGen_D-8_1-WL_REP1_ATH1", + "AtGen_D-24_2-WL_REP2_ATH1", + "AtGen_D-40_3-WL_REP3_ATH1" + ], + "dark_control_4h": [ + "AtGen_D-33_3-DL_REP3_ATH1", + "AtGen_D-1_1-DL_REP1_ATH1", + "AtGen_D-17_2-DL_REP2_ATH1" + ] + } + } + } + }, + "Natural_Variation": { + "database": "arabidopsis_ecotypes", + "view_name": "Natural_Variation", + "groups": { + "Natural_Variation_Set": { + "controls": [ + "ATGE_113_A", + "ATGE_113_C", + "ATGE_113_D" + ], + "treatments": { + "Bay-0_(CS6608)_from_Bayreuth,_Germany._Longitude/Latitude/Elevation:_E11/N50_at_~300m.": [ + "ATGE_111_A", + "ATGE_111_B", + "ATGE_111_C" + ], + "C24_(CS906)_from_unknown.": [ + "ATGE_112_A", + "ATGE_112_C", + "ATGE_112_D" + ], + "Col-0_(N1092)_from_Columbia,_Missouri,_USA._Longitude/Latitude/Elevation:_W93/N38_at_1-100m._Temp_in_C_(Spr/Aut):15-16/21-2,_Precipitation_in_mm_(Spr/Aut):60-70/30-40.": [ + "ATGE_113_A", + "ATGE_113_C", + "ATGE_113_D" + ], + "Cvi-1_(CS8580)_from_Cape_Verde_Islands._Longitude/Latitude/Elevation:_W24/N16_at_1-100m.": [ + "ATGE_114_A", + "ATGE_114_B", + "ATGE_114_C" + ], + "Est_(CS6173)_from_Estonia._Longitude/Latitude/Elevation:_E25/N59_at_100-200m.": [ + "ATGE_115_A", + "ATGE_115_B", + "ATGE_115_D" + ], + "Kin-0_(CS6755)_from_Kindalville,_Michigan,_USA._Longitude/Latitude/Elevation:_W85/N43_at_200-300m.": [ + "ATGE_116_A", + "ATGE_116_B", + "ATGE_116_C" + ], + "Ler-2_(CS8581)_from_Landsberg,_Germany._Longitude/Latitude/Elevation:_E15/N53_at_100-200m.": [ + "ATGE_117_B", + "ATGE_117_C", + "ATGE_117_D" + ], + "Nd-1_(CS1636)_from_Niederzenz,_Germany._Longitude/Latitude/Elevation:_at_200-300m._Temp_in_C_(Spr/Aut):5-6/9-10,_Precipitation_in_mm_(Spr/Aut):20-30/30-40.": [ + "ATGE_118_A", + "ATGE_118_B", + "ATGE_118_C" + ], + "Sha_(CS6180)_from_Pamiro-Alay,_Tajikistan._Longitude/Latitude/Elevation:_E71/N39_at_3400m.": [ + "ATGE_119_A", + "ATGE_119_C", + "ATGE_119_D" + ], + "Van-0_(CS6884)_from_Vancouver,_BC.,_Canada._Longitude/Latitude/Elevation:_W123/N49_at_1-100m._Temp_in_C_(Spr/Aut):2-9/10-18.": [ + "ATGE_120_A", + "ATGE_120_B", + "ATGE_120_C" + ], + "Ak-1_(CS6602)_from_Achkarren,_Germany._Longitude/Latitude/Elevation:_E8/N48_at_200m._Temp_in_C_(Spr/Aut):7-8/11-12,_Precipitation_in_mm_(Spr/Aut):50-60/50-60.": [ + "ATGE_121_A" + ], + "Bla-5_(CS6620)_from_Blanes,_Spain._Longitude/Latitude/Elevation:_E3/N41_at_50m._Temp_in_C_(Spr/Aut):17-18/11-12,_Precipitation_in_mm_(Spr/Aut):40-50/40-50.": [ + "ATGE_124_A" + ], + "Can-0_(CS6660)_from_Canary_Islands,_Spain._Longitude/Latitude/Elevation:_W15/N28_at_1260m.": [ + "ATGE_125_A" + ], + "Cen-0_(CS6661)_from_Caen,_France._Longitude/Latitude/Elevation:_W0/N49_at_1-100m.": [ + "ATGE_126_A" + ], + "CIBC10_(CS22229)_from_United_Kingdom.": [ + "ATGE_127_A" + ], + "Dra-1_(CS6686)_from_Drahonin,_Czech_Republic._Longitude/Latitude/Elevation:_E16/N49_at_450m.": [ + "ATGE_128_A" + ], + "En-T_(CS6176)_from_Tadjikistan.": [ + "ATGE_129_A" + ], + "Er-0_(CS6698)_from_Erlangen,_Germany._Longitude/Latitude/Elevation:_E11/N49_at_200-300m._Temp_in_C_(Spr/Aut):5-6/9-10,_Precipitation_in_mm_(Spr/Aut):30-40/30-40.": [ + "ATGE_130_A" + ], + "Fr-2_(CS6708)_from_Frankfurt,_Germany._Longitude/Latitude/Elevation:_E8/N50_at_0-100m._Temp_in_C_(Spr/Aut):7-8/9-10,_Precipitation_in_mm_(Spr/Aut):20-30/30-40.": [ + "ATGE_131_A" + ], + "GOT1_(CS22277)_from_Goettingen,_Germany._Longitude/Latitude:_E10/N51.": [ + "ATGE_132_A" + ], + "HR-5_(CS22205)_from_United_Kingdom.": [ + "ATGE_133_A" + ], + "Is-0_(CS6741)_from_Isenburg,_Germany._Longitude/Latitude/Elevation:_E7/N50_at_100-200m._Temp_in_C_(Spr/Aut):7-8/11-12.": [ + "ATGE_134_A" + ], + "Li-2:1_(CS6772)_from_Limburg,_Germany._Longitude/Latitude/Elevation:_E8/N50_at_100-200m._Temp_in_C_(Spr/Aut):3-4/9-10,_Precipitation_in_mm_(Spr/Aut):30-40/30-40.": [ + "ATGE_136_A" + ], + "M7323S_(CS6184)_from_unknown.": [ + "ATGE_141_A" + ], + "MS-0_(CS6797)_from_Moscow,_Russia.": [ + "ATGE_142_A" + ], + "NFE1_(CS22163)_from_United_Kingdom.": [ + "ATGE_138_A" + ], + "Nok-1_(CS6808)_from_Noordwijk,_Netherlands._Longitude/Latitude/Elevation:_E4/N52_at_0-100m._Temp_in_C_(Spr/Aut):3-4/13-14.": [ + "ATGE_139_A" + ], + "Nw-1_(CS6812)_from_Neuweilnau,_Germany._Longitude/Latitude/Elevation:_E8/N50_at_100-200m._Temp_in_C_(Spr/Aut):5-6/9-10.": [ + "ATGE_140_A" + ], + "Old-2_(CS6821)_from_Oldenburg,_Germany._Longitude/Latitude/Elevation:_E8/N53_at_1-100m.": [ + "ATGE_144_A" + ], + "Ove-0_(CS6823)_from_Ovelgoenne,_Germany._Longitude/Latitude/Elevation:_E8/N53_at_1-100m._Temp_in_C_(Spr/Aut):5-6/9-10.": [ + "ATGE_145_A" + ], + "Se-0_(CS6852)_from_San_Eleno,_Spain._Longitude/Latitude/Elevation:_E2/N41_at_0-100m.": [ + "ATGE_146_A" + ], + "Sf-2_(CS6857)_from_San_Feliu,_Spain._Longitude/Latitude/Elevation:_E3/N41_at_1-100m._Temp_in_C_(Spr/Aut):11-12/19-20.": [ + "ATGE_147_A" + ], + "Ta-0_(CS6867)_from_Tabor,_Czech_Republic._Longitude/Latitude/Elevation:_E14/N49_at_400-500m._Temp_in_C_(Spr/Aut):3-4/9-10.": [ + "ATGE_148_A" + ], + "Uk-3_(CS6880)_from_Umkirch,_Germany._Longitude/Latitude/Elevation:_E7/N48_at_200-300m._Temp_in_C_(Spr/Aut):7-8/11-12.": [ + "ATGE_149_A" + ] + } + } + } + }, + "Regeneration": { + "database": "meristem_db", + "view_name": "Regeneration", + "groups": { + "0d_rep1;0d_rep2": { + "controls": [ + "0d_rep1", + "0d_rep2" + ], + "treatments": { + "Che_et_al.,_0_day_root_explants": [ + "0d_rep1", + "0d_rep2" + ], + "Che_et_al._expt,_2_days_CIM": [ + "2d_CIM_rep1", + "2d_CIM_rep2" + ], + "Che_et_al.,_4_days_CIM": [ + "4d_CIM_rep1", + "4d_CIM_rep2" + ], + "Che_et_al.,_7_days_CIM": [ + "7d_CIM_rep1", + "7d_CIM_rep2" + ], + "Che_el_al.,_10_days_CIM": [ + "10d_CIM_rep1", + "10d_CIM_rep2" + ], + "Che_et_al.,_7_days_SIM": [ + "7d_SIM_rep1", + "7d_SIM_rep2" + ], + "Che_et_al.,_10_days_SIM": [ + "10d_SIM_rep1", + "10d_SIM_rep2", + "10d_SIM_rep3" + ], + "Che_et_al.,_7_days_RIM": [ + "7d_RIM_rep1", + "7d_RIM_rep2" + ], + "Che_et_al.,_10_days_RIM": [ + "10d_RIM_rep1", + "10d_RIM_rep2" + ] + } + }, + "GSM496078_d0;GSM496077_d0;GSM496080_d0;GSM496079_d0": { + "controls": [ + "GSM496078_d0", + "GSM496077_d0", + "GSM496080_d0", + "GSM496079_d0" + ], + "treatments": { + "Sugimoto_et_al.,_cotyledon_tissue_prior_to_callus_induction": [ + "GSM496078_d0", + "GSM496077_d0", + "GSM496080_d0", + "GSM496079_d0" + ], + "Sugimoto_et_al.,_cotyledon_derived_callus": [ + "GSM496078", + "GSM496077", + "GSM496080", + "GSM496079" + ] + } + }, + "GSM496071_d0;GSM496067_d0;GSM496076_d0;GSM496073_d0": { + "controls": [ + "GSM496071_d0", + "GSM496067_d0", + "GSM496076_d0", + "GSM496073_d0" + ], + "treatments": { + "Sugimoto_et_al.,_root_tissue_prior_to_callus-induction_treatment": [ + "GSM496071_d0", + "GSM496067_d0", + "GSM496076_d0", + "GSM496073_d0" + ], + "Sugimoto_et_al.,_root_derived_callus": [ + "GSM496067", + "GSM496076", + "GSM496073", + "GSM496071" + ] + } + }, + "GSM496084_d0;GSM496083_d0;GSM496082_d0;GSM496081_d0": { + "controls": [ + "GSM496084_d0", + "GSM496083_d0", + "GSM496082_d0", + "GSM496081_d0" + ], + "treatments": { + "Sugimoto_et_al.,_petal_tissue_prior_to_callus_induction": [ + "GSM496084_d0", + "GSM496083_d0", + "GSM496082_d0", + "GSM496081_d0" + ], + "Sugimoto_et_al.,_petal_derived_callus": [ + "GSM496084", + "GSM496083", + "GSM496082", + "GSM496081" + ] + } + }, + "GSM252663;GSM252664;GSM252665;GSM252666": { + "controls": [ + "GSM252663", + "GSM252664", + "GSM252665", + "GSM252666" + ], + "treatments": { + "Sena_et_al.,_130_mm_of_root_tip_(uncut_control)": [ + "GSM252663", + "GSM252664", + "GSM252665", + "GSM252666" + ], + "Sena_et_al.,_regenerating_stump_of_root_tip_at_0hrs": [ + "GSM252667", + "GSM252668", + "GSM252669", + "GSM252670" + ], + "Sena_et_al.,_regenerating_stump_of_root_tip_after_5hrs": [ + "GSM252671", + "GSM252672", + "GSM252673", + "GSM252674" + ], + "Sena_et_al.,_regenerating_stump_of_root_tip_after_13hrs": [ + "GSM252675", + "GSM252676", + "GSM252677", + "GSM252678" + ], + "Sena_et_al.,_regenerating_stump_of_root_tip_after_22hrs": [ + "GSM252679", + "GSM252680", + "GSM252681", + "GSM252682", + "GSM252683" + ] + } + }, + "bot1330w;bot1517;bot1516": { + "controls": [ + "bot1330w", + "bot1517", + "bot1516" + ], + "treatments": { + "wus,_0_hours_2iP": [ + "bot1524", + "bot1600", + "bot1331w" + ] + } + }, + "bot1334w;bot1521;bot1520": { + "controls": [ + "bot1334w", + "bot1521", + "bot1520" + ], + "treatments": { + "wus,_30_hours_2iP": [ + "bot1335w", + "bot1602", + "bot1526" + ] + } + }, + "bot1957;bot1922;bot1920": { + "controls": [ + "bot1957", + "bot1922", + "bot1920" + ], + "treatments": { + "Yadav_et_al.,_WUSp_SAM_cells": [ + "GSM342148", + "GSM342149" + ] + } + }, + "bot1332w;bot1519;bot1518": { + "controls": [ + "bot1332w", + "bot1519", + "bot1518" + ], + "treatments": { + "wus,_19_hours_2iP": [ + "bot1333w", + "bot1601", + "bot1525" + ] + } + }, + "bot1336w;bot1523;bot1522": { + "controls": [ + "bot1336w", + "bot1523", + "bot1522" + ], + "treatments": { + "wus,_48_hours_2iP": [ + "bot1527", + "bot1337w", + "bot1528" + ] + } + } + } + }, + "Root": { + "database": "root", + "view_name": "Root", + "groups": { + "Longitudinal_zone_1,_salt": { + "controls": [ + "GSM184831", + "GSM184832" + ], + "treatments": { + "longitudinal_zone_1,__standard_conditions": [ + "GSM184831", + "GSM184832" + ], + "longitudinal_zone_1,_140_mM_NaCl": [ + "GSM184839", + "GSM184840" + ] + } + }, + "Longitudinal_zone_2,_salt": { + "controls": [ + "GSM184833", + "GSM184834" + ], + "treatments": { + "longitudinal_zone_2,__standard_conditions": [ + "GSM184833", + "GSM184834" + ], + "longitudinal_zone_2,_140_mM_NaCl": [ + "GSM184841", + "GSM184842" + ] + } + }, + "Longitudinal_zone_3,_salt": { + "controls": [ + "GSM184835", + "GSM184836" + ], + "treatments": { + "longitudinal_zone_3,__standard_conditions": [ + "GSM184835", + "GSM184836" + ], + "longitudinal_zone_3,_140_mM_NaCl": [ + "GSM184843", + "GSM184844" + ] + } + }, + "Longitudinal_zone_4,_salt": { + "controls": [ + "GSM184837", + "GSM184838" + ], + "treatments": { + "longitudinal_zone_4,__standard_conditions": [ + "GSM184837", + "GSM184838" + ], + "longitudinal_zone_4,_140_mM_NaCl": [ + "GSM184845", + "GSM184846" + ] + } + }, + "Epidermis_and_LRC": { + "controls": [ + "GSM184889", + "GSM184890", + "GSM184891" + ], + "treatments": { + "epidermis_and_lateral_root_cap,__standard_conditions": [ + "GSM184889", + "GSM184890", + "GSM184891" + ], + "epidermis_and_lateral_root_cap,__140_mM_NaCl": [ + "GSM184907", + "GSM184908", + "GSM184909" + ], + "epidermis_and_lateral_root_cap,__-Fe": [ + "GSM266662", + "GSM266663", + "GSM266664", + "GSM266665" + ] + } + }, + "Columella_root_cap": { + "controls": [ + "GSM184892", + "GSM184893", + "GSM184894" + ], + "treatments": { + "columella_root_cap,__standard_conditions": [ + "GSM184892", + "GSM184893", + "GSM184894" + ], + "columella_root_cap,__140_mM_NaCl": [ + "GSM184910", + "GSM184911", + "GSM184912" + ], + "columella_root_cap,__-Fe": [ + "GSM266666", + "GSM266667", + "GSM266668" + ] + } + }, + "Cortex": { + "controls": [ + "GSM184895", + "GSM184896", + "GSM184897" + ], + "treatments": { + "cortex,__standard_conditions": [ + "GSM184895", + "GSM184896", + "GSM184897" + ], + "cortex,__140_mM_NaCl": [ + "GSM184913", + "GSM184914", + "GSM184915" + ], + "cortex,__-Fe": [ + "GSM266669", + "GSM266670", + "GSM266671" + ] + } + }, + "Endodermis_and_quiescent_center": { + "controls": [ + "GSM184898", + "GSM184899", + "GSM184900" + ], + "treatments": { + "endodermis_and_quiescent_center,__standard_conditions": [ + "GSM184898", + "GSM184899", + "GSM184900" + ], + "endodermis_and_quiescent_center,__140_mM_NaCl": [ + "GSM184916", + "GSM184917", + "GSM184918" + ], + "endodermis_and_quiescent_center,__-Fe": [ + "GSM266672", + "GSM266673", + "GSM266674" + ] + } + }, + "Stele": { + "controls": [ + "GSM184901", + "GSM184902", + "GSM184903" + ], + "treatments": { + "stele,__standard_conditions": [ + "GSM184901", + "GSM184902", + "GSM184903" + ], + "stele,__140_mM_NaCl": [ + "GSM184919", + "GSM184920", + "GSM184921" + ], + "stele,__-Fe": [ + "GSM266675", + "GSM266676", + "GSM266677" + ] + } + }, + "Protophloem": { + "controls": [ + "GSM184904", + "GSM184905", + "GSM184906" + ], + "treatments": { + "protophloem,__standard_conditions": [ + "GSM184904", + "GSM184905", + "GSM184906" + ], + "protophloem,__140_mM_NaCl": [ + "GSM184922", + "GSM184923", + "GSM184924" + ] + } + }, + "Whole_root,_salt": { + "controls": [ + "GSM184925", + "GSM184926" + ], + "treatments": { + "Whole_root,_standard_conditions_(control)": [ + "GSM184925", + "GSM184926" + ], + "Whole_root,_30_minutes_of_140_mM_NaCl_exposure": [ + "GSM184927", + "GSM184928" + ], + "Whole_root,_1_hour_of_140_mM_NaCl_exposure": [ + "GSM184929", + "GSM184930" + ], + "Whole_root,_4_hours_of_140_mM_NaCl_exposure": [ + "GSM184931", + "GSM184932" + ], + "Whole_root,_16_hours_of_140_mM_NaCl_exposure": [ + "GSM184933", + "GSM184934" + ], + "Whole_root,_32_hours_of_140_mM_NaCl_exposure": [ + "GSM184935", + "GSM184936" + ] + } + }, + "Longitudinal_zone_1,_iron_depletion": { + "controls": [ + "GSM265418", + "GSM265419" + ], + "treatments": { + "longitudinal_zone_1,__standard_conditions": [ + "GSM265418", + "GSM265419" + ], + "longitudinal_zone_1,__-Fe_conditions": [ + "GSM265426", + "GSM265427" + ] + } + }, + "Longitudinal_zone_2,_iron_depletion": { + "controls": [ + "GSM265420", + "GSM265421" + ], + "treatments": { + "longitudinal_zone_2,__standard_conditions": [ + "GSM265420", + "GSM265421" + ], + "longitudinal_zone_2,__-Fe_conditions": [ + "GSM265428", + "GSM265429" + ] + } + }, + "Longitudinal_zone_3,_iron_depletion": { + "controls": [ + "GSM265422", + "GSM265423" + ], + "treatments": { + "longitudinal_zone_3,__standard_conditions": [ + "GSM265422", + "GSM265423" + ], + "longitudinal_zone_3,__-Fe_conditions": [ + "GSM265430", + "GSM265431" + ] + } + }, + "Longitudinal_zone_4,_iron_depletion": { + "controls": [ + "GSM265424", + "GSM265425" + ], + "treatments": { + "longitudinal_zone_4,__standard_conditions": [ + "GSM265424", + "GSM265425" + ], + "longitudinal_zone_4,__-Fe_conditions": [ + "GSM265432", + "GSM265433" + ] + } + }, + "Whole_root,_iron_depletion": { + "controls": [ + "GSM265461", + "GSM265462" + ], + "treatments": { + "Whole_root,_standard_conditions,_control": [ + "GSM265461", + "GSM265462" + ], + "Whole_root,_-Fe,__3_hour": [ + "GSM265463", + "GSM265464" + ], + "Whole_root,_-Fe,__6_hour": [ + "GSM265465", + "GSM265466" + ], + "Whole_root,_-Fe,__12_hour": [ + "GSM265467", + "GSM265468" + ], + "Whole_root,_-Fe,__24_hour": [ + "GSM265469", + "GSM265470" + ], + "Whole_root,_-Fe,__48_hour": [ + "GSM265471", + "GSM265472" + ], + "Whole_root,_-Fe,__72_hour": [ + "GSM265473", + "GSM265474" + ] + } + }, + "Lateral_root_cap,_N2_study": { + "controls": [ + "GSM184476", + "GSM184477", + "GSM184478" + ], + "treatments": { + "Lateral_Root_Cap_root_cells_2hr_KCl_control_treated": [ + "GSM184476", + "GSM184477", + "GSM184478" + ], + "Lateral_Root_Cap_root_cells_2hr_continuous_KNO3_treated": [ + "GSM184482", + "GSM184483", + "GSM184484" + ] + } + }, + "Epidermis_and_Cortex_root_cells,_N2_study": { + "controls": [ + "GSM184485", + "GSM184486", + "GSM184487" + ], + "treatments": { + "Epidermis_and_Cortex_root_cells_2hr_KCl_control_treated": [ + "GSM184485", + "GSM184486", + "GSM184487" + ], + "Epidermis_and_Cortex_root_cells_2hr_continuous_KNO3_treated": [ + "GSM184491", + "GSM184492", + "GSM184493" + ] + } + }, + "Endodermis_and_Pericycle_root_cells,_N2_study": { + "controls": [ + "GSM184494", + "GSM184495", + "GSM184496" + ], + "treatments": { + "Endodermis_and_Pericycle_root_cells_2hr_KCl_control_treated": [ + "GSM184494", + "GSM184495", + "GSM184496" + ], + "Endodermis_and_Pericycle_root_cells_2hr_continuous_KNO3_treated": [ + "GSM184500", + "GSM184501", + "GSM184502" + ] + } + }, + "Pericycle_root_cells,_N2_study": { + "controls": [ + "GSM184503", + "GSM184504", + "GSM184505" + ], + "treatments": { + "Pericycle_root_cells_2hr_KCl_control_treated": [ + "GSM184503", + "GSM184504", + "GSM184505" + ], + "Pericycle_root_cells_2hr_continuous_KNO3_treated": [ + "GSM184509", + "GSM184510", + "GSM184511" + ] + } + }, + "Stele_root_cells,_N2_study": { + "controls": [ + "GSM184522", + "GSM184523", + "GSM184524" + ], + "treatments": { + "Stele_root_cells_2hr_KCl_control_treated": [ + "GSM184522", + "GSM184523", + "GSM184524" + ], + "Stele_root_cells_2hr_continuous_KNO3_treated": [ + "GSM184528", + "GSM184529", + "GSM184530" + ] + } + }, + "Spatiotemporal_Map": { + "controls": [ + "ROOT_CTRL" + ], + "treatments": { + "columella": [ + "col_1" + ], + "columella_1": [ + "col_2" + ], + "cortex_9": [ + "cortex_10" + ], + "cortex_10": [ + "cortex_11" + ], + "cortex_11": [ + "cortex_12" + ], + "cortex_12": [ + "cortex_13" + ], + "cortex_1": [ + "cortex_2" + ], + "cortex_2": [ + "cortex_3" + ], + "cortex_3": [ + "cortex_4" + ], + "cortex_4": [ + "cortex_5" + ], + "cortex_5": [ + "cortex_6" + ], + "cortex_6": [ + "cortex_7" + ], + "cortex_7": [ + "cortex_8" + ], + "cortex_8": [ + "cortex_9" + ], + "endodermis_9": [ + "endodermis_10" + ], + "endodermis_10": [ + "endodermis_11" + ], + "endodermis_11": [ + "endodermis_12" + ], + "endodermis_12": [ + "endodermis_13" + ], + "endodermis_1": [ + "endodermis_2" + ], + "endodermis_2": [ + "endodermis_3" + ], + "endodermis_3": [ + "endodermis_4" + ], + "endodermis_4": [ + "endodermis_5" + ], + "endodermis_5": [ + "endodermis_6" + ], + "endodermis_6": [ + "endodermis_7" + ], + "endodermis_7": [ + "endodermis_8" + ], + "endodermis_8": [ + "endodermis_9" + ], + "hair_9": [ + "hair_10" + ], + "hair_10": [ + "hair_11" + ], + "hair_11": [ + "hair_12" + ], + "hair_12": [ + "hair_13" + ], + "hair_1": [ + "hair_2" + ], + "hair_2": [ + "hair_3" + ], + "hair_3": [ + "hair_4" + ], + "hair_4": [ + "hair_5" + ], + "hair_5": [ + "hair_6" + ], + "hair_6": [ + "hair_7" + ], + "hair_7": [ + "hair_8" + ], + "hair_8": [ + "hair_9" + ], + "lateral_root_cap": [ + "lrc_1" + ], + "lateral_root_cap_1": [ + "lrc_2" + ], + "lateral_root_cap_2": [ + "lrc_3" + ], + "lateral_root_cap_3": [ + "lrc_4" + ], + "lateral_root_cap_4": [ + "lrc_5" + ], + "lateral_root_cap_5": [ + "lrc_6" + ], + "lateral_root_primordium_11": [ + "lrp_12" + ], + "meta_protophloem_9": [ + "metaProtoPhloem_10" + ], + "meta_protophloem_10": [ + "metaProtoPhloem_11" + ], + "meta_protophloem_11": [ + "metaProtoPhloem_12" + ], + "meta_protophloem_12": [ + "metaProtoPhloem_13" + ], + "meta_protophloem_2": [ + "metaProtoPhloem_3" + ], + "meta_protophloem_3": [ + "metaProtoPhloem_4" + ], + "meta_protophloem_4": [ + "metaProtoPhloem_5" + ], + "meta_protophloem_5": [ + "metaProtoPhloem_6" + ], + "meta_protophloem_6": [ + "metaProtoPhloem_7" + ], + "meta_protophloem_7": [ + "metaProtoPhloem_8" + ], + "meta_protophloem_8": [ + "metaProtoPhloem_9" + ], + "non_root_hair_cell_9": [ + "nonHair_10" + ], + "non_root_hair_cell_10": [ + "nonHair_11" + ], + "non_root_hair_cell_11": [ + "nonHair_12" + ], + "non_root_hair_cell_12": [ + "nonHair_13" + ], + "non_root_hair_cell_1": [ + "nonHair_2" + ], + "non_root_hair_cell_2": [ + "nonHair_3" + ], + "non_root_hair_cell_3": [ + "nonHair_4" + ], + "non_root_hair_cell_4": [ + "nonHair_5" + ], + "non_root_hair_cell_5": [ + "nonHair_6" + ], + "non_root_hair_cell_6": [ + "nonHair_7" + ], + "non_root_hair_cell_7": [ + "nonHair_8" + ], + "non_root_hair_cell_8": [ + "nonHair_9" + ], + "phloem_companion_cell_9": [ + "phloem_10" + ], + "phloem_companion_cell_10": [ + "phloem_11" + ], + "phloem_companion_cell_11": [ + "phloem_12" + ], + "phloem_companion_cell_12": [ + "phloem_13" + ], + "phloem_companion_cell_2": [ + "phloem_3" + ], + "phloem_companion_cell_3": [ + "phloem_4" + ], + "phloem_companion_cell_4": [ + "phloem_5" + ], + "phloem_companion_cell_5": [ + "phloem_6" + ], + "phloem_companion_cell_6": [ + "phloem_7" + ], + "phloem_companion_cell_7": [ + "phloem_8" + ], + "phloem_companion_cell_8": [ + "phloem_9" + ], + "phloem_pole_pericycle_9": [ + "phloemPole_10" + ], + "phloem_pole_pericycle_10": [ + "phloemPole_11" + ], + "phloem_pole_pericycle_11": [ + "phloemPole_12" + ], + "phloem_pole_pericycle_12": [ + "phloemPole_13" + ], + "phloem_pole_pericycle_1": [ + "phloemPole_2" + ], + "phloem_pole_pericycle_2": [ + "phloemPole_3" + ], + "phloem_pole_pericycle_3": [ + "phloemPole_4" + ], + "phloem_pole_pericycle_4": [ + "phloemPole_5" + ], + "phloem_pole_pericycle_5": [ + "phloemPole_6" + ], + "phloem_pole_pericycle_6": [ + "phloemPole_7" + ], + "phloem_pole_pericycle_7": [ + "phloemPole_8" + ], + "phloem_pole_pericycle_8": [ + "phloemPole_9" + ], + "procambium_9": [ + "procambium_10" + ], + "procambium_10": [ + "procambium_11" + ], + "procambium_11": [ + "procambium_12" + ], + "procambium_12": [ + "procambium_13" + ], + "procambium_1": [ + "procambium_2" + ], + "procambium_2": [ + "procambium_3" + ], + "procambium_3": [ + "procambium_4" + ], + "procambium_4": [ + "procambium_5" + ], + "procambium_5": [ + "procambium_6" + ], + "procambium_6": [ + "procambium_7" + ], + "procambium_7": [ + "procambium_8" + ], + "procambium_8": [ + "procambium_9" + ], + "quiescent_center_1": [ + "qc_2" + ], + "xylem_9": [ + "xylem_10" + ], + "xylem_10": [ + "xylem_11" + ], + "xylem_11": [ + "xylem_12" + ], + "xylem_12": [ + "xylem_13" + ], + "xylem_1": [ + "xylem_2" + ], + "xylem_2": [ + "xylem_3" + ], + "xylem_3": [ + "xylem_4" + ], + "xylem_4": [ + "xylem_5" + ], + "xylem_5": [ + "xylem_6" + ], + "xylem_6": [ + "xylem_7" + ], + "xylem_7": [ + "xylem_8" + ], + "xylem_8": [ + "xylem_9" + ], + "xylem_pole_pericycle_9": [ + "xylemPole_10" + ], + "xylem_pole_pericycle_10": [ + "xylemPole_11" + ], + "xylem_pole_pericycle_11": [ + "xylemPole_12" + ], + "xylem_pole_pericycle_12": [ + "xylemPole_13" + ], + "xylem_pole_pericycle_1": [ + "xylemPole_2" + ], + "xylem_pole_pericycle_2": [ + "xylemPole_3" + ], + "xylem_pole_pericycle_3": [ + "xylemPole_4" + ], + "xylem_pole_pericycle_4": [ + "xylemPole_5" + ], + "xylem_pole_pericycle_5": [ + "xylemPole_6" + ], + "xylem_pole_pericycle_6": [ + "xylemPole_7" + ], + "xylem_pole_pericycle_7": [ + "xylemPole_8" + ], + "xylem_pole_pericycle_8": [ + "xylemPole_9" + ], + "Phloem_Pole_Pericycle,_young_(average_of_levels_in_PPP_cells_in_sections_1-6)": [ + "phloemPole_2", + "phloemPole_3", + "phloemPole_4", + "phloemPole_5", + "phloemPole_6", + "phloemPole_7" + ], + "Xylem_Pole_Pericycle,_young_(average_of_levels_in_XPP_cells_in_sections_1-6)": [ + "xylemPole_2", + "xylemPole_3", + "xylemPole_4", + "xylemPole_5", + "xylemPole_6", + "xylemPole_7" + ], + "Phloem_companion_cells,_young_(average_of_levels_in_PC_cells_in_sections_2-6)": [ + "phloem_3", + "phloem_4", + "phloem_5", + "phloem_6", + "phloem_7" + ], + "Protophloem_and_Metaphloem,__young_(average_of_phloem_levels_in_sections_2-6)": [ + "metaProtoPhloem_3", + "metaProtoPhloem_4", + "metaProtoPhloem_5", + "metaProtoPhloem_6", + "metaProtoPhloem_7" + ], + "Procambium,_young_(average_of_procambium_levels_in_sections_1-6)": [ + "procambium_2", + "procambium_3", + "procambium_4", + "procambium_5", + "procambium_6", + "procambium_7" + ], + "Xylem,_young_(average_of_xylem_levels_in_sections_1-6)": [ + "xylem_2", + "xylem_3", + "xylem_4", + "xylem_5", + "xylem_6", + "xylem_7" + ], + "Phloem_Pole_Pericycle,_old_(average_of_levels_in_PPP_cells_in_sections_7-12)": [ + "phloemPole_8", + "phloemPole_9", + "phloemPole_10", + "phloemPole_11", + "phloemPole_12", + "phloemPole_13" + ], + "Xylem_Pole_Pericycle,_old_(average_of_levels_in_XPP_cells_in_sections_7-12)": [ + "xylemPole_8", + "xylemPole_9", + "xylemPole_10", + "xylemPole_11", + "xylemPole_12", + "xylemPole_13" + ], + "Phloem_companion_cells,_old_(average_of_levels_in_PC_cells_in_sections_7-12)": [ + "phloem_8", + "phloem_9", + "phloem_10", + "phloem_11", + "phloem_12", + "phloem_13" + ], + "Protophloem_and_Metaphloem,__old_(average_of_phloem_levels_in_sections_7-12)": [ + "metaProtoPhloem_8", + "metaProtoPhloem_9", + "metaProtoPhloem_10", + "metaProtoPhloem_11", + "metaProtoPhloem_12", + "metaProtoPhloem_13" + ], + "Procambium,_old_(average_of_procambium_levels_in_sections_7-12)": [ + "procambium_8", + "procambium_9", + "procambium_10", + "procambium_11", + "procambium_12", + "procambium_13" + ], + "Xylem,_old_(average_of_xylem_levels_in_sections_7-12)": [ + "xylem_8", + "xylem_9", + "xylem_10", + "xylem_11", + "xylem_12", + "xylem_13" + ] + } + } + } + }, + "Root_II": { + "database": "root", + "view_name": "Root_II", + "groups": { + "GSM744778;GSM744779": { + "controls": [ + "GSM744778", + "GSM744779" + ], + "treatments": { + "Low_pH,_t=6": [ + "GSM744792", + "GSM744793" + ], + "Standard_pH,_t=6_(control)": [ + "GSM744778", + "GSM744779" + ] + } + }, + "GSM871266;GSM871267;GSM871268": { + "controls": [ + "GSM871266", + "GSM871267", + "GSM871268" + ], + "treatments": { + "intact_root_control_": [ + "GSM871266", + "GSM871267", + "GSM871268" + ], + "intact_root_auxin_": [ + "GSM871269", + "GSM871270", + "GSM871271" + ] + } + }, + "GSM744776;GSM744777": { + "controls": [ + "GSM744776", + "GSM744777" + ], + "treatments": { + "Low_pH,_t=3": [ + "GSM744790", + "GSM744791" + ], + "Standard_pH,_t=3_(Control)": [ + "GSM744776", + "GSM744777" + ] + } + }, + "GSM871254;GSM871255;GSM871256": { + "controls": [ + "GSM871254", + "GSM871255", + "GSM871256" + ], + "treatments": { + "epidermis_auxin_": [ + "GSM871257", + "GSM871258", + "GSM871259" + ], + "epidermis_control_": [ + "GSM871254", + "GSM871255", + "GSM871256" + ] + } + }, + "GSM618328;GSM618336;GSM618344": { + "controls": [ + "GSM618328", + "GSM618336", + "GSM618344" + ], + "treatments": { + "Without_phosphate_6h_into_RNALater": [ + "GSM618329", + "GSM618337", + "GSM618345" + ], + "With_phosphate_6h_into_RNALater_(CONTROL)": [ + "GSM618328", + "GSM618336", + "GSM618344" + ] + } + }, + "GSM744774;GSM744775": { + "controls": [ + "GSM744774", + "GSM744775" + ], + "treatments": { + "Low_pH,_t=1_": [ + "GSM744788", + "GSM744789" + ], + "Standard_pH,_t=1_(Control)": [ + "GSM744774", + "GSM744775" + ] + } + }, + "GSM871242;GSM871243;GSM871244": { + "controls": [ + "GSM871242", + "GSM871243", + "GSM871244" + ], + "treatments": { + "stele_auxin_": [ + "GSM871245", + "GSM871246", + "GSM871247" + ], + "stele_control_": [ + "GSM871242", + "GSM871243", + "GSM871244" + ] + } + }, + "GSM744758;GSM744759": { + "controls": [ + "GSM744758", + "GSM744759" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_section,_longitudinal_zone_1_(Control)": [ + "GSM744758", + "GSM744759" + ], + "Low_pH,_Arabidopsis_root_section,_longitudinal_zone_1": [ + "GSM744756", + "GSM744757" + ] + } + }, + "GSM744747;GSM744748;GSM744749": { + "controls": [ + "GSM744747", + "GSM744748", + "GSM744749" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_cells,_endodermis_and_quiescent_center_(Control)": [ + "GSM744747", + "GSM744748", + "GSM744749" + ], + "Low_pH,_Arabidopsis_root_cells,_endodermis_and_quiescent_center": [ + "GSM744744", + "GSM744745", + "GSM744746" + ] + } + }, + "GSM744741;GSM744742;GSM744743": { + "controls": [ + "GSM744741", + "GSM744742", + "GSM744743" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_cells,_cortex_(Control)": [ + "GSM744741", + "GSM744742", + "GSM744743" + ], + "Low_pH,_Arabidopsis_root_cells,_cortex": [ + "GSM744738", + "GSM744739", + "GSM744740" + ] + } + }, + "GSM871260;GSM871261;GSM871262": { + "controls": [ + "GSM871260", + "GSM871261", + "GSM871262" + ], + "treatments": { + "columella_auxin_": [ + "GSM871263", + "GSM871264", + "GSM871265" + ], + "columella_control_": [ + "GSM871260", + "GSM871261", + "GSM871262" + ] + } + }, + "GSM184895;GSM184896;GSM184897": { + "controls": [ + "GSM184895", + "GSM184896", + "GSM184897" + ], + "treatments": { + "Low_sulfur,_Arabidopsis_root_cells,_cortex_(control)": [ + "GSM184895", + "GSM184896", + "GSM184897" + ], + "Low_sulfur,_Arabidopsis_root_cells,_cortex": [ + "GSM744818", + "GSM744819", + "GSM744820" + ] + } + }, + "GSM265424;GSM265425": { + "controls": [ + "GSM265424", + "GSM265425" + ], + "treatments": { + "Low_Sulfur,_Arabidopsis_root_section,_longitudinal_zone_4": [ + "GSM744833", + "GSM744834" + ], + "Standard_conditions,_Arabidopsis_root_section,_longitudinal_zone_4": [ + "GSM265424", + "GSM265425" + ] + } + }, + "GSM744780;GSM744781": { + "controls": [ + "GSM744780", + "GSM744781" + ], + "treatments": { + "Low_pH,_t=12": [ + "GSM744794", + "GSM744795" + ], + "Standard_pH,_t=12_(control)": [ + "GSM744780", + "GSM744781" + ] + } + }, + "GSM618324;GSM618332;GSM618340": { + "controls": [ + "GSM618324", + "GSM618332", + "GSM618340" + ], + "treatments": { + "Without_phosphate_0h_into_RNALater": [ + "GSM618325", + "GSM618333", + "GSM618341" + ], + "With_phosphate_0h_into_RNALater_(CONTROL)": [ + "GSM618324", + "GSM618332", + "GSM618340" + ] + } + }, + "GSM744800;GSM744801": { + "controls": [ + "GSM744800", + "GSM744801" + ], + "treatments": { + "Low_sulfur,_t=0______": [ + "GSM744800", + "GSM744801" + ], + "Low_sulfur,_t=48": [ + "GSM744808", + "GSM744809" + ], + "Low_sulfur,_t=24": [ + "GSM744806", + "GSM744807" + ], + "Low_sulfur,_t=3______": [ + "GSM744802", + "GSM744803" + ], + "Low_sulfur,_t=72": [ + "GSM744810", + "GSM744811" + ], + "Low_sulfur,_t=12": [ + "GSM744804", + "GSM744805" + ] + } + }, + "GSM871248;GSM871249;GSM871250": { + "controls": [ + "GSM871248", + "GSM871249", + "GSM871250" + ], + "treatments": { + "pericycle_auxin_": [ + "GSM871251", + "GSM871252", + "GSM871253" + ], + "pericycle_control_": [ + "GSM871248", + "GSM871249", + "GSM871250" + ] + } + }, + "GSM744772;GSM744773": { + "controls": [ + "GSM744772", + "GSM744773" + ], + "treatments": { + "Low_pH,_t=0.5_": [ + "GSM744786", + "GSM744787" + ], + "Standard_pH,_t=0.5_(Control)": [ + "GSM744772", + "GSM744773" + ] + } + }, + "GSM744729;GSM744730;GSM744731": { + "controls": [ + "GSM744729", + "GSM744730", + "GSM744731" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_cells,_columella_root_cap_(Control)": [ + "GSM744729", + "GSM744730", + "GSM744731" + ], + "Low_pH,_Arabidopsis_root_cells,_columella_root_cap": [ + "GSM744726", + "GSM744727", + "GSM744728" + ] + } + }, + "GSM744735;GSM744736;GSM744737": { + "controls": [ + "GSM744735", + "GSM744736", + "GSM744737" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_cells,_epidermis_and_lateral_root_cap_(Control)": [ + "GSM744735", + "GSM744736", + "GSM744737" + ], + "Low_pH,_Arabidopsis_root_cells,_epidermis_and_lateral_root_cap": [ + "GSM744732", + "GSM744733", + "GSM744734" + ] + } + }, + "GSM744784;GSM744785": { + "controls": [ + "GSM744784", + "GSM744785" + ], + "treatments": { + "Standard_pH,_t=48_(control)": [ + "GSM744784", + "GSM744785" + ], + "Low_pH,_t=48": [ + "GSM744798", + "GSM744799" + ] + } + }, + "GSM744753;GSM744754;GSM744755": { + "controls": [ + "GSM744753", + "GSM744754", + "GSM744755" + ], + "treatments": { + "Low_pH,_Arabidopsis_root_cells,_stele": [ + "GSM744750", + "GSM744751", + "GSM744752" + ], + "Standard_pH,_Arabidopsis_root_cells,_stele_(Control)": [ + "GSM744753", + "GSM744754", + "GSM744755" + ] + } + }, + "GSM184901;GSM184902;GSM184903": { + "controls": [ + "GSM184901", + "GSM184902", + "GSM184903" + ], + "treatments": { + "Low_sulfur,_Arabidopsis_root_cells,_stele": [ + "GSM744824", + "GSM744825", + "GSM744826" + ], + "Low_sulfur,_Arabidopsis_root_cells,_stele_(Control_from_GSE7641)": [ + "GSM184901", + "GSM184902", + "GSM184903" + ] + } + }, + "GSM744782;GSM744783": { + "controls": [ + "GSM744782", + "GSM744783" + ], + "treatments": { + "Standard_pH,_t=24_(control)": [ + "GSM744782", + "GSM744783" + ], + "Low_pH,_t=24": [ + "GSM744796", + "GSM744797" + ] + } + }, + "GSM184898;GSM184899;GSM184900": { + "controls": [ + "GSM184898", + "GSM184899", + "GSM184900" + ], + "treatments": { + "Low_sulfur,_Arabidopsis_root_cells,_endodermis": [ + "GSM744821", + "GSM744822", + "GSM744823" + ], + "Low_sulfur,_Arabidopsis_root_cells,_endodermis_(control)": [ + "GSM184898", + "GSM184899", + "GSM184900" + ] + } + }, + "GSM618330;GSM618338;GSM618346": { + "controls": [ + "GSM618330", + "GSM618338", + "GSM618346" + ], + "treatments": { + "With_phosphate_24h_into_RNALater_(CONTROL)": [ + "GSM618330", + "GSM618338", + "GSM618346" + ], + "Without_phosphate_24h_into_RNALater": [ + "GSM618331", + "GSM618339", + "GSM618347" + ] + } + }, + "GSM618326;GSM618334;GSM618342": { + "controls": [ + "GSM618326", + "GSM618334", + "GSM618342" + ], + "treatments": { + "With_phosphate_1h_into_RNALater_(CONTROL)": [ + "GSM618326", + "GSM618334", + "GSM618342" + ], + "Without_phosphate_1h_into_RNALater": [ + "GSM618327", + "GSM618343" + ] + } + }, + "GSM184889;GSM184890;GSM184891": { + "controls": [ + "GSM184889", + "GSM184890", + "GSM184891" + ], + "treatments": { + "Low_sulfur,_Arabidopsis_root_cells,_epidermis_and_lateral_root_cap": [ + "GSM744815", + "GSM744816", + "GSM744817" + ], + "Low_sulfur,_Arabidopsis_root_cells,_epidermis_and_lateral_root_cap_(Control)": [ + "GSM184889", + "GSM184890", + "GSM184891" + ] + } + }, + "GSM744762;GSM744763": { + "controls": [ + "GSM744762", + "GSM744763" + ], + "treatments": { + "Standard_pH,_Arabidopsis_root_section,_longitudinal_zone_2": [ + "GSM744762", + "GSM744763" + ], + "Low_pH,_Arabidopsis_root_section,_longitudinal_zone_2": [ + "GSM744760", + "GSM744761" + ] + } + }, + "GSM265420;GSM265421": { + "controls": [ + "GSM265420", + "GSM265421" + ], + "treatments": { + "Low_Sulfur,_Arabidopsis_root_section,_longitudinal_zone_2": [ + "GSM265429", + "GSM265430" + ], + "Standard_conditions,_Arabidopsis_root_section,_longitudinal_zone_2": [ + "GSM265420", + "GSM265421" + ] + } + }, + "GSM265422;GSM265423": { + "controls": [ + "GSM265422", + "GSM265423" + ], + "treatments": { + "Low_Sulfur,_Arabidopsis_root_section,_longitudinal_zone_3": [ + "GSM744831", + "GSM744832" + ], + "Standard_conditions,_Arabidopsis_root_section,_longitudinal_zone_3": [ + "GSM265422", + "GSM265423" + ] + } + }, + "GSM184892;GSM184893;GSM184894": { + "controls": [ + "GSM184892", + "GSM184893", + "GSM184894" + ], + "treatments": { + "Low_sulfur,_Arabidopsis_root_cells,_columella_root_cap": [ + "GSM744812", + "GSM744813", + "GSM744814" + ], + "Low_sulfur,_Arabidopsis_root_cells,_columella_root_cap_(control)": [ + "GSM184892", + "GSM184893", + "GSM184894" + ] + } + }, + "GSM744766;GSM744767": { + "controls": [ + "GSM744766", + "GSM744767" + ], + "treatments": { + "Low_pH,_Arabidopsis_root_section,_longitudinal_zone_3": [ + "GSM744764", + "GSM744765" + ], + "Standard_pH,_Arabidopsis_root_section,_longitudinal_zone_3": [ + "GSM744766", + "GSM744767" + ] + } + }, + "GSM265418;GSM265419": { + "controls": [ + "GSM265418", + "GSM265419" + ], + "treatments": { + "Low_Sulfur,_Arabidopsis_root_section,_longitudinal_zone_1": [ + "GSM744827", + "GSM744828" + ], + "Standard_conditions,_Arabidopsis_root_section,_longitudinal_zone_1": [ + "GSM265418", + "GSM265419" + ] + } + }, + "GSM744770;GSM744771": { + "controls": [ + "GSM744770", + "GSM744771" + ], + "treatments": { + "Low_pH,_Arabidopsis_root_section,_longitudinal_zone_4": [ + "GSM744768", + "GSM744769" + ], + "Standard_pH,_Arabidopsis_root_section,_longitudinal_zone_4": [ + "GSM744770", + "GSM744771" + ] + } + } + } + }, + "Seed": { + "database": "seed_db", + "view_name": "Seed", + "groups": { + "Seeds": { + "controls": [ + "SEED_CTRL" + ], + "treatments": { + "Dry_Seeds": [ + "RIKEN-PRESTON0A", + "RIKEN-PRESTON0B" + ], + "1_h_Imbibed_Seeds": [ + "RIKEN-PRESTON1A", + "RIKEN-PRESTON1B" + ], + "3_h_Imbibed_Seeds": [ + "RIKEN-PRESTON2A", + "RIKEN-PRESTON2B" + ], + "6_h_Imbibed_Seeds": [ + "6hr_rep1", + "6hr_rep2" + ], + "12_h_Imbibed_Seeds": [ + "12hr_rep1", + "12hr_rep2" + ], + "24_h_Imbibed_Seeds": [ + "24hr_rep1", + "24hr_rep2" + ], + "96_h_at_22_C": [ + "RIKEN-YAMAUCHI1A", + "RIKEN-YAMAUCHI1B" + ], + "96_h_at_4_C": [ + "RIKEN-YAMAUCHI2A", + "RIKEN-YAMAUCHI2B" + ], + "3_h_in_water": [ + "RIKEN-LI1A", + "RIKEN-LI1B" + ], + "6_h_in_water": [ + "RIKEN-LI2A", + "RIKEN-LI2B" + ], + "9_h_in_water": [ + "RIKEN-LI3A", + "RIKEN-LI3B" + ], + "3_h_in_GA": [ + "RIKEN-LI4A", + "RIKEN-LI4B" + ], + "6_h_in_GA": [ + "RIKEN-LI5A", + "RIKEN-LI5B" + ], + "9_h_in_GA": [ + "RIKEN-LI6A", + "RIKEN-LI6B" + ], + "24_h_in_water": [ + "RIKEN-NAKABAYASHI2A", + "RIKEN-NAKABAYASHI2B" + ], + "24_h_in_3_uM_ABA": [ + "RIKEN-NAKABAYASHI3A", + "RIKEN-NAKABAYASHI5B" + ], + "_24_h_in_30_uM_ABA": [ + "RIKEN-NAKABAYASHI4A", + "RIKEN-NAKABAYASHI4B" + ], + "Germinated_Embryo": [ + "Penfield_1-10_embryo-control_Rep1_ATH1", + "Penfield_1-11_embryo-control_Rep2_ATH1", + "Penfield_1-12_embryo-control_Rep3_ATH1" + ], + "PAC_Treated_Embryo": [ + "Penfield_1-16_embryo-PAC_Rep1_ATH1", + "Penfield_1-17_embryo-PAC_Rep2_ATH1", + "Penfield_1-18_embryo-PAC_Rep3_ATH1" + ], + "ABA_Treated_Embryo": [ + "Penfield_1-13_embryo-ABA_Rep1_ATH1", + "Penfield_1-14_embryo-ABA_Rep2_ATH1", + "Penfield_1-15_embryo-ABA_Rep3_ATH1" + ], + "Germinated_Endosperm": [ + "Penfield_1-1_endosperm-control_Rep1_ATH1", + "Penfield_1-2_endosperm-control_Rep2_ATH1", + "Penfield_1-3_endosperm-control_Rep3_ATH1" + ], + "PAC_Treated_Endosperm": [ + "Penfield_1-7_endosperm-PAC_Rep1_ATH1", + "Penfield_1-8_endosperm-PAC_Rep2_ATH1", + "Penfield_1-9_endosperm-PAC_Rep3_ATH1" + ], + "ABA_Treated_Endosperm": [ + "Penfield_1-4_endosperm-ABA_Rep1_ATH1", + "Penfield_1-5_endosperm-ABA_Rep2_ATH1", + "Penfield_1-6_endosperm-ABA_Rep3_ATH1" + ], + "PDD": [ + "Finch-Savage_1-29_PDD_Rep1_ATH1", + "Finch-Savage_1-30_PDD_Rep2_ATH1", + "Finch-Savage_1-31_PDD_Rep3_ATH1", + "Finch-Savage_1-32_PDD_Rep4_ATH1" + ], + "DDL": [ + "Finch-Savage_1-33_NDD_Rep1_ATH1", + "Finch-Savage_1-34_NDD_Rep2_ATH1", + "Finch-Savage_1-35_NDD_Rep3_ATH1", + "Finch-Savage_1-36_NDD_Rep4_ATH1" + ], + "PD24h": [ + "Finch-Savage_1-1_PD24h_Rep1_ATH1", + "Finch-Savage_1-2_PD24h_Rep2_ATH1", + "Finch-Savage_1-3_PD24h_Rep3_ATH1", + "Finch-Savage_1-4_PD24h_Rep4_ATH1" + ], + "PD48h": [ + "Finch-Savage_1-13_PD48h_Rep1_ATH1", + "Finch-Savage_1-14_PD48h_Rep2_ATH1", + "Finch-Savage_1-15_PD48h_Rep3_ATH1", + "Finch-Savage_1-16_PD48h_Rep4_ATH1" + ], + "PD30d": [ + "Finch-Savage_1-17_PD30d_Rep1_ATH1", + "Finch-Savage_1-18_PD30d_Rep2_ATH1", + "Finch-Savage_1-19_PD30d_Rep3_ATH1", + "Finch-Savage_1-20_PD30d_Rep4_ATH1" + ], + "SD1": [ + "Finch-Savage_1-9_SD1_Rep1_ATH1", + "Finch-Savage_1-10_SD1_Rep2_ATH1", + "Finch-Savage_1-11_SD1_Rep3_ATH1", + "Finch-Savage_1-12_SD1_Rep4_ATH1" + ], + "SD2": [ + "Finch-Savage_1-21_SD2_Rep1_ATH1", + "Finch-Savage_1-22_SD2_Rep2_ATH1", + "Finch-Savage_1-23_SD2_Rep3_ATH1", + "Finch-Savage_1-24_SD2_Rep4_ATH1" + ], + "PDC": [ + "Finch-Savage_1-49_PDC_Rep1_ATH1", + "Finch-Savage_1-50_PDC_Rep2_ATH1", + "Finch-Savage_1-51_PDC_Rep3_ATH1", + "Finch-Savage_1-52_PDC_Rep4_ATH1" + ], + "PDL": [ + "Finch-Savage_1-37_PDL_Rep1_ATH1", + "Finch-Savage_1-38_PDL_Rep2_ATH1", + "Finch-Savage_1-39_PDL_Rep3_ATH1", + "Finch-Savage_1-40_PDL_Rep4_ATH1" + ], + "DL": [ + "Finch-Savage_1-5_AND_Rep1_ATH1", + "Finch-Savage_1-6_AND_Rep2_ATH1", + "Finch-Savage_1-7_AND_Rep3_ATH1", + "Finch-Savage_1-8_AND_Rep4_ATH1" + ], + "PDN": [ + "Finch-Savage_1-41_PDN_Rep1_ATH1", + "Finch-Savage_1-42_PDN_Rep2_ATH1", + "Finch-Savage_1-43_PDN_Rep3_ATH1", + "Finch-Savage_1-44_PDN_Rep4_ATH1" + ], + "PDLN": [ + "Finch-Savage_1-45_PDLN_Rep1_ATH1", + "Finch-Savage_1-46_PDLN_Rep2_ATH1", + "Finch-Savage_1-47_PDLN_Rep3_ATH1", + "Finch-Savage_1-48_PDLN_Rep4_ATH1" + ], + "LIG": [ + "Finch-Savage_1-25_LIG_Rep1_ATH1", + "Finch-Savage_1-26_LIG_Rep2_ATH1", + "Finch-Savage_1-27_LIG_Rep3_ATH1", + "Finch-Savage_1-28_LIG_Rep4_ATH1" + ], + "aba1-1": [ + "Carrera Begua_1-7_aba_Rep1_ATH1", + "Carrera Begua_1-8_aba_Rep2_ATH1", + "Carrera Begua_1-9_aba_Rep3_ATH1" + ], + "abi1-1": [ + "Carrera Begua_1-10_abi1_Rep1_ATH1", + "Carrera Begua_1-11_abi1_Rep2_ATH1", + "Carrera Begua_1-12_abi1-Rep3_ATH1" + ], + "abi3-4": [ + "Carrera Begua_1-13_abi3_Rep1_ATH1", + "Carrera Begua_1-14_abi3_Rep2_ATH1", + "Carrera Begua_1-15_abi3_Rep3_ATH1" + ], + "cts1": [ + "Carrera Begua_1-31_cts1-24hr-dormancy_Rep1_ATH1", + "Carrera Begua_1-32_cts1-24hr-dormancy_Rep2_ATH1", + "Carrera Begua_1-33_cts1-24hr-dormancy_Rep3_ATH1" + ], + "fus3-8": [ + "Carrera Begua_1-16_fus_Rep1_ATH1", + "Carrera Begua_1-17_fus_Rep2_ATH1", + "Carrera Begua_1-18_fus_Rep3_ATH1" + ], + "rdo2": [ + "Carrera Begua_1-19_rdo_Rep1_ATH1", + "Carrera Begua_1-20_rdo_Rep2_ATH1", + "Carrera Begua_1-21_rdo_Rep3_ATH1" + ], + "Ler_Fresh": [ + "Carrera Begua_1-4_ido_Rep1_ATH1", + "Carrera Begua_1-5_ido_Rep2_ATH1", + "Carrera Begua_1-6_ido_Rep3_ATH1" + ], + "Ler_After-ripened": [ + "Carrera Begua_1-1_lar_Rep1_ATH1", + "Carrera Begua_1-2_lar_Rep2_ATH1", + "Carrera Begua_1-3_lar_Rep3_ATH1" + ], + "Cvi_Fresh": [ + "Carrera Begua_1-22_CVI-24hr-dormancy_Rep1_ATH1", + "Carrera Begua_1-23_CVI-24hr-dormancy_Rep2_ATH1", + "Carrera Begua_1-24_CVI-24hr-dormancy_Rep3_ATH1" + ], + "Cvi_After-ripened": [ + "Carrera Begua_1-25_CVI-24hr-ripening_Rep1_ATH1", + "Carrera Begua_1-26_CVI-24hr-ripening_Rep2_ATH1", + "Carrera Begua_1-27_CVI-24hr-ripening_Rep3_ATH1" + ], + "abi4_dry_seed": [ + "abi4_ds_rep1", + "abi4_ds_rep2" + ], + "abi4_24_HAI": [ + "abi4_24HAI_rep1", + "abi4_24HAI_rep2" + ], + "abi5_dry_seed": [ + "abi5_ds_rep1", + "abi5_ds_rep2" + ], + "abi5_24_HAI": [ + "abi5_24HAI_rep1", + "abi5_24HAI_rep2" + ] + } + }, + "Germination_inhibitors": { + "controls": [ + "bot0142", + "bot0314", + "bot0394" + ], + "treatments": { + "DMSO": [ + "bot0142", + "bot0314", + "bot0394" + ], + "Cycloheximide": [ + "bot0256", + "bot0257" + ], + "Methotrexate": [ + "bot0293", + "bot0294" + ], + "2,4-DNP": [ + "bot0246", + "bot0247" + ] + } + }, + "Seed_Development": { + "controls": [ + "SEED_LCM_CTRL" + ], + "treatments": { + "embryo_pre-globular_stage": [ + "GSM311273", + "GSM311274" + ], + "micropylar_endosperm_pre-globular_stage": [ + "GSM311275", + "GSM311276" + ], + "peripheral_endosperm_pre-globular_stage": [ + "GSM311277", + "GSM311278" + ], + "chalazal_endosperm_pre-globular_stage": [ + "GSM311279", + "GSM311280" + ], + "chalazal_seed_coat_pre-globular_stage": [ + "GSM311281", + "GSM311282" + ], + "general_seed_coat_pre-globular_stage": [ + "GSM311283", + "GSM311284" + ], + "embryo_globular_stage": [ + "GSM284384", + "GSM284385" + ], + "suspensor_globular_stage": [ + "GSM284386", + "GSM284387" + ], + "micropylar_endosperm_globular_stage": [ + "GSM284388", + "GSM284389" + ], + "peripheral_endosperm_globular_stage": [ + "GSM284390", + "GSM284391" + ], + "chalazal_endosperm_globular_stage": [ + "GSM284392", + "GSM284393", + "GSM284394" + ], + "chalazal_seed_coat_globular_stage": [ + "GSM284395", + "GSM284396" + ], + "general_seed_coat_globular_stage": [ + "GSM284397", + "GSM284398" + ], + "embryo_proper_heart_stage": [ + "GSM378645", + "GSM378646" + ], + "micropylar_endosperm_heart_stage": [ + "GSM378647", + "GSM378648" + ], + "peripheral_endosperm_heart_stage": [ + "GSM378649", + "GSM378650" + ], + "chalazal_endosperm_heart_stage": [ + "GSM378651", + "GSM378652", + "GSM378653" + ], + "chalazal_seed_coat_heart_stage": [ + "GSM378654", + "GSM378655", + "GSM378656" + ], + "seed_coat_heart_stage": [ + "GSM378657", + "GSM378658" + ], + "embryo__proper_linear-cotyledon_stage": [ + "GSM311287", + "GSM311288" + ], + "cellularized_endosperm_linear-cotyledon_stage": [ + "GSM311289", + "GSM311290" + ], + "chalazal_endosperm_linear-cotyledon_stage": [ + "GSM311291", + "GSM311292" + ], + "chalazal_seed_coat_linear-cotyledon_stage": [ + "GSM311293", + "GSM311294" + ], + "general_seed_coat_linear-cotyledon_stage": [ + "GSM311295", + "GSM311296" + ], + "embryo_proper_mature_green_stage": [ + "GSM378733", + "GSM378734" + ], + "micropylar_endosperm_mature_green_stage": [ + "GSM378735", + "GSM378736" + ], + "peripherial_endosperm_mature_green_stage": [ + "GSM378737", + "GSM378738" + ], + "chalazal_endosperm_mature_green_stage": [ + "GSM378739", + "GSM378740" + ], + "chalazal_seed_coat_mature_green_stage": [ + "GSM378741", + "GSM378742" + ], + "seed_coat_mature_green_stage": [ + "GSM378743", + "GSM378744" + ] + } + } + } + }, + "Shoot_Apex": { + "database": "shoot_apex", + "view_name": "Shoot_Apex", + "groups": { + "ShootApexGroup": { + "controls": [ + "AVG" + ], + "treatments": { + "ATML1": [ + "ATML1" + ], + "FIL": [ + "FIL" + ], + "PTL": [ + "PTL" + ], + "AS2": [ + "AS2" + ], + "WUS": [ + "WUS" + ], + "CLV3": [ + "CLV3" + ], + "UFO": [ + "UFO" + ], + "LAS": [ + "LAS" + ] + } + } + } + }, + "Silique": { + "database": "silique", + "view_name": "Silique", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Silique_3DAP": [ + "3_dap-1_AGTTCC_L006_R1_001", + "3_dap-2_GAGTGG_L006_R1_001", + "3_dap-3_ATTCCT_L006_R1_001" + ], + "Silique_6DAP": [ + "6_dap-1_CGATGT_L005_R1_001", + "6_dap-2_TTAGGC_L005_R1_001", + "6_dap-3_TGACCA_L005_R1_001", + "6_dap_n_1_ATCACG_L001_R1_001_6_dap_n_1_ATCACG_L002_R1_001", + "6_dap_n_2_TGACCA_L001_R1_001_6_dap_n_2_TGACCA_L002_R1_001", + "6_dap_n_3_ACAGTG_L001_R1_001_6_dap_n_3_ACAGTG_L002_R1_001" + ], + "Silique_9DAP": [ + "9_dap-1_CAGATC_L005_R1_001", + "9_dap-2_GATCAG_L005_R1_001", + "9_dap-3_ACTGAT_L005_R1_001", + "9_dap_n_1_ACTTGA_L001_R1_001_9_dap_n_1_ACTTGA_L002_R1_001", + "9_dap_n_2_TAGCTT_L001_R1_001_9_dap_n_2_TAGCTT_L002_R1_001", + "9_dap_n_3_GGCTAC_L001_R1_001_9_dap_n_3_GGCTAC_L002_R1_001" + ], + "Silique_12DAP": [ + "12_dap-1_ATCACG_L006_R1_001", + "12_dap-2_ACAGTG_L006_R1_001", + "12_dap-3_GGCTAC_L006_R1_001" + ] + } + } + } + }, + "Single_Cell": { + "database": "single_cell", + "view_name": "Single_Cell", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Stele_cells_(6)": [ + "cluster6_WT1.ExprMean", + "cluster6_WT2.ExprMean", + "cluster6_WT3.ExprMean" + ], + "Differentiating_non-hair_epidermal_cells_(1)": [ + "cluster1_WT1.ExprMean", + "cluster1_WT2.ExprMean", + "cluster1_WT3.ExprMean" + ], + "Endodermis_cells_(12)": [ + "cluster12_WT1.ExprMean", + "cluster12_WT2.ExprMean", + "cluster12_WT3.ExprMean" + ], + "Stele_cells_(18)": [ + "cluster18_WT1.ExprMean", + "cluster18_WT2.ExprMean", + "cluster18_WT3.ExprMean" + ], + "Stele_cells_(including_pericyte)_(7)": [ + "cluster7_WT1.ExprMean", + "cluster7_WT2.ExprMean", + "cluster7_WT3.ExprMean" + ], + "Mid-stage_differentiating_root_hair_epidermal_cells_(4)": [ + "cluster4_WT1.ExprMean", + "cluster4_WT2.ExprMean", + "cluster4_WT3.ExprMean" + ], + "Dividing_meristem_cell_(25)": [ + "cluster25_WT1.ExprMean", + "cluster25_WT2.ExprMean", + "cluster25_WT3.ExprMean" + ], + "Late-stage_differentiating_root_hair_epidermal_cells_(3)": [ + "cluster3_WT1.ExprMean", + "cluster3_WT2.ExprMean", + "cluster3_WT3.ExprMean" + ], + "Stele_cells_(including_pericyte)_(14)": [ + "cluster14_WT1.ExprMean", + "cluster14_WT2.ExprMean", + "cluster14_WT3.ExprMean" + ], + "Cortex_cells_(31)": [ + "cluster31_WT1.ExprMean", + "cluster31_WT2.ExprMean", + "cluster31_WT3.ExprMean" + ], + "Stele_cells_(20)": [ + "cluster20_WT1.ExprMean", + "cluster20_WT2.ExprMean", + "cluster20_WT3.ExprMean" + ], + "Differentiating_endodermis/cortex_cells_(30)": [ + "cluster30_WT1.ExprMean", + "cluster30_WT2.ExprMean", + "cluster30_WT3.ExprMean" + ], + "Phloem_cells_(21)": [ + "cluster21_WT1.ExprMean", + "cluster21_WT2.ExprMean", + "cluster21_WT3.ExprMean" + ], + "Lateral_root_cap_cells_(2)": [ + "cluster2_WT1.ExprMean", + "cluster2_WT2.ExprMean", + "cluster2_WT3.ExprMean" + ], + "Quiescent_center_cells_and_young_meristem_cells_(17)": [ + "cluster17_WT1.ExprMean", + "cluster17_WT2.ExprMean", + "cluster17_WT3.ExprMean" + ], + "Root_hair_epidermal_cells_(10)": [ + "cluster10_WT1.ExprMean", + "cluster10_WT2.ExprMean", + "cluster10_WT3.ExprMean" + ], + "Non-hair_epidermal_cells_(16)": [ + "cluster16_WT1.ExprMean", + "cluster16_WT2.ExprMean", + "cluster16_WT3.ExprMean" + ], + "Early-stage_differentiating_root_hair_epidermal_cells_(5)": [ + "cluster5_WT1.ExprMean", + "cluster5_WT2.ExprMean", + "cluster5_WT3.ExprMean" + ], + "Differentiating_lateral_root_cap_cells_(8)": [ + "cluster8_WT1.ExprMean", + "cluster8_WT2.ExprMean", + "cluster8_WT3.ExprMean" + ], + "Stele_cells_(34)": [ + "cluster34_WT1.ExprMean", + "cluster34_WT2.ExprMean", + "cluster34_WT3.ExprMean" + ], + "Root_hair_epidermal_cells_(26)": [ + "cluster26_WT1.ExprMean", + "cluster26_WT2.ExprMean", + "cluster26_WT3.ExprMean" + ], + "Cortex_cells_(11)": [ + "cluster11_WT1.ExprMean", + "cluster11_WT2.ExprMean", + "cluster11_WT3.ExprMean" + ], + "Differentiating_endodermis/cortex_cells_(0)": [ + "cluster0_WT1.ExprMean", + "cluster0_WT2.ExprMean", + "cluster0_WT3.ExprMean" + ], + "Columella_root_cap_cells_(28)": [ + "cluster28_WT1.ExprMean", + "cluster28_WT2.ExprMean", + "cluster28_WT3.ExprMean" + ], + "Stele_cells_(9)": [ + "cluster9_WT1.ExprMean", + "cluster9_WT2.ExprMean", + "cluster9_WT3.ExprMean" + ], + "Xylem_cells_(27)": [ + "cluster27_WT1.ExprMean", + "cluster27_WT2.ExprMean", + "cluster27_WT3.ExprMean" + ], + "Early-stage_differentiating_endodermis/cortex_cells": [ + "cluster13_WT1.ExprMean", + "cluster13_WT2.ExprMean", + "cluster13_WT3.ExprMean" + ], + "Xylem_cells_(23)": [ + "cluster23_WT1.ExprMean", + "cluster23_WT2.ExprMean", + "cluster23_WT3.ExprMean" + ], + "Early-stage_differentiating_endodermis/cortex_cells_(35)": [ + "cluster35_WT1.ExprMean", + "cluster35_WT2.ExprMean", + "cluster35_WT3.ExprMean" + ], + "Early-stage_differentiating_root_hair_epidermal_cells_(15)": [ + "cluster15_WT1.ExprMean", + "cluster15_WT2.ExprMean", + "cluster15_WT3.ExprMean" + ], + "Cortex_cells_(19)": [ + "cluster19_WT1.ExprMean", + "cluster19_WT2.ExprMean", + "cluster19_WT3.ExprMean" + ], + "Dividing_meristem_cells_(24)": [ + "cluster24_WT1.ExprMean", + "cluster24_WT2.ExprMean", + "cluster24_WT3.ExprMean" + ], + "Differentiating_endodermis/cortex_cells_(29)": [ + "cluster29_WT1.ExprMean", + "cluster29_WT2.ExprMean", + "cluster29_WT3.ExprMean" + ], + "Dividing_meristem_cells_(32)": [ + "cluster32_WT1.ExprMean", + "cluster32_WT2.ExprMean", + "cluster32_WT3.ExprMean" + ], + "Protoxylem_cells_(33)": [ + "cluster33_WT1.ExprMean", + "cluster33_WT2.ExprMean", + "cluster33_WT3.ExprMean" + ], + "Endodermis_cells_(22)": [ + "cluster22_WT1.ExprMean", + "cluster22_WT2.ExprMean", + "cluster22_WT3.ExprMean" + ] + } + } + } + }, + "Tissue_Specific": { + "database": "atgenexp_plus", + "view_name": "Tissue_Specific", + "groups": { + "ATGE_CTRL_7": { + "controls": [ + "ATGE_CTRL_7" + ], + "treatments": { + "AtHB8": [ + "GSM706472", + "GSM706473", + "GSM706474" + ] + } + } + } + } + } + } + }, + "arabidopsis seedcoat": { + + "data": { + "species": "arabidopsis seedcoat", + "views": { + "Seed_Coat": { + "database": "seedcoat", + "view_name": "Seed_Coat", + "groups": { + "ap2-7_mutant_seed": { + "controls": [ + "ap2-3-1", + "ap2-3-10", + "ap2-3-11", + "ap2-3-12", + "ap2-3-2", + "ap2-3-3", + "ap2-3-4", + "ap2-3-5", + "ap2-3-6", + "ap2-3-7", + "ap2-3-8", + "ap2-3-9" + ], + "treatments": { + "ap2-7_seedcoat,_11_dpa": [ + "ap2-11-1", + "ap2-11-10", + "ap2-11-11", + "ap2-11-12", + "ap2-11-2", + "ap2-11-3", + "ap2-11-4", + "ap2-11-5", + "ap2-11-6", + "ap2-11-7", + "ap2-11-8", + "ap2-11-9" + ], + "ap2-7_seedcoat,_3_dpa": [ + "ap2-3-1", + "ap2-3-10", + "ap2-3-11", + "ap2-3-12", + "ap2-3-2", + "ap2-3-3", + "ap2-3-4", + "ap2-3-5", + "ap2-3-6", + "ap2-3-7", + "ap2-3-8", + "ap2-3-9" + ], + "ap2-7_seedcoat,_7_dpa": [ + "ap2-7-1", + "ap2-7-10", + "ap2-7-11", + "ap2-7-12", + "ap2-7-13", + "ap2-7-14", + "ap2-7-15", + "ap2-7-16", + "ap2-7-2", + "ap2-7-3", + "ap2-7-4", + "ap2-7-5", + "ap2-7-6", + "ap2-7-7", + "ap2-7-8", + "ap2-7-9" + ] + } + }, + "Col-2_wild-type_seed": { + "controls": [ + "col2-3-1", + "col2-3-2", + "col2-3-3", + "col2-3-4", + "col2-3-5", + "col2-3-6", + "col2-3-7", + "col2-3-8" + ], + "treatments": { + "Col-2_wt_seedcoat,_11_dpa": [ + "col2-11-1", + "col2-11-2", + "col2-11-3", + "col2-11-4", + "col2-11-5", + "col2-11-6", + "col2-11-7", + "col2-11-8" + ], + "Col-2_wt_seedcoat,_3_dpa": [ + "col2-3-1", + "col2-3-2", + "col2-3-3", + "col2-3-4", + "col2-3-5", + "col2-3-6", + "col2-3-7", + "col2-3-8" + ], + "Col-2_wt_seedcoat,_7_dpa": [ + "col2-7-1", + "col2-7-10", + "col2-7-11", + "col2-7-12", + "col2-7-2", + "col2-7-3", + "col2-7-4", + "col2-7-5", + "col2-7-6", + "col2-7-7", + "col2-7-8", + "col2-7-9" + ] + } + }, + "tt16-1_mutant_seed": { + "controls": [ + "ws2-3-1", + "ws2-3-2", + "ws2-3-3", + "ws2-3-4", + "ws2-3-5", + "ws2-3-6", + "ws2-3-7", + "ws2-3-8" + ], + "treatments": { + "Ws-2_seedcoat,_11_dpa": [ + "ws2-11-1", + "ws2-11-2", + "ws2-11-3", + "ws2-11-4", + "ws2-11-5", + "ws2-11-6", + "ws2-11-7", + "ws2-11-8" + ], + "Ws-2_seedcoat,_3_dpa": [ + "ws2-3-1", + "ws2-3-2", + "ws2-3-3", + "ws2-3-4", + "ws2-3-5", + "ws2-3-6", + "ws2-3-7", + "ws2-3-8" + ], + "Ws-2_seedcoat,_7_dpa": [ + "ws2-7-1", + "ws2-7-10", + "ws2-7-11", + "ws2-7-12", + "ws2-7-2", + "ws2-7-3", + "ws2-7-4", + "ws2-7-5", + "ws2-7-6", + "ws2-7-7", + "ws2-7-8", + "ws2-7-9" + ] + } + } + } + } + } + } + }, + "arachis": { + + "data": { + "species": "arachis", + "views": { + "Arachis_Atlas": { + "database": "arachis", + "view_name": "Arachis_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Pattee_1_stalk:__Gynophore_stalk_at_pod_swelling_(Pattee_stage_1)": [ + "Pattee_1_Stalk" + ], + "subterranean_gynophore_tip:__5_mm_(=mostly_ovary_and_zone_of_cell_division)_from_elongating_peg_of_approximately_same_length_as_#9,_but_24_h_after_soil_penetration": [ + "Subterranean_Gynophore_Tip" + ], + "Pattee_1_pod:__Whole_pod_at_pod_swelling_(Pattee_stage_1)": [ + "Pattee_1_Pod" + ], + "Pattee_6_seed:__Torpedo_shaped;_generally_pink_at_embryonic-axis_end_of_kernels_(Pattee_stage_6)": [ + "Pattee_6_Seed" + ], + "aerial_gynophore_tip:__5_mm_(=mostly_ovary_and_zone_of_cell_division)_from_elongating_peg_prior_to_soil_penetration": [ + "Aerial_Gynophore_Tip" + ], + "Pattee_5_seed:__Embryo_flat,_white_or_just_turning_pink_at_one_end_(Pattee_stage_5)": [ + "Pattee_5_Seed" + ], + "Pattee_7_seed:__Torpedo_to_round_shaped;_embryonic_axis_end_of_kernel_pink;_other_end_white_to_light_pink_(Pattee_stage_7)": [ + "Pattee_7_Seed" + ], + "vegetative_shoot_tip:__Growth_stage_Boote_R1_first_flower,_from_mainstem_(n);_5_mm_maxium_length": [ + "Vegetative_Shoot_Tip" + ], + "androecium:__Fully_open,_morning_of_anthesis;_staminal_tube,_filaments_and_anthers": [ + "Androecium" + ], + "reproductive_shoot_tip:__Growth_stage_Boote_R1_first_flower,_from_laterals__(n+1);_5_mm_maxium_length": [ + "Reproductive_Shoot_Tip" + ], + "nodules:__25_d_post-emergence": [ + "Nodules" + ], + "Pattee_10_seed:__Large,_generally_dark_pink_all_over;_seed_coat_beginning_to_dry_out_(Pattee_stage_10)": [ + "Pattee_10_Seed" + ], + "Pattee_5_pericarp:__Pericarp_soft,_not_as_watery,_inner_pericarp_without_cracks_(Pattee_stage_5)": [ + "Pattee_5_Pericarp" + ], + "Pattee_8_seed:__Round,_light_pink_all_over_(Pattee_stage_8)": [ + "Pattee_8_Seed" + ], + "Pattee_3_pod:__Pericarp_very_watery,_embryo_very_small_and_not_easily_removed_(Pattee_stage_3/4)": [ + "Pattee_3_Pod" + ], + "seedling_leaf:__10_d_post-emergence;_leaflets_partially_open": [ + "Seedling_Leaf" + ], + "perianth:__Fully_open,_morning_of_anthesis;_wings,_banner,_hypanthium,_keel_and_lower_lip_of_the_calyx": [ + "Perianth" + ], + "gynoecium:__Fully_open,_morning_of_anthesis;_stigma,_style_and_overy": [ + "Gynoecium" + ], + "lateral_stem_leaf:__Growth_stage_Boote_R1_first_flower;_leaflets_partially_open,_from_laterals__(n+1)": [ + "Lateral_Stem_Leaf" + ], + "Pattee_6_pericarp:__Inner_pericarp_tissue_beginning_to_show_cracks_or_cottony_(Pattee_stage_6/7)": [ + "Pattee_6_Pericarp" + ], + "root_:__10_d_post-emergence": [ + "Roots" + ] + } + }, + "Pattee_10_Seed": { + "controls": [ + "Pattee_10_Seed" + ], + "treatments": { + "main_stem_leaf:__Growth_stage_Boote_R1_first_flower;_leaflets_partially_open,_from_main_stem_(n)": [ + "Main_Stem_Leaf" + ] + } + } + } + } + } + } + }, + "barley": { + + "data": { + "species": "barley", + "views": { + "barley_mas": { + "database": "barley_mas", + "view_name": "barley_mas", + "groups": { + "Seedling": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Leaf": [ + "MX_Leafrep1", + "MX_Leafrep2", + "MX_Leafrep3" + ], + "Golden_Promise_Leaf": [ + "GP_Leafrep1", + "GP_Leafrep2", + "GP_Leafrep3" + ], + "Morex_Crown": [ + "MX_Crownrep1", + "MX_Crownrep2", + "MX_Crownrep3" + ], + "Golden_Promise_Crown": [ + "GP_Crownrep1", + "GP_Crownrep2", + "GP_Crownrep3" + ], + "Morex_Root": [ + "MX_Rootrep1", + "MX_Rootrep2", + "MX_Rootrep3" + ], + "Golden_Promise_Root": [ + "GP_Rootrep1", + "GP_Rootrep2", + "GP_Rootrep3" + ] + } + }, + "Germinating_Seedling": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Coleoptile": [ + "MX_Coleoptilerep1", + "MX_Coleoptilerep2", + "MX_Coleoptilerep3" + ], + "Golden_Promise_Coleoptile": [ + "GP_Coleoptilerep1", + "GP_Coleoptilerep2", + "GP_Coleoptilerep3" + ], + "Morex_Mesocotyl": [ + "MX_Embryorep1", + "MX_Embryorep2", + "MX_Embryorep3" + ], + "Golden_Promise_Mesocotyl": [ + "GP_Embryorep1", + "GP_Embryorep2", + "GP_Embryorep3" + ], + "Morex_Radicle": [ + "MX_Radiclerep1", + "MX_Radiclerep2", + "MX_Radiclerep3" + ], + "Golden_Promise_Radicle": [ + "GP_Radiclerep1", + "GP_Radiclerep2", + "GP_Radiclerep3" + ] + } + }, + "Caryopsis_without_Embryo": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Caryopsis_without_Embryo": [ + "MX_Endosperm22DAPrep1", + "MX_Endosperm22DAPrep2", + "MX_Endosperm22DAPrep3" + ] + } + }, + "Embryo": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Embryo_22_DAP": [ + "MX_Embryo22DAPrep1", + "MX_Embryo22DAPrep2", + "MX_Embryo22DAPrep3" + ] + } + }, + "Caryopsis": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Caryopsis_5_DAP": [ + "MX_Caryopsis5DAPrep1", + "MX_Caryopsis5DAPrep2", + "MX_Caryopsis5DAPrep3" + ], + "Caryopsis_10_DAP": [ + "MX_Caryopsis10DAPrep1", + "MX_Caryopsis10DAPrep2", + "MX_Caryopsis10DAPrep3" + ], + "Caryopsis_16_DAP": [ + "MX_Caryopsis16DAPrep1", + "MX_Caryopsis16DAPrep2", + "MX_Caryopsis16DAPrep3" + ] + } + }, + "Floral_Bracts": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Floral_Bracts": [ + "MX_FloralBractsrep1", + "MX_FloralBractsrep2", + "MX_FloralBractsrep3" + ] + } + }, + "Anthers": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Anthers": [ + "MX_Anthersrep1", + "MX_Anthersrep2", + "MX_Anthersrep3" + ] + } + }, + "Pistil": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Pistil": [ + "MX_Pistilrep1", + "MX_Pistilrep2", + "MX_Pistilrep3" + ] + } + }, + "Immature_Inflorescence": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Immature_Inflorescence": [ + "MX_Inflorescencerep1", + "MX_Inflorescencerep2", + "MX_Inflorescencerep3" + ] + } + }, + "Spike": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Lemma": [ + "Lemma_Rep1", + "Lemma_Rep2", + "Lemma_Rep3" + ], + "Palea": [ + "Palea_Rep1", + "Palea_Rep2", + "Palea_Rep3" + ], + "Awn": [ + "Awn_Rep1", + "Awn_Rep2", + "Awn_Rep3" + ] + } + } + } + }, + "barley_rma": { + "database": "barley_rma", + "view_name": "barley_rma", + "groups": { + "Seedling": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Leaf": [ + "MX_Leafrep1", + "MX_Leafrep2", + "MX_Leafrep3" + ], + "Golden_Promise_Leaf": [ + "GP_Leafrep1", + "GP_Leafrep2", + "GP_Leafrep3" + ], + "Morex_Crown": [ + "MX_Crownrep1", + "MX_Crownrep2", + "MX_Crownrep3" + ], + "Golden_Promise_Crown": [ + "GP_Crownrep1", + "GP_Crownrep2", + "GP_Crownrep3" + ], + "Morex_Root": [ + "MX_Rootrep1", + "MX_Rootrep2", + "MX_Rootrep3" + ], + "Golden_Promise_Root": [ + "GP_Rootrep1", + "GP_Rootrep2", + "GP_Rootrep3" + ] + } + }, + "Germinating_Seedling": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Coleoptile": [ + "MX_Coleoptilerep1", + "MX_Coleoptilerep2", + "MX_Coleoptilerep3" + ], + "Golden_Promise_Coleoptile": [ + "GP_Coleoptilerep1", + "GP_Coleoptilerep2", + "GP_Coleoptilerep3" + ], + "Morex_Mesocotyl": [ + "MX_Embryorep1", + "MX_Embryorep2", + "MX_Embryorep3" + ], + "Golden_Promise_Mesocotyl": [ + "GP_Embryorep1", + "GP_Embryorep2", + "GP_Embryorep3" + ], + "Morex_Radicle": [ + "MX_Radiclerep1", + "MX_Radiclerep2", + "MX_Radiclerep3" + ], + "Golden_Promise_Radicle": [ + "GP_Radiclerep1", + "GP_Radiclerep2", + "GP_Radiclerep3" + ] + } + }, + "Caryopsis_without_Embryo": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Morex_Caryopsis_without_Embryo": [ + "MX_Endosperm22DAPrep1", + "MX_Endosperm22DAPrep2", + "MX_Endosperm22DAPrep3" + ] + } + }, + "Embryo": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Embryo_22_DAP": [ + "MX_Embryo22DAPrep1", + "MX_Embryo22DAPrep2", + "MX_Embryo22DAPrep3" + ] + } + }, + "Caryopsis": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Caryopsis_5_DAP": [ + "MX_Caryopsis5DAPrep1", + "MX_Caryopsis5DAPrep2", + "MX_Caryopsis5DAPrep3" + ], + "Caryopsis_10_DAP": [ + "MX_Caryopsis10DAPrep1", + "MX_Caryopsis10DAPrep2", + "MX_Caryopsis10DAPrep3" + ], + "Caryopsis_16_DAP": [ + "MX_Caryopsis16DAPrep1", + "MX_Caryopsis16DAPrep2", + "MX_Caryopsis16DAPrep3" + ] + } + }, + "Floral_Bracts": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Floral_Bracts": [ + "MX_FloralBractsrep1", + "MX_FloralBractsrep2", + "MX_FloralBractsrep3" + ] + } + }, + "Anthers": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Anthers": [ + "MX_Anthersrep1", + "MX_Anthersrep2", + "MX_Anthersrep3" + ] + } + }, + "Pistil": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Pistil": [ + "MX_Pistilrep1", + "MX_Pistilrep2", + "MX_Pistilrep3" + ] + } + }, + "Immature_Inflorescence": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Immature_Inflorescence": [ + "MX_Inflorescencerep1", + "MX_Inflorescencerep2", + "MX_Inflorescencerep3" + ] + } + }, + "Spike": { + "controls": [ + "BARLEY_CTRL", + "BARLEY_CTRL" + ], + "treatments": { + "Lemma": [ + "Lemma_Rep1", + "Lemma_Rep2", + "Lemma_Rep3" + ], + "Palea": [ + "Palea_Rep1", + "Palea_Rep2", + "Palea_Rep3" + ], + "Awn": [ + "Awn_Rep1", + "Awn_Rep2", + "Awn_Rep3" + ] + } + } + } + } + } + } + }, + "brachypodium": { + + "data": { + "species": "brachypodium", + "views": { + "Brachypodium_Atlas": { + "database": "brachypodium", + "view_name": "Brachypodium_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "I:_De-etiolated_shoots_3_DAG_1": [ + "I:_De-etiolated_shoots_3_DAG_1", + "I:_De-etiolated_shoots_3_DAG_2", + "I:_De-etiolated_shoots_3_DAG_3" + ], + "I:_Etiolated_shoots_3_DAG_1": [ + "I:_Etiolated_shoots_3_DAG_1", + "I:_Etiolated_shoots_3_DAG_2", + "I:_Etiolated_shoots_3_DAG_3" + ], + "P:_Coleoptile_10_DAG_1": [ + "P:_Coleoptile_10_DAG_1", + "P:_Coleoptile_10_DAG_2" + ], + "P:_Coleoptile_17+27_DAG_1": [ + "P:_Coleoptile_17+27_DAG_1", + "P:_Coleoptile_17+27_DAG_2", + "P:_Coleoptile_17+27_DAG_3" + ], + "P:_First_internode_10_DAG_1": [ + "P:_First_internode_10_DAG_1", + "P:_First_internode_10_DAG_2", + "P:_First_internode_10_DAG_3", + "P:_First_internode_10_DAG_4" + ], + "P:_First_internode_17_DAG_1": [ + "P:_First_internode_17_DAG_1", + "P:_First_internode_17_DAG_2" + ], + "P:_First_internode_27_DAG_1": [ + "P:_First_internode_27_DAG_1", + "P:_First_internode_27_DAG_2", + "P:_First_internode_27_DAG_3" + ], + "P:_First_internode_35_DAG_1": [ + "P:_First_internode_35_DAG_1", + "P:_First_internode_35_DAG_2" + ], + "P:_First_internode_60_DAG_1": [ + "P:_First_internode_60_DAG_1", + "P:_First_internode_60_DAG_2" + ], + "P:_First_node_+_adventitious_roots_35_DAG_1": [ + "P:_First_node_+_adventitious_roots_35_DAG_1", + "P:_First_node_+_adventitious_roots_35_DAG_2" + ], + "P:_First_node_10_DAG_1": [ + "P:_First_node_10_DAG_1", + "P:_First_node_10_DAG_2" + ], + "P:_First_node_17_DAG_2": [ + "P:_First_node_17_DAG_1", + "P:_First_node_17_DAG_2", + "P:_First_node_17_DAG_3" + ], + "P:_First_node_27_DAG_1": [ + "P:_First_node_27_DAG_1", + "P:_First_node_27_DAG_2" + ], + "P:_First_node_60_DAG_1": [ + "P:_First_node_60_DAG_1", + "P:_First_node_60_DAG_2" + ], + "P:_Last_internode_60_DAG_1": [ + "P:_Last_internode_60_DAG_1", + "P:_Last_internode_60_DAG_2" + ], + "P:_Leaf_10_DAG_1": [ + "P:_Leaf_10_DAG_1", + "P:_Leaf_10_DAG_2" + ], + "P:_Leaf_17_DAG_1": [ + "P:_Leaf_17_DAG_1", + "P:_Leaf_17_DAG_2", + "P:_Leaf_17_DAG_3" + ], + "P:_Leaf_27_DAG_1": [ + "P:_Leaf_27_DAG_1", + "P:_Leaf_27_DAG_2", + "P:_Leaf_27_DAG_3" + ], + "P:_Leaf_60_DAG_1": [ + "P:_Leaf_60_DAG_1", + "P:_Leaf_60_DAG_2", + "P:_Leaf_60_DAG_3" + ], + "P:_Roots_10_DAG_1": [ + "P:_Roots_10_DAG_1", + "P:_Roots_10_DAG_2", + "P:_Roots_10_DAG_3" + ], + "P:_Second_internode_17_DAG_1": [ + "P:_Second_internode_17_DAG_1", + "P:_Second_internode_17_DAG_2", + "P:_Second_internode_17_DAG_3" + ], + "P:_Second_internode_27_DAG_1": [ + "P:_Second_internode_27_DAG_1", + "P:_Second_internode_27_DAG_2", + "P:_Second_internode_27_DAG_3" + ], + "P:_Young_spikelet_3_DAH_1": [ + "P:_Young_spikelet_3_DAH_1", + "P:_Young_spikelet_3_DAH_2", + "P:_Young_spikelet_3_DAH_3" + ], + "T:_First_internode_60_DAG_1": [ + "T:_First_internode_60_DAG_1", + "T:_First_internode_60_DAG_2", + "T:_First_internode_60_DAG_3" + ], + "T:_Last_internode_60_DAG_1": [ + "T:_Last_internode_60_DAG_1", + "T:_Last_internode_60_DAG_2", + "T:_Last_internode_60_DAG_3" + ], + "T:_Mature_leaf,_fully_expanded_60_DAG_1": [ + "T:_Mature_leaf,_fully_expanded_60_DAG_1", + "T:_Mature_leaf,_fully_expanded_60_DAG_2", + "T:_Mature_leaf,_fully_expanded_60_DAG_3" + ], + "T:_Young_leaf,_under_6_cm_60_DAG_1": [ + "T:_Young_leaf,_under_6_cm_60_DAG_1", + "T:_Young_leaf,_under_6_cm_60_DAG_2", + "T:_Young_leaf,_under_6_cm_60_DAG_3" + ], + "V:_Endosperm_11_DAF_1": [ + "V:_Endosperm_11_DAF_1", + "V:_Endosperm_11_DAF_2", + "V:_Endosperm_11_DAF_3" + ], + "V:_Endosperm_31_DAF_1": [ + "V:_Endosperm_31_DAF_1" + ], + "V:_First_spikelet_internode_42_DAG_1": [ + "V:_First_spikelet_internode_42_DAG_1", + "V:_First_spikelet_internode_42_DAG_2" + ], + "V:_Last_internode_35_DAG_1": [ + "V:_Last_internode_35_DAG_1", + "V:_Last_internode_35_DAG_2" + ], + "V:_Last_node_35_DAG_1": [ + "V:_Last_node_35_DAG_1", + "V:_Last_node_35_DAG_2", + "V:_Last_node_35_DAG_3" + ], + "V:_Last_spikelet_internode_42_DAG_1": [ + "V:_Last_spikelet_internode_42_DAG_1", + "V:_Last_spikelet_internode_42_DAG_2", + "V:_Last_spikelet_internode_42_DAG_3" + ], + "V:_Lower_part_of_inclined_node_42_DAG_1": [ + "V:_Lower_part_of_inclined_node_42_DAG_1", + "V:_Lower_part_of_inclined_node_42_DAG_2" + ], + "V:_Peduncle,_first_2_cm_42_DAG_1": [ + "V:_Peduncle,_first_2_cm_42_DAG_1", + "V:_Peduncle,_first_2_cm_42_DAG_2" + ], + "V:_Peduncle,_last_2_cm_42_DAG_1": [ + "V:_Peduncle,_last_2_cm_42_DAG_1", + "V:_Peduncle,_last_2_cm_42_DAG_2", + "V:_Peduncle,_last_2_cm_42_DAG_3" + ], + "V:_Peduncle,_second_2_cm_42_DAG_1": [ + "V:_Peduncle,_second_2_cm_42_DAG_1", + "V:_Peduncle,_second_2_cm_42_DAG_2" + ], + "V:_Peduncle,_third_2_cm_42_DAG_1": [ + "V:_Peduncle,_third_2_cm_42_DAG_1", + "V:_Peduncle,_third_2_cm_42_DAG_2", + "V:_Peduncle,_third_2_cm_42_DAG_3" + ], + "V:_Roots_35_DAG_1": [ + "V:_Roots_35_DAG_1", + "V:_Roots_35_DAG_2", + "V:_Roots_35_DAG_3" + ], + "V:_Spikelet_pedicel_42_DAG_1": [ + "V:_Spikelet_pedicel_42_DAG_1", + "V:_Spikelet_pedicel_42_DAG_2", + "V:_Spikelet_pedicel_42_DAG_3" + ], + "V:_Upper_part_of_inclined_node_42_DAG_1": [ + "V:_Upper_part_of_inclined_node_42_DAG_1", + "V:_Upper_part_of_inclined_node_42_DAG_2" + ], + "V:_Whole_grain_11_DAF_1": [ + "V:_Whole_grain_11_DAF_1", + "V:_Whole_grain_11_DAF_2", + "V:_Whole_grain_11_DAF_3" + ], + "V:_Whole_grain_2_years_1": [ + "V:_Whole_grain_2_years_1", + "V:_Whole_grain_2_years_2", + "V:_Whole_grain_2_years_3" + ], + "V:_Whole_grain_31_DAF_1": [ + "V:_Whole_grain_31_DAF_1", + "V:_Whole_grain_31_DAF_2", + "V:_Whole_grain_31_DAF_3" + ] + } + } + } + }, + "Brachypodium_Grains": { + "database": "brachypodium_grains", + "view_name": "Brachypodium_Grains", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Full_length_grain": [ + "full.length.grains" + ], + "Germinating_grain": [ + "germinating.grains" + ], + "Mature_grain": [ + "mature.grains" + ], + "Mature_grain_without_embryo": [ + "mature.grains.without.embryo" + ], + "Middle_length_grain": [ + "middle.length.grains" + ], + "Pre-anthesis_ovary": [ + "pre.anthesis.ovaries" + ], + "Young_grain": [ + "young.grains" + ], + "Young_seedling": [ + "young.seedlings" + ] + } + } + } + }, + "Brachypodium_Spikes": { + "database": "brachypodium_Bd21", + "view_name": "Brachypodium_Spikes", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Anther_35DAS": [ + "anther" + ], + "Inflorescence_30DAS": [ + "emerging_inflorescence" + ], + "Leaf_20DAS": [ + "leaf" + ], + "Endosperm_55DAS": [ + "endosperm" + ], + "Inflorescence_20DAS": [ + "early_inflorescence" + ], + "Pistil_35DAS": [ + "pistil" + ], + "Embryo_55DAS": [ + "plant_embryo" + ], + "Seed_(10DAP)_45DAP": [ + "seed_10_days_after_pollination" + ], + "Seed_(5DAP)_40DAS": [ + "seed_5_days_after_pollination" + ] + } + } + } + }, + "Photo_Thermocycle": { + "database": "brachypodium_photo_thermocycle", + "view_name": "Photo_Thermocycle", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "LDHC_0h": [ + "LDHC01" + ], + "LDHC_3h30m": [ + "LDHC02" + ], + "LDHC_7h": [ + "LDHC03" + ], + "LDHC_10h30m": [ + "LDHC04" + ], + "LDHC_14h": [ + "LDHC05" + ], + "LDHC_17h30m": [ + "LDHC06" + ], + "LDHC_21h": [ + "LDHC07" + ], + "LDHC_24h30m": [ + "LDHC08" + ], + "LDHC_27h": [ + "LDHC09" + ], + "LDHC_30h30m": [ + "LDHC10" + ], + "LDHC_34h": [ + "LDHC11" + ], + "LDHC_37h30m": [ + "LDHC12" + ], + "LDHC_42h": [ + "LDHC13" + ], + "LDHC_45h30m": [ + "LDHC14" + ], + "LDHH_0h": [ + "LDHH01" + ], + "LDHH_3h30m": [ + "LDHH02" + ], + "LDHH_7h": [ + "LDHH03" + ], + "LDHH_10h30m": [ + "LDHH04" + ], + "LDHH_14h": [ + "LDHH05" + ], + "LDHH_17h30m": [ + "LDHH06" + ], + "LDHH_21h": [ + "LDHH07" + ], + "LDHH_24h30m": [ + "LDHH08" + ], + "LDHH_27h": [ + "LDHH09" + ], + "LDHH_30h30m": [ + "LDHH10" + ], + "LDHH_34h": [ + "LDHH11" + ], + "LDHH_37h30m": [ + "LDHH12" + ], + "LDHH_42h": [ + "LDHH13" + ], + "LDHH_45h30m": [ + "LDHH14" + ], + "LLHC_0h": [ + "LLHC01" + ], + "LLHC_3h30m": [ + "LLHC02" + ], + "LLHC_7h": [ + "LLHC03" + ], + "LLHC_10h30m": [ + "LLHC04" + ], + "LLHC_14h": [ + "LLHC05" + ], + "LLHC_17h30m": [ + "LLHC06" + ], + "LLHC_21h": [ + "LLHC07" + ], + "LLHC_24h30m": [ + "LLHC08" + ], + "LLHC_27h": [ + "LLHC09" + ], + "LLHC_30h30m": [ + "LLHC10" + ], + "LLHC_34h": [ + "LLHC11" + ], + "LLHC_37h30m": [ + "LLHC12" + ], + "LLHC_42h": [ + "LLHC13" + ], + "LLHC_45h30m": [ + "LLHC14" + ], + "LLHH_0h": [ + "LLHH01" + ], + "LLHH_3h30m": [ + "LLHH02" + ], + "LLHH_7h": [ + "LLHH03" + ], + "LLHH_10h30m": [ + "LLHH04" + ], + "LLHH_14h": [ + "LLHH05" + ], + "LLHH_17h30m": [ + "LLHH06" + ], + "LLHH_21h": [ + "LLHH07" + ], + "LLHH_24h30m": [ + "LLHH08" + ], + "LLHH_27h": [ + "LLHH09" + ], + "LLHH_30h30m": [ + "LLHH10" + ], + "LLHH_34h": [ + "LLHH11" + ], + "LLHH_37h30m": [ + "LLHH12" + ], + "LLHH_42h": [ + "LLHH13" + ], + "LLHH_45h30m": [ + "LLHH14" + ] + } + } + } + } + } + } + }, + "brassica rapa": { + + "data": { + "species": "brassica rapa", + "views": { + "Embryogenesis": { + "database": "brassica_rapa", + "view_name": "Embryogenesis", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "UO": [ + "UO" + ], + "E1": [ + "E1" + ], + "E2": [ + "E2" + ], + "E3": [ + "E3" + ], + "E4": [ + "E4" + ], + "E5": [ + "E5" + ], + "E6": [ + "E6" + ], + "E7": [ + "E7" + ], + "S1": [ + "S1" + ], + "S2": [ + "S2" + ], + "S3": [ + "S3" + ], + "S4": [ + "S4" + ], + "S5": [ + "S5" + ], + "S6": [ + "S6" + ], + "S7": [ + "S7" + ] + } + } + } + } + } + } + }, + "cacao ccn": { + + "data": { + "species": "cacao ccn", + "views": { + "Developmental_Atlas": { + "database": "cacao_developmental_atlas", + "view_name": "Developmental_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "CCN51_Mature_Embryo": [ + "CGA-SE-LS-E_R1", + "CGA-SE-LS-E_R2", + "CGA-SE-LS-E_R3", + "CGA-SE-LS-E_R4", + "CGA-SE-LS-E_R5" + ], + "Germinating_Seed_Root": [ + "CGA-GS-RO_R1", + "CGA-GS-RO_R2", + "CGA-GS-RO_R3", + "CGA-GS-RO_R4", + "CGA-GS-RO_R5" + ], + "Germinating_Seed_Shoot": [ + "CGA-GS-SH_R1", + "CGA-GS-SH_R2", + "CGA-GS-SH_R3", + "CGA-GS-SH_R4", + "CGA-GS-SH_R5" + ], + "Seedling_Root": [ + "CGA-SL-RO_R1", + "CGA-SL-RO_R2", + "CGA-SL-RO_R3", + "CGA-SL-RO_R4", + "CGA-SL-RO_R5" + ], + "Seedling_Shoot": [ + "CGA-SL-SH_R1", + "CGA-SL-SH_R2", + "CGA-SL-SH_R3", + "CGA-SL-SH_R4", + "CGA-SL-SH_R5" + ], + "3mo_Orthotropic_Roots": [ + "CGA-RO_R1", + "CGA-RO_R2", + "CGA-RO_R3", + "CGA-RO_R4", + "CGA-RO_R5" + ], + "3mo_Orthotropic_Leaf_A": [ + "CGA-YL-A_R1", + "CGA-YL-A_R2", + "CGA-YL-A_R3", + "CGA-YL-A_R4", + "CGA-YL-A_R5" + ], + "3mo_Orthotropic_C_Leaf": [ + "CGA-ML-C_2", + "CGA-ML-C_R1", + "CGA-ML-C_R3", + "CGA-ML-C_R4", + "CGA-ML-C_R5" + ], + "3mo_Orthotropic_E1_Leaf": [ + "CGA-ML-E1_R1", + "CGA-ML-E1_R2", + "CGA-ML-E1_R3", + "CGA-ML-E1_R4", + "CGA-ML-E1_R5" + ], + "3mo_Orthotropic_E2_Leaf": [ + "CGA-OL-E2_R1", + "CGA-OL-E2_R2", + "CGA-OL-E2_R3", + "CGA-OL-E2_R4", + "CGA-OL-E2_R5" + ], + "3mo_Orthotropic_Shoot_Apex": [ + "CGA-AX_R1", + "CGA-AX_R2", + "CGA-AX_R3", + "CGA-AX_R4", + "CGA-AX_R5" + ], + "3mo_Orthotropic_Herbaceous_Stem": [ + "CGA-SBA-2_R1", + "CGA-SBA-2_R2", + "CGA-SBA-2_R3", + "CGA-SBA-2_R4", + "CGA-SBA-2_R5" + ], + "3mo_Orthotropic_Woody_Stem": [ + "CGA-SBA-1_R1", + "CGA-SBA-1_R2", + "CGA-SBA-1_R3", + "CGA-SBA-1_R4", + "CGA-SBA-1_R5" + ], + "Premeiotic_Floral_Bud": [ + "CGA-PMFB_R1", + "CGA-PMFB_R2", + "CGA-PMFB_R3", + "CGA-PMFB_R4" + ], + "Floral_Bud_5-10_mm": [ + "CGA-LGFL_R1", + "CGA-LGFL_R2", + "CGA-LGFL_R3", + "CGA-LGFL_R4" + ], + "Open_Flower": [ + "CGA-OF_R1", + "CGA-OF_R2", + "CGA-OF_R3", + "CGA-OF_R4" + ], + "CCN51_Immature_Embryo": [ + "DA-SE-MS-E_R1", + "DA-SE-MS-E_R2", + "DA-SE-MS-E_R3", + "DA-SE-MS-E_R4", + "DA-SE-MS-E_R5" + ], + "Immature_Pod_Seed_Coat": [ + "DA-SE-MS-SC_R1", + "DA-SE-MS-SC_R2", + "DA-SE-MS-SC_R3", + "DA-SE-MS-SC_R4", + "DA-SE-MS-SC_R5" + ], + "CCN51_Developing_Embryo": [ + "DA-SE-MLS-E_R1", + "DA-SE-MLS-E_R2", + "DA-SE-MLS-E_R3", + "DA-SE-MLS-E_R4", + "DA-SE-MLS-E_R5" + ], + "Developing_Pod_Seed_Coat": [ + "DA-MLS-SC_R1", + "DA-MLS-SC_R2", + "DA-MLS-SC_R3", + "DA-MLS-SC_R4", + "DA-MLS-SC_R5" + ], + "Immature_Pod_Skin": [ + "DA-PD-MS-PS_R1", + "DA-PD-MS-PS_R2", + "DA-PD-MS-PS_R3" + ], + "Immature_Pod_Exocarp": [ + "DA-PD-MS-PEX_R1", + "DA-PD-MS-PEX_R2", + "DA-PD-MS-PEX_R3" + ], + "Immature_Pod_Mesocarp": [ + "DA-PD-MS-PMC_R1", + "DA-PD-MS-PMC_R2", + "DA-PD-MS-PMC_R3" + ], + "Immature_Pod_Seed_Mucilage": [ + "DA-PD-MS-SM_R1", + "DA-PD-MS-SM_R2", + "DA-PD-MS-SM_R3" + ], + "Immature_Pod_Endocarp": [ + "DA-PD-MS-PEN_R1", + "DA-PD-MS-PEN_R2", + "DA-PD-MS-PEN_R3" + ], + "Developing_Pod_Skin": [ + "DA-PD-MLS-PS_R1", + "DA-PD-MLS-PS_R2", + "DA-PD-MLS-PS_R3" + ], + "Developing_Pod_Exocarp": [ + "DA-PD-MLS-PEX_R1", + "DA-PD-MLS-PEX_R2", + "DA-PD-MLS-PEX_R3" + ], + "Developing_Pod_Mesocarp": [ + "DA-PD-MLS-PMC_R1", + "DA-PD-MLS-PMC_R2", + "DA-PD-MLS-PMC_R3" + ], + "Developing_Pod_Endocarp": [ + "DA-PD-MLS-PEN_R1", + "DA-PD-MLS-PEN_R2", + "DA-PD-MLS-PEN_R3" + ], + "Developing_Pod_Seed_Mucilage": [ + "DA-PD-MLS-SM_R1", + "DA-PD-MLS-SM_R2", + "DA-PD-MLS-SM_R3" + ], + "Mature_Pod_Skin": [ + "DA-PD-LS-PS_R1", + "DA-PD-LS-PS_R2", + "DA-PD-LS-PS_R3", + "DA-PD-LS-PS_R4", + "DA-PD-LS-PS_R5" + ], + "Mature_Pod_Exocarp": [ + "DA-PD-LS-PEX_R1", + "DA-PD-LS-PEX_R2", + "DA-PD-LS-PEX_R3", + "DA-PD-LS-PEX_R4", + "DA-PD-LS-PEX_R5" + ], + "Mature_Pod_Mesocarp": [ + "DA-PD-LS-PMC_R1", + "DA-PD-LS-PMC_R2", + "DA-PD-LS-PMC_R3", + "DA-PD-LS-PMC_R4", + "DA-PD-LS-PMC_R5" + ], + "Mature_Pod_Endocarp": [ + "DA-PD-LS-PEN_R1", + "DA-PD-LS-PEN_R2", + "DA-PD-LS-PEN_R3", + "DA-PD-LS-PEN_R4", + "DA-PD-LS-PEN_R5" + ], + "Mature_Pod_Seed_Mucilage": [ + "DA-PD-LS-SM_R1", + "DA-PD-LS-SM_R2", + "DA-PD-LS-SM_R3", + "DA-PD-LS-SM_R4", + "DA-PD-LS-SM_R5" + ], + "6mo_Orthotropic_Root": [ + "DA-RO-RT_R1", + "DA-RO-RT_R2", + "DA-RO-RT_R3", + "DA-RO-RT_R4", + "DA-RO-RT_R5" + ], + "6mo_Orthotropic_Leaf_A": [ + "DA-OTL-A_R1", + "DA-OTL-A_R2", + "DA-OTL-A_R3", + "DA-OTL-A_R4", + "DA-OTL-A_R5" + ], + "6mo_Orthotropic_Leaf_C": [ + "DA-OTL-C_R1", + "DA-OTL-C_R2", + "DA-OTL-C_R3", + "DA-OTL-C_R4", + "DA-OTL-C_R5" + ], + "6mo_Orthotropic_Leaf_E1": [ + "DA-OTL-E1_R1", + "DA-OTL-E1_R2", + "DA-OTL-E1_R3", + "DA-OTL-E1_R4", + "DA-OTL-E1_R5" + ], + "6mo_Orthotropic_Leaf_E2": [ + "DA-OTL-E2_R2", + "DA-OTL-E2_R3", + "DA-OTL-E2_R4", + "DA-OTL-E2_R5" + ], + "6mo_Orthotropic_Leaf_E3": [ + "DA-OTL-E3_R1", + "DA-OTL-E3_R2", + "DA-OTL-E3_R3", + "DA-OTL-E3_R4", + "DA-OTL-E3_R5" + ], + "6mo_Orthotropic_Shoot_Apex": [ + "DA-OTA_R1", + "DA-OTA_R2", + "DA-OTA_R3", + "DA-OTA_R4", + "DA-OTA_R5" + ], + "6mo_Orthotropic_Herbaceous_Stem": [ + "DA-OTAC-YS_R1", + "DA-OTAC-YS_R2", + "DA-OTAC-YS_R3", + "DA-OTAC-YS_R4", + "DA-OTAC-YS_R5" + ], + "6mo_Orthotropic_Young_Axilaries": [ + "DA-OAA-YA_R1", + "DA-OAA-YA_R2", + "DA-OAA-YA_R3", + "DA-OAA-YA_R4", + "DA-OAA-YA_R5" + ], + "6mo_Orthotropic_Old_Axilaries": [ + "DA-OAA-OA_R1", + "DA-OAA-OA_R2", + "DA-OAA-OA_R3", + "DA-OAA-OA_R4" + ], + "Plagiotropic_Shoot_Apex": [ + "DA-PSA_R1", + "DA-PSA_R2", + "DA-PSA_R3", + "DA-PSA_R4", + "DA-PSA_R5" + ], + "Plagiotropic_A_Leaf": [ + "DA-PTL-A_R1", + "DA-PTL-A_R2", + "DA-PTL-A_R3", + "DA-PTL-A_R4", + "DA-PTL-A_R5" + ], + "Plagiotropic_C_Leaf": [ + "DA-PTL-C_R1", + "DA-PTL-C_R3", + "DA-PTL-C_R4" + ], + "Plagiotropic_E_Leaf": [ + "DA-PTL-E_R1", + "DA-PTL-E_R2", + "DA-PTL-E_R3", + "DA-PTL-E_R4", + "DA-PTL-E_R5" + ], + "Plagiotropic_Old_Axiliaries": [ + "DA-OA_R1", + "DA-OA_R2", + "DA-OA_R3", + "DA-OA_R4", + "DA-OA_R5" + ], + "Plagiotropic_Young_Axilaries": [ + "DA-YA_R1", + "DA-YA_R2", + "DA-YA_R3", + "DA-YA_R4", + "DA-YA_R5" + ] + } + } + } + }, + "Drought_Diurnal_Atlas": { + "database": "cacao_drought_diurnal_atlas", + "view_name": "Drought_Diurnal_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Root_Watered_T1": [ + "DD-WTR-T1_R1", + "DD-WTR-T1_R2", + "DD-WTR-T1_R3" + ], + "Root_Watered_T2": [ + "DD-WTR-T2_R1", + "DD-WTR-T2_R2", + "DD-WTR-T2_R3" + ], + "Root_Watered_T3": [ + "DD-WTR-T3_R1", + "DD-WTR-T3_R2", + "DD-WTR-T3_R3" + ], + "Root_Watered_T4": [ + "DD-WTR-T4_R1", + "DD-WTR-T4_R2", + "DD-WTR-T4_R3" + ], + "Root_Watered_T5": [ + "DD-WTR-T5_R1", + "DD-WTR-T5_R2", + "DD-WTR-T5_R3" + ], + "Root_Watered_T6": [ + "DD-WTR-T6_R1", + "DD-WTR-T6_R2", + "DD-WTR-T6_R3" + ], + "Root_Watered_T7": [ + "DD-WTR-T7_R2", + "DD-WTR-T7_R3", + "DD-WTR-T7-R1" + ], + "Root_Drought_T1": [ + "DD-DTR-T1_R1", + "DD-DTR-T1_R2", + "DD-DTR-T1_R3" + ], + "Root_Drought_T2": [ + "DD-DTR-T2_R1", + "DD-DTR-T2_R2", + "DD-DTR-T2_R3" + ], + "Root_Drought_T3": [ + "DD-DTR-T3_R1", + "DD-DTR-T3_R2", + "DD-DTR-T3_R3" + ], + "Root_Drought_T4": [ + "DD-DTR-T4_R1", + "DD-DTR-T4_R2", + "DD-DTR-T4_R3" + ], + "Root_Drought_T5": [ + "DD-DTR-T5_R1", + "DD-DTR-T5_R2" + ], + "Root_Drought_T6": [ + "DD-DTR-T6_R1", + "DD-DTR-T6_R2", + "DD-DTR-T6_R3" + ], + "Root_Drought_T7": [ + "DD-DTR-T7_R1", + "DD-DTR-T7_R2", + "DD-DTR-T7_R3" + ], + "Leaf_Watered_T1": [ + "DD-WTL-T1_R1", + "DD-WTL-T1_R2", + "DD-WTL-T1_R3" + ], + "Leaf_Watered_T2": [ + "DD-WTL-T2_R1", + "DD-WTL-T2_R2", + "DD-WTL-T2_R3" + ], + "Leaf_Watered_T3": [ + "DD-WTL-T3_R1", + "DD-WTL-T3_R2", + "DD-WTL-T3_R3" + ], + "Leaf_Watered_T4": [ + "DD-WTL-T4_R1", + "DD-WTL-T4_R2", + "DD-WTL-T4_R3" + ], + "Leaf_Watered_T5": [ + "DD-WTL-T5_R1", + "DD-WTL-T5_R2" + ], + "Leaf_Watered_T6": [ + "DD-WTL-T6_R1", + "DD-WTL-T6_R2", + "DD-WTL-T6_R3" + ], + "Leaf_Watered_T7": [ + "DD-WTL-T7_R1", + "DD-WTL-T7_R2", + "DD-WTL-T7_R3" + ], + "Leaf_Drought_T1": [ + "DD-DTL-T1_R1", + "DD-DTL-T1_R2", + "DD-DTL-T1_R3" + ], + "Leaf_Drought_T2": [ + "DD-DTL-T2_R1", + "DD-DTL-T2_R2", + "DD-DTL-T2_R3" + ], + "Leaf_Drought_T3": [ + "DD-DTL-T3_R1", + "DD-DTL-T3_R2", + "DD-DTL-T3_R3" + ], + "Leaf_Drought_T4": [ + "DD-DTL-T4_R1", + "DD-DTL-T4_R2", + "DD-DTL-T4_R3" + ], + "Leaf_Drought_T5": [ + "DD-DTL-T5_R1", + "DD-DTL-T5_R2", + "DD-DTL-T5_R3" + ], + "Leaf_Drought_T6": [ + "DD-DTL-T6_R1", + "DD-DTL-T6_R2", + "DD-DTL-T6_R3" + ], + "Leaf_Drought_T7": [ + "DD-DTL-T7_R1", + "DD-DTL-T7_R2", + "DD-DTL-T7_R3" + ], + "Apex_Watered_T1": [ + "DD-WTA-T1_R1", + "DD-WTA-T1_R2", + "DD-WTA-T1_R3" + ], + "Apex_Watered_T2": [ + "DD-WTA-T2_R1", + "DD-WTA-T2_R2", + "DD-WTA-T2_R3" + ], + "Apex_Watered_T3": [ + "DD-WTA-T3_R1", + "DD-WTA-T3_R2", + "DD-WTA-T3_R3" + ], + "Apex_Watered_T4": [ + "DD-WTA-T4_R1", + "DD-WTA-T4_R2", + "DD-WTA-T4_R3" + ], + "Apex_Watered_T5": [ + "DD-WTA-T5_R1", + "DD-WTA-T5_R2", + "DD-WTA-T5_R3" + ], + "Apex_Watered_T6": [ + "DD-WTA-T6_R1", + "DD-WTA-T6_R2", + "DD-WTA-T6_R3" + ], + "Apex_Watered_T7": [ + "DD-WTA-T7_R1", + "DD-WTA-T7_R2", + "DD-WTA-T7_R3" + ], + "Apex_Drought_T1": [ + "DD-DTA-T1_R1", + "DD-DTA-T1_R2", + "DD-DTA-T1_R3" + ], + "Apex_Drought_T2": [ + "DD-DTA-T2_R1", + "DD-DTA-T2_R2", + "DD-DTA-T2_R3" + ], + "Apex_Drought_T3": [ + "DD-DTA-T3_R1", + "DD-DTA-T3_R2", + "DD-DTA-T3_R3" + ], + "Apex_Drought_T4": [ + "DD-DTA-T4_R1", + "DD-DTA-T4_R2", + "DD-DTA-T4_R3" + ], + "Apex_Drought_T5": [ + "DD-DTA-T5_R1", + "DD-DTA-T5_R2", + "DD-DTA-T5_R3" + ], + "Apex_Drought_T6": [ + "DD-DTA-T6_R1", + "DD-DTA-T6_R2", + "DD-DTA-T6_R3" + ], + "Apex_Drought_T7": [ + "DD-DTA-T7_R1", + "DD-DTA-T7_R2", + "DD-DTA-T7_R3" + ] + } + } + } + } + } + } + }, + "cacao sca": { + + "data": { + "species": "cacao sca", + "views": { + "Developmental_Atlas": { + "database": "cacao_developmental_atlas_sca", + "view_name": "Developmental_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "CCN51_Mature_Embryo": [ + "CGA-SE-LS-E_R1", + "CGA-SE-LS-E_R2", + "CGA-SE-LS-E_R3", + "CGA-SE-LS-E_R4", + "CGA-SE-LS-E_R5" + ], + "Germinating_Seed_Root": [ + "CGA-GS-RO_R1", + "CGA-GS-RO_R2", + "CGA-GS-RO_R3", + "CGA-GS-RO_R4", + "CGA-GS-RO_R5" + ], + "Germinating_Seed_Shoot": [ + "CGA-GS-SH_R1", + "CGA-GS-SH_R2", + "CGA-GS-SH_R3", + "CGA-GS-SH_R4", + "CGA-GS-SH_R5" + ], + "Seedling_Root": [ + "CGA-SL-RO_R1", + "CGA-SL-RO_R2", + "CGA-SL-RO_R3", + "CGA-SL-RO_R4", + "CGA-SL-RO_R5" + ], + "Seedling_Shoot": [ + "CGA-SL-SH_R1", + "CGA-SL-SH_R2", + "CGA-SL-SH_R3", + "CGA-SL-SH_R4", + "CGA-SL-SH_R5" + ], + "3mo_Orthotropic_Roots": [ + "CGA-RO_R1", + "CGA-RO_R2", + "CGA-RO_R3", + "CGA-RO_R4", + "CGA-RO_R5" + ], + "3mo_Orthotropic_Leaf_A": [ + "CGA-YL-A_R1", + "CGA-YL-A_R2", + "CGA-YL-A_R3", + "CGA-YL-A_R4", + "CGA-YL-A_R5" + ], + "3mo_Orthotropic_C_Leaf": [ + "CGA-ML-C_2", + "CGA-ML-C_R1", + "CGA-ML-C_R3", + "CGA-ML-C_R4", + "CGA-ML-C_R5" + ], + "3mo_Orthotropic_E1_Leaf": [ + "CGA-ML-E1_R1", + "CGA-ML-E1_R2", + "CGA-ML-E1_R3", + "CGA-ML-E1_R4", + "CGA-ML-E1_R5" + ], + "3mo_Orthotropic_E2_Leaf": [ + "CGA-OL-E2_R1", + "CGA-OL-E2_R2", + "CGA-OL-E2_R3", + "CGA-OL-E2_R4", + "CGA-OL-E2_R5" + ], + "3mo_Orthotropic_Shoot_Apex": [ + "CGA-AX_R1", + "CGA-AX_R2", + "CGA-AX_R3", + "CGA-AX_R4", + "CGA-AX_R5" + ], + "3mo_Orthotropic_Herbaceous_Stem": [ + "CGA-SBA-2_R1", + "CGA-SBA-2_R2", + "CGA-SBA-2_R3", + "CGA-SBA-2_R4", + "CGA-SBA-2_R5" + ], + "3mo_Orthotropic_Woody_Stem": [ + "CGA-SBA-1_R1", + "CGA-SBA-1_R2", + "CGA-SBA-1_R3", + "CGA-SBA-1_R4", + "CGA-SBA-1_R5" + ], + "Premeiotic_Floral_Bud": [ + "CGA-PMFB_R1", + "CGA-PMFB_R2", + "CGA-PMFB_R3", + "CGA-PMFB_R4" + ], + "Floral_Bud_5-10_mm": [ + "CGA-LGFL_R1", + "CGA-LGFL_R2", + "CGA-LGFL_R3", + "CGA-LGFL_R4" + ], + "Open_Flower": [ + "CGA-OF_R1", + "CGA-OF_R2", + "CGA-OF_R3", + "CGA-OF_R4" + ], + "CCN51_Immature_Embryo": [ + "DA-SE-MS-E_R1", + "DA-SE-MS-E_R2", + "DA-SE-MS-E_R3", + "DA-SE-MS-E_R4", + "DA-SE-MS-E_R5" + ], + "Immature_Pod_Seed_Coat": [ + "DA-SE-MS-SC_R1", + "DA-SE-MS-SC_R2", + "DA-SE-MS-SC_R3", + "DA-SE-MS-SC_R4", + "DA-SE-MS-SC_R5" + ], + "CCN51_Developing_Embryo": [ + "DA-SE-MLS-E_R1", + "DA-SE-MLS-E_R2", + "DA-SE-MLS-E_R3", + "DA-SE-MLS-E_R4", + "DA-SE-MLS-E_R5" + ], + "Developing_Pod_Seed_Coat": [ + "DA-MLS-SC_R1", + "DA-MLS-SC_R2", + "DA-MLS-SC_R3", + "DA-MLS-SC_R4", + "DA-MLS-SC_R5" + ], + "Immature_Pod_Skin": [ + "DA-PD-MS-PS_R1", + "DA-PD-MS-PS_R2", + "DA-PD-MS-PS_R3" + ], + "Immature_Pod_Exocarp": [ + "DA-PD-MS-PEX_R1", + "DA-PD-MS-PEX_R2", + "DA-PD-MS-PEX_R3" + ], + "Immature_Pod_Mesocarp": [ + "DA-PD-MS-PMC_R1", + "DA-PD-MS-PMC_R2", + "DA-PD-MS-PMC_R3" + ], + "Immature_Pod_Seed_Mucilage": [ + "DA-PD-MS-SM_R1", + "DA-PD-MS-SM_R2", + "DA-PD-MS-SM_R3" + ], + "Immature_Pod_Endocarp": [ + "DA-PD-MS-PEN_R1", + "DA-PD-MS-PEN_R2", + "DA-PD-MS-PEN_R3" + ], + "Developing_Pod_Skin": [ + "DA-PD-MLS-PS_R1", + "DA-PD-MLS-PS_R2", + "DA-PD-MLS-PS_R3" + ], + "Developing_Pod_Exocarp": [ + "DA-PD-MLS-PEX_R1", + "DA-PD-MLS-PEX_R2", + "DA-PD-MLS-PEX_R3" + ], + "Developing_Pod_Mesocarp": [ + "DA-PD-MLS-PMC_R1", + "DA-PD-MLS-PMC_R2", + "DA-PD-MLS-PMC_R3" + ], + "Developing_Pod_Endocarp": [ + "DA-PD-MLS-PEN_R1", + "DA-PD-MLS-PEN_R2", + "DA-PD-MLS-PEN_R3" + ], + "Developing_Pod_Seed_Mucilage": [ + "DA-PD-MLS-SM_R1", + "DA-PD-MLS-SM_R2", + "DA-PD-MLS-SM_R3" + ], + "Mature_Pod_Skin": [ + "DA-PD-LS-PS_R1", + "DA-PD-LS-PS_R2", + "DA-PD-LS-PS_R3", + "DA-PD-LS-PS_R4", + "DA-PD-LS-PS_R5" + ], + "Mature_Pod_Exocarp": [ + "DA-PD-LS-PEX_R1", + "DA-PD-LS-PEX_R2", + "DA-PD-LS-PEX_R3", + "DA-PD-LS-PEX_R4", + "DA-PD-LS-PEX_R5" + ], + "Mature_Pod_Mesocarp": [ + "DA-PD-LS-PMC_R1", + "DA-PD-LS-PMC_R2", + "DA-PD-LS-PMC_R3", + "DA-PD-LS-PMC_R4", + "DA-PD-LS-PMC_R5" + ], + "Mature_Pod_Endocarp": [ + "DA-PD-LS-PEN_R1", + "DA-PD-LS-PEN_R2", + "DA-PD-LS-PEN_R3", + "DA-PD-LS-PEN_R4", + "DA-PD-LS-PEN_R5" + ], + "Mature_Pod_Seed_Mucilage": [ + "DA-PD-LS-SM_R1", + "DA-PD-LS-SM_R2", + "DA-PD-LS-SM_R3", + "DA-PD-LS-SM_R4", + "DA-PD-LS-SM_R5" + ], + "6mo_Orthotropic_Root": [ + "DA-RO-RT_R1", + "DA-RO-RT_R2", + "DA-RO-RT_R3", + "DA-RO-RT_R4", + "DA-RO-RT_R5" + ], + "6mo_Orthotropic_Leaf_A": [ + "DA-OTL-A_R1", + "DA-OTL-A_R2", + "DA-OTL-A_R3", + "DA-OTL-A_R4", + "DA-OTL-A_R5" + ], + "6mo_Orthotropic_Leaf_C": [ + "DA-OTL-C_R1", + "DA-OTL-C_R2", + "DA-OTL-C_R3", + "DA-OTL-C_R4", + "DA-OTL-C_R5" + ], + "6mo_Orthotropic_Leaf_E1": [ + "DA-OTL-E1_R1", + "DA-OTL-E1_R2", + "DA-OTL-E1_R3", + "DA-OTL-E1_R4", + "DA-OTL-E1_R5" + ], + "6mo_Orthotropic_Leaf_E2": [ + "DA-OTL-E2_R2", + "DA-OTL-E2_R3", + "DA-OTL-E2_R4", + "DA-OTL-E2_R5" + ], + "6mo_Orthotropic_Leaf_E3": [ + "DA-OTL-E3_R1", + "DA-OTL-E3_R2", + "DA-OTL-E3_R3", + "DA-OTL-E3_R4", + "DA-OTL-E3_R5" + ], + "6mo_Orthotropic_Shoot_Apex": [ + "DA-OTA_R1", + "DA-OTA_R2", + "DA-OTA_R3", + "DA-OTA_R4", + "DA-OTA_R5" + ], + "6mo_Orthotropic_Herbaceous_Stem": [ + "DA-OTAC-YS_R1", + "DA-OTAC-YS_R2", + "DA-OTAC-YS_R3", + "DA-OTAC-YS_R4", + "DA-OTAC-YS_R5" + ], + "6mo_Orthotropic_Young_Axilaries": [ + "DA-OAA-YA_R1", + "DA-OAA-YA_R2", + "DA-OAA-YA_R3", + "DA-OAA-YA_R4", + "DA-OAA-YA_R5" + ], + "6mo_Orthotropic_Old_Axilaries": [ + "DA-OAA-OA_R1", + "DA-OAA-OA_R2", + "DA-OAA-OA_R3", + "DA-OAA-OA_R4" + ], + "Plagiotropic_Shoot_Apex": [ + "DA-PSA_R1", + "DA-PSA_R2", + "DA-PSA_R3", + "DA-PSA_R4", + "DA-PSA_R5" + ], + "Plagiotropic_A_Leaf": [ + "DA-PTL-A_R1", + "DA-PTL-A_R2", + "DA-PTL-A_R3", + "DA-PTL-A_R4", + "DA-PTL-A_R5" + ], + "Plagiotropic_C_Leaf": [ + "DA-PTL-C_R1", + "DA-PTL-C_R3", + "DA-PTL-C_R4" + ], + "Plagiotropic_E_Leaf": [ + "DA-PTL-E_R1", + "DA-PTL-E_R2", + "DA-PTL-E_R3", + "DA-PTL-E_R4", + "DA-PTL-E_R5" + ], + "Plagiotropic_Old_Axiliaries": [ + "DA-OA_R1", + "DA-OA_R2", + "DA-OA_R3", + "DA-OA_R4", + "DA-OA_R5" + ], + "Plagiotropic_Young_Axilaries": [ + "DA-YA_R1", + "DA-YA_R2", + "DA-YA_R3", + "DA-YA_R4", + "DA-YA_R5" + ] + } + } + } + }, + "Drought_Diurnal_Atlas": { + "database": "cacao_drought_diurnal_atlas_sca", + "view_name": "Drought_Diurnal_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Root_Watered_T1": [ + "DD-WTR-T1_R1", + "DD-WTR-T1_R2", + "DD-WTR-T1_R3" + ], + "Root_Watered_T2": [ + "DD-WTR-T2_R1", + "DD-WTR-T2_R2", + "DD-WTR-T2_R3" + ], + "Root_Watered_T3": [ + "DD-WTR-T3_R1", + "DD-WTR-T3_R2", + "DD-WTR-T3_R3" + ], + "Root_Watered_T4": [ + "DD-WTR-T4_R1", + "DD-WTR-T4_R2", + "DD-WTR-T4_R3" + ], + "Root_Watered_T5": [ + "DD-WTR-T5_R1", + "DD-WTR-T5_R2", + "DD-WTR-T5_R3" + ], + "Root_Watered_T6": [ + "DD-WTR-T6_R1", + "DD-WTR-T6_R2", + "DD-WTR-T6_R3" + ], + "Root_Watered_T7": [ + "DD-WTR-T7_R2", + "DD-WTR-T7_R3", + "DD-WTR-T7-R1" + ], + "Root_Drought_T1": [ + "DD-DTR-T1_R1", + "DD-DTR-T1_R2", + "DD-DTR-T1_R3" + ], + "Root_Drought_T2": [ + "DD-DTR-T2_R1", + "DD-DTR-T2_R2", + "DD-DTR-T2_R3" + ], + "Root_Drought_T3": [ + "DD-DTR-T3_R1", + "DD-DTR-T3_R2", + "DD-DTR-T3_R3" + ], + "Root_Drought_T4": [ + "DD-DTR-T4_R1", + "DD-DTR-T4_R2", + "DD-DTR-T4_R3" + ], + "Root_Drought_T5": [ + "DD-DTR-T5_R1", + "DD-DTR-T5_R2" + ], + "Root_Drought_T6": [ + "DD-DTR-T6_R1", + "DD-DTR-T6_R2", + "DD-DTR-T6_R3" + ], + "Root_Drought_T7": [ + "DD-DTR-T7_R1", + "DD-DTR-T7_R2", + "DD-DTR-T7_R3" + ], + "Leaf_Watered_T1": [ + "DD-WTL-T1_R1", + "DD-WTL-T1_R2", + "DD-WTL-T1_R3" + ], + "Leaf_Watered_T2": [ + "DD-WTL-T2_R1", + "DD-WTL-T2_R2", + "DD-WTL-T2_R3" + ], + "Leaf_Watered_T3": [ + "DD-WTL-T3_R1", + "DD-WTL-T3_R2", + "DD-WTL-T3_R3" + ], + "Leaf_Watered_T4": [ + "DD-WTL-T4_R1", + "DD-WTL-T4_R2", + "DD-WTL-T4_R3" + ], + "Leaf_Watered_T5": [ + "DD-WTL-T5_R1", + "DD-WTL-T5_R2" + ], + "Leaf_Watered_T6": [ + "DD-WTL-T6_R1", + "DD-WTL-T6_R2", + "DD-WTL-T6_R3" + ], + "Leaf_Watered_T7": [ + "DD-WTL-T7_R1", + "DD-WTL-T7_R2", + "DD-WTL-T7_R3" + ], + "Leaf_Drought_T1": [ + "DD-DTL-T1_R1", + "DD-DTL-T1_R2", + "DD-DTL-T1_R3" + ], + "Leaf_Drought_T2": [ + "DD-DTL-T2_R1", + "DD-DTL-T2_R2", + "DD-DTL-T2_R3" + ], + "Leaf_Drought_T3": [ + "DD-DTL-T3_R1", + "DD-DTL-T3_R2", + "DD-DTL-T3_R3" + ], + "Leaf_Drought_T4": [ + "DD-DTL-T4_R1", + "DD-DTL-T4_R2", + "DD-DTL-T4_R3" + ], + "Leaf_Drought_T5": [ + "DD-DTL-T5_R1", + "DD-DTL-T5_R2", + "DD-DTL-T5_R3" + ], + "Leaf_Drought_T6": [ + "DD-DTL-T6_R1", + "DD-DTL-T6_R2", + "DD-DTL-T6_R3" + ], + "Leaf_Drought_T7": [ + "DD-DTL-T7_R1", + "DD-DTL-T7_R2", + "DD-DTL-T7_R3" + ], + "Apex_Watered_T1": [ + "DD-WTA-T1_R1", + "DD-WTA-T1_R2", + "DD-WTA-T1_R3" + ], + "Apex_Watered_T2": [ + "DD-WTA-T2_R1", + "DD-WTA-T2_R2", + "DD-WTA-T2_R3" + ], + "Apex_Watered_T3": [ + "DD-WTA-T3_R1", + "DD-WTA-T3_R2", + "DD-WTA-T3_R3" + ], + "Apex_Watered_T4": [ + "DD-WTA-T4_R1", + "DD-WTA-T4_R2", + "DD-WTA-T4_R3" + ], + "Apex_Watered_T5": [ + "DD-WTA-T5_R1", + "DD-WTA-T5_R2", + "DD-WTA-T5_R3" + ], + "Apex_Watered_T6": [ + "DD-WTA-T6_R1", + "DD-WTA-T6_R2", + "DD-WTA-T6_R3" + ], + "Apex_Watered_T7": [ + "DD-WTA-T7_R1", + "DD-WTA-T7_R2", + "DD-WTA-T7_R3" + ], + "Apex_Drought_T1": [ + "DD-DTA-T1_R1", + "DD-DTA-T1_R2", + "DD-DTA-T1_R3" + ], + "Apex_Drought_T2": [ + "DD-DTA-T2_R1", + "DD-DTA-T2_R2", + "DD-DTA-T2_R3" + ], + "Apex_Drought_T3": [ + "DD-DTA-T3_R1", + "DD-DTA-T3_R2", + "DD-DTA-T3_R3" + ], + "Apex_Drought_T4": [ + "DD-DTA-T4_R1", + "DD-DTA-T4_R2", + "DD-DTA-T4_R3" + ], + "Apex_Drought_T5": [ + "DD-DTA-T5_R1", + "DD-DTA-T5_R2", + "DD-DTA-T5_R3" + ], + "Apex_Drought_T6": [ + "DD-DTA-T6_R1", + "DD-DTA-T6_R2", + "DD-DTA-T6_R3" + ], + "Apex_Drought_T7": [ + "DD-DTA-T7_R1", + "DD-DTA-T7_R2", + "DD-DTA-T7_R3" + ] + } + } + } + }, + "Meristem_Atlas": { + "database": "cacao_meristem_atlas_sca", + "view_name": "Meristem_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Plagiotropic_Apex_Stage_4": [ + "MA-PTA-Sca6-S4_R1", + "MA-PTA-Sca6-S4_R2", + "MA-PTA-Sca6-S4_R3" + ], + "Plagiotropic_Apex_Stage_3": [ + "MA-PTA-Sca6-S3_R1", + "MA-PTA-Sca6-S3_R2", + "MA-PTA-Sca6-S3_R3" + ], + "Plagiotropic_Apex_Stage_2": [ + "MA-PTA-Sca6-S2_R1", + "MA-PTA-Sca6-S2_R2", + "MA-PTA-Sca6-S2_R3" + ], + "Plagiotropic_Apex_Stage_1": [ + "MA-PTA-Sca6-S1_R1", + "MA-PTA-Sca6-S1_R2", + "MA-PTA-Sca6-S1_R3" + ], + "Orthotropic_Apex_Stage_4": [ + "MA-OTA-Sca6-S4_R1", + "MA-OTA-Sca6-S4_R2", + "MA-OTA-Sca6-S4_R3" + ], + "Orthotropic_Apex_Stage_3": [ + "MA-OTA-Sca6-S3_R1", + "MA-OTA-Sca6-S3_R2", + "MA-OTA-Sca6-S3_R3" + ], + "Orthotropic_Apex_Stage_2": [ + "MA-OTA-Sca6-S2_R1", + "MA-OTA-Sca6-S2_R2", + "MA-OTA-Sca6-S2_R3" + ], + "Orthotropic_Apex_Stage_1": [ + "MA-OTA-Sca6-S1_R1", + "MA-OTA-Sca6-S1_R2", + "MA-OTA-Sca6-S1_R3" + ] + } + } + } + }, + "Seed_Atlas": { + "database": "cacao_seed_atlas_sca", + "view_name": "Seed_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "CCN": [ + "CGA-SE-LS-E_R1", + "CGA-SE-LS-E_R2", + "CGA-SE-LS-E_R3", + "CGA-SE-LS-E_R4", + "CGA-SE-LS-E_R5" + ], + "IMC": [ + "SA-SE-LS-IMC-E_R1", + "SA-SE-LS-IMC-E_R2", + "SA-SE-LS-IMC-E_R3", + "SA-SE-LS-IMC-E_R4", + "SA-SE-LS-IMC-E_R5" + ], + "Sca": [ + "SA-SE-LS-Sca-E_R1", + "SA-SE-LS-Sca-E_R2", + "SA-SE-LS-Sca-E_R3", + "SA-SE-LS-Sca-E_R4", + "SA-SE-LS-Sca-E_R5" + ] + } + } + } + } + } + } + }, + "cacao tc": { + + "data": { + "species": "cacao tc", + "views": { + "Cacao_Infection": { + "database": "cacao_infection", + "view_name": "Cacao_Infection", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "NA32_Basal": [ + "basal_N432_rep4", + "basal_NA32_rep1", + "basal_NA32_rep2", + "basal_NA32_rep3", + "basal_NA32_rep5", + "basal_NA32_rep6", + "basal_NA32_rep7", + "basal_NA32_rep8" + ], + "Scavina6_Basal": [ + "basal_SCA6_rep1", + "basal_SCA6_rep2", + "basal_SCA6_rep3", + "basal_SCA6_rep4", + "basal_SCA6_rep5", + "basal_SCA6_rep6", + "basal_SCA6_rep7", + "basal_SCA6_rep8" + ], + "NA32_Control_24h": [ + "NA32_Control_24hr_rep1", + "NA32_Control_24hr_rep2", + "NA32_Control_24hr_rep3", + "NA32_Control_24hr_rep4" + ], + "NA32_Control_6h": [ + "NA32_Control_6hr_rep1", + "NA32_Control_6hr_rep2", + "NA32_Control_6hr_rep3" + ], + "NA32_Control_72h": [ + "NA32_Control_72hr_rep1", + "NA32_Control_72hr_rep2", + "NA32_Control_72hr_rep3", + "NA32_Control_72hr_rep4" + ], + "NA32_Infected_6h": [ + "NA32_Pathogen_6hr_rep1", + "NA32_Pathogen_6hr_rep2", + "NA32_Pathogen_6hr_rep3", + "NA32_Pathogen_6hr_rep4" + ], + "NA32_Infected_24h": [ + "NA32_Pathogen_24hr_rep1", + "NA32_Pathogen_24hr_rep2", + "NA32_Pathogen_24hr_rep3", + "NA32_Pathogen_24hr_rep4" + ], + "NA32_Infected_72h": [ + "NA32_Pathogen_72hr_rep1", + "NA32_Pathogen_72hr_rep2", + "NA32_Pathogen_72hr_rep3", + "NA32_Pathogen_72hr_rep4" + ], + "Scavina6_Control_6h": [ + "SCA6_Control_6hr_rep1", + "SCA6_Control_6hr_rep2", + "SCA6_Control_6hr_rep3", + "SCA6_Control_6hr_rep4" + ], + "Scavina6_Control_24h": [ + "SCA6_Control_24hr_rep1", + "SCA6_Control_24hr_rep2", + "SCA6_Control_24hr_rep3", + "SCA6_Control_24hr_rep4" + ], + "Scavina6_Control_72h": [ + "SCA6_Control_72hr_rep1", + "SCA6_Control_72hr_rep2", + "SCA6_Control_72hr_rep3", + "SCA6_Control_72hr_rep4" + ], + "Scavina6_Infected_6h": [ + "SCA6_Pathogen_6hr_rep1", + "SCA6_Pathogen_6hr_rep2", + "SCA6_Pathogen_6hr_rep3", + "SCA6_Pathogen_6hr_rep4" + ], + "Scavina6_Infected_72h": [ + "SCA6_Pathogen_72hr_rep1", + "SCA6_Pathogen_72hr_rep2", + "SCA6_Pathogen_72hr_rep3", + "SCA6_Pathogen_72hr_rep4" + ] + } + }, + "basal_SCA6_rep8;Med_CTRL": { + "controls": [ + "basal_SCA6_rep8", + "Med_CTRL" + ], + "treatments": { + "Scavina6_Infected_24h": [ + "SCA6_Pathogen_24hr_rep1", + "SCA6_Pathogen_24hr_rep2", + "SCA6_Pathogen_24hr_rep3", + "SCA6_Pathogen_24hr_rep4" + ] + } + } + } + }, + "Cacao_Leaf": { + "database": "cacao_leaf", + "view_name": "Cacao_Leaf", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Scavina6_DE": [ + "Sca6_DE_1", + "Sca6_DE_2", + "Sca6_DE_3", + "Sca6_DE_4", + "Sca6_DE_5" + ], + "Scavina6_AB": [ + "Sca6_AB_1", + "Sca6_AB_2", + "Sca6_AB_3", + "Sca6_AB_4", + "Sca6_AB_5" + ], + "Scavina6_C": [ + "Sca6_C_1", + "Sca6_C_2", + "Sca6_C_3", + "Sca6_C_4", + "Sca6_C_5" + ], + "ICS1_AB": [ + "ICS1_AB_1", + "ICS1_AB_2", + "ICS1_AB_3", + "ICS1_AB_4", + "ICS1_AB_5" + ], + "ICS1_C": [ + "ICS1_C_1", + "ICS1_C_2", + "ICS1_C_3", + "ICS1_C_4", + "ICS1_C_5" + ], + "ICS1_DE": [ + "ICS1_DE_1", + "ICS1_DE_2", + "ICS1_DE_3", + "ICS1_DE_4", + "ICS1_DE_5" + ] + } + } + } + } + } + } + }, + "camelina": { + + "data": { + "species": "camelina", + "views": { + "Developmental_Atlas_FPKM": { + "database": "camelina", + "view_name": "Developmental_Atlas_FPKM", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Germinating_Seed": [ + "germinating_seed_1", + "germinating_seed_2", + "germinating_seed_3" + ], + "Cotyledon": [ + "cotyledon_1", + "cotyledon_2", + "cotyledon_3" + ], + "Young_Leaf": [ + "young_leaf_1", + "young_leaf_2", + "young_leaf_3" + ], + "Senescing_Leaf": [ + "senescing_leaf_1", + "senescing_leaf_2", + "senescing_leaf_3" + ], + "Root": [ + "root_1", + "root_2", + "root_3" + ], + "Stem": [ + "stem_1", + "stem_2", + "stem_3" + ], + "Buds": [ + "bud_1", + "bud_2", + "bud_3" + ], + "Flower": [ + "flower_1", + "flower_2", + "flower_3" + ], + "Early_Seed_Development": [ + "early_seed_development_1", + "early_seed_development_2", + "early_seed_development_3" + ], + "Early-mid_Seed_Development": [ + "early_mid_seed_development_1", + "early_mid_seed_development_2", + "early_mid_seed_development_3" + ], + "Late-mid_Seed_Development": [ + "late_mid_seed_development_1", + "late_mid_seed_development_2", + "late_mid_seed_development_3" + ], + "Late_Seed_Development": [ + "late_seed_development_1", + "late_seed_development_2", + "late_seed_development_3" + ] + } + } + } + }, + "Developmental_Atlas_TPM": { + "database": "camelina_tpm", + "view_name": "Developmental_Atlas_TPM", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Germinating_Seed": [ + "germinating_seed_1", + "germinating_seed_2", + "germinating_seed_3" + ], + "Cotyledon": [ + "cotyledon_1", + "cotyledon_2", + "cotyledon_3" + ], + "Young_Leaf": [ + "young_leaf_1", + "young_leaf_2", + "young_leaf_3" + ], + "Senescing_Leaf": [ + "senescing_leaf_1", + "senescing_leaf_2", + "senescing_leaf_3" + ], + "Root": [ + "root_1", + "root_2", + "root_3" + ], + "Stem": [ + "stem_1", + "stem_2", + "stem_3" + ], + "Buds": [ + "bud_1", + "bud_2", + "bud_3" + ], + "Flower": [ + "flower_1", + "flower_2", + "flower_3" + ], + "Early_Seed_Development": [ + "early_seed_development_1", + "early_seed_development_2", + "early_seed_development_3" + ], + "Early-mid_Seed_Development": [ + "early_mid_seed_development_1", + "early_mid_seed_development_2", + "early_mid_seed_development_3" + ], + "Late-mid_Seed_Development": [ + "late_mid_seed_development_1", + "late_mid_seed_development_2", + "late_mid_seed_development_3" + ], + "Late_Seed_Development": [ + "late_seed_development_1", + "late_seed_development_2", + "late_seed_development_3" + ] + } + } + } + } + } + } + }, + "cannabis": { + + "data": { + "species": "cannabis", + "views": { + "Cannabis_Atlas": { + "database": "cannabis", + "view_name": "Cannabis_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "PK-Shoot": [ + "PK-SHT" + ], + "PK-Root": [ + "PK-RT" + ], + "PK-MidFlower": [ + "PK-MFLW" + ], + "PK-EarlyFlower": [ + "PK-EFLW" + ], + "PK-PreFlower": [ + "PK-PFLW" + ], + "PK-Stem": [ + "PK-STM" + ] + } + } + } + } + } + } + }, + "canola": { + + "data": { + "species": "canola", + "views": { + "Canola_Seed": { + "database": "canola_seed", + "view_name": "Canola_Seed", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Chalazal_proliferating_tissue,_ovule_stage": [ + "ovCPT1_2", + "ovCPT3", + "ovCPT3_2" + ], + "Chalazal_seed_coat,_ovule_stage": [ + "ovCZSC1", + "ovCZSC2", + "ovCZSC3" + ], + "Inner_seed_coat,_ovule_stage": [ + "ovISC1", + "ovISC2", + "ovISC3" + ], + "Outer_seed_coat,_ovule_stage": [ + "ovOSC1", + "ovOSC2", + "ovOSC3" + ], + "Chalazal_proliferating_tissue,_globular_stage": [ + "gCPT1", + "gCPT2", + "gCPT3" + ], + "Chalazal_endosperm,_globular_stage": [ + "gCZE1", + "gCZE2", + "gCZE3" + ], + "Chalazal_seed_coat,_globular_stage": [ + "gCZSC1", + "gCZSC2", + "gCZSC3" + ], + "Embryo_proper,_globular_stage": [ + "gEP1", + "gEP2", + "GLOB_EP4J1", + "GLOB_EP4J17" + ], + "Inner_seed_coat,_globular_stage": [ + "gISC1", + "gISC2", + "gISC3" + ], + "Outer_seed_coat,_globular_stage": [ + "gOSC2", + "gOSC3" + ], + "Micropylar_endosperm,_globular_stage": [ + "gMCE1", + "gMCE2", + "gMCE3", + "gMCE4", + "GLOB_MCE2" + ], + "Peripheral_endosperm,_globular_stage": [ + "gPEN1", + "gPEN2" + ], + "Chalazal_proliferating_tissue,_heart_stage": [ + "hCPT1", + "hCPT2", + "hCPT3" + ], + "Chalazal_endosperm,_heart_stage": [ + "hCZE1", + "hCZE2" + ], + "Chalazal_seed_coat,_heart_stage": [ + "hCZSC1", + "hCZSC2", + "hCZSC3" + ], + "Embryo_proper,_heart_stage": [ + "hEPJ", + "HRT_EPJ" + ], + "Inner_seed_coat,_heart_stage": [ + "hISC1_3", + "hISC2", + "hISC3" + ], + "Micropylar_endosperm,_heart_stage": [ + "hMCE2", + "HRT_MCE1", + "HRT_MCE2", + "HRT_MCE26" + ], + "Outer_seed_coat,_heart_stage": [ + "hOSC1", + "hOSC2", + "hOSC3" + ], + "Peripheral_endosperm,_heart_stage": [ + "hPEN1", + "hPEN2" + ], + "Chalazal_proliferating_tissue,_maturation_green_stage": [ + "mgCPT1", + "mgCPT2", + "mgCPT3" + ], + "Chalazal_seed_coat,_maturation_green_stage": [ + "mgCZSC2", + "mgCZSC3", + "mgCZSC3_2" + ], + "Inner_seed_coat,_maturation_green_stage": [ + "mgISC1", + "mgISC2" + ], + "Outer_seed_coat,_maturation_green_stage": [ + "mgOSC1", + "mgOSC2", + "mgOSC3" + ], + "Embryo_cotyledons,_maturation_green_stage": [ + "MG_COT1", + "MG_COT2", + "MG_COT8" + ], + "Embryo_root,_maturation_green_stage": [ + "MG_ROOT2", + "MG_ROOT3" + ] + } + } + } + } + } + } + }, + "eutrema": { + + "data": { + "species": "eutrema", + "views": { + "Eutrema": { + "database": "thellungiella_db", + "view_name": "Eutrema", + "groups": { + "THELLUNGIELLA_CTRL": { + "controls": [ + "THELLUNGIELLA_CTRL" + ], + "treatments": { + "Shandong_accession_grown_in_cabinet,_rosette_leaves": [ + "SC1", + "SC2", + "SC3" + ], + "Yukon_accession_grown_in_cabinet,_rosette_leaves": [ + "YC1", + "YC2", + "YC3" + ], + "Yukon_accession_collected_from_the_field_in_2005": [ + "YF1", + "YF2", + "YF3" + ] + } + } + } + } + } + } + }, + "grape": { + + "data": { + "species": "grape", + "views": { + "grape_developmental": { + "database": "grape_developmental", + "view_name": "grape_developmental", + "groups": { + "Dev": { + "controls": [ + "GRAPE_CTRL" + ], + "treatments": { + "Tendril_-_Young": [ + "GSM881670", + "GSM881671", + "GSM881672" + ], + "Tendril_-_Well_Developed": [ + "GSM881673", + "GSM881674", + "GSM881675" + ], + "Tendril_-_Fruit_Set": [ + "GSM881676", + "GSM881677", + "GSM881678" + ], + "Leaf_-_Young": [ + "GSM881586", + "GSM881587", + "GSM881588" + ], + "Leaf_-_Fruit_Set": [ + "GSM881589", + "GSM881590", + "GSM881591" + ], + "Leaf_-_Senescent": [ + "GSM881592", + "GSM881593", + "GSM881594" + ], + "Seedling": [ + "GSM881640", + "GSM881641", + "GSM881642" + ], + "Stem_-_Young": [ + "GSM881664", + "GSM881665", + "GSM881666" + ], + "Stem_-_Mature_(Woody)": [ + "GSM881667", + "GSM881668", + "GSM881669" + ], + "Bud_-_Bud_Swelling_Stage": [ + "GSM881535", + "GSM881536", + "GSM881537" + ], + "Bud_-_Bud_Burst_Initial_Stage": [ + "GSM881538", + "GSM881539", + "GSM881540" + ], + "Bud_-_Bud_Burst_Later_Stage": [ + "GSM881541", + "GSM881542", + "GSM881543" + ], + "Bud_-_Latent_Bud": [ + "GSM881544", + "GSM881545", + "GSM881546" + ], + "Bud_-_Winter_Dormant": [ + "GSM881547", + "GSM881548", + "GSM881549" + ], + "Flower_-_Young": [ + "GSM881571", + "GSM881572", + "GSM881573" + ], + "Flower_-_Well_Developed": [ + "GSM881574", + "GSM881575", + "GSM881576" + ], + "Flower_-_Start_of_Flowering": [ + "GSM881577", + "GSM881578", + "GSM881579" + ], + "Flower_-_Flowering": [ + "GSM881580", + "GSM881581", + "GSM881582" + ], + "Root": [ + "GSM881583", + "GSM881584", + "GSM881585" + ], + "Carpel": [ + "GSM881595", + "GSM881596", + "GSM881597" + ], + "Stamen": [ + "GSM881517", + "GSM881518", + "GSM881519" + ], + "Petals": [ + "GSM881598", + "GSM881599", + "GSM881600" + ], + "Pollen": [ + "GSM881610", + "GSM881611", + "GSM881612" + ], + "Rachis_-_Fruit_Set": [ + "GSM881613", + "GSM881614", + "GSM881615" + ], + "Seed_-_Fruit_Set": [ + "GSM881634", + "GSM881635", + "GSM881636" + ], + "Pericarp_-_Fruit_Set": [ + "GSM881520", + "GSM881521", + "GSM881522" + ], + "Rachis_-_Post_Fruit_Set": [ + "GSM881616", + "GSM881617", + "GSM881618" + ], + "Pericarp_-_Post_Fruit_Set": [ + "GSM881523", + "GSM881524", + "GSM881525" + ], + "Seed_-_Post_Fruit_Set": [ + "GSM881637", + "GSM881638", + "GSM881639" + ], + "Flesh_-_Post_Fruit_Set": [ + "GSM881550", + "GSM881551", + "GSM881552" + ], + "Skin_-_Post_Fruit_Set": [ + "GSM881643", + "GSM881644", + "GSM881645" + ], + "Seed_-_Veraison": [ + "GSM881628", + "GSM881629", + "GSM881630" + ], + "Pericarp_-_Veraison": [ + "GSM881526", + "GSM881527", + "GSM881528" + ], + "Flesh_-_Veraison": [ + "GSM881553", + "GSM881554", + "GSM881555" + ], + "Skin_-_Veraison": [ + "GSM881646", + "GSM881647", + "GSM881648" + ], + "Rachis_-_Veraison": [ + "GSM881619", + "GSM881620", + "GSM881621" + ], + "Rachis_-_Mid_Ripening": [ + "GSM881622", + "GSM881623", + "GSM881624" + ], + "Seed_-_Mid_Ripening": [ + "GSM881628", + "GSM881629", + "GSM881630" + ], + "Pericarp_-_Mid_Ripening": [ + "GSM881529", + "GSM881530", + "GSM881531" + ], + "Flesh_-_Mid_Ripening": [ + "GSM881556", + "GSM881557", + "GSM881558" + ], + "Skin_-_Mid_Ripening": [ + "GSM881649", + "GSM881650", + "GSM881651" + ], + "Rachis_-_Ripening": [ + "GSM881625", + "GSM881626", + "GSM881627" + ], + "Pericarp_-_Ripening": [ + "GSM881532", + "GSM881533", + "GSM881534" + ], + "Flesh_-_Ripening": [ + "GSM881559", + "GSM881560", + "GSM881561" + ], + "Skin_-_Ripening": [ + "GSM881652", + "GSM881653", + "GSM881654" + ] + } + }, + "Flesh_Stress": { + "controls": [ + "GRAPE_FLESH_STRESS_CTRL" + ], + "treatments": { + "Flesh_-_PHWI": [ + "GSM881562", + "GSM881563", + "GSM881564" + ], + "Flesh_-_PHWII": [ + "GSM881565", + "GSM881566", + "GSM881567" + ], + "Flesh_-_PHWIII": [ + "GSM881568", + "GSM881569", + "GSM881570" + ] + } + }, + "Pericarp_Stress": { + "controls": [ + "GRAPE_PERICARP_STRESS_CTRL" + ], + "treatments": { + "Pericarp_-_PHWI": [ + "GSM881601", + "GSM881602", + "GSM881603" + ], + "Pericarp_-_PHWII": [ + "GSM881604", + "GSM881605", + "GSM881606" + ], + "Pericarp_-_PHWIII": [ + "GSM881607", + "GSM881608", + "GSM881609" + ] + } + }, + "Skin_Stress": { + "controls": [ + "GRAPE_SKIN_STRESS_CTRL" + ], + "treatments": { + "Skin_-_PHWI": [ + "GSM881655", + "GSM881656", + "GSM881657" + ], + "Skin_-_PHWII": [ + "GSM881658", + "GSM881659", + "GSM881660" + ], + "Skin_-_PHWIII": [ + "GSM881661", + "GSM881662", + "GSM881663" + ] + } + } + } + } + } + } + }, + "kalanchoe": { + + "data": { + "species": "kalanchoe", + "views": { + "Light_Response": { + "database": "kalanchoe", + "view_name": "Light_Response", + "groups": { + "White_Light_Dawn_control_group": { + "controls": [ + "WL_Dawn_rep1", + "WL_Dawn_rep2", + "WL_Dawn_rep3" + ], + "treatments": { + "HL_Dusk": [ + "HL_Dusk_rep1", + "HL_Dusk_rep2", + "HL_Dusk_rep3" + ], + "RL_Dusk": [ + "RL_Dusk_rep1", + "RL_Dusk_rep2", + "RL_Dusk_rep3" + ], + "HL_Dawn": [ + "HL_Dawn_rep1", + "HL_Dawn_rep2", + "HL_Dawn_rep3" + ], + "BL_Dawn": [ + "BL_Dawn_rep1", + "BL_Dawn_rep2", + "BL_Dawn_rep3" + ], + "LL_Dawn": [ + "LL_Dawn_rep1", + "LL_Dawn_rep2", + "LL_Dawn_rep3" + ], + "LL_Dusk": [ + "LL_Dusk_rep1", + "LL_Dusk_rep2", + "LL_Dusk_rep3" + ], + "WL_Dusk": [ + "WL_Dusk_rep1", + "WL_Dusk_rep2", + "WL_Dusk_rep3" + ], + "BL_Dusk": [ + "BL_Dusk_rep1", + "BL_Dusk_rep2", + "BL_Dusk_rep3" + ], + "DG_Dusk": [ + "DG_Dusk_rep1", + "DG_Dusk_rep2", + "DG_Dusk_rep3" + ], + "RL_Dawn": [ + "RL_Dawn_rep1", + "RL_Dawn_rep2", + "RL_Dawn_rep3" + ], + "DG_Dawn": [ + "DG_Dawn_rep1", + "DG_Dawn_rep2", + "DG_Dawn_rep3" + ], + "WL_Dawn": [ + "WL_Dawn_rep1", + "WL_Dawn_rep2", + "WL_Dawn_rep3" + ], + "FR_Dawn": [ + "FRL_Dawn_rep1", + "FRL_Dawn_rep2", + "FRL_Dawn_rep3" + ], + "FR_Dusk": [ + "FRL_Dusk_rep1", + "FRL_Dusk_rep2", + "FRL_Dusk_rep3" + ] + } + } + } + } + } + } + }, + "little millet": { + + "data": { + "species": "little millet", + "views": { + "Life_Cycle": { + "database": "little_millet", + "view_name": "Life_Cycle", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Germinating_Seed": [ + "GS1", + "GS2", + "GS3" + ], + "Radicle": [ + "RD1", + "RD2", + "RD3" + ], + "Plumule": [ + "PU1", + "PU2", + "PU3" + ], + "Young_Leaf": [ + "YL1", + "YL2", + "YL3" + ], + "Young_Root": [ + "YR1", + "YR2" + ], + "Crown_Meristem": [ + "CM1", + "CM2", + "CM3" + ], + "Vegetative_Stem": [ + "VS1", + "VS2" + ], + "Panicle_Early": [ + "PE1", + "PE2", + "PE3" + ], + "Panicle_Mid": [ + "PM1", + "PM2", + "PM3" + ], + "Panicle_Late": [ + "PL1", + "PL2", + "PL3" + ] + } + } + } + } + } + } + }, + "lupin": { + + "data": { + "species": "lupin", + "views": { + "LCM_Leaf": { + "database": "lupin_lcm_leaf", + "view_name": "LCM_Leaf", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Epidermis": [ + "Leaf_epidermis_1", + "Leaf_epidermis_2" + ], + "Mesophyll": [ + "Leaf_mesophyll_1", + "Leaf_mesophyll_2" + ], + "Vasculature": [ + "Leaf_vasculature_1", + "Leaf_vasculature_2" + ] + } + } + } + }, + "LCM_Pod": { + "database": "lupin_lcm_pod", + "view_name": "LCM_Pod", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Exocarp": [ + "Pod_exocarp_1", + "Pod_exocarp_2" + ], + "Endocarp": [ + "Pod_endocarp_1", + "Pod_endocarp_2" + ], + "Bundle_sheath": [ + "Pod_bundle_sheath_1", + "Pod_bundle_sheath_2" + ], + "Mesocarp": [ + "Pod_mesocarp_1", + "Pod_mesocarp_2" + ], + "Transverse_vasculature": [ + "Pod_transverse_vasculature_1", + "Pod_transverse_vasculature_2" + ], + "Ventral_suture_vasculature": [ + "Pod_ventral_suture_vasculature_1", + "Pod_ventral_suture_vasculature_2" + ] + } + } + } + }, + "LCM_Stem": { + "database": "lupin_lcm_stem", + "view_name": "LCM_Stem", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Epidermis": [ + "Stem_epidermis_1" + ], + "Parenchyma": [ + "Stem_parenchyma_1", + "Stem_parenchyma_2" + ], + "Phloem": [ + "Stem_phloem_1", + "Stem_phloem_2" + ], + "Xylem": [ + "Stem_xylem_1", + "Stem_xylem_2" + ] + } + } + } + }, + "Whole_Plant": { + "database": "lupin_whole_plant", + "view_name": "Whole_Plant", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Big_seed": [ + "Big_seed" + ], + "Big_pod": [ + "Big_pod" + ], + "Flowers": [ + "Flowers" + ], + "Leaves": [ + "Leaves" + ], + "Pedicels": [ + "Pedicels" + ], + "Roots": [ + "Roots" + ], + "Small_pod_with_seeds": [ + "Small_pod_with_seeds" + ], + "Stem": [ + "Stem" + ] + } + } + } + } + } + } + }, + "maize": { + + "data": { + "species": "maize", + "views": { + "Downs_et_al_Atlas": { + "database": "maize_gdowns", + "view_name": "Downs_et_al_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "24DAP_leaf;_15cm_tip_of_2nd_leaf_above_top_ear": [ + "24DAP_leaf_1", + "24DAP_leaf_2", + "24DAP_leaf_3" + ], + "17DAP_endosperm;_endosperm_of_top_ear": [ + "17DAP_endosperm_1", + "17DAP_endosperm_2", + "17DAP_endosperm_3" + ], + "VE_root;_seminal_root": [ + "VE_root_1", + "VE_root_2", + "VE_root_3" + ], + "V16_tassel;_spikelet_of_tassel_(top_10_cm)": [ + "V16_tassel_1", + "V16_tassel_2", + "V16_tassel_3" + ], + "V4_tassel;_1mm_tassel_meristem_and_1mm_uppermost_stem_below_tassel": [ + "V4_tassel_1", + "V4_tassel_2", + "V4_tassel_3" + ], + "24DAP_embryo;_embryo_of_top_ear": [ + "24DAP_embryo_1", + "24DAP_embryo_2", + "24DAP_embryo_3" + ], + "V2_nodal_root;_nodal_root": [ + "V2_nodal_root_1", + "V2_nodal_root_2", + "V2_nodal_root_3" + ], + "V16_cob;_top_ear_(5_cm)_cob": [ + "V16_cob_1", + "V16_cob_2", + "V16_cob_3" + ], + "R1_stalk;_R1-15_cm_stalk_below_tassel": [ + "R1_stalk_1", + "R1_stalk_2", + "R1_stalk_3" + ], + "10DAP_embryo;_embryo_of_top_ear": [ + "10DAP_embryo_1", + "10DAP_embryo_2", + "10DAP_embryo_3" + ], + "24DAP_endosperm;_endosperm_of_top_ear": [ + "24DAP_endosperm_1", + "24DAP_endosperm_2", + "24DAP_endosperm_3" + ], + "17DAP_pericarp;_pericarp_of_top_ear": [ + "17DAP_pericarp_1", + "17DAP_pericarp_2", + "17DAP_pericarp_3" + ], + "V5_stalk_below_tassel;_stalk_below_tassel_(2_cm)": [ + "V5_stalk_below_tassel_1", + "V5_stalk_below_tassel_2", + "V5_stalk_below_tassel_3" + ], + "V10_tassel;_top_10_cm_of_tassel_(~20_cm)": [ + "V10_tassel_1", + "V10_tassel_2", + "V10_tassel_3" + ], + "R1_leaf;_15_cm_tip_of_2nd_leaf_above_top_ear": [ + "R1_leaf_1", + "R1_leaf_2", + "R1_leaf_3" + ], + "V5_tassel;_tassel_3-5mm": [ + "V5_tassel_1", + "V5_tassel_2", + "V5_tassel_3" + ], + "31DAP_embryo;_embryo_of_top_ear": [ + "31DAP_embryo_1", + "31DAP_embryo_2", + "31DAP_embryo_3" + ], + "V8_V9_ear;_top_ear_3-5mm": [ + "V8_V9_ear_1", + "V8_V9_ear_2", + "V8_V9_ear_3" + ], + "V2_stalk;_stalk": [ + "V2_stalk_1", + "V2_stalk_2", + "V2_stalk_3" + ], + "V2_leaf;_actively_growing_leaf:_fourth_leaf": [ + "V2_leaf_1", + "V2_leaf_2", + "V2_leaf_3" + ], + "17DAP_leaf;_15_cm_tip_of_2nd_leaf_above_top_ear": [ + "17DAP_leaf_1", + "17DAP_leaf_2", + "17DAP_leaf_3" + ], + "R1_cob;_cob_of_top_ear": [ + "R1_cob_1", + "R1_cob_2", + "R1_cob_3" + ], + "V7_top_ear_shoot;_top_ear_shoot": [ + "V7_top_ear_shoot_1", + "V7_top_ear_shoot_2", + "V7_top_ear_shoot_3" + ], + "VT_anthers;_anther": [ + "VT_anthers_1", + "VT_anthers_2", + "VT_anthers_3" + ], + "5DAP_ovule;_ovule_of_top_ear": [ + "5DAP_ovule_1", + "5DAP_ovule_2", + "5DAP_ovule_3" + ], + "V16_floret;_top_ear_(5_cm)_floret": [ + "V16_floret_1", + "V16_floret_2", + "V16_floret_3" + ], + "V1_leaf;_1st_and_2nd_leaf": [ + "V1_leaf_1", + "V1_leaf_2", + "V1_leaf_3" + ], + "10DAP_leaf;_15_cm_tip_of_2nd_leaf_above_top_ear": [ + "10DAP_leaf_1", + "10DAP_leaf_2", + "10DAP_leaf_3" + ], + "R1_husk;_most_inner_husk_of_top_ear": [ + "R1_husk_1", + "R1_husk_2", + "R1_husk_3" + ], + "VE_leaf;_coleoptile": [ + "VE_leaf_1", + "VE_leaf_2", + "VE_leaf_3" + ], + "V2_seminal_root;_seminal_root": [ + "V2_seminal_root_1", + "V2_seminal_root_2", + "V2_seminal_root_3" + ], + "V16_silk;_top_ear_(5_cm)_silk": [ + "V16_silk_1", + "V16_silk_2", + "V16_silk_3" + ], + "V8_V9_tassel;_tassel_12-14_cm": [ + "V8_V9_tassel_1", + "V8_V9_tassel_2", + "V8_V9_tassel_3" + ], + "24DAP_root;_nodal_root": [ + "24DAP_root_1", + "24DAP_root_2", + "24DAP_root_3" + ], + "R1_ovule;_R1-ovule_of_top_ear": [ + "R1_ovule_1", + "R1_ovule_2", + "R1_ovule_3" + ], + "5DAP_cob;_cob_of_top_ear": [ + "5DAP_cob_1", + "5DAP_cob_2", + "5DAP_cob_3" + ], + "V7_tassel;_tassel_2_cm": [ + "V7_tassel_1", + "V7_tassel_2", + "V7_tassel_3" + ], + "V5_seminal_root;_seminal_root": [ + "V5_seminal_root_1", + "V5_seminal_root_2", + "V5_seminal_root_3" + ], + "V15_tassel;_spikelet_of_tassel_(~22_cm)": [ + "V15_tassel_1", + "V15_tassel_2", + "V15_tassel_3" + ], + "24DAP_pericarp;_pericarp_of_top_ear": [ + "24DAP_pericarp_1", + "24DAP_pericarp_2", + "24DAP_pericarp_3" + ], + "V10_ear;_top_ear_1-1.5_cm": [ + "V10_ear_1", + "V10_ear_2", + "V10_ear_3" + ], + "V5_leaf;_actively_growing_leaf:_eighth_leaf,_15_cm_including_tip": [ + "V5_leaf_1", + "V5_leaf_2", + "V5_leaf_3" + ], + "10DAP_endosperm;_endosperm_of_top_ear": [ + "10DAP_endosperm_1", + "10DAP_endosperm_2", + "10DAP_endosperm_3" + ], + "31DAP_leaf;_15_cm_tip_of_2nd_leaf_above_top_ear": [ + "31DAP_leaf_1", + "31DAP_leaf_2", + "31DAP_leaf_3" + ], + "R1_silk;_silk_of_top_ear": [ + "R1_silk_1", + "R1_silk_2", + "R1_silk_3" + ], + "V15_ear;_top_ear_3-3.5_cm": [ + "V15_ear_1", + "V15_ear_2", + "V15_ear_3" + ], + "17DAP_embryo;_embryo_of_top_ear": [ + "17DAP_embryo_1", + "17DAP_embryo_2", + "17DAP_embryo_3" + ], + "V5_nodal_root;_nodal_root": [ + "V5_nodal_root_1", + "V5_nodal_root_2", + "V5_nodal_root_3" + ], + "R1_root;_adult_nodal_root": [ + "R1_root_1", + "R1_root_2", + "R1_root_3" + ], + "V1_root;_seminal_root": [ + "V1_root_1", + "V1_root_2", + "V1_root_3" + ] + } + } + } + }, + "Early_Seed": { + "database": "maize_early_seed", + "view_name": "Early_Seed", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "NU0": [ + "NU0" + ], + "NU4": [ + "NU4" + ], + "NU8": [ + "NU8" + ], + "NU12": [ + "NU12" + ], + "NU16": [ + "NU16" + ], + "NU20": [ + "NU20" + ], + "NU24": [ + "NU24" + ], + "NU28": [ + "NU28" + ], + "NU32": [ + "NU32" + ], + "NU36": [ + "NU36" + ], + "NU40": [ + "NU40" + ], + "NU44": [ + "NU44" + ], + "NU48": [ + "NU48" + ], + "NU52": [ + "NU52" + ], + "NU56": [ + "NU56" + ], + "NU60": [ + "NU60" + ], + "NU64": [ + "NU64" + ], + "NU68": [ + "NU68" + ], + "NU72": [ + "NU72" + ], + "NU78": [ + "NU78" + ], + "NU84": [ + "NU84" + ], + "NU90": [ + "NU90" + ], + "NU96": [ + "NU96" + ], + "NU102": [ + "NU102" + ], + "NU108": [ + "NU108" + ], + "NU114": [ + "NU114" + ], + "NU120": [ + "NU120" + ], + "NU126": [ + "NU126" + ], + "NU132": [ + "NU132" + ], + "NU138": [ + "NU138" + ], + "NU144": [ + "NU144" + ] + } + } + } + }, + "Embryonic_Leaf_Development": { + "database": "maize_embryonic_leaf_development", + "view_name": "Embryonic_Leaf_Development", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Prepalisade_mesophylll": [ + "PM_JW04", + "PM_JW06" + ], + "Median_ground_meristem": [ + "mGM_JW07" + ], + "4BS+V-stage_PM": [ + "4PM_IZ11", + "4PM_IZ16", + "4PM_JX03" + ], + "3C-stage_PM": [ + "mGM_JW07" + ], + "3_contiguous_cells": [ + "mGM_JW07" + ], + "5/6BS+V-stage_PM": [ + "5_6PM_IZ13", + "5_6PM_IZ18B" + ], + "4_pre-bundle_sheath_cells_+_pre-vein_cells": [ + "4BS_V_IZ02", + "4BS_V_IZ06" + ], + "1_median_mesophyll_cell": [ + "1_M_IZ09", + "1_M_IZ14", + "1_M_JX01" + ], + "2_median_mesophyll_cells": [ + "2_M_IZ10", + "2_M_IZ15", + "2_M_JX02" + ], + "5_pre-bundle_sheath_cells_+_pre-vein_cells": [ + "5BS_V_IZ03", + "5BS_V_IZ07" + ], + "6_pre-bundle_sheath_cells_+_pre-vein": [ + "6BS_V_IZ04", + "6BS_V_IZ08" + ] + } + } + } + }, + "Hoopes_et_al_Atlas": { + "database": "maize_buell_lab", + "view_name": "Hoopes_et_al_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Shoot_tip_V5": [ + "SK037__V5_Shoot_tip_R1", + "SK038__V5_Shoot_tip_R2", + "SK039__V5_Shoot_tip_R3" + ], + "Seed_2DAP": [ + "SK106__2DAP_Whole_seed_R1", + "SK107__2DAP_Whole_seed_R2", + "SK108__2DAP_Whole_seed_R3" + ], + "Meiotic_Tassel_V18": [ + "SK076__V18_Meiotic_tassel_R1", + "SK077__V18_Meiotic_tassel_R2", + "SK078__V18_Meiotic_tassel_R3" + ], + "Immature_Tassel_V13": [ + "SK073__V13_Immature_tassel_R1", + "SK074__V13_Immature_tassel_R2", + "SK075__V13_Immature_tassel_R3" + ], + "ThreeDAS-MZEZ": [ + "SS.27__Mz.Ez_3d_R2", + "SS.45__Mz.Ez_3d_R1", + "SS.56__Mz.Ez_3d_R3" + ], + "Internode_24DAP": [ + "PP_33__24_POL_INT_R1", + "PP_34__24_POL_INT_R2" + ], + "V13-BR-Node6": [ + "SS.69__BraceRoot_Node6_abvgrnd_V13_R1", + "SS.74__BraceRoot_Node6_abvgrnd_V13_R2", + "SS.76__BraceRoot_Node6_abvgrnd_V13_R3" + ], + "V7-CR-Nodes1-3": [ + "SS.70__CrownRoot_Nodes_1.3__V7_R1", + "SS.71__CrownRoot_Nodes_1.3__V7_R3" + ], + "Fourth_Internode_V9": [ + "SK058__V9_Fourth_elongated_internode_R1", + "SK059__V9_Fourth_elongated_internode_R2", + "SK060__V9_Fourth_elongated_internode_R3" + ], + "Coleoptile_6DAS_Primary_Root": [ + "SK007__6DAS_GH_Primary_Root_R1", + "SK008__6DAS_GH_Primary_Root_R2", + "SK009__6DAS_GH_Primary_Root_R3" + ], + "SevenDAS-PR-Z1": [ + "RA.2__TapRoot_Z1_7d_R2", + "RA.4__TapRoot_Z1_7d_R1", + "RA.5__TapRoot_Z1_7d_R3" + ], + "Pooled_Leaves_V1": [ + "SK019__V1_4D_PE_Pooled_Leaves_R1", + "SK020__V1_4D_PE_Pooled_Leaves_R2", + "SK021__V1_4D_PE_Pooled_Leaves_R3" + ], + "SevenDAS-PR-Z3": [ + "RA.14__TapRoot_Z3_7d_R1", + "RA.20__TapRoot_Z3_7d_R3", + "RA.21__TapRoot_Z3_7d_R2" + ], + "Immature_Leaf_V9": [ + "SK070__V9_Papery_Leaves_R1", + "SK071__V9_Papery_Leaves_R2", + "SK072__V9_Papery_Leaves_R3" + ], + "Seed_24DAP": [ + "SK172__24DAP_Whole_Seed_R1", + "SK173__24DAP_Whole_Seed_R2", + "SK174__24DAP_Whole_Seed_R3" + ], + "Silks_R1": [ + "SK088__R1_Silks_R1", + "SK089__R1_Silks_R2", + "SK090__R1_Silks_R3" + ], + "Endosperm_20DAP": [ + "SK157__20DAP_Endosperm_R1", + "SK158__20DAP_Endosperm_R2", + "SK159__20DAP_Endosperm_R3" + ], + "SevenDAS-PR-Z2": [ + "RA.15__TapRoot_Z2_7d_R3", + "RA.18__TapRoot_Z2_7d_R1", + "RA.3__TapRoot_Z2_7d_R2" + ], + "Tip_of_Stage_2_leaf_V7": [ + "SK052__V7_Tip_of_transition_leaf_R1", + "SK053__V7_Tip_of_transition_leaf_R2", + "SK054__V7_Tip_of_transition_leaf_R3" + ], + "ThreeDAS-CorticalParenchyma": [ + "RA.13__CortPar_3d_R2", + "RA.8__CortPar_3d_R3", + "RA.9__CortPar_3d_R1" + ], + "Tip_of_Stage_2_leaf_V5": [ + "SK043__V5_Tip_of_Stage_2_Leaf_R1", + "SK044__V5_Tip_of_Stage_2_Leaf_R2", + "SK045__V5_Tip_of_Stage_2_Leaf_R3" + ], + "Leaf_30DAP": [ + "PP.45__30_DAP_POL_LEAF_R1", + "PP.46__30_DAP_POL_LEAF_R2" + ], + "SevenDAS-RootSystem": [ + "SS.22__WholeRootSystem_7d_R2", + "SS.30__WholeRootSystem_7d_R1", + "SS.54__WholeRootSystem_7d_R3" + ], + "ThreeDAS-DZ": [ + "SS.21__DifferentiationZone_3d_R1", + "SS.28__DifferentiationZone_3d_R3", + "SS.61__DifferentiationZone_3d_R2" + ], + "Internode_18DAP": [ + "PP_25__18_POL_INT_R1", + "PP_26__18_POL_INT_R2" + ], + "Endosperm_12DAP": [ + "SK124__12DAP_Endopsperm_R1", + "SK125__12DAP_Endopsperm_R2", + "SK126__12DAP_Endopsperm_R3" + ], + "Seed_16DAP": [ + "SK133__16DAP_Whole_seed_R1", + "SK134__16DAP_Whole_seed_R2", + "SK135__16DAP_Whole_seed_R3" + ], + "Thirteenth_Leaf_R2": [ + "SK097__R2_Thirteenth_Leaf_R1", + "SK098__R2_Thirteenth_Leaf_R2", + "SK099__R2_Thirteenth_Leaf_R3" + ], + "Endosperm_22DAP": [ + "SK166__22DAP_Endosperm_R1", + "SK167__22DAP_Endosperm_R2", + "SK168__22DAP_Endosperm_R3" + ], + "Leaf_6DAP": [ + "PP.14__6_DAP_POL_LEAF_R2" + ], + "Eleventh_Leaf_V9": [ + "SK064__V9_Eleventh_Leaf_R1", + "SK065__V9_Eleventh_Leaf_R2", + "SK066__V9_Eleventh_Leaf_R3" + ], + "Endosperm_16DAP": [ + "SK136__16DAP_Endosperm_R1", + "SK137__16DAP_Endosperm_R2", + "SK138__16DAP_Endosperm_R3" + ], + "Seed_22DAP": [ + "SK163__22DAP_Whole_Seed_R1", + "SK164__22DAP_Whole_Seed_R2", + "SK165__22DAP_Whole_Seed_R3" + ], + "Base_of_Stage_2_leaf_V5": [ + "SK046__V5_Bottom_of_transition_leaf_R1", + "SK047__V5_Bottom_of_transition_leaf_R2", + "SK048__V5_Bottom_of_transition_leaf_R3" + ], + "Prepollination_Cob_R1": [ + "SK085__R1_Pre_pollination_cob_R1", + "SK086__R1_Pre_pollination_cob_R2", + "SK087__R1_Pre_pollination_cob_R3" + ], + "Seed_8DAP": [ + "SK115__8DAP_Whole_Seed_R1", + "SK116__8DAP_Whole_Seed_R2", + "SK117__8DAP_Whole_Seed_R3" + ], + "V13-CR-Node5": [ + "SS.68__CrownRoot_Node5_V13_R1", + "SS.75__CrownRoot_Node5_V13_R3", + "SS.77__CrownRoot_Node5_V13_R2" + ], + "Topmost_Leaf_V3": [ + "SK034__V3_Topmost_leaf_R1", + "SK035__V3_Topmost_leaf_R2", + "SK036__V3_Topmost_leaf_R3" + ], + "Thirteenth_Leaf_V9": [ + "SK067__V9_Thirteenth_Leaf_R1", + "SK068__V9_Thirteenth_Leaf_R2", + "SK069__V9_Thirteenth_Leaf_R3" + ], + "Endosperm_24DAP": [ + "SK175__24DAP_Endosperm_R1", + "SK176__24DAP_Endosperm_R2", + "SK177__24DAP_Endosperm_R3" + ], + "Anthers_R1": [ + "SK091__R1_Anthers_R1", + "SK092__R1_Anthers_R2", + "SK093__R1_Anthers_R3" + ], + "Base_of_Stage_2_leaf_V7": [ + "SK055__V7_Bottom_of_transition_leaf_R1", + "SK056__V7_Bottom_of_transition_leaf_R2", + "SK057__V7_Bottom_of_transition_leaf_R3" + ], + "Coleoptile_6DAS_GH": [ + "SK004__6_DAS_GH_Coleoptile_R1", + "SK005__6_DAS_GH_Coleoptile_R2", + "SK006__6_DAS_GH_Coleoptile_R3" + ], + "Embryo_20DAP": [ + "SK160__20DAP_Embryo_R1", + "SK161__20DAP_Embryo_R2", + "SK162__20DAP_Embryo_R3" + ], + "Immature_Cob_V18": [ + "SK079__V18_Immature_cob_R1", + "SK080__V18_Immature_cob_R2", + "SK081__V18_Immature_cob_R3" + ], + "Seed_12DAP": [ + "SK121__12DAP_Whole_seed_R1", + "SK122__12DAP_Whole_seed_R2", + "SK123__12DAP_Whole_seed_R3" + ], + "Seed_20DAP": [ + "SK154__20DAP_Whole_Seed_R1", + "SK155__20DAP_Whole_Seed_R2", + "SK156__20DAP_Whole_Seed_R3" + ], + "Pericarp_18DAP": [ + "SK151__18DAP_Pericarp_R1", + "SK152__18DAP_Pericarp_R2", + "SK153__18DAP_Pericarp_R3" + ], + "SevenDAS-PR-Z4": [ + "RA.10__TapRoot_Z4_7d_R2", + "RA.22__TapRoot_Z4_7d_R3", + "RA.23__TapRoot_Z4_7d_R1" + ], + "ThreeDAS-PrimaryRoot": [ + "SS.38__WholeRootSystem_3d_R3", + "SS.39__WholeRootSystem_3d_R1", + "SS.40__WholeRootSystem_3d_R2" + ], + "Seed_18DAP": [ + "SK142__18DAP_Whole_Seed_R1", + "SK144__18DAP_Whole_Seed_R3", + "SK147__18DAP_Whole_Seed_R2" + ], + "Thirteenth_Leaf_VT": [ + "SK082__VT_Thirteenth_Leaf_R1", + "SK083__VT_Thirteenth_Leaf_R2", + "SK084__VT_Thirteenth_Leaf_R3" + ], + "Internode_12DAP": [ + "PP_17__12_POL_INT_R1", + "PP_18__12_POL_INT_R2" + ], + "SevenDAS-SeminalRoots": [ + "SS.25__Seminal_7d_R3", + "SS.44__Seminal_7d_R1" + ], + "Endosperm_18DAP": [ + "SK143__18DAP_Endosperm_R3", + "SK145__18DAP_Endosperm_R1", + "SK146__18DAP_Endosperm_R2" + ], + "SevenDAS-PrimaryRoot": [ + "SS.36__WholePrimaryRoot_7d_R3", + "SS.42__WholePrimaryRoot_7d_R2", + "SS.58__WholePrimaryRoot_7d_R1" + ], + "Internode_6DAP": [ + "PP_10__6_POL_INT_R2", + "PP_9__6_POL_INT_R1" + ], + "ThreeDAS-Stele": [ + "RA.17__Stele_3d_R1", + "RA.6__Stele_3d_R3", + "RA.7__Stele_3d_R2" + ], + "Embryo_16DAP": [ + "SK139__16DAP_Embryo_R1", + "SK140__16DAP_Embryo_R2", + "SK141__16DAP_Embryo_R3" + ], + "Eighth_Leaf_V9": [ + "SK061__V9_Eighth_Leaf_R1", + "SK062__V9_Eighth_Leaf_R2", + "SK063__V9_Eighth_Leaf_R3" + ], + "First_Internode_V5": [ + "SK040__V5_First_elongated_internode_R1", + "SK041__V5_First_elongated_internode_R2", + "SK042__V5_First_elongated_internode_R3" + ], + "Seed_14DAP": [ + "SK127__14DAP_Whole_seed_R1", + "SK128__14DAP_Whole_seed_R2", + "SK129__14DAP_Whole_seed_R3" + ], + "Embryo_24DAP": [ + "SK178__24DAP_Embryo_R1", + "SK179__24DAP_Embryo_R2", + "SK180__24DAP_Embryo_R3" + ], + "Stem_and_SAM_V1": [ + "SK022__V1_4D_PE_Stem_plus_SAM_R1", + "SK023__V1_4D_PE_Stem_plus_SAM_R2", + "SK024__V1_4D_PE_Stem_plus_SAM_R3" + ], + "Stem_and_SAM_V3": [ + "SK028__V3_Stem_and_SAM_R1", + "SK029_2__V3_Stem_and_SAM_R2", + "SK030_2__V3_Stem_and_SAM_R3" + ], + "V7-CR-Node5": [ + "RA.35__CrownRoot_Node5_V7_R1", + "SS.78__CrownRoot_Node5_V7_R2" + ], + "V7-CR-Node4": [ + "SS.65__CrownRoot_Node4_V7_R1", + "SS.66__CrownRoot_Node4_V7_R2", + "SS.73__CrownRoot_Node4_V7_R3" + ], + "Seed_6DAP": [ + "SK112__6DAP_Whole_seed_R1", + "SK113__6DAP_Whole_seed_R2", + "SK114__6DAP_Whole_seed_R3" + ], + "Leaf_18DAP": [ + "PP.29__18_DAP_POL_LEAF_R1", + "PP.30__18_DAP_POL_LEAF_R2" + ], + "Internode_0DAP": [ + "PP1__0_POL_INT_R1", + "PP_2___0_POL_INT_R2" + ], + "Seed_4DAP": [ + "SK109__4DAP_Whole_Seed_R1", + "SK110__4DAP_Whole_Seed_R2", + "SK111__4DAP_Whole_Seed_R3" + ], + "Leaf_24DAP": [ + "PP.37__24_DAP_POL_LEAF_R1", + "PP.38__24_DAP_POL_LEAF_R2" + ], + "Endosperm_14DAP": [ + "SK130__14DAP_Endopsperm_R1", + "SK131__14DAP_Endopsperm_R2", + "SK132__14DAP_Endopsperm_R3" + ], + "Internode_30DAP": [ + "PP_41__30_POL_INT_R1", + "PP_42__30_POL_INT_R2" + ], + "Embryo_18DAP": [ + "SK148__18DAP_Embryo_R1", + "SK149__18DAP_Embryo_R2", + "SK150__18DAP_Embryo_R3" + ], + "Seed_10DAP": [ + "SK118__10DAP_Whole_seed_R1", + "SK119__10DAP_Whole_seed_R2", + "SK120__10DAP_Whole_seed_R3" + ], + "Leaf_12DAP": [ + "PP.21__12_DAP_POL_LEAF_R1", + "PP.22__12_DAP_POL_LEAF_R2" + ], + "Embryo_22DAP": [ + "SK169__22DAP_Embryo_R1", + "SK170__22DAP_Embryo_R2", + "SK171__22DAP_Embryo_R3" + ], + "Leaf_0DAP": [ + "PP.5__0_DAP_POL_LEAF_R1", + "PP.6__0_DAP_POL_LEAF_R2" + ] + } + } + } + }, + "Hoopes_et_al_Stress": { + "database": "maize_buell_lab", + "view_name": "Hoopes_et_al_Stress", + "groups": { + "htcld_ctrl_R1;htcld_ctrl_R2;htcld_ctrl_R3": { + "controls": [ + "htcld_ctrl_R1", + "htcld_ctrl_R2", + "htcld_ctrl_R3" + ], + "treatments": { + "TemperatureStress-Control": [ + "htcld_ctrl_R1", + "htcld_ctrl_R2", + "htcld_ctrl_R3" + ], + "TemperatureStress-Cold": [ + "cold_R1", + "cold_R2", + "cold_R3" + ], + "TemperatureStress-Heat": [ + "heat_R1", + "heat_R2", + "heat_R3" + ] + } + }, + "alb_ctrl_R1;alb_ctrl_R2;alb_ctrl_R3": { + "controls": [ + "alb_ctrl_R1", + "alb_ctrl_R2", + "alb_ctrl_R3" + ], + "treatments": { + "C_graminicola-48hpi": [ + "alb_48h_R2", + "alb_48h_R3" + ], + "C_graminicola-24hpi": [ + "alb_24h_R2", + "alb_24h_R3" + ], + "C_graminicola-0hpi": [ + "alb_ctrl_R1", + "alb_ctrl_R2", + "alb_ctrl_R3" + ] + } + }, + "drght_ctrl_6h_R1;drght_ctrl_6h_R2;drght_ctrl_6h_R3;drght_ctrl_6h_R4": { + "controls": [ + "drght_ctrl_6h_R1", + "drght_ctrl_6h_R2", + "drght_ctrl_6h_R3", + "drght_ctrl_6h_R4" + ], + "treatments": { + "DroughtStress-0MPa-6h": [ + "drght_ctrl_6h_R1", + "drght_ctrl_6h_R2", + "drght_ctrl_6h_R3", + "drght_ctrl_6h_R4" + ], + "DroughtStress-LowMPa-6h": [ + "drght_0.2_6h_R1", + "drght_0.2_6h_R2", + "drght_0.2_6h_R3", + "drght_0.2_6h_R4" + ], + "DroughtStress-VeryLowMPa-6h": [ + "drght_0.8_6h_R1", + "drght_0.8_6h_R2", + "drght_0.8_6h_R3", + "drght_0.8_6h_R4" + ] + } + }, + "gls_us_ctrl_R1;gls_us_ctrl_R2;gls_us_ctrl_R3": { + "controls": [ + "gls_us_ctrl_R1", + "gls_us_ctrl_R2", + "gls_us_ctrl_R3" + ], + "treatments": { + "C_zeina-UpperLeaves": [ + "gls_us_ctrl_R1", + "gls_us_ctrl_R2", + "gls_us_ctrl_R3" + ], + "C_zeina-LowerLeaves": [ + "gls_us_R1", + "gls_us_R2", + "gls_us_R3" + ] + } + }, + "drght_ctrl_24h_R1;drght_ctrl_24h_R2;drght_ctrl_24h_R3;drght_ctrl_24h_R4": { + "controls": [ + "drght_ctrl_24h_R1", + "drght_ctrl_24h_R2", + "drght_ctrl_24h_R3", + "drght_ctrl_24h_R4" + ], + "treatments": { + "DroughtStress-VeryLowMPa-24h": [ + "drght_0.8_24h_R1", + "drght_0.8_24h_R2", + "drght_0.8_24h_R3", + "drght_0.8_24h_R4" + ], + "DroughtStress-LowMPa-24h": [ + "drght_0.2_24h_R1", + "drght_0.2_24h_R2", + "drght_0.2_24h_R3", + "drght_0.2_24h_R4" + ], + "DroughtStress-0MPa-24h": [ + "drght_ctrl_24h_R1", + "drght_ctrl_24h_R2", + "drght_ctrl_24h_R3", + "drght_ctrl_24h_R4" + ] + } + }, + "slt_ctrl_R1;slt_ctrl_R2;slt_ctrl_R3": { + "controls": [ + "slt_ctrl_R1", + "slt_ctrl_R2", + "slt_ctrl_R3" + ], + "treatments": { + "SaltStress-0mM": [ + "slt_ctrl_R1", + "slt_ctrl_R2", + "slt_ctrl_R3" + ], + "SaltStress-200mM": [ + "slt_R1", + "slt_R2", + "slt_R3" + ] + } + } + } + }, + "Maize_Kernel": { + "database": "maize_early_seed", + "view_name": "Maize_Kernel", + "groups": { + "Med_CTRL_WIDIEZ": { + "controls": [ + "Med_CTRL_WIDIEZ" + ], + "treatments": { + "Apical_scutellum": [ + "AS_1", + "AS_2", + "AS_3", + "AS_4" + ], + "Endosperm": [ + "End_1", + "End_2", + "End_3", + "End_4" + ], + "Scutellar_Alleurone_Layer": [ + "SAL_1", + "SAL_2", + "SAL_3", + "SAL_4" + ], + "Embryo": [ + "Emb_1", + "Emb_2", + "Emb_3", + "Emb_4" + ], + "Endosperm_Adjacent_to_Scutellum": [ + "EAS_1", + "EAS_2", + "EAS_3", + "EAS_4" + ], + "Pericarp": [ + "Per_1", + "Per_2", + "Per_3", + "Per_4" + ] + } + } + } + }, + "Maize_Root": { + "database": "maize_root", + "view_name": "Maize_Root", + "groups": { + "CTRL_med": { + "controls": [ + "CTRL_med" + ], + "treatments": { + "Meristematic_zone_": [ + "Meristematic_zone_(control):_mean_RPKM" + ], + "Primary_root": [ + "Primary_root_FPKM" + ], + "Elongation_zone": [ + "Elongation_zone_(control):_mean_RPKM" + ], + "Root_hairs": [ + "Root_hair_FPKM" + ], + "Seminal_roots": [ + "Seminal_root_FPKM" + ], + "Crown_roots": [ + "Crown_root_FPKM" + ], + "Cortex": [ + "Cortex_(control):_mean_RPKM" + ], + "Root_hairless_root": [ + "root_FPKM" + ], + "Stele": [ + "Stele_(control):_mean_RPKM" + ] + } + }, + "6h_control:_mean_RPKM": { + "controls": [ + "6h_control:_mean_RPKM" + ], + "treatments": { + "Drought_6_hour_at_-0.2_MPA": [ + "6h_-0.2_MPa_(mild_stress):_mean_RPKM" + ], + "Drought_6_hr_control": [ + "6h_control:_mean_RPKM" + ], + "Drought_6_hour_at_-0.8_MPa": [ + "6h_-0.8_MPa_(severe_stress):_mean_RPKM" + ] + } + }, + "24h_control:_mean_RPKM": { + "controls": [ + "24h_control:_mean_RPKM" + ], + "treatments": { + "Drought_24_hr_control": [ + "24h_control:_mean_RPKM" + ], + "Drought_24_hr_-0.2_MPa": [ + "24h_-0.2_MPa_(mild_stress):_mean_RPKM" + ], + "Drought_24_hr_at_-0.8_MPa": [ + "24h_-0.8_MPa_(severe_stress):_mean_RPKM" + ] + } + } + } + }, + "Sekhon_et_al_Atlas": { + "database": "maize_RMA_linear", + "view_name": "Sekhon_et_al_Atlas", + "groups": { + "Maize_-_Kaeppler": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "Germinating_Seed_24h._PO:0009001_kernel;_PO:imbibition.": [ + "24H_Germinating Seed_R1", + "24H_Germinating Seed_R2", + "24H_Germinating Seed_R3" + ], + "Coleoptile_6DAS_GH._PO:0025287_seedling_coleoptile;_PO:0007045_coleoptile_emergence.": [ + "6DAS_GH_Coleoptile_R1", + "6DAS_GH_Coleoptile_R2", + "6DAS_GH_Coleoptile_R3" + ], + "Coleoptile_6DAS_Primary_Root._PO:0020127_primary_root;_PO:0007015_radical_emergence.": [ + "6DAS_GH_Primary Root_R1", + "6DAS_GH_Primary Root_R2", + "6DAS_GH_Primary Root_R3" + ], + "Stem_and_SAM_(V1)._PO:0020142_stem_internode;_PO:0020148_shoot_apical_meristem;_PO:0007106_LP.03_three_leaves_visible.": [ + "V1_Stem and SAM_R1", + "V1_Stem and SAM_R2", + "V1_Stem and SAM_R3" + ], + "Stem_and_SAM_(V3)._PO:0020142_stem_internode;_PO:0020148_shoot_apical_meristem;_PO:0007065_LP.05_five_leaves_visible.": [ + "V3_Stem and SAM_R1", + "V3_Stem and SAM_R2", + "V3_Stem and SAM_R3" + ], + "Stem_and_SAM_(V4)._PO:0020148_shoot_apical_meristem;_PO:0020142_internode;_PO:0007123_leaves_visible.": [ + "V4_Stem and SAM_R1", + "V4_Stem and SAM_R2", + "V4_Stem and SAM_R3" + ], + "Shoot_tip_(V5)._PO:0000037_shoot_apex;_PO:0009025_vascular_PO:0006340_adult_leaf;_PO:0001052_2_leaf_expansion_stage;_PO:0020040_leaf_PO:0020104_leaf_sheath;_PO:0007063_LP.07_7_leaves_visible.": [ + "V5_Shoot Tip_R1", + "V5_Shoot Tip_R2", + "V5_Shoot Tip_R3" + ], + "First_Internode_(V5)._PO:0020142_stem_internode;_PO:0021004_inflorescence_initiation_stage;_PO:0007063_seven_leaves_visible.": [ + "V5_First Internode_R1", + "V5_First Internode_R2", + "V5_First Internode_R3" + ], + "First_Internode_(V7)._PO:0020142_stem_internode;_PO:0021004_inflorescence_initiation_stage;_PO:0007101_LP.09_nine_leaves_visible": [ + "V7_First Internode_R1", + "V7_First Internode_R2", + "V7_First Internode_R3" + ], + "Fourth_Internode_(V9)._PO:0020142_stem_internode;_PO:0001083_inflorescence_development_stages;_PO:0007116_LP.11_eleven_leaves_visible.": [ + "V9_Fourth Internode_R1", + "V9_Fourth Internode_R2", + "V9_Fourth Internode_R3" + ], + "Immature_Tassel_(V13)._PO:0020126_tassel;_PO:0001007_pollen_developmental_stages;_PO:0007104_LP.15_fifteen_leaves_visible.": [ + "V13_Immature Tassel_R1", + "V13_Immature Tassel_R2", + "V13_Immature Tassel_R3" + ], + "Meiotic_Tassel_(V18)._PO:0020126_tassel;_PO:0001009_D_pollen_mother_cell_meiosis_stage;_PO:0007072_LP.18_eighteen_leaves_visible.": [ + "V18_Meiotic Tassel_R1", + "V18_Meiotic Tassel_R2", + "V18_Meiotic Tassel_R3" + ], + "Anthers_(R1)._PO:0006310_tassel_floret;_PO:0009066_anther;_PO:0001007_pollen_developmental_stages.": [ + "R1_Anthers_R1", + "R1_Anthers_R2", + "R1_Anthers_R3" + ], + "Whole_Seedling_(VE)._PO:0006341_primary_shoot;_PO:0007094_LP.01_one_leaf_visible.": [ + "VE_Whole Seedling_R1", + "VE_Whole Seedling_R2", + "VE_Whole Seedling_R3" + ], + "Primary_Root_(VE)._PO:0020127_primary_root;_PO:0007112_1_main_shoot_growth.": [ + "VE_Primary Root_R1", + "VE_Primary Root_R2", + "VE_Primary Root_R3" + ], + "Pooled_Leaves_(V1)._PO:0006339_juvenile_leaf;_PO:0009025_vascular_leaf;_PO:0001052_2_leaf_expansion_stage;_PO:0001053_3_leaf_fully_expanded;_PO:0007106_LP.03_three_leaves_visible.": [ + "V1_Pooled Leaves_R1", + "V1_Pooled Leaves_R2", + "V1_Pooled Leaves_R3" + ], + "Primary_Root_(V1)._PO:0020127_primary_root;_PO:0007106_LP.03_three_leaves_visible.": [ + "V1_GH_Primary Root_R1", + "V1_GH_Primary Root_R2", + "V1_GH_Primary Root_R3" + ], + "Topmost_Leaf_(V3)._PO:0006339_juvenile_leaf;_PO:0009025_vascular_leaf;_PO:0001052_2_leaf_expansion_stage;_PO:0007065_LP.05_five_leaves_visible.": [ + "V3_Topmost Leaf_R1", + "V3_Topmost Leaf_R2", + "V3_Topmost Leaf_R3" + ], + "First_Leaf_(V3)._PO:0006339_juvenile_leaf;_PO:0009025_vascular_leaf;_PO:0001053_3_leaf_fully_expanded;_PO:0007065_LP.05_five_leaves_visible.": [ + "V3_First Leaf and Sheath_R1", + "V3_First Leaf and Sheath_R2", + "V3_First Leaf and Sheath_R3" + ], + "Tip_of_Stage_2_leaf_(V5)._PO:0006339_juvenile_leaf;_PO:0008018_transition_leaf;_PO:0009025_vascular_leaf;_PO:0025142_leaf_tip;_PO:0001052_2_leaf_expansion_stage;_PO:0007063_LP.07_seven_leaves_visible.": [ + "V5_Tip of stage-2 Leaf_R1", + "V5_Tip of stage-2 Leaf_R2", + "V5_Tip of stage-2 Leaf_R3" + ], + "Base_of_Stage_2_leaf_(V5)._PO:0006340_adult_leaf;_PO:0008018_transition_leaf;_PO:0009025_vascular_leaf;_PO:0020040_leaf_base;_PO:0001052_2_leaf_expansion_stage;_PO:0007063_LP.07_seven_leaves_visible.": [ + "V5_Base of stage-2 Leaf_R1", + "V5_Base of stage-2 Leaf_R2", + "V5_Base of stage-2 Leaf_R3" + ], + "Tip_of_Stage_2_leaf_(V7)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0025142_leaf_tip;_PO:0001052_2_leaf_expansion_stage;_PO:0007101_LP.09_nine_leaves_visible.": [ + "V7_Tip of stage-2 Leaf_R1", + "V7_Tip of stage-2 Leaf_R2", + "V7_Tip of stage-2 Leaf_R3" + ], + "Base_of_Stage_2_leaf_(V7)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0020040_leaf_base;_PO:0001052_2_leaf_expansion_stage;_PO:0007101_LP.09_nine_leaves_visible.": [ + "V7_Base of stage-2 Leaf_R1", + "V7_Base of stage-2 Leaf_R2", + "V7_Base of stage-2 Leaf_R3" + ], + "Eighth_Leaf_(V9)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0001053_3_leaf_fully_expanded;_PO:0007116_LP.11_eleven_leaves_visible.": [ + "V9_Eighth Leaf_R1", + "V9_Eighth Leaf_R2", + "V9_Eighth Leaf_R3" + ], + "Eleventh_Leaf_(V9)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0001052_2_leaf_expansion_stage;_PO:0007116_LP.11_eleven_leaves_visible.": [ + "V9_Eleventh Leaf_R1", + "V9_Eleventh Leaf_R2", + "V9_Eleventh Leaf_R3" + ], + "Thirteenth_Leaf_(V9)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0020040_leaf_base;_PO:0001052_2_leaf_expansion_stage;_PO:0007116_LP.11_eleven_leaves_visible.": [ + "V9_Thirteenth Leaf_R1", + "V9_Thirteenth Leaf_R2", + "V9_Thirteenth Leaf_R3" + ], + "Immature_Leaf_(V9)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0001052_2_leaf_expansion_stage;_PO:0007116_LP.11_eleven_leaves_visible.": [ + "V9_Immature Leaves_R1", + "V9_Immature Leaves_R2", + "V9_Immature Leaves_R3" + ], + "Thirteenth_Leaf_(VT)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0020040_leaf_base;_PO:0001053_3_leaf_fully_expanded;_PO:0007003_IL.03_full_inflorescence_length_reached;_PO:0007072_LP.18_eighteen_leaves_visible.": [ + "VT_Thirteenth Leaf_R1", + "VT_Thirteenth Leaf_R2", + "VT_Thirteenth Leaf_R3" + ], + "Immature_Cob_(V18)._PO:0006505_central_spike_of_ear;_PO:0007006_IL.00_inflorescence_just_visible;_PO:0007072_LP.18_eighteen_leaves_visible.": [ + "V18_Immature Cob_R1", + "V18_Immature Cob_R2", + "V18_Immature Cob_R3" + ], + "Pre-pollination_Cob_(R1)._PO:0006505_central_spike_of_ear;_PO:0007016_4_flowering": [ + "R1_Pre-pollination Cob_R1", + "R1_Pre-pollination Cob_R2", + "R1_Pre-pollination Cob_R3" + ], + "Silks_(R1)._PO:0006354_ear_floret;_PO:0009074_style;_PO:0007016_4_flowering.": [ + "R1_Silks_R1", + "R1_Silks_R2", + "R1_Silks_R3" + ], + "Thirteenth_Leaf_(R2)._PO:0006340_adult_leaf;_PO:0009025_vascular_leaf;_PO:0020040_leaf_base;_PO:0001053_3_leaf_fully_expanded;_PO:0007001_FR.01_early_stage_of_fruit_ripening.": [ + "R2_Thirteenth Leaf_R1", + "R2_Thirteenth Leaf_R2", + "R2_Thirteenth Leaf_R3" + ], + "Innermost_Husk_(R1)._PO:0009054_inflorescence_bract;_PO:0020136_Zea_ear;_PO:0007026_FL.00_first_flower(s)_open.": [ + "R1_Innermost Husk_R1", + "R1_Innermost Husk_R2", + "R1_Innermost Husk_R3" + ], + "Innermost_Husk_(R2)._PO:0009054_inflorescence_bract;_PO:0020136_Zea_ear;_PO:0007001_FR.01_early_stage_of_fruit_ripening.": [ + "R2_Innermost Husk_R1", + "R2_Innermost Husk_R2", + "R2_Innermost Husk_R3" + ], + "Outer_Husk_(R2)._PO:0009054_inflorescence_bract;_PO:0020136_Zea_ear;_PO:0007001_FR.01_early_stage_of_fruit_ripening.": [ + "R2_Outer Husk_R1", + "R2_Outer Husk_R2", + "R2_Outer Husk_R3" + ], + "Embryo_16DAP._PO:0009009_plant_embryo;_PO:0001095_true_leaf_formation;_PO:0007001_FR.01_early_stage_of_fruit_ripening.": [ + "16DAP_Embryo_R1", + "16DAP_Embryo_R2", + "16DAP_Embryo_R3" + ], + "Embryo_18DAP._PO:0009009_plant_embryo;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening.": [ + "18DAP_Embryo_R1", + "18DAP_Embryo_R2", + "18DAP_Embryo_R3" + ], + "Embryo_20DAP._PO:0009009_plant_embryo;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening.": [ + "20DAP_Embryo_R1", + "20DAP_Embryo_R2", + "20DAP_Embryo_R3" + ], + "Embryo_22DAP._PO:0009009_plant_embryo;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening.": [ + "22DAP_Embryo_R1", + "22DAP_Embryo_R2", + "22DAP_Embryo_R3" + ], + "Embryo_24DAP._PO:0009009_plant_embryo;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening.": [ + "24DAP_Embryo_R1", + "24DAP_Embryo_R2", + "24DAP_Embryo_R3" + ], + "Endosperm_12DAP._PO:0009089_endosperm;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "12DAP_Endosperm_R1", + "12DAP_Endosperm_R2", + "12DAP_Endosperm_R3" + ], + "Endosperm_14DAP._PO:0009089_endosperm;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "14DAP_Endosperm_R1", + "14DAP_Endosperm_R2", + "14DAP_Endosperm_R3" + ], + "Endosperm_16DAP._PO:0009089_endosperm;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "16DAP_Endosperm_R1", + "16DAP_Endosperm_R2", + "16DAP_Endosperm_R3" + ], + "Endosperm_18DAP._PO:0009089_endosperm;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "18DAP_Endosperm_R1", + "18DAP_Endosperm_R2", + "18DAP_Endosperm_R3" + ], + "Endosperm_20DAP._PO:0009089_endosperm;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "20DAP_Endosperm_R1", + "20DAP_Endosperm_R2", + "20DAP_Endosperm_R3" + ], + "Endosperm_22DAP._PO:0009089_endosperm;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "22DAP_Endosperm_R1", + "22DAP_Endosperm_R2", + "22DAP_Endosperm_R3" + ], + "Endosperm_24DAP._PO:0009089_endosperm;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "24DAP_Endosperm_R1", + "24DAP_Endosperm_R2", + "24DAP_Endosperm_R3" + ], + "Seed_2DAP._PO:0009001_fruit;_PO:0001180_B_proembryo_stage;_PO:0007042_5_fruit_formation.": [ + "2DAP_Whole Seed_R1", + "2DAP_Whole Seed_R2", + "2DAP_Whole Seed_R3" + ], + "Seed_4DAP._PO:0009001_fruit;_PO:0001180_B_proembryo_stage;_PO:0007042_5_fruit_formation.": [ + "4DAP_Whole Seed_R1", + "4DAP_Whole Seed_R2", + "4DAP_Whole Seed_R3" + ], + "Seed_6DAP._PO:0009001_fruit;_PO:0001180_B_proembryo_stage;_PO:0007042_5_fruit_formation;_PO:0007633_endosperm_development_stages.": [ + "6DAP_Whole Seed_R1", + "6DAP_Whole Seed_R2", + "6DAP_Whole Seed_R3" + ], + "Seed_8DAP._PO:0009001_fruit;_PO:0001180_B_proembryo_stage;_PO:0007042_5_fruit_formation;_PO:0007633_endosperm_development_stages.": [ + "8DAP_Whole Seed_R1", + "8DAP_Whole Seed_R2", + "8DAP_Whole Seed_R3" + ], + "Seed_10DAP._PO:0009001_fruit;_PO:0001180_B_proembryo_stage;_PO:0007042_5_fruit_formation;_PO:0007633_endosperm_development_stages.": [ + "10DAP_Whole Seed_R1", + "10DAP_Whole Seed_R2", + "10DAP_Whole Seed_R3" + ], + "Seed_12DAP._PO:0009001_fruit;_PO:0001094_coleoptilar_stage;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "12DAP_Whole Seed_R1", + "12DAP_Whole Seed_R2", + "12DAP_Whole Seed_R3" + ], + "Seed_14DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "14DAP_Whole Seed_R1", + "14DAP_Whole Seed_R2", + "14DAP_Whole Seed_R3" + ], + "Seed_16DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007001_FR.01_early_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "16DAP_Whole Seed_R1", + "16DAP_Whole Seed_R2", + "16DAP_Whole Seed_R3" + ], + "Seed_18DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "18DAP_Whole Seed_R1", + "18DAP_Whole Seed_R2", + "18DAP_Whole Seed_R3" + ], + "Pericarp_18DAP._PO:0009084_pericarp;_PO:0007001_FR.01_early_stage_of_fruit_ripening.": [ + "18DAP_Pericarp_R1", + "18DAP_Pericarp_R2", + "18DAP_Pericarp_R3" + ], + "Seed_20DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007633_endosperm_development_stages.": [ + "20DAP_Whole Seed_R1", + "20DAP_Whole Seed_R2", + "20DAP_Whole Seed_R3" + ], + "Seed_22DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "22DAP_Whole Seed_R1", + "22DAP_Whole Seed_R2", + "22DAP_Whole Seed_R3" + ], + "Seed_24DAP._PO:0009001_fruit;_PO:0001095_true_leaf_formation;_PO:0007031_FR.02_mid_stage_of_fruit_ripening;_PO:0007633_endosperm_development_stages.": [ + "24DAP_Whole Seed_R1", + "24DAP_Whole Seed_R2", + "24DAP_Whole Seed_R3" + ] + } + } + } + }, + "Tassel_and_Ear_Primordia": { + "database": "maize_ears", + "view_name": "Tassel_and_Ear_Primordia", + "groups": { + "Ear_Development_and_Tassel_Primordia": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "ear_base": [ + "ear_tip" + ], + "ear_mid": [ + "ear_mid" + ], + "ear_tip": [ + "ear_tip" + ], + "tassel_2mm": [ + "tassel_2mm" + ], + "tassel_3-4mm": [ + "tassel_3-4mm" + ], + "tassel_5-7mm": [ + "tassel_5-7mm" + ], + "2mm_ear": [ + "2mm_ear" + ], + "1mm_ear": [ + "1mm_ear" + ] + } + } + } + }, + "maize_iplant": { + "database": "maize_iplant", + "view_name": "maize_iplant", + "groups": { + "Leaf_developmental_gradient_-_4_sections": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "Base": [ + "Base" + ], + "-1_from_ligule": [ + "Ligule+4" + ], + "+4_from_ligule": [ + "Ligule+9" + ], + "-1_from_tip": [ + "Tip_-1" + ] + } + }, + "LCM_ME_vs_BS_at_tip": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "Tip_BS": [ + "Tip_BS" + ], + "Tip_ME": [ + "Tip_ME" + ] + } + } + } + }, + "maize_leaf_gradient": { + "database": "maize_leaf_gradient", + "view_name": "maize_leaf_gradient", + "groups": { + "Maize_Leaf_Gradient": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "M1": [ + "M1" + ], + "M2": [ + "M2" + ], + "M3": [ + "M3" + ], + "M4": [ + "M4" + ], + "M5": [ + "M5" + ], + "M6": [ + "M6" + ], + "M7": [ + "M7" + ], + "M8": [ + "M8" + ], + "M9": [ + "M9" + ], + "M10": [ + "M10" + ], + "M11": [ + "M11" + ], + "M12": [ + "M12" + ], + "M13": [ + "M13" + ], + "M14": [ + "M14" + ], + "M15": [ + "M15" + ] + } + } + } + }, + "maize_rice_comparison": { + "database": "maize_rice_comparison", + "view_name": "maize_rice_comparison", + "groups": { + "Maize_Leaf_Gradient": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "M1": [ + "M1" + ], + "M2": [ + "M2" + ], + "M3": [ + "M3" + ], + "M4": [ + "M4" + ], + "M5": [ + "M5" + ], + "M6": [ + "M6" + ], + "M7": [ + "M7" + ], + "M8": [ + "M8" + ], + "M9": [ + "M9" + ], + "M10": [ + "M10" + ], + "M11": [ + "M11" + ], + "M12": [ + "M12" + ], + "M13": [ + "M13" + ], + "M14": [ + "M14" + ], + "M15": [ + "M15" + ] + } + }, + "Rice": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "R1": [ + "R1" + ], + "R2": [ + "R2" + ], + "R3": [ + "R3" + ], + "R4": [ + "R4" + ], + "R5": [ + "R5" + ], + "R6": [ + "R6" + ], + "R7": [ + "R7" + ], + "R8": [ + "R8" + ], + "R9": [ + "R9" + ], + "R10": [ + "R10" + ], + "R11": [ + "R11" + ] + } + } + } + } + } + } + }, + "mangosteen": { + + "data": { + "species": "mangosteen", + "views": { + "Aril_vs_Rind": { + "database": "mangosteen_aril_vs_rind", + "view_name": "Aril_vs_Rind", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Aril": [ + "A_1", + "A_2", + "A_3", + "A_5", + "A_6" + ], + "Rind": [ + "R_1", + "R_2", + "R_3", + "R_4", + "R_5", + "R_6" + ] + } + } + } + }, + "Callus": { + "database": "mangosteen_callus", + "view_name": "Callus", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Non-embryogenic": [ + "NE" + ], + "Somatic_embryogenic": [ + "SM" + ] + } + } + } + }, + "Diseased_vs_Normal": { + "database": "mangosteen_diseased_vs_normal", + "view_name": "Diseased_vs_Normal", + "groups": { + "ANC_1;ANC_2;ANC_3": { + "controls": [ + "ANC_1", + "ANC_2", + "ANC_3" + ], + "treatments": { + "Normal_aril_under_control_condition_": [ + "ANC_1", + "ANC_2", + "ANC_3" + ], + "Translucent_flesh_disorder-affected_aril_under_control_condition_": [ + "TFDA_AC_1", + "TFDA_AC_2", + "TFDA_AC_3" + ] + } + }, + "ANT_1;ANT_2;ANT_3": { + "controls": [ + "ANT_1", + "ANT_2", + "ANT_3" + ], + "treatments": { + "Normal_aril_under_treatment_condition_": [ + "ANT_1", + "ANT_2", + "ANT_3" + ], + "Translucent_flesh_disorder-affected_aril_under_treatment_condition": [ + "TFDA_AT_1", + "TFDA_AT_2", + "TFDA_AT_3" + ] + } + }, + "RNC_1;RNC_2;RNC_3": { + "controls": [ + "RNC_1", + "RNC_2", + "RNC_3" + ], + "treatments": { + "Normal_rind_under_control_condition_": [ + "RNC_1", + "RNC_2", + "RNC_3" + ], + "Gamboge_disorder-affected_rind_under_control_condition_": [ + "GDA_RC_1", + "GDA_RC_2", + "GDA_RC_3" + ] + } + }, + "RNT_1;RNT_2;RNT_3": { + "controls": [ + "RNT_1", + "RNT_2", + "RNT_3" + ], + "treatments": { + "Normal_rind_under_treatment_condition_": [ + "RNT_1", + "RNT_2", + "RNT_3" + ], + "Gamboge_disorder-affected_rind_under_treatment_condition_": [ + "GDA_RT_1", + "GDA_RT_2", + "GDA_RT_3" + ] + } + } + } + }, + "Fruit_Ripening": { + "database": "mangosteen_fruit_ripening", + "view_name": "Fruit_Ripening", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Fruit_ripening_stage_0": [ + "GmS0_1", + "GmS0_2" + ], + "Fruit_ripening_stage_2": [ + "GmS2_1", + "GmS2_2" + ], + "Fruit_ripening_stage_6": [ + "GmS6_1", + "GmS6_2" + ] + } + } + } + }, + "Seed_Development": { + "database": "mangosteen_seed_development", + "view_name": "Seed_Development", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Seed_development_week_8": [ + "GmW8_1", + "GmW8_2" + ], + "Seed_development_week_10": [ + "GmW10_1", + "GmW10_2" + ], + "Seed_development_week_12": [ + "GmW12_1", + "GmW12_2" + ], + "Seed_development_week_14": [ + "GmW14_1", + "GmW14_2" + ] + } + } + } + }, + "Seed_Germination": { + "database": "mangosteen_seed_germination", + "view_name": "Seed_Germination", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Seed_germination_D0": [ + "GSS0" + ], + "Seed_germination_D3": [ + "GSS3" + ], + "Seed_germination_D5": [ + "GSS5" + ], + "Seed_germination_D7": [ + "GSS7" + ] + } + } + } + } + } + } + }, + "medicago": { + + "data": { + "species": "medicago", + "views": { + "medicago_mas": { + "database": "medicago_mas", + "view_name": "medicago_mas", + "groups": { + "Seed": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Seed_10d": [ + "Seed10d_rep1", + "Seed10d_rep2", + "Seed10d_rep3" + ], + "Seed_12d": [ + "Seed12d_rep1", + "Seed12d_rep2", + "Seed12d_rep3" + ], + "Seed_16d": [ + "Seed16d_rep1", + "Seed16d_rep2", + "Seed16d_rep3" + ], + "Seed_20d": [ + "Seed20d_rep1", + "Seed20d_rep2", + "Seed20d_rep3" + ], + "Seed_24d": [ + "Seed24d_rep1", + "Seed24d_rep2", + "Seed24d_rep3" + ], + "Seed_36d": [ + "Seed36d_rep1", + "Seed36d_rep2", + "Seed36d_rep3" + ] + } + }, + "Flower": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Flower": [ + "Flower_rep1", + "Flower_rep2", + "Flower_rep3" + ] + } + }, + "Nodule": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Nodule_4d": [ + "Nod4d_rep1", + "Nod4d_rep2", + "Nod4d_rep3" + ], + "Nodule_10d": [ + "Nod10d_rep1", + "Nod10d_rep2", + "Nod10d_rep3" + ], + "Nodule_14d": [ + "Nod14d_rep1", + "Nod14d_rep2", + "Nod14d_rep3" + ], + "Nodule_Mature_(4w)": [ + "Nodule_rep1", + "Nodule_rep2", + "Nodule_rep3" + ] + } + }, + "Pod": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Pod": [ + "Pod_rep1", + "Pod_rep2", + "Pod_rep3" + ] + } + }, + "Vegetative_Bud": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Vegetative_Bud": [ + "Vegetative Bud_rep1", + "Vegetative Bud_rep2", + "Vegetative Bud_rep3" + ] + } + }, + "Petiole": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Petiole": [ + "Petiole_rep1", + "Petiole_rep2", + "Petiole_rep3" + ] + } + }, + "Stem": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Stem": [ + "Stem_rep1", + "Stem_rep2", + "Stem_rep3" + ] + } + }, + "Leaf_with_Petiolules": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Leaf_with_Petiolules": [ + "Leaf_rep1", + "Leaf_rep2", + "Leaf_rep3" + ] + } + }, + "Root": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Root": [ + "Root_rep1", + "Root_rep2", + "Root_rep3" + ] + } + }, + "Non-inoculated_root": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Non-inoculated_root": [ + "Root0d_rep1", + "Root0d_rep2", + "Root0d_rep3" + ] + } + } + } + }, + "medicago_rma": { + "database": "medicago_rma", + "view_name": "medicago_rma", + "groups": { + "Seed": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Seed_10d": [ + "Seed10d_rep1", + "Seed10d_rep2", + "Seed10d_rep3" + ], + "Seed_12d": [ + "Seed12d_rep1", + "Seed12d_rep2", + "Seed12d_rep3" + ], + "Seed_16d": [ + "Seed16d_rep1", + "Seed16d_rep2", + "Seed16d_rep3" + ], + "Seed_20d": [ + "Seed20d_rep1", + "Seed20d_rep2", + "Seed20d_rep3" + ], + "Seed_24d": [ + "Seed24d_rep1", + "Seed24d_rep2", + "Seed24d_rep3" + ], + "Seed_36d": [ + "Seed36d_rep1", + "Seed36d_rep2", + "Seed36d_rep3" + ] + } + }, + "Flower": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Flower": [ + "Flower_rep1", + "Flower_rep2", + "Flower_rep3" + ] + } + }, + "Nodule": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Nodule_4d": [ + "Nod4d_rep1", + "Nod4d_rep2", + "Nod4d_rep3" + ], + "Nodule_10d": [ + "Nod10d_rep1", + "Nod10d_rep2", + "Nod10d_rep3" + ], + "Nodule_14d": [ + "Nod14d_rep1", + "Nod14d_rep2", + "Nod14d_rep3" + ], + "Nodule_Mature_(4w)": [ + "Nodule_rep1", + "Nodule_rep2", + "Nodule_rep3" + ] + } + }, + "Pod": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Pod": [ + "Pod_rep1", + "Pod_rep2", + "Pod_rep3" + ] + } + }, + "Vegetative_Bud": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Vegetative_Bud": [ + "Vegetative Bud_rep1", + "Vegetative Bud_rep2", + "Vegetative Bud_rep3" + ] + } + }, + "Petiole": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Petiole": [ + "Petiole_rep1", + "Petiole_rep2", + "Petiole_rep3" + ] + } + }, + "Stem": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Stem": [ + "Stem_rep1", + "Stem_rep2", + "Stem_rep3" + ] + } + }, + "Leaf_with_Petiolules": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Leaf_with_Petiolules": [ + "Leaf_rep1", + "Leaf_rep2", + "Leaf_rep3" + ] + } + }, + "Root": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Root": [ + "Root_rep1", + "Root_rep2", + "Root_rep3" + ] + } + }, + "Non-inoculated_root": { + "controls": [ + "MED_CTRL", + "MED_CTRL" + ], + "treatments": { + "Non-inoculated_root": [ + "Root0d_rep1", + "Root0d_rep2", + "Root0d_rep3" + ] + } + } + } + }, + "medicago_seed": { + "database": "medicago_seed", + "view_name": "medicago_seed", + "groups": { + "Seed_14c": { + "controls": [ + "Med_CTRL_14C" + ], + "treatments": { + "Seed_22DAP_14C": [ + "22_DAP_14C" + ], + "Seed_28DAP_14C": [ + "28_DAP_14C" + ], + "Seed_34DAP_14C": [ + "34_DAP_14C" + ], + "Seed_40DAP_14C": [ + "40_DAP_14C" + ], + "Seed_46DAP_14C": [ + "46_DAP_14C" + ], + "Seed_52DAP_14C": [ + "52_DAP_14C" + ], + "Seed_58DAP_14C": [ + "58_DAP_14C" + ], + "Seed_65DAP_14C": [ + "65_DAP_14C" + ], + "Seed_ABS_14C": [ + "Abs_DAP_14C" + ], + "Seed_DS_14C": [ + "DS_DAP_14C" + ] + } + }, + "Seed_20c": { + "controls": [ + "Med_CTRL_20C" + ], + "treatments": { + "Seed_8DAP_20C": [ + "8_DAP_20C" + ], + "Seed_11DAP_20C": [ + "11_DAP_20C" + ], + "Seed_14DAP_20C": [ + "14_DAP_20C" + ], + "Seed_17DAP_20C": [ + "17_DAP_20C" + ], + "Seed_20DAP_20C": [ + "20_DAP_20C" + ], + "Seed_23DAP_20C": [ + "23_DAP_20C" + ], + "Seed_26DAP_20C": [ + "26_DAP_20C" + ], + "Seed_29DAP_20C": [ + "29_DAP_20C" + ], + "Seed_32DAP_20C": [ + "32_DAP_20C" + ], + "Seed_35DAP_20C": [ + "35_DAP_20C" + ], + "Seed_38DAP_20C": [ + "38_DAP_20C" + ], + "Seed_41DAP_20C": [ + "41_DAP_20C" + ], + "Seed_44DAP_20C": [ + "44_DAP_20C" + ], + "Seed_ABS_20C": [ + "Abs_DAP_20C" + ], + "Seed_DS_20C": [ + "DS_DAP_20C" + ] + } + }, + "Seed_26C": { + "controls": [ + "Med_CTRL_26C" + ], + "treatments": { + "Seed_7DAP_26C": [ + "7_DAP_26C" + ], + "Seed_9DAP_26C": [ + "9_DAP_26C" + ], + "Seed_11DAP_26C": [ + "11_DAP_26C" + ], + "Seed_14DAP_26C": [ + "14_DAP_26C" + ], + "Seed_17DAP_26C": [ + "17_DAP_26C" + ], + "Seed_20DAP_26C": [ + "20_DAP_26C" + ], + "Seed_ABS_26C": [ + "Abs_DAP_20C" + ], + "Seed_DS_26C": [ + "DS_DAP_20C" + ] + } + }, + "Greenhouse": { + "controls": [ + "Med_CTRL_GH" + ], + "treatments": { + "16DAP_Greenhouse": [ + "16_DAP_GH" + ], + "20DAP_Greenhouse": [ + "20_DAP_GH" + ], + "24DAP_Greenhouse": [ + "24_DAP_GH" + ], + "28DAP_Greenhouse": [ + "28_DAP_GH" + ], + "32DAP_Greenhouse": [ + "32_DAP_GH" + ], + "36DAP_Greenhouse": [ + "36_DAP_GH" + ], + "40DAP_Greenhouse": [ + "40_DAP_GH" + ], + "ABS_Greenhouse": [ + "Abs_DAP_GH" + ], + "DS_Greenhouse": [ + "DS_DAP_GH" + ] + } + }, + "Osmotic_Stress": { + "controls": [ + "Med_CTRL_OS" + ], + "treatments": { + "12DAP_Osmotic": [ + "12_DAP_OS" + ], + "15DAP_Osmotic": [ + "15_DAP_OS" + ], + "20DAP_Osmotic": [ + "20_DAP_OS" + ], + "25DAP_Osmotic": [ + "25_DAP_OS" + ], + "30DAP_Osmotic": [ + "30_DAP_OS" + ], + "ABS_Osmotic": [ + "Abs_DAP_OS" + ], + "DS_Osmotic": [ + "DS_DAP_OS" + ] + } + } + } + } + } + } + }, + "poplar": { + + "data": { + "species": "poplar", + "views": { + "Poplar": { + "database": "poplar", + "view_name": "Poplar", + "groups": { + "Poplar": { + "controls": [ + "POP_CTRL" + ], + "treatments": { + "Mature_Leaf": [ + "bot0894", + "bot0895", + "bot0896" + ], + "Young_Leaf": [ + "bot0882", + "bot0883", + "bot0884" + ], + "Root": [ + "bot0885", + "bot0886", + "bot0887" + ], + "Dark-grown_seedling,__etiolated": [ + "bot1125", + "bot1126" + ], + "Dark-grown_seedling,_etiolated,_exposed_to_light_for_3hr": [ + "bot1123", + "bot1124" + ], + "Continuous_light-_grown_seedling": [ + "bot1116", + "bot1117rh", + "bot1118" + ], + "female_catkins": [ + "bot0945", + "bot0946", + "bot0947" + ], + "male_catkins": [ + "bot0948", + "bot0949", + "bot0950" + ], + "xylem": [ + "bot1017", + "bot1018", + "bot1019rh" + ] + } + } + } + }, + "PoplarTreatment": { + "database": "poplar", + "view_name": "PoplarTreatment", + "groups": { + "DN34_Midday": { + "controls": [ + "GSM377381", + "GSM377382", + "GSM377383" + ], + "treatments": { + "DN34_Midday_Well_Watered": [ + "GSM377381", + "GSM377382", + "GSM377383" + ], + "DN34_Midday_Droughted": [ + "GSM377384", + "GSM377385", + "GSM377386" + ] + } + }, + "DN34_Late_Day": { + "controls": [ + "GSM377390", + "GSM377392", + "GSM377393" + ], + "treatments": { + "DN34_Late_Day_Well_Watered": [ + "GSM377390", + "GSM377392", + "GSM377393" + ], + "DN34_Late_Day_Droughted": [ + "GSM377394", + "GSM377395", + "GSM377391" + ] + } + }, + "DN34_Midnight": { + "controls": [ + "GSM377359", + "GSM377360", + "GSM377361" + ], + "treatments": { + "DN34_Midnight_Well_Watered": [ + "GSM377359", + "GSM377360", + "GSM377361" + ], + "DN34_Midnight_Droughted": [ + "GSM377362", + "GSM377363", + "GSM377364" + ] + } + }, + "DN34_Predawn": { + "controls": [ + "GSM377365", + "GSM377367", + "GSM377366" + ], + "treatments": { + "DN34_Predawn_Well_Watered": [ + "GSM377365", + "GSM377367", + "GSM377366" + ], + "DN34_Predawn_Droughted": [ + "GSM377378", + "GSM377380", + "GSM377379" + ] + } + }, + "NM6_Midday": { + "controls": [ + "GSM378180", + "GSM378181", + "GSM378182" + ], + "treatments": { + "NM6_Midday_Well_Watered": [ + "GSM378180", + "GSM378181", + "GSM378182" + ], + "NM6_Midday_Droughted": [ + "GSM378183", + "GSM378184", + "GSM378185" + ] + } + }, + "NM6_Late_Day": { + "controls": [ + "GSM378186", + "GSM378187", + "GSM378188" + ], + "treatments": { + "NM6_Late_Day_Well_Watered": [ + "GSM378186", + "GSM378187", + "GSM378188" + ], + "NM6_Late_Day_Droughted": [ + "GSM378189", + "GSM378190", + "GSM378191" + ] + } + }, + "NM6_Midnight": { + "controls": [ + "GSM377396", + "GSM377409", + "GSM380346" + ], + "treatments": { + "NM6_Midnight_Well_Watered": [ + "GSM377396", + "GSM377409", + "GSM380346" + ], + "NM6_Midnight_Droughted": [ + "GSM377408", + "GSM377397", + "GSM377410" + ] + } + }, + "NM6_Predawn": { + "controls": [ + "GSM377412", + "GSM377415", + "GSM377418" + ], + "treatments": { + "NM6_Predawn_Well_Watered": [ + "GSM377412", + "GSM377415", + "GSM377418" + ], + "NM6_Predawn_Droughted": [ + "GSM378177", + "GSM378178", + "GSM378179" + ] + } + } + } + } + } + } + }, + "potato": { + + "data": { + "species": "potato", + "views": { + "Potato_Developmental": { + "database": "potato_dev", + "view_name": "Potato_Developmental", + "groups": { + "Potato": { + "controls": [ + "POTATO_CTRL" + ], + "treatments": { + "BV_P_X_[Stamens]": [ + "BV_P_X" + ], + "STD_AE_[Mature_whole_fruit]": [ + "STD_AE" + ], + "BV_P_S_[Tubers_(Whole,_Sample_2)]": [ + "BV_P_S" + ], + "BV_P_R_[Tubers_(Whole,_Sample_1)]": [ + "BV_P_R" + ], + "S8_[Mature_Tuber]": [ + "S8" + ], + "STD_AF_[Immature_whole_fruit]": [ + "STD_AF" + ], + "BV_W_[Petals]": [ + "BV_W" + ], + "S9_[Root]": [ + "S9" + ], + "BV_Y_[Carpels]": [ + "BV_Y" + ], + "S14_[Whole_in_vitro_Plant]": [ + "S14" + ], + "S7_[Young_Tuber]": [ + "S7" + ], + "BV_T_[Whole_Mature_Flowers]": [ + "BV_T" + ], + "BV_N_[Roots_(in_vitro,_Media_B)]": [ + "BV_N" + ], + "BV_P_P_[Callus_(10_and_11_wks_old,_Leaves_and_Stems,_in_vitro,_Media_D)]": [ + "BV_P_P" + ], + "STD_AH_[Inside_of_fruit_(mesocarp_and_endocarp)]": [ + "STD_AH" + ], + "S6_[Stolon]": [ + "S6" + ], + "BV_Q_[Stolons_(below_ground)]": [ + "BV_Q" + ], + "BV_Q_[Stolons_(above_)]": [ + "BV_Q" + ], + "BV_P_V_[Sepals]": [ + "BV_P_V" + ], + "S10_[Stamen]": [ + "S10" + ], + "S13_[Tuber_Peel]": [ + "S13" + ], + "S4_[Shoot_Apex]": [ + "S4" + ], + "S1_[Flower]": [ + "S1" + ], + "S15_[Tuber_Sprout]": [ + "S15" + ], + "BV_L_[Leaves]": [ + "BV_L" + ], + "BV_U_[Petioles]": [ + "BV_U" + ], + "BV_O_[Shoots_(in_vitro,_Media_B)]": [ + "BV_O" + ], + "S2_[Leaf]": [ + "S2" + ], + "S3_[Petiole]": [ + "S3" + ], + "S5_[Stem]": [ + "S5" + ], + "S16_[Tuber_Cortex]": [ + "S16" + ], + "S12_[Tuber_Pith]": [ + "S12" + ] + } + } + } + }, + "Potato_Stress": { + "database": "potato_stress", + "view_name": "Potato_Stress", + "groups": { + "STD_AA": { + "controls": [ + "STD_AA" + ], + "treatments": { + "STD_AA_[Control_(Biotic_Stress)]": [ + "STD_AA" + ], + "STD_AB_[P._infestans_Infected_Leaves_(24hr/48hr/72hr)]": [ + "STD_AB" + ], + "STD_AD_[BTH_Treated_Leaves_(24hr/48hr/72hr)]": [ + "STD_AD" + ], + "STD_AC_[BABA_Treated_Leaves_(24hr/48hr/72hr)]": [ + "STD_AC" + ] + } + }, + "BV_Z": { + "controls": [ + "BV_Z" + ], + "treatments": { + "BV_Z_[Leaves_-_Wounding_Primary_Tissue]": [ + "BV_Z" + ] + } + }, + "PE_BV_P_M": { + "controls": [ + "PE_BV_P_M" + ], + "treatments": { + "PE_BV_P_M_[Leaves_-_Wounding_Secondary_Tissue_[paired_ends]]": [ + "PE_BV_P_M" + ] + } + }, + "BV_A": { + "controls": [ + "BV_A" + ], + "treatments": { + "BV_A_[Control_(Salt;_Mannitol,_Whole_Plant_in_vitro,_Media_B)]": [ + "BV_A" + ], + "BV_B_[Salt_-_150mM_NaCl,_24hr]": [ + "BV_B" + ], + "BV_P_C_[Mannitol_-_260uM,_24hr]": [ + "BV_P_C" + ] + } + }, + "BV_P_I": { + "controls": [ + "BV_P_I" + ], + "treatments": { + "BV_P_I_[Control_(35C_treatment,_Whole_Plant_in_vitro,_Media_A)]": [ + "BV_P_I" + ], + "BV_K_[Heat_-_24hr,_35C]": [ + "BV_K" + ] + } + }, + "BV_D": { + "controls": [ + "BV_D" + ], + "treatments": { + "BV_D_[Control_(IAA;_GA3;_BAP;_ABA,_Whole_Plant_in_vitro,_Media_C)]": [ + "BV_D" + ], + "BV_P_F_[IAA_-_24hr,_10uM]": [ + "BV_P_F" + ], + "BV_P_E_[ABA_-_24hr,_50uM]": [ + "BV_P_E" + ], + "BV_P_G_[GA3_-_24hr,_50uM]": [ + "BV_P_G" + ], + "BV_H_[BAP_-_24hr,_10uM]": [ + "BV_H" + ] + } + } + } + } + } + } + }, + "rice": { + + "data": { + "species": "rice", + "views": { + "rice_drought_heat_stress": { + "database": "rice_drought_heat_stress", + "view_name": "rice_drought_heat_stress", + "groups": { + "W30_s2_r1;W30_s2_r2;W30_s2_r3;W30_s2_r4": { + "controls": [ + "W30_s2_r1", + "W30_s2_r2", + "W30_s2_r3", + "W30_s2_r4" + ], + "treatments": { + "Well-watered,_30C,_S2_": [ + "W30_s2_r1", + "W30_s2_r2", + "W30_s2_r3", + "W30_s2_r4" + ], + "Growth_limiting_drought,_30C,_S2": [ + "D30_s2_r1", + "D30_s2_r2", + "D30_s2_r3", + "D30_s2_r4" + ], + "Well-watered,_30_min._at_40C": [ + "W40_s2_r1", + "W40_s2_r2", + "W40_s2_r3", + "W40_s2_r4" + ], + "Well-watered,_30_min._at_40C,_S2": [ + "W40_s2_r1", + "W40_s2_r2", + "W40_s2_r3", + "W40_s2_r4" + ], + "Growth_limiting_drought,_30_min._at_40C,_S2": [ + "D40_s2_r1", + "D40_s2_r2", + "D40_s2_r3", + "D40_s2_r4" + ] + } + }, + "W30_s3_r1;W30_s3_r2;W30_s3_r3;W30_s3_r4": { + "controls": [ + "W30_s3_r1", + "W30_s3_r2", + "W30_s3_r3", + "W30_s3_r4" + ], + "treatments": { + "Well-watered,_30C,_S3_": [ + "W30_s3_r1", + "W30_s3_r2", + "W30_s3_r3", + "W30_s3_r4" + ], + "Growth_limiting_drought,_30C,_S3": [ + "D30_s3_r1", + "D30_s3_r2", + "D30_s3_r3", + "D30_s3_r4" + ], + "Well-watered,_30_min._at_40C,_S3": [ + "W40_s3_r1", + "W40_s3_r2", + "W40_s3_r3", + "W40_s3_r4" + ], + "Growth_limiting_drought,_30_min._at_40C,_S3": [ + "D40_s3_r1", + "D40_s3_r2", + "D40_s3_r3", + "D40_s3_r4" + ] + } + }, + "W30_s4_r1;W30_s4_r2;W30_s4_r3;W30_s4_r4": { + "controls": [ + "W30_s4_r1", + "W30_s4_r2", + "W30_s4_r3", + "W30_s4_r4" + ], + "treatments": { + "Well-watered,_30C,_S4_": [ + "W30_s4_r1", + "W30_s4_r2", + "W30_s4_r3", + "W30_s4_r4" + ], + "Growth_limiting_drought,_30C,_S4": [ + "D30_s4_r1", + "D30_s4_r2", + "D30_s4_r3", + "D30_s4_r4" + ], + "Well-watered,_30_min._at_40C,_S4": [ + "W40_s4_r1", + "W40_s4_r2", + "W40_s4_r3", + "W40_s4_r4" + ], + "Growth_limiting_drought,_30_min._at_40C,_S4": [ + "D40_s4_r1", + "D40_s4_r2", + "D40_s4_r3", + "D40_s4_r4" + ] + } + }, + "W30_s5_r1;W30_s5_r2;W30_s5_r3;W30_s5_r4": { + "controls": [ + "W30_s5_r1", + "W30_s5_r2", + "W30_s5_r3", + "W30_s5_r4" + ], + "treatments": { + "Well-watered,_30C,_S5_": [ + "W30_s5_r1", + "W30_s5_r2", + "W30_s5_r3", + "W30_s5_r4" + ], + "Growth_limiting_drought,_30C,_S5": [ + "D30_s5_r1", + "D30_s5_r2", + "D30_s5_r3", + "D30_s5_r4" + ], + "Well-watered,_30_min._at_40C,_S5": [ + "W40_s5_r1", + "W40_s5_r2", + "W40_s5_r3", + "W40_s5_r4" + ], + "Growth_limiting_drought,_30_min._at_40C,_S5": [ + "D40_s5_r1", + "D40_s5_r2", + "D40_s5_r3", + "D40_s5_r4" + ] + } + }, + "W30_s6_r1;W30_s6_r2;W30_s6_r3": { + "controls": [ + "W30_s6_r1", + "W30_s6_r2", + "W30_s6_r3" + ], + "treatments": { + "Well-watered,_30C,_S6_": [ + "W30_s6_r1", + "W30_s6_r2", + "W30_s6_r3", + "W30_s6_r4" + ] + } + }, + "W30_s6_r1;W30_s6_r2;W30_s6_r3;W30_s6_r4": { + "controls": [ + "W30_s6_r1", + "W30_s6_r2", + "W30_s6_r3", + "W30_s6_r4" + ], + "treatments": { + "Growth_limiting_drought,_30C,_S6": [ + "D30_s6_r1", + "D30_s6_r2", + "D30_s6_r3", + "D30_s6_r4" + ], + "Well-watered,_30_min._at_40C,_S6": [ + "W40_s6_r1", + "W40_s6_r2", + "W40_s6_r3", + "W40_s6_r4" + ], + "Growth_limiting_drought,_30_min._at_40C,_S6": [ + "D40_s6_r1", + "D40_s6_r2", + "D40_s6_r3", + "D40_s6_r4" + ] + } + } + } + }, + "rice_leaf_gradient": { + "database": "rice_leaf_gradient", + "view_name": "rice_leaf_gradient", + "groups": { + "Rice": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "R1": [ + "R1" + ], + "R2": [ + "R2" + ], + "R3": [ + "R3" + ], + "R4": [ + "R4" + ], + "R5": [ + "R5" + ], + "R6": [ + "R6" + ], + "R7": [ + "R7" + ], + "R8": [ + "R8" + ], + "R9": [ + "R9" + ], + "R10": [ + "R10" + ], + "R11": [ + "R11" + ] + } + } + } + }, + "rice_maize_comparison": { + "database": "rice_maize_comparison", + "view_name": "rice_maize_comparison", + "groups": { + "Rice": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "R1": [ + "R1" + ], + "R2": [ + "R2" + ], + "R3": [ + "R3" + ], + "R4": [ + "R4" + ], + "R5": [ + "R5" + ], + "R6": [ + "R6" + ], + "R7": [ + "R7" + ], + "R8": [ + "R8" + ], + "R9": [ + "R9" + ], + "R10": [ + "R10" + ], + "R11": [ + "R11" + ] + } + }, + "Maize_Leaf_Gradient": { + "controls": [ + "MAIZE_CTRL" + ], + "treatments": { + "M1": [ + "M1" + ], + "M2": [ + "M2" + ], + "M3": [ + "M3" + ], + "M4": [ + "M4" + ], + "M5": [ + "M5" + ], + "M6": [ + "M6" + ], + "M7": [ + "M7" + ], + "M8": [ + "M8" + ], + "M9": [ + "M9" + ], + "M10": [ + "M10" + ], + "M11": [ + "M11" + ], + "M12": [ + "M12" + ], + "M13": [ + "M13" + ], + "M14": [ + "M14" + ], + "M15": [ + "M15" + ] + } + } + } + }, + "rice_mas": { + "database": "rice_mas", + "view_name": "rice_mas", + "groups": { + "Seedling_Root": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Seedling_Root": [ + "Seedling_Root_Rep1", + "Seedling_Root_Rep2", + "Seedling_Root_Rep3" + ] + } + }, + "Leaf": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Mature_Leaf": [ + "MatureLeaf_Rep1", + "MatureLeaf_Rep2", + "MatureLeaf_Rep3" + ], + "Young_Leaf": [ + "YoungLeaf_Rep1", + "YoungLeaf_Rep2", + "YoungLeaf_Rep3" + ] + } + }, + "SAM": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "SAM": [ + "SAM_Rep1", + "SAM_Rep2", + "SAM_Rep3" + ] + } + }, + "Inflorescence": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Young_Inflorescence": [ + "YoungInflorescence_Rep1", + "YoungInflorescence_Rep2", + "YoungInflorescence_Rep3" + ], + "Inflorescence_P2": [ + "InflorescenceP2_Rep1", + "InflorescenceP2_Rep2", + "InflorescenceP2_Rep3" + ], + "Inflorescence_P3": [ + "InflorescenceP3_Rep1", + "InflorescenceP3_Rep2", + "InflorescenceP3_Rep3" + ], + "Inflorescence_P4": [ + "InflorescenceP4_Rep1", + "InflorescenceP4_Rep2", + "InflorescenceP4_Rep3" + ], + "Inflorescence_P5": [ + "InflorescenceP5_Rep1", + "InflorescenceP5_Rep2", + "InflorescenceP5_Rep3" + ], + "Inflorescence_P6": [ + "InflorescenceP6_Rep1", + "InflorescenceP6_Rep2", + "InflorescenceP6_Rep3" + ] + } + }, + "Seed": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Seed_S1": [ + "Seed_S1_Rep1", + "Seed_S1_Rep2", + "Seed_S1_Rep3" + ], + "Seed_S2": [ + "Seed_S2_Rep1", + "Seed_S2_Rep2", + "Seed_S2_Rep3" + ], + "Seed_S3": [ + "Seed_S3_Rep1", + "Seed_S3_Rep2", + "Seed_S3_Rep3" + ], + "Seed_S4": [ + "Seed_S4_Rep1", + "Seed_S4_Rep2", + "Seed_S4_Rep3" + ], + "Seed_S5": [ + "Seed_S5_Rep1", + "Seed_S5_Rep2", + "Seed_S5_Rep3" + ] + } + } + } + }, + "rice_rma": { + "database": "rice_rma", + "view_name": "rice_rma", + "groups": { + "Seedling_Root": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Seedling_Root": [ + "Seedling_Root_Rep1", + "Seedling_Root_Rep2", + "Seedling_Root_Rep3" + ] + } + }, + "Leaf": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Mature_Leaf": [ + "MatureLeaf_Rep1", + "MatureLeaf_Rep2", + "MatureLeaf_Rep3" + ], + "Young_Leaf": [ + "YoungLeaf_Rep1", + "YoungLeaf_Rep2", + "YoungLeaf_Rep3" + ] + } + }, + "SAM": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "SAM": [ + "SAM_Rep1", + "SAM_Rep2", + "SAM_Rep3" + ] + } + }, + "Inflorescence": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Young_Inflorescence": [ + "YoungInflorescence_Rep1", + "YoungInflorescence_Rep2", + "YoungInflorescence_Rep3" + ], + "Inflorescence_P2": [ + "InflorescenceP2_Rep1", + "InflorescenceP2_Rep2", + "InflorescenceP2_Rep3" + ], + "Inflorescence_P3": [ + "InflorescenceP3_Rep1", + "InflorescenceP3_Rep2", + "InflorescenceP3_Rep3" + ], + "Inflorescence_P4": [ + "InflorescenceP4_Rep1", + "InflorescenceP4_Rep2", + "InflorescenceP4_Rep3" + ], + "Inflorescence_P5": [ + "InflorescenceP5_Rep1", + "InflorescenceP5_Rep2", + "InflorescenceP5_Rep3" + ], + "Inflorescence_P6": [ + "InflorescenceP6_Rep1", + "InflorescenceP6_Rep2", + "InflorescenceP6_Rep3" + ] + } + }, + "Seed": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Seed_S1": [ + "Seed_S1_Rep1", + "Seed_S1_Rep2", + "Seed_S1_Rep3" + ], + "Seed_S2": [ + "Seed_S2_Rep1", + "Seed_S2_Rep2", + "Seed_S2_Rep3" + ], + "Seed_S3": [ + "Seed_S3_Rep1", + "Seed_S3_Rep2", + "Seed_S3_Rep3" + ], + "Seed_S4": [ + "Seed_S4_Rep1", + "Seed_S4_Rep2", + "Seed_S4_Rep3" + ], + "Seed_S5": [ + "Seed_S5_Rep1", + "Seed_S5_Rep2", + "Seed_S5_Rep3" + ] + } + } + } + }, + "riceanoxia_mas": { + "database": "rice_mas", + "view_name": "riceanoxia_mas", + "groups": { + "Aerobic_Coleoptile": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Aerobic_coleoptile": [ + "Aerobic_coleoptile_Rep1", + "Aerobic_coleoptile_Rep2" + ], + "Anoxic_coleoptile": [ + "Anoxic_coleoptile_Rep1", + "Anoxic_coleoptile_Rep2" + ] + } + } + } + }, + "riceanoxia_rma": { + "database": "rice_rma", + "view_name": "riceanoxia_rma", + "groups": { + "Coleoptile": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Aerobic_coleoptile": [ + "Aerobic_coleoptile_Rep1", + "Aerobic_coleoptile_Rep2" + ], + "Anoxic_coleptile": [ + "Anoxic_coleoptile_Rep1", + "Anoxic_coleoptile_Rep2" + ] + } + } + } + }, + "ricestigma_mas": { + "database": "rice_mas", + "view_name": "ricestigma_mas", + "groups": { + "Stigma": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Stigma": [ + "Stigma_Rep1", + "Stigma_Rep2", + "Stigma_Rep3" + ] + } + }, + "Ovary": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Ovary": [ + "Ovary_Rep1", + "Ovary_Rep2", + "Ovary_Rep3" + ] + } + }, + "SuspensionCell": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Suspension_Cell": [ + "SuspensionCell_Rep1" + ] + } + }, + "Shoot": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Shoot": [ + "Shoot_Rep1" + ] + } + }, + "Root": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Root": [ + "Root_Rep1" + ] + } + }, + "Anther": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Anther": [ + "Anther_Rep1" + ] + } + }, + "Embryo": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Embryo": [ + "Embryo_Rep1" + ] + } + }, + "Endosperm": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Endosperm": [ + "Endosperm_Rep1" + ] + } + }, + "5d-seed": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "5d-seed": [ + "5d-seed_Rep1" + ] + } + } + } + }, + "ricestigma_rma": { + "database": "rice_rma", + "view_name": "ricestigma_rma", + "groups": { + "Stigma": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Stigma": [ + "Stigma_Rep1", + "Stigma_Rep2", + "Stigma_Rep3" + ] + } + }, + "Ovary": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Ovary": [ + "Ovary_Rep1", + "Ovary_Rep2", + "Ovary_Rep3" + ] + } + }, + "SuspensionCell": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Suspension_Cell": [ + "SuspensionCell_Rep1" + ] + } + }, + "Shoot": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Shoot": [ + "Shoot_Rep1" + ] + } + }, + "Root": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Root": [ + "Root_Rep1" + ] + } + }, + "Anther": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Anther": [ + "Anther_Rep1" + ] + } + }, + "Embryo": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Embryo": [ + "Embryo_Rep1" + ] + } + }, + "Endosperm": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "Endosperm": [ + "Endosperm_Rep1" + ] + } + }, + "5d-seed": { + "controls": [ + "RICE_CTRL" + ], + "treatments": { + "5d-seed": [ + "5d-seed_Rep1" + ] + } + } + } + }, + "ricestress_mas": { + "database": "rice_mas", + "view_name": "ricestress_mas", + "groups": { + "Control_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Control_Shoot": [ + "RICE_CTRL_STRESS" + ], + "Control_Root": [ + "RICE_CTRL_STRESS" + ] + } + }, + "Drought_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Drought_Shoot": [ + "Drought_stress_rep1", + "Drought_stress_rep2", + "Drought_stress_rep3" + ], + "Drought_Root": [ + "Drought_stress_rep1", + "Drought_stress_rep2", + "Drought_stress_rep3" + ] + } + }, + "Salt_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Salt_Shoot": [ + "Salt_stress_rep1", + "Salt_stress_rep2", + "Salt_stress_rep3" + ], + "Salt_Root": [ + "Salt_stress_rep1", + "Salt_stress_rep2", + "Salt_stress_rep3" + ] + } + }, + "Cold_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Cold_Shoot": [ + "Cold_stress_rep1", + "Cold_stress_rep2", + "Cold_stress_rep3" + ], + "Cold_Root": [ + "Cold_stress_rep1", + "Cold_stress_rep2", + "Cold_stress_rep3" + ] + } + } + } + }, + "ricestress_rma": { + "database": "rice_rma", + "view_name": "ricestress_rma", + "groups": { + "Control_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Control_Shoot": [ + "RICE_CTRL_STRESS" + ], + "Control_Root": [ + "RICE_CTRL_STRESS" + ] + } + }, + "Drought_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Drought_Shoot": [ + "Drought_stress_rep1", + "Drought_stress_rep2", + "Drought_stress_rep3" + ], + "Drought_Root": [ + "Drought_stress_rep1", + "Drought_stress_rep2", + "Drought_stress_rep3" + ] + } + }, + "Salt_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Salt_Shoot": [ + "Salt_stress_rep1", + "Salt_stress_rep2", + "Salt_stress_rep3" + ], + "Salt_Root": [ + "Salt_stress_rep1", + "Salt_stress_rep2", + "Salt_stress_rep3" + ] + } + }, + "Cold_stress_Seedling": { + "controls": [ + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS", + "RICE_CTRL_STRESS" + ], + "treatments": { + "Cold_Shoot": [ + "Cold_stress_rep1", + "Cold_stress_rep2", + "Cold_stress_rep3" + ], + "Cold_Root": [ + "Cold_stress_rep1", + "Cold_stress_rep2", + "Cold_stress_rep3" + ] + } + } + } + } + } + } + }, + "soybean": { + + "data": { + "species": "soybean", + "views": { + "soybean": { + "database": "soybean", + "view_name": "soybean", + "groups": { + "Root_Hair_12HAI": { + "controls": [ + "Roothair_12HAImock" + ], + "treatments": { + "Root_Hair_12HAI": [ + "Roothair_12HAI" + ], + "Roothair_12HAImock": [ + "Roothair_12HAImock" + ] + } + }, + "Root_Hair_24HAI": { + "controls": [ + "Roothair_24HAImock" + ], + "treatments": { + "Root_Hair_24_HAI": [ + "Roothair_24HAI" + ], + "Roothair_24HAImock": [ + "Roothair_24HAImock" + ] + } + }, + "Root_Hair_48HAI": { + "controls": [ + "Roothair_48HAImock" + ], + "treatments": { + "Root_Hair_48_HAI": [ + "Roothair_48HAI" + ], + "Roothair_48HAImock": [ + "Roothair_48HAImock" + ], + "Root_Hair_48_HAI_Stripped": [ + "Root_stripped" + ] + } + }, + "StaceyTissues": { + "controls": [ + "SOYBEAN_CTRL", + "SOYBEAN_CTRL" + ], + "treatments": { + "SAM": [ + "SAM" + ], + "Flower": [ + "Flower" + ], + "Green_Pods": [ + "Green_Pods" + ], + "Leaves": [ + "Leaves" + ], + "Nodule": [ + "Nodule" + ], + "Root": [ + "Root" + ], + "Root_tip": [ + "Root_tip" + ] + } + } + } + }, + "soybean_embryonic_development": { + "database": "soybean_embryonic_development", + "view_name": "soybean_embryonic_development", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Embryo_Axis_Epidermis": [ + "embryo_axis_epidermis" + ], + "Embryo_Axis_Parenchyma": [ + "embryo_axis_parenchyma" + ], + "Embryo_Axis_Plumule": [ + "embryo_axis_plumule" + ], + "Embryo_Axis_Root_Tip": [ + "embryo_root_tip" + ], + "Embryo_Axis_SAM": [ + "embryo_axis_SAM" + ], + "Embryo_Axis_Stele": [ + "embryo_axis_stele" + ], + "Embryo_Axis_Vasculature": [ + "embryo_axis_vasculature" + ], + "Embryo_Cotyledon_Abaxial_Parenchyma": [ + "embryo_cotyledon_abaxial_parenchyma" + ], + "Embryo_Cotyledon_Adaxial_Epidermis": [ + "embryo_cotyledon_adaxial_epidermis" + ], + "Seed_Cotyledon_Vasculature": [ + "seed_cotyledon_vasculature" + ], + "Embryo_Cotyledon_Adaxial_Parenchyma": [ + "embryo_cotyledon_adaxial_parenchyma" + ], + "Seed_Coat_Hilum": [ + "seed_coat_hilum" + ], + "Seed_Coat_Hourglass": [ + "seed_coat_hourglass" + ], + "Seed_Coat_Palisade": [ + "seed_coat_palisade" + ], + "Seed_Coat_Parenchyma": [ + "seed_coat_parenchyma" + ], + "Seed_Cotyledon_Abaxial_Epidermis": [ + "seed_cotyledon_abaxial_epidermis" + ], + "Seed_Endosperm": [ + "seed_endosperm" + ] + } + } + } + }, + "soybean_heart_cotyledon_globular": { + "database": "soybean_heart_cotyledon_globular", + "view_name": "soybean_heart_cotyledon_globular", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Cotyledon_Embryo_Cotyledon": [ + "cotyledon_embryocotyledon" + ], + "Cotyledon_Embryo_Proper": [ + "cotyledon_embryo" + ], + "Cotyledon_Embryo_Axis": [ + "cotyledon_embryoaxis" + ], + "Cotyledon_Endosperm": [ + "cotyledon_endosperm" + ], + "Cotyledon_Seed_Coat_Endothelium": [ + "cotyledon_seedcoatendothelium" + ], + "Cotyledon_Seed_Coat_Epidermis": [ + "cotyledon_seedcoatepidermis" + ], + "Cotyledon_Seed_Coat_Hilum": [ + "cotyledon_seedcoathilum" + ], + "Cotyledon_Seed_Coat_Inner_Integument": [ + "cotyledon_seedcoatinnerintegument" + ], + "Cotyledon_Seed_Coat_Outer_Integument": [ + "cotyledon_seedcoatouterintegument" + ], + "Cotyledon_Suspensor": [ + "cotyledon_suspensor" + ], + "Globular_Embryo": [ + "globular_embryo" + ], + "Globular_Endosperm": [ + "globular_endosperm" + ], + "Globular_Seed_Coat_Endothelium": [ + "globular_seedcoatendothelium" + ], + "Globular_Seed_Coat_Epidermis": [ + "globular_seedcoatepidermis" + ], + "Globular_Seed_Coat_Hilum": [ + "globular_seedcoathilum" + ], + "Globular_Seed_Coat_Inner_Integument": [ + "globular_seedcoatinnerintegument" + ], + "Globular_Seed_Coat_Outer_Integument": [ + "globular_seedcoatouterintegument" + ], + "Globular_Suspensor": [ + "globular_suspensor" + ], + "Heart_Embryo": [ + "heart_embryo" + ], + "Heart_Endosperm": [ + "heart_endosperm" + ], + "Heart_Seed_Coat_Endothelium": [ + "heart_seedcoatendothelium" + ], + "Heart_Seed_Coat_Epidermis": [ + "heart_seedcoatepidermis" + ], + "Heart_Seed_Coat_Hilum": [ + "heart_seedcoathilum" + ], + "Heart_Seed_Coat_Inner_Integument": [ + "heart_seedcoatinnerintegument" + ], + "Heart_Seed_Coat_Outer_Integument": [ + "heart_seedcoatouterintegument" + ], + "Heart_Suspensor": [ + "heart_suspensor" + ] + } + } + } + }, + "soybean_senescence": { + "database": "soybean_senescence", + "view_name": "soybean_senescence", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Cotyledon_Stage_1": [ + "C_I-1", + "C_I-2", + "C_I-3" + ], + "Cotyledon_Stage_2": [ + "C_II-1", + "C_II-2", + "C_II-3" + ], + "Cotyledon_Stage_3": [ + "C_III-1", + "C_III-2", + "C_III-3" + ], + "Leaf_Stage_1": [ + "L_I-1", + "L_I-2", + "L_I-3" + ], + "Leaf_Stage_2": [ + "L_II-1", + "L_II-2", + "L_II-3" + ], + "Leaf_Stage_3": [ + "L_III-1", + "L_III-2", + "L_III-3" + ], + "Leaf_Stage_4": [ + "L_IV-1", + "L_IV-2", + "L_IV-3" + ], + "Leaf_Stage_5": [ + "L_V-1", + "L_V-2", + "L_V-3" + ] + } + } + } + }, + "soybean_severin": { + "database": "soybean_severin", + "view_name": "soybean_severin", + "groups": { + "Soybean_Severin": { + "controls": [ + "SOYBEAN_CTRL" + ], + "treatments": { + "Young_Leaf": [ + "young_leaf" + ], + "Flower": [ + "flower" + ], + "One_CM_Pod": [ + "one_cm_pod" + ], + "Pod_Shell_(10-13_DAF)": [ + "pod_shell_10DAF" + ], + "Pod_Shell_(14_17_DAF)": [ + "pod_shell_14DAF" + ], + "Nodule": [ + "nodule" + ], + "Root": [ + "root" + ], + "Seed_10_13_DAF": [ + "seed_10DAF" + ], + "Seed_14_17_DAF": [ + "seed_14DAF" + ], + "Seed_21_DAF": [ + "seed_21DAF" + ], + "Seed_25_DAF": [ + "seed_25DAF" + ], + "Seed_28_DAF": [ + "seed_28DAF" + ], + "Seed_35_DAF": [ + "seed_35DAF" + ], + "Seed_42_DAF": [ + "seed_42DAF" + ] + } + } + } + } + } + } + }, + "strawberry": { + + "data": { + "species": "strawberry", + "views": { + "Developmental_Map_Strawberry_Flower_and_Fruit": { + "database": "strawberry", + "view_name": "Developmental_Map_Strawberry_Flower_and_Fruit", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Anther,_stage_10": [ + "Anther_10_A", + "Anther_10_B" + ], + "Anther,_stage_11": [ + "Anther_11_A", + "Anther_11_B" + ], + "Anther,_stage_12": [ + "Anther_12_A", + "Anther_12_B" + ], + "Anther,_stages_7-8": [ + "Anther_7-8_A", + "Anther_7-8_B" + ], + "Anther,_stage_9": [ + "Anther_9_A", + "Anther_9_B" + ], + "Carpel,_stage_10": [ + "Carpel_10_A", + "Carpel_10_B" + ], + "Carpel,_stage_12": [ + "Carpel_12_A", + "Carpel_12_B" + ], + "Carpel,_stages_7-8": [ + "Carpel_7-8_A", + "Carpel_7-8_B" + ], + "Carpel,_stage_9": [ + "Carpel_9_A", + "Carpel_9_B" + ], + "Cortex,_stage_1": [ + "Cortex_1_A", + "Cortex_1_B" + ], + "Cortex,_stage_2": [ + "Cortex_2_A", + "Cortex_2_B" + ], + "Cortex,_stage_3": [ + "Cortex_3_A", + "Cortex_3_B" + ], + "Cortex,_stage_4": [ + "Cortex_4_A", + "Cortex_4_B" + ], + "Cortex,_stage_5": [ + "Cortex_5_A", + "Cortex_5_B" + ], + "Embryo,_stage_3": [ + "Embryo_3_A", + "Embryo_3_B" + ], + "Embryo,_stage_4": [ + "Embryo_4_A", + "Embryo_4_B" + ], + "Embryo,_stage_5": [ + "Embryo_5_A", + "Embryo_5_B" + ], + "Ghost,_stage_3": [ + "Ghost_3_A", + "Ghost_3_B" + ], + "Ghost,_stage_4": [ + "Ghost_4_A", + "Ghost_4_B" + ], + "Ghost,_stage_5": [ + "Ghost_5_A", + "Ghost_5_B" + ], + "Leaf": [ + "Leaf_A", + "Leaf_B" + ], + "Ovule,_stage_1": [ + "Ovule_1_A", + "Ovule_1_B" + ], + "Pith,_stage_1": [ + "Pith_1_A", + "Pith_1_B" + ], + "Pith,_stage_2": [ + "Pith_2_A", + "Pith_2_B" + ], + "Pith,_stage_3": [ + "Pith_3_A", + "Pith_3_B" + ], + "Pith,_stage_4": [ + "Pith_4_A", + "Pith_4_B" + ], + "Pith,_stage_5": [ + "Pith_5_A", + "Pith_5_B" + ], + "Pollen": [ + "Pollen_A", + "Pollen_B" + ], + "Seed,_stage_2": [ + "Seed_2_A", + "Seed_2_B" + ], + "Seedling": [ + "Seedling_A", + "Seedling_B" + ], + "Style,_stage_1": [ + "Style_1_A", + "Style_1_B" + ], + "Style,_stage_2": [ + "Style_2_A", + "Style_2_B" + ], + "Wall,_stage_1": [ + "Wall_1_A", + "Wall_1_B" + ], + "Wall,_stage_2": [ + "Wall_2_A", + "Wall_2_B" + ], + "Wall,_stage_3": [ + "Wall_3_A", + "Wall_3_B" + ], + "Wall,_stage_4": [ + "Wall_4_A", + "Wall_4_B" + ], + "Wall,_stage_5": [ + "Wall_5_A", + "Wall_5_B" + ], + "Anther,_stages_6-7": [ + "Anther_6-7_A", + "Anther_6-7_B" + ], + "Flower,_stages_1-4": [ + "Flower_1-4_A", + "Flower_1-4_B" + ], + "Microspore,_stage_10": [ + "Microspore_10_A", + "Microspore_10_B" + ], + "Perianth,_stages_5-6": [ + "Perianth_5-6_A", + "Perianth_5-6_B" + ], + "Receptacle,_stages_6-7": [ + "Receptacle_6-7_A", + "Receptacle_6-7_B" + ] + } + } + } + }, + "Strawberry_Green_vs_White_Stage": { + "database": "strawberry", + "view_name": "Strawberry_Green_vs_White_Stage", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Ruegen,_15d": [ + "RG_15d_A", + "RG_15d_B" + ], + "Ruegen,_Turning": [ + "RG_22d_A", + "RG_22d_B" + ], + "Yellow_Wonder,_15d": [ + "YW_15d_A", + "YW_15d_B" + ], + "Yellow_Wonder,_Turning": [ + "YW_22d_A", + "YW_22d_B" + ] + } + } + } + } + } + } + }, + "tomato": { + + "data": { + "species": "tomato", + "views": { + "ILs_Leaf_Chitwood_et_al": { + "database": "tomato_ils", + "view_name": "ILs_Leaf_Chitwood_et_al", + "groups": { + "CTRL_MED": { + "controls": [ + "CTRL_MED" + ], + "treatments": { + "IL1.1": [ + "IL1.1" + ], + "IL1.1.2": [ + "IL1.1.2" + ], + "IL1.1.3": [ + "IL1.1.3" + ], + "IL1.2": [ + "IL1.2" + ], + "IL1.3": [ + "IL1.3" + ], + "IL1.4": [ + "IL1.4" + ], + "IL1.4.18": [ + "IL1.4.18" + ], + "IL2.1": [ + "IL2.1" + ], + "IL2.1.1": [ + "IL2.1.1" + ], + "IL2.2": [ + "IL2.2" + ], + "IL2.3": [ + "IL2.3" + ], + "IL2.4": [ + "IL2.4" + ], + "IL2.5": [ + "IL2.5" + ], + "IL2.6": [ + "IL2.6" + ], + "IL2.6.5": [ + "IL2.6.5" + ], + "IL3.1": [ + "IL3.1" + ], + "IL3.2": [ + "IL3.2" + ], + "IL3.3": [ + "IL3.3" + ], + "IL3.4": [ + "IL3.4" + ], + "IL3.5": [ + "IL3.5" + ], + "IL4.1": [ + "IL4.1" + ], + "IL4.1.1": [ + "IL4.1.1" + ], + "IL4.2": [ + "IL4.2" + ], + "IL4.3": [ + "IL4.3" + ], + "IL4.3.2": [ + "IL4.3.2" + ], + "IL4.4": [ + "IL4.4" + ], + "IL5.1": [ + "IL5.1" + ], + "IL5.2": [ + "IL5.2" + ], + "IL5.3": [ + "IL5.3" + ], + "IL5.4": [ + "IL5.4" + ], + "IL5.5": [ + "IL5.5" + ], + "IL6.1": [ + "IL6.1" + ], + "IL6.2": [ + "IL6.2" + ], + "IL6.2.2": [ + "IL6.2.2" + ], + "IL6.3": [ + "IL6.3" + ], + "IL6.4": [ + "IL6.4" + ], + "IL7.1": [ + "IL7.1" + ], + "IL7.2": [ + "IL7.2" + ], + "IL7.3": [ + "IL7.3" + ], + "IL7.4.1": [ + "IL7.4.1" + ], + "IL7.5": [ + "IL7.5" + ], + "IL7.5.5": [ + "IL7.5.5" + ], + "IL8.1": [ + "IL8.1" + ], + "IL8.1.1": [ + "IL8.1.1" + ], + "IL8.1.5": [ + "IL8.1.5" + ], + "IL8.2": [ + "IL8.2" + ], + "IL8.2.1": [ + "IL8.2.1" + ], + "IL8.3": [ + "IL8.3" + ], + "IL8.3.1": [ + "IL8.3.1" + ], + "IL9.1": [ + "IL9.1" + ], + "IL9.1.2": [ + "IL9.1.2" + ], + "IL9.1.3": [ + "IL9.1.3" + ], + "IL9.2": [ + "IL9.2" + ], + "IL9.2.5": [ + "IL9.2.5" + ], + "IL9.2.6": [ + "IL9.2.6" + ], + "IL9.3": [ + "IL9.3" + ], + "IL9.3.1": [ + "IL9.3.1" + ], + "IL9.3.2": [ + "IL9.3.2" + ], + "IL10.1": [ + "IL10.1" + ], + "IL10.1.1": [ + "IL10.1.1" + ], + "IL10.2": [ + "IL10.2" + ], + "IL10.2.2": [ + "IL10.2.2" + ], + "IL10.3": [ + "IL10.3" + ], + "IL11.1": [ + "IL11.1" + ], + "IL11.2": [ + "IL11.2" + ], + "IL11.3": [ + "IL11.3" + ], + "IL11.4": [ + "IL11.4" + ], + "IL11.4.1": [ + "IL11.4.1" + ], + "IL12.1": [ + "IL12.1" + ], + "IL12.1.1": [ + "IL12.1.1" + ], + "IL12.2": [ + "IL12.2" + ], + "IL12.3": [ + "IL12.3" + ], + "IL12.3.1": [ + "IL12.3.1" + ], + "IL12.4": [ + "IL12.4" + ], + "M82": [ + "SLY" + ], + "SPE": [ + "SPE" + ] + } + } + } + }, + "ILs_Root_Tip_Brady_Lab": { + "database": "tomato_ils2", + "view_name": "ILs_Root_Tip_Brady_Lab", + "groups": { + "CTRL_MED": { + "controls": [ + "CTRL_MED" + ], + "treatments": { + "IL1-1-2": [ + "IL1-1-2" + ], + "IL1-1-3": [ + "IL1-1-3" + ], + "IL1-1-4": [ + "IL1-1-4" + ], + "IL1-2": [ + "IL1-2" + ], + "IL1-3": [ + "IL1-3" + ], + "IL1-4": [ + "IL1-4" + ], + "IL1-4-18": [ + "IL1-4-18" + ], + "IL2-1": [ + "IL2-1" + ], + "IL2-1-1": [ + "IL2-1-1" + ], + "IL2-2": [ + "IL2-2" + ], + "IL2-3": [ + "IL2-3" + ], + "IL2-4": [ + "IL2-4" + ], + "IL2-5": [ + "IL2-5" + ], + "IL2-6": [ + "IL2-6" + ], + "IL2-6-5": [ + "IL2-6-5" + ], + "IL3-1": [ + "IL3-1" + ], + "IL3-2": [ + "IL3-2" + ], + "IL3-4": [ + "IL3-4" + ], + "IL3-5": [ + "IL3-5" + ], + "IL4-1": [ + "IL4-1" + ], + "IL4-1-1": [ + "IL4-1-1" + ], + "IL4-2": [ + "IL4-2" + ], + "IL4-3": [ + "IL4-3" + ], + "IL4-3-2": [ + "IL4-3-2" + ], + "IL4-4": [ + "IL4-4" + ], + "IL5-1": [ + "IL5-1" + ], + "IL5-2": [ + "IL5-2" + ], + "IL5-3": [ + "IL5-3" + ], + "IL5-4": [ + "IL5-4" + ], + "IL5-5": [ + "IL5-5" + ], + "IL6-1": [ + "IL6-1" + ], + "IL6-2": [ + "IL6-2" + ], + "IL6-3": [ + "IL6-3" + ], + "IL6-4": [ + "IL6-4" + ], + "IL7-1": [ + "IL7-1" + ], + "IL7-2": [ + "IL7-2" + ], + "IL7-3": [ + "IL7-3" + ], + "IL7-4": [ + "IL7-4" + ], + "IL7-4-1": [ + "IL7-4-1" + ], + "IL7-5": [ + "IL7-5" + ], + "IL7-5-1": [ + "IL7-5-1" + ], + "IL7-5-5": [ + "IL7-5-5" + ], + "IL7-5-P5": [ + "IL7-5-P5" + ], + "IL7-5-P75": [ + "IL7-5-P75" + ], + "IL8-1": [ + "IL8-1" + ], + "IL8-1-1": [ + "IL8-1-1" + ], + "IL8-1-5": [ + "IL8-1-5" + ], + "IL8-2": [ + "IL8-2" + ], + "IL8-2-1": [ + "IL8-2-1" + ], + "IL8-3": [ + "IL8-3" + ], + "IL8-3-1": [ + "IL8-3-1" + ], + "IL9-1": [ + "IL9-1" + ], + "IL9-1-2": [ + "IL9-1-2" + ], + "IL9-1-3": [ + "IL9-1-3" + ], + "IL9-2": [ + "IL9-2" + ], + "IL9-2-5": [ + "IL9-2-5" + ], + "IL9-2-6": [ + "IL9-2-6" + ], + "IL9-3": [ + "IL9-3" + ], + "IL9-3-1": [ + "IL9-3-1" + ], + "IL9-3-2": [ + "IL9-3-2" + ], + "IL10-1": [ + "IL10-1" + ], + "IL10-1-1": [ + "IL10-1-1" + ], + "IL10-2": [ + "IL10-2" + ], + "IL10-2-2": [ + "IL10-2-2" + ], + "IL10-3": [ + "IL10-3" + ], + "IL11-1": [ + "IL11-1" + ], + "IL11-2": [ + "IL11-2" + ], + "IL11-3": [ + "IL11-3" + ], + "IL11-4": [ + "IL11-4" + ], + "IL11-4-1": [ + "IL11-4-1" + ], + "IL12-1": [ + "IL12-1" + ], + "IL12-1-1": [ + "IL12-1-1" + ], + "IL12-2": [ + "IL12-2" + ], + "IL12-3": [ + "IL12-3" + ], + "IL12-3-1": [ + "IL12-3-1" + ], + "IL12-4": [ + "IL12-4" + ], + "IL12-4-1": [ + "IL12-4-1" + ], + "M82": [ + "M82" + ], + "PENN": [ + "PENN" + ] + } + } + } + }, + "M82_S_pennellii_Atlases_Koenig_et_al": { + "database": "tomato_s_pennellii", + "view_name": "M82_S_pennellii_Atlases_Koenig_et_al", + "groups": { + "CTRL_MED": { + "controls": [ + "CTRL_MED" + ], + "treatments": { + "M82.floral": [ + "M82.floral" + ], + "M82.stem": [ + "M82.stem" + ], + "M82.leaf": [ + "M82.leaf" + ], + "M82.veg": [ + "M82.veg" + ], + "M82.sdling": [ + "M82.sdling" + ], + "M82.root": [ + "M82.root" + ], + "M82.MatureFruit": [ + "M82.MatureFruit" + ], + "M82.DevelopingFruit": [ + "M82.DevelopingFruit" + ], + "penn.floral": [ + "penn.floral" + ], + "penn.stem": [ + "penn.stem" + ], + "penn.leaf": [ + "penn.leaf" + ], + "penn.veg": [ + "penn.veg" + ], + "penn.sdling": [ + "penn.sdling" + ], + "penn.root": [ + "penn.root" + ], + "penn.MatureFruit": [ + "penn.MatureFruit" + ], + "penn.DevelopingFruit": [ + "penn.DevelopingFruit" + ] + } + } + } + }, + "Rose_Lab_Atlas": { + "database": "tomato", + "view_name": "Rose_Lab_Atlas", + "groups": { + "454": { + "controls": [ + "TOMATO_CTRL_454" + ], + "treatments": { + "epidermis": [ + "epidermis" + ], + "collenchyma": [ + "collenchyma" + ], + "vascular": [ + "vascular" + ], + "parenchyma": [ + "parenchyma" + ], + "endodermis": [ + "endodermis" + ] + } + }, + "Illumina": { + "controls": [ + "TOMATO_CTRL" + ], + "treatments": { + "Unopened_Flower_Bud": [ + "Heinz_bud" + ], + "Fully_Opened_Flower": [ + "Heinz_flower" + ], + "Leaves": [ + "Heinz_leaf" + ], + "Root": [ + "Heinz_root" + ], + "1cm_Fruit": [ + "Heinz_1cm_fruit" + ], + "2cm_Fruit": [ + "Heinz_2cm_fruit" + ], + "3cm_Fruit": [ + "Heinz_3cm_fruit" + ], + "Mature_Green_Fruit": [ + "Heinz_MG" + ], + "Breaker_Fruit": [ + "Heinz_B" + ], + "Breaker_Fruit_+_10": [ + "Heinz_B10" + ], + "Pimpinellifolium_Immature_Green_Fruit": [ + "Pimp_IM" + ], + "Pimpinellifolium_Breaker_Fruit": [ + "Pimp_B" + ], + "Pimpinellifolium_Breaker_+_5_Fruit": [ + "Pimp_B5" + ], + "Pimpinellifolium_Leaf": [ + "Pimp_leaf" + ] + } + } + } + }, + "Rose_Lab_Atlas_Renormalized": { + "database": "tomato_renormalized", + "view_name": "Rose_Lab_Atlas_Renormalized", + "groups": { + "454": { + "controls": [ + "TOMATO_CTRL_454" + ], + "treatments": { + "epidermis": [ + "epidermis" + ], + "collenchyma": [ + "collenchyma" + ], + "vascular": [ + "vascular" + ], + "parenchyma": [ + "parenchyma" + ], + "endodermis": [ + "endodermis" + ] + } + }, + "Illumina": { + "controls": [ + "TOMATO_CTRL" + ], + "treatments": { + "Unopened_Flower_Bud": [ + "Heinz_bud" + ], + "Fully_Opened_Flower": [ + "Heinz_flower" + ], + "Leaves": [ + "Heinz_leaf" + ], + "Root": [ + "Heinz_root" + ], + "1cm_Fruit": [ + "Heinz_1cm_fruit" + ], + "2cm_Fruit": [ + "Heinz_2cm_fruit" + ], + "3cm_Fruit": [ + "Heinz_3cm_fruit" + ], + "Mature_Green_Fruit": [ + "Heinz_MG" + ], + "Breaker_Fruit": [ + "Heinz_B" + ], + "Breaker_Fruit_+_10": [ + "Heinz_B10" + ], + "Pimpinellifolium_Immature_Green_Fruit": [ + "Pimp_IM" + ], + "Pimpinellifolium_Breaker_Fruit": [ + "Pimp_B" + ], + "Pimpinellifolium_Breaker_+_5_Fruit": [ + "Pimp_B5" + ], + "Pimpinellifolium_Leaf": [ + "Pimp_leaf" + ] + } + } + } + }, + "SEED_Lab_Angers": { + "database": "tomato_seed", + "view_name": "SEED_Lab_Angers", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Seed_15DAF": [ + "15_S_1", + "15_S_2", + "15_S_3" + ], + "Seed_21DAF": [ + "21_S_1", + "21_S_2", + "21_S_3" + ], + "Seed_28DAF": [ + "28_S_1", + "28_S_2", + "28_S_3" + ], + "Embryo_35DAF": [ + "35_Em_1", + "35_Em_2", + "35_Em_3" + ], + "Seed_Coat_35DAF": [ + "35_SC_1", + "35_SC_2", + "35_SC_3" + ], + "Embryo_42DAF": [ + "42_Em_1", + "42_Em_2", + "42_Em_3" + ], + "Endosperm_42DAF": [ + "42_End_1", + "42_End_2", + "42_End_3" + ], + "Endosperm_35DAF": [ + "35_End_1", + "35_End_2", + "35_End_3" + ], + "Seed_Coat_42DAF": [ + "42_SC_1", + "42_SC_2", + "42_SC_3" + ], + "Embryo_49DAF": [ + "49_Em_1", + "49_Em_2", + "49_Em_3" + ], + "Endosperm_49DAF": [ + "49_End_1", + "49_End_2", + "49_End_3" + ], + "Seed_Coat_49DAF": [ + "49_SC_1", + "49_SC_2", + "49_SC_3" + ], + "Embryo_Br": [ + "B_Em_1", + "B_Em_3", + "B_Em_4" + ], + "Endosperm_Br": [ + "B_End_1", + "B_End_3", + "B_End_4" + ], + "Embryo_DO": [ + "DO_Em_1", + "DO_Em_2", + "DO_Em_4" + ], + "Endosperm_DO": [ + "DO_End_1", + "DO_End_2", + "DO_End_4" + ], + "Embryo_MG": [ + "MG_Em_2", + "MG_Em_3", + "MG_Em_4" + ], + "Endosperm_MG": [ + "MG_End_2", + "MG_End_3", + "MG_End_4" + ], + "Embryo_O": [ + "O_Em_1", + "O_Em_2", + "O_Em_3" + ], + "Endosperm_O": [ + "O_End_1", + "O_End_2", + "O_End_3" + ], + "Embryo_PO": [ + "PO_Em_2", + "PO_Em_3", + "PO_Em_4" + ], + "Endosperm_PO": [ + "PO_End_1", + "PO_End_2", + "PO_End_3" + ], + "Embryo_R": [ + "R_Em_1", + "R_Em_2", + "R_Em_3" + ], + "Endosperm_R": [ + "R_End_1", + "R_End_2", + "R_End_3" + ], + "Embryo_R+14d": [ + "R14_Em_1", + "R14_Em_3", + "R14_Em_4" + ], + "Endosperm_R+14d": [ + "R14_End_1", + "R14_End_3", + "R14_End_4" + ], + "Embryo_R+7d": [ + "R7_Em_1", + "R7_Em_2", + "R7_Em_3" + ], + "Endosperm_R+7d": [ + "R7_End_1", + "R7_End_2", + "R7_End_3" + ] + } + } + } + }, + "Shade_Mutants": { + "database": "tomato_shade_mutants", + "view_name": "Shade_Mutants", + "groups": { + "WT_6h_L_WL_1;WT_6h_L_WL_2;WT_6h_L_WL_3": { + "controls": [ + "WT_6h_L_WL_1", + "WT_6h_L_WL_2", + "WT_6h_L_WL_3" + ], + "treatments": { + "WT_first_leaf,_FR_light,_6h": [ + "WT_6h_L_FR_1", + "WT_6h_L_FR_2", + "WT_6h_L_FR_3" + ], + "WT_first_leaf,_white_light,_6h": [ + "WT_6h_L_WL_1", + "WT_6h_L_WL_2", + "WT_6h_L_WL_3" + ] + } + }, + "WT_6h_E_WL_1;WT_6h_E_WL_2;WT_6h_E_WL_3": { + "controls": [ + "WT_6h_E_WL_1", + "WT_6h_E_WL_2", + "WT_6h_E_WL_3" + ], + "treatments": { + "WT_epicotyl,_FR_light,_6h": [ + "WT_6h_E_FR_1", + "WT_6h_E_FR_2", + "WT_6h_E_FR_3" + ], + "WT_epicotyl,_white_light,_6h": [ + "WT_6h_E_WL_1", + "WT_6h_E_WL_2", + "WT_6h_E_WL_3" + ] + } + }, + "WT_6h_C_WL_1;WT_6h_C_WL_2;WT_6h_C_WL_3": { + "controls": [ + "WT_6h_C_WL_1", + "WT_6h_C_WL_2", + "WT_6h_C_WL_3" + ], + "treatments": { + "WT_cotyledon,_FR_light,_6h": [ + "WT_6h_C_FR_1", + "WT_6h_C_FR_2", + "WT_6h_C_FR_3" + ], + "WT_cotyledon,_white_light,_6h": [ + "WT_6h_C_WL_1", + "WT_6h_C_WL_2", + "WT_6h_C_WL_3" + ] + } + }, + "WT_6h_H_WL_1;WT_6h_H_WL_2;WT_6h_H_WL_3": { + "controls": [ + "WT_6h_H_WL_1", + "WT_6h_H_WL_2", + "WT_6h_H_WL_3" + ], + "treatments": { + "WT_hypocotyl,_FR_light,_6h": [ + "WT_6h_H_FR_1", + "WT_6h_H_FR_2", + "WT_6h_H_FR_3" + ], + "WT_hypocotyl,_white_light,_6h": [ + "WT_6h_H_WL_1", + "WT_6h_H_WL_2", + "WT_6h_H_WL_3" + ] + } + }, + "slpif8a_6h_L_WL_1;slpif8a_6h_L_WL_2;slpif8a_6h_L_WL_3": { + "controls": [ + "slpif8a_6h_L_WL_1", + "slpif8a_6h_L_WL_2", + "slpif8a_6h_L_WL_3" + ], + "treatments": { + "slpif8a_first_leaf,_FR_light,_6h": [ + "slpif8a_6h_L_FR_1", + "slpif8a_6h_L_FR_2", + "slpif8a_6h_L_FR_3" + ], + "slpif8a_first_leaf,_white_light,_6h": [ + "slpif8a_6h_L_WL_1", + "slpif8a_6h_L_WL_2", + "slpif8a_6h_L_WL_3" + ] + } + }, + "slpif8a_6h_E_WL_1;slpif8a_6h_E_WL_2;slpif8a_6h_E_WL_3": { + "controls": [ + "slpif8a_6h_E_WL_1", + "slpif8a_6h_E_WL_2", + "slpif8a_6h_E_WL_3" + ], + "treatments": { + "slpif8a_epicotyl,_FR_light,_6h": [ + "slpif8a_6h_E_FR_1", + "slpif8a_6h_E_FR_2", + "slpif8a_6h_E_FR_3" + ], + "slpif8a_epicotyl,_white_light,_6h": [ + "slpif8a_6h_E_WL_1", + "slpif8a_6h_E_WL_2", + "slpif8a_6h_E_WL_3" + ] + } + }, + "slpif8a_6h_C_WL_1;slpif8a_6h_C_WL_2;slpif8a_6h_C_WL_3": { + "controls": [ + "slpif8a_6h_C_WL_1", + "slpif8a_6h_C_WL_2", + "slpif8a_6h_C_WL_3" + ], + "treatments": { + "slpif8a_cotyledon,_FR_light,_6h": [ + "slpif8a_6h_C_FR_1", + "slpif8a_6h_C_FR_2", + "slpif8a_6h_C_FR_3" + ], + "slpif8a_cotyledon,_white_light,_6h": [ + "slpif8a_6h_C_WL_1", + "slpif8a_6h_C_WL_2", + "slpif8a_6h_C_WL_3" + ] + } + }, + "slpif8a_6h_H_WL_1;slpif8a_6h_H_WL_2;slpif8a_6h_H_WL_3": { + "controls": [ + "slpif8a_6h_H_WL_1", + "slpif8a_6h_H_WL_2", + "slpif8a_6h_H_WL_3" + ], + "treatments": { + "slpif8a_hypocotyl,_FR_light,_6h": [ + "slpif8a_6h_H_FR_1", + "slpif8a_6h_H_FR_2", + "slpif8a_6h_H_FR_3" + ], + "slpif8a_hypocotyl,_white_light,_6h": [ + "slpif8a_6h_H_WL_1", + "slpif8a_6h_H_WL_2", + "slpif8a_6h_H_WL_3" + ] + } + }, + "slpifq_6h_L_WL_1;slpifq_6h_L_WL_2;slpifq_6h_L_WL_3": { + "controls": [ + "slpifq_6h_L_WL_1", + "slpifq_6h_L_WL_2", + "slpifq_6h_L_WL_3" + ], + "treatments": { + "First_leaf,_FR_light,_6h": [ + "slpifq_6h_L_FR_1", + "slpifq_6h_L_FR_2", + "slpifq_6h_L_FR_3" + ], + "First_leaf,_white_light,_6h": [ + "slpifq_6h_L_WL_1", + "slpifq_6h_L_WL_2", + "slpifq_6h_L_WL_3" + ] + } + }, + "slpifq_6h_E_WL_1;slpifq_6h_E_WL_2;slpifq_6h_E_WL_3": { + "controls": [ + "slpifq_6h_E_WL_1", + "slpifq_6h_E_WL_2", + "slpifq_6h_E_WL_3" + ], + "treatments": { + "Epicotyl,_FR_light,_6h": [ + "slpifq_6h_E_FR_1", + "slpifq_6h_E_FR_2", + "slpifq_6h_E_FR_3" + ], + "Epicotyl,_white_light,_6h": [ + "slpifq_6h_E_WL_1", + "slpifq_6h_E_WL_2", + "slpifq_6h_E_WL_3" + ] + } + }, + "slpifq_6h_C_WL_1;slpifq_6h_C_WL_2;slpifq_6h_C_WL_3": { + "controls": [ + "slpifq_6h_C_WL_1", + "slpifq_6h_C_WL_2", + "slpifq_6h_C_WL_3" + ], + "treatments": { + "Cotyledon,_FR_light,_6h": [ + "slpifq_6h_C_FR_1", + "slpifq_6h_C_FR_2", + "slpifq_6h_C_FR_3" + ], + "Cotyledon,_white_light,_6h": [ + "slpifq_6h_C_WL_1", + "slpifq_6h_C_WL_2", + "slpifq_6h_C_WL_3" + ] + } + }, + "slpifq_6h_H_WL_1;slpifq_6h_H_WL_2;slpifq_6h_H_WL_3": { + "controls": [ + "slpifq_6h_H_WL_1", + "slpifq_6h_H_WL_2", + "slpifq_6h_H_WL_3" + ], + "treatments": { + "Hypocotyl,_FR_light,_6h": [ + "slpifq_6h_H_FR_1", + "slpifq_6h_H_FR_2", + "slpifq_6h_H_FR_3" + ], + "Hypocotyl,_white_light,_6h": [ + "slpifq_6h_H_WL_1", + "slpifq_6h_H_WL_2", + "slpifq_6h_H_WL_3" + ] + } + } + } + }, + "Shade_Timecourse_WT": { + "database": "tomato_shade_timecourse", + "view_name": "Shade_Timecourse_WT", + "groups": { + "WT_3h_L_WL_1;WT_3h_L_WL_2;WT_3h_L_WL_3": { + "controls": [ + "WT_3h_L_WL_1", + "WT_3h_L_WL_2", + "WT_3h_L_WL_3" + ], + "treatments": { + "First_leaf,_FR_light,_3h": [ + "WT_3h_L_FR_1", + "WT_3h_L_FR_2", + "WT_3h_L_FR_3" + ], + "First_leaf,_white_light,_3h": [ + "WT_3h_L_WL_1", + "WT_3h_L_WL_2", + "WT_3h_L_WL_3" + ] + } + }, + "WT_3h_E_WL_1;WT_3h_E_WL_2;WT_3h_E_WL_3": { + "controls": [ + "WT_3h_E_WL_1", + "WT_3h_E_WL_2", + "WT_3h_E_WL_3" + ], + "treatments": { + "Epicotyl,_FR_light,_3h": [ + "WT_3h_E_FR_1", + "WT_3h_E_FR_2", + "WT_3h_E_FR_3" + ], + "Epicotyl,_white_light,_3h": [ + "WT_3h_E_WL_1", + "WT_3h_E_WL_2", + "WT_3h_E_WL_3" + ] + } + }, + "WT_3h_C_WL_1;WT_3h_C_WL_2;WT_3h_C_WL_3": { + "controls": [ + "WT_3h_C_WL_1", + "WT_3h_C_WL_2", + "WT_3h_C_WL_3" + ], + "treatments": { + "Cotyledon,_FR_light,_3h": [ + "WT_3h_C_FR_1", + "WT_3h_C_FR_2", + "WT_3h_C_FR_3" + ], + "Cotyledon,_white_light,_3h": [ + "WT_3h_C_WL_1", + "WT_3h_C_WL_2", + "WT_3h_C_WL_3" + ] + } + }, + "WT_3h_H_WL_1;WT_3h_H_WL_2;WT_3h_H_WL_3": { + "controls": [ + "WT_3h_H_WL_1", + "WT_3h_H_WL_2", + "WT_3h_H_WL_3" + ], + "treatments": { + "Hypocotyl,_FR_light,_3h": [ + "WT_3h_H_FR_1", + "WT_3h_H_FR_2", + "WT_3h_H_FR_3" + ], + "Hypocotyl,_white_light,_3h": [ + "WT_3h_H_WL_1", + "WT_3h_H_WL_2", + "WT_3h_H_WL_3" + ] + } + }, + "WT_6h_L_WL_1;WT_6h_L_WL_2;WT_6h_L_WL_3": { + "controls": [ + "WT_6h_L_WL_1", + "WT_6h_L_WL_2", + "WT_6h_L_WL_3" + ], + "treatments": { + "First_leaf,_FR_light,_6h": [ + "WT_6h_L_FR_1", + "WT_6h_L_FR_2", + "WT_6h_L_FR_3" + ], + "First_leaf,_white_light,_6h": [ + "WT_6h_L_WL_1", + "WT_6h_L_WL_2", + "WT_6h_L_WL_3" + ] + } + }, + "WT_6h_E_WL_1;WT_6h_E_WL_2;WT_6h_E_WL_3": { + "controls": [ + "WT_6h_E_WL_1", + "WT_6h_E_WL_2", + "WT_6h_E_WL_3" + ], + "treatments": { + "Epicotyl,_FR_light,_6h": [ + "WT_6h_E_FR_1", + "WT_6h_E_FR_2", + "WT_6h_E_FR_3" + ], + "Epicotyl,_white_light,_6h": [ + "WT_6h_E_WL_1", + "WT_6h_E_WL_2", + "WT_6h_E_WL_3" + ] + } + }, + "WT_6h_C_WL_1;WT_6h_C_WL_2;WT_6h_C_WL_3": { + "controls": [ + "WT_6h_C_WL_1", + "WT_6h_C_WL_2", + "WT_6h_C_WL_3" + ], + "treatments": { + "Cotyledon,_FR_light,_6h": [ + "WT_6h_C_FR_1", + "WT_6h_C_FR_2", + "WT_6h_C_FR_3" + ], + "Cotyledon,_white_light,_6h": [ + "WT_6h_C_WL_1", + "WT_6h_C_WL_2", + "WT_6h_C_WL_3" + ] + } + }, + "WT_6h_H_WL_1;WT_6h_H_WL_2;WT_6h_H_WL_3": { + "controls": [ + "WT_6h_H_WL_1", + "WT_6h_H_WL_2", + "WT_6h_H_WL_3" + ], + "treatments": { + "Hypocotyl,_FR_light,_6h": [ + "WT_6h_H_FR_1", + "WT_6h_H_FR_2", + "WT_6h_H_FR_3" + ], + "Hypocotyl,_white_light,_6h": [ + "WT_6h_H_WL_1", + "WT_6h_H_WL_2", + "WT_6h_H_WL_3" + ] + } + }, + "WT_24h_L_WL_1;WT_24h_L_WL_2;WT_24h_L_WL_3": { + "controls": [ + "WT_24h_L_WL_1", + "WT_24h_L_WL_2", + "WT_24h_L_WL_3" + ], + "treatments": { + "First_leaf,_FR_light,_24h": [ + "WT_24h_L_FR_1", + "WT_24h_L_FR_2", + "WT_24h_L_FR_3" + ], + "First_leaf,_white_light,_24h": [ + "WT_24h_L_WL_1", + "WT_24h_L_WL_2", + "WT_24h_L_WL_3" + ] + } + }, + "WT_24h_E_WL_1;WT_24h_E_WL_2;WT_24h_E_WL_3": { + "controls": [ + "WT_24h_E_WL_1", + "WT_24h_E_WL_2", + "WT_24h_E_WL_3" + ], + "treatments": { + "Epicotyl,_FR_light,_24h": [ + "WT_24h_E_FR_1", + "WT_24h_E_FR_2", + "WT_24h_E_FR_3" + ], + "Epicotyl,_white_light,_24h": [ + "WT_24h_E_WL_1", + "WT_24h_E_WL_2", + "WT_24h_E_WL_3" + ] + } + }, + "WT_24h_C_WL_1;WT_24h_C_WL_2;WT_24h_C_WL_3": { + "controls": [ + "WT_24h_C_WL_1", + "WT_24h_C_WL_2", + "WT_24h_C_WL_3" + ], + "treatments": { + "Cotyledon,_FR_light,_24h": [ + "WT_24h_C_FR_1", + "WT_24h_C_FR_2", + "WT_24h_C_FR_3" + ], + "Cotyledon,_white_light,_24h": [ + "WT_24h_C_WL_1", + "WT_24h_C_WL_2", + "WT_24h_C_WL_3" + ] + } + }, + "WT_24h_H_WL_1;WT_24h_H_WL_2;WT_24h_H_WL_3": { + "controls": [ + "WT_24h_H_WL_1", + "WT_24h_H_WL_2", + "WT_24h_H_WL_3" + ], + "treatments": { + "Hypocotyl,_FR_light,_24h": [ + "WT_24h_H_FR_1", + "WT_24h_H_FR_2", + "WT_24h_H_FR_3" + ], + "Hypocotyl,_white_light,_24h": [ + "WT_24h_H_WL_1", + "WT_24h_H_WL_2", + "WT_24h_H_WL_3" + ] + } + } + } + }, + "Tomato_Meristem": { + "database": "tomato_meristem", + "view_name": "Tomato_Meristem", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "WT_Base_Margin": [ + "wt_base_margin_1", + "wt_base_margin_2", + "wt_base_margin_3", + "wt_base_margin_4", + "wt_base_margin_5", + "wt_base_margin_6" + ], + "WT_Base_Rachis": [ + "wt_base_rachis_1", + "wt_base_rachis_2", + "wt_base_rachis_3" + ], + "WT_Middle_Margin": [ + "wt_middle_margin_1", + "wt_middle_margin_2", + "wt_middle_margin_3" + ], + "WT_Middle_Rachis": [ + "wt_middle_rachis_1", + "wt_middle_rachis_2", + "wt_middle_rachis_3" + ], + "WT_Top_Margin": [ + "wt_top_margin_1", + "wt_top_margin_2", + "wt_top_margin_3" + ], + "WT_Top_Rachis": [ + "wt_top_rachis_1", + "wt_top_rachis_2", + "wt_top_rachis_3", + "wt_top_rachis_4", + "wt_top_rachis_5" + ], + "TF2_Base_Margin": [ + "tf2_base_margin_1", + "tf2_base_margin_2", + "tf2_base_margin_3", + "tf2_base_margin_4" + ], + "TF2_Base_Rachis": [ + "tf2_base_rachis_1", + "tf2_base_rachis_2", + "tf2_base_rachis_3", + "tf2_base_rachis_4" + ], + "TF2_Middle_Margin": [ + "tf2_middle_margin_1", + "tf2_middle_margin_2", + "tf2_middle_margin_3" + ], + "TF2_Middle_Rachis": [ + "tf2_middle_rachis_1", + "tf2_middle_rachis_2", + "tf2_middle_rachis_3", + "tf2_middle_rachis_4" + ], + "TF2_Top_Margin": [ + "tf2_top_margin_1", + "tf2_top_margin_2", + "tf2_top_margin_3" + ], + "TF2_Top_Rachis": [ + "tf2_top_rachis_1", + "tf2_top_rachis_2", + "tf2_top_rachis_3", + "tf2_top_rachis_4" + ] + } + } + } + } + } + } + }, + "triticale": { + + "data": { + "species": "triticale", + "views": { + "triticale": { + "database": "triticale", + "view_name": "triticale", + "groups": { + "Reproductive": { + "controls": [ + "TRITICALE_CTRL" + ], + "treatments": { + "Anther_tetrad": [ + "Anther_TET1", + "Anther_TET2", + "Anther_TET3" + ], + "Stigma_tetrad": [ + "Stigma_TET1", + "Stigma_TET2", + "Stigma_TET3" + ], + "Ovary_tetrad": [ + "Ovary_TET1", + "Ovary_TET2", + "Ovary_TET3" + ], + "Anther_uninucleate": [ + "Anther_UNM1", + "Anther_UNM2", + "Anther_UNM3" + ], + "Stigma_uninucleate": [ + "Stigma_UNM1", + "Stigma_UNM2", + "Stigma_UNM3" + ], + "Ovary_uninucleate": [ + "Ovary_UNM1", + "Ovary_UNM2", + "Ovary_UNM3" + ], + "Anther_bicellular_pollen": [ + "Anther_BCP1", + "Anther_BCP2", + "Anther_BCP3" + ], + "Stigma_bicellular_pollen": [ + "Stigma_BCP1", + "Stigma_BCP2", + "Stigma_BCP3" + ], + "Ovary_bicellular_pollen": [ + "Ovary_BCP1", + "Ovary_BCP2", + "Ovary_BCP3" + ], + "Anther_tricellular_pollen": [ + "Anther_TCP1", + "Anther_TCP2", + "Anther_TCP3" + ], + "Stigma_tricellular_pollen": [ + "Stigma_TCP1", + "Stigma_TCP2", + "Stigma_TCP3" + ], + "Ovary_tricellular_pollen": [ + "Ovary_TCP1", + "Ovary_TCP2", + "Ovary_TCP3" + ], + "Mature_pollen": [ + "Pollen_MPG1", + "Pollen_MPG2", + "Pollen_MPG3" + ] + } + } + } + }, + "triticale_mas": { + "database": "triticale_mas", + "view_name": "triticale_mas", + "groups": { + "Reproductive": { + "controls": [ + "TRITICALE_CTRL" + ], + "treatments": { + "Anther_tetrad": [ + "Anther_tetrad_1", + "Anther_tetrad_2", + "Anther_tetrad_3" + ], + "Stigma_tetrad": [ + "Stigma_tetrad_1", + "Stigma_tetrad_2", + "Stigma_tetrad_3" + ], + "Ovary_tetrad": [ + "Ovary_tetrad_1", + "Ovary_tetrad_2", + "Ovary_tetrad_3" + ], + "Anther_uninucleate": [ + "Anther_uninucleate_1", + "Anther_uninucleate_2", + "Anther_uninucleate_3" + ], + "Stigma_uninucleate": [ + "Stigma_uninucleate_1", + "Stigma_uninucleate_2", + "Stigma_uninucleate_3" + ], + "Ovary_uninucleate": [ + "Ovary_uninucleate_1", + "Ovary_uninucleate_2", + "Ovary_uninucleate_3" + ], + "Anther_bicellular_pollen": [ + "Anther_bicellular_pollen_1", + "Anther_bicellular_pollen_2", + "Anther_bicellular_pollen_3" + ], + "Stigma_bicellular_pollen": [ + "Stigma_bicellular_pollen_1", + "Stigma_bicellular_pollen_2", + "Stigma_bicellular_pollen_3" + ], + "Ovary_bicellular_pollen": [ + "Ovary_bicellular_pollen_1", + "Ovary_bicellular_pollen_2", + "Ovary_bicellular_pollen_3" + ], + "Anther_tricellular_pollen": [ + "Anther_tricellular_pollen_1", + "Anther_tricellular_pollen_2", + "Anther_tricellular_pollen_3" + ], + "Stigma_tricellular_pollen": [ + "Stigma_tricellular_pollen_1", + "Stigma_tricellular_pollen_2", + "Stigma_tricellular_pollen_3" + ], + "Ovary_tricellular_pollen": [ + "Ovary_tricellular_pollen_1", + "Ovary_tricellular_pollen_2", + "Ovary_tricellular_pollen_3" + ], + "Mature_pollen": [ + "Mature_pollen_1", + "Mature_pollen_2", + "Mature_pollen_3" + ] + } + } + } + } + } + } + }, + "wheat": { + + "data": { + "species": "wheat", + "views": { + "Developmental_Atlas": { + "database": "wheat", + "view_name": "Developmental_Atlas", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "First_leaf_sheath_-_Tillering_stage": [ + "Sample_43A", + "Sample_44A", + "Sample_45A" + ], + "Internode_#2_-_Milk_grain_stage": [ + "Sample_188B", + "Sample_189B" + ], + "Shoot_apical_meristem_-_Seedling_stage": [ + "Sample_19A", + "Sample_20A", + "Sample_21A" + ], + "Grain_-_Milk_grain_stage": [ + "Sample_199A", + "Sample_200A", + "Sample_201A" + ], + "First_leaf_blade_-_Seedling_stage": [ + "Sample_13R1", + "Sample_23", + "Sample_32" + ], + "Flag_leaf_blade_-_Full_boot_": [ + "Sample_94B", + "Sample_95A", + "Sample_96A" + ], + "Awn_-_50_percent_spike": [ + "Sample_118A", + "Sample_119B", + "Sample_120A" + ], + "flag_leaf_blade_night_(-0.25h)_06:45": [ + "Sample_166A", + "Sample_167A", + "Sample_168A" + ], + "Shoot_axis_-_Flag_leaf_stage": [ + "Sample_70A", + "Sample_71A", + "Sample_72A" + ], + "Fifth_leaf_blade_-_Flag_leaf_stage": [ + "Sample_67A", + "Sample_68A", + "Sample_69A" + ], + "Third_leaf_sheath_-_Three_leaf_stage": [ + "Sample_25A", + "Sample_26A", + "Sample_27A" + ], + "Internode_#2_-_Ear_emergence": [ + "Sample_136A", + "Sample_137B", + "Sample_138A" + ], + "Anther": [ + "Sample_160A", + "Sample_161A", + "Sample_162A" + ], + "Spike": [ + "Sample_100A", + "Sample_101A", + "Sample_102A" + ], + "Coleoptile": [ + "Sample_12", + "Sample_26", + "Sample_6A" + ], + "Stigma_and_Ovary": [ + "Sample_163A", + "Sample_164A", + "Sample_165A" + ], + "Roots_-_Flag_leaf_stage": [ + "Sample_73A", + "Sample_74A", + "Sample_76A" + ], + "Fifth_leaf_sheath_-_Flag_leaf_stage": [ + "Sample_64A", + "Sample_65A", + "Sample_66A" + ], + "Root_apical_meristem_-_Three_leaf_stage": [ + "Sample_15", + "Sample_32R2", + "Sample_33A" + ], + "Flag_leaf_sheath_-_Ear_emergence": [ + "Sample_124A", + "Sample_125A", + "Sample_126A" + ], + "Roots_-_Three_leaf_stage": [ + "Sample_28A", + "Sample_29A", + "Sample_30A" + ], + "Axillary_roots_-_Three_leaf_stage": [ + "Sample_16", + "Sample_35R1", + "Sample_36A" + ], + "Flag_leaf_sheath_-_50_percent_spike": [ + "Sample_106A", + "Sample_107B", + "Sample_108A" + ], + "Radicle_-_Seedling_stage": [ + "Sample_10", + "Sample_18", + "Sample_3A" + ], + "Roots_-_50_percent_spike": [ + "Sample_103A", + "Sample_104B", + "Sample_105B" + ], + "Third_leaf_blade_-_Three_leaf_stage": [ + "Sample_22B", + "Sample_23A", + "Sample_24A" + ], + "Spikelets_-_50_percent_spike": [ + "Sample_121A", + "Sample_122A", + "Sample_123A" + ], + "Root_apical_meristem_-_Tillering_stage": [ + "Sample_58A", + "Sample_59A", + "Sample_60A" + ], + "Grain_-_Ripening_stage": [ + "Sample_217B", + "Sample_218A", + "Sample_219A" + ], + "Awns_-_Ear_emergence": [ + "Sample_139A", + "Sample_140A", + "Sample_141A" + ], + "Glumes": [ + "Sample_193A", + "Sample_194A", + "Sample_195A" + ], + "Glumes_-_Ear_emergence": [ + "Sample_142A", + "Sample_143A", + "Sample_144B" + ], + "Leaf_ligule": [ + "Sample_88A", + "Sample_89B", + "Sample_90A" + ], + "Flag_leaf_blade_-_50_percent_spike": [ + "Sample_109A", + "Sample_110A", + "Sample_111B" + ], + "Internode_#2_-_50_percent_spike": [ + "Sample_112B", + "Sample_113B", + "Sample_114B" + ], + "Fifth_leaf_sheath_-_Fifth_leaf_stage": [ + "Sample_37A", + "Sample_38A", + "Sample_39A" + ], + "fifth_leaf_blade_night_(-0.25h)_21:45": [ + "Sample_79A", + "Sample_80A", + "Sample_81A" + ], + "Grain_-_Soft_dough": [ + "Sample_205A", + "Sample_206A", + "Sample_207A" + ], + "Flag_leaf_blade_(senescence)_-_Dough_stage": [ + "Sample_202A", + "Sample_203A", + "Sample_204A" + ], + "Flag_leaf_blade_night_(-0.25h)_06:45_-_Flag_leaf_stage": [ + "Sample_75A", + "Sample_77A", + "Sample_78A" + ], + "Flag_leaf_blade_(senescence)_-_Ripening_stage": [ + "Sample_223B", + "Sample_225A" + ], + "First_leaf_blade_-_Tillering_stage": [ + "Sample_46A", + "Sample_d11", + "Sample_d12" + ], + "Shoot_apical_meristem_-_Tillering_stage": [ + "Sample_52A", + "Sample_53A", + "Sample_54A" + ], + "Shoot_axis_-_First_leaf_stage": [ + "Sample_11", + "Sample_20", + "Sample_9A" + ], + "Roots_-_Seedling_stage": [ + "Sample_13", + "Sample_18A", + "Sample_33" + ], + "Shoot_axis_-_Milk_grain_stage": [ + "Sample_178A", + "Sample_179A", + "Sample_180A" + ], + "Fifth_leaf_blade_-_Fifth_leaf_stage": [ + "Sample_40A", + "Sample_41A", + "Sample_42A" + ], + "Flag_leaf_blade_-_Ear_emergence": [ + "Sample_127A", + "Sample_128A", + "Sample_129A" + ], + "flag_leaf_blade_night_(+0.25h)_07:15": [ + "Sample_82A", + "Sample_83B", + "Sample_84A" + ], + "Fifth_leaf_blade_night_(-0.25h)_21:45": [ + "Sample_169A", + "Sample_170A", + "Sample_171A" + ], + "Shoot_axis_-_Tillering_stage": [ + "Sample_49A", + "Sample_50A", + "Sample_51A" + ], + "Stem_axis_-_First_leaf_stage": [ + "Sample_11", + "Sample_20", + "Sample_9A" + ], + "Endosperm": [ + "Sample_211B", + "Sample_212A", + "Sample_213A" + ], + "Peduncle": [ + "Sample_184A", + "Sample_185A", + "Sample_186A" + ], + "Peduncle_-_50_percent_spike": [ + "Sample_115A", + "Sample_116A", + "Sample_117A" + ], + "Peduncle_-_Ear_emergence": [ + "Sample_133A", + "Sample_134A", + "Sample_135A" + ], + "Flag_leaf_sheath_-_Full_boot": [ + "Sample_91A", + "Sample_92A", + "Sample_93A" + ], + "Flag_leaf_blade_-_Flag_leaf_stage": [ + "Sample_61A", + "Sample_62A", + "Sample_63A" + ], + "Lemma": [ + "Sample_196A", + "Sample_197A", + "Sample_198A" + ], + "Lemma_-_Ear_emergence": [ + "Sample_157A", + "Sample_158A", + "Sample_159B" + ], + "Awns_-_Milk_grain_stage": [ + "Sample_190A", + "Sample_191A", + "Sample_192A" + ], + "fifth_leaf_blade_night_(+0.25h)_22:15": [ + "Sample_85B", + "Sample_86A", + "Sample_87A" + ], + "Flag_leaf_blade_-_Milk_grain_stage": [ + "Sample_175A", + "Sample_176A", + "Sample_177A" + ], + "Grain_-_Hard_dough": [ + "Sample_208A", + "Sample_209A", + "Sample_210A" + ], + "Flag_leaf_sheath_-_Milk_grain_stage": [ + "Sample_172A", + "Sample_173A", + "Sample_174A" + ], + "Embryo_proper": [ + "Sample_214A", + "Sample_215A", + "Sample_216A" + ], + "Fifth_leaf_blade_(senescence)_-_Milk_grain_stage": [ + "Sample_181A", + "Sample_182A", + "Sample_183A" + ], + "Roots_-_Tillering_stage": [ + "Sample_55B", + "Sample_56A", + "Sample_57A" + ], + "Shoot_axis_-_Full_boot": [ + "Sample_97A", + "Sample_98A", + "Sample_99A" + ], + "Fifth_leaf_blade_-_Ear_emergence": [ + "Sample_130A", + "Sample_131A", + "Sample_132A" + ], + "First_leaf_sheath_-_Seedling_stage": [ + "Sample_10R1", + "Sample_21", + "Sample_30" + ] + } + } + } + }, + "Wheat_Abiotic_Stress": { + "database": "wheat_abiotic_stress", + "view_name": "Wheat_Abiotic_Stress", + "groups": { + "Med_CTRL": { + "controls": [ + "C1", + "C2", + "C4", + "C8" + ], + "treatments": { + "All": [ + "SHD4", + "SHD5", + "SHD6", + "SHD7" + ], + "Salt_+_Drought": [ + "SD1", + "SD5", + "SD6", + "SD8" + ], + "Salt_+_Heat": [ + "SH2", + "SH3", + "SH4", + "SH8" + ], + "Heat_+_Drought": [ + "HD3", + "HD4", + "HD7", + "HD8" + ], + "Drought_Only": [ + "D1", + "D4", + "D6", + "D8" + ], + "Heat_Only": [ + "H1", + "H2", + "H3", + "H4" + ], + "Salt_Only": [ + "S1", + "S3", + "S5", + "S8" + ], + "Control": [ + "C1", + "C2", + "C4", + "C8" + ] + } + } + } + }, + "Wheat_Embryogenesis": { + "database": "wheat_embryogenesis", + "view_name": "Wheat_Embryogenesis", + "groups": { + "AA-DV92_Med_CTRL": { + "controls": [ + "AA-DV92_Med_CTRL" + ], + "treatments": { + "AA-DV92_Leaf_Early_Seed_Coat": [ + "AA-DV92_Leaf_early_stage_seed_coat" + ], + "AA-DV92_Leaf_Late_Embryo": [ + "AA-DV92_Leaf_late_embryo" + ], + "AA-DV92_Leaf_Early_Embryo": [ + "AA-DV92_Leaf_early_embryo" + ], + "AA-DV92_Leaf_Late_Endosperm": [ + "AA-DV92_Leaf_late_stage_endosperm" + ], + "AA-DV92_Leaf_Middle_Embryo": [ + "AA-DV92_Leaf_middle_embryo" + ], + "AA-DV92_Pre-Embryo": [ + "AA-DV92_Pre-embryo" + ], + "AA-DV92_Mature_Embryo": [ + "AA-DV92_Mature_embryo" + ], + "AA-DV92_Two_Cell_Embryo": [ + "AA-DV92_Two_cell_embryo" + ], + "AA-DV92_Transition_Embryo": [ + "AA-DV92_Transition_embryo" + ], + "AA-DV92_Transition_Endosperm": [ + "AA-DV92_Transition_stage_endosperm" + ] + } + }, + "Hexaploid-AC_Med_CTRL": { + "controls": [ + "Hexaploid-AC_Med_CTRL" + ], + "treatments": { + "Hexaploid-AC_Leaf_Late_Endosperm": [ + "Hexaploid-AC_Late_leaf_stage_endosperm" + ], + "Hexaploid-AC_Leaf_Early_Embryo": [ + "Hexaploid-AC_Leaf_early_embryo" + ], + "Hexaploid-AC_Leaf_Early_Seed_Coat": [ + "Hexaploid-AC_Leaf_early_stage_seed_coat" + ], + "Hexaploid-AC_Leaf_Late_Embryo": [ + "Hexaploid-AC_Leaf_early_stage_seed_coat" + ], + "Hexaploid-AC_Leaf_Middle_Embryo": [ + "Hexaploid-AC_Leaf_middle_embryo" + ], + "Hexaploid-AC_Mature_Embryo": [ + "Hexaploid-AC_Mature_embryo" + ], + "Hexaploid-AC_Pre-Embryo": [ + "Hexaploid-AC_Pre-embryo" + ], + "Hexaploid-AC_Transition_Embryo": [ + "Hexaploid-AC_Transition_embryo" + ], + "Hexaploid-AC_Transition_Endosperm": [ + "Hexaploid-AC_Transition_stage_endosperm" + ], + "Hexaploid-AC_Two_Cell_Embryo": [ + "Hexaploid-AC_Two_cell_embryo" + ] + } + }, + "Tetraploid-SF_Med_CTRL": { + "controls": [ + "Tetraploid-SF_Med_CTRL" + ], + "treatments": { + "Tetraploid-SF_Leaf_Early_Seed_Coat": [ + "Tetraploid-SF_Leaf_early_stage_seed_coat" + ], + "Tetraploid-SF_Leaf_Early_Embryo": [ + "Tetraploid-SF_Leaf_early_embryo" + ], + "Tetraploid-SF_Leaf_Late_Embryo": [ + "Tetraploid-SF_Leaf_late_embryo" + ], + "Tetraploid-SF_Leaf_Late_Endosperm": [ + "Tetraploid-SF_Leaf_late_stage_endosperm" + ], + "Tetraploid-SF_Leaf_Middle_Embryo": [ + "Tetraploid-SF_Leaf_middle_embryo" + ], + "Tetraploid-SF_Mature_Embryo": [ + "Tetraploid-SF_Mature_embryo" + ], + "Tetraploid-SF_Pre-Embryo": [ + "Tetraploid-SF_Pre-embryo" + ], + "Tetraploid-SF_Transition_Embryo": [ + "Tetraploid-SF_Transition_embryo" + ], + "Tetraploid-SF_Transition_Endosperm": [ + "Tetraploid-SF_Transition_stage_endosperm" + ], + "Tetraploid-SF_Two_Cell_Embryo": [ + "Tetraploid-SF_Two_cell_embryo" + ] + } + }, + "BB-TA2780_Med_CTRL": { + "controls": [ + "BB-TA2780_Med_CTRL" + ], + "treatments": { + "BB-TA2780_Leaf_Early_Seed_Coat": [ + "BB-TA2780_Leaf_early_stage_seed_coat" + ], + "BB-TA2780_Leaf_Early_Embryo": [ + "BB-TA2780_Leaf_early_embryo" + ], + "BB-TA2780_Leaf_Late_Embryo": [ + "BB-TA2780_Leaf_late_embryo" + ], + "BB-TA2780_Leaf_Late_Endosperm": [ + "BB-TA2780_Leaf_late_stage_endosperm" + ], + "BB-TA2780_Leaf_Middle_Embryo": [ + "BB-TA2780_Leaf_middle_embryo" + ], + "BB-TA2780_Mature_Embryo": [ + "BB-TA2780_Mature_embryo" + ], + "BB-TA2780_Pre-Embryo": [ + "BB-TA2780_Pre-embryo" + ], + "BB-TA2780_Transition_Embryo": [ + "BB-TA2780_Transition_embryo" + ], + "BB-TA2780_Transition_Endosperm": [ + "BB-TA2780_Transition_stage_endosperm" + ], + "BB-TA2780_Two_Cell_Embryo": [ + "BB-TA2780_Two_cell_embryo" + ] + } + }, + "DD-TA101132_Med_CTRL": { + "controls": [ + "DD-TA101132_Med_CTRL" + ], + "treatments": { + "DD-TA101132_Leaf_Early_Embryo": [ + "DD-TA101132_Leaf_early_embryo" + ], + "DD-TA101132_Leaf_Early_Seed_Coat": [ + "DD-TA101132_Leaf_early_stage_seed_coat" + ], + "DD-TA101132_Leaf_Late_Embryo": [ + "DD-TA101132_Leaf_late_embryo" + ], + "DD-TA101132_Leaf_Late_Endosperm": [ + "DD-TA101132_Leaf_late_stage_endosperm" + ], + "DD-TA101132_Leaf_Middle_Embryo": [ + "DD-TA101132_leaf_middle_embryo" + ], + "DD-TA101132_Mature_Embryo": [ + "DD-TA101132_Mature_embryo" + ], + "DD-TA101132_Transition_Embryo": [ + "DD-TA101132_Transition_embryo" + ], + "DD-TA101132_Transition_Endosperm": [ + "DD-TA101132_Transition_stage_endosperm" + ], + "DD-TA101132_Two_Cell_Embryo": [ + "DD-TA101132_Two_cell_embryo" + ], + "DD-TA101132_Pre-Embryo": [ + "DD-TA101132_Pre-embryo" + ] + } + } + } + }, + "Wheat_Meiosis": { + "database": "wheat_meiosis", + "view_name": "Wheat_Meiosis", + "groups": { + "Med_CTRL": { + "controls": [ + "Med_CTRL" + ], + "treatments": { + "Anther": [ + "Anther_rep1", + "Anther_rep2", + "Anther_rep3" + ], + "Diplotene": [ + "Diplotene_rep1", + "Diplotene_rep2", + "Diplotene_rep3" + ], + "Flagleaf": [ + "FlagLeaf_rep1", + "FlagLeaf_rep2", + "FlagLeaf_rep3" + ], + "Leaf": [ + "Leaf_rep1", + "Leaf_rep2", + "Leaf_rep3" + ], + "Leptotene": [ + "Leptotene_rep1", + "Leptotene_rep2", + "Leptotene_rep3" + ], + "Metaphase_I": [ + "Metaphase-I_rep1", + "Metaphase-I_rep2", + "Metaphase-I_rep3" + ], + "Metaphase_II": [ + "Metaphase-II_rep1", + "Metaphase-II_rep2", + "Metaphase-II_rep3" + ], + "Pachytene": [ + "Pachytene_rep1", + "Pachytene_rep2", + "Pachytene_rep3" + ], + "Pollen": [ + "Pollen_rep1", + "Pollen_rep2", + "Pollen_rep3" + ], + "Pre-meiotic_G2": [ + "Pre-meiotic_G2_rep1", + "Pre-meiotic_G2_rep2", + "Pre-meiotic_G2_rep3" + ], + "Zygotene": [ + "Zygotene_rep1", + "Zygotene_rep2", + "Zygotene_rep3" + ] + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/data/gene_information/gene_isoforms/example_placeholder.txt b/data/gene_information/gene_isoforms/example_placeholder.txt deleted file mode 100644 index e69de29..0000000 diff --git a/docs/efp_proxy.md b/docs/efp_proxy.md new file mode 100644 index 0000000..ef6c12f --- /dev/null +++ b/docs/efp_proxy.md @@ -0,0 +1,115 @@ +# eFP Proxy Guide + +This note documents how the new `/efp_proxy` endpoints work, why they satisfy the “one web call + one SQL query” requirement, and how to exercise them locally even without access to the production MySQL servers. + +## What This Implementation Delivers + +- **Single HTTP request** to BAR’s CGI: `/efp_proxy/values/{database}/{gene_id}` collects every sample (either from the `samples` query param or by auto-loading the list from `data/efp_info/efp_species_view_info.json`) and ships them to `https://bar.utoronto.ca/eplant/cgi-bin/plantefp.cgi` in one call. See `api/resources/efp_proxy.py` (function `fetch_efp_data`). +- **Single SQL query** for any mirrored database: `/efp_proxy/expression/{database}/{gene_id}` looks up the table/column names in a schema catalog and runs one `SELECT sample, value FROM sample_data WHERE gene_column = :gene_id` statement. No per-database ORM/models or branching logic are needed. +- **Dynamic database routing**: Every request first tries the live SQLAlchemy bind (`db.get_engine(bind=database)`), then falls back to the SQLite mirror you generate locally. The same code therefore works offline (using mirrors) and online (using the real DB) without any changes. +- **Consistent JSON payload**: Both endpoints output `[{"name": SAMPLE_ID, "value": SIGNAL}, …]`, so the frontend expects the same structure whether data came from the CGI or a local/remote database. + +## Key Code Highlights + +### One Web Call + +```python +def fetch_efp_data(datasource, gene_id, samples=None): + query_params = [ + ("datasource", datasource), + ("id", gene_id), + ("format", "json"), + ] + ... + response = requests.get(base_url, params=query_params) +``` + +- If `samples` are provided (repeat `?samples=foo&samples=bar` in the query string, or use the legacy JSON array), they are appended once. +- If `samples` is omitted, `get_all_samples_for_view` loads every sample for that datasource and adds that list. +- The request is made **exactly once**; if the CGI returns nothing we retry without the `samples` hint but still as a single call. +- Returned data already looks like `[{"name": "...", "value": "..."}]`. + +### One SQL Query + +```python +def query_efp_database_dynamic(database, gene_id, sample_ids=None): + schema = DYNAMIC_DATABASE_SCHEMAS[database] + db_path = DATABASE_DIR / schema["filename"] + engine_candidates = [] + try: + bound_engine = db.get_engine(bind=database) + engine_candidates.append(("sqlalchemy_bind", bound_engine, False)) + except Exception: + ... + if db_path.exists(): + sqlite_engine = create_engine(f"sqlite:///{db_path}") + engine_candidates.append(("sqlite_mirror", sqlite_engine, True)) + + query_sql = text( + f"SELECT {schema['sample_column']} AS sample, " + f"{schema['value_column']} AS value " + f"FROM {schema['table']} " + f"WHERE {schema['gene_column']} = :gene_id" + ) +``` + +- `DYNAMIC_DATABASE_SCHEMAS` is a simple dictionary (`{db_name: {table, gene_column, ...}}`). No per-database models are required for the endpoint. +- The helper first attempts the live bind (`sqlalchemy_bind`) and only if that fails does it open the SQLite mirror (`sqlite_mirror`). +- One SQL statement fetches every sample/value row for the requested gene and we normalize it into `[{"name": ..., "value": ...}]`. + +### Why You Might Not See “All Values” Locally + +- The repo ships *trimmed-down* `.sql` dumps (fixtures) inside `config/databases/*.sql`. When you build mirrors with `python scripts/build_sqlite_mirrors.py`, you are mirroring that limited data, so `/expression/klepikova/AT1G01010` only returns the single SRR row included in the dump (currently `SRR3581336`). The long `INSERT INTO sample_general_info ... SRR...` block is metadata; it doesn’t contain expression values. `/expression` only reads `sample_data`, because that table has the `data_signal` column required for output. +- The long `INSERT INTO sample_general_info ... SRR...` block is metadata; it doesn’t contain expression values. `/expression` only reads `sample_data`, because that table has the `data_signal` column required for output. +- As soon as you connect to the real MySQL databases (by running the dockerized MySQL or pointing `SQLALCHEMY_BINDS` at production), the bind succeeds first and you immediately get the full data set. + +## Workflow: Local Mirrors vs. Real Databases + +1. **Generate mirrors** (local dev only): + ```bash + python scripts/build_sqlite_mirrors.py klepikova sample_data + ``` + This produces `config/databases/klepikova.db`, etc. The endpoint automatically uses them when the MySQL bind isn’t available. + +2. **Run the API**: + ```bash + flask run # or docker compose up api + ``` + +3. **Test the endpoints**: + - External CGI with auto-loaded samples (one web call): + ``` + http://127.0.0.1:5000/efp_proxy/values/atgenexp_stress/AT1G01010 + http://127.0.0.1:5000/efp_proxy/values/root_Schaefer_lab/AT3G24650?samples=WTCHG_203594_01&samples=WTCHG_203594_05 + ``` + - Dynamic DB query (one SQL statement): + ``` + http://127.0.0.1:5000/efp_proxy/expression/klepikova/AT1G01010 + http://127.0.0.1:5000/efp_proxy/expression/sample_data/261585_at + ``` + +4. **Deploying with the real databases**: ensure `config/BAR_API.cfg` points to the production MySQL hosts. `query_efp_database_dynamic` will hit them via `db.get_engine(bind=database)`; the SQLite mirrors simply act as a fallback when you’re offline. + +## Static vs. Dynamic: What Changed + +- **Static approach** (old): every database needed its own model file (e.g., `api/models/klepikova.py`), controller logic, and SQL query. Adding a new dataset meant writing more Python and risking inconsistencies. +- **Dynamic approach** (new): + - We only maintain the simple schema catalog (table + column names per database). + - The same endpoint and SQL query cover every database. + - No new ORM classes are required for `/efp_proxy/expression`. (Other parts of the API still use those models, which is why the files remain in the repo.) + - Switching between local mirrors and live MySQL happens automatically. + +## Why We Still Can’t “Pull Everything” Locally + +- The SQLite mirrors you generate reflect whatever is inside the `.sql` dump—often a very small subset used by tests. +- Without the real MySQL dump, the endpoint physically can’t return rows that don’t exist in the mirror. This is a data limitation, not a code bug. +- Once hooked to the production database, the query returns all values in a single request/statement, fulfilling the original requirement. + +## Summary + +- `/efp_proxy/values` → ONE external web call, optional sample filtering. +- `/efp_proxy/expression` → ONE SQL query per request, dynamic schema lookup, automatic choice between live MySQL and local SQLite. +- Schema catalog + mirror script = no more per-database boilerplate. +- Full datasets appear as soon as the real databases are reachable; mirrors just keep development/testing running offline. + +This architecture hits the deliverables outlined in the project brief while keeping the codebase maintainable for future databases. diff --git a/scripts/build_sqlite_mirrors.py b/scripts/build_sqlite_mirrors.py new file mode 100755 index 0000000..640041c --- /dev/null +++ b/scripts/build_sqlite_mirrors.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +Utility to convert the shipped MySQL dumps under config/databases into local +SQLite mirrors that api.resources.efp_proxy can read without a live MySQL bind. + +Usage: + python scripts/build_sqlite_mirrors.py # build every mirror + python scripts/build_sqlite_mirrors.py klepikova # build selected DBs + python scripts/build_sqlite_mirrors.py --force ... # overwrite .db files +""" + +from __future__ import annotations + +import argparse +import re +import sqlite3 +import sys +from pathlib import Path +from typing import Iterable + + +ROOT_DIR = Path(__file__).resolve().parents[1] +DATABASE_DIR = ROOT_DIR / "config" / "databases" + +# Regex helpers to strip MySQL-only clauses (storage engine, charset, auto-increment, etc.) +# so the CREATE TABLE statements can be executed by SQLite without syntax errors. +ENGINE_REGEX = re.compile(r"\)\s*ENGINE=.*;", flags=re.IGNORECASE) +CHARSET_REGEX = re.compile(r"DEFAULT\s+CHARSET=.*?(?=\)|;)", flags=re.IGNORECASE) +COLLATE_REGEX = re.compile(r"COLLATE\s*=\s*[^\s)]+", flags=re.IGNORECASE) +COLUMN_AUTO_INCREMENT_REGEX = re.compile(r"\s+AUTO_INCREMENT\b", flags=re.IGNORECASE) +AUTO_INCREMENT_REGEX = re.compile(r"AUTO_INCREMENT=\d+", flags=re.IGNORECASE) + + +def discover_sql_files() -> dict[str, Path]: + """Return a map of database name -> dump path (stem of filename).""" + sql_files = {} + for path in DATABASE_DIR.glob("*.sql"): + sql_files[path.stem] = path + return sql_files + + +def sanitize_mysql_dump(sql_text: str) -> str: + """Remove MySQL-only statements so SQLite can execute the script.""" + sanitized_lines = [] + skip_block = False + + for line in sql_text.splitlines(): + if skip_block: + if ";" in line: + skip_block = False + continue + + stripped = line.strip() + if not stripped: + continue + if stripped.startswith("--"): + continue + + upper = stripped.upper() + if upper.startswith("LOCK TABLES") or upper.startswith("UNLOCK TABLES"): + continue + if upper.startswith("CREATE DATABASE") or upper.startswith("USE "): + continue + if upper.startswith("SET ") or upper.startswith("DELIMITER "): + continue + if upper.startswith("START TRANSACTION") or upper == "COMMIT;": + continue + if upper.startswith("ALTER TABLE "): + skip_block = True + continue + if upper.startswith("KEY ") or upper.startswith("UNIQUE KEY") or upper.startswith("FULLTEXT KEY"): + continue + if stripped.startswith("/*!"): + # Skip MySQL conditional comments entirely. + continue + + line = ENGINE_REGEX.sub(");", line) + line = CHARSET_REGEX.sub("", line) + line = COLLATE_REGEX.sub("", line) + line = AUTO_INCREMENT_REGEX.sub("", line) + line = COLUMN_AUTO_INCREMENT_REGEX.sub("", line) + + sanitized_lines.append(line) + + sanitized = "\n".join(sanitized_lines) + sanitized = re.sub(r",\s*\n\)", "\n)", sanitized) + return sanitized + + +def build_sqlite_db(sql_path: Path, db_path: Path, force: bool) -> None: + """Create/overwrite SQLite DB from the provided MySQL dump.""" + if db_path.exists(): + if not force: + print(f"[skip] {db_path.name} already exists (use --force to overwrite)") + return + db_path.unlink() + + sql_text = sql_path.read_text(encoding="utf-8") + # SQLite cannot run raw MySQL dumps, so we strip dialect-specific bits first. + sanitized_sql = sanitize_mysql_dump(sql_text) + if not sanitized_sql.strip(): + raise RuntimeError(f"No executable SQL found in {sql_path.name}") + + conn = sqlite3.connect(db_path) + try: + # Disable FK constraints while replaying the dump to avoid dependency issues. + conn.executescript("PRAGMA foreign_keys = OFF;") + # Executescript lets us run the entire dump in one go. + conn.executescript(sanitized_sql) + conn.commit() + print(f"[ok] Created {db_path.relative_to(ROOT_DIR)}") + finally: + conn.close() + + +def parse_args(argv: Iterable[str]) -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Generate SQLite mirrors from the MySQL dumps in config/databases", + ) + parser.add_argument( + "databases", + nargs="*", + help="Database names to convert (defaults to every *.sql file).", + ) + parser.add_argument( + "--force", + action="store_true", + help="Overwrite existing .db files instead of skipping them.", + ) + return parser.parse_args(list(argv)) + + +def main(argv: Iterable[str]) -> int: + args = parse_args(argv) + # Step 1: discover every *.sql dump shipped with the repo. + # These dumps are the source of truth for the local mirrors. + available = discover_sql_files() + if not available: + print("No .sql dumps found in config/databases", file=sys.stderr) + return 1 + + targets = args.databases or sorted(available.keys()) + missing = [name for name in targets if name not in available] + if missing: + print(f"Unknown database(s): {', '.join(missing)}", file=sys.stderr) + print(f"Available dumps: {', '.join(sorted(available.keys()))}", file=sys.stderr) + return 1 + + # Step 2: iterate over each requested dump and build the matching SQLite db. + for name in targets: + sql_path = available[name] + db_path = DATABASE_DIR / f"{name}.db" + build_sqlite_db(sql_path, db_path, force=args.force) + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv[1:])) From a1d09c7d37de11e8152354fa37b16e0719456f48 Mon Sep 17 00:00:00 2001 From: Reena Date: Thu, 4 Dec 2025 14:12:36 -0500 Subject: [PATCH 2/6] dynamic ORMs --- api/models/arabidopsis_ecotypes.py | 15 - api/models/arachis.py | 12 - api/models/cannabis.py | 12 - api/models/dna_damage.py | 12 - api/models/efp_dynamic.py | 50 ++ api/models/efp_schemas.py | 313 ++++++++ api/models/embryo.py | 12 - api/models/germination.py | 12 - api/models/kalanchoe.py | 12 - api/models/klepikova.py | 12 - api/models/phelipanche.py | 12 - api/models/physcomitrella_db.py | 12 - api/models/selaginella.py | 12 - api/models/shoot_apex.py | 12 - api/models/silique.py | 12 - api/models/single_cell.py | 12 - api/models/strawberry.py | 12 - api/models/striga.py | 12 - api/models/triphysaria.py | 12 - api/resources/efp_proxy.py | 399 +++------- api/resources/microarray_gene_expression.py | 7 +- api/resources/rnaseq_gene_expression.py | 251 +++---- api/services/__init__.py | 3 + api/services/efp_bootstrap.py | 128 ++++ api/services/efp_data.py | 274 +++++++ config/init.sh | 6 +- docs/efp_proxy.md | 115 --- scripts/bootstrap_simple_efp_dbs.py | 60 ++ tests/services/test_efp_data.py | 112 +++ vendor/flask_sqlacodegen/LICENSE | 22 + vendor/flask_sqlacodegen/MANIFEST.in | 1 + vendor/flask_sqlacodegen/Makefile | 59 ++ vendor/flask_sqlacodegen/README.md | 36 + vendor/flask_sqlacodegen/requirements.txt | 22 + vendor/flask_sqlacodegen/setup.cfg | 13 + vendor/flask_sqlacodegen/setup.py | 67 ++ .../flask_sqlacodegen/sqlacodegen/__init__.py | 1 + .../flask_sqlacodegen/sqlacodegen/codegen.py | 702 ++++++++++++++++++ .../sqlacodegen/dialects/__init__.py | 0 .../sqlacodegen/dialects/postgresql.py | 36 + vendor/flask_sqlacodegen/sqlacodegen/main.py | 71 ++ vendor/flask_sqlacodegen/tox.ini | 26 + 42 files changed, 2191 insertions(+), 790 deletions(-) delete mode 100644 api/models/arabidopsis_ecotypes.py delete mode 100644 api/models/arachis.py delete mode 100644 api/models/cannabis.py delete mode 100644 api/models/dna_damage.py create mode 100644 api/models/efp_dynamic.py create mode 100644 api/models/efp_schemas.py delete mode 100644 api/models/embryo.py delete mode 100644 api/models/germination.py delete mode 100644 api/models/kalanchoe.py delete mode 100644 api/models/klepikova.py delete mode 100644 api/models/phelipanche.py delete mode 100644 api/models/physcomitrella_db.py delete mode 100644 api/models/selaginella.py delete mode 100644 api/models/shoot_apex.py delete mode 100644 api/models/silique.py delete mode 100644 api/models/single_cell.py delete mode 100644 api/models/strawberry.py delete mode 100644 api/models/striga.py delete mode 100644 api/models/triphysaria.py create mode 100644 api/services/__init__.py create mode 100644 api/services/efp_bootstrap.py create mode 100644 api/services/efp_data.py delete mode 100644 docs/efp_proxy.md create mode 100644 scripts/bootstrap_simple_efp_dbs.py create mode 100644 tests/services/test_efp_data.py create mode 100644 vendor/flask_sqlacodegen/LICENSE create mode 100644 vendor/flask_sqlacodegen/MANIFEST.in create mode 100644 vendor/flask_sqlacodegen/Makefile create mode 100644 vendor/flask_sqlacodegen/README.md create mode 100644 vendor/flask_sqlacodegen/requirements.txt create mode 100644 vendor/flask_sqlacodegen/setup.cfg create mode 100644 vendor/flask_sqlacodegen/setup.py create mode 100644 vendor/flask_sqlacodegen/sqlacodegen/__init__.py create mode 100644 vendor/flask_sqlacodegen/sqlacodegen/codegen.py create mode 100644 vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py create mode 100644 vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py create mode 100644 vendor/flask_sqlacodegen/sqlacodegen/main.py create mode 100644 vendor/flask_sqlacodegen/tox.ini diff --git a/api/models/arabidopsis_ecotypes.py b/api/models/arabidopsis_ecotypes.py deleted file mode 100644 index d582703..0000000 --- a/api/models/arabidopsis_ecotypes.py +++ /dev/null @@ -1,15 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "arabidopsis_ecotypes" - __tablename__ = "sample_data" - - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - proj_id: db.Mapped[str] = db.mapped_column(db.String(15), nullable=False) - sample_file_name: db.Mapped[str] = db.mapped_column(db.String) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(30), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float) - data_call: db.Mapped[str] = db.mapped_column(db.String) - data_p_val: db.Mapped[float] = db.mapped_column(db.Float) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False) diff --git a/api/models/arachis.py b/api/models/arachis.py deleted file mode 100644 index 7247e8b..0000000 --- a/api/models/arachis.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "arachis" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.String(5), nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(30), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(64), nullable=False, primary_key=True) diff --git a/api/models/cannabis.py b/api/models/cannabis.py deleted file mode 100644 index d257936..0000000 --- a/api/models/cannabis.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "cannabis" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(2), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(8), nullable=False, primary_key=True) diff --git a/api/models/dna_damage.py b/api/models/dna_damage.py deleted file mode 100644 index 95e2d9a..0000000 --- a/api/models/dna_damage.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "dna_damage" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(10), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(32), nullable=False, primary_key=True) diff --git a/api/models/efp_dynamic.py b/api/models/efp_dynamic.py new file mode 100644 index 0000000..b410e84 --- /dev/null +++ b/api/models/efp_dynamic.py @@ -0,0 +1,50 @@ +""" +dynamic sqlalchemy model generation for simple efp databases +""" + +from __future__ import annotations + +from typing import Dict + +from sqlalchemy import Float, Integer, String, Text +from sqlalchemy.dialects.mysql import INTEGER + +from api import db +from api.models.efp_schemas import SIMPLE_EFP_DATABASE_SCHEMAS + + +def _to_sqla_type(column_spec): + """map a simple column spec to a sqlalchemy column type""" + col_type = column_spec.get("type") + if col_type == "string": + return String(column_spec["length"]) + if col_type == "integer": + if column_spec.get("unsigned"): + return INTEGER(unsigned=True) + return Integer + if col_type == "float": + return Float + if col_type == "text": + return Text + raise ValueError(f"Unsupported column type: {col_type}") + + +def _generate_model(bind_key: str, spec) -> db.Model: + """build a concrete sqlalchemy model for the given schema""" + attrs = {"__bind_key__": bind_key, "__tablename__": spec["table_name"]} + + for column in spec["columns"]: + kwargs = {"nullable": column.get("nullable", True)} + if column.get("primary_key"): + kwargs["primary_key"] = True + attrs[column["name"]] = db.mapped_column(_to_sqla_type(column), **kwargs) + + class_name = "".join([part.capitalize() for part in bind_key.split("_")]) + "SampleData" + return type(class_name, (db.Model,), attrs) + + +SIMPLE_EFP_SAMPLE_MODELS: Dict[str, db.Model] = { + db_name: _generate_model(db_name, spec) for db_name, spec in SIMPLE_EFP_DATABASE_SCHEMAS.items() +} + +__all__ = ["SIMPLE_EFP_SAMPLE_MODELS"] diff --git a/api/models/efp_schemas.py b/api/models/efp_schemas.py new file mode 100644 index 0000000..0d78c39 --- /dev/null +++ b/api/models/efp_schemas.py @@ -0,0 +1,313 @@ +""" +simple schema definitions for efp databases that only expose a sample_data table +""" + +from __future__ import annotations + +from typing import Any, Dict, List + +ColumnSpec = Dict[str, Any] +DatabaseSpec = Dict[str, Any] + + +def _column( + name: str, + col_type: str, + *, + length: int | None = None, + unsigned: bool = False, + nullable: bool = True, + default: Any | None = None, + primary_key: bool = False, +) -> ColumnSpec: + column: ColumnSpec = {"name": name, "type": col_type, "nullable": nullable} + if length is not None: + column["length"] = length + if unsigned: + column["unsigned"] = True + if default is not None: + column["default"] = default + if primary_key: + column["primary_key"] = True + return column + + +# base column specs keep every schema consistent unless an override is provided +BASE_COLUMNS: Dict[str, ColumnSpec] = { + "proj_id": _column("proj_id", "string", length=5, nullable=False, default="0"), + "sample_id": _column("sample_id", "integer", unsigned=True, nullable=False, default=0), + "data_probeset_id": _column("data_probeset_id", "string", length=24, nullable=False, primary_key=True), + "data_signal": _column("data_signal", "float", nullable=False, default=0, primary_key=True), + "data_bot_id": _column("data_bot_id", "string", length=16, nullable=False, primary_key=True), +} + +# blueprint defines the order we hydrate into tables +DEFAULT_BLUEPRINT: List[str] = ["proj_id", "sample_id", "data_probeset_id", "data_signal", "data_bot_id"] +DEFAULT_INDEX = ["data_probeset_id", "data_bot_id", "data_signal"] + + +def _build_schema( + *, + charset: str = "latin1", + table_name: str = "sample_data", + column_overrides: Dict[str, Dict[str, Any]] | None = None, + extra_columns: List[ColumnSpec] | None = None, + index: List[str] | None = None, + seed_rows: List[Dict[str, Any]] | None = None, + identifier_type: str = "agi", + metadata: Dict[str, Any] | None = None, +) -> DatabaseSpec: + overrides = column_overrides or {} + columns: List[ColumnSpec] = [] + + for column_name in DEFAULT_BLUEPRINT: + spec = dict(BASE_COLUMNS[column_name]) + if column_name in overrides: + spec.update(overrides[column_name]) + columns.append(spec) + + if extra_columns: + columns.extend(extra_columns) + + # schema dict is the single source of truth for each database + schema: DatabaseSpec = { + "table_name": table_name, + "charset": charset, + "columns": columns, + "index": index if index is not None else list(DEFAULT_INDEX), + "identifier_type": identifier_type, + } + + if seed_rows: + schema["seed_rows"] = seed_rows + if metadata: + schema["metadata"] = metadata + + return schema + + +# simple canonical schema for the easiest efp mirrors so the orm code and bootstrap script stay in sync +SIMPLE_EFP_DATABASE_SCHEMAS: Dict[str, DatabaseSpec] = { + "arabidopsis_ecotypes": _build_schema( + charset="latin1", + column_overrides={ + "proj_id": {"length": 15}, + "data_probeset_id": {"length": 30}, + "data_signal": {"nullable": True, "primary_key": False}, + "data_bot_id": {"nullable": True}, + }, + extra_columns=[ + _column("sample_file_name", "text", nullable=True), + _column("data_call", "text", nullable=True), + _column("data_p_val", "float", nullable=True, default=0), + ], + index=["data_probeset_id"], + metadata={ + "species": "arabidopsis", + "sample_regex": r"^[A-Z0-9_]{1,20}$|Med_CTRL$", + }, + ), + "arachis": _build_schema( + column_overrides={ + "proj_id": {"length": 24, "default": None}, + "sample_id": {"type": "string", "length": 5, "unsigned": False, "default": None}, + "data_probeset_id": {"length": 30}, + "data_bot_id": {"length": 65}, + }, + metadata={ + "species": "arachis", + "sample_regex": r"^[\D\d_]{1,30}|MED_CTRL$", + }, + ), + "cannabis": _build_schema( + column_overrides={ + "proj_id": {"length": 2}, + "data_bot_id": {"length": 8}, + }, + seed_rows=[ + {"proj_id": "1", "sample_id": 1, "data_probeset_id": "AGQN03009284", "data_signal": 0, "data_bot_id": "PK-RT"} + ], + metadata={ + "species": "cannabis", + "sample_regex": r"^PK-\D{1,4}|MED_CTRL$", + }, + ), + "dna_damage": _build_schema( + charset="utf8mb4", + column_overrides={ + "data_probeset_id": {"length": 10}, + "data_bot_id": {"length": 32, "nullable": True}, + }, + seed_rows=[ + { + "proj_id": "1", + "sample_id": 1, + "data_probeset_id": "AT1G01010", + "data_signal": 59, + "data_bot_id": "col-0_rep1_12hr_minus_Y", + } + ], + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\D{1,3}.{1,30}_plus_Y|\D{1,3}.{1,30}_minus_Y|Med_CTRL$", + }, + ), + "embryo": _build_schema( + column_overrides={ + "proj_id": {"length": 3}, + "data_probeset_id": {"length": 16}, + "data_signal": {"nullable": True}, + "data_bot_id": {"length": 8}, + }, + seed_rows=[ + {"proj_id": "1", "sample_id": 1, "data_probeset_id": "AT1G01010", "data_signal": 0.67, "data_bot_id": "pg_1"} + ], + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\D{1,3}_\d$|Med_CTRL$", + }, + ), + "germination": _build_schema( + column_overrides={ + "proj_id": {"length": 3}, + "data_probeset_id": {"length": 30}, + "data_bot_id": {"length": 16}, + }, + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\d{1,3}\D{1,4}_\d{1,3}|harvest_\d|Med_CTRL$", + }, + ), + "kalanchoe": _build_schema( + column_overrides={ + "proj_id": {"length": 2}, + "data_bot_id": {"length": 16}, + }, + metadata={ + "species": "kalanchoe", + "sample_regex": r"^\D{1,4}_\D{1,5}_rep\d|MED_CTRL$", + }, + ), + "klepikova": _build_schema( + column_overrides={ + "proj_id": {"length": 3}, + "data_probeset_id": {"length": 30}, + "data_bot_id": {"length": 16}, + }, + extra_columns=[_column("data_call", "string", length=2, nullable=True)], + metadata={ + "species": "arabidopsis", + "sample_regex": r"^SRR\d{1,9}|Med_CTRL$", + }, + ), + "phelipanche": _build_schema( + charset="utf8mb4", + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 16}, + "data_bot_id": {"length": 32}, + }, + metadata={ + "species": "phelipanche", + "sample_regex": r"^[a-z_-]{1,35}|MED_CTRL$", + }, + ), + "physcomitrella_db": _build_schema( + column_overrides={ + "proj_id": {"length": 30, "default": ""}, + "sample_id": {"type": "string", "length": 30, "unsigned": False, "default": ""}, + "data_probeset_id": {"length": 40, "default": "", "primary_key": True}, + "data_bot_id": {"length": 40}, + }, + metadata={ + "species": "physcomitrella", + "sample_regex": r"^[a-z_123]{1,15}|MED_CTRL$", + }, + ), + "selaginella": _build_schema( + column_overrides={ + "proj_id": {"length": 5}, + "data_probeset_id": {"length": 18}, + "data_bot_id": {"length": 36}, + }, + metadata={ + "species": "selaginella", + "sample_regex": r"^[\D\d]{1,33}|MED_CTRL$", + }, + ), + "shoot_apex": _build_schema( + column_overrides={ + "proj_id": {"length": 2, "nullable": True, "default": None}, + "data_probeset_id": {"length": 12}, + "data_bot_id": {"length": 8}, + }, + extra_columns=[ + _column("sample_file_name", "string", length=16, nullable=True), + _column("data_call", "string", length=2, nullable=True), + _column("data_p_val", "float", nullable=True, default=0), + ], + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\D{1,5}\d{0,2}|MED_CTRL$", + }, + ), + "silique": _build_schema( + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 12}, + "data_bot_id": {"length": 64}, + }, + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\d{1,3}_dap.{1,58}_R1_001|Med_CTRL$", + }, + ), + "single_cell": _build_schema( + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 24}, + "data_bot_id": {"length": 32}, + }, + metadata={ + "species": "arabidopsis", + "sample_regex": r"^\D+\d+_WT\d+.ExprMean|MED_CTRL$", + }, + ), + "strawberry": _build_schema( + charset="utf8mb4", + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 16}, + "data_bot_id": {"length": 24}, + }, + metadata={ + "species": "strawberry", + "sample_regex": r"^\D{1,12}_.{1,8}_\D{1,2}|MED_CTRL$", + }, + ), + "striga": _build_schema( + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 24}, + "data_bot_id": {"length": 42}, + }, + metadata={ + "species": "striga", + "sample_regex": r"^\D{1,35}|MED_CTRL$", + }, + ), + "triphysaria": _build_schema( + charset="utf8mb4", + column_overrides={ + "proj_id": {"length": 5, "default": None}, + "data_probeset_id": {"length": 16}, + "data_bot_id": {"length": 32}, + }, + metadata={ + "species": "triphysaria", + "sample_regex": r"^[a-z_]{1,35}|MED_CTRL$", + }, + ), +} + +__all__: List[str] = ["SIMPLE_EFP_DATABASE_SCHEMAS", "ColumnSpec", "DatabaseSpec"] diff --git a/api/models/embryo.py b/api/models/embryo.py deleted file mode 100644 index 5c14d4a..0000000 --- a/api/models/embryo.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "embryo" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(3), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(8), nullable=False, primary_key=True) diff --git a/api/models/germination.py b/api/models/germination.py deleted file mode 100644 index 89aaceb..0000000 --- a/api/models/germination.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "germination" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(3), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(30), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) diff --git a/api/models/kalanchoe.py b/api/models/kalanchoe.py deleted file mode 100644 index c3c03f9..0000000 --- a/api/models/kalanchoe.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "kalanchoe" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(2), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) diff --git a/api/models/klepikova.py b/api/models/klepikova.py deleted file mode 100644 index 8a76513..0000000 --- a/api/models/klepikova.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "klepikova" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(3), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(30), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) diff --git a/api/models/phelipanche.py b/api/models/phelipanche.py deleted file mode 100644 index 937a998..0000000 --- a/api/models/phelipanche.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "phelipanche" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(32), nullable=False, primary_key=True) diff --git a/api/models/physcomitrella_db.py b/api/models/physcomitrella_db.py deleted file mode 100644 index 62fa3b4..0000000 --- a/api/models/physcomitrella_db.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "physcomitrella_db" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(30), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.String(30), nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(40), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(40), nullable=False, primary_key=True) diff --git a/api/models/selaginella.py b/api/models/selaginella.py deleted file mode 100644 index b911648..0000000 --- a/api/models/selaginella.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "selaginella" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(18), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(36), nullable=False, primary_key=True) diff --git a/api/models/shoot_apex.py b/api/models/shoot_apex.py deleted file mode 100644 index f8495d9..0000000 --- a/api/models/shoot_apex.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "shoot_apex" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(2), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(12), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(8), nullable=False, primary_key=True) diff --git a/api/models/silique.py b/api/models/silique.py deleted file mode 100644 index 9421f89..0000000 --- a/api/models/silique.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "silique" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(12), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(64), nullable=False, primary_key=True) diff --git a/api/models/single_cell.py b/api/models/single_cell.py deleted file mode 100644 index d046058..0000000 --- a/api/models/single_cell.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "single_cell" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(32), nullable=False, primary_key=True) diff --git a/api/models/strawberry.py b/api/models/strawberry.py deleted file mode 100644 index 7d0b85d..0000000 --- a/api/models/strawberry.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "strawberry" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False, primary_key=True) diff --git a/api/models/striga.py b/api/models/striga.py deleted file mode 100644 index 10fa4ac..0000000 --- a/api/models/striga.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "striga" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(24), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(42), nullable=False, primary_key=True) diff --git a/api/models/triphysaria.py b/api/models/triphysaria.py deleted file mode 100644 index d301873..0000000 --- a/api/models/triphysaria.py +++ /dev/null @@ -1,12 +0,0 @@ -from api import db - - -class SampleData(db.Model): - __bind_key__ = "triphysaria" - __tablename__ = "sample_data" - - proj_id: db.Mapped[str] = db.mapped_column(db.String(5), nullable=False) - sample_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False) - data_probeset_id: db.Mapped[str] = db.mapped_column(db.String(16), nullable=False, primary_key=True) - data_signal: db.Mapped[float] = db.mapped_column(db.Float, primary_key=True) - data_bot_id: db.Mapped[str] = db.mapped_column(db.String(32), nullable=False, primary_key=True) diff --git a/api/resources/efp_proxy.py b/api/resources/efp_proxy.py index 6c5a489..0dd3d14 100644 --- a/api/resources/efp_proxy.py +++ b/api/resources/efp_proxy.py @@ -1,103 +1,29 @@ import requests import json import os -import traceback -from pathlib import Path -from typing import Dict, List, Optional +from typing import List, Optional from collections import OrderedDict from flask_restx import Namespace, Resource -from flask import request, has_app_context +from flask import request, current_app from markupsafe import escape -from sqlalchemy import create_engine, text -from sqlalchemy.orm import Session +from sqlalchemy.engine.url import make_url from sqlalchemy.exc import SQLAlchemyError -from api import db -from api.models.annotations_lookup import AtAgiLookup -from api.models.bar_utils import BARUtils -# efp proxy namespace - provides two endpoints for gene expression data: -# 1. /values talks to the live BAR ePlant CGI -# 2. /expression reads from our local/remote databases using one shared query +from api.models.efp_dynamic import SIMPLE_EFP_SAMPLE_MODELS +from api.models.efp_schemas import SIMPLE_EFP_DATABASE_SCHEMAS +from api.services.efp_bootstrap import bootstrap_simple_efp_databases +from api.services.efp_data import query_efp_database_dynamic + +# efp proxy namespace provides two endpoints for gene expression data +# 1. /values talks to the live bar eplant cgi +# 2. /expression reads from our local or remote databases using one shared query efp_proxy_ns = Namespace( 'efp Proxy', description='Expression data retrieveal service from BAR eplant databse.', path='/efp_proxy', ) -# absolute path to the config/databases directory (where the sqlite mirrors live) -# centralized path keeps helper functions in sync about where mirrors live -ROOT_DIR = Path(__file__).resolve().parents[2] -DATABASE_DIR = ROOT_DIR / "config" / "databases" - -# schema catalog for every database in config/databases -# spelling out the table + column names once means every db can share the same query code -# centralizing schema knowledge avoids per-database ORM duplication -DEFAULT_SAMPLE_SCHEMA = { - "table": "sample_data", - "gene_column": "data_probeset_id", - "sample_column": "data_bot_id", - "value_column": "data_signal", -} - -# list of all mirrors that follow the default schema (sample_data/data_signal, etc.) -# adding new entries here is enough for the dynamic endpoint to pick them up -SAMPLE_DATA_DATABASES = [ - "arabidopsis_ecotypes", - "arachis", - "cannabis", - "canola_nssnp", - "dna_damage", - "embryo", - "eplant2", - "eplant_poplar", - "eplant_rice", - "eplant_soybean", - "eplant_tomato", - "fastpheno", - "germination", - "homologs_db", - "interactions_vincent_v2", - "kalanchoe", - "klepikova", - "llama3", - "phelipanche", - "physcomitrella_db", - "poplar_nssnp", - "rice_interactions", - "sample_data", - "selaginella", - "shoot_apex", - "silique", - "single_cell", - "soybean_nssnp", - "strawberry", - "striga", - "tomato_nssnp", - "tomato_sequence", - "triphysaria", -] - -# databases that store microarray probeset identifiers in data_probeset_id. -# every other db expects a normal arabidopsis gene id (AT1G01010, etc.) -# this toggle informs the dynamic query whether it needs to translate AGIs to probesets -PROBESET_DATABASES = {"sample_data"} - -# build the catalog once at import time so every request can look up its schema quickly -# precomputing avoids rebuilding dictionaries for every HTTP request -DYNAMIC_DATABASE_SCHEMAS: Dict[str, Dict[str, str]] = {} -for db_name in SAMPLE_DATA_DATABASES: - schema = DEFAULT_SAMPLE_SCHEMA.copy() - schema.update( - { - "filename": f"{db_name}.db", - "identifier_type": "probeset" if db_name in PROBESET_DATABASES else "agi", - } - ) - DYNAMIC_DATABASE_SCHEMAS[db_name] = schema - -# normalize optional samples provided via query params (supports repeated params, -# comma-delimited strings, or the legacy JSON array format) -# clients historically sent sample lists in several shapes; this keeps backward compatibility +# normalize optional samples from the query string so legacy formats still work def parse_samples_query_values(raw_values: Optional[List[str]]) -> Optional[List[str]]: if not raw_values: return None @@ -113,7 +39,7 @@ def parse_samples_query_values(raw_values: Optional[List[str]]) -> Optional[List if not candidate: return None - # interpret JSON array strings (legacy clients sent one JSON string value) + # interpret json array strings because legacy clients sent one json string value if candidate.startswith("[") and candidate.endswith("]"): try: parsed = json.loads(candidate) @@ -123,7 +49,7 @@ def parse_samples_query_values(raw_values: Optional[List[str]]) -> Optional[List pass if "," in candidate: - # support comma-separated lists (?samples=A,B,C) by splitting manually + # support comma-separated lists by splitting manually split_values = [item.strip() for item in candidate.split(",") if item.strip()] if split_values: return split_values @@ -131,7 +57,7 @@ def parse_samples_query_values(raw_values: Optional[List[str]]) -> Optional[List return [candidate] # fetch gene expression data from the external bar eplant api -# either use the samples passed in or auto-fill the full list before calling the CGI +# either use the samples provided or auto-fill the list before calling the cgi def fetch_efp_data(datasource, gene_id, samples=None): # set up the external bar api url and basic query parameters base_url = "https://bar.utoronto.ca//eplant/cgi-bin/plantefp.cgi" @@ -140,10 +66,9 @@ def fetch_efp_data(datasource, gene_id, samples=None): ("id", gene_id), ("format", "json"), ] - samples_applied = False # tracks whether we hinted the CGI with explicit samples + samples_applied = False # track whether we hinted the cgi with explicit samples - # handle optional sample filtering parameter - # when provided, expect a list of sample ids collected from the query params + # handle optional sample filtering and expect a normalized list of sample ids if samples: cleaned_samples = [sample.strip() for sample in samples if isinstance(sample, str) and sample.strip()] if cleaned_samples: @@ -157,29 +82,28 @@ def fetch_efp_data(datasource, gene_id, samples=None): query_params.append(("samples", json.dumps(samples))) samples_applied = True else: - # no metadata entry means we let the CGI decide which default samples to use + # no metadata entry means the cgi decides which default samples to use print(f"[warn] no samples found for datasource {datasource}") - # make exactly one http get request to the bar eplant cgi (packs every sample into this call) + # make exactly one http get request to the bar eplant cgi with every sample packed in response = requests.get(base_url, params=query_params) url_called = response.url # check if the request failed with an http error code if not response.ok: - # propagate error status so clients see the same HTTP code the CGI returned + # propagate error status so clients see the same http code the cgi returned return {"success": False, "error": f"bar returned {response.status_code} for url {url_called}"}, response.status_code - # attempt to parse json response and extract data array + # attempt to parse json response and extract the data array try: data = response.json() if isinstance(data, dict) and "data" in data: data = data["data"] except Exception: - # remote endpoint occasionally emits HTML error pages—treat them as no data + # remote endpoint occasionally emits html error pages so treat them as no data data = [] - # if no results returned with samples, retry without sample filtering - # if filtering wiped out the response, retry once without sample hints + # if no results returned with samples, retry once without sample filtering if (not data or data == []) and samples_applied: retry_params = [ ("datasource", datasource), @@ -209,24 +133,22 @@ def fetch_efp_data(datasource, gene_id, samples=None): "success": True, "url_called": url_called, "record_count": len(data) if isinstance(data, list) else 0, - "data": data # payload mirrors what the real CGI would have returned + "data": data # payload mirrors what the real cgi would have returned } -# load all available samples for a datasource using our metadata json -# includes hardcoded fallbacks for specific views when the json is missing +# load all available samples for a datasource using the metadata json and fallbacks def get_all_samples_for_view(datasource: str): - # point at the metadata json that was scraped from the eFP site - # during tests this file lives in the repo, so os.getcwd() resolves correctly + # point at the scraped metadata json so tests resolve it from the repo path = os.path.join(os.getcwd(), "data/efp_info/efp_species_view_info.json") - # check for specific datasources that need hardcoded samples + # check for datasources that need hardcoded samples if datasource == "root_Schaefer_lab": - # this dataset is missing from the scraped metadata, so we pin a curated set + # this dataset is missing from the scraped metadata so we pin a curated set print("[info] using hardcoded fallback samples for root_Schaefer_lab") return ["WTCHG_203594_01","WTCHG_203594_05","WTCHG_203839_04","WTCHG_203594_03","WTCHG_203594_07","WTCHG_203839_06","WTCHG_203839_01","WTCHG_203594_10","WTCHG_203839_08","WTCHG_129187_01","WTCHG_129189_01","WTCHG_129190_01","WTCHG_129187_03","WTCHG_129189_03","WTCHG_129190_03","WTCHG_129187_05","WTCHG_129189_05","WTCHG_129187_07","WTCHG_131167_01","WTCHG_125416_01","WTCHG_129190_05","WTCHG_131167_03","WTCHG_125416_03","WTCHG_129190_07","WTCHG_131167_05","WTCHG_125416_05","WTCHG_129189_07"] if datasource == "atgenexp_stress": - # AtGenExp stress views still rely on the JSON metadata but we keep a minimal fallback + # atgenexp stress views still rely on the json metadata so we keep a minimal fallback print("[info] using fallback arabidopsis samples from json spec") return ["AtGen_6_0011", "AtGen_6_0012", "AtGen_6_0021", "AtGen_6_0022", "AtGen_6_0711", "AtGen_6_0712", "AtGen_6_0721", "AtGen_6_0722" @@ -246,8 +168,7 @@ def get_all_samples_for_view(datasource: str): print(f"[error] unable to read json: {e}") return [] - # search through all species and views to find matching datasource - # the metadata format is nested (species -> views -> groups -> treatments) + # search through all species and views to find a matching datasource for species, obj in metadata.items(): views = obj.get("data", {}).get("views", {}) for vname, vinfo in views.items(): @@ -264,195 +185,22 @@ def get_all_samples_for_view(datasource: str): print(f"[warn] datasource {datasource} not found in json") return [] -# convert arabidopsis agi gene id (like AT1G01010) to probeset id -# queries the lookup table to find the most recent mapping -def agi_to_probset(gene_id: str): - try: - # build query to find most recent probeset for this agi - subquery = ( - db.select(AtAgiLookup.probeset) - .where(AtAgiLookup.agi == gene_id.upper()) - .order_by(AtAgiLookup.date.desc()) - .limit(1) - .subquery() - ) - - sq_query = db.session.query(subquery) - if sq_query.count() > 0: - # safest pick is the newest mapping because the array design changed over time - return sq_query[0][0] - else: - return None - except Exception as e: - print(f"[error] AGI to probeset conversion failed {e}") - return None - -# dynamically query any eFP database using the schema catalog above -# this replaces dozens of per-database ORM classes with one shared query path -def query_efp_database_dynamic(database: str, gene_id: str, sample_ids=None): - try: - database = str(database) - gene_id = str(gene_id) - - # look up how this database stores genes/samples so the generic query knows which columns to use - schema = DYNAMIC_DATABASE_SCHEMAS.get(database) - if not schema: - return { - "success": False, - "error": ( - f"Database '{database}' is not supported. " - f"Select one of: {', '.join(sorted(DYNAMIC_DATABASE_SCHEMAS.keys()))}" - ), - "error_code": 400, - } - - # decide which identifier should be used for the WHERE clause - query_id = gene_id - probset_display = None # used to echo what identifier we ultimately queried with - upper_id = gene_id.upper() - is_agi_id = upper_id.startswith("AT") and "G" in upper_id - - if is_agi_id: - # reject invalid AGI formatting up front before hitting the database - if not BARUtils.is_arabidopsis_gene_valid(upper_id): - return { - "success": False, - "error": "Invalid Arabidopsis gene ID format", - "error_code": 400, - } - - if schema["identifier_type"] == "probeset": - # older microarray mirrors store probeset-only identifiers - # some microarray mirrors still store probeset ids, so translate AGIs on the fly - probset = agi_to_probset(upper_id) - if not probset: - return { - "success": False, - "error": f"Could not find probeset for gene {gene_id}", - "error_code": 404, - } - query_id = probset - probset_display = probset - print(f"[info] Converted {gene_id} to probeset {query_id} for {database}") - else: - query_id = upper_id - probset_display = upper_id - - # build the full path to the requested database file (sqlite mirror on disk) - # tests ship trimmed fixtures, but production deployments still point to MySQL binds - db_path = DATABASE_DIR / schema["filename"] - - # try the real mysql bind first; if that fails, use the sqlite mirror - engine_candidates = [] - # candidate order matters: we prefer live binds but degrade gracefully to sqlite - if has_app_context(): - try: - bound_engine = db.get_engine(bind=database) - engine_candidates.append(("sqlalchemy_bind", bound_engine, False)) - except Exception as exc: - print(f"[warn] Unable to load SQLAlchemy bind for {database}: {exc}") - - if db_path.exists(): - # mirrors are SQLite files generated via scripts/build_sqlite_mirrors.py - sqlite_engine = create_engine(f"sqlite:///{db_path}") - engine_candidates.append(("sqlite_mirror", sqlite_engine, True)) - - if not engine_candidates: - return { - "success": False, - "error": f"Database {database} is not available (no active bind or sqlite mirror).", - "error_code": 404, - } - - where_clauses = [f"{schema['gene_column']} = :gene_id"] - # always parameterize values to avoid SQL injection and to cache query plans - params = {"gene_id": query_id} - - if sample_ids: - filtered = [s for s in sample_ids if s] - if filtered: - placeholders = [] - # build `IN (:sample_0, :sample_1, ...)` dynamically to keep it safe - for idx, sample in enumerate(filtered): - key = f"sample_{idx}" - placeholders.append(f":{key}") - params[key] = sample - where_clauses.append( - f"{schema['sample_column']} IN ({', '.join(placeholders)})" - ) - - # assemble one select statement that returns every sample/value for this gene - query_sql = text( - # select statements return a flat list of {sample, value} dicts for the caller - f"SELECT {schema['sample_column']} AS sample, {schema['value_column']} AS value " - f"FROM {schema['table']} " - f"WHERE {' AND '.join(where_clauses)}" - ) - - results = None - active_source = None - last_error = None - - for source_label, engine, dispose_after in engine_candidates: - try: - with Session(engine) as session: - results = session.execute(query_sql, params).all() - active_source = source_label # track whether MySQL or SQLite satisfied the query - break - except SQLAlchemyError as exc: - last_error = f"{source_label} failed: {exc}" - print(f"[warn] {last_error}") - except Exception as exc: - last_error = f"{source_label} unexpected failure: {exc}" - print(f"[warn] {last_error}") - finally: - if dispose_after: - # SQLite engines are cheap but keeping them open leaks file handles in tests - engine.dispose() - - if results is None: - return { - "success": False, - "error": ( - f"Database query failed for {database}. " - f"{'Last error: ' + last_error if last_error else ''}" - ).strip(), - "error_code": 500, - } - - if not results: - # returning 404 keeps parity with the legacy API response for missing genes - return { - "success": False, - "error": ( - f"No expression data found for {gene_id} " - f"(query identifier: {query_id})" - ), - "error_code": 404, - } - - # normalize the payload to match the eFP json structure the frontend expects - expression_data = [{"name": row.sample, "value": str(row.value)} for row in results] - # str() coercion keeps parity with the remote CGI which serializes numbers as strings +def _infer_default_db_credentials(): + """Derive MySQL connection info for the simple eFP datasets from the configured binds.""" + binds = current_app.config.get("SQLALCHEMY_BINDS") or {} + for db_name in SIMPLE_EFP_DATABASE_SCHEMAS.keys(): + uri = binds.get(db_name) + if not uri: + continue + url = make_url(uri) return { - "success": True, - "gene_id": gene_id, - "probset_id": probset_display or query_id, - "database": database, - "record_count": len(expression_data), - "data": expression_data, - } - - except Exception as e: - error_trace = traceback.format_exc() - # printing the trace means docker logs show full context without leaking to client - print(f"[error] Database query exception: {error_trace}") - return { - "success": False, - "error": f"Database query failed: {str(e)}", - "error_code": 500 + "host": url.host or "localhost", + "port": url.port or 3306, + "user": url.username or "root", + "password": url.password or "", } + raise ValueError("No SQLAlchemy bind configured for the simple eFP databases.") # rest endpoint that proxies requests to the external bar eplant api # supports urls like /efp_proxy/values/atgenexp_stress/AT1G01010 @@ -531,5 +279,66 @@ def get(self, database, gene_id): else: return result, result.get("error_code", 500) + +@efp_proxy_ns.route("/bootstrap/simple") +@efp_proxy_ns.doc( + description="Create or update the simple eFP MySQL databases using the in-memory schema definitions.", + params={ + "host": "Optional MySQL hostname override. Defaults to the host defined in SQLALCHEMY_BINDS.", + "port": "Optional MySQL port override. Defaults to the port defined in SQLALCHEMY_BINDS.", + "user": "Optional MySQL username override. Defaults to the username defined in SQLALCHEMY_BINDS.", + "password": "Optional MySQL password override. Defaults to the password defined in SQLALCHEMY_BINDS.", + "databases": "Optional list of database names to bootstrap. Defaults to every simple database.", + }, +) +class EFPSimpleBootstrap(Resource): + def post(self): + payload = request.get_json(silent=True) or {} + try: + defaults = _infer_default_db_credentials() + except ValueError as exc: + return {"success": False, "error": str(exc)}, 500 + + host = payload.get("host") or defaults["host"] + try: + port_value = payload.get("port") + port = int(port_value) if port_value is not None else int(defaults["port"]) + except (TypeError, ValueError): + return {"success": False, "error": "port must be an integer"}, 400 + user = payload.get("user") or defaults["user"] + password = payload.get("password") or defaults["password"] + + databases = payload.get("databases") + if databases is not None: + if not isinstance(databases, list) or not all(isinstance(item, str) for item in databases): + return {"success": False, "error": "databases must be a list of names."}, 400 + + try: + results = bootstrap_simple_efp_databases( + host=host, + port=port, + user=user, + password=password, + databases=databases, + ) + except ValueError as exc: + return {"success": False, "error": str(exc)}, 400 + except SQLAlchemyError as exc: + return {"success": False, "error": str(exc)}, 500 + + model_info = [ + {"database": name, "model": model.__name__} + for name, model in SIMPLE_EFP_SAMPLE_MODELS.items() + if databases is None or name in databases + ] + + return { + "success": True, + "databases": results, + "models": model_info, + "note": "Simple eFP databases are materialized in MySQL while SQLAlchemy models remain dynamic.", + }, 200 + efp_proxy_ns.add_resource(EFPValues, '/values//') efp_proxy_ns.add_resource(EFPExpression, '/expression//') +efp_proxy_ns.add_resource(EFPSimpleBootstrap, '/bootstrap/simple') diff --git a/api/resources/microarray_gene_expression.py b/api/resources/microarray_gene_expression.py index df1022c..5dc9c33 100644 --- a/api/resources/microarray_gene_expression.py +++ b/api/resources/microarray_gene_expression.py @@ -2,11 +2,14 @@ from markupsafe import escape from api import db from api.models.annotations_lookup import AtAgiLookup -from api.models.arabidopsis_ecotypes import SampleData as EcotypesSampleData +from api.models.efp_dynamic import SIMPLE_EFP_SAMPLE_MODELS from api.utils.bar_utils import BARUtils from api.utils.world_efp_utils import WorldeFPUtils import json +# pull the dynamic model so this resource stays in sync with the schema catalog +EcotypesSampleData = SIMPLE_EFP_SAMPLE_MODELS["arabidopsis_ecotypes"] + microarray_gene_expression = Namespace( "Microarray Gene Expression", description="Microarray (probe-based) Gene Expression data from the BAR Databases", @@ -294,4 +297,4 @@ def get(self, species="", view=""): "species": species, "view": view, "groups": species_data["views"][view]["groups"] - }) \ No newline at end of file + }) diff --git a/api/resources/rnaseq_gene_expression.py b/api/resources/rnaseq_gene_expression.py index 79cde39..205ba96 100644 --- a/api/resources/rnaseq_gene_expression.py +++ b/api/resources/rnaseq_gene_expression.py @@ -2,26 +2,10 @@ from flask_restx import Namespace, Resource, fields from flask import request from api.utils.bar_utils import BARUtils +from api.services.efp_data import query_efp_database_dynamic +from api.models.efp_schemas import SIMPLE_EFP_DATABASE_SCHEMAS from marshmallow import Schema, ValidationError, fields as marshmallow_fields from markupsafe import escape -from api import db -from api.models.arachis import SampleData as Arachis -from api.models.cannabis import SampleData as Cannabis -from api.models.dna_damage import SampleData as DNADamage -from api.models.embryo import SampleData as Embryo -from api.models.germination import SampleData as Germination -from api.models.kalanchoe import SampleData as Kalanchoe -from api.models.klepikova import SampleData as Klepikova -from api.models.phelipanche import SampleData as Phelipanche -from api.models.physcomitrella_db import SampleData as Physcomitrella -from api.models.selaginella import SampleData as Selaginella -from api.models.shoot_apex import SampleData as ShootApex -from api.models.silique import SampleData as Silique -from api.models.single_cell import SampleData as SingleCell -from api.models.strawberry import SampleData as Strawberry -from api.models.striga import SampleData as Striga -from api.models.triphysaria import SampleData as Triphysaria -from sqlalchemy import and_ rnaseq_gene_expression = Namespace( "RNA-Seq Gene Expression", @@ -29,7 +13,27 @@ path="/rnaseq_gene_expression", ) -# I think this is only needed for Swagger UI POST +# validators stay here so schema metadata can reference them +SPECIES_VALIDATORS = { + "arabidopsis": BARUtils.is_arabidopsis_gene_valid, + "arachis": BARUtils.is_arachis_gene_valid, + "cannabis": BARUtils.is_cannabis_gene_valid, + "kalanchoe": BARUtils.is_kalanchoe_gene_valid, + "selaginella": BARUtils.is_selaginella_gene_valid, + "strawberry": BARUtils.is_strawberry_gene_valid, + "striga": BARUtils.is_striga_gene_valid, + "triphysaria": BARUtils.is_triphysaria_gene_valid, + "phelipanche": BARUtils.is_phelipanche_gene_valid, + "physcomitrella": BARUtils.is_physcomitrella_gene_valid, +} + +# metadata mirrors the schema catalog so validation stays in sync +DATABASE_METADATA = { + name: spec.get("metadata") or {} + for name, spec in SIMPLE_EFP_DATABASE_SCHEMAS.items() +} + +# this is only needed for swagger ui post examples gene_expression_request_fields = rnaseq_gene_expression.model( "GeneExpression", { @@ -48,7 +52,7 @@ ) -# Validation is done in a different way to keep things simple +# validation is done manually to keep things simple class RNASeqSchema(Schema): species = marshmallow_fields.String(required=True) database = marshmallow_fields.String(required=True) @@ -59,146 +63,43 @@ class RNASeqSchema(Schema): class RNASeqUtils: @staticmethod def get_data(species, database, gene_id, sample_ids=None): - """This function is used to query the database for gene expression - :param species: name of species - :param database: name of BAR database - :param gene_id: gene id in the data_probeset column - :param sample_ids: sample ids in the data_bot_id column - :return: dict gene expression data - """ + """query the database for gene expression values""" if sample_ids is None: sample_ids = [] - data = {} + data: dict = {} - # Set species and check gene ID format + # validate species selection and gene id format species = species.lower() - if species == "arabidopsis": - if not BARUtils.is_arabidopsis_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "arachis": - if not BARUtils.is_arachis_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "cannabis": - if not BARUtils.is_cannabis_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "kalanchoe": - if not BARUtils.is_kalanchoe_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "selaginella": - if not BARUtils.is_selaginella_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "strawberry": - if not BARUtils.is_strawberry_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "striga": - if not BARUtils.is_striga_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "triphysaria": - if not BARUtils.is_triphysaria_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "phelipanche": - if not BARUtils.is_phelipanche_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - elif species == "physcomitrella": - if not BARUtils.is_physcomitrella_gene_valid(gene_id): - return {"success": False, "error": "Invalid gene id", "error_code": 400} - else: + gene_validator = SPECIES_VALIDATORS.get(species) + if not gene_validator: return {"success": False, "error": "Invalid species", "error_code": 400} - # Set database database = database.lower() - if database == "arachis": - table = Arachis - # Example: Pattee_8_Seed - sample_regex = re.compile(r"^[\D\d_]{1,30}|MED_CTRL$", re.I) - - elif database == "cannabis": - table = Cannabis - # Example: PK-PFLW - sample_regex = re.compile(r"^PK-\D{1,4}|MED_CTRL$", re.I) - - elif database == "dna_damage": - table = DNADamage - # Another insane regex! - sample_regex = re.compile(r"^\D{1,3}.{1,30}_plus_Y|\D{1,3}.{1,30}_minus_Y|Med_CTRL$", re.I) - - elif database == "embryo": - table = Embryo - sample_regex = re.compile(r"^\D{1,3}_\d$|Med_CTRL$", re.I) - - elif database == "germination": - table = Germination - sample_regex = re.compile(r"^\d{1,3}\D{1,4}_\d{1,3}|harvest_\d|Med_CTRL$", re.I) - - elif database == "kalanchoe": - table = Kalanchoe - # Example: FRL_Dusk_rep3 - sample_regex = re.compile(r"^\D{1,4}_\D{1,5}_rep\d|MED_CTRL$", re.I) - - elif database == "klepikova": - table = Klepikova - sample_regex = re.compile(r"^SRR\d{1,9}|Med_CTRL$", re.I) - - elif database == "phelipanche": - table = Phelipanche - # Example: Pre-Emergence_from_Soil_Shoots - sample_regex = re.compile(r"^[a-z_-]{1,35}|MED_CTRL$", re.I) - - elif database == "physcomitrella_db": - table = Physcomitrella - # Example: Sporophyte_S1 - sample_regex = re.compile(r"^[a-z_123]{1,15}|MED_CTRL$", re.I) - - elif database == "selaginella": - table = Selaginella - # Insane regex! - sample_regex = re.compile(r"^[\D\d]{1,33}|MED_CTRL$", re.I) - - elif database == "shoot_apex": - table = ShootApex - sample_regex = re.compile(r"^\D{1,5}\d{0,2}|MED_CTRL$", re.I) - - elif database == "silique": - table = Silique - # Insane regex! Needs work - sample_regex = re.compile(r"^\d{1,3}_dap.{1,58}_R1_001|Med_CTRL$", re.I) - - elif database == "single_cell": - table = SingleCell - # Example: cluster0_WT1.ExprMean - sample_regex = re.compile(r"^\D+\d+_WT\d+.ExprMean|MED_CTRL$", re.I) - - elif database == "strawberry": - table = Strawberry - # Example: Perianth_5-6_A - sample_regex = re.compile(r"^\D{1,12}_.{1,8}_\D{1,2}|MED_CTRL$", re.I) - - elif database == "striga": - table = Striga - # Example: Reproductive_Structures - sample_regex = re.compile(r"^\D{1,35}|MED_CTRL$", re.I) - - elif database == "triphysaria": - table = Triphysaria - # Example: Roots_in_Late_Post_Attachment - sample_regex = re.compile(r"^[a-z_]{1,35}|MED_CTRL$", re.I) + db_metadata = DATABASE_METADATA.get(database, {}) + db_species = db_metadata.get("species") + if db_species and db_species != species: + return {"success": False, "error": "Invalid species", "error_code": 400} - else: + if not gene_validator(gene_id): + return {"success": False, "error": "Invalid gene id", "error_code": 400} + + if database not in DATABASE_METADATA: return {"success": False, "error": "Invalid database", "error_code": 400} - # Now query the database - # We are querying only some columns because full indexes are made on some columns, now the whole table - if len(sample_ids) == 0 or sample_ids is None: - rows = db.session.execute( - db.select(table.data_probeset_id, table.data_bot_id, table.data_signal).where( - table.data_probeset_id == gene_id - ) - ).all() - for row in rows: - data[row[1]] = row[2] + # sample validation is driven by metadata so regex updates live in one place + sample_pattern = db_metadata.get("sample_regex") + if not sample_pattern: + return { + "success": False, + "error": f"Sample validation metadata missing for database {database}", + "error_code": 500, + } - else: - # Validate all samples + regex_flags = re.I if db_metadata.get("sample_regex_case_insensitive", True) else 0 + sample_regex = re.compile(sample_pattern, regex_flags) + + # validate samples if the caller provided any + if sample_ids: for sample_id in sample_ids: if not sample_regex.search(sample_id): return { @@ -207,16 +108,30 @@ def get_data(species, database, gene_id, sample_ids=None): "error_code": 400, } - rows = db.session.execute( - db.select(table.data_probeset_id, table.data_bot_id, table.data_signal).where( - and_( - table.data_probeset_id == gene_id, - table.data_bot_id.in_(sample_ids), - ) - ) - ).all() - for row in rows: - data[row[1]] = row[2] + query_result = query_efp_database_dynamic( + database, + gene_id, + sample_ids=sample_ids or None, + allow_empty_results=True, + sample_case_insensitive=db_metadata.get("sample_case_insensitive_query", True), + ) + + if not query_result["success"]: + return { + "success": False, + "error": query_result.get("error", "Database query failed"), + "error_code": query_result.get("error_code", 500), + } + + for entry in query_result.get("data", []): + sample_name = entry.get("name") + value = entry.get("value") + if sample_name is None: + continue + try: + data[sample_name] = float(value) + except (TypeError, ValueError): + data[sample_name] = value return {"success": True, "data": data} @@ -225,10 +140,10 @@ def get_data(species, database, gene_id, sample_ids=None): class PostRNASeqExpression(Resource): @rnaseq_gene_expression.expect(gene_expression_request_fields) def post(self): - """This end point returns gene expression data for a single gene and multiple samples.""" + """return gene expression data for a single gene and a list of samples""" json_data = request.get_json() - # Validate json + # validate json payload try: json_data = RNASeqSchema().load(json_data) except ValidationError as err: @@ -242,7 +157,7 @@ def post(self): results = RNASeqUtils.get_data(species, database, gene_id, sample_ids) if results["success"]: - # Return results if there are data + # return results when rows exist if len(results["data"]) > 0: return BARUtils.success_exit(results["data"]) else: @@ -257,8 +172,8 @@ class GetRNASeqGeneExpression(Resource): @rnaseq_gene_expression.param("database", _in="path", default="single_cell") @rnaseq_gene_expression.param("gene_id", _in="path", default="At1g01010") def get(self, species="", database="", gene_id=""): - """This end point returns RNA-Seq gene expression data""" - # Variables + """return rna-seq gene expression data""" + # sanitize path inputs species = escape(species) database = escape(database) gene_id = escape(gene_id) @@ -266,7 +181,7 @@ def get(self, species="", database="", gene_id=""): results = RNASeqUtils.get_data(species, database, gene_id) if results["success"]: - # Return results if there are data + # return results when rows exist if len(results["data"]) > 0: return BARUtils.success_exit(results["data"]) else: @@ -282,8 +197,8 @@ class GetRNASeqGeneExpressionSample(Resource): @rnaseq_gene_expression.param("gene_id", _in="path", default="At1g01010") @rnaseq_gene_expression.param("sample_id", _in="path", default="cluster0_WT1.ExprMean") def get(self, species="", database="", gene_id="", sample_id=""): - """This end point returns RNA-Seq gene expression data""" - # Variables + """return rna-seq gene expression for a specific sample""" + # sanitize path inputs species = escape(species) database = escape(database) gene_id = escape(gene_id) @@ -292,7 +207,7 @@ def get(self, species="", database="", gene_id="", sample_id=""): results = RNASeqUtils.get_data(species, database, gene_id, [sample_id]) if results["success"]: - # Return results if there are data + # return results when rows exist if len(results["data"]) > 0: return BARUtils.success_exit(results["data"]) else: diff --git a/api/services/__init__.py b/api/services/__init__.py new file mode 100644 index 0000000..83476a9 --- /dev/null +++ b/api/services/__init__.py @@ -0,0 +1,3 @@ +"""Service layer helpers shared across multiple resources.""" + +__all__ = [] diff --git a/api/services/efp_bootstrap.py b/api/services/efp_bootstrap.py new file mode 100644 index 0000000..27e566a --- /dev/null +++ b/api/services/efp_bootstrap.py @@ -0,0 +1,128 @@ +""" +Utilities to bootstrap the simple eFP databases directly from the shared schema +definitions. Shared by the CLI script and the Flask endpoint so we only maintain +one implementation. +""" + +from __future__ import annotations + +from typing import Dict, Iterable, List + +from sqlalchemy import Column, Index, MetaData, Table, create_engine, text +from sqlalchemy.dialects.mysql import FLOAT, INTEGER, TEXT, VARCHAR +from sqlalchemy.engine import URL + +from api.models.efp_schemas import SIMPLE_EFP_DATABASE_SCHEMAS + + +def _column_type(column_spec): + """Return the MySQL column type for a schema entry.""" + col_type = column_spec.get("type") + if col_type == "string": + return VARCHAR(column_spec["length"]) + if col_type == "integer": + return INTEGER(unsigned=column_spec.get("unsigned", False)) + if col_type == "float": + # explicit mysql float keeps parity with the original dumps + return FLOAT() + if col_type == "text": + return TEXT() + raise ValueError(f"Unsupported column type: {col_type}") + + +def _build_table(metadata: MetaData, spec, db_name: str) -> Table: + columns = [] + for column in spec["columns"]: + kwargs = {"nullable": column.get("nullable", True)} + if column.get("primary_key"): + kwargs["primary_key"] = True + default_value = column.get("default") + if default_value is not None: + if isinstance(default_value, str): + kwargs["server_default"] = text(f"'{default_value}'") + else: + kwargs["server_default"] = text(str(default_value)) + + columns.append(Column(column["name"], _column_type(column), **kwargs)) + + table = Table(spec["table_name"], metadata, *columns, mysql_charset=spec.get("charset")) + index_cols = spec.get("index") or [] + if index_cols: + Index(f"ix_{db_name}_{'_'.join(index_cols)}", *[table.c[col] for col in index_cols]) + return table + + +def _build_url(host: str, port: int, user: str, password: str, database: str | None = None) -> URL: + return URL.create( + drivername="mysql+mysqldb", + username=user, + password=password, + host=host, + port=port, + database=database, + ) + + +def ensure_database(server_url: URL, db_name: str, charset: str) -> None: + server_engine = create_engine(server_url) + with server_engine.begin() as conn: + conn.execute(text(f"CREATE DATABASE IF NOT EXISTS `{db_name}` DEFAULT CHARACTER SET {charset}")) + + +def ensure_schema(db_url: URL, spec, db_name: str) -> Dict[str, object]: + metadata = MetaData() + table = _build_table(metadata, spec, db_name) + engine = create_engine(db_url) + metadata.create_all(engine, checkfirst=True) + + seed_rows = spec.get("seed_rows") or [] + inserted = 0 + if seed_rows: + with engine.connect() as conn: + count = conn.execute(text(f"SELECT COUNT(1) FROM {table.name}")).scalar() or 0 + if count == 0: + with engine.begin() as write_conn: + write_conn.execute(table.insert(), seed_rows) + inserted = len(seed_rows) + + return {"table": table.name, "seeded_rows": inserted} + + +def bootstrap_simple_efp_databases( + *, + host: str, + port: int, + user: str, + password: str, + databases: Iterable[str] | None = None, +) -> List[Dict[str, object]]: + """ + Ensure that all requested simple eFP databases exist in MySQL and their schema + matches the definitions in SIMPLE_EFP_DATABASE_SCHEMAS. + """ + + results: List[Dict[str, object]] = [] + target_dbs = list(databases) if databases is not None else list(SIMPLE_EFP_DATABASE_SCHEMAS.keys()) + + server_url = _build_url(host, port, user, password, database=None) + for db_name in target_dbs: + if db_name not in SIMPLE_EFP_DATABASE_SCHEMAS: + raise ValueError(f"Unknown simple eFP database: {db_name}") + + spec = SIMPLE_EFP_DATABASE_SCHEMAS[db_name] + charset = spec.get("charset", "utf8mb4") + ensure_database(server_url, db_name, charset) + db_url = _build_url(host, port, user, password, database=db_name) + schema_result = ensure_schema(db_url, spec, db_name) + results.append( + { + "database": db_name, + "table": schema_result["table"], + "seeded_rows": schema_result["seeded_rows"], + } + ) + + return results + + +__all__ = ["bootstrap_simple_efp_databases"] diff --git a/api/services/efp_data.py b/api/services/efp_data.py new file mode 100644 index 0000000..46e70b8 --- /dev/null +++ b/api/services/efp_data.py @@ -0,0 +1,274 @@ +""" +shared helper utilities for querying efp databases +""" + +from __future__ import annotations + +import traceback +from pathlib import Path +from typing import Any, Dict, Iterable, List, Optional, Tuple + +from flask import has_app_context +from sqlalchemy import create_engine, text +from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.engine import Engine +from sqlalchemy.orm import Session + +from api import db +from api.models.annotations_lookup import AtAgiLookup +from api.models.bar_utils import BARUtils +from api.models.efp_schemas import SIMPLE_EFP_DATABASE_SCHEMAS + +# absolute path to the config/databases directory where the sqlite mirrors live +ROOT_DIR = Path(__file__).resolve().parents[2] +DATABASE_DIR = ROOT_DIR / "config" / "databases" + +DEFAULT_SAMPLE_SCHEMA = { + "table": "sample_data", + "gene_column": "data_probeset_id", + "sample_column": "data_bot_id", + "value_column": "data_signal", +} + +# manual list covers datasets still backed by shipped dumps +_MANUAL_DEFAULT_DATABASES = [ + "canola_nssnp", + "eplant2", + "eplant_poplar", + "eplant_rice", + "eplant_soybean", + "eplant_tomato", + "fastpheno", + "homologs_db", + "interactions_vincent_v2", + "llama3", + "poplar_nssnp", + "rice_interactions", + "soybean_nssnp", + "tomato_nssnp", + "tomato_sequence", +] + +MANUAL_DATABASE_SCHEMAS = { + name: { + **DEFAULT_SAMPLE_SCHEMA, + "filename": f"{name}.db", + "identifier_type": "agi", + "metadata": {}, + } + for name in _MANUAL_DEFAULT_DATABASES +} + +MANUAL_DATABASE_SCHEMAS["sample_data"] = { + **DEFAULT_SAMPLE_SCHEMA, + "filename": "sample_data.db", + "identifier_type": "probeset", + "metadata": {"species": "arabidopsis"}, +} + + +def _build_schema_catalog() -> Dict[str, Dict[str, Any]]: + # stitch together the python schemas + legacy dumps into one lookup table + catalog: Dict[str, Dict[str, Any]] = {} + for db_name, spec in SIMPLE_EFP_DATABASE_SCHEMAS.items(): + schema = dict(DEFAULT_SAMPLE_SCHEMA) + schema.update( + { + "filename": f"{db_name}.db", + "identifier_type": spec.get("identifier_type", "agi"), + "metadata": spec.get("metadata") or {}, + } + ) + catalog[db_name] = schema + + for db_name, schema in MANUAL_DATABASE_SCHEMAS.items(): + catalog[db_name] = dict(schema) + + return catalog + + +DYNAMIC_DATABASE_SCHEMAS = _build_schema_catalog() + + +def agi_to_probset(gene_id: str) -> Optional[str]: + """convert an arabidopsis agi to its probeset when needed""" + try: + subquery = ( + db.select(AtAgiLookup.probeset) + .where(AtAgiLookup.agi == gene_id.upper()) + .order_by(AtAgiLookup.date.desc()) + .limit(1) + .subquery() + ) + + sq_query = db.session.query(subquery) + if sq_query.count() > 0: + # safest pick is the newest mapping because the array design changed over time + return sq_query[0][0] + return None + except Exception as exc: # pragma: no cover - defensive logging path + print(f"[error] agi to probeset conversion failed {exc}") + return None + + +def _iter_engine_candidates(database: str) -> Iterable[Tuple[str, Engine, bool]]: + """yield engine candidates (bind first, then sqlite mirror)""" + # prefer live mysql binds but fall back to sqlite mirrors when needed + db_path = DATABASE_DIR / DYNAMIC_DATABASE_SCHEMAS[database]["filename"] + if has_app_context(): + try: + bound_engine = db.get_engine(bind=database) + yield ("sqlalchemy_bind", bound_engine, False) + except Exception as exc: + print(f"[warn] unable to load sqlalchemy bind for {database}: {exc}") + + if db_path.exists(): + sqlite_engine = create_engine(f"sqlite:///{db_path}") + yield ("sqlite_mirror", sqlite_engine, True) + + +def query_efp_database_dynamic( + database: str, + gene_id: str, + sample_ids: Optional[List[str]] = None, + allow_empty_results: bool = False, + sample_case_insensitive: bool = False, +) -> Dict[str, object]: + """dynamically query any efp database using the shared schema catalog""" + try: + database = str(database) + gene_id = str(gene_id) + + schema = DYNAMIC_DATABASE_SCHEMAS.get(database) + if not schema: + return { + "success": False, + "error": ( + f"Database '{database}' is not supported. " + f"Select one of: {', '.join(sorted(DYNAMIC_DATABASE_SCHEMAS.keys()))}" + ), + "error_code": 400, + } + + query_id = gene_id + probset_display = None + gene_case_insensitive = False + upper_id = gene_id.upper() + is_agi_id = upper_id.startswith("AT") and "G" in upper_id + + if is_agi_id: + if not BARUtils.is_arabidopsis_gene_valid(upper_id): + return { + "success": False, + "error": "Invalid Arabidopsis gene ID format", + "error_code": 400, + } + + if schema["identifier_type"] == "probeset": + probset = agi_to_probset(upper_id) + if not probset: + return { + "success": False, + "error": f"Could not find probeset for gene {gene_id}", + "error_code": 404, + } + query_id = probset + probset_display = probset + print(f"[info] Converted {gene_id} to probeset {query_id} for {database}") + else: + query_id = upper_id + gene_case_insensitive = True + probset_display = upper_id + + engine_candidates = list(_iter_engine_candidates(database)) + if not engine_candidates: + return { + "success": False, + "error": f"Database {database} is not available (no active bind or sqlite mirror).", + "error_code": 404, + } + + gene_column_expr = ( + f"UPPER({schema['gene_column']})" if gene_case_insensitive else schema["gene_column"] + ) + params = {"gene_id": query_id.upper() if gene_case_insensitive else query_id} + where_clauses = [f"{gene_column_expr} = :gene_id"] + + if sample_ids: + filtered = [s for s in sample_ids if s] + if filtered: + sample_column_expr = ( + f"UPPER({schema['sample_column']})" + if sample_case_insensitive + else schema["sample_column"] + ) + sample_conditions = [] + for idx, sample in enumerate(filtered): + key = f"sample_{idx}" + params[key] = sample.upper() if sample_case_insensitive else sample + sample_conditions.append(f"{sample_column_expr} = :{key}") + where_clauses.append(f"({' OR '.join(sample_conditions)})") + + query_sql = text( + f"SELECT {schema['sample_column']} AS sample, {schema['value_column']} AS value " + f"FROM {schema['table']} " + f"WHERE {' AND '.join(where_clauses)}" + ) + + results = None + last_error = None + + for source_label, engine, dispose_after in engine_candidates: + try: + with Session(engine) as session: + results = session.execute(query_sql, params).all() + break + except SQLAlchemyError as exc: + last_error = f"{source_label} failed: {exc}" + print(f"[warn] {last_error}") + except Exception as exc: + last_error = f"{source_label} unexpected failure: {exc}" + print(f"[warn] {last_error}") + finally: + if dispose_after: + engine.dispose() + + if results is None: + return { + "success": False, + "error": ( + f"Database query failed for {database}. " + f"{'Last error: ' + last_error if last_error else ''}" + ).strip(), + "error_code": 500, + } + + if not results and not allow_empty_results: + return { + "success": False, + "error": ( + f"No expression data found for {gene_id} " + f"(query identifier: {query_id})" + ), + "error_code": 404, + } + + expression_data = [{"name": row.sample, "value": str(row.value)} for row in results] + + return { + "success": True, + "gene_id": gene_id, + "probset_id": probset_display or query_id, + "database": database, + "record_count": len(expression_data), + "data": expression_data, + } + + except Exception as exc: + error_trace = traceback.format_exc() + print(f"[error] Database query exception: {error_trace}") + return { + "success": False, + "error": f"Database query failed: {str(exc)}", + "error_code": 500, + } diff --git a/config/init.sh b/config/init.sh index 8da8309..4365605 100755 --- a/config/init.sh +++ b/config/init.sh @@ -9,13 +9,13 @@ DB_PASS="root" # Load the data echo "Welcome to the BAR API. Running init!" +# Build simple eFP databases dynamically so we do not need static SQL dumps +python3 ./scripts/bootstrap_simple_efp_dbs.py --user "$DB_USER" --password "$DB_PASS" + mysql -u $DB_USER -p$DB_PASS < ./config/databases/annotations_lookup.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/arabidopsis_ecotypes.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/arachis.sql -mysql -u $DB_USER -p$DB_PASS < ./config/databases/cannabis.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/canola_nssnp.sql -mysql -u $DB_USER -p$DB_PASS < ./config/databases/dna_damage.sql -mysql -u $DB_USER -p$DB_PASS < ./config/databases/embryo.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/eplant2.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/eplant_poplar.sql mysql -u $DB_USER -p$DB_PASS < ./config/databases/eplant_rice.sql diff --git a/docs/efp_proxy.md b/docs/efp_proxy.md deleted file mode 100644 index ef6c12f..0000000 --- a/docs/efp_proxy.md +++ /dev/null @@ -1,115 +0,0 @@ -# eFP Proxy Guide - -This note documents how the new `/efp_proxy` endpoints work, why they satisfy the “one web call + one SQL query” requirement, and how to exercise them locally even without access to the production MySQL servers. - -## What This Implementation Delivers - -- **Single HTTP request** to BAR’s CGI: `/efp_proxy/values/{database}/{gene_id}` collects every sample (either from the `samples` query param or by auto-loading the list from `data/efp_info/efp_species_view_info.json`) and ships them to `https://bar.utoronto.ca/eplant/cgi-bin/plantefp.cgi` in one call. See `api/resources/efp_proxy.py` (function `fetch_efp_data`). -- **Single SQL query** for any mirrored database: `/efp_proxy/expression/{database}/{gene_id}` looks up the table/column names in a schema catalog and runs one `SELECT sample, value FROM sample_data WHERE gene_column = :gene_id` statement. No per-database ORM/models or branching logic are needed. -- **Dynamic database routing**: Every request first tries the live SQLAlchemy bind (`db.get_engine(bind=database)`), then falls back to the SQLite mirror you generate locally. The same code therefore works offline (using mirrors) and online (using the real DB) without any changes. -- **Consistent JSON payload**: Both endpoints output `[{"name": SAMPLE_ID, "value": SIGNAL}, …]`, so the frontend expects the same structure whether data came from the CGI or a local/remote database. - -## Key Code Highlights - -### One Web Call - -```python -def fetch_efp_data(datasource, gene_id, samples=None): - query_params = [ - ("datasource", datasource), - ("id", gene_id), - ("format", "json"), - ] - ... - response = requests.get(base_url, params=query_params) -``` - -- If `samples` are provided (repeat `?samples=foo&samples=bar` in the query string, or use the legacy JSON array), they are appended once. -- If `samples` is omitted, `get_all_samples_for_view` loads every sample for that datasource and adds that list. -- The request is made **exactly once**; if the CGI returns nothing we retry without the `samples` hint but still as a single call. -- Returned data already looks like `[{"name": "...", "value": "..."}]`. - -### One SQL Query - -```python -def query_efp_database_dynamic(database, gene_id, sample_ids=None): - schema = DYNAMIC_DATABASE_SCHEMAS[database] - db_path = DATABASE_DIR / schema["filename"] - engine_candidates = [] - try: - bound_engine = db.get_engine(bind=database) - engine_candidates.append(("sqlalchemy_bind", bound_engine, False)) - except Exception: - ... - if db_path.exists(): - sqlite_engine = create_engine(f"sqlite:///{db_path}") - engine_candidates.append(("sqlite_mirror", sqlite_engine, True)) - - query_sql = text( - f"SELECT {schema['sample_column']} AS sample, " - f"{schema['value_column']} AS value " - f"FROM {schema['table']} " - f"WHERE {schema['gene_column']} = :gene_id" - ) -``` - -- `DYNAMIC_DATABASE_SCHEMAS` is a simple dictionary (`{db_name: {table, gene_column, ...}}`). No per-database models are required for the endpoint. -- The helper first attempts the live bind (`sqlalchemy_bind`) and only if that fails does it open the SQLite mirror (`sqlite_mirror`). -- One SQL statement fetches every sample/value row for the requested gene and we normalize it into `[{"name": ..., "value": ...}]`. - -### Why You Might Not See “All Values” Locally - -- The repo ships *trimmed-down* `.sql` dumps (fixtures) inside `config/databases/*.sql`. When you build mirrors with `python scripts/build_sqlite_mirrors.py`, you are mirroring that limited data, so `/expression/klepikova/AT1G01010` only returns the single SRR row included in the dump (currently `SRR3581336`). The long `INSERT INTO sample_general_info ... SRR...` block is metadata; it doesn’t contain expression values. `/expression` only reads `sample_data`, because that table has the `data_signal` column required for output. -- The long `INSERT INTO sample_general_info ... SRR...` block is metadata; it doesn’t contain expression values. `/expression` only reads `sample_data`, because that table has the `data_signal` column required for output. -- As soon as you connect to the real MySQL databases (by running the dockerized MySQL or pointing `SQLALCHEMY_BINDS` at production), the bind succeeds first and you immediately get the full data set. - -## Workflow: Local Mirrors vs. Real Databases - -1. **Generate mirrors** (local dev only): - ```bash - python scripts/build_sqlite_mirrors.py klepikova sample_data - ``` - This produces `config/databases/klepikova.db`, etc. The endpoint automatically uses them when the MySQL bind isn’t available. - -2. **Run the API**: - ```bash - flask run # or docker compose up api - ``` - -3. **Test the endpoints**: - - External CGI with auto-loaded samples (one web call): - ``` - http://127.0.0.1:5000/efp_proxy/values/atgenexp_stress/AT1G01010 - http://127.0.0.1:5000/efp_proxy/values/root_Schaefer_lab/AT3G24650?samples=WTCHG_203594_01&samples=WTCHG_203594_05 - ``` - - Dynamic DB query (one SQL statement): - ``` - http://127.0.0.1:5000/efp_proxy/expression/klepikova/AT1G01010 - http://127.0.0.1:5000/efp_proxy/expression/sample_data/261585_at - ``` - -4. **Deploying with the real databases**: ensure `config/BAR_API.cfg` points to the production MySQL hosts. `query_efp_database_dynamic` will hit them via `db.get_engine(bind=database)`; the SQLite mirrors simply act as a fallback when you’re offline. - -## Static vs. Dynamic: What Changed - -- **Static approach** (old): every database needed its own model file (e.g., `api/models/klepikova.py`), controller logic, and SQL query. Adding a new dataset meant writing more Python and risking inconsistencies. -- **Dynamic approach** (new): - - We only maintain the simple schema catalog (table + column names per database). - - The same endpoint and SQL query cover every database. - - No new ORM classes are required for `/efp_proxy/expression`. (Other parts of the API still use those models, which is why the files remain in the repo.) - - Switching between local mirrors and live MySQL happens automatically. - -## Why We Still Can’t “Pull Everything” Locally - -- The SQLite mirrors you generate reflect whatever is inside the `.sql` dump—often a very small subset used by tests. -- Without the real MySQL dump, the endpoint physically can’t return rows that don’t exist in the mirror. This is a data limitation, not a code bug. -- Once hooked to the production database, the query returns all values in a single request/statement, fulfilling the original requirement. - -## Summary - -- `/efp_proxy/values` → ONE external web call, optional sample filtering. -- `/efp_proxy/expression` → ONE SQL query per request, dynamic schema lookup, automatic choice between live MySQL and local SQLite. -- Schema catalog + mirror script = no more per-database boilerplate. -- Full datasets appear as soon as the real databases are reachable; mirrors just keep development/testing running offline. - -This architecture hits the deliverables outlined in the project brief while keeping the codebase maintainable for future databases. diff --git a/scripts/bootstrap_simple_efp_dbs.py b/scripts/bootstrap_simple_efp_dbs.py new file mode 100644 index 0000000..583ac4c --- /dev/null +++ b/scripts/bootstrap_simple_efp_dbs.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" +bootstrap the simple efp databases from the shared schema definitions +""" + +from __future__ import annotations + +import argparse +import os + +from sqlalchemy.exc import SQLAlchemyError + +from api.services.efp_bootstrap import bootstrap_simple_efp_databases + + +def _default_host() -> str: + if os.environ.get("DB_HOST"): + return os.environ["DB_HOST"] + if os.environ.get("MYSQL_HOST"): + return os.environ["MYSQL_HOST"] + # inside docker compose the db host is bar_mysqldb; locally it is usually localhost + return "BAR_mysqldb" if os.environ.get("CI") else "localhost" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Create simple eFP MySQL databases from in-memory schemas.") + parser.add_argument("--host", default=_default_host(), help="MySQL hostname (default: %(default)s)") + parser.add_argument("--port", type=int, default=int(os.environ.get("DB_PORT", 3306)), help="MySQL port") + parser.add_argument("--user", default=os.environ.get("DB_USER", "root"), help="MySQL user") + parser.add_argument("--password", default=os.environ.get("DB_PASS", "root"), help="MySQL password") + parser.add_argument( + "--databases", + nargs="*", + help="Optional list of databases to bootstrap (defaults to every simple schema).", + ) + return parser.parse_args() + + +def main(): + args = parse_args() + results = bootstrap_simple_efp_databases( + host=args.host, + port=args.port, + user=args.user, + password=args.password, + databases=args.databases, + ) + for entry in results: + seeded = entry["seeded_rows"] + seed_msg = f"seeded {seeded} rows" if seeded else "no seed rows inserted" + print(f"[ok] ensured {entry['database']}.{entry['table']} ({seed_msg})") + + +if __name__ == "__main__": + try: + main() + except SQLAlchemyError as exc: + # match init.sh style output to keep ci logs readable + print(f"failed to initialize simple efp databases: {exc}") + raise diff --git a/tests/services/test_efp_data.py b/tests/services/test_efp_data.py new file mode 100644 index 0000000..75c0947 --- /dev/null +++ b/tests/services/test_efp_data.py @@ -0,0 +1,112 @@ +import os +import sys +from datetime import date +from unittest import TestCase + +# allow importing api when invoking pytest from this directory tree +ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +if ROOT_DIR not in sys.path: + sys.path.insert(0, ROOT_DIR) + +from api import app, db +from api.models.annotations_lookup import AtAgiLookup +from api.services.efp_data import query_efp_database_dynamic + + +class TestDynamicEfpData(TestCase): + """unit tests for the shared efp query helper in api/services/efp_data.py""" + + def setUp(self): + # each test needs an application context so flask-sqlalchemy can look up binds + self.ctx = app.app_context() + self.ctx.push() + + def tearDown(self): + self.ctx.pop() + + def test_embryo_query_is_case_insensitive(self): + """lower-case agi ids still return the embryo sample row""" + result = query_efp_database_dynamic("embryo", "at1g01010", allow_empty_results=False) + self.assertTrue(result["success"]) + self.assertEqual(result["record_count"], 1) + self.assertEqual(result["data"][0]["name"], "pg_1") + self.assertEqual(result["data"][0]["value"], "0.67") + + def test_sample_filter_handles_case(self): + """sample filters compare case-insensitively when the flag is set""" + result = query_efp_database_dynamic( + "shoot_apex", + "AT1G01010", + sample_ids=["ufo"], + allow_empty_results=False, + sample_case_insensitive=True, + ) + self.assertTrue(result["success"]) + self.assertEqual(result["record_count"], 1) + self.assertEqual(result["data"][0]["name"], "UFO") + self.assertEqual(result["data"][0]["value"], "1.61714") + + def test_invalid_database(self): + """an unsupported database name should trigger a 400 error""" + result = query_efp_database_dynamic("not_a_db", "AT1G01010") + self.assertFalse(result["success"]) + self.assertEqual(result["error_code"], 400) + + def test_invalid_gene_format(self): + """malformed agi ids are rejected before hitting the database""" + result = query_efp_database_dynamic("embryo", "AT1G0101X") + self.assertFalse(result["success"]) + self.assertEqual(result["error_code"], 400) + self.assertIn("Invalid Arabidopsis gene ID format", result["error"]) + + def test_sample_data_agi_is_converted_to_probeset(self): + """sample_data requires probesets, so agi ids should be converted automatically""" + mapping_date = date(2020, 1, 1) + db.session.query(AtAgiLookup).filter_by( + probeset="261585_at", agi="AT1G01010", date=mapping_date + ).delete() + db.session.add( + AtAgiLookup( + probeset="261585_at", + agi="AT1G01010", + date=mapping_date, + ) + ) + db.session.commit() + result = None + try: + result = query_efp_database_dynamic("sample_data", "At1g01010", allow_empty_results=False) + finally: + db.session.query(AtAgiLookup).filter_by( + probeset="261585_at", agi="AT1G01010", date=mapping_date + ).delete() + db.session.commit() + + self.assertTrue(result["success"]) + self.assertEqual(result["probset_id"], "261585_at") + self.assertGreater(result["record_count"], 0) + sample_lookup = {row["name"]: row["value"] for row in result["data"]} + self.assertEqual(sample_lookup["ATGE_100_A"], "40.381") + + def test_sample_data_filter_returns_case_insensitive_matches(self): + """sample_data filters should honor case-insensitive flag just like other datasets""" + result = query_efp_database_dynamic( + "sample_data", + "261585_at", + sample_ids=["atge_100_a", "ATGE_100_B"], + allow_empty_results=False, + sample_case_insensitive=True, + ) + self.assertTrue(result["success"]) + self.assertEqual(result["record_count"], 2) + names = sorted(row["name"] for row in result["data"]) + self.assertEqual(names, ["ATGE_100_A", "ATGE_100_B"]) + + def test_sample_data_empty_results_allowed(self): + """allow_empty_results should return success even when filters exclude everything""" + result = query_efp_database_dynamic( + "sample_data", "256898_at", sample_ids=["DOES_NOT_EXIST"], allow_empty_results=True + ) + self.assertTrue(result["success"]) + self.assertEqual(result["record_count"], 0) + self.assertEqual(result["data"], []) diff --git a/vendor/flask_sqlacodegen/LICENSE b/vendor/flask_sqlacodegen/LICENSE new file mode 100644 index 0000000..2a8b1a0 --- /dev/null +++ b/vendor/flask_sqlacodegen/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Original work Copyright (c) Alex Gronholm +Modified work Copyright (c) Kamil Sindi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/flask_sqlacodegen/MANIFEST.in b/vendor/flask_sqlacodegen/MANIFEST.in new file mode 100644 index 0000000..40128c7 --- /dev/null +++ b/vendor/flask_sqlacodegen/MANIFEST.in @@ -0,0 +1 @@ +include LICENSE README.md tox.ini diff --git a/vendor/flask_sqlacodegen/Makefile b/vendor/flask_sqlacodegen/Makefile new file mode 100644 index 0000000..c523df2 --- /dev/null +++ b/vendor/flask_sqlacodegen/Makefile @@ -0,0 +1,59 @@ +.PHONY: clean build install version release dist + +help: + @echo "clean-build - remove build artifacts" + @echo "clean-test - remove Python file artifacts" + @echo "clean-eggs - remove cached eggs" + @echo "build - build package" + @echo "version - get version number" + @echo "install - install packages" + @echo "test - run tests quickly with the default Python" + @echo "test-all - run tests on every Python version with tox" + @echo "release - package and upload a release" + @echo "dist - package" + +clean: clean-build clean-test clean-eggs + rm -rf htmlcov/ + +clean-build: + rm -rf build/ + rm -rf dist/ + rm -rf *.egg-info + +.PHONY: clean-test +clean-test: + find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf + rm -rf .pytest_cache/ + +.PHONY: clean-eggs +clean-eggs: + rm -rf .eggs/ + +.PHONY: build +build: clean-build clean-eggs + python3 setup.py build_ext --inplace + +install: clean-build + python3 setup.py install + +version: + python3 setup.py --version + +.PHONY: test +test: + python3 setup.py test + +.PHONY: test-all +test-all: + tox + +.PHONY: release +release: clean build + python3 setup.py sdist bdist_wheel + twine check dist/* + twine upload --verbose dist/* + +.PHONY: dist +dist: clean build + python3 setup.py sdist bdist_wheel + twine check dist/* diff --git a/vendor/flask_sqlacodegen/README.md b/vendor/flask_sqlacodegen/README.md new file mode 100644 index 0000000..debc29f --- /dev/null +++ b/vendor/flask_sqlacodegen/README.md @@ -0,0 +1,36 @@ +# Flask sqlacodegen + +Fork of [sqlacodegen](https://pypi.python.org/pypi/sqlacodegen) by Alex Gronholm. + +What's different: + +* Support for Flask-SQLAlchemy syntax using `--flask` option. +* Defaults to generating backrefs in relationships. `--nobackref` still included as option in case backrefs are not wanted. +* Naming of backrefs is class name in snake_case (as opposed to CamelCase) and is pluralized if it's Many-to-One or Many-to-Many using [inflect](https://pypi.python.org/pypi/inflect). +* Primary joins are explicit. +* If column has a server_default set it to `FetchValue()` instead of trying to determine what that value is. Original code did not set the right server defaults in my setup. +* `--ignore-cols` ignores special columns when generating association tables. Original code requires all columns to be foreign keys in order to generate association table. Example: `--ignore-cols id,inserted,updated`. +* Uses the command `flask-sqlacodegen` instead of `sqlacodegen`. +* Added support for `--notables` to only generate model classes, even for association tables + +## Install + +With pip: +```sh +pip install flask-sqlacodegen +``` + +Without pip: +```sh +git clone https://github.com/ksindi/flask-sqlacodegen.git +cd flask-sqlacodegen/ +python setup.py install +``` + +For contributing: +```sh +git clone https://github.com/ksindi/flask-sqlacodegen.git +python -m venv env +pip install -r requirements.txt +python -m sqlacodegen.main --flask --outfile models.py mysql+pymysql://:@:/ [--tables ] [--notables] +``` diff --git a/vendor/flask_sqlacodegen/requirements.txt b/vendor/flask_sqlacodegen/requirements.txt new file mode 100644 index 0000000..d31a0c5 --- /dev/null +++ b/vendor/flask_sqlacodegen/requirements.txt @@ -0,0 +1,22 @@ +apipkg==1.5 +atomicwrites==1.4.0 +attrs==19.3.0 +colorama==0.4.3 +execnet==1.7.1 +importlib-metadata==1.6.0 +inflect==4.1.0 +more-itertools==8.2.0 +packaging==20.3 +sqlacodegen==1.1.6 +pep8==1.7.1 +pluggy==0.13.1 +py==1.10.0 +PyMySQL==0.9.3 +pyparsing==2.4.7 +pytest==5.4.2 +pytest-cache==1.0 +pytest-pep8==1.0.6 +six==1.14.0 +SQLAlchemy==1.3.17 +wcwidth==0.1.9 +zipp==3.1.0 diff --git a/vendor/flask_sqlacodegen/setup.cfg b/vendor/flask_sqlacodegen/setup.cfg new file mode 100644 index 0000000..25e98b5 --- /dev/null +++ b/vendor/flask_sqlacodegen/setup.cfg @@ -0,0 +1,13 @@ +[metadata] +description-file = README.md + +[pep8] +max-line-length = 120 +exclude = .tox + +[tool:pytest] +pep8maxlinelength = 120 +addopts = --tb=short + +[bdist_wheel] +universal=1 diff --git a/vendor/flask_sqlacodegen/setup.py b/vendor/flask_sqlacodegen/setup.py new file mode 100644 index 0000000..3b2435d --- /dev/null +++ b/vendor/flask_sqlacodegen/setup.py @@ -0,0 +1,67 @@ +import sys + +from setuptools import setup, find_packages +from setuptools.command.test import test as TestCommand + +import sqlacodegen + + +class PyTest(TestCommand): + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_args = [] + self.test_suite = True + + def run_tests(self): + import pytest + errno = pytest.main(self.test_args) + sys.exit(errno) + + +extra_requirements = () +if sys.version_info < (2, 7): + extra_requirements = ('argparse',) + +setup( + name='flask-sqlacodegen', + description='Automatic model code generator for SQLAlchemy with Flask support', + long_description=open("README.md").read(), + long_description_content_type="text/markdown", + version=sqlacodegen.version, + author='Kamil Sindi', + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Environment :: Console', + 'Topic :: Database', + 'Topic :: Software Development :: Code Generators', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + ], + keywords=['sqlalchemy', 'sqlacodegen', 'flask'], + license='MIT', + packages=find_packages(exclude=['tests']), + install_requires=( + "SQLAlchemy >= 2.0", + "inflect >= 4.0.0", + ) + extra_requirements, + tests_require=['pytest', 'pytest-pep8'], + cmdclass={'test': PyTest}, + zip_safe=False, + entry_points={ + 'console_scripts': [ + 'flask-sqlacodegen=sqlacodegen.main:main' + ] + } +) diff --git a/vendor/flask_sqlacodegen/sqlacodegen/__init__.py b/vendor/flask_sqlacodegen/sqlacodegen/__init__.py new file mode 100644 index 0000000..20c46f3 --- /dev/null +++ b/vendor/flask_sqlacodegen/sqlacodegen/__init__.py @@ -0,0 +1 @@ +version = __version__ = '2.0.0' diff --git a/vendor/flask_sqlacodegen/sqlacodegen/codegen.py b/vendor/flask_sqlacodegen/sqlacodegen/codegen.py new file mode 100644 index 0000000..2949822 --- /dev/null +++ b/vendor/flask_sqlacodegen/sqlacodegen/codegen.py @@ -0,0 +1,702 @@ +"""Contains the code generation logic and helper functions.""" +from __future__ import unicode_literals, division, print_function, absolute_import +from collections import defaultdict +from keyword import iskeyword +import inspect +import sys +import re + +from sqlalchemy import (Enum, ForeignKeyConstraint, PrimaryKeyConstraint, CheckConstraint, UniqueConstraint, Table, + Column) +from sqlalchemy.schema import ForeignKey +from sqlalchemy.util import OrderedDict +from sqlalchemy.types import Boolean, String +import sqlalchemy + +try: + from sqlalchemy.sql.expression import text, TextClause +except ImportError: + # SQLAlchemy < 0.8 + from sqlalchemy.sql.expression import text, _TextClause as TextClause + +_re_boolean_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \(0, 1\)") +_re_column_name = re.compile(r'(?:(["`]?)(?:.*)\1\.)?(["`]?)(.*)\2') +_re_enum_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \((.+)\)") +_re_enum_item = re.compile(r"'(.*?)(? String) + for column in table.columns: + cls = column.type.__class__ + for supercls in cls.__mro__: + if hasattr(supercls, '__visit_name__'): + cls = supercls + if supercls.__name__ != supercls.__name__.upper() and not supercls.__name__.startswith('_'): + break + + column.type = column.type.adapt(cls) + + def add_imports(self, collector): + if self.table.columns: + collector.add_import(Column) + + for column in self.table.columns: + collector.add_import(column.type) + if column.server_default: + collector.add_literal_import('sqlalchemy.schema', 'FetchedValue') + + for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): + if isinstance(constraint, ForeignKeyConstraint): + if len(constraint.columns) > 1: + collector.add_literal_import('sqlalchemy', 'ForeignKeyConstraint') + else: + collector.add_literal_import('sqlalchemy', 'ForeignKey') + elif isinstance(constraint, UniqueConstraint): + if len(constraint.columns) > 1: + collector.add_literal_import('sqlalchemy', 'UniqueConstraint') + elif not isinstance(constraint, PrimaryKeyConstraint): + collector.add_import(constraint) + + for index in self.table.indexes: + if len(index.columns) > 1: + collector.add_import(index) + + +class ModelTable(Model): + def add_imports(self, collector): + super(ModelTable, self).add_imports(collector) + collector.add_import(Table) + + def render(self): + met = ' metadata,' if _flask_prepend == '' else '' + text = 't_{0} = {1}Table(\n {0!r},{2}\n'.format(self.table.name, _flask_prepend, met) + + for column in self.table.columns: + text += ' {0},\n'.format(_render_column(column, True)) + + for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): + if isinstance(constraint, PrimaryKeyConstraint): + continue + if isinstance(constraint, (ForeignKeyConstraint, UniqueConstraint)) and len(constraint.columns) == 1: + continue + text += ' {0},\n'.format(_render_constraint(constraint)) + + for index in self.table.indexes: + if len(index.columns) > 1: + text += ' {0},\n'.format(_render_index(index)) + + if self.schema: + text += " schema='{0}',\n".format(self.schema) + + return text.rstrip('\n,') + '\n)' + + +class ModelClass(Model): + parent_name = 'Base' + + def __init__(self, table, association_tables, inflect_engine, detect_joined, collector): + super(ModelClass, self).__init__(table) + self.name = self._tablename_to_classname(table.name, inflect_engine) + self.children = [] + self.attributes = OrderedDict() + + # Assign attribute names for columns + for column in table.columns: + self._add_attribute(column.name, column) + if _dataclass: + if column.type.python_type.__module__ != 'builtins': + collector.add_literal_import(column.type.python_type.__module__, column.type.python_type.__name__) + + + # Add many-to-one relationships + pk_column_names = set(col.name for col in table.primary_key.columns) + for constraint in sorted(table.constraints, key=_get_constraint_sort_key): + if isinstance(constraint, ForeignKeyConstraint): + target_cls = self._tablename_to_classname(constraint.elements[0].column.table.name, inflect_engine) + if (detect_joined and self.parent_name == 'Base' and + set(_get_column_names(constraint)) == pk_column_names): + self.parent_name = target_cls + else: + relationship_ = ManyToOneRelationship(self.name, target_cls, constraint, inflect_engine) + self._add_attribute(relationship_.preferred_name, relationship_) + + # Add many-to-many relationships + for association_table in association_tables: + fk_constraints = [c for c in association_table.constraints if isinstance(c, ForeignKeyConstraint)] + fk_constraints.sort(key=_get_constraint_sort_key) + target_cls = self._tablename_to_classname(fk_constraints[1].elements[0].column.table.name, inflect_engine) + relationship_ = ManyToManyRelationship(self.name, target_cls, association_table, inflect_engine) + self._add_attribute(relationship_.preferred_name, relationship_) + + @staticmethod + def _tablename_to_classname(tablename, inflect_engine): + camel_case_name = ''.join(part[:1].upper() + part[1:] for part in re.split(r'_|-', tablename)) + return inflect_engine.singular_noun(camel_case_name) or camel_case_name + + def _add_attribute(self, attrname, value): + attrname = tempname = _convert_to_valid_identifier(attrname) + counter = 1 + while tempname in self.attributes: + tempname = attrname + str(counter) + counter += 1 + + self.attributes[tempname] = value + return tempname + + def add_imports(self, collector): + super(ModelClass, self).add_imports(collector) + + if any(isinstance(value, Relationship) for value in self.attributes.values()): + collector.add_literal_import('sqlalchemy.orm', 'relationship') + + for child in self.children: + child.add_imports(collector) + + def render(self): + global _dataclass + + text = 'class {0}({1}):\n'.format(self.name, self.parent_name) + + if _dataclass: + text = '@dataclass\n' + text + + text += ' __tablename__ = {0!r}\n'.format(self.table.name) + + # Render constraints and indexes as __table_args__ + table_args = [] + for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): + if isinstance(constraint, PrimaryKeyConstraint): + continue + if isinstance(constraint, (ForeignKeyConstraint, UniqueConstraint)) and len(constraint.columns) == 1: + continue + table_args.append(_render_constraint(constraint)) + for index in self.table.indexes: + if len(index.columns) > 1: + table_args.append(_render_index(index)) + + table_kwargs = {} + if self.schema: + table_kwargs['schema'] = self.schema + + kwargs_items = ', '.join('{0!r}: {1!r}'.format(key, table_kwargs[key]) for key in table_kwargs) + kwargs_items = '{{{0}}}'.format(kwargs_items) if kwargs_items else None + if table_kwargs and not table_args: + text += ' __table_args__ = {0}\n'.format(kwargs_items) + elif table_args: + if kwargs_items: + table_args.append(kwargs_items) + if len(table_args) == 1: + table_args[0] += ',' + text += ' __table_args__ = (\n {0}\n )\n'.format(',\n '.join(table_args)) + + # Render columns + text += '\n' + for attr, column in self.attributes.items(): + if isinstance(column, Column): + show_name = attr != column.name + if _dataclass: + text += ' ' + attr + ' : ' + column.type.python_type.__name__ + '\n' + + text += ' {0} = {1}\n'.format(attr, _render_column(column, show_name)) + + # Render relationships + if any(isinstance(value, Relationship) for value in self.attributes.values()): + text += '\n' + for attr, relationship in self.attributes.items(): + if isinstance(relationship, Relationship): + text += ' {0} = {1}\n'.format(attr, relationship.render()) + + # Render subclasses + for child_class in self.children: + text += '\n\n' + child_class.render() + + return text + + +class Relationship(object): + def __init__(self, source_cls, target_cls): + super(Relationship, self).__init__() + self.source_cls = source_cls + self.target_cls = target_cls + self.kwargs = OrderedDict() + self.backref_name = _underscore(self.source_cls) + + def render(self): + text = _flask_prepend + 'relationship(' + args = [repr(self.target_cls)] + + if 'secondaryjoin' in self.kwargs: + text += '\n ' + delimiter, end = ',\n ', '\n )' + else: + delimiter, end = ', ', ')' + + args.extend([key + '=' + value for key, value in self.kwargs.items()]) + + return _re_invalid_relationship.sub('_', text + delimiter.join(args) + end) + + def make_backref(self, relationships, classes): + backref = self.backref_name + original_backref = backref + # Check if backref already exists for relationship source_cls to target_cls and add suffix + suffix = 0 + while (self.target_cls, backref) in [(x.target_cls, x.backref_name) for x in relationships]: + backref = original_backref + str('_{0}'.format(suffix)) + suffix += 1 + + self.kwargs['backref'] = repr(backref) + # Check if any of the target_cls inherit from other target_cls + # If so, modify backref name of descendant + # "backref({0}, lazy='dynamic')".format(repr(backref)) + for rel in [x for x in relationships if 'backref' in x.kwargs]: + if self.target_cls in classes and rel.target_cls in classes: + if _is_model_descendant(classes[self.target_cls], classes[rel.target_cls]): + self.backref_name = self.target_cls.lower() + '_' + backref + self.kwargs['backref'] = repr(self.backref_name) + if _is_model_descendant(classes[rel.target_cls], classes[self.target_cls]): + backref = rel.backref_name + rel.backref_name = rel.target_cls.lower() + '_' + backref + rel.kwargs['backref'] = repr(rel.backref_name) + + +class ManyToOneRelationship(Relationship): + def __init__(self, source_cls, target_cls, constraint, inflect_engine): + super(ManyToOneRelationship, self).__init__(source_cls, target_cls) + + column_names = _get_column_names(constraint) + colname = column_names[0] + tablename = constraint.elements[0].column.table.name + if not colname.endswith('_id'): + self.preferred_name = inflect_engine.singular_noun(tablename) or tablename + else: + self.preferred_name = colname[:-3] + self.backref_name = inflect_engine.plural_noun(self.backref_name) + + # Add uselist=False to One-to-One relationships + if any(isinstance(c, (PrimaryKeyConstraint, UniqueConstraint)) and + set(col.name for col in c.columns) == set(column_names) + for c in constraint.table.constraints): + self.kwargs['uselist'] = 'False' + + # Handle self referential relationships + if source_cls == target_cls: + self.preferred_name = 'parent' if not colname.endswith('_id') else colname[:-3] + pk_col_names = [col.name for col in constraint.table.primary_key] + self.kwargs['remote_side'] = '[{0}]'.format(', '.join(pk_col_names)) + + # If the two tables share more than one foreign key constraint, + # SQLAlchemy needs an explicit primaryjoin to figure out which column(s) to join with + # common_fk_constraints = _get_common_fk_constraints(constraint.table, constraint.elements[0].column.table) + # if len(common_fk_constraints) > 1: + # self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, constraint.columns[0], target_cls, constraint.elements[0].column.name) + if len(constraint.elements) > 1: # or + self.kwargs['primaryjoin'] = "'and_({0})'".format(', '.join(['{0}.{1} == {2}.{3}'.format(source_cls, k.parent.name, target_cls, k.column.name) + for k in constraint.elements])) + else: + self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, column_names[0], target_cls, + constraint.elements[0].column.name) + + +class ManyToManyRelationship(Relationship): + def __init__(self, source_cls, target_cls, assocation_table, inflect_engine): + super(ManyToManyRelationship, self).__init__(source_cls, target_cls) + prefix = assocation_table.schema + '.' if assocation_table.schema is not None else '' + self.kwargs['secondary'] = repr(prefix + assocation_table.name) + constraints = [c for c in assocation_table.constraints if isinstance(c, ForeignKeyConstraint)] + constraints.sort(key=_get_constraint_sort_key) + colname = _get_column_names(constraints[1])[0] + tablename = constraints[1].elements[0].column.table.name + self.preferred_name = tablename if not colname.endswith('_id') else colname[:-3] + 's' + self.backref_name = inflect_engine.plural_noun(self.backref_name) + + # Handle self referential relationships + if source_cls == target_cls: + self.preferred_name = 'parents' if not colname.endswith('_id') else colname[:-3] + 's' + pri_pairs = zip(_get_column_names(constraints[0]), constraints[0].elements) + sec_pairs = zip(_get_column_names(constraints[1]), constraints[1].elements) + pri_joins = ['{0}.{1} == {2}.c.{3}'.format(source_cls, elem.column.name, assocation_table.name, col) + for col, elem in pri_pairs] + sec_joins = ['{0}.{1} == {2}.c.{3}'.format(target_cls, elem.column.name, assocation_table.name, col) + for col, elem in sec_pairs] + self.kwargs['primaryjoin'] = ( + repr('and_({0})'.format(', '.join(pri_joins))) if len(pri_joins) > 1 else repr(pri_joins[0])) + self.kwargs['secondaryjoin'] = ( + repr('and_({0})'.format(', '.join(sec_joins))) if len(sec_joins) > 1 else repr(sec_joins[0])) + + +class CodeGenerator(object): + header = '# coding: utf-8' + footer = '' + + def __init__(self, metadata, noindexes=False, noconstraints=False, + nojoined=False, noinflect=False, nobackrefs=False, + flask=False, ignore_cols=None, noclasses=False, nocomments=False, notables=False, dataclass=False): + super(CodeGenerator, self).__init__() + + if noinflect: + inflect_engine = _DummyInflectEngine() + else: + import inflect + inflect_engine = inflect.engine() + + # exclude these column names from consideration when generating association tables + _ignore_columns = ignore_cols or [] + + self.flask = flask + if not self.flask: + global _flask_prepend + _flask_prepend = '' + + self.nocomments = nocomments + + self.dataclass = dataclass + if self.dataclass: + global _dataclass + _dataclass = True + + # Pick association tables from the metadata into their own set, don't process them normally + links = defaultdict(lambda: []) + association_tables = set() + for table in metadata.tables.values(): + # Link tables have exactly two foreign key constraints and all columns are involved in them + # except for special columns like id, inserted, and updated + fk_constraints = [constr for constr in table.constraints if isinstance(constr, ForeignKeyConstraint)] + if len(fk_constraints) == 2 and all(col.foreign_keys for col in table.columns if col.name not in _ignore_columns): + association_tables.add(table.name) + tablename = sorted(fk_constraints, key=_get_constraint_sort_key)[0].elements[0].column.table.name + links[tablename].append(table) + + # Iterate through the tables and create model classes when possible + self.models = [] + self.collector = ImportCollector() + classes = {} + for table in sorted(metadata.tables.values(), key=lambda t: (t.schema or '', t.name)): + # Support for Alembic and sqlalchemy-migrate -- never expose the schema version tables + if table.name in ('alembic_version', 'migrate_version'): + continue + + if noindexes: + table.indexes.clear() + + if noconstraints: + table.constraints = set([table.primary_key]) + table.foreign_keys.clear() + for col in table.columns: + col.foreign_keys.clear() + else: + # Detect check constraints for boolean and enum columns + for constraint in table.constraints.copy(): + if isinstance(constraint, CheckConstraint): + sqltext = _get_compiled_expression(constraint.sqltext) + + # Turn any integer-like column with a CheckConstraint like "column IN (0, 1)" into a Boolean + match = _re_boolean_check_constraint.match(sqltext) + if match: + colname = _re_column_name.match(match.group(1)).group(3) + table.constraints.remove(constraint) + table.c[colname].type = Boolean() + continue + + # Turn any string-type column with a CheckConstraint like "column IN (...)" into an Enum + match = _re_enum_check_constraint.match(sqltext) + if match: + colname = _re_column_name.match(match.group(1)).group(3) + items = match.group(2) + if isinstance(table.c[colname].type, String): + table.constraints.remove(constraint) + if not isinstance(table.c[colname].type, Enum): + options = _re_enum_item.findall(items) + table.c[colname].type = Enum(*options, native_enum=False) + continue + + # Only generate classes when notables is set to True + if notables: + model = ModelClass(table, links[table.name], inflect_engine, not nojoined, self.collector) + classes[model.name] = model + elif not table.primary_key or table.name in association_tables or noclasses: + # Only form model classes for tables that have a primary key and are not association tables + model = ModelTable(table) + elif not noclasses: + model = ModelClass(table, links[table.name], inflect_engine, not nojoined, self.collector) + classes[model.name] = model + + self.models.append(model) + + # collect imports for models only if flask is not specified + if not self.flask: + model.add_imports(self.collector) + + # Nest inherited classes in their superclasses to ensure proper ordering + for model in classes.values(): + if model.parent_name != 'Base': + classes[model.parent_name].children.append(model) + self.models.remove(model) + + # If backrefs are allowed. Resolve any relationships conflicts where one + # target class might inherit from another + if not nobackrefs: + for model in classes.values(): + visited = [] + for relationship in model.attributes.values(): + if isinstance(relationship, Relationship): + relationship.make_backref(visited, classes) + visited.append(relationship) + + if self.flask: + # Add Flask-SQLAlchemy support + self.collector.add_literal_import('flask_sqlalchemy', 'SQLAlchemy') + parent_name = 'db.Model' + + for model in classes.values(): + if model.parent_name == 'Base': + model.parent_name = parent_name + else: + self.collector.add_literal_import('sqlalchemy.ext.declarative', 'declarative_base') + self.collector.add_literal_import('sqlalchemy', 'MetaData') + + + if self.dataclass: + self.collector.add_literal_import('dataclasses', 'dataclass') + + def render(self, outfile=sys.stdout): + + print(self.header, file=outfile) + + # Render the collected imports + print(self.collector.render() + '\n\n', file=outfile) + + if self.flask: + print('db = SQLAlchemy()', file=outfile) + else: + if any(isinstance(model, ModelClass) for model in self.models): + print('Base = declarative_base()\nmetadata = Base.metadata', file=outfile) + else: + print('metadata = MetaData()', file=outfile) + + # Render the model tables and classes + for model in self.models: + print('\n\n', file=outfile) + print(model.render().rstrip('\n'), file=outfile) + + if self.footer: + print(self.footer, file=outfile) diff --git a/vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py b/vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py b/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py new file mode 100644 index 0000000..e4eb907 --- /dev/null +++ b/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py @@ -0,0 +1,36 @@ +""" +Provides missing Postgresql types. + +Use GeoAlchemy2 to support Postgis types. +Implement mockups for Point and LTree type, but generated models won't work out +of the box: a better way would be to use a package implementing proper classes +which could be imported in the target project. + +""" + +from sqlalchemy.dialects.postgresql.base import ischema_names, PGTypeCompiler +from sqlalchemy import types as sqltypes + +try: + import geoalchemy2 +except ImportError: + pass + + +class LTREE(sqltypes.TypeEngine): + """Postgresql LTREE type mockup.""" + + __visit_name__ = 'LTREE' + + +class POINT(sqltypes.TypeEngine): + """Postgresql POINT type mockup.""" + + __visit_name__ = 'POINT' + + +ischema_names['ltree'] = LTREE +ischema_names['point'] = POINT + +PGTypeCompiler.visit_LTREE = lambda self, type_: 'LTREE' +PGTypeCompiler.visit_POINT = lambda self, type_: 'POINT' diff --git a/vendor/flask_sqlacodegen/sqlacodegen/main.py b/vendor/flask_sqlacodegen/sqlacodegen/main.py new file mode 100644 index 0000000..d8646e9 --- /dev/null +++ b/vendor/flask_sqlacodegen/sqlacodegen/main.py @@ -0,0 +1,71 @@ +""" """ +from __future__ import unicode_literals, division, print_function, absolute_import +import argparse +import codecs +import importlib +import sys + +from sqlalchemy.engine import create_engine +from sqlalchemy.schema import MetaData + +from sqlacodegen.codegen import CodeGenerator +import sqlacodegen +import sqlacodegen.dialects + + +def import_dialect_specificities(engine): + dialect_name = '.' + engine.dialect.name + try: + importlib.import_module(dialect_name, 'sqlacodegen.dialects') + except ImportError: + pass + + +def main(): + parser = argparse.ArgumentParser(description='Generates SQLAlchemy model code from an existing database.') + parser.add_argument('url', nargs='?', help='SQLAlchemy url to the database') + parser.add_argument('--version', action='store_true', help="print the version number and exit") + parser.add_argument('--schema', help='load tables from an alternate schema') + parser.add_argument('--default-schema', help='default schema name for local schema object') + parser.add_argument('--tables', help='tables to process (comma-separated, default: all)') + parser.add_argument('--noviews', action='store_true', help="ignore views") + parser.add_argument('--noindexes', action='store_true', help='ignore indexes') + parser.add_argument('--noconstraints', action='store_true', help='ignore constraints') + parser.add_argument('--nojoined', action='store_true', help="don't autodetect joined table inheritance") + parser.add_argument('--noinflect', action='store_true', help="don't try to convert tables names to singular form") + parser.add_argument('--noclasses', action='store_true', help="don't generate classes, only tables") + parser.add_argument('--notables', action='store_true', help="don't generate tables, only classes") + parser.add_argument('--outfile', help='file to write output to (default: stdout)') + parser.add_argument('--nobackrefs', action='store_true', help="don't include backrefs") + parser.add_argument('--flask', action='store_true', help="use Flask-SQLAlchemy columns") + parser.add_argument('--ignore-cols', help="Don't check foreign key constraints on specified columns (comma-separated)") + parser.add_argument('--nocomments', action='store_true', help="don't render column comments") + parser.add_argument('--dataclass', action='store_true', help="add dataclass decorators for JSON serialization") + args = parser.parse_args() + + if args.version: + print(sqlacodegen.version) + return + if not args.url: + print('You must supply a url\n', file=sys.stderr) + parser.print_help() + return + default_schema = args.default_schema + if not default_schema: + default_schema = None + + engine = create_engine(args.url) + import_dialect_specificities(engine) + metadata = MetaData() + tables = args.tables.split(',') if args.tables else None + ignore_cols = args.ignore_cols.split(',') if args.ignore_cols else None + metadata.reflect(engine, args.schema, not args.noviews, tables) + outfile = codecs.open(args.outfile, 'w', encoding='utf-8') if args.outfile else sys.stdout + generator = CodeGenerator(metadata, args.noindexes, args.noconstraints, + args.nojoined, args.noinflect, args.nobackrefs, + args.flask, ignore_cols, args.noclasses, args.nocomments, args.notables, args.dataclass) + generator.render(outfile) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/vendor/flask_sqlacodegen/tox.ini b/vendor/flask_sqlacodegen/tox.ini new file mode 100644 index 0000000..1c16db7 --- /dev/null +++ b/vendor/flask_sqlacodegen/tox.ini @@ -0,0 +1,26 @@ +[tox] +envlist = py26,py27,py32,py33,py26-sqla08,py26-sqla07,py26-sqla06,pep8 + +[testenv] +deps=pytest +commands=py.test [] + +[testenv:py26-sqla08] +basepython=python2.6 +deps=pytest + sqlalchemy<=0.8.99 + +[testenv:py26-sqla07] +basepython=python2.6 +deps=pytest + sqlalchemy<=0.7.99 + +[testenv:py26-sqla06] +basepython=python2.6 +deps=pytest + sqlalchemy==0.6.0 + +[testenv:pep8] +deps=pytest + pytest-pep8 +commands=py.test --pep8 -m pep8 [] From 4ab2af351d018319f8d229561513f8c734765a11 Mon Sep 17 00:00:00 2001 From: Reena Date: Thu, 18 Dec 2025 12:21:08 -0500 Subject: [PATCH 3/6] tried to fix to pass --- .github/workflows/codeql.yml | 6 +- api/__init__.py.save | 116 --- api/services/efp_data.py | 5 +- scripts/bootstrap_simple_efp_dbs.py | 6 +- vendor/flask_sqlacodegen/LICENSE | 22 - vendor/flask_sqlacodegen/MANIFEST.in | 1 - vendor/flask_sqlacodegen/Makefile | 59 -- vendor/flask_sqlacodegen/README.md | 36 - vendor/flask_sqlacodegen/requirements.txt | 22 - vendor/flask_sqlacodegen/setup.cfg | 13 - vendor/flask_sqlacodegen/setup.py | 67 -- .../flask_sqlacodegen/sqlacodegen/__init__.py | 1 - .../flask_sqlacodegen/sqlacodegen/codegen.py | 702 ------------------ .../sqlacodegen/dialects/__init__.py | 0 .../sqlacodegen/dialects/postgresql.py | 36 - vendor/flask_sqlacodegen/sqlacodegen/main.py | 71 -- vendor/flask_sqlacodegen/tox.ini | 26 - 17 files changed, 10 insertions(+), 1179 deletions(-) delete mode 100644 api/__init__.py.save delete mode 100644 vendor/flask_sqlacodegen/LICENSE delete mode 100644 vendor/flask_sqlacodegen/MANIFEST.in delete mode 100644 vendor/flask_sqlacodegen/Makefile delete mode 100644 vendor/flask_sqlacodegen/README.md delete mode 100644 vendor/flask_sqlacodegen/requirements.txt delete mode 100644 vendor/flask_sqlacodegen/setup.cfg delete mode 100644 vendor/flask_sqlacodegen/setup.py delete mode 100644 vendor/flask_sqlacodegen/sqlacodegen/__init__.py delete mode 100644 vendor/flask_sqlacodegen/sqlacodegen/codegen.py delete mode 100644 vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py delete mode 100644 vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py delete mode 100644 vendor/flask_sqlacodegen/sqlacodegen/main.py delete mode 100644 vendor/flask_sqlacodegen/tox.ini diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c97b361..efaa815 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,16 +29,16 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" \ No newline at end of file diff --git a/api/__init__.py.save b/api/__init__.py.save deleted file mode 100644 index ebc57da..0000000 --- a/api/__init__.py.save +++ /dev/null @@ -1,116 +0,0 @@ -from flask import Flask -from flask_sqlalchemy import SQLAlchemy -from flask_restx import Api -from flask_cors import CORS -from flask_caching import Cache -from flask_limiter import Limiter -from flask_limiter.util import get_remote_address -import os -from api.resources.efp_proxy import efp_proxy -bar_api.add_namespace(efp_proxy) - - -def create_app(): - """Initialize the app factory based on the official Flask documentation""" - bar_app = Flask(__name__) - CORS(bar_app) - - # Load configuration - if os.environ.get("CI"): - # Travis - print("We are now loading configuration.") - bar_app.config.from_pyfile(os.getcwd() + "/config/BAR_API.cfg", silent=True) - - elif os.environ.get("BAR"): - # The BAR - bar_app.config.from_pyfile(os.environ.get("BAR_API_PATH"), silent=True) - - # Load environment variables on the BAR - if bar_app.config.get("PHENIX"): - os.environ["PHENIX"] = bar_app.config.get("PHENIX") - if bar_app.config.get("PHENIX_VERSION"): - os.environ["PHENIX_VERSION"] = bar_app.config.get("PHENIX_VERSION") - if bar_app.config.get("PATH"): - os.environ["PATH"] = bar_app.config.get("PATH") + ":/usr/local/phenix-1.18.2-3874/build/bin" - else: - # The localhost - bar_app.config.from_pyfile(os.path.expanduser("~") + "/.config/BAR_API.cfg", silent=True) - - # Initialize the databases - db.init_app(bar_app) - - # Initialize the cache - cache.init_app(bar_app) - - # Initialize rate limiter - limiter.init_app(bar_app) - - # Configure the Swagger UI - bar_api = Api( - title="BAR API", - version="0.0.1", - description="API for the Bio-Analytic Resource", - ) - - # Now add routes - from api.resources.gene_information import gene_information - from api.resources.rnaseq_gene_expression import rnaseq_gene_expression - from api.resources.microarray_gene_expression import microarray_gene_expression - from api.resources.proxy import bar_proxy - from api.resources.thalemine import thalemine - from api.resources.snps import snps - from api.resources.sequence import sequence - from api.resources.gene_annotation import gene_annotation - from api.resources.interactions import itrns - from api.resources.gene_localizations import loc - from api.resources.efp_image import efp_image - from api.resources.fastpheno import fastpheno - from api.resources.llama3 import llama3 - - bar_api.add_namespace(gene_information) - bar_api.add_namespace(rnaseq_gene_expression) - bar_api.add_namespace(microarray_gene_expression) - bar_api.add_namespace(bar_proxy) - bar_api.add_namespace(thalemine) - bar_api.add_namespace(snps) - bar_api.add_namespace(sequence) - bar_api.add_namespace(gene_annotation) - bar_api.add_namespace(itrns) - bar_api.add_namespace(loc) - bar_api.add_namespace(efp_image) - bar_api.add_namespace(fastpheno) - bar_api.add_namespace(llama3) - bar_api.init_app(bar_app) - return bar_app - - -# Initialize database system -db = SQLAlchemy() - -# Initialize Redis -if os.environ.get("BAR"): - cache = Cache( - config={ - "CACHE_TYPE": "RedisCache", - "CACHE_KEY_PREFIX": "BAR_API_", - "CACHE_REDIS_HOST": os.environ.get("BAR_REDIS_HOST"), - "CACHE_REDIS_PASSWORD": os.environ.get("BAR_REDIS_PASSWORD"), - } - ) -else: - cache = Cache( - config={ - "CACHE_TYPE": "RedisCache", - "CACHE_KEY_PREFIX": "BAR_API_", - "CACHE_REDIS_HOST": "localhost", - } - ) - -# Initialize Limiter -limiter = Limiter(key_func=get_remote_address) - -# Now create the bar_app -app = create_app() - -if __name__ == "__main__": - app.run() diff --git a/api/services/efp_data.py b/api/services/efp_data.py index 46e70b8..9f4f510 100644 --- a/api/services/efp_data.py +++ b/api/services/efp_data.py @@ -117,8 +117,9 @@ def _iter_engine_candidates(database: str) -> Iterable[Tuple[str, Engine, bool]] db_path = DATABASE_DIR / DYNAMIC_DATABASE_SCHEMAS[database]["filename"] if has_app_context(): try: - bound_engine = db.get_engine(bind=database) - yield ("sqlalchemy_bind", bound_engine, False) + bound_engine = db.engines.get(database) + if bound_engine: + yield ("sqlalchemy_bind", bound_engine, False) except Exception as exc: print(f"[warn] unable to load sqlalchemy bind for {database}: {exc}") diff --git a/scripts/bootstrap_simple_efp_dbs.py b/scripts/bootstrap_simple_efp_dbs.py index 583ac4c..3c4cc92 100644 --- a/scripts/bootstrap_simple_efp_dbs.py +++ b/scripts/bootstrap_simple_efp_dbs.py @@ -18,8 +18,10 @@ def _default_host() -> str: return os.environ["DB_HOST"] if os.environ.get("MYSQL_HOST"): return os.environ["MYSQL_HOST"] - # inside docker compose the db host is bar_mysqldb; locally it is usually localhost - return "BAR_mysqldb" if os.environ.get("CI") else "localhost" + # GitHub Actions CI uses localhost; Docker Compose uses bar_mysqldb + # CI env var is set in GitHub Actions, but not DB_HOST + # In Docker, DB_HOST should be explicitly set to BAR_mysqldb + return "localhost" def parse_args() -> argparse.Namespace: diff --git a/vendor/flask_sqlacodegen/LICENSE b/vendor/flask_sqlacodegen/LICENSE deleted file mode 100644 index 2a8b1a0..0000000 --- a/vendor/flask_sqlacodegen/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Original work Copyright (c) Alex Gronholm -Modified work Copyright (c) Kamil Sindi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/flask_sqlacodegen/MANIFEST.in b/vendor/flask_sqlacodegen/MANIFEST.in deleted file mode 100644 index 40128c7..0000000 --- a/vendor/flask_sqlacodegen/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include LICENSE README.md tox.ini diff --git a/vendor/flask_sqlacodegen/Makefile b/vendor/flask_sqlacodegen/Makefile deleted file mode 100644 index c523df2..0000000 --- a/vendor/flask_sqlacodegen/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -.PHONY: clean build install version release dist - -help: - @echo "clean-build - remove build artifacts" - @echo "clean-test - remove Python file artifacts" - @echo "clean-eggs - remove cached eggs" - @echo "build - build package" - @echo "version - get version number" - @echo "install - install packages" - @echo "test - run tests quickly with the default Python" - @echo "test-all - run tests on every Python version with tox" - @echo "release - package and upload a release" - @echo "dist - package" - -clean: clean-build clean-test clean-eggs - rm -rf htmlcov/ - -clean-build: - rm -rf build/ - rm -rf dist/ - rm -rf *.egg-info - -.PHONY: clean-test -clean-test: - find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf - rm -rf .pytest_cache/ - -.PHONY: clean-eggs -clean-eggs: - rm -rf .eggs/ - -.PHONY: build -build: clean-build clean-eggs - python3 setup.py build_ext --inplace - -install: clean-build - python3 setup.py install - -version: - python3 setup.py --version - -.PHONY: test -test: - python3 setup.py test - -.PHONY: test-all -test-all: - tox - -.PHONY: release -release: clean build - python3 setup.py sdist bdist_wheel - twine check dist/* - twine upload --verbose dist/* - -.PHONY: dist -dist: clean build - python3 setup.py sdist bdist_wheel - twine check dist/* diff --git a/vendor/flask_sqlacodegen/README.md b/vendor/flask_sqlacodegen/README.md deleted file mode 100644 index debc29f..0000000 --- a/vendor/flask_sqlacodegen/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Flask sqlacodegen - -Fork of [sqlacodegen](https://pypi.python.org/pypi/sqlacodegen) by Alex Gronholm. - -What's different: - -* Support for Flask-SQLAlchemy syntax using `--flask` option. -* Defaults to generating backrefs in relationships. `--nobackref` still included as option in case backrefs are not wanted. -* Naming of backrefs is class name in snake_case (as opposed to CamelCase) and is pluralized if it's Many-to-One or Many-to-Many using [inflect](https://pypi.python.org/pypi/inflect). -* Primary joins are explicit. -* If column has a server_default set it to `FetchValue()` instead of trying to determine what that value is. Original code did not set the right server defaults in my setup. -* `--ignore-cols` ignores special columns when generating association tables. Original code requires all columns to be foreign keys in order to generate association table. Example: `--ignore-cols id,inserted,updated`. -* Uses the command `flask-sqlacodegen` instead of `sqlacodegen`. -* Added support for `--notables` to only generate model classes, even for association tables - -## Install - -With pip: -```sh -pip install flask-sqlacodegen -``` - -Without pip: -```sh -git clone https://github.com/ksindi/flask-sqlacodegen.git -cd flask-sqlacodegen/ -python setup.py install -``` - -For contributing: -```sh -git clone https://github.com/ksindi/flask-sqlacodegen.git -python -m venv env -pip install -r requirements.txt -python -m sqlacodegen.main --flask --outfile models.py mysql+pymysql://:@:/ [--tables ] [--notables] -``` diff --git a/vendor/flask_sqlacodegen/requirements.txt b/vendor/flask_sqlacodegen/requirements.txt deleted file mode 100644 index d31a0c5..0000000 --- a/vendor/flask_sqlacodegen/requirements.txt +++ /dev/null @@ -1,22 +0,0 @@ -apipkg==1.5 -atomicwrites==1.4.0 -attrs==19.3.0 -colorama==0.4.3 -execnet==1.7.1 -importlib-metadata==1.6.0 -inflect==4.1.0 -more-itertools==8.2.0 -packaging==20.3 -sqlacodegen==1.1.6 -pep8==1.7.1 -pluggy==0.13.1 -py==1.10.0 -PyMySQL==0.9.3 -pyparsing==2.4.7 -pytest==5.4.2 -pytest-cache==1.0 -pytest-pep8==1.0.6 -six==1.14.0 -SQLAlchemy==1.3.17 -wcwidth==0.1.9 -zipp==3.1.0 diff --git a/vendor/flask_sqlacodegen/setup.cfg b/vendor/flask_sqlacodegen/setup.cfg deleted file mode 100644 index 25e98b5..0000000 --- a/vendor/flask_sqlacodegen/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[metadata] -description-file = README.md - -[pep8] -max-line-length = 120 -exclude = .tox - -[tool:pytest] -pep8maxlinelength = 120 -addopts = --tb=short - -[bdist_wheel] -universal=1 diff --git a/vendor/flask_sqlacodegen/setup.py b/vendor/flask_sqlacodegen/setup.py deleted file mode 100644 index 3b2435d..0000000 --- a/vendor/flask_sqlacodegen/setup.py +++ /dev/null @@ -1,67 +0,0 @@ -import sys - -from setuptools import setup, find_packages -from setuptools.command.test import test as TestCommand - -import sqlacodegen - - -class PyTest(TestCommand): - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = [] - self.test_suite = True - - def run_tests(self): - import pytest - errno = pytest.main(self.test_args) - sys.exit(errno) - - -extra_requirements = () -if sys.version_info < (2, 7): - extra_requirements = ('argparse',) - -setup( - name='flask-sqlacodegen', - description='Automatic model code generator for SQLAlchemy with Flask support', - long_description=open("README.md").read(), - long_description_content_type="text/markdown", - version=sqlacodegen.version, - author='Kamil Sindi', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Environment :: Console', - 'Topic :: Database', - 'Topic :: Software Development :: Code Generators', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - ], - keywords=['sqlalchemy', 'sqlacodegen', 'flask'], - license='MIT', - packages=find_packages(exclude=['tests']), - install_requires=( - "SQLAlchemy >= 2.0", - "inflect >= 4.0.0", - ) + extra_requirements, - tests_require=['pytest', 'pytest-pep8'], - cmdclass={'test': PyTest}, - zip_safe=False, - entry_points={ - 'console_scripts': [ - 'flask-sqlacodegen=sqlacodegen.main:main' - ] - } -) diff --git a/vendor/flask_sqlacodegen/sqlacodegen/__init__.py b/vendor/flask_sqlacodegen/sqlacodegen/__init__.py deleted file mode 100644 index 20c46f3..0000000 --- a/vendor/flask_sqlacodegen/sqlacodegen/__init__.py +++ /dev/null @@ -1 +0,0 @@ -version = __version__ = '2.0.0' diff --git a/vendor/flask_sqlacodegen/sqlacodegen/codegen.py b/vendor/flask_sqlacodegen/sqlacodegen/codegen.py deleted file mode 100644 index 2949822..0000000 --- a/vendor/flask_sqlacodegen/sqlacodegen/codegen.py +++ /dev/null @@ -1,702 +0,0 @@ -"""Contains the code generation logic and helper functions.""" -from __future__ import unicode_literals, division, print_function, absolute_import -from collections import defaultdict -from keyword import iskeyword -import inspect -import sys -import re - -from sqlalchemy import (Enum, ForeignKeyConstraint, PrimaryKeyConstraint, CheckConstraint, UniqueConstraint, Table, - Column) -from sqlalchemy.schema import ForeignKey -from sqlalchemy.util import OrderedDict -from sqlalchemy.types import Boolean, String -import sqlalchemy - -try: - from sqlalchemy.sql.expression import text, TextClause -except ImportError: - # SQLAlchemy < 0.8 - from sqlalchemy.sql.expression import text, _TextClause as TextClause - -_re_boolean_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \(0, 1\)") -_re_column_name = re.compile(r'(?:(["`]?)(?:.*)\1\.)?(["`]?)(.*)\2') -_re_enum_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \((.+)\)") -_re_enum_item = re.compile(r"'(.*?)(? String) - for column in table.columns: - cls = column.type.__class__ - for supercls in cls.__mro__: - if hasattr(supercls, '__visit_name__'): - cls = supercls - if supercls.__name__ != supercls.__name__.upper() and not supercls.__name__.startswith('_'): - break - - column.type = column.type.adapt(cls) - - def add_imports(self, collector): - if self.table.columns: - collector.add_import(Column) - - for column in self.table.columns: - collector.add_import(column.type) - if column.server_default: - collector.add_literal_import('sqlalchemy.schema', 'FetchedValue') - - for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): - if isinstance(constraint, ForeignKeyConstraint): - if len(constraint.columns) > 1: - collector.add_literal_import('sqlalchemy', 'ForeignKeyConstraint') - else: - collector.add_literal_import('sqlalchemy', 'ForeignKey') - elif isinstance(constraint, UniqueConstraint): - if len(constraint.columns) > 1: - collector.add_literal_import('sqlalchemy', 'UniqueConstraint') - elif not isinstance(constraint, PrimaryKeyConstraint): - collector.add_import(constraint) - - for index in self.table.indexes: - if len(index.columns) > 1: - collector.add_import(index) - - -class ModelTable(Model): - def add_imports(self, collector): - super(ModelTable, self).add_imports(collector) - collector.add_import(Table) - - def render(self): - met = ' metadata,' if _flask_prepend == '' else '' - text = 't_{0} = {1}Table(\n {0!r},{2}\n'.format(self.table.name, _flask_prepend, met) - - for column in self.table.columns: - text += ' {0},\n'.format(_render_column(column, True)) - - for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): - if isinstance(constraint, PrimaryKeyConstraint): - continue - if isinstance(constraint, (ForeignKeyConstraint, UniqueConstraint)) and len(constraint.columns) == 1: - continue - text += ' {0},\n'.format(_render_constraint(constraint)) - - for index in self.table.indexes: - if len(index.columns) > 1: - text += ' {0},\n'.format(_render_index(index)) - - if self.schema: - text += " schema='{0}',\n".format(self.schema) - - return text.rstrip('\n,') + '\n)' - - -class ModelClass(Model): - parent_name = 'Base' - - def __init__(self, table, association_tables, inflect_engine, detect_joined, collector): - super(ModelClass, self).__init__(table) - self.name = self._tablename_to_classname(table.name, inflect_engine) - self.children = [] - self.attributes = OrderedDict() - - # Assign attribute names for columns - for column in table.columns: - self._add_attribute(column.name, column) - if _dataclass: - if column.type.python_type.__module__ != 'builtins': - collector.add_literal_import(column.type.python_type.__module__, column.type.python_type.__name__) - - - # Add many-to-one relationships - pk_column_names = set(col.name for col in table.primary_key.columns) - for constraint in sorted(table.constraints, key=_get_constraint_sort_key): - if isinstance(constraint, ForeignKeyConstraint): - target_cls = self._tablename_to_classname(constraint.elements[0].column.table.name, inflect_engine) - if (detect_joined and self.parent_name == 'Base' and - set(_get_column_names(constraint)) == pk_column_names): - self.parent_name = target_cls - else: - relationship_ = ManyToOneRelationship(self.name, target_cls, constraint, inflect_engine) - self._add_attribute(relationship_.preferred_name, relationship_) - - # Add many-to-many relationships - for association_table in association_tables: - fk_constraints = [c for c in association_table.constraints if isinstance(c, ForeignKeyConstraint)] - fk_constraints.sort(key=_get_constraint_sort_key) - target_cls = self._tablename_to_classname(fk_constraints[1].elements[0].column.table.name, inflect_engine) - relationship_ = ManyToManyRelationship(self.name, target_cls, association_table, inflect_engine) - self._add_attribute(relationship_.preferred_name, relationship_) - - @staticmethod - def _tablename_to_classname(tablename, inflect_engine): - camel_case_name = ''.join(part[:1].upper() + part[1:] for part in re.split(r'_|-', tablename)) - return inflect_engine.singular_noun(camel_case_name) or camel_case_name - - def _add_attribute(self, attrname, value): - attrname = tempname = _convert_to_valid_identifier(attrname) - counter = 1 - while tempname in self.attributes: - tempname = attrname + str(counter) - counter += 1 - - self.attributes[tempname] = value - return tempname - - def add_imports(self, collector): - super(ModelClass, self).add_imports(collector) - - if any(isinstance(value, Relationship) for value in self.attributes.values()): - collector.add_literal_import('sqlalchemy.orm', 'relationship') - - for child in self.children: - child.add_imports(collector) - - def render(self): - global _dataclass - - text = 'class {0}({1}):\n'.format(self.name, self.parent_name) - - if _dataclass: - text = '@dataclass\n' + text - - text += ' __tablename__ = {0!r}\n'.format(self.table.name) - - # Render constraints and indexes as __table_args__ - table_args = [] - for constraint in sorted(self.table.constraints, key=_get_constraint_sort_key): - if isinstance(constraint, PrimaryKeyConstraint): - continue - if isinstance(constraint, (ForeignKeyConstraint, UniqueConstraint)) and len(constraint.columns) == 1: - continue - table_args.append(_render_constraint(constraint)) - for index in self.table.indexes: - if len(index.columns) > 1: - table_args.append(_render_index(index)) - - table_kwargs = {} - if self.schema: - table_kwargs['schema'] = self.schema - - kwargs_items = ', '.join('{0!r}: {1!r}'.format(key, table_kwargs[key]) for key in table_kwargs) - kwargs_items = '{{{0}}}'.format(kwargs_items) if kwargs_items else None - if table_kwargs and not table_args: - text += ' __table_args__ = {0}\n'.format(kwargs_items) - elif table_args: - if kwargs_items: - table_args.append(kwargs_items) - if len(table_args) == 1: - table_args[0] += ',' - text += ' __table_args__ = (\n {0}\n )\n'.format(',\n '.join(table_args)) - - # Render columns - text += '\n' - for attr, column in self.attributes.items(): - if isinstance(column, Column): - show_name = attr != column.name - if _dataclass: - text += ' ' + attr + ' : ' + column.type.python_type.__name__ + '\n' - - text += ' {0} = {1}\n'.format(attr, _render_column(column, show_name)) - - # Render relationships - if any(isinstance(value, Relationship) for value in self.attributes.values()): - text += '\n' - for attr, relationship in self.attributes.items(): - if isinstance(relationship, Relationship): - text += ' {0} = {1}\n'.format(attr, relationship.render()) - - # Render subclasses - for child_class in self.children: - text += '\n\n' + child_class.render() - - return text - - -class Relationship(object): - def __init__(self, source_cls, target_cls): - super(Relationship, self).__init__() - self.source_cls = source_cls - self.target_cls = target_cls - self.kwargs = OrderedDict() - self.backref_name = _underscore(self.source_cls) - - def render(self): - text = _flask_prepend + 'relationship(' - args = [repr(self.target_cls)] - - if 'secondaryjoin' in self.kwargs: - text += '\n ' - delimiter, end = ',\n ', '\n )' - else: - delimiter, end = ', ', ')' - - args.extend([key + '=' + value for key, value in self.kwargs.items()]) - - return _re_invalid_relationship.sub('_', text + delimiter.join(args) + end) - - def make_backref(self, relationships, classes): - backref = self.backref_name - original_backref = backref - # Check if backref already exists for relationship source_cls to target_cls and add suffix - suffix = 0 - while (self.target_cls, backref) in [(x.target_cls, x.backref_name) for x in relationships]: - backref = original_backref + str('_{0}'.format(suffix)) - suffix += 1 - - self.kwargs['backref'] = repr(backref) - # Check if any of the target_cls inherit from other target_cls - # If so, modify backref name of descendant - # "backref({0}, lazy='dynamic')".format(repr(backref)) - for rel in [x for x in relationships if 'backref' in x.kwargs]: - if self.target_cls in classes and rel.target_cls in classes: - if _is_model_descendant(classes[self.target_cls], classes[rel.target_cls]): - self.backref_name = self.target_cls.lower() + '_' + backref - self.kwargs['backref'] = repr(self.backref_name) - if _is_model_descendant(classes[rel.target_cls], classes[self.target_cls]): - backref = rel.backref_name - rel.backref_name = rel.target_cls.lower() + '_' + backref - rel.kwargs['backref'] = repr(rel.backref_name) - - -class ManyToOneRelationship(Relationship): - def __init__(self, source_cls, target_cls, constraint, inflect_engine): - super(ManyToOneRelationship, self).__init__(source_cls, target_cls) - - column_names = _get_column_names(constraint) - colname = column_names[0] - tablename = constraint.elements[0].column.table.name - if not colname.endswith('_id'): - self.preferred_name = inflect_engine.singular_noun(tablename) or tablename - else: - self.preferred_name = colname[:-3] - self.backref_name = inflect_engine.plural_noun(self.backref_name) - - # Add uselist=False to One-to-One relationships - if any(isinstance(c, (PrimaryKeyConstraint, UniqueConstraint)) and - set(col.name for col in c.columns) == set(column_names) - for c in constraint.table.constraints): - self.kwargs['uselist'] = 'False' - - # Handle self referential relationships - if source_cls == target_cls: - self.preferred_name = 'parent' if not colname.endswith('_id') else colname[:-3] - pk_col_names = [col.name for col in constraint.table.primary_key] - self.kwargs['remote_side'] = '[{0}]'.format(', '.join(pk_col_names)) - - # If the two tables share more than one foreign key constraint, - # SQLAlchemy needs an explicit primaryjoin to figure out which column(s) to join with - # common_fk_constraints = _get_common_fk_constraints(constraint.table, constraint.elements[0].column.table) - # if len(common_fk_constraints) > 1: - # self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, constraint.columns[0], target_cls, constraint.elements[0].column.name) - if len(constraint.elements) > 1: # or - self.kwargs['primaryjoin'] = "'and_({0})'".format(', '.join(['{0}.{1} == {2}.{3}'.format(source_cls, k.parent.name, target_cls, k.column.name) - for k in constraint.elements])) - else: - self.kwargs['primaryjoin'] = "'{0}.{1} == {2}.{3}'".format(source_cls, column_names[0], target_cls, - constraint.elements[0].column.name) - - -class ManyToManyRelationship(Relationship): - def __init__(self, source_cls, target_cls, assocation_table, inflect_engine): - super(ManyToManyRelationship, self).__init__(source_cls, target_cls) - prefix = assocation_table.schema + '.' if assocation_table.schema is not None else '' - self.kwargs['secondary'] = repr(prefix + assocation_table.name) - constraints = [c for c in assocation_table.constraints if isinstance(c, ForeignKeyConstraint)] - constraints.sort(key=_get_constraint_sort_key) - colname = _get_column_names(constraints[1])[0] - tablename = constraints[1].elements[0].column.table.name - self.preferred_name = tablename if not colname.endswith('_id') else colname[:-3] + 's' - self.backref_name = inflect_engine.plural_noun(self.backref_name) - - # Handle self referential relationships - if source_cls == target_cls: - self.preferred_name = 'parents' if not colname.endswith('_id') else colname[:-3] + 's' - pri_pairs = zip(_get_column_names(constraints[0]), constraints[0].elements) - sec_pairs = zip(_get_column_names(constraints[1]), constraints[1].elements) - pri_joins = ['{0}.{1} == {2}.c.{3}'.format(source_cls, elem.column.name, assocation_table.name, col) - for col, elem in pri_pairs] - sec_joins = ['{0}.{1} == {2}.c.{3}'.format(target_cls, elem.column.name, assocation_table.name, col) - for col, elem in sec_pairs] - self.kwargs['primaryjoin'] = ( - repr('and_({0})'.format(', '.join(pri_joins))) if len(pri_joins) > 1 else repr(pri_joins[0])) - self.kwargs['secondaryjoin'] = ( - repr('and_({0})'.format(', '.join(sec_joins))) if len(sec_joins) > 1 else repr(sec_joins[0])) - - -class CodeGenerator(object): - header = '# coding: utf-8' - footer = '' - - def __init__(self, metadata, noindexes=False, noconstraints=False, - nojoined=False, noinflect=False, nobackrefs=False, - flask=False, ignore_cols=None, noclasses=False, nocomments=False, notables=False, dataclass=False): - super(CodeGenerator, self).__init__() - - if noinflect: - inflect_engine = _DummyInflectEngine() - else: - import inflect - inflect_engine = inflect.engine() - - # exclude these column names from consideration when generating association tables - _ignore_columns = ignore_cols or [] - - self.flask = flask - if not self.flask: - global _flask_prepend - _flask_prepend = '' - - self.nocomments = nocomments - - self.dataclass = dataclass - if self.dataclass: - global _dataclass - _dataclass = True - - # Pick association tables from the metadata into their own set, don't process them normally - links = defaultdict(lambda: []) - association_tables = set() - for table in metadata.tables.values(): - # Link tables have exactly two foreign key constraints and all columns are involved in them - # except for special columns like id, inserted, and updated - fk_constraints = [constr for constr in table.constraints if isinstance(constr, ForeignKeyConstraint)] - if len(fk_constraints) == 2 and all(col.foreign_keys for col in table.columns if col.name not in _ignore_columns): - association_tables.add(table.name) - tablename = sorted(fk_constraints, key=_get_constraint_sort_key)[0].elements[0].column.table.name - links[tablename].append(table) - - # Iterate through the tables and create model classes when possible - self.models = [] - self.collector = ImportCollector() - classes = {} - for table in sorted(metadata.tables.values(), key=lambda t: (t.schema or '', t.name)): - # Support for Alembic and sqlalchemy-migrate -- never expose the schema version tables - if table.name in ('alembic_version', 'migrate_version'): - continue - - if noindexes: - table.indexes.clear() - - if noconstraints: - table.constraints = set([table.primary_key]) - table.foreign_keys.clear() - for col in table.columns: - col.foreign_keys.clear() - else: - # Detect check constraints for boolean and enum columns - for constraint in table.constraints.copy(): - if isinstance(constraint, CheckConstraint): - sqltext = _get_compiled_expression(constraint.sqltext) - - # Turn any integer-like column with a CheckConstraint like "column IN (0, 1)" into a Boolean - match = _re_boolean_check_constraint.match(sqltext) - if match: - colname = _re_column_name.match(match.group(1)).group(3) - table.constraints.remove(constraint) - table.c[colname].type = Boolean() - continue - - # Turn any string-type column with a CheckConstraint like "column IN (...)" into an Enum - match = _re_enum_check_constraint.match(sqltext) - if match: - colname = _re_column_name.match(match.group(1)).group(3) - items = match.group(2) - if isinstance(table.c[colname].type, String): - table.constraints.remove(constraint) - if not isinstance(table.c[colname].type, Enum): - options = _re_enum_item.findall(items) - table.c[colname].type = Enum(*options, native_enum=False) - continue - - # Only generate classes when notables is set to True - if notables: - model = ModelClass(table, links[table.name], inflect_engine, not nojoined, self.collector) - classes[model.name] = model - elif not table.primary_key or table.name in association_tables or noclasses: - # Only form model classes for tables that have a primary key and are not association tables - model = ModelTable(table) - elif not noclasses: - model = ModelClass(table, links[table.name], inflect_engine, not nojoined, self.collector) - classes[model.name] = model - - self.models.append(model) - - # collect imports for models only if flask is not specified - if not self.flask: - model.add_imports(self.collector) - - # Nest inherited classes in their superclasses to ensure proper ordering - for model in classes.values(): - if model.parent_name != 'Base': - classes[model.parent_name].children.append(model) - self.models.remove(model) - - # If backrefs are allowed. Resolve any relationships conflicts where one - # target class might inherit from another - if not nobackrefs: - for model in classes.values(): - visited = [] - for relationship in model.attributes.values(): - if isinstance(relationship, Relationship): - relationship.make_backref(visited, classes) - visited.append(relationship) - - if self.flask: - # Add Flask-SQLAlchemy support - self.collector.add_literal_import('flask_sqlalchemy', 'SQLAlchemy') - parent_name = 'db.Model' - - for model in classes.values(): - if model.parent_name == 'Base': - model.parent_name = parent_name - else: - self.collector.add_literal_import('sqlalchemy.ext.declarative', 'declarative_base') - self.collector.add_literal_import('sqlalchemy', 'MetaData') - - - if self.dataclass: - self.collector.add_literal_import('dataclasses', 'dataclass') - - def render(self, outfile=sys.stdout): - - print(self.header, file=outfile) - - # Render the collected imports - print(self.collector.render() + '\n\n', file=outfile) - - if self.flask: - print('db = SQLAlchemy()', file=outfile) - else: - if any(isinstance(model, ModelClass) for model in self.models): - print('Base = declarative_base()\nmetadata = Base.metadata', file=outfile) - else: - print('metadata = MetaData()', file=outfile) - - # Render the model tables and classes - for model in self.models: - print('\n\n', file=outfile) - print(model.render().rstrip('\n'), file=outfile) - - if self.footer: - print(self.footer, file=outfile) diff --git a/vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py b/vendor/flask_sqlacodegen/sqlacodegen/dialects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py b/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py deleted file mode 100644 index e4eb907..0000000 --- a/vendor/flask_sqlacodegen/sqlacodegen/dialects/postgresql.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Provides missing Postgresql types. - -Use GeoAlchemy2 to support Postgis types. -Implement mockups for Point and LTree type, but generated models won't work out -of the box: a better way would be to use a package implementing proper classes -which could be imported in the target project. - -""" - -from sqlalchemy.dialects.postgresql.base import ischema_names, PGTypeCompiler -from sqlalchemy import types as sqltypes - -try: - import geoalchemy2 -except ImportError: - pass - - -class LTREE(sqltypes.TypeEngine): - """Postgresql LTREE type mockup.""" - - __visit_name__ = 'LTREE' - - -class POINT(sqltypes.TypeEngine): - """Postgresql POINT type mockup.""" - - __visit_name__ = 'POINT' - - -ischema_names['ltree'] = LTREE -ischema_names['point'] = POINT - -PGTypeCompiler.visit_LTREE = lambda self, type_: 'LTREE' -PGTypeCompiler.visit_POINT = lambda self, type_: 'POINT' diff --git a/vendor/flask_sqlacodegen/sqlacodegen/main.py b/vendor/flask_sqlacodegen/sqlacodegen/main.py deleted file mode 100644 index d8646e9..0000000 --- a/vendor/flask_sqlacodegen/sqlacodegen/main.py +++ /dev/null @@ -1,71 +0,0 @@ -""" """ -from __future__ import unicode_literals, division, print_function, absolute_import -import argparse -import codecs -import importlib -import sys - -from sqlalchemy.engine import create_engine -from sqlalchemy.schema import MetaData - -from sqlacodegen.codegen import CodeGenerator -import sqlacodegen -import sqlacodegen.dialects - - -def import_dialect_specificities(engine): - dialect_name = '.' + engine.dialect.name - try: - importlib.import_module(dialect_name, 'sqlacodegen.dialects') - except ImportError: - pass - - -def main(): - parser = argparse.ArgumentParser(description='Generates SQLAlchemy model code from an existing database.') - parser.add_argument('url', nargs='?', help='SQLAlchemy url to the database') - parser.add_argument('--version', action='store_true', help="print the version number and exit") - parser.add_argument('--schema', help='load tables from an alternate schema') - parser.add_argument('--default-schema', help='default schema name for local schema object') - parser.add_argument('--tables', help='tables to process (comma-separated, default: all)') - parser.add_argument('--noviews', action='store_true', help="ignore views") - parser.add_argument('--noindexes', action='store_true', help='ignore indexes') - parser.add_argument('--noconstraints', action='store_true', help='ignore constraints') - parser.add_argument('--nojoined', action='store_true', help="don't autodetect joined table inheritance") - parser.add_argument('--noinflect', action='store_true', help="don't try to convert tables names to singular form") - parser.add_argument('--noclasses', action='store_true', help="don't generate classes, only tables") - parser.add_argument('--notables', action='store_true', help="don't generate tables, only classes") - parser.add_argument('--outfile', help='file to write output to (default: stdout)') - parser.add_argument('--nobackrefs', action='store_true', help="don't include backrefs") - parser.add_argument('--flask', action='store_true', help="use Flask-SQLAlchemy columns") - parser.add_argument('--ignore-cols', help="Don't check foreign key constraints on specified columns (comma-separated)") - parser.add_argument('--nocomments', action='store_true', help="don't render column comments") - parser.add_argument('--dataclass', action='store_true', help="add dataclass decorators for JSON serialization") - args = parser.parse_args() - - if args.version: - print(sqlacodegen.version) - return - if not args.url: - print('You must supply a url\n', file=sys.stderr) - parser.print_help() - return - default_schema = args.default_schema - if not default_schema: - default_schema = None - - engine = create_engine(args.url) - import_dialect_specificities(engine) - metadata = MetaData() - tables = args.tables.split(',') if args.tables else None - ignore_cols = args.ignore_cols.split(',') if args.ignore_cols else None - metadata.reflect(engine, args.schema, not args.noviews, tables) - outfile = codecs.open(args.outfile, 'w', encoding='utf-8') if args.outfile else sys.stdout - generator = CodeGenerator(metadata, args.noindexes, args.noconstraints, - args.nojoined, args.noinflect, args.nobackrefs, - args.flask, ignore_cols, args.noclasses, args.nocomments, args.notables, args.dataclass) - generator.render(outfile) - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/vendor/flask_sqlacodegen/tox.ini b/vendor/flask_sqlacodegen/tox.ini deleted file mode 100644 index 1c16db7..0000000 --- a/vendor/flask_sqlacodegen/tox.ini +++ /dev/null @@ -1,26 +0,0 @@ -[tox] -envlist = py26,py27,py32,py33,py26-sqla08,py26-sqla07,py26-sqla06,pep8 - -[testenv] -deps=pytest -commands=py.test [] - -[testenv:py26-sqla08] -basepython=python2.6 -deps=pytest - sqlalchemy<=0.8.99 - -[testenv:py26-sqla07] -basepython=python2.6 -deps=pytest - sqlalchemy<=0.7.99 - -[testenv:py26-sqla06] -basepython=python2.6 -deps=pytest - sqlalchemy==0.6.0 - -[testenv:pep8] -deps=pytest - pytest-pep8 -commands=py.test --pep8 -m pep8 [] From 3dcc24cc4acc5aa34008c28f20127dc4eefe5a8a Mon Sep 17 00:00:00 2001 From: Reena Date: Thu, 18 Dec 2025 12:46:13 -0500 Subject: [PATCH 4/6] Add fail-fast: false to see all Python test results --- .github/workflows/bar-api.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/bar-api.yml b/.github/workflows/bar-api.yml index f6a68dc..b04383e 100644 --- a/.github/workflows/bar-api.yml +++ b/.github/workflows/bar-api.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-24.04 strategy: + fail-fast: false matrix: python-version: [3.10.18, 3.11, 3.12, 3.13] From fb84c4bd3a5ad3199f7c520f6975ff3e9555f92e Mon Sep 17 00:00:00 2001 From: Reena Date: Thu, 18 Dec 2025 13:12:35 -0500 Subject: [PATCH 5/6] Add Sphinx/reST docstrings to dynamic ORM functions --- DYNAMIC_ORM_SIMPLE_GUIDE.md | 48 ++++++++++++ api/services/efp_bootstrap.py | 114 +++++++++++++++++++++++++++- api/services/efp_data.py | 29 ++++++- scripts/bootstrap_simple_efp_dbs.py | 29 +++++++ 4 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 DYNAMIC_ORM_SIMPLE_GUIDE.md diff --git a/DYNAMIC_ORM_SIMPLE_GUIDE.md b/DYNAMIC_ORM_SIMPLE_GUIDE.md new file mode 100644 index 0000000..b501360 --- /dev/null +++ b/DYNAMIC_ORM_SIMPLE_GUIDE.md @@ -0,0 +1,48 @@ +# Dynamic ORM - Simple Guide + +## File Roles + +### `api/models/efp_schemas.py` +Defines database schemas in Python. Single source of truth for all columns, types, and test data. + +### `api/models/efp_dynamic.py` +Reads schemas and auto-generates SQLAlchemy ORM model classes at import time. No model files needed. + +### `api/services/efp_bootstrap.py` +Creates MySQL databases and tables from schemas. Inserts seed data for testing. + +### `scripts/bootstrap_simple_efp_dbs.py` +CLI tool to run the bootstrap. Usage: `python scripts/bootstrap_simple_efp_dbs.py --databases cannabis` + +### `api/services/efp_data.py` +Query engine. Tries MySQL first (production), falls back to SQLite (local dev). + +## Test Locally + +### With MySQL: +```bash +# Create databases +python scripts/bootstrap_simple_efp_dbs.py --user root --password root + +# Run tests +pytest tests/services/test_efp_data.py -v +``` + +### With SQLite: +```bash +# Just run tests - will use SQLite files in config/databases/ +pytest tests/services/test_efp_data.py -v +``` + +## How It Works on Server + +1. Docker starts → runs `config/init.sh` +2. `init.sh` runs bootstrap script +3. Bootstrap creates MySQL databases from schemas +4. Flask app connects to MySQL via SQLAlchemy binds +5. Queries use `db.engines.get("cannabis")` to get MySQL connection + +## Summary + +**Before:** Write .sql files + Python models manually +**Now:** Define schema once in Python → everything auto-generated diff --git a/api/services/efp_bootstrap.py b/api/services/efp_bootstrap.py index 27e566a..bf35c91 100644 --- a/api/services/efp_bootstrap.py +++ b/api/services/efp_bootstrap.py @@ -16,7 +16,15 @@ def _column_type(column_spec): - """Return the MySQL column type for a schema entry.""" + """ + Convert a column specification dictionary to a SQLAlchemy MySQL column type. + + :param column_spec: Dictionary containing column metadata from schema definition + :type column_spec: Dict[str, Any] + :return: SQLAlchemy column type object (VARCHAR, INTEGER, FLOAT, or TEXT) + :rtype: sqlalchemy.types.TypeEngine + :raises ValueError: If column type is not one of: string, integer, float, text + """ col_type = column_spec.get("type") if col_type == "string": return VARCHAR(column_spec["length"]) @@ -31,6 +39,22 @@ def _column_type(column_spec): def _build_table(metadata: MetaData, spec, db_name: str) -> Table: + """ + Build a SQLAlchemy Table object from a schema specification. + + Creates columns with proper types, constraints, defaults, and indexes based on + the schema definition. This Table object can be used to generate CREATE TABLE + SQL statements. + + :param metadata: SQLAlchemy MetaData object to attach the table to + :type metadata: sqlalchemy.schema.MetaData + :param spec: Database schema specification from SIMPLE_EFP_DATABASE_SCHEMAS + :type spec: Dict[str, Any] + :param db_name: Name of the database (used for index naming) + :type db_name: str + :return: SQLAlchemy Table object with all columns and indexes defined + :rtype: sqlalchemy.schema.Table + """ columns = [] for column in spec["columns"]: kwargs = {"nullable": column.get("nullable", True)} @@ -53,6 +77,22 @@ def _build_table(metadata: MetaData, spec, db_name: str) -> Table: def _build_url(host: str, port: int, user: str, password: str, database: str | None = None) -> URL: + """ + Build a SQLAlchemy database URL for MySQL connections. + + :param host: MySQL server hostname (e.g., 'localhost', 'BAR_mysqldb') + :type host: str + :param port: MySQL server port number (typically 3306) + :type port: int + :param user: MySQL username for authentication + :type user: str + :param password: MySQL password for authentication + :type password: str + :param database: Optional database name to connect to; if None, connects to server without selecting a database + :type database: str or None + :return: SQLAlchemy URL object for mysql+mysqldb connections + :rtype: sqlalchemy.engine.URL + """ return URL.create( drivername="mysql+mysqldb", username=user, @@ -64,12 +104,43 @@ def _build_url(host: str, port: int, user: str, password: str, database: str | N def ensure_database(server_url: URL, db_name: str, charset: str) -> None: + """ + Create a MySQL database if it doesn't already exist. + + Executes CREATE DATABASE IF NOT EXISTS with the specified character set. + Safe to call multiple times - will not error if database already exists. + + :param server_url: SQLAlchemy URL for MySQL server connection (without database selected) + :type server_url: sqlalchemy.engine.URL + :param db_name: Name of the database to create + :type db_name: str + :param charset: MySQL character set (e.g., 'latin1', 'utf8mb4') + :type charset: str + :return: None + :rtype: None + """ server_engine = create_engine(server_url) with server_engine.begin() as conn: conn.execute(text(f"CREATE DATABASE IF NOT EXISTS `{db_name}` DEFAULT CHARACTER SET {charset}")) def ensure_schema(db_url: URL, spec, db_name: str) -> Dict[str, object]: + """ + Create database tables and insert seed data if the table is empty. + + Uses SQLAlchemy's metadata.create_all() to generate CREATE TABLE statements + from the schema specification. If seed_rows are defined in the spec and the + table is empty, inserts the seed data. + + :param db_url: SQLAlchemy URL for the specific database connection + :type db_url: sqlalchemy.engine.URL + :param spec: Database schema specification from SIMPLE_EFP_DATABASE_SCHEMAS + :type spec: Dict[str, Any] + :param db_name: Name of the database (used for table naming) + :type db_name: str + :return: Dictionary with 'table' (table name) and 'seeded_rows' (count of inserted rows) + :rtype: Dict[str, object] + """ metadata = MetaData() table = _build_table(metadata, spec, db_name) engine = create_engine(db_url) @@ -97,8 +168,45 @@ def bootstrap_simple_efp_databases( databases: Iterable[str] | None = None, ) -> List[Dict[str, object]]: """ - Ensure that all requested simple eFP databases exist in MySQL and their schema - matches the definitions in SIMPLE_EFP_DATABASE_SCHEMAS. + Bootstrap simple eFP databases in MySQL from schema definitions. + + This is the main entry point for creating eFP databases. For each database: + 1. Creates the database if it doesn't exist + 2. Creates the sample_data table with schema from SIMPLE_EFP_DATABASE_SCHEMAS + 3. Inserts seed rows if the table is empty and seed_rows are defined + + Used by: + - scripts/bootstrap_simple_efp_dbs.py (CLI tool) + - config/init.sh (Docker/CI initialization) + - api/resources/efp_proxy.py (HTTP bootstrap endpoint) + + :param host: MySQL server hostname (e.g., 'localhost', 'BAR_mysqldb' for Docker) + :type host: str + :param port: MySQL server port number (typically 3306) + :type port: int + :param user: MySQL username with CREATE DATABASE privileges + :type user: str + :param password: MySQL password for authentication + :type password: str + :param databases: Optional list of specific databases to bootstrap; if None, bootstraps all databases in SIMPLE_EFP_DATABASE_SCHEMAS + :type databases: Iterable[str] or None + :return: List of result dictionaries, each containing 'database' (name), 'table' (table name), and 'seeded_rows' (count) + :rtype: List[Dict[str, object]] + :raises ValueError: If a requested database is not defined in SIMPLE_EFP_DATABASE_SCHEMAS + + Example:: + + results = bootstrap_simple_efp_databases( + host='localhost', + port=3306, + user='root', + password='password', + databases=['cannabis', 'dna_damage'] + ) + # Returns: [ + # {'database': 'cannabis', 'table': 'sample_data', 'seeded_rows': 1}, + # {'database': 'dna_damage', 'table': 'sample_data', 'seeded_rows': 1} + # ] """ results: List[Dict[str, object]] = [] diff --git a/api/services/efp_data.py b/api/services/efp_data.py index 9f4f510..8a33c49 100644 --- a/api/services/efp_data.py +++ b/api/services/efp_data.py @@ -112,7 +112,34 @@ def agi_to_probset(gene_id: str) -> Optional[str]: def _iter_engine_candidates(database: str) -> Iterable[Tuple[str, Engine, bool]]: - """yield engine candidates (bind first, then sqlite mirror)""" + """ + Yield database engine candidates with MySQL priority and SQLite fallback. + + This function enables dual-mode operation: + - Production/CI: Uses MySQL via Flask-SQLAlchemy binds + - Local development: Falls back to SQLite mirror files + + Priority order: + 1. Flask-SQLAlchemy bind (MySQL) - if Flask app context exists + 2. SQLite mirror file - if exists in config/databases/ + + :param database: Database name (e.g., 'cannabis', 'dna_damage') + :type database: str + :yields: Tuples of (engine_type, engine, is_sqlite) where: + - engine_type: 'sqlalchemy_bind' or 'sqlite_mirror' + - engine: SQLAlchemy Engine object + - is_sqlite: True if SQLite, False if MySQL + :rtype: Iterator[Tuple[str, sqlalchemy.engine.Engine, bool]] + + Example:: + + for engine_type, engine, is_sqlite in _iter_engine_candidates('cannabis'): + try: + result = engine.execute('SELECT * FROM sample_data LIMIT 1') + break # Found working engine + except: + continue # Try next engine + """ # prefer live mysql binds but fall back to sqlite mirrors when needed db_path = DATABASE_DIR / DYNAMIC_DATABASE_SCHEMAS[database]["filename"] if has_app_context(): diff --git a/scripts/bootstrap_simple_efp_dbs.py b/scripts/bootstrap_simple_efp_dbs.py index 3c4cc92..b893cc0 100644 --- a/scripts/bootstrap_simple_efp_dbs.py +++ b/scripts/bootstrap_simple_efp_dbs.py @@ -14,6 +14,19 @@ def _default_host() -> str: + """ + Determine the default MySQL hostname from environment variables. + + Priority order: + 1. DB_HOST environment variable (explicit override) + 2. MYSQL_HOST environment variable (alternative name) + 3. 'localhost' (default for local dev and GitHub Actions CI) + + Docker deployments should set DB_HOST=BAR_mysqldb explicitly. + + :return: MySQL hostname to use for connections + :rtype: str + """ if os.environ.get("DB_HOST"): return os.environ["DB_HOST"] if os.environ.get("MYSQL_HOST"): @@ -25,6 +38,12 @@ def _default_host() -> str: def parse_args() -> argparse.Namespace: + """ + Parse command-line arguments for the bootstrap script. + + :return: Parsed arguments containing host, port, user, password, and optional database list + :rtype: argparse.Namespace + """ parser = argparse.ArgumentParser(description="Create simple eFP MySQL databases from in-memory schemas.") parser.add_argument("--host", default=_default_host(), help="MySQL hostname (default: %(default)s)") parser.add_argument("--port", type=int, default=int(os.environ.get("DB_PORT", 3306)), help="MySQL port") @@ -39,6 +58,16 @@ def parse_args() -> argparse.Namespace: def main(): + """ + Main entry point for the bootstrap CLI script. + + Parses command-line arguments and calls bootstrap_simple_efp_databases() + to create MySQL databases. Prints success messages for each database created. + + Output format: [ok] ensured database_name.table_name (seeded N rows) + + :raises SQLAlchemyError: If database creation or connection fails + """ args = parse_args() results = bootstrap_simple_efp_databases( host=args.host, From 339746a432ce5d0eba88e503ade3dec5a0b55085 Mon Sep 17 00:00:00 2001 From: Reena Date: Thu, 18 Dec 2025 13:15:06 -0500 Subject: [PATCH 6/6] comment style --- DYNAMIC_ORM_SIMPLE_GUIDE.md | 48 ------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 DYNAMIC_ORM_SIMPLE_GUIDE.md diff --git a/DYNAMIC_ORM_SIMPLE_GUIDE.md b/DYNAMIC_ORM_SIMPLE_GUIDE.md deleted file mode 100644 index b501360..0000000 --- a/DYNAMIC_ORM_SIMPLE_GUIDE.md +++ /dev/null @@ -1,48 +0,0 @@ -# Dynamic ORM - Simple Guide - -## File Roles - -### `api/models/efp_schemas.py` -Defines database schemas in Python. Single source of truth for all columns, types, and test data. - -### `api/models/efp_dynamic.py` -Reads schemas and auto-generates SQLAlchemy ORM model classes at import time. No model files needed. - -### `api/services/efp_bootstrap.py` -Creates MySQL databases and tables from schemas. Inserts seed data for testing. - -### `scripts/bootstrap_simple_efp_dbs.py` -CLI tool to run the bootstrap. Usage: `python scripts/bootstrap_simple_efp_dbs.py --databases cannabis` - -### `api/services/efp_data.py` -Query engine. Tries MySQL first (production), falls back to SQLite (local dev). - -## Test Locally - -### With MySQL: -```bash -# Create databases -python scripts/bootstrap_simple_efp_dbs.py --user root --password root - -# Run tests -pytest tests/services/test_efp_data.py -v -``` - -### With SQLite: -```bash -# Just run tests - will use SQLite files in config/databases/ -pytest tests/services/test_efp_data.py -v -``` - -## How It Works on Server - -1. Docker starts → runs `config/init.sh` -2. `init.sh` runs bootstrap script -3. Bootstrap creates MySQL databases from schemas -4. Flask app connects to MySQL via SQLAlchemy binds -5. Queries use `db.engines.get("cannabis")` to get MySQL connection - -## Summary - -**Before:** Write .sql files + Python models manually -**Now:** Define schema once in Python → everything auto-generated