This commit is contained in:
Kaivan Kamali
2020-04-27 10:30:30 -04:00
172 changed files with 4822 additions and 1589 deletions
+1
View File
@@ -0,0 +1 @@
api
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --skip_flakey_fails -api "$@"
+1
View File
@@ -0,0 +1 @@
framework
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --framework "$@"
+1
View File
@@ -0,0 +1 @@
integration
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
DOCKER_RUN_EXTRA_ARGS="--privileged" ./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --integration "$@"
+1
View File
@@ -0,0 +1 @@
main-tools
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
./run_tests.sh --dockerize --python3 --db postgres --clean_pyc -main "$@"
+2 -3
View File
@@ -20,8 +20,7 @@ virtualenv "$GALAXY_VIRTUAL_ENV"
chown -R "$GALAXY_TEST_UID:$GALAXY_TEST_UID" "$GALAXY_VIRTUAL_ENV"
cd /galaxy
HOME=/galaxy
sudo -E -u "#${GALAXY_TEST_UID}" ./scripts/common_startup.sh || { echo "common_startup.sh failed"; exit 1; }
sudo -E -H -u "#${GALAXY_TEST_UID}" ./scripts/common_startup.sh || { echo "common_startup.sh failed"; exit 1; }
echo "Waiting for postgres to become available"
while ! nc -z postgres 5432;
@@ -34,7 +33,7 @@ echo "Creating postgres database for Galaxy"
createdb -w -U postgres -h postgres galaxy
echo "Starting and waiting for Galaxy daemon(s)"
sudo -E -u "#${GALAXY_TEST_UID}" GALAXY_RUN_ALL=1 bash "$GALAXY_ROOT/run.sh" --daemon --wait
sudo -E -H -u "#${GALAXY_TEST_UID}" GALAXY_RUN_ALL=1 bash "$GALAXY_ROOT/run.sh" --daemon --wait
echo "Galaxy daemon ready, monitoring Galaxy logs"
tail -f "$GALAXY_ROOT/main.log"
+1
View File
@@ -0,0 +1 @@
selenium
-26
View File
@@ -1,26 +0,0 @@
#!/bin/bash
# Enable retries on tests to reduce chances of transient failures.
: ${GALAXY_TEST_SELENIUM_RETRIES:=1}
# If in Jenkins environment, use it for artifacts.
if [ -n "$BUILD_NUMBER" ];
then
: ${GALAXY_TEST_ERRORS_DIRECTORY:=${BUILD_NUMBER}-test-errors}
: ${GALAXY_TEST_SCREENSHOTS_DIRECTORY:=${BUILD_NUMBER}-test-screenshots}
else
: ${GALAXY_TEST_ERRORS_DIRECTORY:=database/test-errors}
: ${GALAXY_TEST_SCREENSHOTS_DIRECTORY:=database/test-screenshots}
fi
mkdir -p "$GALAXY_TEST_ERRORS_DIRECTORY"
mkdir -p "$GALAXY_TEST_SCREENSHOTS_DIRECTORY"
mkdir -p ~/.jenkins-yarn-cache
YARN_CACHE_FOLDER=~/.jenkins-yarn-cache
# Start Selenium server in the test Docker container.
DOCKER_RUN_EXTRA_ARGS="${DOCKER_RUN_EXTRA_ARGS} --shm-size=2g -v $YARN_CACHE_FOLDER:$YARN_CACHE_FOLDER -e YARN_CACHE_FOLDER=$YARN_CACHE_FOLDER -e USE_SELENIUM=1 -e GALAXY_TEST_SELENIUM_RETRIES=${GALAXY_TEST_SELENIUM_RETRIES} -e GALAXY_TEST_ERRORS_DIRECTORY=${GALAXY_TEST_ERRORS_DIRECTORY} -e GALAXY_TEST_SCREENSHOTS_DIRECTORY=${GALAXY_TEST_SCREENSHOTS_DIRECTORY}"
export DOCKER_RUN_EXTRA_ARGS
./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --skip_flakey_fails --selenium "$@"
+3 -35
View File
@@ -81,23 +81,6 @@ jobs:
key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo
py27_lint:
docker:
- image: circleci/python:2.7
<<: *set_workdir
steps:
- *restore_repo_cache
- *install_tox
- run: tox -e py27-lint
py27_unit:
docker:
- image: circleci/python:2.7
<<: *set_workdir
steps:
- *restore_repo_cache
# Ensure minimum virtualenv version due to https://github.com/pypa/virtualenv/issues/1670
- run: sudo pip install tox 'virtualenv>=20.0.8'
- run: tox -e py27-unit
py35_docstring:
docker:
- image: circleci/python:3.5
@@ -106,14 +89,6 @@ jobs:
- *restore_repo_cache
- *install_tox
- run: tox -e py35-lint_docstring_include_list
py27_first_startup:
docker:
- image: circleci/python:2.7
<<: *set_workdir
steps:
- *restore_repo_cache
- *install_tox
- run: tox -e py27-first_startup
py35_lint:
docker:
- image: circleci/python:3.5
@@ -136,10 +111,9 @@ jobs:
<<: *set_workdir
steps:
- *restore_repo_cache
- run: sh scripts/common_startup.sh
- run: wget -q https://github.com/jmchilton/galaxy-downloads/raw/master/db_gx_rev_0127.sqlite
- run: mv db_gx_rev_0127.sqlite database/universe.sqlite
- run: sh manage_db.sh -c ./config/galaxy.yml.sample upgrade
# Use this job to test the latest migrations
- run: wget -q https://github.com/jmchilton/galaxy-downloads/raw/master/db_gx_rev_0141.sqlite
- run: mv db_gx_rev_0141.sqlite database/universe.sqlite
- *install_tox
- run: tox -e py35-first_startup
validate_test_tools:
@@ -195,12 +169,6 @@ workflows:
get_code_and_test:
jobs:
- get_code
- py27_lint:
<<: *requires_get_code
- py27_unit:
<<: *requires_get_code
- py27_first_startup:
<<: *requires_get_code
- py35_docstring:
<<: *requires_get_code
- py35_lint:
@@ -0,0 +1,45 @@
name: Integration Selenium
on: [push, pull_request]
env:
GALAXY_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
GALAXY_TEST_SELENIUM_REMOTE: '1'
GALAXY_TEST_SELENIUM_REMOTE_PORT: "4444"
GALAXY_SKIP_CLIENT_BUILD: '0'
jobs:
test:
name: Test
runs-on: ubuntu-18.04
strategy:
matrix:
python-version: [3.7]
services:
postgres:
image: postgres:11
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
selenium:
image: selenium/standalone-chrome:3.141.59
ports:
- 4444:4444
steps:
- name: Prune unused docker image, volumes and containers
run: docker system prune -a -f
- uses: actions/checkout@v2
with:
path: 'galaxy root'
- uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dir
uses: actions/cache@v1
id: pip-cache
with:
path: ~/.cache/pip
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
- name: Run tests
run: './run_tests.sh -integration test/integration_selenium'
working-directory: 'galaxy root'
+1
View File
@@ -178,3 +178,4 @@ packages/*/*.egg-info
config/plugins/visualizations/**/static/script.js
# TODO: Really need to follow up on this and make it standard.
config/plugins/visualizations/**/static/main.css
config/plugins/visualizations/**/static/plugin_build_hash.txt
+14 -18
View File
@@ -5,14 +5,14 @@ The latest information about Galaxy can be found on the `Galaxy Community Hub <h
Community support is available at `Galaxy Help <https://help.galaxyproject.org/>`__.
.. image:: https://img.shields.io/badge/chat-irc.freenode.net%23galaxyproject-blue.svg
:target: https://webchat.freenode.net/?channels=galaxyproject
:alt: Chat on irc
.. image:: https://img.shields.io/badge/chat-gitter-blue.svg
:target: https://gitter.im/galaxyproject/Lobby
:alt: Chat on gitter
.. image:: https://img.shields.io/badge/chat-irc.freenode.net%23galaxyproject-blue.svg
:target: https://webchat.freenode.net/?channels=galaxyproject
:alt: Chat on irc
.. image:: https://img.shields.io/badge/release-documentation-blue.svg
:target: https://docs.galaxyproject.org/en/master/
:alt: Release Documentation
@@ -24,12 +24,12 @@ Community support is available at `Galaxy Help <https://help.galaxyproject.org/>
Galaxy Quickstart
=================
Galaxy requires Python 2.7 To check your python version, run:
Galaxy requires Python 3.5 or 3.6 . To check your Python version, run:
.. code:: console
$ python -V
Python 2.7.3
Python 3.6.10
Start Galaxy:
@@ -38,18 +38,19 @@ Start Galaxy:
$ sh run.sh
Once Galaxy completes startup, you should be able to view Galaxy in your
browser at:
browser at: http://localhost:8080
http://localhost:8080
For more installation details please see: https://getgalaxy.org/
Configuration & Tools
=====================
Documentation is available at: https://docs.galaxyproject.org/
You may wish to make changes from the default configuration. This can be
done in the ``config/galaxy.ini`` file.
Tutorials on how to use Galaxy, perform scientific analyses with it, develop Galaxy and its tools, and admin a Galaxy server are at: https://training.galaxyproject.org/
Tools
=====
Tools can be either installed from the Tool Shed or added manually.
For details please see the `tutorial <https://galaxyproject.org/admin/tools/add-tool-from-toolshed-tutorial/>`__.
For details please see the `tutorial <https://galaxyproject.org/admin/tools/add-tool-from-toolshed-tutorial/>`__.
Note that not all dependencies for the tools provided in the
``tool_conf.xml.sample`` are included. To install them please visit
"Manage dependencies" in the admin interface.
@@ -58,8 +59,3 @@ Issues and Galaxy Development
=============================
Please see `CONTRIBUTING.md <CONTRIBUTING.md>`_ .
Roadmap
=============================
Interested in the next steps for Galaxy? Take a look at the `roadmap <https://github.com/galaxyproject/galaxy/projects/8>`__.
+1
View File
@@ -95,6 +95,7 @@ export { mountJobMetrics } from "components/JobMetrics";
export { mountJobParameters } from "components/JobParameters";
export { mountWorkflowEditor } from "components/Workflow/Editor/mount";
export { mountPageDisplay } from "components/PageDisplay";
export { mountDestinationParams } from "components/JobDestinationParams";
// Used in common.mako
export { default as store } from "storemodern";
@@ -0,0 +1,67 @@
import Vuex from "vuex";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { mount, createLocalVue } from "@vue/test-utils";
import { createStore } from "../../store";
import flushPromises from "flush-promises";
import JobDestinationParams from "./JobDestinationParams";
import jobDestinationResponse from "./testData/jobDestinationResponse";
const JOB_ID = "foo_job_id";
describe("JobDestinationParams/JobDestinationParams.vue", () => {
const localVue = createLocalVue();
localVue.use(Vuex);
const responseKeys = Object.keys(jobDestinationResponse);
let testStore, axiosMock, wrapper;
beforeEach(async () => {
axiosMock = new MockAdapter(axios);
testStore = createStore();
const propsData = {
jobId: JOB_ID,
};
axiosMock.onGet(`/api/jobs/${JOB_ID}/destination_params`).reply(200, jobDestinationResponse);
wrapper = mount(JobDestinationParams, {
store: testStore,
propsData,
localVue,
});
await flushPromises();
assert(responseKeys.length > 0, "test data is invalid!");
});
afterEach(() => {
axiosMock.restore();
});
it("destination parameters should exist", async () => {
expect(Object.keys(wrapper.vm.jobDestinationParams).length).to.equals(responseKeys.length);
expect(wrapper.vm.jobId).to.equals(JOB_ID);
expect(wrapper.vm.jobDestinationParams["docker_net"]).to.equals("bridge");
expect(wrapper.vm.jobDestinationParams["docker_set_user"]).to.equals(null);
});
it("destination parameters should be rendered", async () => {
console.log(wrapper.html());
const paramsTable = wrapper.find("#destination_parameters");
expect(paramsTable.isVisible()).to.equals(true);
const params = paramsTable.findAll("tbody > tr");
expect(params.length).to.equals(responseKeys.length);
for (let counter = 0; counter < responseKeys.length - 1; counter++) {
const parameter = params.at(counter).findAll("td");
const parameterTitle = parameter.at(0).text();
const parameterValue = parameter.at(1).text();
assert(responseKeys.includes(parameterTitle), "rendered parameter should exist in test data!");
// since we render null as an empty string, rendered empty string should always equal null in test data
assert(
jobDestinationResponse[parameterTitle] === (parameterValue === "" ? null : parameterValue),
"parameter value is not equal to test data!"
);
}
});
});
@@ -0,0 +1,36 @@
<template>
<div>
<table id="destination_parameters" class="tabletip info_data_table">
<tbody>
<tr v-for="(value, title) in jobDestinationParams" :key="title">
<td>{{ title }}</td>
<td>{{ value }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import { mapCacheActions } from "vuex-cache";
export default {
props: {
jobId: {
type: String,
required: true,
},
},
created: function () {
this.fetchJobDestinationParams(this.jobId);
},
computed: {
jobDestinationParams: function () {
return this.$store.getters.jobDestinationParams(this.jobId);
},
},
methods: {
...mapCacheActions(["fetchJobDestinationParams"]),
},
};
</script>
@@ -0,0 +1,3 @@
export { default as JobDestinationParams } from "./JobDestinationParams";
export { mountDestinationParams } from "./mount";
@@ -0,0 +1,13 @@
/**
* Endpoint for mounting job metrics from non-Vue environment.
*/
import $ from "jquery";
import JobDestinationParams from "./JobDestinationParams.vue";
import { mountVueComponent } from "utils/mountVueComponent";
export const mountDestinationParams = (propsData = {}) => {
$(".job-destination-parameters").each((index, el) => {
propsData.jobId = $(el).attr("job_id");
mountVueComponent(JobDestinationParams)(propsData, el);
});
};
@@ -0,0 +1,12 @@
{
"Runner": "local",
"Runner Job ID": "23027",
"Handler": "main.web.1",
"docker_auto_rm": "true",
"docker_enabled": "true",
"docker_net": "bridge",
"docker_set_user": null,
"docker_sudo": "false",
"docker_volumes": "$galaxy_root:ro,$tool_directory:ro,$job_directory:rw,$working_directory:rw,$default_file_path:ro",
"require_container": "true"
}
@@ -5,6 +5,7 @@ import { mount, createLocalVue } from "@vue/test-utils";
import { createStore } from "../../store";
import flushPromises from "flush-promises";
import JobMetrics from "./JobMetrics";
import ec2 from "./ec2.json";
const JOB_ID = "moo";
@@ -65,4 +66,63 @@ describe("JobMetrics/JobMetrics.vue", () => {
expect(metricsTables.at(1).find(".metrics_plugin_title").text()).to.equals("extended");
expect(metricsTables.at(1).findAll("tr").length).to.equals(1);
});
it("should render correct AWS Estimates", async () => {
let deriveRenderedAwsEstimate = async (cores, seconds, memory) => {
const JOB_ID = Math.random().toString(36).substring(2);
const propsData = {
jobId: JOB_ID,
aws_estimate: "True",
};
const metricsResponse = [
{ plugin: "core", name: "galaxy_slots", raw_value: cores },
{ plugin: "core", name: "runtime_seconds", raw_value: seconds },
{ plugin: "core", name: "galaxy_memory_mb", raw_value: memory },
];
axiosMock.onGet(`/api/jobs/${JOB_ID}/metrics`).reply(200, metricsResponse);
const wrapper = mount(JobMetrics, {
store: testStore,
propsData,
localVue,
});
// Wait for axios and rendering.
await flushPromises();
const estimates = {};
if (!wrapper.find("#aws-estimate").exists()) return false;
estimates.cost = wrapper.find("#aws-estimate > b").text();
estimates.vcpus = wrapper.find("#aws_vcpus").text();
estimates.cpu = wrapper.find("#aws_cpu").text();
estimates.mem = wrapper.find("#aws_mem").text();
estimates.name = wrapper.find("#aws_name").text();
return estimates;
};
let assertAwsInstance = (estimates) => {
const instance = ec2.find((instance) => estimates.name === instance.name);
expect(estimates.mem).to.equals(instance.mem.toString());
expect(estimates.vcpus).to.equals(instance.vcpus.toString());
expect(estimates.cpu).to.equals(instance.cpu.toString());
};
let estimates_small = await deriveRenderedAwsEstimate("1.0000000", "9.0000000", "2048.0000000");
expect(estimates_small.name).to.equals("t2.small");
expect(estimates_small.cost).to.equals("0.00 USD");
assertAwsInstance(estimates_small);
let estimates_large = await deriveRenderedAwsEstimate("40.0000000", "18000.0000000", "194560.0000000");
expect(estimates_large.name).to.equals("m5d.12xlarge");
expect(estimates_large.cost).to.equals("16.32 USD");
assertAwsInstance(estimates_large);
let estimates_not_available = await deriveRenderedAwsEstimate(
"99999.0000000",
"18000.0000000",
"99999.0000000"
);
expect(estimates_not_available).to.equals(false);
});
});
@@ -12,12 +12,27 @@
</tbody>
</table>
</div>
<div id="aws-estimate" v-if="isAwsEstimate && awsEstimate">
<h3>AWS estimate</h3>
<b>{{ awsEstimate.price }} USD</b><br />
This job requested {{ awsEstimate.vcpus }} cores and {{ awsEstimate.memory }} Gb. Given this, the smallest
EC2 machine we could find is <span id="aws_name">{{ awsEstimate.instance.name }}</span> (<span
id="aws_mem"
>{{ awsEstimate.instance.mem }}</span
>
GB / <span id="aws_vcpus">{{ awsEstimate.instance.vcpus }}</span> vCPUs /
<span id="aws_cpu">{{ awsEstimate.instance.cpu }}</span
>). That instance is priced at {{ awsEstimate.instance.price }} USD/hour.<br />
Please note, that those numbers are only estimates, all jobs are always free of charge for all users.
</div>
</div>
</template>
<script>
import { mapCacheActions } from "vuex-cache";
import { mapGetters } from "vuex";
import ec2 from "./ec2.json";
export default {
props: {
@@ -27,6 +42,9 @@ export default {
datasetId: {
type: String,
},
aws_estimate: {
type: String,
},
datasetType: {
type: String,
default: "hda",
@@ -48,6 +66,40 @@ export default {
},
computed: {
...mapGetters(["getJobMetricsByDatasetId", "getJobMetricsByJobId"]),
isAwsEstimate: function () {
return this.aws_estimate && this.aws_estimate.toUpperCase() === "true".toUpperCase();
},
awsEstimate: function () {
if (!this.isAwsEstimate) return;
const aws = {};
this.jobMetrics.forEach((metric) => {
switch (metric.name) {
case "galaxy_memory_mb":
aws.memory = parseInt(metric.raw_value);
break;
case "galaxy_slots":
aws.vcpus = parseInt(metric.raw_value);
break;
case "runtime_seconds":
aws.seconds = parseInt(metric.raw_value);
break;
default:
}
});
if (aws.memory) aws.memory /= 1024;
// if memory was not specified, assign the smallest amount (we judge based on CPU-count only)
else aws.memory = 0.5;
// ec2 is already pre-sorted
aws.instance = ec2.find((ec) => {
return ec.mem >= aws.memory && ec.vcpus >= aws.vcpus;
});
if (aws.instance === undefined) return;
aws.price = ((aws.seconds * aws.instance.price) / 3600).toFixed(2);
return aws;
},
jobMetrics: function () {
if (this.jobId) {
return this.getJobMetricsByJobId(this.jobId);
@@ -0,0 +1,306 @@
[
{
"name": "t2.nano",
"mem": 0.5,
"price": 0.0067,
"priceunit": "Hrs",
"vcpus": 1,
"cpu": "Intel Xeon Family"
},
{
"name": "t3.nano",
"mem": 0.5,
"price": 0.006,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "t2.micro",
"mem": 1,
"price": 0.0134,
"priceunit": "Hrs",
"vcpus": 1,
"cpu": "Intel Xeon Family"
},
{
"name": "t3.micro",
"mem": 1,
"price": 0.012,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "t2.small",
"mem": 2,
"price": 0.0268,
"priceunit": "Hrs",
"vcpus": 1,
"cpu": "Intel Xeon Family"
},
{
"name": "t3.small",
"mem": 2,
"price": 0.024,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "m3.medium",
"mem": 3.75,
"price": 0.079,
"priceunit": "Hrs",
"vcpus": 1,
"cpu": "Intel Xeon E5-2670 v2 (Ivy Bridge/Sandy Bridge)"
},
{
"name": "t2.medium",
"mem": 4,
"price": 0.0536,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon Family"
},
{
"name": "t3.medium",
"mem": 4,
"price": 0.048,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "m3.large",
"mem": 7.5,
"price": 0.158,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon E5-2670 v2 (Ivy Bridge/Sandy Bridge)"
},
{
"name": "t2.large",
"mem": 8,
"price": 0.1072,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon Family"
},
{
"name": "t3.large",
"mem": 8,
"price": 0.096,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "m5.large",
"mem": 8,
"price": 0.115,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5d.large",
"mem": 8,
"price": 0.136,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.large",
"mem": 8,
"price": 0.12,
"priceunit": "Hrs",
"vcpus": 2,
"cpu": "Intel Xeon E5-2676 v3 (Haswell)"
},
{
"name": "m3.xlarge",
"mem": 15,
"price": 0.315,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Xeon E5-2670 v2 (Ivy Bridge/Sandy Bridge)"
},
{
"name": "m5.xlarge",
"mem": 16,
"price": 0.23,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.xlarge",
"mem": 16,
"price": 0.24,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Xeon E5-2676 v3 (Haswell)"
},
{
"name": "t3.xlarge",
"mem": 16,
"price": 0.192,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "t2.xlarge",
"mem": 16,
"price": 0.2144,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Xeon Family"
},
{
"name": "m5d.xlarge",
"mem": 16,
"price": 0.272,
"priceunit": "Hrs",
"vcpus": 4,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m3.2xlarge",
"mem": 30,
"price": 0.632,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Xeon E5-2670 v2 (Ivy Bridge/Sandy Bridge)"
},
{
"name": "m5d.2xlarge",
"mem": 32,
"price": 0.544,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5.2xlarge",
"mem": 32,
"price": 0.46,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.2xlarge",
"mem": 32,
"price": 0.48,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Xeon E5-2676 v3 (Haswell)"
},
{
"name": "t3.2xlarge",
"mem": 32,
"price": 0.384,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Skylake E5 2686 v5 (2.5 GHz)"
},
{
"name": "t2.2xlarge",
"mem": 32,
"price": 0.4288,
"priceunit": "Hrs",
"vcpus": 8,
"cpu": "Intel Xeon Family"
},
{
"name": "m5d.4xlarge",
"mem": 64,
"price": 1.088,
"priceunit": "Hrs",
"vcpus": 16,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.4xlarge",
"mem": 64,
"price": 0.96,
"priceunit": "Hrs",
"vcpus": 16,
"cpu": "Intel Xeon E5-2676 v3 (Haswell)"
},
{
"name": "m5.4xlarge",
"mem": 64,
"price": 0.92,
"priceunit": "Hrs",
"vcpus": 16,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.10xlarge",
"mem": 160,
"price": 2.4,
"priceunit": "Hrs",
"vcpus": 40,
"cpu": "Intel Xeon E5-2676 v3 (Haswell)"
},
{
"name": "m5d.12xlarge",
"mem": 192,
"price": 3.264,
"priceunit": "Hrs",
"vcpus": 48,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5.12xlarge",
"mem": 192,
"price": 2.76,
"priceunit": "Hrs",
"vcpus": 48,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m4.16xlarge",
"mem": 256,
"price": 3.84,
"priceunit": "Hrs",
"vcpus": 64,
"cpu": "Intel Xeon E5-2686 v4 (Broadwell)"
},
{
"name": "m5d.metal",
"mem": 384,
"price": 6.528,
"priceunit": "Hrs",
"vcpus": 96,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5.metal",
"mem": 384,
"price": 5.52,
"priceunit": "Hrs",
"vcpus": 96,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5d.24xlarge",
"mem": 384,
"price": 6.528,
"priceunit": "Hrs",
"vcpus": 96,
"cpu": "Intel Xeon Platinum 8175"
},
{
"name": "m5.24xlarge",
"mem": 384,
"price": 5.52,
"priceunit": "Hrs",
"vcpus": 96,
"cpu": "Intel Xeon Platinum 8175"
}
]
@@ -8,11 +8,13 @@ import { mountVueComponent } from "utils/mountVueComponent";
export const mountJobMetrics = (propsData = {}) => {
$(".job-metrics").each((index, el) => {
const jobId = $(el).attr("job_id");
const aws_estimate = $(el).attr("aws_estimate");
const datasetId = $(el).attr("dataset_id");
const datasetType = $(el).attr("dataset_type") || "hda";
propsData.jobId = jobId;
propsData.datasetId = datasetId;
propsData.datasetType = datasetType;
propsData.aws_estimate = aws_estimate;
mountVueComponent(JobMetrics)(propsData, el);
});
};
@@ -0,0 +1,138 @@
<template>
<div class="rule-column-selector" v-if="!multiple || !ordered">
<label class="d-flex justify-content-end align-items-center">
<span class="mr-auto" v-b-tooltip.hover :title="help">{{ label }}</span>
<div class="mr-1" v-b-tooltip.hover :title="title">
<select2 :value="target" @input="handleInput" :multiple="multiple">
<option v-for="(col, index) in colHeaders" :value="index" :key="col">{{ col }}</option>
</select2>
</div>
<slot></slot>
</label>
</div>
<div class="rule-column-selector" v-else>
<span>{{ label }}</span>
<slot></slot>
<ol>
<li v-for="(targetEl, index) in target" :index="index" :key="targetEl" class="rule-column-selector-target">
{{ colHeaders[targetEl] }}
<span class="fa fa-times rule-column-selector-target-remove" @click="handleRemove(index)"></span>
<span class="fa fa-arrow-up rule-column-selector-up" v-if="index !== 0" @click="moveUp(index)"></span>
<span
class="fa fa-arrow-down rule-column-selector-down"
v-if="index < target.length - 1"
@click="moveUp(index + 1)"
></span>
</li>
<li v-if="this.target.length < this.colHeaders.length">
<span class="rule-column-selector-target-add" v-if="!orderedEdit">
<i @click="$emit('update:orderedEdit', true)">... {{ l("Assign Another Column") }}</i>
</span>
<span class="rule-column-selector-target-select" v-else>
<select2 @input="handleAdd" placeholder="Select a column">
<option /><!-- empty option selection for placeholder -->
<option v-for="(col, index) in remainingHeaders" :value="index" :key="col">{{ col }}</option>
</select2>
</span>
</li>
</ol>
</div>
</template>
<script>
import Vue from "vue";
import _l from "utils/localization";
import Select2 from "components/Select2";
export default {
components: {
Select2,
},
data: function () {
return {
l: _l,
};
},
props: {
target: {
required: true,
},
label: {
required: false,
type: String,
default: _l("From Column"),
},
help: {
required: false,
},
colHeaders: {
type: Array,
required: true,
},
multiple: {
type: Boolean,
required: false,
default: false,
},
ordered: {
type: Boolean,
required: false,
default: false,
},
valueAsList: {
type: Boolean,
required: false,
default: false,
},
orderedEdit: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
remainingHeaders() {
const colHeaders = this.colHeaders;
if (!this.multiple) {
return colHeaders;
}
const remaining = {};
for (const key in colHeaders) {
if (this.target.indexOf(parseInt(key)) === -1) {
remaining[key] = colHeaders[key];
}
}
return remaining;
},
title() {
return _l("Select a column");
},
},
methods: {
handleInput(value) {
if (this.multiple) {
// https://stackoverflow.com/questions/262427/why-does-parseint-yield-nan-with-arraymap
const val = value.map((idx) => parseInt(idx));
this.$emit("update:target", val);
} else {
let val = parseInt(value);
if (this.valueAsList) {
val = [val];
}
this.$emit("update:target", val);
}
},
handleAdd(value) {
this.target.push(parseInt(value));
this.$emit("update:orderedEdit", false);
},
handleRemove(index) {
this.target.splice(index, 1);
},
moveUp(value) {
const swapVal = this.target[value - 1];
Vue.set(this.target, value - 1, this.target[value]);
Vue.set(this.target, value, swapVal);
},
},
};
</script>
@@ -0,0 +1,54 @@
<template>
<li class="rule">
<span v-b-tooltip.hover :title="help">Set {{ columnsLabel }} as {{ typeDisplay }}</span>
<span v-b-tooltip.hover :title="titleEdit" class="fa fa-edit" @click="edit"></span>
<span v-b-tooltip.hover :title="titleRemove" class="fa fa-times" @click="remove"></span>
</li>
</template>
<script>
import _l from "utils/localization";
import RuleDefs from "mvc/rules/rule-definitions";
const MAPPING_TARGETS = RuleDefs.MAPPING_TARGETS;
export default {
props: {
type: {
type: String,
required: true,
},
columns: {
required: true,
},
colHeaders: {
type: Array,
required: true,
},
},
methods: {
remove() {
this.$emit("remove");
},
edit() {
this.$emit("edit");
},
},
computed: {
typeDisplay() {
return MAPPING_TARGETS[this.type].label;
},
help() {
return MAPPING_TARGETS[this.type].help || "";
},
titleEdit() {
return _l("Edit column definition");
},
titleRemove() {
return _l("Remove this column definition");
},
columnsLabel() {
return RuleDefs.columnDisplay(this.columns, this.colHeaders);
},
},
};
</script>
@@ -0,0 +1,43 @@
<template>
<div>
<label for="regular_expression" v-b-tooltip.hover :title="title">{{ label }}</label>
<span v-b-popover.html="popoverContent" :title="popoverTitle" class="fa fa-question"></span>
<input
v-b-tooltip.hover.left
:title="title"
name="regular_expression"
class="rule-regular-expression"
type="text"
:value="target"
@input="$emit('update:target', $event.target.value)"
/>
</div>
</template>
<script>
import _l from "utils/localization";
export default {
props: {
target: {
required: true,
},
},
computed: {
label() {
return _l("Regular Expression");
},
title() {
return _l("Enter a regular expression.");
},
popoverTitle() {
return _l("Regular Expressions");
},
popoverContent() {
return _l(
`Regular expressions are patterns used to match character combinations in strings. This input accepts Python-style regular expressions, find more information about these in <a href="https://pythonforbiologists.com/regular-expressions/">this Python for Biologists tutorial</a>.`
);
},
},
};
</script>
@@ -0,0 +1,48 @@
<template>
<div v-if="ruleType == displayRuleType" class="rule-editor" :class="typeToClass">
<slot></slot>
<div class="buttons rule-edit-buttons d-flex justify-content-end">
<button type="button" class="btn rule-editor-cancel mr-1" @click="cancel">{{ cancelLabel }}</button>
<button type="button" class="btn btn-primary rule-editor-ok" @click="okay">{{ applyLabel }}</button>
</div>
</div>
</template>
<script>
import _l from "utils/localization";
export default {
data: function () {
return {
applyLabel: _l("Apply"),
cancelLabel: _l("Cancel"),
};
},
props: {
ruleType: {
type: String,
required: true,
},
displayRuleType: {
required: true,
},
builder: {
required: true,
},
},
methods: {
cancel() {
this.builder.displayRuleType = null;
},
okay() {
this.builder.handleRuleSave(this.ruleType);
this.cancel();
},
},
computed: {
typeToClass() {
return "rule-edit-" + this.ruleType.replace(/_/g, "-");
},
},
};
</script>
@@ -0,0 +1,54 @@
<template>
<li class="rule">
<span class="rule-display">
<span class="mr-1">{{ title }}</span>
<span v-b-tooltip.hover :title="editTitle" class="fa fa-edit mr-1" @click="edit"></span>
<span v-b-tooltip.hover :title="removeTitle" class="fa fa-times map" @click="remove"></span>
</span>
<span class="rule-warning" v-if="rule.warn">
{{ rule.warn }}
</span>
<span class="rule-error" v-if="rule.error">
<span class="alert-message">{{ rule.error }}</span>
</span>
</li>
</template>
<script>
import _l from "utils/localization";
import RuleDefs from "mvc/rules/rule-definitions";
const RULES = RuleDefs.RULES;
export default {
props: {
rule: {
required: true,
type: Object,
},
colHeaders: {
type: Array,
required: true,
},
},
computed: {
title() {
const ruleType = this.rule.type;
return RULES[ruleType].display(this.rule, this.colHeaders);
},
editTitle() {
return _l("Edit this rule.");
},
removeTitle() {
return _l("Remove this rule.");
},
},
methods: {
edit() {
this.$emit("edit");
},
remove() {
this.$emit("remove");
},
},
};
</script>
@@ -0,0 +1,10 @@
<template>
<div class="rule-footer footer flex-row no-flex">
<slot name="inputs"></slot>
<div class="actions clear vertically-spaced">
<div class="main-options float-right">
<slot></slot>
</div>
</div>
</div>
</template>
@@ -0,0 +1,3 @@
<template>
<div class="header flex-row no-flex"><slot></slot></div>
</template>
@@ -0,0 +1,3 @@
<template>
<div class="middle flex-row flex-row-container"><slot></slot></div>
</template>
@@ -0,0 +1,34 @@
<template>
<a
class="rule-link dropdown-item"
href="javascript:void(0)"
:class="linkClassName"
@click="builder.addNewRule(ruleType)"
>{{ title }}</a
>
</template>
<script>
import RuleDefs from "mvc/rules/rule-definitions";
const RULES = RuleDefs.RULES;
export default {
props: {
ruleType: {
type: String,
required: true,
},
builder: {
required: true,
},
},
computed: {
linkClassName() {
return "rule-link-" + this.ruleType.replace(/_/g, "-");
},
title() {
return RULES[this.ruleType].title;
},
},
};
</script>
@@ -0,0 +1,5 @@
<template>
<div class="rule-collection-creator collection-creator flex-row-container">
<slot></slot>
</div>
</template>
@@ -576,360 +576,22 @@ import RuleDefs from "mvc/rules/rule-definitions";
import Vue from "vue";
import BootstrapVue from "bootstrap-vue";
import Select2 from "components/Select2";
import ColumnSelector from "components/RuleBuilder/ColumnSelector";
import RegularExpressionInput from "components/RuleBuilder/RegularExpressionInput";
import RuleDisplay from "components/RuleBuilder/RuleDisplay";
import IdentifierDisplay from "components/RuleBuilder/IdentifierDisplay";
import RuleTargetComponent from "components/RuleBuilder/RuleTargetComponent";
import RuleComponent from "components/RuleBuilder/RuleComponent";
import RuleModalHeader from "components/RuleBuilder/RuleModalHeader";
import RuleModalMiddle from "components/RuleBuilder/RuleModalMiddle";
import RuleModalFooter from "components/RuleBuilder/RuleModalFooter";
import StateDiv from "components/RuleBuilder/StateDiv";
Vue.use(BootstrapVue);
const RULES = RuleDefs.RULES;
const MAPPING_TARGETS = RuleDefs.MAPPING_TARGETS;
const ColumnSelector = {
template: `
<div class="rule-column-selector" v-if="!multiple || !ordered">
<label class="d-flex justify-content-end align-items-center">
<span class="mr-auto" v-b-tooltip.hover :title="help">{{ label }}</span>
<div class="mr-1" v-b-tooltip.hover :title="title"><select2 :value="target" @input="handleInput" :multiple="multiple">
<option v-for="(col, index) in colHeaders" :value="index">{{ col }}</option>
</select2></div>
<slot></slot>
</label>
</div>
<div class="rule-column-selector" v-else>
<span>{{ label }}</span>
<slot></slot>
<ol>
<li v-for="(targetEl, index) in target"
v-bind:index="index"
v-bind:key="targetEl"
class="rule-column-selector-target">
{{ colHeaders[targetEl] }}
<span class="fa fa-times rule-column-selector-target-remove" @click="handleRemove(index)"></span>
<span class="fa fa-arrow-up rule-column-selector-up" v-if="index !== 0" @click="moveUp(index)"></span>
<span class="fa fa-arrow-down rule-column-selector-down" v-if="index < target.length - 1" @click="moveUp(index + 1)"></span>
</li>
<li v-if="this.target.length < this.colHeaders.length">
<span class="rule-column-selector-target-add" v-if="!orderedEdit">
<i @click="$emit('update:orderedEdit', true)">... {{ l("Assign Another Column") }}</i>
</span>
<span class="rule-column-selector-target-select" v-else>
<select2 @input="handleAdd" placeholder="Select a column">
<option /><!-- empty option selection for placeholder -->
<option v-for="(col, index) in remainingHeaders" :value="index">{{ col }}</option>
</select2>
</span>
</li>
</ol>
</div>
`,
data: function () {
return {
l: _l,
};
},
props: {
target: {
required: true,
},
label: {
required: false,
type: String,
default: _l("From Column"),
},
help: {
required: false,
},
colHeaders: {
type: Array,
required: true,
},
multiple: {
type: Boolean,
required: false,
default: false,
},
ordered: {
type: Boolean,
required: false,
default: false,
},
valueAsList: {
type: Boolean,
required: false,
default: false,
},
orderedEdit: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
remainingHeaders() {
const colHeaders = this.colHeaders;
if (!this.multiple) {
return colHeaders;
}
const remaining = {};
for (const key in colHeaders) {
if (this.target.indexOf(parseInt(key)) === -1) {
remaining[key] = colHeaders[key];
}
}
return remaining;
},
title() {
return _l("Select a column");
},
},
methods: {
handleInput(value) {
if (this.multiple) {
// https://stackoverflow.com/questions/262427/why-does-parseint-yield-nan-with-arraymap
const val = value.map((idx) => parseInt(idx));
this.$emit("update:target", val);
} else {
let val = parseInt(value);
if (this.valueAsList) {
val = [val];
}
this.$emit("update:target", val);
}
},
handleAdd(value) {
this.target.push(parseInt(value));
this.$emit("update:orderedEdit", false);
},
handleRemove(index) {
this.target.splice(index, 1);
},
moveUp(value) {
const swapVal = this.target[value - 1];
Vue.set(this.target, value - 1, this.target[value]);
Vue.set(this.target, value, swapVal);
},
},
components: {
Select2,
},
};
const RegularExpressionInput = {
template: `
<div>
<label for="regular_expression" v-b-tooltip.hover :title="title">{{ label }}</label>
<span v-b-popover.html="popoverContent" :title="popoverTitle" class="fa fa-question"></span>
<input v-b-tooltip.hover.left :title="title" name="regular_expression" class="rule-regular-expression" type="text" :value="target" @input="$emit('update:target', $event.target.value)" />
</div>
`,
props: {
target: {
required: true,
},
},
computed: {
label() {
return _l("Regular Expression");
},
title() {
return _l("Enter a regular expression.");
},
popoverTitle() {
return _l("Regular Expressions");
},
popoverContent() {
return _l(
`Regular expressions are patterns used to match character combinations in strings. This input accepts Python-style regular expressions, find more information about these in <a href="https://pythonforbiologists.com/regular-expressions/">this Python for Biologists tutorial</a>.`
);
},
},
};
const RuleDisplay = {
template: `
<li class="rule">
<span class="rule-display">
<span class="mr-1">{{ title }}</span>
<span v-b-tooltip.hover :title="editTitle" class="fa fa-edit mr-1" @click="edit"></span>
<span v-b-tooltip.hover :title="removeTitle" class="fa fa-times map" @click="remove"></span>
</span>
<span class="rule-warning" v-if="rule.warn">
{{ rule.warn }}
</span>
<span class="rule-error" v-if="rule.error">
<span class="alert-message">{{ rule.error }}</span>
</span>
</li>
`,
props: {
rule: {
required: true,
type: Object,
},
colHeaders: {
type: Array,
required: true,
},
},
computed: {
title() {
const ruleType = this.rule.type;
return RULES[ruleType].display(this.rule, this.colHeaders);
},
editTitle() {
return _l("Edit this rule.");
},
removeTitle() {
return _l("Remove this rule.");
},
},
methods: {
edit() {
this.$emit("edit");
},
remove() {
this.$emit("remove");
},
},
};
const IdentifierDisplay = {
template: `
<li class="rule">
<span v-b-tooltip.hover :title="help">Set {{ columnsLabel }} as {{ typeDisplay }}</span>
<span v-b-tooltip.hover :title="titleEdit" class="fa fa-edit" @click="edit"></span>
<span v-b-tooltip.hover :title="titleRemove" class="fa fa-times" @click="remove"></span>
</li>
`,
props: {
type: {
type: String,
required: true,
},
columns: {
required: true,
},
colHeaders: {
type: Array,
required: true,
},
},
methods: {
remove() {
this.$emit("remove");
},
edit() {
this.$emit("edit");
},
},
computed: {
typeDisplay() {
return MAPPING_TARGETS[this.type].label;
},
help() {
return MAPPING_TARGETS[this.type].help || "";
},
titleEdit() {
return _l("Edit column definition");
},
titleRemove() {
return _l("Remove this column definition");
},
columnsLabel() {
return RuleDefs.columnDisplay(this.columns, this.colHeaders);
},
},
};
const RuleTargetComponent = {
template: `<a class="rule-link dropdown-item" href="javascript:void(0)" :class="linkClassName" @click="builder.addNewRule(ruleType)">{{title}}</a>`,
props: {
ruleType: {
type: String,
required: true,
},
builder: {
required: true,
},
},
computed: {
linkClassName() {
return "rule-link-" + this.ruleType.replace(/_/g, "-");
},
title() {
return RULES[this.ruleType].title;
},
},
};
const RuleComponent = {
template: `
<div v-if="ruleType == displayRuleType" class="rule-editor" :class="typeToClass">
<slot></slot>
<div class="buttons rule-edit-buttons d-flex justify-content-end">
<button type="button" class="btn rule-editor-cancel mr-1" @click="cancel">{{ cancelLabel }}</button>
<button type="button" class="btn btn-primary rule-editor-ok" @click="okay">{{ applyLabel }}</button>
</div>
</div>`,
data: function () {
return {
applyLabel: _l("Apply"),
cancelLabel: _l("Cancel"),
};
},
props: {
ruleType: {
type: String,
required: true,
},
displayRuleType: {
required: true,
},
builder: {
required: true,
},
},
methods: {
cancel() {
this.builder.displayRuleType = null;
},
okay() {
this.builder.handleRuleSave(this.ruleType);
this.cancel();
},
},
computed: {
typeToClass() {
return "rule-edit-" + this.ruleType.replace(/_/g, "-");
},
},
};
const StateDiv = {
template: `
<div class="rule-collection-creator collection-creator flex-row-container">
<slot></slot>
</div>`,
};
const RuleModalHeader = {
template: `<div class="header flex-row no-flex"><slot></slot></div>`,
};
const RuleModalMiddle = {
template: `<div class="middle flex-row flex-row-container"><slot></slot></div>`,
};
const RuleModalFooter = {
template: `
<div class="rule-footer footer flex-row no-flex">
<slot name="inputs"></slot>
<div class="actions clear vertically-spaced">
<div class="main-options float-right">
<slot></slot>
</div>
</div>
</div>`,
};
export default {
data: function () {
let orientation = "vertical";
@@ -1977,19 +1639,19 @@ export default {
<style>
.table-column {
width: 100%;
/* overflow: scroll; */
overflow: hidden;
}
.select2-container {
min-width: 60px;
}
.vertical #hot-table {
width: 100%;
overflow: scroll;
overflow: hidden;
height: 400px;
}
.horizontal #hot-table {
width: 100%;
overflow: scroll;
overflow: hidden;
height: 250px;
}
.rule-builder-body {
@@ -1,6 +1,6 @@
<template>
<div id="tool-recommendation" class="tool-recommendation-view">
<div v-if="!deprecated" class="infomessagelarge">
<div>
<div v-if="!deprecated && showMessage" class="infomessagelarge">
<h4>Tool recommendation</h4>
You have used {{ getToolId }} tool. For further analysis, you could try using the following/recommended
tools. The recommended tools are shown in the decreasing order of their scores predicted using machine
@@ -8,14 +8,17 @@
tool than a tool with a lower score. Please click on one of the following/recommended tools to open its
definition.
</div>
<div v-else class="warningmessagelarge">You have used {{ getToolId }} tool. {{ deprecatedMessage }}</div>
<div v-else-if="deprecated" class="warningmessagelarge">
You have used {{ getToolId }} tool. {{ deprecatedMessage }}
</div>
<div id="tool-recommendation" class="tool-recommendation-view"></div>
</div>
</template>
<script>
import * as d3 from "d3";
import { getAppRoot } from "onload/loadConfig";
import axios from "axios";
import { getDatatypeMapping, getToolPredictions } from "components/Workflow/Editor/services";
export default {
props: {
@@ -26,8 +29,9 @@ export default {
},
data() {
return {
deprecated: null,
deprecated: false,
deprecatedMessage: "",
showMessage: false,
};
},
created() {
@@ -46,86 +50,75 @@ export default {
methods: {
loadRecommendations() {
const toolId = this.getToolId;
const url = `${getAppRoot()}api/workflows/get_tool_predictions`;
axios
.post(url, {
tool_sequence: toolId,
})
.then((response) => {
axios.get(`${getAppRoot()}api/datatypes/mapping`).then((responseMapping) => {
const predData = response.data.predicted_data;
const datatypesMapping = responseMapping.data;
const extToType = datatypesMapping.ext_to_class_name;
const typeToType = datatypesMapping.class_to_classes;
this.deprecated = predData.is_deprecated;
if (response.data !== null && predData.children.length > 0) {
const filteredData = {};
const compatibleTools = {};
const filteredChildren = [];
const outputDatatypes = predData.o_extensions;
const children = predData.children;
for (const nameObj of children.entries()) {
const inputDatatypes = nameObj[1].i_extensions;
for (const out_t of outputDatatypes.entries()) {
for (const in_t of inputDatatypes.entries()) {
const child = extToType[out_t[1]];
const parent = extToType[in_t[1]];
if (
(typeToType[child] && parent in typeToType[child]) === true ||
out_t[1] === "input" ||
out_t[1] === "_sniff_" ||
out_t[1] === "input_collection"
) {
compatibleTools[nameObj[1].tool_id] = nameObj[1].name;
break;
}
}
}
}
for (const id in compatibleTools) {
for (const nameObj of children.entries()) {
if (nameObj[1].tool_id === id) {
filteredChildren.push(nameObj[1]);
const requestData = {
tool_sequence: toolId,
};
getToolPredictions(requestData).then((responsePred) => {
getDatatypeMapping().then((datatypesMapping) => {
const predData = responsePred.predicted_data;
const extToType = datatypesMapping.ext_to_class_name;
const typeToType = datatypesMapping.class_to_classes;
this.deprecated = predData.is_deprecated;
this.deprecatedMessage = predData.message;
if (responsePred !== null && predData.children.length > 0) {
const filteredData = {};
const compatibleTools = {};
const filteredChildren = [];
const outputDatatypes = predData.o_extensions;
const children = predData.children;
for (const nameObj of children.entries()) {
const inputDatatypes = nameObj[1].i_extensions;
for (const outT of outputDatatypes.entries()) {
for (const inTool of inputDatatypes.entries()) {
const child = extToType[outT[1]];
const parent = extToType[inTool[1]];
if (
(typeToType[child] && parent in typeToType[child]) === true ||
outT[1] === "input" ||
outT[1] === "_sniff_" ||
outT[1] === "input_collection"
) {
compatibleTools[nameObj[1].tool_id] = nameObj[1].name;
break;
}
}
}
filteredData.o_extensions = predData.o_extensions;
filteredData.name = predData.name;
filteredData.children = filteredChildren;
if (filteredChildren.length > 0 && this.deprecated === false) {
this.renderD3Tree(filteredData);
} else if (this.deprecated === true) {
this.deprecatedMessage = predData.message;
}
for (const id in compatibleTools) {
for (const nameObj of children.entries()) {
if (nameObj[1].tool_id === id) {
filteredChildren.push(nameObj[1]);
break;
}
}
}
});
filteredData.o_extensions = predData.o_extensions;
filteredData.name = predData.name;
filteredData.children = filteredChildren;
if (filteredChildren.length > 0 && this.deprecated === false) {
this.showMessage = true;
this.renderD3Tree(filteredData);
}
}
});
});
},
renderD3Tree(predictedTools) {
const duration = 750;
const svg = d3.select("#tool-recommendation").append("svg").attr("class", "tree-size").append("g");
let i = 0;
let root = null;
let x = 0;
let y = 0;
let translateX = 0;
const duration = 750;
const maxTextLength = 20;
const svg = d3.select("#tool-recommendation").append("svg").attr("class", "tree-size").append("g");
const gElem = svg[0][0];
const svgElem = gElem.parentNode;
const clientH = svgElem.clientHeight;
const clientW = svgElem.clientWidth;
y = parseInt(clientH * 0.9);
x = parseInt(clientW * 0.6);
translateX = parseInt(clientW * 0.15);
const translateX = parseInt(clientW * 0.15);
svgElem.setAttribute("viewBox", "0 0 " + x + " " + clientH);
svgElem.setAttribute("preserveAspectRatio", "xMinYMin");
gElem.setAttribute("transform", "translate(" + translateX + ", 5)");
const tree = d3.layout.tree().size([y, x]);
svgElem.setAttribute("viewBox", -translateX + " 0 " + 0.5 * clientW + " " + clientH);
svgElem.setAttribute("preserveAspectRatio", "xMidYMid meet");
const tree = d3.layout.tree().size([clientH, clientW]);
const diagonal = d3.svg.diagonal().projection((d) => {
return [d.y, d.x];
});
@@ -135,9 +128,9 @@ export default {
const links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach((d) => {
d.y = d.depth * 180;
d.y = d.depth * (clientW / 10);
});
// Update the nodes…
// Update the nodes
const node = svg.selectAll("g.node").data(nodes, (d) => {
return d.id || (d.id = ++i);
});
@@ -161,11 +154,14 @@ export default {
return d.children || d._children ? "end" : "start";
})
.text((d) => {
const tName = d.name;
if (tName.length > maxTextLength) {
return tName.slice(0, maxTextLength) + "...";
}
return d.name;
})
.attr("class", "node-enter");
});
nodeEnter.append("title").text((d) => {
return d.children || d._children ? "Click to collapse" : "Click to open tool definition";
return d.children || d._children ? d.name : "Open tool - " + d.name;
});
// Transition nodes to their new position.
const nodeUpdate = node
@@ -174,19 +170,15 @@ export default {
.attr("transform", (d) => {
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("circle").attr("r", 4.5);
nodeUpdate.select("text").attr("class", "node-update");
nodeUpdate.select("circle").attr("r", 2.5);
// Transition exiting nodes to the parent's new position.
const nodeExit = node
.exit()
node.exit()
.transition()
.duration(duration)
.attr("transform", (d) => {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("circle").attr("r", 1e-6);
nodeExit.select("text").attr("class", "node-enter");
// Update the links
const link = svg.selectAll("path.link").data(links, (d) => {
return d.target.id;
@@ -239,7 +231,7 @@ export default {
}
};
root = predictedTools;
root.x0 = y / 2;
root.x0 = parseInt(clientH / 2);
root.y0 = 0;
root.children.forEach(collapse);
update(root);
@@ -4,6 +4,7 @@
<div v-else>
<b-input-group class="mb-3">
<b-input
id="toolshed-repo-search"
placeholder="Search Repositories"
v-model="queryInput"
@input="delayQuery"
@@ -1,5 +1,5 @@
<template>
<b-modal :static="modalStatic" v-model="modalShow" @ok="onOk" @hide="onHide">
<b-modal id="repo-install-settings" :static="modalStatic" v-model="modalShow" @ok="onOk" @hide="onHide">
<template v-slot:modal-header>
<h4 class="title m-0">
{{ modalTitle }}
@@ -1,6 +1,6 @@
<template>
<div>
<b-table striped :items="repositories" :fields="fields">
<b-table striped id="shed-search-results" :items="repositories" :fields="fields">
<template v-slot:cell(name)="row">
<b-link href="javascript:void(0)" role="button" class="font-weight-bold" @click="row.toggleDetails">
{{ row.item.name }}
@@ -260,6 +260,7 @@ export default {
// add ftp file viewer
this.ftp = new Popover({
title: _l("FTP files"),
class: "ftp-upload",
container: $(this.$refs.btnFtp),
});
},
@@ -83,7 +83,7 @@ export const getUserPreferencesModel = () => {
},
logout: {
title: _l("Sign Out"),
id: "edit-preferences-custom-builds",
id: "edit-preferences-sign-out",
description: _l("Click here to sign out of all sessions."),
icon: "fa-sign-out",
shouldRender: !!Galaxy.session_csrf_token,
@@ -10,6 +10,19 @@
>
<i class="fa fa-times" />
</b-button>
<b-button
:id="popoverId"
v-if="isEnabled"
class="node-recommendations py-0 float-right"
variant="primary"
size="sm"
aria-label="tool recommendations"
>
<i class="fa fa-arrow-right" />
</b-button>
<b-popover :target="popoverId" triggers="hover" placement="bottom" :show.sync="popoverShow">
<WorkflowRecommendations :node="node" @onCreate="onCreate" />
</b-popover>
<b-button
v-if="canClone"
class="node-clone py-0 float-right"
@@ -35,13 +48,22 @@
import Vue from "vue";
import BootstrapVue from "bootstrap-vue";
import WorkflowIcons from "components/Workflow/icons";
import { getModule } from "./services";
import LoadingSpan from "components/LoadingSpan";
import { getGalaxyInstance } from "app";
import WorkflowRecommendations from "components/Workflow/Editor/Recommendations";
Vue.use(BootstrapVue);
export default {
components: {
LoadingSpan,
WorkflowRecommendations,
},
data() {
return {
popoverShow: false,
};
},
props: {
id: {
@@ -60,6 +82,10 @@ export default {
type: Object,
default: null,
},
nodeId: {
type: String,
default: "",
},
},
computed: {
iconClass() {
@@ -69,9 +95,15 @@ export default {
}
return null;
},
popoverId() {
return `popover-${this.nodeId}`;
},
canClone() {
return this.type != "subworkflow";
},
isEnabled() {
return getGalaxyInstance().config.enable_tool_recommendations;
},
},
methods: {
onDestroy() {
@@ -80,6 +112,18 @@ export default {
onClone() {
this.node.clone();
},
onCreate(toolId, event) {
const requestData = {
tool_id: toolId,
type: "tool",
_: "true",
};
getModule(requestData).then((response) => {
var node = this.node.app.create_node("tool", response.name, toolId);
this.node.app.set_node(node, response);
this.popoverShow = false;
});
},
},
};
</script>
@@ -0,0 +1,145 @@
<template>
<div class="workflow-recommendations">
<div class="header-background">
<h4>{{ popoverHeaderText }}</h4>
</div>
<LoadingSpan v-if="showLoading" message="Loading recommendations" />
<div v-if="compatibleTools.length > 0 && !isDeprecated">
<div v-for="tool in compatibleTools" :key="tool.id">
<i class="fa mr-1 fa-wrench"></i>
<a href="#" title="Open tool" :id="tool.id" @click="$emit('onCreate', tool.id, $event)">
{{ tool.name }}
</a>
</div>
</div>
<div v-else-if="isDeprecated">
{{ deprecatedMessage }}
</div>
<div v-if="compatibleTools.length === 0 && !showLoading">
{{ noRecommendationsMessage }}
</div>
</div>
</template>
<script>
import { getToolPredictions } from "./services";
import LoadingSpan from "components/LoadingSpan";
import _l from "utils/localization";
export default {
components: {
LoadingSpan,
},
props: {
node: {
type: Object,
required: true,
},
},
data() {
return {
compatibleTools: [],
isDeprecated: false,
popoverHeaderText: _l("Tool recommendations"),
noRecommendationsMessage: _l("No tool recommendations"),
deprecatedMessage: "",
showLoading: true,
};
},
created() {
this.loadRecommendations();
},
methods: {
getToolId(toolId) {
if (toolId !== undefined && toolId !== null && toolId.indexOf("/") > -1) {
const toolIdSlash = toolId.split("/");
toolId = toolIdSlash[toolIdSlash.length - 2];
}
return toolId;
},
getWorkflowPath(wfSteps, currentNodeId) {
const steps = {};
const stepNames = {};
for (const stpIdx in wfSteps.steps) {
const step = wfSteps.steps[stpIdx];
const inputConnections = step.input_connections;
stepNames[step.id] = this.getToolId(step.content_id);
for (const icIdx in inputConnections) {
const ic = inputConnections[icIdx];
if (ic !== null && ic !== undefined) {
const prevConn = [];
for (const conn of ic) {
prevConn.push(conn.id.toString());
}
steps[step.id.toString()] = prevConn;
}
}
}
// recursive call to determine path
function readPaths(nodeId, ph) {
for (const st in steps) {
if (parseInt(st) === parseInt(nodeId)) {
const parentId = parseInt(steps[st][0]);
if (parentId !== undefined && parentId !== null) {
ph.push(parentId);
if (steps[parentId] !== undefined && steps[parentId] !== null) {
readPaths(parentId, ph);
}
}
}
}
return ph;
}
let ph = [];
const stepNameList = [];
ph.push(currentNodeId);
ph = readPaths(currentNodeId, ph);
for (const sIdx of ph) {
const sName = stepNames[sIdx.toString()];
if (sName !== undefined && sName !== null) {
stepNameList.push(sName);
}
}
return stepNameList.join(",");
},
loadRecommendations() {
const workflowSimple = this.node.app.to_simple();
const node = this.node;
const toolSequence = this.getWorkflowPath(workflowSimple, node.id);
const requestData = { tool_sequence: toolSequence };
getToolPredictions(requestData).then((responsePred) => {
const predictedData = responsePred.predicted_data;
const outputDatatypes = predictedData.o_extensions;
const predictedDataChildren = predictedData.children;
const app = this.node.app;
this.isDeprecated = predictedData.is_deprecated;
this.deprecatedMessage = predictedData.message;
if (predictedDataChildren.length > 0) {
const cTools = [];
for (const nameObj of predictedDataChildren.entries()) {
const t = {};
const inputDatatypes = nameObj[1].i_extensions;
for (const outT of outputDatatypes.entries()) {
for (const inTool of inputDatatypes.entries()) {
if (
app.isSubType(outT[1], inTool[1]) === true ||
outT[1] === "input" ||
outT[1] === "_sniff_" ||
outT[1] === "input_collection"
) {
t.id = nameObj[1].tool_id;
t.name = nameObj[1].name;
cTools.push(t);
break;
}
}
}
}
this.compatibleTools = cTools;
}
this.showLoading = false;
});
},
},
};
</script>
@@ -67,3 +67,21 @@ export async function saveWorkflow(workflow, id) {
}
return {};
}
export async function getDatatypeMapping() {
try {
const mappingRequest = await axios.get(`${getAppRoot()}api/datatypes/mapping`);
return mappingRequest.data;
} catch (e) {
rethrowSimple(e);
}
}
export async function getToolPredictions(requestData) {
try {
const response = await axios.post(`${getAppRoot()}api/workflows/get_tool_predictions`, requestData);
return response.data;
} catch (e) {
rethrowSimple(e);
}
}
@@ -84,6 +84,7 @@ export default {
const oidc_idps_icons = {
google: "https://developers.google.com/identity/images/btn_google_signin_light_normal_web.png",
elixir: "https://elixir-europe.org/sites/default/files/images/login-button-orange.png",
okta: "https://www.okta.com/sites/all/themes/Okta/images/blog/Logos/Okta_Logo_BrightBlue_Medium.png",
};
return {
login: null,
@@ -321,10 +321,7 @@ export const getAnalysisRouter = (Galaxy) =>
},
show_workflows: function () {
const workflowListInstance = Vue.extend(WorkflowList);
const vm = document.createElement("div");
this.page.display(vm);
new workflowListInstance().$mount(vm);
this._display_vue_helper(WorkflowList);
},
show_workflows_create: function () {
@@ -87,6 +87,7 @@ const AdminPanel = Backbone.View.extend({
title: _l("Forms"),
url: "admin/forms",
target: "__use_router__",
id: "admin-link-forms",
},
],
},
@@ -97,17 +98,20 @@ const AdminPanel = Backbone.View.extend({
title: _l("Install and Uninstall"),
url: "admin/toolshed",
target: "__use_router__",
id: "admin-link-toolshed",
enabled: this.settings.is_tool_shed_installed,
},
{
title: _l("Manage Metadata"),
url: "admin/reset_metadata",
id: "admin-link-metadata",
enabled: this.settings.is_repo_installed,
target: "__use_router__",
},
{
title: _l("Manage Whitelist"),
url: "admin/sanitize_whitelist",
id: "admin-link-whitelist",
},
{
title: _l("Manage Dependencies"),
@@ -123,14 +127,17 @@ const AdminPanel = Backbone.View.extend({
title: _l("View Lineage"),
url: "admin/tool_versions",
target: "__use_router__",
id: "admin-link-tool-versions",
},
{
title: _l("View Migration Stages"),
url: "admin/review_tool_migration_stages",
id: "admin-link-migrations",
},
{
title: _l("View Error Logs"),
url: "admin/error_stack",
id: "admin-link-error-stack",
target: "__use_router__",
},
],
+4 -1
View File
@@ -21,7 +21,7 @@ export default Backbone.View.extend({
* Show popover
*/
show: function ($content) {
const btn = "<i class='fa fa-times-circle'/>";
const btn = "<i class='popover-close fa fa-times-circle'/>";
$(this.$target).popover({
title: `${this.options.title} ${btn}`,
placement: this.options.placement,
@@ -29,6 +29,9 @@ export default Backbone.View.extend({
html: true,
trigger: "manual",
});
if (this.options.class) {
$(this.$target).addClass(this.options.class);
}
$(this.$target).popover("show");
// add event to hide if click is outside of popup and not on container
@@ -18,6 +18,7 @@ class Workflow extends EventEmitter {
this.has_changes = false;
this.workflowOutputLabels = {};
this.workflow_version = 0;
this.popover_counter = 0;
// Canvas overview management
this.canvas_manager = new WorkflowCanvas(this, $("#canvas-viewport"), $("#overview-container"));
@@ -142,8 +143,10 @@ class Workflow extends EventEmitter {
type: type,
title: title_text,
node: node,
nodeId: this.popover_counter,
});
this.popover_counter++;
// Set initial scroll position
$f.css("left", $(window).scrollLeft() + 20);
$f.css("top", $(window).scrollTop() + 20);
+2
View File
@@ -9,6 +9,7 @@ import createCache from "vuex-cache";
import { gridSearchStore } from "./gridSearchStore";
import { tagStore } from "./tagStore";
import { jobMetricsStore } from "./jobMetricsStore";
import { jobDestinationParametersStore } from "./jobDestinationParametersStore";
import { invocationStore } from "./invocationStore";
import { historyStore } from "./historyStore";
import { userStore } from "./userStore";
@@ -31,6 +32,7 @@ export function createStore() {
histories: historyStore,
tags: tagStore,
jobMetrics: jobMetricsStore,
destinationParameters: jobDestinationParametersStore,
invocations: invocationStore,
user: userStore,
config: configStore,
@@ -0,0 +1,33 @@
export const state = {
jobDestinationParametersByJobId: {},
};
import Vue from "vue";
import { getAppRoot } from "onload/loadConfig";
import axios from "axios";
const getters = {
jobDestinationParams: (state) => (jobId) => {
return state.jobDestinationParametersByJobId[jobId] || [];
},
};
const actions = {
fetchJobDestinationParams: async ({ commit }, jobId) => {
const { data } = await axios.get(`${getAppRoot()}api/jobs/${jobId}/destination_params`);
commit("saveJobDestinationParamsForJobId", { jobId, jobDestinationParams: data });
},
};
const mutations = {
saveJobDestinationParamsForJobId: (state, { jobId, jobDestinationParams }) => {
Vue.set(state.jobDestinationParametersByJobId, jobId, jobDestinationParams);
},
};
export const jobDestinationParametersStore = {
state,
getters,
actions,
mutations,
};
+13 -15
View File
@@ -1656,31 +1656,29 @@ body.reports {
.node {
cursor: pointer;
circle {
fill: lighten($brand-primary, 20%);
stroke: lighten($brand-primary, 20%);
stroke-width: 0.1rem;
fill: $brand-primary;
stroke: $brand-primary;
}
text {
font: 0.4rem sans-serif;
font-size: 0.4rem;
}
}
.node-enter {
fill-opacity: 1e-6;
}
.node-update {
fill-opacity: 1;
}
.tree-size {
width: 100%;
height: 50%;
}
.link {
fill: none;
stroke: lighten($brand-primary, 20%);
stroke-width: 0.2rem;
stroke: $brand-primary;
stroke-width: 1;
}
}
.workflow-recommendations {
display: block;
.header-background {
border-bottom: solid 1px $brand-primary;
margin-bottom: 0.5rem;
}
}
+3
View File
@@ -7,6 +7,9 @@
display: flex;
flex-direction: column;
flex-grow: 1;
.workflow-recommendations {
height: 30rem;
}
.workflow-node {
@extend .card;
@extend .position-absolute;
+42 -17
View File
@@ -2,14 +2,14 @@ const path = require("path");
const fs = require("fs");
const del = require("del");
const { src, dest, series, parallel } = require("gulp");
const spawn = require("child_process").spawnSync;
const child_process = require("child_process");
const glob = require("glob");
const paths = {
node_modules: "./node_modules",
plugin_dirs: [
"../config/plugins/{visualizations,interactive_environments}/*/static/**/*",
"../config/plugins/{visualizations,interactive_environments}/*/*/static/**/*"
"../config/plugins/{visualizations,interactive_environments}/*/*/static/**/*",
],
/*
* We'll want a flexible glob down the road, but for now there are no
@@ -20,9 +20,7 @@ const paths = {
// "../config/plugins/{visualizations,interactive_environments}/*/package.json",
// "../config/plugins/{visualizations,interactive_environments}/*/*/package.json"
//],
plugin_build_dirs: [
"../config/plugins/visualizations/{annotate_image,hyphyvision,openlayers,editor}/package.json",
],
plugin_build_dirs: ["../config/plugins/visualizations/{annotate_image,hyphyvision,openlayers,editor}/package.json"],
lib_locs: {
// This is a stepping stone towards having all this staged
// automatically. Eventually, this dictionary and staging step will
@@ -37,13 +35,13 @@ const paths = {
"jquery-mousewheel": ["jquery.mousewheel.js", "jquery/jquery.mousewheel.js"],
"raven-js": ["dist/raven.js", "raven.js"],
requirejs: ["require.js", "require.js"],
underscore: ["underscore.js", "underscore.js"]
underscore: ["underscore.js", "underscore.js"],
},
libs: ["galaxy/scripts/libs/**/*.js"]
libs: ["galaxy/scripts/libs/**/*.js"],
};
function stageLibs(callback) {
Object.keys(paths.lib_locs).forEach(lib => {
Object.keys(paths.lib_locs).forEach((lib) => {
var p1 = path.resolve(path.join(paths.node_modules, lib, paths.lib_locs[lib][0]));
var p2 = path.resolve(path.join("galaxy", "scripts", "libs", paths.lib_locs[lib][1]));
if (fs.existsSync(p1)) {
@@ -69,18 +67,45 @@ function stagePlugins() {
return src(paths.plugin_dirs).pipe(dest("../static/plugins/"));
}
function buildPlugins(callback){
function buildPlugins(callback) {
/*
* Walk plugin build glob and attempt to build anything with a package.json
* Walk plugin_build_dirs glob and attempt to build modules.
* */
paths.plugin_build_dirs.map( build_dir => {
paths.plugin_build_dirs.map((build_dir) => {
glob(build_dir, {}, (er, files) => {
files.map( file => {
files.map((file) => {
let skip_build = false;
const f = path.join(process.cwd(), file).slice(0, -12);
console.log("Installing Dependencies for", f);
spawn('yarn', ['install', '--production=false', '--network-timeout=300000', '--check-files'], { cwd: f, stdio: 'inherit', shell: true });
console.log("Building ", f);
spawn('yarn', ['build'], { cwd: f, stdio: 'inherit', shell: true });
const plugin_name = path.dirname(file).split(path.sep).pop();
const hash_file_path = path.join(f, "static", "plugin_build_hash.txt");
if (fs.existsSync(hash_file_path)) {
skip_build =
child_process.spawnSync("git", ["diff", "--quiet", `$(cat ${hash_file_path})`, "--", f], {
stdio: "inherit",
shell: true,
}).status === 0;
} else {
console.log(`No build hashfile detected for ${plugin_name}, generating now.`);
}
if (skip_build) {
console.log(`No changes detected for ${plugin_name}`);
} else {
console.log(`Installing Dependencies for ${plugin_name}`);
child_process.spawnSync(
"yarn",
["install", "--production=false", "--network-timeout=300000", "--check-files"],
{
cwd: f,
stdio: "inherit",
shell: true,
}
);
console.log(`Building ${plugin_name}`);
child_process.spawnSync("yarn", ["build"], { cwd: f, stdio: "inherit", shell: true });
child_process.exec(`"(git rev-parse HEAD 2>/dev/null || echo \`\`) > ${hash_file_path} "`);
}
});
});
});
@@ -92,7 +117,7 @@ function cleanPlugins() {
}
client = parallel(fonts, stageLibs);
plugins = series(cleanPlugins, buildPlugins, stagePlugins);
plugins = series(buildPlugins, cleanPlugins, stagePlugins);
module.exports.client = client;
module.exports.plugins = plugins;
+4 -4
View File
@@ -12,8 +12,8 @@
<filter>${$site_id.startswith( 'local_' ) or $dataset.dbkey in $site_dbkeys}</filter>
<!-- We define url and params as normal, but values defined in dynamic_param are available by specified name -->
<url>${redirect_url}</url>
<param type="data" name="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz" format="vcf_bgzip" />
<param type="data" name="tabix_file" dataset="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz.tbi" format="tabix" />
<param type="data" name="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz" format="vcf_bgzip" allow_cors="true" mimetype="application/octet-stream"/>
<param type="data" name="tabix_file" metadata="tabix_index" url="galaxy_${DATASET_HASH}.vcf.gz.tbi" allow_cors="true" mimetype="application/octet-stream"/>
<param type="template" name="site_organism" strip="True" >
#if ($dataset.dbkey in $site_dbkeys)
$site_organisms[ $site_dbkeys.index( $bgzip_file.dbkey ) ]
@@ -94,8 +94,8 @@
<filter>${ $dataset.dbkey == $value }</filter>
<!-- We define url and params as normal, but values defined in dynamic_param are available by specified name -->
<url>http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bgzip_file.qp}&amp;genome=${qp($bgzip_file.dbkey)}&amp;merge=true&amp;name=${qp( ( $bgzip_file.name or $DATASET_HASH ).replace( ',', ';' ) )}</url>
<param type="data" name="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz" format="vcf_bgzip" />
<param type="data" name="tabix_file" dataset="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz.tbi" format="tabix" />
<param type="data" name="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz" format="vcf_bgzip" mimetype="application/octet-stream"/>
<param type="data" name="tabix_file" metadata="tabix_index" url="galaxy_${DATASET_HASH}.vcf.gz.tbi" format="vcf_bgzip" mimetype="application/octet-stream"/>
</dynamic_links>
</display>
<!-- Dan Blankenberg -->
+1 -1
View File
@@ -18,7 +18,7 @@ If deploying Galaxy using the default authentication option, user activation can
## OIDC and OAuth2.0
Leveraging OpenID Connect (OIDC) protocol, we enable login to Galaxy without explicitly creating a Galaxy user. This feature is disabled by default. In short, to enable this feature, a Galaxy server admin has to take the following two steps:
1. Define the Galaxy instance on an OIDC identity provider. At the moment, we support Google. To set a Galaxy instance on Google, go to _credentials_ section at [developers console](https://console.developers.google.com/), and configure the instance. At the end, you'll receive _client ID_ and _client secret_ take a note of these two tokens.
1. Define the Galaxy instance on an OIDC identity provider. At the moment, we support Google and Okta. To set a Galaxy instance on Google, go to _credentials_ section at [developers console](https://console.developers.google.com/), and configure the instance. At the end, you'll receive _client ID_ and _client secret_ take a note of these two tokens. For Okta, create a new application in Okta, type _web_. At the end you should take note of the _client ID_ and _client secret_ tokens.
2. Configure Galaxy. In the `galaxy.yml` file enable the OIDC service using the `enable_oidc` key and set the two configuration files (i.e., `oidc_config_file` and `oidc_backends_config_file`), based on the IdP information.
+19 -5
View File
@@ -1376,6 +1376,19 @@
:Type: bool
~~~~~~~~~~~~~~~~
``aws_estimate``
~~~~~~~~~~~~~~~~
:Description:
This flag enables an AWS cost estimate for every job based on
their runtime matrices. CPU, RAM and runtime usage is mapped
against AWS pricing table. Please note, that those numbers are
only estimates.
:Default: ``false``
:Type: bool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``interactivetools_proxy_host``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2317,8 +2330,7 @@
:Description:
Heartbeat log filename. Can accept the template variables
{server_name} and {pid}
Sample default 'heartbeat_{server_name}.log'
:Default: ``None``
:Default: ``heartbeat_{server_name}.log``
:Type: str
@@ -3836,11 +3848,13 @@
from workflow_resource_params_file). If this this is a function
reference it will be passed various inputs (workflow model object
and user) and it should produce a list of input IDs. If it is a
path it is expected to an XML or YAML file describing how to map
group names to parameter descriptions (additional types of
path it is expected to be an XML or YAML file describing how to
map group names to parameter descriptions (additional types of
mappings via these files could be implemented but haven't yet -
for instance using workflow tags to do the mapping).
:Default: ``config/workflow_resource_mapper_conf.yml``
Sample default path
'config/workflow_resource_mapper_conf.yml.sample'
:Default: ``None``
:Type: str
+5
View File
@@ -121,6 +121,11 @@ class AuthnzManager(object):
'enable_idp_logout': asbool(config_xml.findtext('enable_idp_logout', 'false'))}
if config_xml.find('prompt') is not None:
rtv['prompt'] = config_xml.find('prompt').text
if config_xml.find('api_url') is not None:
rtv['api_url'] = config_xml.find('api_url').text
if config_xml.find('url') is not None:
rtv['url'] = config_xml.find('url').text
return rtv
def _parse_custos_config(self, config_xml):
+14 -6
View File
@@ -22,14 +22,16 @@ DEFAULTS = {
BACKENDS = {
'google': 'social_core.backends.google_openidconnect.GoogleOpenIdConnect',
"globus": "social_core.backends.globus.GlobusOpenIdConnect",
'elixir': 'social_core.backends.elixir.ElixirOpenIdConnect'
'globus': 'social_core.backends.globus.GlobusOpenIdConnect',
'elixir': 'social_core.backends.elixir.ElixirOpenIdConnect',
'okta': 'social_core.backends.okta_openidconnect.OktaOpenIdConnect'
}
BACKENDS_NAME = {
'google': 'google-openidconnect',
"globus": "globus",
'elixir': 'elixir'
'globus': 'globus',
'elixir': 'elixir',
'okta': 'okta-openidconnect'
}
AUTH_PIPELINE = (
@@ -114,8 +116,10 @@ class PSAAuthnz(IdentityProvider):
# Secondary AuthZ with Google identities is currently supported
if provider != "google":
del self.config["SOCIAL_AUTH_SECONDARY_AUTH_PROVIDER"]
del self.config["SOCIAL_AUTH_SECONDARY_AUTH_ENDPOINT"]
if 'SOCIAL_AUTH_SECONDARY_AUTH_PROVIDER' in self.config:
del self.config["SOCIAL_AUTH_SECONDARY_AUTH_PROVIDER"]
if 'SOCIAL_AUTH_SECONDARY_AUTH_ENDPOINT' in self.config:
del self.config["SOCIAL_AUTH_SECONDARY_AUTH_ENDPOINT"]
def _setup_idp(self, oidc_backend_config):
self.config[setting_name('AUTH_EXTRA_ARGUMENTS')] = {'access_type': 'offline'}
@@ -124,6 +128,10 @@ class PSAAuthnz(IdentityProvider):
self.config['redirect_uri'] = oidc_backend_config.get('redirect_uri')
if oidc_backend_config.get('prompt') is not None:
self.config[setting_name('AUTH_EXTRA_ARGUMENTS')]['prompt'] = oidc_backend_config.get('prompt')
if oidc_backend_config.get('api_url') is not None:
self.config[setting_name('API_URL')] = oidc_backend_config.get('api_url')
if oidc_backend_config.get('url') is not None:
self.config[setting_name('URL')] = oidc_backend_config.get('url')
def _get_helper(self, name, do_import=False):
this_config = self.config.get(setting_name(name), DEFAULTS.get(name, None))
+30 -34
View File
@@ -340,6 +340,13 @@ class CommonConfigurationMixin(object):
# Warning: the value of self.config_dict['foo'] may be different from self.foo
return self.config_dict.get(key, default)
def _ensure_directory(self, path):
if path not in [None, False] and not os.path.isdir(path):
try:
os.makedirs(path)
except Exception as e:
raise ConfigurationError("Unable to create missing directory: %s\n%s" % (path, unicodify(e)))
class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
deprecated_options = ('database_file', 'track_jobs_in_database')
@@ -348,11 +355,16 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
def __init__(self, **kwargs):
super(GalaxyAppConfiguration, self).__init__(**kwargs)
self._override_tempdir(kwargs)
self._process_config(kwargs)
def _load_schema(self):
return AppSchema(GALAXY_CONFIG_SCHEMA_PATH, GALAXY_APP_NAME)
def _override_tempdir(self, kwargs):
if string_as_bool(kwargs.get("override_tempdir", "True")):
tempfile.tempdir = self.new_file_path
def _process_config(self, kwargs):
# Resolve paths of other config files
self.parse_config_file_options(kwargs)
@@ -377,10 +389,6 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
self.thread_local_log = threading.local()
# Install database related configuration (if different)
self.install_database_engine_options = get_database_engine_options(kwargs, model_prefix="install_")
override_tempdir = string_as_bool(kwargs.get("override_tempdir", "True"))
if override_tempdir:
tempfile.tempdir = self.new_file_path
self.shared_home_dir = kwargs.get("shared_home_dir")
self.cookie_path = kwargs.get("cookie_path")
self.tool_path = self._in_root_dir(self.tool_path)
@@ -493,14 +501,9 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
# you want yours tools to be broken in the future.
self.enable_beta_tool_formats = string_as_bool(kwargs.get('enable_beta_tool_formats', 'False'))
workflow_resource_params_mapper = kwargs.get("workflow_resource_params_mapper")
if not workflow_resource_params_mapper:
workflow_resource_params_mapper = None
elif ":" not in workflow_resource_params_mapper:
# Assume it is not a Python function, so a file
workflow_resource_params_mapper = self._in_root_dir(workflow_resource_params_mapper)
# else: a Python a function!
self.workflow_resource_params_mapper = workflow_resource_params_mapper
if self.workflow_resource_params_mapper and ':' not in self.workflow_resource_params_mapper:
# Assume it is not a Python function, so a file; else: a Python function
self.workflow_resource_params_mapper = self._in_root_dir(self.workflow_resource_params_mapper)
self.pbs_application_server = kwargs.get('pbs_application_server', "")
self.pbs_dataset_server = kwargs.get('pbs_dataset_server', "")
@@ -600,8 +603,6 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
# Heartbeat log file name override
if self.global_conf is not None and 'heartbeat_log' in self.global_conf:
self.heartbeat_log = self.global_conf['heartbeat_log']
if self.heartbeat_log is None:
self.heartbeat_log = 'heartbeat_{server_name}.log'
# Determine which 'server:' this is
self.server_name = 'main'
for arg in sys.argv:
@@ -670,8 +671,8 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
# InteractiveTools propagator mapping file
self.interactivetools_map = self._in_root_dir(kwargs.get("interactivetools_map", self._in_data_dir("interactivetools_map.sqlite")))
self.interactivetool_prefix = kwargs.get("interactivetools_prefix", "interactivetool")
self.interactivetool_proxy_host = kwargs.get("interactivetool_proxy_host", None)
self.interactivetools_prefix = kwargs.get("interactivetools_prefix", "interactivetool")
self.interactivetools_proxy_host = kwargs.get("interactivetool_proxy_host", None)
self.containers_conf = parse_containers_config(self.containers_config_file)
@@ -810,26 +811,21 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
def ensure_tempdir(self):
self._ensure_directory(self.new_file_path)
def _ensure_directory(self, path):
if path not in [None, False] and not os.path.isdir(path):
try:
os.makedirs(path)
except Exception as e:
raise ConfigurationError("Unable to create missing directory: %s\n%s" % (path, unicodify(e)))
def check(self):
paths_to_check = [self.tool_data_path, self.data_dir, self.managed_config_dir]
# Check that required directories exist
# Check that required directories exist; attempt to create otherwise
paths_to_check = [
self.data_dir,
self.ftp_upload_dir,
self.library_import_dir,
self.managed_config_dir,
self.new_file_path,
self.nginx_upload_store,
self.object_store_cache_path,
self.template_cache_path,
self.tool_data_path,
self.user_library_import_dir,
]
for path in paths_to_check:
if path not in [None, False] and not os.path.isdir(path):
try:
os.makedirs(path)
except Exception as e:
raise ConfigurationError("Unable to create missing directory: %s\n%s" % (path, unicodify(e)))
# Create the directories that it makes sense to create
for path in (self.new_file_path, self.template_cache_path, self.ftp_upload_dir,
self.library_import_dir, self.user_library_import_dir,
self.nginx_upload_store, self.object_store_cache_path):
self._ensure_directory(path)
# Check that required files exist
tool_configs = self.tool_configs
@@ -230,19 +230,27 @@
<datatype extension="directory" type="galaxy.datatypes.data:Directory">
</datatype>
<!-- Proteomics Datatypes -->
<datatype extension="mrm" type="galaxy.datatypes.tabular:Tabular" display_in_upload="true" subclass="true"/>
<datatype extension="dta" type="galaxy.datatypes.proteomics:Dta" display_in_upload="true" />
<datatype extension="dta2d" type="galaxy.datatypes.proteomics:Dta2d" display_in_upload="true" />
<datatype extension="edta" type="galaxy.datatypes.proteomics:Edta" display_in_upload="true" />
<datatype extension="pepxml" type="galaxy.datatypes.proteomics:PepXml" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="raw_pepxml" type="galaxy.datatypes.proteomics:PepXml" mimetype="application/xml" subclass="true"/>
<datatype extension="peptideprophet_pepxml" type="galaxy.datatypes.proteomics:PepXml" mimetype="application/xml" subclass="true"/>
<datatype extension="interprophet_pepxml" type="galaxy.datatypes.proteomics:PepXml" mimetype="application/xml" subclass="true"/>
<datatype extension="protxml" type="galaxy.datatypes.proteomics:ProtXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="trafoxml" type="galaxy.datatypes.xml:GenericXml" mimetype="application/xml" subclass="true" display_in_upload="true" description="Transformation of retention times"/>
<datatype extension="paramxml" type="galaxy.datatypes.proteomics:ParamXml" mimetype="application/xml" subclass="true" display_in_upload="true" />
<datatype extension="qcml" type="galaxy.datatypes.xml:GenericXml" mimetype="application/xml" subclass="true" display_in_upload="true" description="Quality control data in XML format (https://code.google.com/p/qcml/)."/>
<datatype extension="kroenik" type="galaxy.datatypes.proteomics:Kroenik" display_in_upload="true"/>
<datatype extension="peplist" type="galaxy.datatypes.proteomics:PepList" display_in_upload="true"/>
<datatype extension="psms" type="galaxy.datatypes.proteomics:PSMS" display_in_upload="true"/>
<datatype extension="pepxml.tsv" type="galaxy.datatypes.proteomics:PepXmlReport" display_in_upload="true"/>
<datatype extension="protxml.tsv" type="galaxy.datatypes.proteomics:ProtXmlReport" display_in_upload="true"/>
<datatype extension="mascotdat" type="galaxy.datatypes.proteomics:MascotDat" display_in_upload="false"/>
<datatype extension="mzid" type="galaxy.datatypes.proteomics:MzIdentML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="idxml" type="galaxy.datatypes.proteomics:IdXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="tandem" type="galaxy.datatypes.proteomics:TandemXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="sirius.ms" type="galaxy.datatypes.data:Text" subclass="true" display_in_upload="false"/>
<datatype extension="thermo.raw" type="galaxy.datatypes.proteomics:ThermoRAW" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="brukerbaf.d.tar" type="galaxy.datatypes.binary:BafTar" display_in_upload="true"/>
<datatype extension="agilentbrukeryep.d.tar" type="galaxy.datatypes.binary:YepTar" display_in_upload="true"/>
@@ -250,6 +258,9 @@
<datatype extension="agilentmasshunter.d.tar" type="galaxy.datatypes.binary:MassHunterTar" display_in_upload="true"/>
<datatype extension="watersmasslynx.raw.tar" type="galaxy.datatypes.binary:MassLynxTar" display_in_upload="true"/>
<datatype extension="wiff.tar" type="galaxy.datatypes.binary:WiffTar" display_in_upload="true"/>
<datatype extension="mascotxml" type="galaxy.datatypes.proteomics:MascotXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="mztab" type="galaxy.datatypes.proteomics:MzTab" display_in_upload="true"/>
<datatype extension="mztab2" type="galaxy.datatypes.proteomics:MzTab2" display_in_upload="true"/>
<datatype extension="mzml" type="galaxy.datatypes.proteomics:MzML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="nmrml" type="galaxy.datatypes.proteomics:NmrML" mimetype="application/xml" display_in_upload="true" description="nmrML is an open mark-up language for NMR data." description_url="http://nmrml.org/schema/"/>
<datatype extension="mgf" type="galaxy.datatypes.proteomics:Mgf" display_in_upload="true"/>
@@ -258,11 +269,18 @@
<datatype extension="mzdata" type="galaxy.datatypes.proteomics:MzData" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="ms2" type="galaxy.datatypes.proteomics:Ms2" display_in_upload="true"/>
<datatype extension="mzq" type="galaxy.datatypes.proteomics:MzQuantML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="sqlite" type="galaxy.datatypes.binary:SQlite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="mz.sqlite" type="galaxy.datatypes.binary:MzSQlite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="osw" type="galaxy.datatypes.binary:OSW" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="pqp" type="galaxy.datatypes.binary:PQP" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="traml" type="galaxy.datatypes.proteomics:TraML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="trafoxml" type="galaxy.datatypes.proteomics:TrafoXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="featurexml" type="galaxy.datatypes.proteomics:FeatureXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="consensusxml" type="galaxy.datatypes.proteomics:ConsensusXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="uniprotxml" type="galaxy.datatypes.proteomics:UniProtXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="xquest.xml" type="galaxy.datatypes.proteomics:XquestXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="spec.xml" type="galaxy.datatypes.proteomics:XquestSpecXML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="qcml" type="galaxy.datatypes.proteomics:QCML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="msp" type="galaxy.datatypes.proteomics:Msp" display_in_upload="true"/>
<datatype extension="splib_noindex" type="galaxy.datatypes.proteomics:SPLibNoIndex" display_in_upload="true"/>
<datatype extension="splib" type="galaxy.datatypes.proteomics:SPLib" display_in_upload="true"/>
@@ -286,6 +304,7 @@
<datatype extension="kronik" type="galaxy.datatypes.tabular:Tabular" subclass="true"/>
<datatype extension="imzml" type="galaxy.datatypes.proteomics:ImzML" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="analyze75" type="galaxy.datatypes.proteomics:Analyze75" mimetype="application/xml" display_in_upload="true"/>
<datatype extension="peff" type="galaxy.datatypes.proteomics:PEFF" display_in_upload="true"/>
<!-- End Proteomics Datatypes -->
<datatype extension="deeptools_compute_matrix_archive" type="galaxy.datatypes.binary:CompressedArchive" subclass="true" display_in_upload="true"/>
<datatype extension="deeptools_coverage_matrix" type="galaxy.datatypes.binary:CompressedArchive" subclass="true" display_in_upload="true"/>
@@ -343,9 +362,7 @@
<converter file="tabular_to_csv.xml" target_datatype="csv"/>
</datatype>
<datatype extension="twobit" type="galaxy.datatypes.binary:TwoBit" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="sqlite" type="galaxy.datatypes.binary:SQlite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="pqp" type="galaxy.datatypes.binary:SQlite" mimetype="application/octet-stream" display_in_upload="true" subclass="true"/>
<datatype extension="osw" type="galaxy.datatypes.binary:SQlite" mimetype="application/octet-stream" display_in_upload="true" subclass="true"/>
<datatype extension="sqmass" type="galaxy.datatypes.binary:SQmass" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="gemini.sqlite" type="galaxy.datatypes.binary:GeminiSQLite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="cuffdiff.sqlite" type="galaxy.datatypes.binary:CuffDiffSQlite" display_in_upload="true"/>
<datatype extension="gafa.sqlite" type="galaxy.datatypes.binary:GAFASQLite" mimetype="application/octet-stream" display_in_upload="true"/>
@@ -381,7 +398,11 @@
<display file="igb/wig.xml"/>
</datatype>
<datatype extension="interval_index" type="galaxy.datatypes.binary:Binary" subclass="true"/>
<datatype extension="odgi" type="galaxy.datatypes.binary:Binary" subclass="true" description="Genomic variation graphs self index used by odgi."/>
<datatype extension="odgi" type="galaxy.datatypes.binary:Binary" subclass="true" description="Genomic variation graphs self index used by odgi." display_in_upload="true"/>
<datatype extension="vg" type="galaxy.datatypes.binary:Binary" subclass="true" description="Genomic variation graphs." display_in_upload="true"/>
<datatype extension="xg" type="galaxy.datatypes.binary:Binary" subclass="true" description="Genomic variation graphs with vg index." display_in_upload="true"/>
<datatype extension="protobuf2" type="galaxy.datatypes.binary:Binary" subclass="true" description="Protocol Buffers (Protobuf) is data format for serializing structured data."/>
<datatype extension="protobuf3" type="galaxy.datatypes.binary:Binary" subclass="true" description="Protocol Buffers (Protobuf) is data format for serializing structured data."/>
<datatype extension="tabix" type="galaxy.datatypes.binary:Binary" subclass="true"/>
<datatype extension="bgzip" type="galaxy.datatypes.binary:Binary" subclass="true"/>
<datatype extension="vcf_bgzip" type="galaxy.datatypes.tabular:VcfGz" display_in_upload="true">
@@ -801,7 +822,10 @@
<sniffer type="galaxy.datatypes.tabular:Vcf"/>
<sniffer type="galaxy.datatypes.binary:TwoBit"/>
<sniffer type="galaxy.datatypes.binary:GeminiSQLite"/>
<sniffer type="galaxy.datatypes.binary:SQmass"/>
<sniffer type="galaxy.datatypes.binary:MzSQlite"/>
<sniffer type="galaxy.datatypes.binary:OSW"/>
<sniffer type="galaxy.datatypes.binary:PQP"/>
<sniffer type="galaxy.datatypes.binary:IdpDB"/>
<sniffer type="galaxy.datatypes.binary:ElibSQlite"/>
<sniffer type="galaxy.datatypes.binary:DlibSQlite"/>
@@ -851,21 +875,40 @@
<sniffer type="galaxy.datatypes.xml:Phyloxml"/>
<sniffer type="galaxy.datatypes.xml:Owl"/>
<sniffer type="galaxy.datatypes.xml:Sbml"/>
<sniffer type="galaxy.datatypes.proteomics:MzML"/>
<sniffer type="galaxy.datatypes.proteomics:NmrML"/>
<sniffer type="galaxy.datatypes.proteomics:TandemXML"/>
<sniffer type="galaxy.datatypes.proteomics:PepXml"/>
<sniffer type="galaxy.datatypes.proteomics:Dta2d"/>
<sniffer type="galaxy.datatypes.proteomics:Edta"/>
<sniffer type="galaxy.datatypes.proteomics:ConsensusXML"/>
<sniffer type="galaxy.datatypes.proteomics:IdXML"/>
<sniffer type="galaxy.datatypes.proteomics:FeatureXML"/>
<sniffer type="galaxy.datatypes.proteomics:MascotXML"/>
<sniffer type="galaxy.datatypes.proteomics:Mgf"/>
<sniffer type="galaxy.datatypes.proteomics:ProtXML"/>
<sniffer type="galaxy.datatypes.proteomics:MzXML"/>
<sniffer type="galaxy.datatypes.proteomics:MzData"/>
<sniffer type="galaxy.datatypes.proteomics:TraML"/>
<sniffer type="galaxy.datatypes.proteomics:MzIdentML"/>
<sniffer type="galaxy.datatypes.proteomics:MzQuantML"/>
<sniffer type="galaxy.datatypes.proteomics:UniProtXML"/>
<sniffer type="galaxy.datatypes.proteomics:Ms2"/>
<sniffer type="galaxy.datatypes.proteomics:Msp"/>
<sniffer type="galaxy.datatypes.proteomics:MzData"/>
<sniffer type="galaxy.datatypes.proteomics:MzIdentML"/>
<sniffer type="galaxy.datatypes.proteomics:MzML"/>
<sniffer type="galaxy.datatypes.proteomics:MzQuantML"/>
<sniffer type="galaxy.datatypes.proteomics:MzTab"/>
<sniffer type="galaxy.datatypes.proteomics:MzTab2"/>
<sniffer type="galaxy.datatypes.proteomics:ParamXml"/>
<sniffer type="galaxy.datatypes.proteomics:MzXML"/>
<sniffer type="galaxy.datatypes.proteomics:NmrML"/>
<sniffer type="galaxy.datatypes.proteomics:Kroenik"/>
<sniffer type="galaxy.datatypes.proteomics:PepList"/>
<sniffer type="galaxy.datatypes.proteomics:PSMS"/>
<sniffer type="galaxy.datatypes.proteomics:PepXml"/>
<sniffer type="galaxy.datatypes.proteomics:ProtXML"/>
<sniffer type="galaxy.datatypes.proteomics:SPLib"/>
<sniffer type="galaxy.datatypes.proteomics:TandemXML"/>
<sniffer type="galaxy.datatypes.proteomics:ThermoRAW"/>
<sniffer type="galaxy.datatypes.proteomics:TraML"/>
<sniffer type="galaxy.datatypes.proteomics:TrafoXML"/>
<sniffer type="galaxy.datatypes.proteomics:UniProtXML"/>
<sniffer type="galaxy.datatypes.proteomics:XquestXML"/>
<sniffer type="galaxy.datatypes.proteomics:XquestSpecXML"/>
<sniffer type="galaxy.datatypes.proteomics:QCML"/>
<sniffer type="galaxy.datatypes.proteomics:Wiff"/>
<sniffer type="galaxy.datatypes.proteomics:PEFF"/>
<sniffer type="galaxy.datatypes.molecules:CML"/>
<sniffer type="galaxy.datatypes.xml:GenericXml"/>
<sniffer type="galaxy.datatypes.triples:HDT"/>
+13 -7
View File
@@ -761,6 +761,11 @@ galaxy:
# Enable InteractiveTools.
#interactivetools_enable: false
# This flag enables an AWS cost estimate for every job based on their
# runtime matrices. CPU, RAM and runtime usage is mapped against AWS
# pricing table. Please note, that those numbers are only estimates.
#aws_estimate: false
# Proxy host - assumed to just be hosted on the same hostname and port
# as Galaxy by default.
#interactivetools_proxy_host: null
@@ -1161,8 +1166,7 @@ galaxy:
# Heartbeat log filename. Can accept the template variables
# {server_name} and {pid}
# Sample default 'heartbeat_{server_name}.log'
#heartbeat_log: null
#heartbeat_log: heartbeat_{server_name}.log
# Log to Sentry Sentry is an open source logging and error aggregation
# platform. Setting sentry_dsn will enable the Sentry middleware and
@@ -1881,11 +1885,13 @@ galaxy:
# workflow_resource_params_file). If this this is a function reference
# it will be passed various inputs (workflow model object and user)
# and it should produce a list of input IDs. If it is a path it is
# expected to an XML or YAML file describing how to map group names to
# parameter descriptions (additional types of mappings via these files
# could be implemented but haven't yet - for instance using workflow
# tags to do the mapping).
#workflow_resource_params_mapper: config/workflow_resource_mapper_conf.yml
# expected to be an XML or YAML file describing how to map group names
# to parameter descriptions (additional types of mappings via these
# files could be implemented but haven't yet - for instance using
# workflow tags to do the mapping).
# Sample default path
# 'config/workflow_resource_mapper_conf.yml.sample'
#workflow_resource_params_mapper: null
# Optional configuration file similar to `job_config_file` to specify
# which Galaxy processes should schedule workflows.
@@ -110,4 +110,25 @@ Please mind `http` and `https`.
<prompt>consent</prompt>
</provider>
<provider name="Okta">
<client_id> ... </client_id>
<client_secret> ... </client_secret>
<redirect_uri>http://localhost:8080/authnz/okta/callback</redirect_uri>
<!-- Okta API URL, based on 'Single Sign-On to Okta' URL here: https://developer.okta.com/docs/api/resources/oidc#2-okta-as-the-identity-platform-for-your-app-or-api
This has subsequently had the '/v1/authorize' removed. In productive deployments, this will likely resemble:
https://${company}.okta.com/oauth2/${authServerId}/
To get the URL, you have to create an application in Okta. The following settings serve as example as of the time of writing:
- Page 1 - Platform
- Platform: Web
- Page 2 - Settings
- Name: (Decide yourself)
- Base URIs: http://localhost:8080/
- Login redirect URIs: http://localhost:8080/authnz/okta/callback
- Grant type allowed: Authorization code
You should subsequently be able to get the client ID and the client secret from the Okta website.
-->
<api_url> ... </api_url>
</provider>
</OIDC>
@@ -5,6 +5,7 @@
<tool file="data_source/ucsc_tablebrowser.xml" />
<!-- <tool file="data_source/ucsc_tablebrowser_test.xml" /> -->
<tool file="data_source/ucsc_tablebrowser_archaea.xml" />
<tool file="data_source/sra.xml" />
<tool file="data_source/ebi_sra.xml" />
<tool file="data_source/fly_modencode.xml" />
<tool file="data_source/intermine.xml" />
@@ -246,10 +246,12 @@ tool_shed:
#allow_user_deletion: false
# For use by email messages sent from the Tool Shed.
#smtp_server: smtp.your_tool_shed_server
# (smtp.your_tool_shed_server)
#smtp_server: null
# For use by email messages sent from the Tool Shed.
#email_from: your_tool_shed_email@server
# (your_tool_shed_email@server)
#email_from: null
# If your SMTP server requires a username and password, you can
# provide them here (password in cleartext here, but if your server
@@ -377,7 +379,7 @@ tool_shed:
# logged are grid views, tool searches, and use of "recently" used
# tools menu. The log_events and log_actions functionality will
# eventually be merged.
#log_actions: true
#log_actions: false
# Password expiration period (in days). Users are required to change
# their password every x days. Users will be redirected to the change
+85
View File
@@ -1581,6 +1581,91 @@ class MzSQlite(SQlite):
return False
class PQP(SQlite):
"""
Class describing a Peptide query parameters file
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.pqp')
>>> PQP().sniff(fname)
True
>>> fname = get_test_fname('test.osw')
>>> PQP().sniff(fname)
False
"""
file_ext = "pqp"
def set_meta(self, dataset, overwrite=True, **kwd):
super(PQP, self).set_meta(dataset, overwrite=overwrite, **kwd)
def sniff(self, filename):
"""
table definition according to https://github.com/grosenberger/OpenMS/blob/develop/src/openms/source/ANALYSIS/OPENSWATH/TransitionPQPFile.cpp#L264
for now VERSION GENE PEPTIDE_GENE_MAPPING are excluded, since
there is test data wo these tables, see also here https://github.com/OpenMS/OpenMS/issues/4365
"""
if not super(PQP, self).sniff(filename):
return False
table_names = ['COMPOUND', 'PEPTIDE', 'PEPTIDE_PROTEIN_MAPPING', 'PRECURSOR',
'PRECURSOR_COMPOUND_MAPPING', 'PRECURSOR_PEPTIDE_MAPPING', 'PROTEIN',
'TRANSITION', 'TRANSITION_PEPTIDE_MAPPING', 'TRANSITION_PRECURSOR_MAPPING']
osw_table_names = ['FEATURE', 'FEATURE_MS1', 'FEATURE_MS2', 'FEATURE_TRANSITION', 'RUN']
return self.sniff_table_names(filename, table_names) and not self.sniff_table_names(filename, osw_table_names)
class OSW(SQlite):
"""
Class describing OpenSwath output
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.osw')
>>> OSW().sniff(fname)
True
>>> fname = get_test_fname('test.sqmass')
>>> OSW().sniff(fname)
False
"""
file_ext = "osw"
def set_meta(self, dataset, overwrite=True, **kwd):
super(OSW, self).set_meta(dataset, overwrite=overwrite, **kwd)
def sniff(self, filename):
# osw seems to be an extension of pqp (few tables are added)
# see also here https://github.com/OpenMS/OpenMS/issues/4365
if not super(OSW, self).sniff(filename):
return False
table_names = ['COMPOUND', 'PEPTIDE', 'PEPTIDE_PROTEIN_MAPPING', 'PRECURSOR',
'PRECURSOR_COMPOUND_MAPPING', 'PRECURSOR_PEPTIDE_MAPPING', 'PROTEIN',
'TRANSITION', 'TRANSITION_PEPTIDE_MAPPING', 'TRANSITION_PRECURSOR_MAPPING',
'FEATURE', 'FEATURE_MS1', 'FEATURE_MS2', 'FEATURE_TRANSITION', 'RUN']
return self.sniff_table_names(filename, table_names)
class SQmass(SQlite):
"""
Class describing a Sqmass database
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.sqmass')
>>> SQmass().sniff(fname)
True
>>> fname = get_test_fname('test.pqp')
>>> SQmass().sniff(fname)
False
"""
file_ext = "sqmass"
def set_meta(self, dataset, overwrite=True, **kwd):
super(SQmass, self).set_meta(dataset, overwrite=overwrite, **kwd)
def sniff(self, filename):
if super(SQmass, self).sniff(filename):
table_names = ["CHROMATOGRAM", "PRECURSOR", "RUN", "SPECTRUM", "DATA", "PRODUCT", "RUN_EXTRA"]
return self.sniff_table_names(filename, table_names)
return False
class BlibSQlite(SQlite):
"""Class describing a Proteomics Spectral Library Sqlite database """
MetadataElement(name="blib_version", default='1.8', param=MetadataParameter, desc="Blib Version",
+535 -5
View File
@@ -7,8 +7,9 @@ import re
from galaxy.datatypes import data
from galaxy.datatypes.binary import Binary
from galaxy.datatypes.data import Text
from galaxy.datatypes.sequence import Sequence
from galaxy.datatypes.sniff import build_sniff_from_prefix
from galaxy.datatypes.tabular import Tabular
from galaxy.datatypes.tabular import Tabular, TabularData
from galaxy.datatypes.xml import GenericXml
from galaxy.util import nice_size
@@ -53,6 +54,221 @@ class Wiff(Binary):
return "\n".join(rval)
@build_sniff_from_prefix
class MzTab(Text):
"""
exchange format for proteomics and metabolomics results
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.mztab')
>>> MzTab().sniff(fname)
True
>>> fname = get_test_fname('test.mztab2')
>>> MzTab().sniff(fname)
False
"""
edam_data = "data_3681"
file_ext = "mztab"
# section names (except MTD)
_sections = ["PRH", "PRT", "PEH", "PEP", "PSH", "PSM", "SMH", "SML", "COM"]
# mandatory metadata fields and list of allowed entries (in lower case)
# (or None if everything is allowed)
_man_mtd = {"mzTab-mode": ["complete", "summary"],
"mzTab-type": ['quantification', 'identification'],
"description": None}
_version_re = r"(1)(\.[0-9])?(\.[0-9])?"
def __init__(self, **kwd):
super(MzTab, self).__init__(**kwd)
def set_peek(self, dataset, is_multi_byte=False):
"""Set the peek and blurb text"""
if not dataset.dataset.purged:
dataset.peek = data.get_file_peek(dataset.file_name)
dataset.blurb = 'mzTab Format'
else:
dataset.peek = 'file does not exist'
dataset.blurb = 'file purged from disk'
def sniff_prefix(self, file_prefix):
""" Determines whether the file is the correct type. """
has_version = False
found_man_mtd = set()
contents = file_prefix.string_io()
for line in contents:
if re.match(r"^\s*$", line):
continue
line = line.strip("\r\n").split("\t")
if line[0] == "MTD":
if line[1] == "mzTab-version" and re.match(self._version_re, line[2]) is not None:
has_version = True
elif line[1] in self._man_mtd and (self._man_mtd[line[1]] is None or line[2].lower() in self._man_mtd[line[1]]):
found_man_mtd.add(line[1])
elif not line[0] in self._sections:
return False
return has_version and found_man_mtd == set(self._man_mtd.keys())
class MzTab2(MzTab):
"""
exchange format for proteomics and metabolomics results
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.mztab2')
>>> MzTab2().sniff(fname)
True
>>> fname = get_test_fname('test.mztab')
>>> MzTab2().sniff(fname)
False
"""
file_ext = "mztab2"
_sections = ["SMH", "SML", "SFH", "SMF", "SEH", "SME", "COM"]
_version_re = r"(2)(\.[0-9])?(\.[0-9])?-M$"
_man_mtd = {"mzTab-ID": None}
def __init__(self, **kwd):
super(MzTab2, self).__init__(**kwd)
def set_peek(self, dataset, is_multi_byte=False):
"""Set the peek and blurb text"""
if not dataset.dataset.purged:
dataset.peek = data.get_file_peek(dataset.file_name)
dataset.blurb = 'mzTab2 Format'
else:
dataset.peek = 'file does not exist'
dataset.blurb = 'file purged from disk'
@build_sniff_from_prefix
class Kroenik(Tabular):
"""
Kroenik (HardKloer sibling) files
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.kroenik')
>>> Kroenik().sniff(fname)
True
>>> fname = get_test_fname('test.peplist')
>>> Kroenik().sniff(fname)
False
"""
file_ext = "kroenik"
def __init__(self, **kwd):
super(Kroenik, self).__init__(**kwd)
self.column_names = ["File", "First Scan", "Last Scan", "Num of Scans", "Charge", "Monoisotopic Mass", "Base Isotope Peak", "Best Intensity", "Summed Intensity", "First RTime", "Last RTime", "Best RTime", "Best Correlation", "Modifications"]
def display_peek(self, dataset):
"""Returns formated html of peek"""
return self.make_html_table(dataset, column_names=self.column_names)
def sniff_prefix(self, file_prefix):
fh = file_prefix.string_io()
line = [_.strip() for _ in fh.readline().split("\t")]
if line != self.column_names:
return False
line = fh.readline().split("\t")
try:
[int(_) for _ in line[1:5]]
[float(_) for _ in line[5:13]]
except ValueError:
return False
return True
@build_sniff_from_prefix
class PepList(Tabular):
"""
Peplist file as used in OpenMS
https://github.com/OpenMS/OpenMS/blob/0fc8765670a0ad625c883f328de60f738f7325a4/src/openms/source/FORMAT/FileHandler.cpp#L432
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.peplist')
>>> PepList().sniff(fname)
True
>>> fname = get_test_fname('test.psms')
>>> PepList().sniff(fname)
False
"""
file_ext = "peplist"
def __init__(self, **kwd):
super(PepList, self).__init__(**kwd)
self.column_names = ["m/z", "rt(min)", "snr", "charge", "intensity"]
def display_peek(self, dataset):
"""Returns formated html of peek"""
return self.make_html_table(dataset, column_names=self.column_names)
def sniff_prefix(self, file_prefix):
fh = file_prefix.string_io()
line = [_.strip() for _ in fh.readline().split("\t")]
if line == self.column_names:
return True
return False
@build_sniff_from_prefix
class PSMS(Tabular):
"""
Percolator tab-delimited output (PSM level, .psms) as used in OpenMS
https://github.com/OpenMS/OpenMS/blob/0fc8765670a0ad625c883f328de60f738f7325a4/src/openms/source/FORMAT/FileHandler.cpp#L453
see also http://www.kojak-ms.org/docs/percresults.html
Note that the data rows can have more columns than the header line
since ProteinIds are listed tab-separated.
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.psms')
>>> PSMS().sniff(fname)
True
>>> fname = get_test_fname('test.kroenik')
>>> PSMS().sniff(fname)
False
"""
file_ext = "psms"
def __init__(self, **kwd):
super(PSMS, self).__init__(**kwd)
self.column_names = ["PSMId", "score", "q-value", "posterior_error_prob", "peptide", "proteinIds"]
def display_peek(self, dataset):
"""Returns formated html of peek"""
return self.make_html_table(dataset, column_names=self.column_names)
def sniff_prefix(self, file_prefix):
fh = file_prefix.string_io()
line = [_.strip() for _ in fh.readline().split("\t")]
if line == self.column_names:
return True
return False
@build_sniff_from_prefix
class PEFF(Sequence):
"""
PSI Extended FASTA Format
https://github.com/HUPO-PSI/PEFF
"""
file_ext = "peff"
def sniff_prefix(self, file_prefix):
"""
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname( 'test.peff' )
>>> PEFF().sniff( fname )
True
>>> fname = get_test_fname( 'sequence.fasta' )
>>> PEFF().sniff( fname )
False
"""
fh = file_prefix.string_io()
if re.match(r"# PEFF \d+.\d+", fh.readline()):
return True
else:
return False
class PepXmlReport(Tabular):
"""pepxml converted to tabular report"""
edam_data = "data_2536"
@@ -92,6 +308,277 @@ class ProtXmlReport(Tabular):
return self.make_html_table(dataset, column_names=self.column_names)
class Dta(TabularData):
"""dta
The first line contains the singly protonated peptide mass (MH+) and the
peptide charge state separated by a space. Subsequent lines contain space
separated pairs of fragment ion m/z and intensity values.
"""
file_ext = "dta"
comment_lines = 0
def set_meta(self, dataset, **kwd):
column_types = []
data_row = []
data_lines = 0
if dataset.has_data():
with open(dataset.file_name, 'r') as dtafile:
for line in dtafile:
data_lines += 1
# Guess column types
for cell in data_row:
column_types.append(self.guess_type(cell))
# Set metadata
dataset.metadata.data_lines = data_lines
dataset.metadata.comment_lines = 0
dataset.metadata.column_types = ['float', 'float']
dataset.metadata.columns = 2
dataset.metadata.column_names = ['m/z', 'intensity']
dataset.metadata.delimiter = " "
@build_sniff_from_prefix
class Dta2d(TabularData):
"""
dta2d: files with three tab/space-separated columns.
The default format is: retention time (seconds) , m/z , intensity.
If the first line starts with '#', a different order is defined by the the
order of the keywords 'MIN' (retention time in minutes) or 'SEC' (retention
time in seconds), 'MZ', and 'INT'.
Example: '#MZ MIN INT'
The peaks of one retention time have to be in subsequent lines.
Note: sniffer detects (tab or space separated) dta2d files with correct
header, wo header seems to generic
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.dta2d')
>>> Dta2d().sniff(fname)
True
>>> fname = get_test_fname('test.edta')
>>> Dta2d().sniff(fname)
False
"""
file_ext = "dta2d"
comment_lines = 0
def _parse_header(self, line):
if len(line) != 3 or len(line[0]) < 3 or not line[0].startswith("#"):
return None
line[0] = line[0].lstrip("#")
line = [_.strip() for _ in line]
if 'MZ' not in line or 'INT' not in line or ('MIN' not in line and 'SEC' not in line):
return None
return line
def _parse_delimiter(self, line):
if len(line.split(" ")) == 3:
return " "
elif len(line.split("\t")) == 3:
return "\t"
return None
def _parse_dataline(self, line):
try:
line = [float(_) for _ in line]
except ValueError:
return False
if not all(_ >= 0 for _ in line):
return False
return True
def set_meta(self, dataset, **kwd):
data_lines = 0
delim = None
if dataset.has_data():
with open(dataset.file_name, 'r') as dtafile:
for line in dtafile:
if delim is None:
delim = self._parse_delimiter(line)
dataset.metadata.column_names = self._parse_header(line.split(delim))
data_lines += 1
# Set metadata
if delim is not None:
dataset.metadata.delimiter = delim
dataset.metadata.data_lines = data_lines
dataset.metadata.comment_lines = 0
dataset.metadata.column_types = ['float', 'float', 'float']
dataset.metadata.columns = 3
if dataset.metadata.column_names is None or dataset.metadata.column_names == []:
dataset.metadata.comment_lines += 1
dataset.metadata.data_lines -= 1
dataset.metadata.column_names = ['SEC', 'MZ', 'INT']
def sniff_prefix(self, file_prefix):
sep = None
header = None
for idx, line in enumerate(file_prefix.line_iterator()):
line = line.strip()
if sep is None:
sep = self._parse_delimiter(line)
if sep is None:
return False
line = line.split(sep)
if len(line) != 3:
return False
if idx == 0:
header = self._parse_header(line)
if (header is None) and not self._parse_dataline(line):
return False
elif not self._parse_dataline(line):
return False
if sep is None or header is None:
return False
return True
@build_sniff_from_prefix
class Edta(TabularData):
"""
Input text file containing tab, space or comma separated columns.
The separator between columns is checked in the first line in this order.
It supports three variants of this format.
1. Columns are: RT, MZ, Intensity A header is optional.
2. Columns are: RT, MZ, Intensity, Charge, <Meta-Data> columns{0,} A header is mandatory.
3. Columns are: (RT, MZ, Intensity, Charge){1,}, <Meta-Data> columns{0,}
Header is mandatory. First quadruplet is the consensus. All following
quadruplets describe the sub-features. This variant is discerned from
variant #2 by the name of the fifth column, which is required to be RT1
(or rt1). All other column names for sub-features are faithfully ignored.
Note the sniffer only detects files with header.
>>> from galaxy.datatypes.sniff import get_test_fname
>>> fname = get_test_fname('test.edta')
>>> Edta().sniff(fname)
True
>>> fname = get_test_fname('test.dta2d')
>>> Edta().sniff(fname)
False
"""
file_ext = "edta"
comment_lines = 0
def _parse_delimiter(self, line):
if len(line.split(" ")) >= 3:
return " "
elif len(line.split("\t")) >= 3:
return "\t"
elif len(line.split(",")) >= 3:
return "\t"
return None
def _parse_type(self, line):
"""
parse the type from the header line
types 1-3 as in the class docs, 0: type 1 wo/wrong header
"""
if len(line) < 3:
return None
line = [_.lower().replace("/", "") for _ in line]
if len(line) == 3:
if line[0] == "rt" and line[1] == "mz" and (line[2] == "int" or line[2] == "intensity"):
return 1
else:
return None
if line[0] != "rt" or line[1] != "mz" or (line[2] != "int" and line[2] != "intensity") or line[3] != "charge":
return None
if not line[4].startswith("rt"):
return 2
else:
return 3
def _parse_dataline(self, line, tpe):
if tpe == 2 or tpe == 3:
idx = 4
else:
idx = 3
try:
line = [float(_) for _ in line[:idx]]
except ValueError:
return False
if not all(_ >= 0 for _ in line[:idx]):
return False
return True
def _clean_header(self, line):
for idx, el in enumerate(line):
el = el.lower()
if el.startswith("rt"):
line[idx] = "RT"
elif el.startswith("int"):
line[idx] = "intensity"
elif el.startswith("mz"):
line[idx] = "m/z"
elif el.startswith("charge"):
line[idx] = "charge"
else:
break
if idx // 4 > 0:
line[idx] += str(idx // 4)
return line
def set_meta(self, dataset, **kwd):
data_lines = 0
delim = None
if dataset.has_data():
with open(dataset.file_name, 'r') as dtafile:
for idx, line in enumerate(dtafile):
if idx == 0:
delim = self._parse_delimiter(line)
tpe = self._parse_type(line.split(delim))
if tpe == 0:
dataset.metadata.column_names = ["RT", "m/z", "intensity"]
else:
dataset.metadata.column_names = self._clean_header(line.split(delim))
data_lines += 1
# Set metadata
if delim is not None:
dataset.metadata.delimiter = delim
for c in dataset.metadata.column_names:
if any(c.startswith(_) for _ in ["RT", "m/z", "intensity", "charge"]):
dataset.metadata.column_types.append("float")
else:
dataset.metadata.column_types.append("str")
dataset.metadata.data_lines = data_lines
dataset.metadata.comment_lines = 0
dataset.metadata.columns = len(dataset.metadata.column_names)
if tpe > 0:
dataset.metadata.comment_lines += 1
dataset.metadata.data_lines -= 1
def sniff_prefix(self, file_prefix):
sep = None
tpe = None
for idx, line in enumerate(file_prefix.line_iterator()):
line = line.strip("\r\n")
if sep is None:
sep = self._parse_delimiter(line)
if sep is None:
return False
line = line.split(sep)
if idx == 0:
tpe = self._parse_type(line)
if tpe is None:
return False
elif tpe == 0 and not self._parse_dataline(line, tpe):
return False
elif not self._parse_dataline(line, tpe):
return False
if tpe is None:
return False
return True
class ProteomicsXml(GenericXml):
""" An enhanced XML datatype used to reuse code across several
proteomic/mass-spec datatypes. """
@@ -102,12 +589,12 @@ class ProteomicsXml(GenericXml):
""" Determines whether the file is the correct XML type. """
contents = file_prefix.string_io()
while True:
line = contents.readline()
line = contents.readline().strip()
if line is None or not line.startswith('<?'):
break
# pattern match <root or <ns:root for any ns string
pattern = r'^<(\w*:)?%s' % self.root
return line is not None and re.match(pattern, line) is not None
pattern = r'<(\w*:)?%s' % self.root
return line is not None and re.search(pattern, line) is not None
def set_peek(self, dataset, is_multi_byte=False):
"""Set the peek and blurb text"""
@@ -119,6 +606,13 @@ class ProteomicsXml(GenericXml):
dataset.blurb = 'file purged from disk'
class ParamXml(ProteomicsXml):
"""store Parameters in XML formal"""
file_ext = "paramxml"
blurb = "parameters in xmls"
root = "parameters|PARAMETERS"
class PepXml(ProteomicsXml):
"""pepXML data"""
edam_format = "format_3655"
@@ -127,6 +621,13 @@ class PepXml(ProteomicsXml):
root = "msms_pipeline_analysis"
class MascotXML(ProteomicsXml):
"""mzXML data"""
file_ext = "mascotxml"
blurb = "mascot Mass Spectrometry data"
root = "mascot_search_results"
class MzML(ProteomicsXml):
"""mzML data"""
edam_format = "format_3244"
@@ -180,6 +681,12 @@ class TraML(ProteomicsXml):
root = "TraML"
class TrafoXML(ProteomicsXml):
file_ext = "trafoxml"
blurb = "RT alignment tranformation"
root = "TrafoXML"
class MzQuantML(ProteomicsXml):
edam_format = "format_3248"
file_ext = "mzq"
@@ -218,6 +725,29 @@ class UniProtXML(ProteomicsXml):
root = "uniprot"
class XquestXML(ProteomicsXml):
file_ext = "xquest.xml"
blurb = "XQuest XML file"
root = "xquest_results"
class XquestSpecXML(ProteomicsXml):
"""spec.xml"""
file_ext = "spec.xml"
blurb = 'xquest_spectra'
root = "xquest_spectra"
class QCML(ProteomicsXml):
"""qcml
https://github.com/OpenMS/OpenMS/blob/113c49d01677f7f03343ce7cd542d83c99b351ee/share/OpenMS/SCHEMAS/mzQCML_0_0_5.xsd
https://github.com/OpenMS/OpenMS/blob/3cfc57ad1788e7ab2bd6dd9862818b2855234c3f/share/OpenMS/SCHEMAS/qcML_0.0.7.xsd
"""
file_ext = "qcml"
blurb = 'QualityAssessments to runs'
root = "qcML|MzQualityML)"
class Mgf(Text):
"""Mascot Generic Format data"""
edam_data = "data_2536"
@@ -278,7 +808,7 @@ class ThermoRAW(Binary):
"""Class describing a Thermo Finnigan binary RAW file"""
edam_data = "data_2536"
edam_format = "format_3712"
file_ext = "raw"
file_ext = "thermo.raw"
def sniff(self, filename):
# Thermo Finnigan RAW format is proprietary and hence not well documented.
-13
View File
@@ -765,23 +765,19 @@ class Registry(object):
'coverage' : coverage.LastzCoverage(),
'customtrack' : interval.CustomTrack(),
'csfasta' : sequence.csFasta(),
'db3' : binary.SQlite(),
'fasta' : sequence.Fasta(),
'eland' : tabular.Eland(),
'fastq' : sequence.Fastq(),
'fastqsanger' : sequence.FastqSanger(),
'gemini.sqlite' : binary.GeminiSQLite(),
'gtf' : interval.Gtf(),
'gff' : interval.Gff(),
'gff3' : interval.Gff3(),
'genetrack' : tracks.GeneTrack(),
'h5' : binary.H5(),
'idpdb' : binary.IdpDB(),
'interval' : interval.Interval(),
'laj' : images.Laj(),
'lav' : sequence.Lav(),
'maf' : sequence.Maf(),
'mz.sqlite' : binary.MzSQlite(),
'pileup' : tabular.Pileup(),
'qualsolid' : qualityscore.QualityScoreSOLiD(),
'qualsolexa' : qualityscore.QualityScoreSolexa(),
@@ -801,26 +797,21 @@ class Registry(object):
'axt' : 'text/plain',
'bam' : 'application/octet-stream',
'bed' : 'text/plain',
'blib' : 'application/octet-stream',
'customtrack' : 'text/plain',
'csfasta' : 'text/plain',
'db3' : 'application/octet-stream',
'eland' : 'application/octet-stream',
'fasta' : 'text/plain',
'fastq' : 'text/plain',
'fastqsanger' : 'text/plain',
'gemini.sqlite' : 'application/octet-stream',
'gtf' : 'text/plain',
'gff' : 'text/plain',
'gff3' : 'text/plain',
'h5' : 'application/octet-stream',
'idpdb' : 'application/octet-stream',
'interval' : 'text/plain',
'laj' : 'text/plain',
'lav' : 'text/plain',
'maf' : 'text/plain',
'memexml' : 'application/xml',
'mz.sqlite' : 'application/octet-stream',
'pileup' : 'text/plain',
'qualsolid' : 'text/plain',
'qualsolexa' : 'text/plain',
@@ -846,10 +837,6 @@ class Registry(object):
binary.Bam(),
binary.Sff(),
binary.H5(),
binary.GeminiSQLite(),
binary.MzSQlite(),
binary.IdpDB(),
binary.SQlite(),
xml.GenericXml(),
sequence.Maf(),
sequence.Lav(),
+9
View File
@@ -0,0 +1,9 @@
#MZ SEC INT
500.0 0 50
600.0 1 100
700.0 2 200
800.0 3 400
900.0 4 200
1000.0 5 100
1100.0 6 50
900.0 2 200
+7
View File
@@ -0,0 +1,7 @@
RT mz Int charge Meta2
10 114 2342 1
10 115 232 2
10 116 523 2
14 220 343 1 value
14 431.1 343 2
15 543.2393 343 3 b
+23
View File
@@ -0,0 +1,23 @@
File First Scan Last Scan Num of Scans Charge Monoisotopic Mass Base Isotope Peak Best Intensity Summed Intensity First RTime Last RTime Best RTime Best Correlation Modifications
20060502data08_exc_RTf.mzXML 1480 1578 15 3 1345.607960 449.543300 60834.925781 506348.656250 521.106018 553.833008 533.018982 0.991700 _
20060502data08_exc_RTf.mzXML 1487 1557 11 2 1345.608400 673.811500 26904.589844 199969.046875 523.559998 546.731018 533.018982 0.995300 _
20060502data08_exc_RTf.mzXML 1557 1620 10 3 2002.810800 668.945100 38904.792969 217929.312500 546.731018 567.784973 553.833008 0.986300 _
20060502data08_exc_RTf.mzXML 1571 1592 4 2 2002.811525 1002.913800 4603.663086 14353.689453 551.427979 558.577026 556.184998 0.978400 _
20060502data08_exc_RTf.mzXML 1592 1690 15 3 1772.892100 591.971200 91715.507813 502103.500000 558.577026 590.963013 567.784973 0.986900 _
20060502data08_exc_RTf.mzXML 1599 1683 13 4 1772.891285 444.230100 72974.398438 417335.125000 560.914001 588.521973 570.002014 0.974700 _
20060502data08_exc_RTf.mzXML 1599 1676 11 2 1772.889336 887.452600 22342.041016 122096.265625 560.914001 586.155029 567.784973 0.994600 _
20060502data08_exc_RTf.mzXML 1690 1774 13 2 1401.655615 701.834900 37010.062500 262936.343750 590.963013 619.705017 605.291992 0.995500 _
20060502data08_exc_RTf.mzXML 1746 1816 11 2 1065.545100 533.779800 48403.296875 347601.562500 610.046997 634.202026 622.135986 0.979800 _
20060502data08_exc_RTf.mzXML 1816 1851 6 4 2095.873767 525.226300 17985.734375 73192.179688 634.202026 646.385986 641.471008 0.986700 _
20060502data08_exc_RTf.mzXML 1858 1879 4 4 1904.987400 477.504500 7037.772461 16893.957031 648.786011 656.114014 656.114014 0.962100 _
20060502data08_exc_RTf.mzXML 1879 1907 4 2 994.581075 498.297700 28557.644531 92082.468750 656.114014 665.525024 660.861023 0.996100 _
20060502data08_exc_RTf.mzXML 1886 1994 15 3 1506.688193 503.236500 223091.640625 1329185.625000 658.479980 693.369995 670.021973 0.989100 _
20060502data08_exc_RTf.mzXML 1893 1955 10 2 1506.689740 754.352500 49197.664063 307397.281250 660.861023 680.966003 672.174988 0.990500 _
20060502data08_exc_RTf.mzXML 1907 2056 23 4 2239.081209 561.027900 189284.390625 1359320.875000 665.525024 713.080994 685.143005 0.973600 _
20060502data08_exc_RTf.mzXML 1914 1994 13 2 1336.644692 669.329400 174888.703125 994234.375000 667.744019 693.369995 676.612000 0.990700 _
20060502data08_exc_RTf.mzXML 1921 1988 10 2 1478.675160 740.344800 119720.226563 577115.250000 670.021973 691.309998 678.859985 0.985600 _
20060502data08_exc_RTf.mzXML 1928 1948 3 2 1697.803500 849.907800 3211.451660 7545.761719 672.174988 678.859985 672.174988 0.927400 _
20060502data08_exc_RTf.mzXML 1935 1955 4 2 1127.618850 564.816500 67462.703125 183348.593750 674.471985 680.966003 680.966003 0.950400 _
20060502data08_exc_RTf.mzXML 1941 2021 12 3 2239.081067 747.701800 67137.210938 463090.031250 676.612000 701.872009 683.143982 0.991200 _
20060502data08_exc_RTf.mzXML 1948 2028 13 2 1583.758454 792.886000 36854.781250 262471.843750 678.859985 704.109009 691.309998 0.993400 _
20060502data08_exc_RTf.mzXML 1955 2021 11 3 1583.757945 528.926500 128648.492188 829892.062500 680.966003 701.872009 691.309998 0.990400 _
+28
View File
@@ -0,0 +1,28 @@
MTD mzTab-version 1.0 rc5
MTD mzTab-mode Summary
MTD mzTab-type Identification
MTD mzTab-ID Cytidine
MTD description LC-MS/MS Reference Standard
MTD sample_processing[1] [MS, MS:1000544, Conversion to mzML, ]|[MS, MS:1000035, Peak picking, ]|[MS, MS:1001994, Top Hat baseline reduction, ]|[MS, MS:1000782, Savitzky-Golay smoothing, ]|[MS, MS:1000594, Low intensity data point removal, ]
MTD instrument[1]-name [MS, MS:1000483, Thermo Fisher Scientific instrument model, LTQ Orbitrap Velos]
MTD instrument[1]-source [MS, MS:1000008, Ionization Type, ESI]
MTD instrument[1]-analyzer[1] [MS, MS:1000443, Mass Analyzer Type, Orbitrap]
MTD instrument[1]-detector [MS, MS:1000453, Detector, Dynode Detector]
MTD software[1] [MS, MS:1002205, ProteoWizard msconvert, ]
MTD software[1]-setting[1] Peak Picking MS1
MTD software[1] [MS, MS:1001457, data processing software, MassCascade-KNIME]
MTD smallmolecule_search_engine_score[1] [MS, MS:1001153, search engine specific score,]
MTD contact[1]-name Stephan Beisken
MTD contact[1]-affiliation European Bioinformatics Institute (EMBL-EBI)
MTD contact[1]-email beiken@ebi.ac.uk
MTD uri[1] http://www.ebi.ac.uk/metabolights/MTBLS38
MTD fixed_mod[1] [MS, MS:1002453, No fixed modifications searched, ]
MTD variable_mod[1] [ , , CHEMMOD:2M+H, ]
MTD variable_mod[2] [ , , CHEMMOD:M-C5H8O4, ]
MTD ms_run[1]-format [MS, MS:1000584, Proteomics Standards Inititative mzML file format, mzML file]
MTD ms_run[1]-location ftp://ftp.ebi.ac.uk/pub/databases/metabolights/studies/public/MTBLS38/cytidine.mzML
MTD ms_run[1]-id_format [MS, MS:1000767, Native spectrum identifier format, ]
MTD ms_run[1]-fragmentation_method [MS, MS:1000133, Collision-induced dissociation, ]
SMH identifier chemical_formula smiles inchi_key description exp_mass_to_charge calc_mass_to_charge charge retention_time taxid species database database_version spectra_ref search_engine best_search_engine_score[1] modifications
SML CHEBI:17562 C9H13N3O5 Nc1ccn([C@@H]2O[C@H](CO)[C@@H](O)[C@H]2O)c(=O)n1 UHDGCWIWMRVCDJ-XVFCMESISA-N Cytidine 244.0928 null 1 193.25 null null ChEBI 109 null [MS, MS:1001083, ms-ms search, MassBank] 977 CHEMMOD:2M+H,CHEMMOD:M-C5H8O4
+92
View File
@@ -0,0 +1,92 @@
COM Meta data section
MTD mzTab-version 2.0.0-M
MTD mzTab-ID mzTab-GCxGC-MS
MTD description Minimal sample file for GCxGC-MS quantification of small molecules between two experiments
MTD instrument[1]-name [MS, MS:1001945, Pegasus 4D, ]
MTD instrument[1]-source [MS, MS:1000389, electron Ionization, ]
MTD instrument[1]-analyzer[1] [MS, MS:1000084, time-of-flight, ]
MTD instrument[1]-detector [MS, MS:1000114, microchannel plate detector, ]
MTD software[1] [MS, MS:1001799, ChromaTOF software, 3.21]
MTD software[1]-setting[1] baseline=0.2
MTD software[1]-setting[2] dbMatchTreshold=900
MTD sample[1]-species[1] [NCBITaxon, NCBITaxon:9606, Homo sapiens, ]
MTD sample[1]-cell_type[1] [CL, CL:0000233, platelet, ]
MTD sample[1]-description Unstimulated human blood platelets
MTD sample[2]-species[1] [NCBITaxon, NCBITaxon:9606, Homo sapiens, ]
MTD sample[2]-cell_type[1] [CL, CL:0000233, platelet, ]
MTD sample[2]-description Unstimulated human blood platelets
MTD ms_run[1]-location file://c:/data/control.mzML
MTD ms_run[1]-format [MS, MS:1000584, mzML file, ]
MTD ms_run[1]-id_format [MS, MS:1000776, scan number only nativeID format, ]
MTD ms_run[1]-scan_polarity[1] [MS, MS:1000130, positive scan, ]
MTD ms_run[2]-location file://c:/data/treatment.mzML
MTD ms_run[2]-format [MS, MS:1000584, mzML file, ]
MTD ms_run[2]-id_format [MS, MS:1000776, scan number only nativeID format, ]
MTD ms_run[2]-scan_polarity[1] [MS, MS:1000130, positive scan, ]
MTD assay[1]-sample_ref sample[1]
MTD assay[1]-ms_run_ref ms_run[1]
MTD assay[2]-sample_ref sample[2]
MTD assay[2]-ms_run_ref ms_run[2]
MTD study_variable[1] Untreated
MTD study_variable[1]-assay_refs assay[1]
MTD study_variable[1]-description drug response control
MTD study_variable[1]-average_function [MS, MS:1002962, mean, ]
MTD study_variable[1]-variation_function [MS, MS:1002885, standard error, ]
MTD study_variable[2] Treated
MTD study_variable[2]-assay_refs assay[2]
MTD study_variable[2]-description drug response treatment
MTD study_variable[2]-average_function [MS, MS:1002962, mean, ]
MTD study_variable[2]-variation_function [MS, MS:1002885, standard error, ]
MTD cv[1]-label MS
MTD cv[1]-full_name PSI-MS controlled vocabulary
MTD cv[1]-version 20-06-2018
MTD cv[1]-uri https://www.ebi.ac.uk/ols/ontologies/ms
MTD cv[2]-label NCBITaxon
MTD cv[2]-full_name An ontology representation of the NCBI organismal taxonomy Ontology
MTD cv[2]-version 2018-03-02
MTD cv[2]-uri https://www.ebi.ac.uk/ols/ontologies/ncbitaxon
MTD cv[3]-label CL
MTD cv[3]-full_name The Cell Ontology is a structured controlled vocabulary for cell types in animals.
MTD cv[3]-version 2017-12-11
MTD cv[3]-uri https://www.ebi.ac.uk/ols/ontologies/cl
MTD cv[4]-label PRIDE
MTD cv[4]-full_name PRIDE PRoteomics IDEntifications (PRIDE) database controlled vocabulary
MTD cv[4]-version 14-06-2018
MTD cv[4]-uri https://www.ebi.ac.uk/ols/ontologies/pride
MTD cv[5]-label CHEBI
MTD cv[5]-full_name Chemical Entities of Biological Interest
MTD cv[5]-version 08-02-2019
MTD cv[5]-uri https://www.ebi.ac.uk/ols/ontologies/chebi
MTD database[1] [, ,Golm Metabolite Database, ]
MTD database[1]-prefix GMD
MTD database[1]-version 2.3
MTD database[1]-uri http://gmd.mpimp-golm.mpg.de/
MTD database[2] [, , no database, null]
MTD database[2]-prefix null
MTD database[2]-uri null
MTD database[2]-version Unknown
MTD derivatization_agent[1] [,,Methoxylamine hydrochloride,]
MTD derivatization_agent[2] [CHEBI, CHEBI:85064, N-methyl-N-(trimethylsilyl)trifluoroacetamide,]
MTD small_molecule-identification_reliability [MS, MS:1002896, compound identification confidence level, ]
MTD id_confidence_measure[1] [MS, MS:1002890, fragmentation score, ]
MTD small_molecule-quantification_unit [PRIDE, PRIDE:0000330, Arbitrary quantification unit, ]
MTD small_molecule_feature-quantification_unit [PRIDE, PRIDE:0000330, Arbitrary quantification unit, ]
MTD quantification_method [,,baseline-corrected intensity quantification,]
MTD custom[1] [MS, MS:1000901, retention time normalization standard, n-alkanes C10–C36]
COM Small molecule summary rows (similar to Protein section).
COM Evidences (e.g. multiple modifications, adducts incl. charge variants are summarized).
COM For most use cases this summary lines might be sufficient.
SMH SML_ID SMF_ID_REFS database_identifier chemical_formula smiles inchi chemical_name uri theoretical_neutral_mass adduct_ions reliability best_id_confidence_measure best_id_confidence_value abundance_assay[1] abundance_study_variable[1] abundance_variation_study_variable[1] abundance_assay[2] abundance_study_variable[2] abundance_variation_study_variable[2]
SML 1 1 | 2 GMD:cd7993ea-ad14-452a-a907-33376cc98790 C18H36O2 CCCCCCCCCCCCCCCCCC(O)=O InChI=1S/C18H36O2/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18(19)20/h2-17H2,1H3,(H,19,20) Octadecanoic acid http://identifiers.org/gmd/cd7993ea-ad14-452a-a907-33376cc98790 284.478 [M+H]1+ 2 [MS, MS:1002890, fragmentation score, ] 978 805.16 805.16 0 589.9 589.9 0
COM Small molecule feature rows (only reported in Complete Quantification files and if feature information like e.g. mass traces are important)
SFH SMF_ID SME_ID_REFS SME_ID_REF_ambiguity_code adduct_ion isotopomer exp_mass_to_charge charge retention_time_in_seconds retention_time_in_seconds_start retention_time_in_seconds_end abundance_assay[1] abundance_assay[2] opt_global_retention_time_nd opt_global_retention_time_nd_window_start opt_global_retention_time_nd_window_end
SMF 1 1 null [M+H]1+ null 285.484 1 1564.47 1559.45 1564.48 805.16 805.16 1562 | 2.47 1557 | 2.45 1562 | 2.48
SMF 2 2 null [M+H]1+ null 285.484 1 1564.48 1554.45 1569.47 589.9 589.9 1562 | 2.48 1552 | 2.45 1567| 2.47
COM Small molecule evidence rows for parent ions. Analog to PSM.
COM Primary use case: report single hits from spectral library or accurate mass searches without quantification.
SEH SME_ID evidence_input_id database_identifier chemical_formula smiles inchi chemical_name uri derivatized_form adduct_ion exp_mass_to_charge charge theoretical_mass_to_charge spectra_ref identification_method ms_level id_confidence_measure[1] rank
SME 1 ms_run[1]:scan=8 GMD:f634c736-39e8-4323-8155-fa3cc26ac9e3 C18H36O2 CCCCCCCCCCCCCCCCCC(O)=O InChI=1S/C18H36O2/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18(19)20/h2-17H2,1H3,(H,19,20) Octadecanoic acid (1TMS) http://identifiers.org/gmd.analyte/f634c736-39e8-4323-8155-fa3cc26ac9e3 [CHEBI, CHEBI:51088, trimethylsilyl group, 1] [M+H]+ 356.6588 1 356.659 ms_run[1]:scan=8 [,, ChromaTOF database search,] [MS, MS:1000511, ms level, 1] 957 1
SME 2 ms_run[2]:scan=23 GMD:f634c736-39e8-4323-8155-fa3cc26ac9e3 C18H36O2 CCCCCCCCCCCCCCCCCC(O)=O InChI=1S/C18H36O2/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18(19)20/h2-17H2,1H3,(H,19,20) Octadecanoic acid (1TMS) http://identifiers.org/gmd.analyte/f634c736-39e8-4323-8155-fa3cc26ac9e3 [CHEBI, CHEBI:51088, trimethylsilyl group, 1] [M+H]+ 356.6589 1 356.659 ms_run[2]:scan=23 [,, ChromaTOF database search,] [MS, MS:1000511, ms level, 1] 972 1
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
# PEFF 1.0
# //
# DbName=Minimal Test example PEFF_Minimal_Valid.peff
# Prefix=sp
# DbSource=http://www.peptideatlas.org/formats/PEFF/PEFF_Minimal_Valid.peff
# DbVersion=1
# SequenceType=AA
# NumberOfEntries=1
# //
>sp:Q9Y2X3 \Length=1
M
+36
View File
@@ -0,0 +1,36 @@
m/z rt(min) snr charge intensity
706.0656 47.997 70.443 3 3709.630
740.4292 60.127 28.895 4 2153.832
708.7055 63.321 28.970 3 2377.576
728.7255 56.390 28.530 3 1820.929
721.3855 57.410 25.965 3 1332.942
740.4400 64.272 16.639 2 1024.329
707.3855 63.423 20.248 3 1495.899
735.7055 50.275 29.838 3 804.873
726.7255 63.966 13.282 3 1364.349
723.4000 57.647 13.069 2 713.563
700.4400 61.588 11.435 2 579.007
736.3400 61.113 9.765 2 464.364
705.4000 54.454 12.855 2 457.507
709.0056 57.104 12.614 3 454.622
710.3000 49.459 18.364 2 534.519
719.4000 64.714 7.860 3 447.372
742.4400 64.170 6.799 2 357.583
752.4000 55.983 7.138 2 290.348
714.1492 47.114 22.442 4 576.568
753.4256 61.486 7.788 3 318.019
730.3800 53.536 8.914 2 284.038
708.8400 58.836 6.272 2 246.319
737.0400 50.207 12.257 3 309.824
716.9200 58.123 6.188 2 283.297
729.7456 50.308 9.760 3 428.650
712.3200 49.391 8.749 2 235.981
748.9400 51.294 9.114 2 250.202
712.8800 53.672 6.466 2 160.206
714.9000 53.604 6.417 2 202.450
716.8800 54.080 6.920 2 225.521
715.7055 49.017 10.866 3 198.560
728.3600 53.299 6.913 3 156.242
753.8800 49.527 6.406 2 113.352
724.0400 47.997 6.559 3 281.194
745.9200 47.521 6.732 2 87.974
Binary file not shown.
+122
View File
@@ -0,0 +1,122 @@
PSMId score q-value posterior_error_prob peptide proteinIds
query:161610;rank:1;spectrum:1093.0258_2187.96_spectrum=40633_uteruspremenopause;rt:2187.96;mz:1093.0258;charge:2 11.0472 0 1.48741e-12 X.SLAGSSGPGASSGTSGDHGELVVR.X UniProt_E9PI39 UniProt_E9PIZ1 UniProt_E9PK01 UniProt_E9PL12 UniProt_E9PMW7 UniProt_E9PPR1 UniProt_E9PQ49 UniProt_E9PRY8 UniProt_H0YCK7 UniProt_P29692 UniProt_P29692-2 genCDS_ENST00000317198_8_143579792-143586845_-1 genCDS_ENST00000395119_8_143579792-143586845_-1 genCDS_ENST00000419152_8_143579792-143586845_-1 genCDS_ENST00000423316_8_143579792-143590081_-1 genCDS_ENST00000442189_8_143579792-143590081_-1 genCDS_ENST00000524397_8_143580630-143586845_-1 genCDS_ENST00000529007_8_143580630-143586845_-1 genCDS_ENST00000529272_8_143579792-143586845_-1 genCDS_ENST00000530191_8_143580506-143586845_-1 genCDS_ENST00000530445_8_143580620-143586845_-1 genCDS_ENST00000530616_8_143580630-143589222_-1 genCDS_ENST00000531218_8_143580522-143586845_-1 genCDS_ENST00000532741_8_143579792-143590231_-1 genCDS_ENST00000533204_8_143580506-143586845_-1 genCDS_ENST00000533494_8_143580613-143586845_-1 genCDS_ENST00000533749_8_143581079-143599321_-1 genCDS_ENST00000534380_8_143580034-143586845_-1 genCDS_ENST00000618139_8_143580019-143590081_-1
query:132093;rank:1;spectrum:832.40479_2605.29_spectrum=72602_uteruspremenopause;rt:2605.29;mz:832.40479;charge:2 9.36298 0 7.2763e-11 X.AAAFEEQENETVVVK.X UniProt_Q5TCU6 UniProt_Q9Y490 genCDS_ENST00000314888_9_35697791-35725694_-1
query:119552;rank:1;spectrum:769.39142_3320.48_spectrum=167622_uteruspremenopause;rt:3320.48;mz:769.39142;charge:2 8.72204 0 3.19783e-10 X.FALQDLSVEETSAK.X UniProt_B2RCS5 UniProt_G3V2E8 UniProt_G3V2N5 UniProt_G3V2W4 UniProt_G3V2X9 UniProt_G3V5M4 UniProt_H9KV75 UniProt_O43707 UniProt_P12814 UniProt_P12814-2 UniProt_P12814-3 UniProt_P12814-4 UniProt_P35609 UniProt_Q08043 genCDS_ENST00000193403_14_68874859-68979056_-1 genCDS_ENST00000252699_19_38647746-38729432_1 genCDS_ENST00000366578_1_236686674-236762619_1 genCDS_ENST00000376839_14_68874859-68925582_-1 genCDS_ENST00000394419_14_68874859-68979056_-1 genCDS_ENST00000438964_14_68874859-68979056_-1 genCDS_ENST00000502692_11_66546511-66563193_1 genCDS_ENST00000513398_11_66546938-66563193_1 genCDS_ENST00000538545_14_68874859-68979056_-1 genCDS_ENST00000542672_1_236686674-236762619_1 genCDS_ENST00000553370_14_68904702-68925582_-1 genCDS_ENST00000553779_14_68910020-68925582_-1 genCDS_ENST00000555616_14_68892228-68925582_-1 genCDS_ENST00000556433_14_68893665-68978258_-1 genCDS_ENST00000556571_14_68910022-68978051_-1
query:105717;rank:1;spectrum:715.89587_3127.2_spectrum=82140_uteruspremenopause;rt:3127.2;mz:715.89587;charge:2 8.58807 0 4.35755e-10 X.LDSLSAQLSQLQK.X UniProt_P02545 UniProt_P02545-2 UniProt_P02545-3 UniProt_P02545-4 UniProt_P02545-5 UniProt_P02545-6 UniProt_Q5TCI8 genCDS_ENST00000347559_1_156114919-156139106_1 genCDS_ENST00000361308_1_156114919-156137764_1 genCDS_ENST00000368297_1_156126803-156137764_1 genCDS_ENST00000368299_1_156114919-156139106_1 genCDS_ENST00000368300_1_156114919-156139106_1 genCDS_ENST00000368301_1_156114919-156137764_1 genCDS_ENST00000448611_1_156126204-156139839_1 genCDS_ENST00000473598_1_156129850-156139106_1
query:121144;rank:1;spectrum:776.86639_1943.52_spectrum=62937_uteruspremenopause;rt:1943.52;mz:776.86639;charge:2 8.31993 0 8.09508e-10 X.TSTTSSMVASAEQPR.X UniProt_E7EMN6 UniProt_E7EUI7 UniProt_P41236 UniProt_Q6NXS1 genCDS_ENST00000413183_3_195527890-195543025_-1 genCDS_ENST00000438848_3_195516925-195543025_-1 genCDS_ENST00000618156_3_195516896-195543025_-1
query:91084;rank:1;spectrum:661.3443_2685.51_spectrum=127861_uteruspremenopause;rt:2685.51;mz:661.3443;charge:2 7.84396 0 2.43037e-09 X.STSGGTAALGCLVK.X UniProt_P01857 UniProt_P01860 genCDS_ENST00000390542_14_105741473-105743071_-1 genCDS_ENST00000390548_14_105737762-105743071_-1 genCDS_ENST00000390549_14_105741473-105743071_-1 genCDS_ENST00000390551_14_105769237-105771405_-1 genCDS_ENST00000612473_14_105741473-106005532_-1 genCDS_ENST00000613152_14_105741473-106211391_-1 genCDS_ENST00000615822_14_105741473-106062604_-1 genCDS_ENST00000616127_14_105769237-106038345_-1 genCDS_ENST00000618145_14_105741473-106012356_-1 genCDS_ENST00000618756_14_105668245-106538265_-1 genCDS_ENST00000619212_14_105741473-106211391_-1 genCDS_ENST00000621473_14_105769237-106005532_-1
query:128131;rank:1;spectrum:813.40948_2244.71_spectrum=40773_uteruspremenopause;rt:2244.71;mz:813.40948;charge:2 7.38397 0 7.03248e-09 X.DALQNPNDLQLQEK.X UniProt_C9IYV6 UniProt_C9JPE5 UniProt_Q9H0Q0 genCDS_ENST00000381323_2_16552936-16588119_-1 genCDS_ENST00000406434_2_16552936-16588119_-1 genCDS_ENST00000445605_2_16564005-16588119_-1 genCDS_ENST00000451689_2_16564024-16588119_-1
query:141775;rank:1;spectrum:893.9129_2874.06_spectrum=158864_uteruspremenopause;rt:2874.06;mz:893.9129;charge:2 7.1148 0 1.30952e-08 X.NKDQGTYEDYVEGLR.X Augustus2_AUGUSTUS00000061902_12_56160654-56153919_1 UniProt_B7Z6Z4 UniProt_F8VPF3 UniProt_F8VZU9 UniProt_F8W180 UniProt_F8W1R7 UniProt_G3V1V0 UniProt_G3V1Y7 UniProt_G8JLA2 UniProt_J3KND3 UniProt_P60660 UniProt_P60660-2 genCDS_ENST00000293422_12_56158402-56161415_1 genCDS_ENST00000348108_12_56158402-56160654_1 genCDS_ENST00000536128_12_56158402-56160331_1 genCDS_ENST00000547408_12_56158402-56162322_1 genCDS_ENST00000547649_12_56158402-56161415_1 genCDS_ENST00000548293_12_56158402-56160654_1 genCDS_ENST00000548400_12_56158402-56160654_1 genCDS_ENST00000548580_12_56158402-56161415_1 genCDS_ENST00000549392_12_56158402-56160320_1 genCDS_ENST00000549566_12_56158402-56161415_1 genCDS_ENST00000550697_12_56158402-56160654_1 genCDS_ENST00000551589_12_56158402-56160331_1
query:71406;rank:1;spectrum:404.21942_2506.81_spectrum=119549_uteruspremenopause;rt:2506.81;mz:404.21942;charge:3 7.03952 0 1.55822e-08 X.TANDAVELHLK.X UniProt_Q9P2B2 genCDS_ENST00000393203_1_116910204-116986967_1
query:129027;rank:1;spectrum:817.40759_3010.12_spectrum=35161_uteruspremenopause;rt:3010.12;mz:817.40759;charge:2 7.02828 0 1.5992e-08 X.EGCTVSPETLSLNVK.X UniProt_E5KLJ5 UniProt_E5KLJ6 UniProt_E5KLJ9 UniProt_E5KLK1 UniProt_O60313 UniProt_O60313-2 genCDS_ENST00000361150_3_193593378-193692127_1 genCDS_ENST00000361510_3_193593378-193692127_1 genCDS_ENST00000361715_3_193593378-193692127_1 genCDS_ENST00000361828_3_193593378-193692127_1 genCDS_ENST00000361908_3_193593378-193692127_1 genCDS_ENST00000392438_3_193593378-193692127_1
query:79758;rank:1;spectrum:627.82471_1646.41_spectrum=69987_uteruspremenopause;rt:1646.41;mz:627.82471;charge:2 6.79995 0 2.70985e-08 X.LEPGGGAEAQAVR.X UniProt_Q14315 UniProt_Q14315-2 genCDS_ENST00000325888_7_128830638-128858523_1 genCDS_ENST00000346177_7_128830638-128858523_1
query:107233;rank:1;spectrum:721.87775_2878.99_spectrum=96857_uteruspremenopause;rt:2878.99;mz:721.87775;charge:2 6.53355 0 5.01392e-08 X.EAGAGGLSLAVEGPSK.X UniProt_E7EN95 UniProt_O75369 UniProt_O75369-2 UniProt_O75369-3 UniProt_O75369-6 UniProt_O75369-7 UniProt_O75369-8 UniProt_O75369-9 UniProt_Q14315 UniProt_Q14315-2 genCDS_ENST00000295956_3_58008565-58170762_1 genCDS_ENST00000325888_7_128830638-128858523_1 genCDS_ENST00000346177_7_128830638-128858523_1 genCDS_ENST00000358537_3_58008565-58170762_1 genCDS_ENST00000429972_3_58008565-58170762_1 genCDS_ENST00000490882_3_58008565-58170762_1 genCDS_ENST00000493452_3_58078486-58170762_1
query:146872;rank:1;spectrum:619.28918_2152.13_spectrum=141583_uteruspremenopause;rt:2152.13;mz:619.28918;charge:3 6.13383 0 1.26226e-07 X.SEETKENEGFTVTAEGK.X UniProt_M0QYC8 UniProt_P01024 genCDS_ENST00000245907_19_6677882-6720589_-1 genCDS_ENST00000596548_19_6680159-6685038_-1
query:172404;rank:1;spectrum:871.76086_2726.33_spectrum=42005_uteruspremenopause;rt:2726.33;mz:871.76086;charge:3 5.99128 0 1.75446e-07 X.SEAEEALTSFN(Deamidated)GHKPPGSSEPLTVK.X UniProt_B4DVB8 UniProt_Q15717 genCDS_ENST00000351593_19_7963483-7991815_-1 genCDS_ENST00000407627_19_7963483-7991815_-1 genCDS_ENST00000596459_19_7963483-7991815_-1
query:105836;rank:1;spectrum:716.36646_2072.32_spectrum=141400_uteruspremenopause;rt:2072.32;mz:716.36646;charge:2 5.83486 0 2.51791e-07 X.VASSPVM(Oxidation)VSNPATR.X UniProt_A6NEM2 UniProt_P51610 UniProt_P51610-2 UniProt_P51610-4 genCDS_ENST00000310441_X_153949347-153970840_-1 genCDS_ENST00000369984_X_153949347-153970840_-1
query:89905;rank:1;spectrum:657.87396_3407.52_spectrum=152816_uteruspremenopause;rt:3407.52;mz:657.87396;charge:2 5.75831 0 3.00493e-07 X.EHALLAYTLGVK.X Augustus2_AUGUSTUS00000028250_3_184026960-184027756_-1 UniProt_P68104 UniProt_Q05639 UniProt_Q5VTE0 calCuffs_CUFF.68550.1_19_35873852-35875252_1_1_ORF2 ensBodymap_RNASEQT00000006703_5_14651962-14653630_-1 ensBodymap_RNASEQT00000053260_5_14650973-14653630_-1 ensBodymap_RNASEQT00000095825_9_135894020-135896638_1 ensBodymap_RNASEQT00000213862_9_135894020-135896638_1 genCDS_ENST00000217182_20_63488298-63497763_-1 genCDS_ENST00000298049_20_63488298-63497763_-1 genCDS_ENST00000309268_6_73517810-73520026_-1 genCDS_ENST00000316292_6_73517810-73520026_-1 genCDS_ENST00000331523_6_73517810-73520026_-1 genCDS_ENST00000615060_6_73517916-73520026_-1 genpseudogene_ENST00000415278_1_96446930-96448318_1_1_ORF2 genpseudogene_ENST00000419025_3_184026369-184027756_-1_2_ORF4 genpseudogene_ENST00000436459_9_133019486-133020874_1_1_ORF1 genpseudogene_ENST00000514975_4_105484698-105486080_1_1_ORF1 genpseudogene_ENST00000596811_19_35382172-35384052_1_1_ORF5 yalePseudo_PGOHUM00000234671_19_35873074-35874951_1_2_ORF13 yalePseudo_PGOHUM00000237893_3_183744160-183745544_-1_2_ORF4 yalePseudo_PGOHUM00000244804_1_96912486-96913871_1_1_ORF2 yalePseudo_PGOHUM00000246017_4_106405855-106407234_1_1_ORF1
query:120224;rank:1;spectrum:772.3432_1845.25_spectrum=39781_uteruspremenopause;rt:1845.25;mz:772.3432;charge:2 5.59137 0 4.41859e-07 X.FYEQM(Oxidation)N(Deamidated)GPVAGASR.X UniProt_E9PI39 UniProt_E9PIZ1 UniProt_E9PK01 UniProt_E9PK06 UniProt_E9PK72 UniProt_E9PKK3 UniProt_E9PL12 UniProt_E9PL71 UniProt_E9PMW7 UniProt_E9PN91 UniProt_E9PPR1 UniProt_E9PQ49 UniProt_E9PQZ1 UniProt_E9PRY8 UniProt_H0YCK7 UniProt_P29692 UniProt_P29692-2 UniProt_P29692-3 UniProt_P29692-4 genCDS_ENST00000317198_8_143579792-143586845_-1 genCDS_ENST00000395119_8_143579792-143586845_-1 genCDS_ENST00000419152_8_143579792-143586845_-1 genCDS_ENST00000423316_8_143579792-143590081_-1 genCDS_ENST00000442189_8_143579792-143590081_-1 genCDS_ENST00000524397_8_143580630-143586845_-1 genCDS_ENST00000524624_8_143579792-143586845_-1 genCDS_ENST00000525223_8_143586729-143586845_-1 genCDS_ENST00000526340_8_143586219-143586845_-1 genCDS_ENST00000526838_8_143579792-143586845_-1 genCDS_ENST00000528610_8_143579792-143586845_-1 genCDS_ENST00000529007_8_143580630-143586845_-1 genCDS_ENST00000529272_8_143579792-143586845_-1 genCDS_ENST00000529516_8_143580642-143586845_-1 genCDS_ENST00000530191_8_143580506-143586845_-1 genCDS_ENST00000530445_8_143580620-143586845_-1 genCDS_ENST00000530616_8_143580630-143589222_-1 genCDS_ENST00000531218_8_143580522-143586845_-1 genCDS_ENST00000531621_8_143579792-143586845_-1 genCDS_ENST00000532543_8_143586729-143586845_-1 genCDS_ENST00000532741_8_143579792-143590231_-1 genCDS_ENST00000533204_8_143580506-143586845_-1 genCDS_ENST00000533494_8_143580613-143586845_-1 genCDS_ENST00000533749_8_143581079-143599321_-1 genCDS_ENST00000533833_8_143580630-143586845_-1 genCDS_ENST00000534377_8_143580186-143586845_-1 genCDS_ENST00000534380_8_143580034-143586845_-1 genCDS_ENST00000618139_8_143580019-143590081_-1 genpseudogene_ENST00000433698_9_92836826-92837668_-1_1_ORF1 yalePseudo_PGOHUM00000236264_9_95599111-95599989_-1_1_ORF1
query:83950;rank:1;spectrum:640.32916_1950.76_spectrum=62954_uteruspremenopause;rt:1950.76;mz:640.32916;charge:2 5.43278 0 6.3732e-07 X.YLAEVAAGDDKK.X UniProt_B0AZS6 UniProt_B7Z2E6 UniProt_E7EX29 UniProt_H0YB80 UniProt_P63104 UniProt_P63104-2 genCDS_ENST00000353245_8_100920693-100948889_-1 genCDS_ENST00000395948_8_100920693-100948658_-1 genCDS_ENST00000395951_8_100920693-100948889_-1 genCDS_ENST00000395953_8_100920693-100948889_-1 genCDS_ENST00000395956_8_100920693-100948889_-1 genCDS_ENST00000395957_8_100920693-100948889_-1 genCDS_ENST00000395958_8_100920693-100948889_-1 genCDS_ENST00000419477_8_100920693-100948889_-1 genCDS_ENST00000457309_8_100920693-100948889_-1 genCDS_ENST00000521309_8_100920693-100924973_-1 genCDS_ENST00000521607_8_100920716-100948889_-1 genCDS_ENST00000522542_8_100920693-100948145_-1 genCDS_ENST00000522819_8_100920693-100924973_-1 genCDS_ENST00000523848_8_100920693-100924988_-1 genpseudogene_ENST00000415292_10_23136924-23137661_1_1_ORF1
query:70327;rank:1;spectrum:602.85034_3098.02_spectrum=159460_uteruspremenopause;rt:3098.02;mz:602.85034;charge:2 5.3382 0 7.92901e-07 X.TLMALGSLAVTK.X UniProt_H0YCU9 UniProt_Q01995 genCDS_ENST00000278968_11_117203014-117204359_1 genCDS_ENST00000392951_11_117203014-117204359_1 genCDS_ENST00000525531_11_117203014-117204359_1 genCDS_ENST00000529622_11_117203144-117204359_1 genCDS_ENST00000530649_11_117203014-117204359_1 genCDS_ENST00000532870_11_117203014-117204359_1
query:161278;rank:1;spectrum:725.35535_3439.5_spectrum=82985_uteruspremenopause;rt:3439.5;mz:725.35535;charge:3 5.26056 0 9.48615e-07 X.LEWLESHQDADLEDFKAK.X UniProt_P11021 genCDS_ENST00000324460_9_125236592-125241126_-1
query:61382;rank:1;spectrum:578.83197_2603.98_spectrum=142644_uteruspremenopause;rt:2603.98;mz:578.83197;charge:2 5.23568 0 1.00471e-06 X.VKGDVDVSLPK.X UniProt_Q09666 genCDS_ENST00000378024_11_62516744-62536098_-1
query:121082;rank:1;spectrum:776.46204_3500.05_spectrum=153073_uteruspremenopause;rt:3500.05;mz:776.46204;charge:2 4.84174 0 2.49494e-06 X.LVQVALNGLENLLR.X UniProt_F5GYL8 UniProt_F5H4G7 UniProt_H0Y3K0 UniProt_O15131 UniProt_O60684 UniProt_P52294 genCDS_ENST00000344337_3_122426985-122496565_-1 genCDS_ENST00000356348_6_116681335-116732323_1 genCDS_ENST00000368564_6_116681335-116732323_1 genCDS_ENST00000373625_1_32108131-32170894_1 genCDS_ENST00000392517_6_116729563-116732323_1
query:93986;rank:1;spectrum:671.32318_2044.34_spectrum=17669_uteruspremenopause;rt:2044.34;mz:671.32318;charge:2 4.67543 0 3.66237e-06 X.YELEETETVTK.X UniProt_C9J813 UniProt_E7EX44 UniProt_E9PGZ1 UniProt_F5H1Z9 UniProt_Q05682 UniProt_Q05682-2 UniProt_Q05682-3 UniProt_Q05682-4 UniProt_Q05682-5 UniProt_Q05682-6 genCDS_ENST00000361675_7_134867734-134968345_1 genCDS_ENST00000361901_7_134867734-134968345_1 genCDS_ENST00000393118_7_134891621-134968345_1 genCDS_ENST00000417172_7_134867734-134968345_1 genCDS_ENST00000422748_7_134867734-134968345_1 genCDS_ENST00000424922_7_134891621-134968345_1 genCDS_ENST00000436461_7_134867734-134960056_1 genCDS_ENST00000443197_7_134891621-134962918_1 genCDS_ENST00000495522_7_134891621-134968345_1
query:108382;rank:1;spectrum:363.20432_2784.99_spectrum=158641_uteruspremenopause;rt:2784.99;mz:363.20432;charge:4 4.56709 0 4.70247e-06 X.VVAGVANALAHKYH.X UniProt_P02042 UniProt_P68871 genCDS_ENST00000335295_11_5225598-5227021_-1 genCDS_ENST00000380299_11_5232964-5234433_-1
query:102060;rank:1;spectrum:701.8067_912.458_spectrum=14837_uteruspremenopause;rt:912.458;mz:701.8067;charge:2 4.56217 0 4.75611e-06 X.SDESDQQESLHK.X UniProt_G3V5E5 UniProt_H0YJJ8 UniProt_P49770 genCDS_ENST00000266126_14_75002991-75009188_1 genCDS_ENST00000553401_14_75003018-75005873_1 genCDS_ENST00000556028_14_75002991-75005920_1
query:41841;rank:1;spectrum:522.80469_1137.9_spectrum=15355_uteruspremenopause;rt:1137.9;mz:522.80469;charge:2 4.55643 0 4.8195e-06 X.TSTGAPAALKK.X UniProt_B8ZZL6 UniProt_E7ENU9 UniProt_P40121 UniProt_P40121-2 genCDS_ENST00000263867_2_85394893-85402145_-1 genCDS_ENST00000409275_2_85399146-85402145_-1 genCDS_ENST00000409670_2_85394893-85402145_-1 genCDS_ENST00000409724_2_85394893-85402145_-1 genCDS_ENST00000409921_2_85394893-85402145_-1 genCDS_ENST00000439385_2_85398690-85402145_-1 genCDS_ENST00000447219_2_85398690-85402145_-1 genCDS_ENST00000449030_2_85398690-85402145_-1
query:67749;rank:1;spectrum:596.77612_2303.32_spectrum=10843_uteruspremenopause;rt:2303.32;mz:596.77612;charge:2 4.29846 0 8.73504e-06 X.(Acetyl)EAESSPFVER.X UniProt_P14625 genCDS_ENST00000299767_12_103930516-103947662_1
query:113387;rank:1;spectrum:745.88556_2835.91_spectrum=65124_uteruspremenopause;rt:2835.91;mz:745.88556;charge:2 4.24758 0 9.82097e-06 X.NQYVTLHDM(Oxidation)LLK.X UniProt_B3KQ25 UniProt_K7ESG5 UniProt_P61289 UniProt_P61289-2 genCDS_ENST00000293362_17_42833632-42841578_1 genCDS_ENST00000441946_17_42834182-42841578_1 genCDS_ENST00000541124_17_42833632-42841578_1 genCDS_ENST00000545225_17_42834817-42841578_1 genCDS_ENST00000590720_17_42833632-42841578_1 genCDS_ENST00000592169_17_42833632-42841578_1 genCDS_ENST00000622892_17_42833632-42841578_1
query:125401;rank:1;spectrum:532.63049_2532.44_spectrum=80569_uteruspremenopause;rt:2532.44;mz:532.63049;charge:3 4.23343 0 1.01462e-05 X.GLHQSTLDLKNELK.X UniProt_Q14258 genCDS_ENST00000316881_17_56891700-56913988_-1 genCDS_ENST00000537230_17_56891700-56913988_-1
query:164495;rank:1;spectrum:1143.5902_3304.6_spectrum=121470_uteruspremenopause;rt:3304.6;mz:1143.5902;charge:2 4.20795 0 1.07591e-05 X.YTPVQQGPVGVNVTYGGDPLPK.X UniProt_P21333 UniProt_P21333-2 UniProt_Q5HY54 genCDS_ENST00000344736_X_154348849-154371245_-1 genCDS_ENST00000360319_X_154348849-154371245_-1 genCDS_ENST00000369850_X_154348849-154371245_-1 genCDS_ENST00000369856_X_154348849-154371164_-1 genCDS_ENST00000422373_X_154348849-154371245_-1 genCDS_ENST00000610817_X_154348849-154371164_-1
query:139545;rank:1;spectrum:586.2818_2698.67_spectrum=72867_uteruspremenopause;rt:2698.67;mz:586.2818;charge:3 3.86858 0 2.34555e-05 X.SPFEVYVDKSQGDASK.X UniProt_F8WE98 UniProt_P21333 UniProt_P21333-2 UniProt_Q5HY54 genCDS_ENST00000344736_X_154348849-154371245_-1 genCDS_ENST00000360319_X_154348849-154371245_-1 genCDS_ENST00000369850_X_154348849-154371245_-1 genCDS_ENST00000369856_X_154348849-154371164_-1 genCDS_ENST00000420627_X_154364689-154371203_-1 genCDS_ENST00000422373_X_154348849-154371245_-1 genCDS_ENST00000610817_X_154348849-154371164_-1
query:20233;rank:1;spectrum:453.24112_1930.62_spectrum=171610_uteruspremenopause;rt:1930.62;mz:453.24112;charge:2 3.73764 0 3.16384e-05 X.ATDVMLAGK.X UniProt_P23526 UniProt_P23526-2 genCDS_ENST00000217426_20_34281034-34303270_-1 genCDS_ENST00000538132_20_34281034-34295529_-1
query:81528;rank:1;spectrum:422.55518_3442.78_spectrum=98225_uteruspremenopause;rt:3442.78;mz:422.55518;charge:3 3.73141 0 3.20907e-05 X.TEFSLLHYAGK.X UniProt_P35749 UniProt_P35749-2 UniProt_P35749-3 UniProt_P35749-4 genCDS_ENST00000300036_16_15703991-15838252_-1 genCDS_ENST00000396324_16_15703991-15838252_-1 genCDS_ENST00000452625_16_15708811-15838252_-1 genCDS_ENST00000576790_16_15708811-15838252_-1 genCDS_ENST00000611087_16_15703879-15838252_-1 genCDS_ENST00000616439_16_15703879-15838252_-1
query:116580;rank:1;spectrum:505.94232_2944.82_spectrum=120611_uteruspremenopause;rt:2944.82;mz:505.94232;charge:3 3.69185 0 3.51185e-05 X.TLRDLEVVEGSAAR.X UniProt_Q15746 UniProt_Q15746-10 UniProt_Q15746-11 UniProt_Q15746-2 UniProt_Q15746-3 UniProt_Q15746-4 UniProt_Q15746-5 UniProt_Q15746-6 UniProt_Q15746-7 UniProt_Q15746-8 UniProt_Q15746-9 genCDS_ENST00000346322_3_123614105-123793841_-1 genCDS_ENST00000354792_3_123614105-123793841_-1 genCDS_ENST00000359169_3_123614105-123793841_-1 genCDS_ENST00000360304_3_123614105-123793841_-1 genCDS_ENST00000360772_3_123614105-123793841_-1 genCDS_ENST00000418370_3_123614105-123620294_-1 genCDS_ENST00000475616_3_123614105-123793841_-1 genCDS_ENST00000578202_3_123614105-123620294_-1 genCDS_ENST00000583087_3_123614105-123620294_-1
query:68430;rank:1;spectrum:598.2746_1630.22_spectrum=54409_uteruspremenopause;rt:1630.22;mz:598.2746;charge:2 3.62415 0 4.09639e-05 X.WCALSHHER.X UniProt_J3KN47 UniProt_P02787 genCDS_ENST00000402696_3_133746441-133778620_1
query:74880;rank:1;spectrum:614.34271_3247.74_spectrum=43355_uteruspremenopause;rt:3247.74;mz:614.34271;charge:2 3.44948 0 6.07926e-05 X.EVM(Oxidation)LLLTGAHK.X UniProt_B7Z3X4 UniProt_D6R9P4 UniProt_D6RFF8 UniProt_E7EVU7 UniProt_P46926 UniProt_Q8TDQ7 UniProt_Q8TDQ7-2 UniProt_Q8TDQ7-3 UniProt_Q8TDQ7-4 UniProt_Q8TDQ7-5 UniProt_V9GYK3 genCDS_ENST00000295448_4_44703081-44722207_-1 genCDS_ENST00000311337_5_142002029-142012035_-1 genCDS_ENST00000500692_5_142002029-142012035_-1 genCDS_ENST00000503794_5_142002029-142012035_-1 genCDS_ENST00000505689_5_142002090-142012035_-1 genCDS_ENST00000507534_4_44703081-44718324_-1 genCDS_ENST00000507917_4_44703081-44722207_-1 genCDS_ENST00000508177_5_142002029-142012035_-1 genCDS_ENST00000509756_4_44707741-44722207_-1 genCDS_ENST00000513454_5_141991865-142012035_-1 genCDS_ENST00000609092_4_44682339-44711023_-1
query:28620;rank:1;spectrum:480.78506_3493.94_spectrum=83136_uteruspremenopause;rt:3493.94;mz:480.78506;charge:2 3.4276 0 6.3855e-05 X.FQNALLVR.X CON_P02768-1 UniProt_B7WNR0 UniProt_C9JKR2 UniProt_D6RHD5 UniProt_H0YA55 UniProt_P02768 UniProt_P02768-2 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000401494_4_73404328-73420298_1 genCDS_ENST00000415165_4_73404328-73420298_1 genCDS_ENST00000503124_4_73406730-73420298_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000511370_4_73409340-73420298_1 genCDS_ENST00000621085_4_73404328-73420298_1 genCDS_ENST00000621628_4_73404328-73420298_1
query:103766;rank:1;spectrum:473.23645_1715.59_spectrum=163581_uteruspremenopause;rt:1715.59;mz:473.23645;charge:3 3.41086 0 6.62984e-05 X.DLSTNYYASQKK.X UniProt_H0YIV0 UniProt_P14625 genCDS_ENST00000299767_12_103930516-103947662_1 genCDS_ENST00000550595_12_103943796-103953394_1
query:150850;rank:1;spectrum:961.95966_2525.59_spectrum=88300_uteruspremenopause;rt:2525.59;mz:961.95966;charge:2 3.3544 0 7.52191e-05 X.DLQM(Oxidation)TQSPSSLSVSVGDR.X UniProt_P01605
query:42641;rank:1;spectrum:525.26251_2586.03_spectrum=158158_uteruspremenopause;rt:2586.03;mz:525.26251;charge:2 3.24482 0 9.5912e-05 X.HTNFVEFR.X UniProt_M0QYZ2 UniProt_M0QZ21 UniProt_M0R0N4 UniProt_P53680 genCDS_ENST00000263270_19_46838447-46850766_-1 genCDS_ENST00000597020_19_46838447-46846085_-1 genCDS_ENST00000599990_19_46838447-46850664_-1 genCDS_ENST00000601498_19_46838447-46850184_-1
query:81555;rank:1;spectrum:633.38092_3300.56_spectrum=13202_uteruspremenopause;rt:3300.56;mz:633.38092;charge:2 3.13577 0 0.000121753 X.VVLAPQDVVVAR.X UniProt_Q13308 UniProt_Q13308-2 UniProt_Q13308-3 UniProt_Q13308-4 UniProt_Q13308-5 UniProt_Q13308-6 UniProt_Q86X91 genCDS_ENST00000230418_6_43076489-43146661_1 genCDS_ENST00000230419_6_43076489-43160881_1 genCDS_ENST00000345201_6_43076489-43160881_1 genCDS_ENST00000349241_6_43076489-43160881_1 genCDS_ENST00000352931_6_43076489-43160881_1 genCDS_ENST00000471863_6_43076489-43132839_1 genCDS_ENST00000481273_6_43076884-43160881_1
query:155440;rank:1;spectrum:673.72321_3106.63_spectrum=143874_uteruspremenopause;rt:3106.63;mz:673.72321;charge:3 3.10231 2.28599e-05 0.00013089 X.LKPEDLTQLQPQQLVLR.X UniProt_C9JPK5 UniProt_E7EQW5 UniProt_E7ERX5 UniProt_E7EUI6 UniProt_E9PLR6 UniProt_P05556 UniProt_P05556-2 UniProt_P05556-3 UniProt_P05556-4 UniProt_P05556-5 UniProt_Q5T3E6 genCDS_ENST00000302278_10_32901570-32935558_-1 genCDS_ENST00000396033_10_32901570-32935558_-1 genCDS_ENST00000423113_10_32907069-32935558_-1 genCDS_ENST00000437302_10_32928232-32935558_-1 genCDS_ENST00000474568_10_32928174-32930026_-1 genCDS_ENST00000475184_10_32929824-32935558_-1 genCDS_ENST00000480226_10_32928150-32935558_-1 genCDS_ENST00000488494_10_32928193-32935558_-1 genCDS_ENST00000534049_10_32928212-32935558_-1
query:23764;rank:1;spectrum:465.2739_1931.52_spectrum=118184_uteruspremenopause;rt:1931.52;mz:465.2739;charge:2 2.96175 4.11168e-05 0.000176679 X.QVNLTVQK.X UniProt_H3BPZ1 UniProt_H3BS72 UniProt_Q9P035 genCDS_ENST00000261875_15_65530632-65576379_1 genCDS_ENST00000565299_15_65530632-65576379_1 genCDS_ENST00000568793_15_65530632-65576379_1
query:113164;rank:1;spectrum:744.89307_1335.79_spectrum=53683_uteruspremenopause;rt:1335.79;mz:744.89307;charge:2 2.94029 4.11168e-05 0.000184873 X.RKPDTLEVQQM(Oxidation)K.X Augustus2_AUGUSTUS00000009543_5_25910749-25909503_1 UniProt_E7EQR4 UniProt_P15311 UniProt_P26038 UniProt_P35241 UniProt_P35241-4 UniProt_P35241-5 ensBodymap_RNASEQT00000007907_5_25909357-26027537_1 ensBodymap_RNASEQT00000020282_5_25909357-26027537_1 ensBodymap_RNASEQT00000153980_5_25909357-25913455_1 genCDS_ENST00000337147_6_158766914-158818093_-1 genCDS_ENST00000343115_11_110231869-110279692_-1 genCDS_ENST00000360270_X_65667842-65739893_1 genCDS_ENST00000367075_6_158766914-158818093_-1 genCDS_ENST00000392177_6_158766914-158789474_-1 genCDS_ENST00000405097_11_110199612-110279692_-1 genCDS_ENST00000528498_11_110199612-110279692_-1 genCDS_ENST00000530749_11_110199612-110279692_-1 genCDS_ENST00000544551_11_110231869-110272594_-1 genpseudogene_ENST00000367074_X_27517884-27519759_1_3_ORF10 genpseudogene_ENST00000511640_5_25909503-25911234_1_3_ORF3 yalePseudo_PGOHUM00000235534_5_25909612-25911337_1_3_ORF3
query:88804;rank:1;spectrum:655.29285_1964.03_spectrum=141151_uteruspremenopause;rt:1964.03;mz:655.29285;charge:2 2.93857 4.11168e-05 0.000185547 X.EVEVEVESM(Oxidation)DK.X UniProt_Q7KZF4 genCDS_ENST00000354725_7_127652374-128092058_1
query:86060;rank:1;spectrum:646.33569_2494.06_spectrum=33876_uteruspremenopause;rt:2494.06;mz:646.33569;charge:2 2.87421 4.11168e-05 0.000212455 X.AQSLEPYGTGLR.X UniProt_K7ERU2 UniProt_Q63ZY3 UniProt_Q63ZY3-2 UniProt_Q63ZY3-3 genCDS_ENST00000586659_19_11166558-11194511_-1 genCDS_ENST00000589359_19_11166558-11194511_-1 genCDS_ENST00000589894_19_11169853-11194511_-1 genCDS_ENST00000592675_19_11192881-11193248_-1
query:90688;rank:1;spectrum:660.26282_1490.8_spectrum=109667_uteruspremenopause;rt:1490.8;mz:660.26282;charge:2 2.87129 4.11168e-05 0.000213763 X.YTM(Oxidation)GDAPDYDR.X UniProt_B9ZVX7 UniProt_E7EWW9 UniProt_E9PHN6 UniProt_E9PHN7 UniProt_E9PLF1 UniProt_F6XZQ7 UniProt_H3BQT3 UniProt_P09488 UniProt_P09488-2 UniProt_P28161 UniProt_P28161-2 UniProt_Q03013 UniProt_Q03013-2 UniProt_Q03013-3 genCDS_ENST00000241337_1_109668116-109674836_1 genCDS_ENST00000309851_1_109687874-109693295_1 genCDS_ENST00000326729_1_109656390-109665031_1 genCDS_ENST00000336075_1_109656390-109674836_1 genCDS_ENST00000349334_1_109687874-109693295_1 genCDS_ENST00000369819_1_109687874-109693295_1 genCDS_ENST00000369823_1_109687874-109693295_1 genCDS_ENST00000369827_1_109668116-109674836_1 genCDS_ENST00000369829_1_109668116-109673217_1 genCDS_ENST00000369831_1_109668116-109708576_1 genCDS_ENST00000369836_1_109656390-109661254_1 genCDS_ENST00000442650_1_109668116-109681817_1 genCDS_ENST00000460717_1_109668116-109681817_1 genCDS_ENST00000467579_1_109668116-109671486_1 genCDS_ENST00000483399_1_109687874-109689305_1
query:127987;rank:1;spectrum:813.32916_1266.09_spectrum=69023_uteruspremenopause;rt:1266.09;mz:813.32916;charge:2 2.77394 5.68587e-05 0.000262028 X.LECDDKGDGSCDVR.X UniProt_P21333 UniProt_P21333-2 UniProt_Q14315 UniProt_Q14315-2 UniProt_Q5HY54 genCDS_ENST00000325888_7_128830638-128858523_1 genCDS_ENST00000344736_X_154348849-154371245_-1 genCDS_ENST00000346177_7_128830638-128858523_1 genCDS_ENST00000360319_X_154348849-154371245_-1 genCDS_ENST00000369850_X_154348849-154371245_-1 genCDS_ENST00000369856_X_154348849-154371164_-1 genCDS_ENST00000422373_X_154348849-154371245_-1 genCDS_ENST00000610817_X_154348849-154371164_-1
query:154012;rank:1;spectrum:663.6684_2273.32_spectrum=79890_uteruspremenopause;rt:2273.32;mz:663.6684;charge:3 2.74607 5.68587e-05 0.000277701 X.VNPFRPGDSEPPPAPGAQR.X UniProt_C9IZ41 UniProt_H0Y2Y8 UniProt_Q15942 genCDS_ENST00000322764_7_143381572-143390682_1 genCDS_ENST00000354434_7_143381575-143390682_1 genCDS_ENST00000457235_7_143381572-143382676_1
query:136470;rank:1;spectrum:572.59875_1543.09_spectrum=101367_uteruspremenopause;rt:1543.09;mz:572.59875;charge:3 2.67373 5.68587e-05 0.000322851 X.QEPERN(Deamidated)ECFLQHK.X CON_P02768-1 UniProt_H7C013 UniProt_P02768 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000441319_4_73397114-73409457_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000621085_4_73404328-73420298_1 genCDS_ENST00000621628_4_73404328-73420298_1
query:106081;rank:1;spectrum:717.35742_2615.44_spectrum=165819_uteruspremenopause;rt:2615.44;mz:717.35742;charge:2 2.64505 5.68587e-05 0.00034272 X.AYGPGLEPTGNMVK.X UniProt_F8WE98 UniProt_P21333 UniProt_P21333-2 UniProt_Q5HY54 genCDS_ENST00000344736_X_154348849-154371245_-1 genCDS_ENST00000360319_X_154348849-154371245_-1 genCDS_ENST00000369850_X_154348849-154371245_-1 genCDS_ENST00000369856_X_154348849-154371164_-1 genCDS_ENST00000420627_X_154364689-154371203_-1 genCDS_ENST00000422373_X_154348849-154371245_-1 genCDS_ENST00000610817_X_154348849-154371164_-1
query:135079;rank:1;spectrum:425.48462_2830.36_spectrum=96739_uteruspremenopause;rt:2830.36;mz:425.48462;charge:4 2.64252 5.68587e-05 0.000344529 X.TGVELGKPTHFTVNAK.X UniProt_P21333 UniProt_P21333-2 UniProt_Q5HY54 genCDS_ENST00000344736_X_154348849-154371245_-1 genCDS_ENST00000360319_X_154348849-154371245_-1 genCDS_ENST00000369850_X_154348849-154371245_-1 genCDS_ENST00000369856_X_154348849-154371164_-1 genCDS_ENST00000422373_X_154348849-154371245_-1 genCDS_ENST00000610817_X_154348849-154371164_-1
query:133212;rank:1;spectrum:558.92828_2461.58_spectrum=18781_uteruspremenopause;rt:2461.58;mz:558.92828;charge:3 2.52804 6.99035e-05 0.000437424 X.LSPQFPNEEDSFHK.X UniProt_P49770 genCDS_ENST00000266126_14_75002991-75009188_1
query:139472;rank:1;spectrum:585.95319_3414.38_spectrum=137257_uteruspremenopause;rt:3414.38;mz:585.95319;charge:3 2.48232 6.99035e-05 0.000481293 X.VFDKDGN(Deamidated)GYLSAAELR.X UniProt_E7EMB3 UniProt_E7ETZ0 UniProt_G3V361 UniProt_H0Y7A7 UniProt_P62158 UniProt_Q96HY3 genCDS_ENST00000272298_2_47160776-47176443_-1 genCDS_ENST00000291295_19_46601435-46609153_1 genCDS_ENST00000356978_14_90397231-90404717_1 genCDS_ENST00000391918_19_46608271-46609153_1 genCDS_ENST00000409563_2_47160776-47167650_-1 genCDS_ENST00000447653_14_90399082-90404717_1 genCDS_ENST00000456319_2_47160776-47176511_-1 genCDS_ENST00000544280_14_90401333-90404717_1 genCDS_ENST00000553542_14_90401333-90404717_1 genCDS_ENST00000557020_14_90401333-90404496_1 genCDS_ENST00000594523_19_46608271-46609153_1 genCDS_ENST00000596362_19_46602208-46609153_1 genCDS_ENST00000598871_19_46608271-46609153_1 genCDS_ENST00000599839_19_46608271-46609153_1
query:75760;rank:1;spectrum:411.56995_2371.79_spectrum=149868_uteruspremenopause;rt:2371.79;mz:411.56995;charge:3 2.46586 6.99035e-05 0.000498166 X.SNFKPSLLAQK.X UniProt_C9JJ47 UniProt_E9PFW3 UniProt_Q96CW1 UniProt_Q96CW1-2 genCDS_ENST00000292807_3_184176994-184183616_1 genCDS_ENST00000382456_3_184176994-184183616_1 genCDS_ENST00000411763_3_184176994-184183616_1 genCDS_ENST00000432591_3_184176994-184182054_1 genCDS_ENST00000439647_3_184176994-184183616_1 genCDS_ENST00000621863_3_184176994-184183616_1
query:13577;rank:1;spectrum:430.2381_2030.02_spectrum=133876_uteruspremenopause;rt:2030.02;mz:430.2381;charge:2 2.43497 6.99035e-05 0.000531473 X.LQLPNM(Oxidation)K.X UniProt_G3V281 UniProt_G3V5R2 UniProt_H0YJ34 UniProt_Q96AC1 UniProt_Q96AC1-2 UniProt_Q96AC1-3 genCDS_ENST00000341590_14_52858377-52950568_-1 genCDS_ENST00000343279_14_52858377-52950568_-1 genCDS_ENST00000395631_14_52858377-52950568_-1 genCDS_ENST00000399304_14_52859561-52950568_-1 genCDS_ENST00000553373_14_52858377-52950568_-1 genCDS_ENST00000554152_14_52858377-52919339_-1 genCDS_ENST00000554712_14_52893359-52950568_-1 genCDS_ENST00000555692_14_52893288-52928044_-1
query:23073;rank:1;spectrum:463.27121_2707.23_spectrum=57220_uteruspremenopause;rt:2707.23;mz:463.27121;charge:2 2.37455 6.99035e-05 0.000603366 X.VPSGLPDLK.X UniProt_P21810 genCDS_ENST00000331595_X_153504632-153508445_1
query:35867;rank:1;spectrum:503.7821_2660.72_spectrum=19332_uteruspremenopause;rt:2660.72;mz:503.7821;charge:2 2.36667 6.99035e-05 0.000613454 X.LVLEYVDR.X UniProt_E7ETH0 UniProt_G3XAM2 UniProt_P05156 genCDS_ENST00000394634_4_109740893-109801971_-1 genCDS_ENST00000394635_4_109740893-109801971_-1 genCDS_ENST00000512148_4_109740893-109801971_-1
query:776;rank:1;spectrum:365.2341_2550.23_spectrum=11418_uteruspremenopause;rt:2550.23;mz:365.2341;charge:2 2.30486 8.72312e-05 0.000698664 X.ATVGLLR.X UniProt_B4DGU4 UniProt_P35222 calCuffs_CUFF.144442.10_7_134101990-134117256_-1_3_ORF25 calCuffs_CUFF.144442.11_7_134101990-134117266_-1_2_ORF13 calCuffs_CUFF.144442.12_7_134101990-134117277_-1_1_ORF18 calCuffs_CUFF.144442.13_7_134101990-134117277_-1_2_ORF23 calCuffs_CUFF.144442.9_7_134101990-134117207_-1_1_ORF15 genCDS_ENST00000349496_3_41224069-41239342_1 genCDS_ENST00000396183_3_41224069-41239342_1 genCDS_ENST00000396185_3_41224069-41239342_1 genCDS_ENST00000405570_3_41224069-41239342_1 genCDS_ENST00000453024_3_41224534-41239342_1
query:18439;rank:1;spectrum:447.25858_2796.88_spectrum=73148_uteruspremenopause;rt:2796.88;mz:447.25858;charge:2 2.29139 0.000102579 0.000718741 X.TLLFSGQK.X UniProt_Q07954 genCDS_ENST00000243077_12_57128965-57212555_1
query:16494;rank:1;spectrum:440.72366_1790.49_spectrum=86445_uteruspremenopause;rt:1790.49;mz:440.72366;charge:2 2.26159 0.000102579 0.00076526 X.AEFAEVSK.X CON_P02768-1 UniProt_B7WNR0 UniProt_C9JKR2 UniProt_D6RHD5 UniProt_H0YA55 UniProt_P02768 UniProt_P02768-2 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000401494_4_73404328-73420298_1 genCDS_ENST00000415165_4_73404328-73420298_1 genCDS_ENST00000503124_4_73406730-73420298_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000511370_4_73409340-73420298_1
query:146021;rank:1;spectrum:614.65961_2560.2_spectrum=34039_uteruspremenopause;rt:2560.2;mz:614.65961;charge:3 2.19403 0.000116791 0.00088215 X.HVVPAQVHVN(Deamidated)GGALASER.X UniProt_E7ERH1 UniProt_E9PF55 UniProt_E9PGF5 UniProt_Q9HBL0 genCDS_ENST00000171887_2_217804459-217897965_-1 genCDS_ENST00000419504_2_217804459-217897965_-1 genCDS_ENST00000430930_2_217804459-217897965_-1 genCDS_ENST00000446903_2_217848176-218002872_-1 genCDS_ENST00000611415_2_217804459-217897965_-1 genCDS_ENST00000615025_2_217804459-217880904_-1
query:40708;rank:1;spectrum:519.25708_2498.24_spectrum=127342_uteruspremenopause;rt:2498.24;mz:519.25708;charge:2 2.15281 0.000132074 0.00096205 X.(Acetyl)VNFAM(Oxidation)NVGK.X UniProt_P14618 UniProt_P14618-2 UniProt_P14618-3 UniProt_Q504U3 genCDS_ENST00000319622_15_72199650-72219097_-1 genCDS_ENST00000335181_15_72199650-72219097_-1 genCDS_ENST00000389093_15_72199650-72219097_-1 genCDS_ENST00000449901_15_72199650-72221201_-1 genCDS_ENST00000565154_15_72199650-72219097_-1 genCDS_ENST00000565184_15_72199650-72219097_-1 genCDS_ENST00000568459_15_72199650-72219097_-1 genCDS_ENST00000568883_15_72199650-72219097_-1
query:101279;rank:1;spectrum:465.91821_2796_spectrum=73145_uteruspremenopause;rt:2796;mz:465.91821;charge:3 2.15095 0.000132074 0.000965824 X.VEHGSVALPALM(Oxidation)R.X UniProt_Q5TCU6 UniProt_Q9Y490 genCDS_ENST00000314888_9_35697791-35725694_-1
query:65246;rank:1;spectrum:589.34381_3432.2_spectrum=182979_uteruspremenopause;rt:3432.2;mz:589.34381;charge:2 2.1457 0.000132074 0.00097655 X.EKGDYLLLVK.X UniProt_Q14315 UniProt_Q14315-2 genCDS_ENST00000325888_7_128830638-128858523_1 genCDS_ENST00000346177_7_128830638-128858523_1
query:111686;rank:1;spectrum:492.8963_1268.73_spectrum=15674_uteruspremenopause;rt:1268.73;mz:492.8963;charge:3 2.14508 0.000132074 0.00097782 X.LEEAEKAADESER.X Augustus2_AUGUSTUS00000096365_2_230573165-230575961_-1 CON_Q3SX28 UniProt_B7Z596 UniProt_D6R904 UniProt_F5H7S3 UniProt_H0YK48 UniProt_H0YKP3 UniProt_H0YKX5 UniProt_H0YL52 UniProt_H0YL80 UniProt_H0YNC7 UniProt_H7BYY1 UniProt_J3KN67 UniProt_K7ENT6 UniProt_K7EP68 UniProt_K7ERG3 UniProt_P06753 UniProt_P06753-2 UniProt_P06753-3 UniProt_P06753-4 UniProt_P06753-5 UniProt_P07951 UniProt_P07951-2 UniProt_P07951-3 UniProt_P09493 UniProt_P09493-10 UniProt_P09493-2 UniProt_P09493-3 UniProt_P09493-4 UniProt_P09493-5 UniProt_P09493-6 UniProt_P09493-7 UniProt_P09493-8 UniProt_P09493-9 UniProt_P67936 UniProt_P67936-2 UniProt_Q5TCU3 UniProt_Q5TCU8 UniProt_Q5VU58 UniProt_Q5VU61 UniProt_Q6ZN40 genCDS_ENST00000267996_15_63042830-63071172_1 genCDS_ENST00000271850_1_154157639-154192018_-1 genCDS_ENST00000288398_15_63042830-63064146_1 genCDS_ENST00000300933_19_16076566-16101346_1 genCDS_ENST00000317516_15_63048576-63069943_1 genCDS_ENST00000323144_1_154158969-154183119_-1 genCDS_ENST00000328159_1_154157718-154183119_-1 genCDS_ENST00000329305_9_35682081-35689817_-1 genCDS_ENST00000330188_1_154157639-154183119_-1 genCDS_ENST00000334895_15_63048576-63069943_1 genCDS_ENST00000341372_1_154157639-154183119_-1 genCDS_ENST00000344824_19_16067625-16101346_1 genCDS_ENST00000357980_15_63042830-63071172_1 genCDS_ENST00000358278_15_63042830-63071172_1 genCDS_ENST00000360958_9_35683159-35689817_-1 genCDS_ENST00000368530_1_154167937-154192018_-1 genCDS_ENST00000368531_1_154158969-154183119_-1 genCDS_ENST00000368533_1_154157639-154183119_-1 genCDS_ENST00000378292_9_35682081-35689817_-1 genCDS_ENST00000378300_9_35682708-35689817_-1 genCDS_ENST00000403994_15_63042830-63065899_1 genCDS_ENST00000404484_15_63048576-63071172_1 genCDS_ENST00000509601_1_154172070-154183119_-1 genCDS_ENST00000558347_15_63042830-63061226_1 genCDS_ENST00000559281_15_63048576-63065899_1 genCDS_ENST00000559397_15_63042830-63071172_1 genCDS_ENST00000559556_15_63042830-63071172_1 genCDS_ENST00000559831_15_63044141-63061730_1 genCDS_ENST00000560959_15_63048576-63062809_1 genCDS_ENST00000560970_15_63042888-63064146_1 genCDS_ENST00000561266_15_63043776-63064146_1 genCDS_ENST00000561395_15_63057006-63061730_1 genCDS_ENST00000586499_19_16067897-16088093_1 genCDS_ENST00000586833_19_16075707-16093544_1 genCDS_ENST00000588410_19_16080953-16088066_1 genCDS_ENST00000611659_1_154157639-154183119_-1 genpseudogene_ENST00000330554_2_230573167-230573809_-1_1_ORF1 genpseudogene_ENST00000368528_3_27632976-27633720_1_2_ORF2 genpseudogene_ENST00000600996_19_41506152-41506898_1_3_ORF3 yalePseudo_PGOHUM00000240545_2_231437883-231438626_-1_1_ORF1
query:48481;rank:1;spectrum:361.85358_1714.94_spectrum=140581_uteruspremenopause;rt:1714.94;mz:361.85358;charge:3 2.12562 0.000132074 0.00101867 X.VYLYHSSSK.X UniProt_B4DDT0 UniProt_H0YA32 UniProt_K7EMU3 UniProt_P26006 UniProt_P26006-1 genCDS_ENST00000007722_17_50056440-50089265_1 genCDS_ENST00000320031_17_50056440-50088335_1 genCDS_ENST00000510809_17_50072160-50074284_1 genCDS_ENST00000512553_17_50070873-50074514_1
query:29295;rank:1;spectrum:483.24051_2183.66_spectrum=149333_uteruspremenopause;rt:2183.66;mz:483.24051;charge:2 2.06983 0.000144798 0.00114547 X.VDFNVPM(Oxidation)K.X UniProt_E7ERH5 UniProt_P00558 UniProt_P07205 genCDS_ENST00000304801_6_49785934-49787187_-1 genCDS_ENST00000373316_X_78104341-78125830_1
query:36143;rank:1;spectrum:504.74222_1377.49_spectrum=31223_uteruspremenopause;rt:1377.49;mz:504.74222;charge:2 2.02503 0.000173319 0.00125862 X.SLM(Oxidation)SADNVR.X UniProt_O43143 genCDS_ENST00000336812_4_24527924-24584393_-1
query:123327;rank:1;spectrum:525.58398_2676.85_spectrum=49516_uteruspremenopause;rt:2676.85;mz:525.58398;charge:3 1.99921 0.000173319 0.00132883 X.QVDVTSFAGHPCTR.X UniProt_H0Y5U1 UniProt_O00468 UniProt_O00468-2 UniProt_O00468-3 UniProt_O00468-4 UniProt_O00468-5 UniProt_O00468-6 UniProt_O00468-7 genCDS_ENST00000379370_1_1020173-1054981_1 genCDS_ENST00000419249_1_1050556-1053950_1 genCDS_ENST00000620552_1_1022414-1054981_1
query:59938;rank:1;spectrum:575.31378_2777.5_spectrum=112771_uteruspremenopause;rt:2777.5;mz:575.31378;charge:2 1.9623 0.000173319 0.00143597 X.LVNEVTEFAK.X CON_P02768-1 UniProt_H7C013 UniProt_P02768 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000441319_4_73397114-73409457_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000621085_4_73404328-73420298_1 genCDS_ENST00000621628_4_73404328-73420298_1
query:23238;rank:1;spectrum:464.21664_1155.55_spectrum=169721_uteruspremenopause;rt:1155.55;mz:464.21664;charge:2 1.87479 0.000198798 0.00172556 X.CQYVTEK.X UniProt_H3BPS8 UniProt_H3BQN4 UniProt_J3KPS3 UniProt_P04075 UniProt_P04075-2 UniProt_P09972 genCDS_ENST00000226253_17_28573526-28575532_-1 genCDS_ENST00000338110_16_30067255-30070212_1 genCDS_ENST00000395240_16_30067255-30070212_1 genCDS_ENST00000395248_16_30066898-30070212_1 genCDS_ENST00000395321_17_28573526-28575532_-1 genCDS_ENST00000412304_16_30067255-30070212_1 genCDS_ENST00000562679_16_30066898-30069547_1 genCDS_ENST00000563060_16_30067255-30070212_1 genCDS_ENST00000564546_16_30067255-30070212_1 genCDS_ENST00000564595_16_30066898-30070212_1 genCDS_ENST00000566897_16_30067255-30070212_1 genCDS_ENST00000569545_16_30067255-30070212_1 genCDS_ENST00000569798_16_30067255-30070116_1
query:57302;rank:1;spectrum:379.21075_3171.84_spectrum=50657_uteruspremenopause;rt:3171.84;mz:379.21075;charge:3 1.8485 0.000212479 0.00182324 X.FKM(Oxidation)PELNLK.X UniProt_Q09666 genCDS_ENST00000378024_11_62516744-62536098_-1
query:17102;rank:1;spectrum:442.76447_2988.18_spectrum=166780_uteruspremenopause;rt:2988.18;mz:442.76447;charge:2 1.7864 0.000268723 0.00207556 X.(Acetyl)VATVSLPR.X CON_P00761
query:86128;rank:1;spectrum:431.55176_762.55_spectrum=60182_uteruspremenopause;rt:762.55;mz:431.55176;charge:3 1.68922 0.000320239 0.00253864 X.HM(Oxidation)QANPEPPKK.X UniProt_Q15404 UniProt_Q15404-2 genCDS_ENST00000345264_10_16593394-16817081_-1 genCDS_ENST00000377921_10_16593394-16817081_-1 genCDS_ENST00000602389_10_16593394-16782034_-1
query:5783;rank:1;spectrum:395.23944_2103.35_spectrum=103066_uteruspremenopause;rt:2103.35;mz:395.23944;charge:2 1.63365 0.000371014 0.00284701 X.LVTDLTK.X CON_P02768-1 CON_P02769 UniProt_B7WNR0 UniProt_C9JKR2 UniProt_D6RHD5 UniProt_H0YA55 UniProt_P02768 UniProt_P02768-2 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000401494_4_73404328-73420298_1 genCDS_ENST00000415165_4_73404328-73420298_1 genCDS_ENST00000503124_4_73406730-73420298_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000511370_4_73409340-73420298_1
query:95400;rank:1;spectrum:450.9129_2783.38_spectrum=4821_uteruspremenopause;rt:2783.38;mz:450.9129;charge:3 1.62591 0.000371014 0.00289274 X.TAAENEFVTLKK.X CON_P02538 CON_P04259 CON_P12035 CON_P48668 CON_P50446 UniProt_J3QST3 UniProt_P02538 UniProt_P04259 UniProt_P12035 UniProt_P48668 genCDS_ENST00000252250_12_52469062-52473737_-1 genCDS_ENST00000252252_12_52447190-52452078_-1 genCDS_ENST00000330722_12_52487720-52493188_-1 genCDS_ENST00000417996_12_52790042-52796042_-1
query:16267;rank:1;spectrum:439.74139_3590.06_spectrum=75323_uteruspremenopause;rt:3590.06;mz:439.74139;charge:2 1.62109 0.000371014 0.00292163 X.FVADLWK.X UniProt_P35749 UniProt_P35749-2 UniProt_P35749-3 UniProt_P35749-4 genCDS_ENST00000300036_16_15703991-15838252_-1 genCDS_ENST00000396324_16_15703991-15838252_-1 genCDS_ENST00000452625_16_15708811-15838252_-1 genCDS_ENST00000576790_16_15708811-15838252_-1 genCDS_ENST00000611087_16_15703879-15838252_-1 genCDS_ENST00000616439_16_15703879-15838252_-1
query:96057;rank:1;spectrum:452.58298_2886.61_spectrum=166517_uteruspremenopause;rt:2886.61;mz:452.58298;charge:3 1.60885 0.000371014 0.00299626 X.VTGEVHLGGVM(Oxidation)LK.X UniProt_G3V281 UniProt_G3V379 UniProt_Q96AC1 UniProt_Q96AC1-2 UniProt_Q96AC1-3 genCDS_ENST00000341590_14_52858377-52950568_-1 genCDS_ENST00000343279_14_52858377-52950568_-1 genCDS_ENST00000395631_14_52858377-52950568_-1 genCDS_ENST00000399304_14_52859561-52950568_-1 genCDS_ENST00000553373_14_52858377-52950568_-1 genCDS_ENST00000554712_14_52893359-52950568_-1 genCDS_ENST00000557562_14_52919335-52950568_-1
query:47514;rank:1;spectrum:360.18124_1413.26_spectrum=124451_uteruspremenopause;rt:1413.26;mz:360.18124;charge:3 1.48919 0.000510326 0.00383368 X.FLENEDRR.X UniProt_P01009 UniProt_P01009-2 UniProt_P01009-3 genCDS_ENST00000355814_14_94378449-94383237_-1 genCDS_ENST00000393087_14_94378449-94383237_-1 genCDS_ENST00000393088_14_94378449-94383237_-1 genCDS_ENST00000402629_14_94379449-94383237_-1 genCDS_ENST00000404814_14_94378449-94383237_-1 genCDS_ENST00000437397_14_94378449-94383237_-1 genCDS_ENST00000440909_14_94378449-94383237_-1 genCDS_ENST00000448921_14_94378449-94383237_-1 genCDS_ENST00000449399_14_94378449-94383237_-1 genCDS_ENST00000489769_14_94380867-94383237_-1
query:31310;rank:1;spectrum:489.31235_2716.22_spectrum=127949_uteruspremenopause;rt:2716.22;mz:489.31235;charge:2 1.36197 0.000578424 0.0050008 X.KLELHLPK.X UniProt_P29622 genCDS_ENST00000298841_14_94563483-94569595_1 genCDS_ENST00000555095_14_94563483-94569595_1 genCDS_ENST00000557004_14_94563483-94569595_1
query:129404;rank:1;spectrum:546.57996_1004.75_spectrum=161953_uteruspremenopause;rt:1004.75;mz:546.57996;charge:3 1.28237 0.000726094 0.005938 X.LGREEPAM(Oxidation)SM(Oxidation)DANGK.X UniProt_B4DZI8 UniProt_P35606 genCDS_ENST00000333188_3_139357863-139389550_-1 genCDS_ENST00000507777_3_139357863-139383351_-1
query:40260;rank:1;spectrum:517.28729_2307.21_spectrum=95484_uteruspremenopause;rt:2307.21;mz:517.28729;charge:2 1.25301 0.000760157 0.00633558 X.YVPGVGNVTK.X UniProt_Q8IWV7 UniProt_Q8IWV7-2 genCDS_ENST00000290650_15_42945329-43106022_-1 genCDS_ENST00000546274_15_43015684-43106022_-1 genCDS_ENST00000569066_15_43026631-43037829_-1
query:19664;rank:1;spectrum:451.27832_3344.97_spectrum=106687_uteruspremenopause;rt:3344.97;mz:451.27832;charge:2 1.24376 0.000772162 0.00646756 X.GPFLVALGK.X UniProt_F5H7Y0 UniProt_H0Y8Y3 UniProt_Q96HC4 UniProt_Q96HC4-4 UniProt_Q96HC4-6 UniProt_Q96HC4-7 genCDS_ENST00000317968_4_94455289-94664067_1 genCDS_ENST00000437932_4_94618059-94664067_1 genCDS_ENST00000503974_4_94455289-94666026_1 genCDS_ENST00000506632_4_94585627-94656820_1 genCDS_ENST00000514743_4_94455289-94664067_1 genCDS_ENST00000542407_4_94575691-94664067_1 genCDS_ENST00000615540_4_94455289-94664067_1
query:25040;rank:1;spectrum:469.26465_1783.6_spectrum=54803_uteruspremenopause;rt:1783.6;mz:469.26465;charge:2 1.2271 0.000782926 0.00671406 X.LLHTYYK.X UniProt_B5ME19 UniProt_H3BRV0 UniProt_Q99613 genCDS_ENST00000331666_16_28711687-28735513_1 genCDS_ENST00000380876_16_28379798-28403618_-1 genCDS_ENST00000395587_16_28711687-28735513_1 genCDS_ENST00000398944_16_28379798-28403618_-1 genCDS_ENST00000564243_16_28711687-28735513_1 genCDS_ENST00000566501_16_28711687-28735513_1 genCDS_ENST00000566866_16_28711687-28735513_1
query:136411;rank:1;spectrum:429.48587_1838.93_spectrum=163885_uteruspremenopause;rt:1838.93;mz:429.48587;charge:4 1.16869 0.000861273 0.00767686 X.LDSEDKDKEGKPLLK.X UniProt_P13639 genCDS_ENST00000309311_19_3976554-3985380_-1
query:11971;rank:1;spectrum:423.73737_1581.19_spectrum=24615_uteruspremenopause;rt:1581.19;mz:423.73737;charge:2 1.15731 0.00087327 0.00788465 X.ATEVTVAR.X UniProt_F5GZL7 UniProt_F8W8Q1 UniProt_H0Y390 UniProt_H3BPE1 UniProt_H3BQK9 UniProt_Q9UPN3 UniProt_Q9UPN3-2 UniProt_Q9UPN3-3 UniProt_Q9UPN3-4 UniProt_Q9UPN3-5 genCDS_ENST00000289893_1_39331269-39485794_1 genCDS_ENST00000361689_1_39084219-39485794_1 genCDS_ENST00000372915_1_39084219-39485794_1 genCDS_ENST00000372925_1_39300314-39485794_1 genCDS_ENST00000564288_1_39205023-39485794_1 genCDS_ENST00000567887_1_39084219-39485794_1
query:1271;rank:1;spectrum:368.20523_2167.57_spectrum=33073_uteruspremenopause;rt:2167.57;mz:368.20523;charge:2 1.14788 0.000884565 0.00806222 X.GDVAFVK.X CON_Q0IIK2 CON_Q29443 CON_Q2HJF0 UniProt_H7C5E8 UniProt_J3KN47 UniProt_P02787 genCDS_ENST00000402696_3_133746441-133778620_1 genCDS_ENST00000461695_3_133766278-133775445_1
query:95023;rank:1;spectrum:450.21964_926.016_spectrum=108365_uteruspremenopause;rt:926.016;mz:450.21964;charge:3 1.14691 0.000884565 0.00808068 X.SDDNRESLEKR.X UniProt_P30085 UniProt_P30085-2 genCDS_ENST00000371873_1_47333946-47376745_1 genCDS_ENST00000450808_1_47333946-47376745_1
query:78779;rank:1;spectrum:625.27612_1963.17_spectrum=17448_uteruspremenopause;rt:1963.17;mz:625.27612;charge:2 1.11901 0.000928303 0.0086392 X.DNVDDPTGNFR.X UniProt_Q12907 genCDS_ENST00000303127_5_177332086-177351647_-1
query:32633;rank:1;spectrum:493.74869_1021.76_spectrum=139019_uteruspremenopause;rt:1021.76;mz:493.74869;charge:2 1.11186 0.000928303 0.00879018 X.ASPEAASTPR.X UniProt_H3BT29 UniProt_H3BT57 UniProt_H3BUJ5 UniProt_H3BVD2 UniProt_P29590 UniProt_P29590-10 UniProt_P29590-11 UniProt_P29590-12 UniProt_P29590-13 UniProt_P29590-14 UniProt_P29590-2 UniProt_P29590-3 UniProt_P29590-4 UniProt_P29590-5 UniProt_P29590-8 UniProt_P29590-9 genCDS_ENST00000268058_15_73994813-74045008_1 genCDS_ENST00000268059_15_73994813-74035951_1 genCDS_ENST00000354026_15_73994813-74035951_1 genCDS_ENST00000359928_15_73994813-74034495_1 genCDS_ENST00000395132_15_73994813-74036060_1 genCDS_ENST00000395135_15_73994813-74043180_1 genCDS_ENST00000435786_15_73994813-74034656_1 genCDS_ENST00000436891_15_73994813-74034495_1 genCDS_ENST00000563500_15_73994813-74033608_1 genCDS_ENST00000564428_15_73994813-74043180_1 genCDS_ENST00000565239_15_74022912-74036060_1 genCDS_ENST00000565898_15_73994813-74045008_1 genCDS_ENST00000566068_15_74023295-74035154_1 genCDS_ENST00000567543_15_73994813-74034495_1 genCDS_ENST00000567606_15_74022981-74034495_1 genCDS_ENST00000569477_15_73994813-74035347_1 genCDS_ENST00000569965_15_73994813-74034495_1
query:38217;rank:1;spectrum:511.28668_2167.71_spectrum=55788_uteruspremenopause;rt:2167.71;mz:511.28668;charge:2 1.03421 0.00103826 0.0106727 X.DLPEHAVLK.X UniProt_Q00839 UniProt_Q00839-2 genCDS_ENST00000283179_1_244854450-244864307_-1 genCDS_ENST00000444376_1_244854450-244864307_-1
query:162959;rank:1;spectrum:1114.509_3262.17_spectrum=159859_uteruspremenopause;rt:3262.17;mz:1114.509;charge:2 1.02402 0.00105016 0.0109563 X.AM(Oxidation)LSGPGQ(Deamidated)FAENETNEVNFR.X UniProt_E5RHG8 UniProt_Q15369 UniProt_Q15369-2 calCuffs_CUFF.49941.1_15_41849132-41849866_1_1_ORF2 genCDS_ENST00000284811_8_73946630-73959768_-1 genCDS_ENST00000518127_8_73946630-73959768_-1 genCDS_ENST00000519082_8_73946700-73959768_-1 genCDS_ENST00000519487_8_73946630-73959768_-1 genCDS_ENST00000520210_8_73946630-73956010_-1 genCDS_ENST00000520242_8_73946630-73959768_-1 genCDS_ENST00000522337_8_73946630-73959768_-1 genCDS_ENST00000523815_8_73946630-73959768_-1 genCDS_ENST00000622804_8_73946630-73959768_-1
query:493;rank:1;spectrum:364.2103_2722.7_spectrum=34432_uteruspremenopause;rt:2722.7;mz:364.2103;charge:2 1.01234 0.00107207 0.011293 X.YLYLR.X CON_Q05443 UniProt_A2RUS2 UniProt_A2RUS2-2 UniProt_E9PF32 UniProt_H0YAY3 UniProt_P51884 UniProt_Q8IZT6 XXX_1317687 XXX_1318739 XXX_1319802 XXX_1320698 XXX_1321015 XXX_1322425 XXX_1508340 XXX_1759976 XXX_1802721 XXX_1908615 XXX_244137 XXX_24581 XXX_2923480 XXX_2928492 XXX_2928493 XXX_2928495 XXX_2928496 XXX_2949234 XXX_2981109 XXX_2981110 XXX_3632075 XXX_3860754 XXX_3986952 XXX_3986953 XXX_3986954 XXX_3986955 XXX_3987789 XXX_4011861 XXX_4011867 XXX_4011870 XXX_815771 XXX_816106 calCuffs_CUFF.103119.2_3_161317860-161356881_1_2_ORF21 calCuffs_CUFF.103119.5_3_161333860-161356881_1_3_ORF17 calCuffs_CUFF.103119.6_3_161334114-161356881_1_1_ORF14 calCuffs_CUFF.103119.8_3_161346370-161356881_1_3_ORF15 calCuffs_CUFF.115499.1_5_1473232-1481829_1_2_ORF7 calCuffs_CUFF.128368.1_6_31802244-31811541_-1_1_ORF46 calCuffs_CUFF.128368.2_6_31802244-31811541_-1_1_ORF46 calCuffs_CUFF.1336.1_1_22047526-22055216_1_1_ORF1 calCuffs_CUFF.165574.1_X_121355709-121383470_1_3_ORF111 calCuffs_CUFF.165574.2_X_121355709-121383470_1_3_ORF155 calCuffs_CUFF.165574.3_X_121355857-121383470_1_1_ORF180 calCuffs_CUFF.165574.4_X_121355857-121383470_1_3_ORF146 calCuffs_CUFF.165574.6_X_121356178-121383470_1_3_ORF139 calCuffs_CUFF.165574.7_X_121363426-121383470_1_2_ORF112 calCuffs_CUFF.46425.1_14_68586652-68634192_-1_3_ORF32 calCuffs_CUFF.46425.2_14_68586652-68634288_-1_1_ORF52 calCuffs_CUFF.64507.5_18_33515874-33530500_-1_1_ORF63 calCuffs_CUFF.65492.2_18_61137255-61172334_-1_2_ORF176 calCuffs_CUFF.65972.3_18_70992026-71027992_1_1_ORF37 calCuffs_CUFF.65972.4_18_70992026-71027992_1_1_ORF19 calCuffs_CUFF.65972.7_18_70992235-71027992_1_3_ORF16 calCuffs_CUFF.87619.6_20_49983340-50039104_1_1_ORF17 calCuffs_CUFF.9273.1_1_173606791-173638011_1_1_ORF112 calCuffs_CUFF.9273.2_1_173606791-173638011_1_1_ORF106 genCDS_ENST00000262585_8_141136647-141194233_1 genCDS_ENST00000266718_12_91104165-91108979_-1 genCDS_ENST00000367409_1_197084324-197146437_-1 genCDS_ENST00000424248_8_141136647-141194233_1 genCDS_ENST00000518668_8_141128779-141194233_1 genCDS_ENST00000519811_8_141128708-141194233_1 genlncRNA_ENST00000449713_21_44485577-44490288_1_3_ORF3 genlncRNA_ENST00000562834_6_54943167-54945099_1_3_ORF15 genlncRNA_ENST00000614289_7_9082557-9189785_-1_1_ORF3
query:172844;rank:1;spectrum:659.81531_2195.32_spectrum=87449_uteruspremenopause;rt:2195.32;mz:659.81531;charge:4 0.865178 0.00138098 0.0168505 X.QEPERNECFLQHKDDNPNLPR.X CON_P02768-1 UniProt_H7C013 UniProt_P02768 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000441319_4_73397114-73409457_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000621085_4_73404328-73420298_1 genCDS_ENST00000621628_4_73404328-73420298_1
query:3314;rank:1;spectrum:381.23285_2666.74_spectrum=19351_uteruspremenopause;rt:2666.74;mz:381.23285;charge:2 0.532423 0.00282806 0.0455454 X.LM(Oxidation)VALAK.X Augustus2_AUGUSTUS00000042791_4_153307709-153311274_-1 UniProt_A6NMY6 UniProt_H0YKS4 UniProt_H0YL33 UniProt_H0YM50 UniProt_H0YMD0 UniProt_H0YMU9 UniProt_H0YN28 UniProt_H0YN42 UniProt_H0YN52 UniProt_H0YNA0 UniProt_H0YNP5 UniProt_P07355 UniProt_P07355-2 genCDS_ENST00000332680_15_60347630-60397913_-1 genCDS_ENST00000396024_15_60347630-60386075_-1 genCDS_ENST00000421017_15_60347630-60386075_-1 genCDS_ENST00000451270_15_60347630-60386075_-1 genCDS_ENST00000557906_15_60355919-60386075_-1 genCDS_ENST00000558132_15_60351782-60386075_-1 genCDS_ENST00000558985_15_60351724-60360946_-1 genCDS_ENST00000558998_15_60354154-60360946_-1 genCDS_ENST00000559113_15_60355919-60360946_-1 genCDS_ENST00000559176_15_60351192-60374505_-1 genCDS_ENST00000559818_15_60351733-60386075_-1 genCDS_ENST00000560014_15_60351813-60386075_-1 genCDS_ENST00000560165_15_60355919-60386075_-1 genCDS_ENST00000560367_15_60352383-60386075_-1 genCDS_ENST00000560389_15_60355919-60386075_-1 genCDS_ENST00000560466_15_60351733-60360946_-1 genpseudogene_ENST00000435128_9_33624274-33625293_1_1_ORF1
query:14008;rank:1;spectrum:431.7608_3415_spectrum=82918_uteruspremenopause;rt:3415;mz:431.7608;charge:2 0.482234 0.0031261 0.0531809 X.FLLSNLR.X UniProt_E9PGM4 UniProt_Q04446 XXX_3648561 genCDS_ENST00000429644_3_81490407-81761517_-1 genCDS_ENST00000489715_3_81490407-81743576_-1
query:26472;rank:1;spectrum:474.24692_2020.57_spectrum=133852_uteruspremenopause;rt:2020.57;mz:474.24692;charge:2 0.378973 0.00408 0.0731188 X.CLLVEEGK.X Augustus2_AUGUSTUS00000097311_8_73984804-73984493_1 UniProt_F6RFD5 UniProt_P60981 UniProt_P60981-2 genCDS_ENST00000246069_20_17570209-17607146_1 genCDS_ENST00000449141_20_17570209-17605129_1 genCDS_ENST00000474024_20_17600786-17607146_1 genpseudogene_ENST00000399472_3_39214199-39214672_1_1_ORF1 genpseudogene_ENST00000517767_8_73984493-73984883_1_1_ORF1 yalePseudo_PGOHUM00000249715_8_74896728-74897132_1_1_ORF1
query:25242;rank:1;spectrum:470.24841_1903.97_spectrum=25332_uteruspremenopause;rt:1903.97;mz:470.24841;charge:2 0.374892 0.00415655 0.0740455 X.VSSYGGTLR.X UniProt_O15230 genCDS_ENST00000252999_20_62309336-62367245_-1
query:14390;rank:1;spectrum:433.73349_2095.35_spectrum=156931_uteruspremenopause;rt:2095.35;mz:433.73349;charge:2 0.337635 0.00458149 0.0830843 X.(Carbamidomethyl)YLSALN(Deamidated)K.X genlncRNA_ENST00000433639_3_6490479-6736129_1_3_ORF9
query:59374;rank:1;spectrum:574.29547_1290.25_spectrum=46381_uteruspremenopause;rt:1290.25;mz:574.29547;charge:2 0.216141 0.00585082 0.121453 X.ESKPAQGQFR.X UniProt_Q05707 UniProt_Q05707-2 UniProt_Q05707-3 UniProt_Q4G0W3 genCDS_ENST00000297848_8_120147843-120371231_1 genCDS_ENST00000309791_8_120147843-120370367_1 genCDS_ENST00000498051_8_120147843-120213942_1 genCDS_ENST00000537875_8_120147843-120213942_1
query:139088;rank:1;spectrum:584.30249_2663.68_spectrum=181151_uteruspremenopause;rt:2663.68;mz:584.30249;charge:3 0.201002 0.00605916 0.127366 X.(Acetyl)LRTEGDGVYTLNDKK.X Augustus2_AUGUSTUS00000011721_16_72077081-72063214_1 UniProt_H0Y300 UniProt_J3KRH2 UniProt_J3KTC3 UniProt_J3QLC9 UniProt_J3QR68 UniProt_P00738 UniProt_P00739 UniProt_P00739-2 genCDS_ENST00000355906_16_72054653-72060890_1 genCDS_ENST00000357763_16_72054653-72060890_1 genCDS_ENST00000540303_16_72063256-72077081_1 genCDS_ENST00000561690_16_72063256-72076993_1 genCDS_ENST00000565574_16_72054653-72060890_1 genCDS_ENST00000567185_16_72056161-72060890_1 genCDS_ENST00000567612_16_72056161-72060890_1 genCDS_ENST00000576168_16_72056161-72059199_1
query:41161;rank:1;spectrum:520.79297_2617.01_spectrum=165822_uteruspremenopause;rt:2617.01;mz:520.79297;charge:2 0.17738 0.00651168 0.137133 X.SVPM(Oxidation)VPPGLK.X CON_Q05443 UniProt_P51884 genCDS_ENST00000266718_12_91104165-91108979_-1
query:46620;rank:1;spectrum:537.77405_1721.6_spectrum=2503_uteruspremenopause;rt:1721.6;mz:537.77405;charge:2 0.107507 0.00780292 0.169915 X.LDELRDEGK.X CON_P02768-1 UniProt_B7WNR0 UniProt_D6RHD5 UniProt_H0YA55 UniProt_P02768 genCDS_ENST00000295897_4_73404328-73420298_1 genCDS_ENST00000401494_4_73404328-73420298_1 genCDS_ENST00000503124_4_73406730-73420298_1 genCDS_ENST00000509063_4_73404328-73421121_1 genCDS_ENST00000511370_4_73409340-73420298_1
query:70107;rank:1;spectrum:602.77112_906.603_spectrum=45528_uteruspremenopause;rt:906.603;mz:602.77112;charge:2 0.100629 0.00788342 0.173457 X.QQQQMEQER.X UniProt_H0YDN1 UniProt_Q15149 UniProt_Q15149-2 UniProt_Q15149-3 UniProt_Q15149-4 UniProt_Q15149-5 UniProt_Q15149-6 UniProt_Q15149-7 UniProt_Q15149-8 UniProt_Q15149-9 genCDS_ENST00000322810_8_143916177-143950706_-1 genCDS_ENST00000345136_8_143916177-143939461_-1 genCDS_ENST00000354589_8_143916177-143943890_-1 genCDS_ENST00000354958_8_143916177-143953771_-1 genCDS_ENST00000356346_8_143916177-143973472_-1 genCDS_ENST00000357649_8_143916177-143942515_-1 genCDS_ENST00000398774_8_143916177-143944663_-1 genCDS_ENST00000436759_8_143916177-143975369_-1 genCDS_ENST00000527096_8_143916177-143975369_-1 genCDS_ENST00000527303_8_143921932-143927011_-1
query:58423;rank:1;spectrum:571.82373_3329.4_spectrum=28523_uteruspremenopause;rt:3329.4;mz:571.82373;charge:2 -0.0664699 0.0118764 0.276689 X.VKGDVDVSVPK.X UniProt_Q09666 genCDS_ENST00000378024_11_62516744-62536098_-1
query:4273;rank:1;spectrum:388.21448_1441.57_spectrum=147307_uteruspremenopause;rt:1441.57;mz:388.21448;charge:2 -0.0871283 0.0123296 0.291726 X.LASLDEK.X UniProt_E9PNR6 UniProt_H0YE29 UniProt_Q07960 genCDS_ENST00000311956_11_46679037-46696107_-1 genCDS_ENST00000525488_11_46681069-46696107_-1 genCDS_ENST00000528837_11_46679217-46696099_-1
query:981;rank:1;spectrum:366.20657_1827.57_spectrum=78717_uteruspremenopause;rt:1827.57;mz:366.20657;charge:2 -0.266624 0.0180136 0.438278 X.DNTLLR.X UniProt_A6NN80 UniProt_H0YG46 UniProt_J3KNE4 UniProt_P08133 UniProt_P08133-2 UniProt_Q8WZ42 UniProt_Q8WZ42-11 UniProt_Q8WZ42-12 UniProt_Q8WZ42-13 UniProt_Q8WZ42-2 UniProt_Q8WZ42-4 UniProt_Q8WZ42-5 UniProt_Q8WZ42-7 UniProt_Q8WZ42-8 UniProt_Q99550 UniProt_Q99550-2 UniProt_U3KQ28 XXX_3776517 XXX_3780596 XXX_3818260 XXX_3846030 XXX_3896565 XXX_4087153 XXX_4095718 XXX_4139454 XXX_4158810 XXX_4177746 genCDS_ENST00000302373_12_123161368-123221847_-1 genCDS_ENST00000342992_2_178527012-178804642_-1 genCDS_ENST00000354546_5_151101448-151147901_-1 genCDS_ENST00000523714_5_151101448-151140165_-1 genCDS_ENST00000539024_12_123161368-123218478_-1 genCDS_ENST00000541076_12_123156807-123230364_-1 genCDS_ENST00000589042_2_178527012-178804642_-1 genCDS_ENST00000591111_2_178527012-178804642_-1 genCDS_ENST00000606320_12_123156807-123230364_-1 genCDS_ENST00000615779_2_178527012-178804642_-1
query:33052;rank:1;spectrum:494.77515_1390.27_spectrum=155237_uteruspremenopause;rt:1390.27;mz:494.77515;charge:2 -0.390915 0.0229485 0.545281 X.KQVENKN(Deamidated)K.X UniProt_Q15431 UniProt_Q5VXJ5 genCDS_ENST00000369518_1_114855465-114995019_1 genCDS_ENST00000369522_1_114855465-114995019_1 genCDS_ENST00000455987_1_114855465-114977610_1 genCDS_ENST00000613524_1_114855465-114995019_1 genCDS_ENST00000618516_1_114855465-114995019_1
query:15821;rank:1;spectrum:438.23367_2620.9_spectrum=88556_uteruspremenopause;rt:2620.9;mz:438.23367;charge:2 -0.554281 0.0308507 0.671862 X.QGGPEFLK.X calCuffs_CUFF.56789.1_16_67551854-67597900_-1_1_ORF3 calCuffs_CUFF.56789.2_16_67551854-67562677_-1_1_ORF3 calCuffs_CUFF.56789.3_16_67551854-67562643_-1_3_ORF2 calCuffs_CUFF.56789.4_16_67551854-67564404_-1_2_ORF5 calCuffs_CUFF.56789.5_16_67551854-67556024_-1_1_ORF2 ensBodymap_RNASEQT00000108700_16_67551703-67597612_-1 genlncRNA_ENST00000613438_16_67517862-67528632_-1_3_ORF2 genlncRNA_ENST00000621378_16_67517950-67528675_-1_2_ORF4 mitSBM_kidney_16_67551858-67562264_-1_3_ORF1 mitSBM_lymphNode_16_67551861-67562262_-1_1_ORF1
query:149496;rank:1;spectrum:951.48413_3058.62_spectrum=89727_uteruspremenopause;rt:3058.62;mz:951.48413;charge:2 -0.634256 0.0352042 0.722362 X.(Acetyl)KPGAAGQHPAPFDPQSVR.X genlncRNA_ENST00000449990_9_90463659-90582744_-1_3_ORF1
query:106872;rank:1;spectrum:720.35449_2699.4_spectrum=150809_uteruspremenopause;rt:2699.4;mz:720.35449;charge:2 -0.816145 0.0457039 0.814517 X.STDNVFLACWVK.X calCuffs_CUFF.6079.5_1_107514034-107541205_-1_3_ORF3
query:44599;rank:1;spectrum:531.28_2604.3_spectrum=19171_uteruspremenopause;rt:2604.3;mz:531.28;charge:2 -0.98233 0.0555745 0.881893 X.KQ(Deamidated)WERTGR.X calCuffs_CUFF.84105.1_2_227648862-227677259_1_3_ORF138 calCuffs_CUFF.84105.2_2_227653754-227677259_1_1_ORF74
query:2044;rank:1;spectrum:374.22897_2891.89_spectrum=135978_uteruspremenopause;rt:2891.89;mz:374.22897;charge:2 -1.04589 0.0593188 0.912796 X.FLLQAR.X UniProt_P07360 UniProt_Q5SQ08 XXX_2911659 XXX_2911660 XXX_3992543 XXX_4073578 calCuffs_CUFF.65457.2_18_60989274-60994029_1_2_ORF3 genCDS_ENST00000224181_9_136945321-136946781_1 genCDS_ENST00000371634_9_136945321-136946361_1
query:154157;rank:1;spectrum:664.31238_3596.01_spectrum=176082_uteruspremenopause;rt:3596.01;mz:664.31238;charge:3 -1.09757 0.0622534 0.94086 X.(Acetyl)SKCFASN(Deamidated)SQ(Deamidated)LLYSQGEK.X genlncRNA_ENST00000428520_10_10934524-10952095_-1_1_ORF2
query:109576;rank:1;spectrum:730.34552_2652.62_spectrum=142764_uteruspremenopause;rt:2652.62;mz:730.34552;charge:2 -1.13897 0.0647164 0.964364 X.(Carbamidomethyl)NN(Deamidated)PVMSLQDQ(Deamidated)VR.X UniProt_A6ND99 UniProt_K7EP71 UniProt_Q7LGA3 UniProt_Q7LGA3-2 UniProt_Q7LGA3-3 genCDS_ENST00000370548_1_86993082-87168176_1 genCDS_ENST00000370550_1_86915037-87104696_1 genCDS_ENST00000370551_1_86915037-87097939_1 genCDS_ENST00000591456_1_87072984-87092588_1
query:10757;rank:1;spectrum:419.25119_2212.53_spectrum=126558_uteruspremenopause;rt:2212.53;mz:419.25119;charge:2 -1.35549 0.0765402 1 X.KSRFTAK.X calCuffs_CUFF.117687.1_5_43436710-43444350_-1_3_ORF32
query:81984;rank:1;spectrum:634.33673_1983.63_spectrum=10106_uteruspremenopause;rt:1983.63;mz:634.33673;charge:2 -1.63897 0.0885601 1 X.(Acetyl)KGLDVAEPGPSR.X UniProt_Q01433 genCDS_ENST00000256578_1_109621014-109631152_1 genCDS_ENST00000528667_1_109621014-109631152_1
query:58730;rank:1;spectrum:572.7724_1350.11_spectrum=155143_uteruspremenopause;rt:1350.11;mz:572.7724;charge:2 -1.85044 0.0949322 1 X.LGGQ(Deamidated)M(Oxidation)Q(Deamidated)VHQ(Deamidated)K.X genpseudogene_ENST00000442645_7_14985378-14986074_-1_3_ORF2
query:175487;rank:1;spectrum:943.40503_1694.59_spectrum=101873_uteruspremenopause;rt:1694.59;mz:943.40503;charge:3 -2.1027 0.100208 1 X.(Acetyl)YEDSQQ(Deamidated)EEAQ(Deamidated)YGAMFQ(Deamidated)EQLM(Oxidation)TLK.X UniProt_F5H4J1 UniProt_Q14980 UniProt_Q14980-2 UniProt_Q14980-3 UniProt_Q14980-4 genCDS_ENST00000358965_11_72003527-72035943_-1 genCDS_ENST00000393695_11_72003527-72035943_-1 genCDS_ENST00000542977_11_72014948-72035943_-1 genCDS_ENST00000616538_11_72003527-72035943_-1 genCDS_ENST00000620566_11_72003527-72035943_-1
query:90871;rank:1;spectrum:660.8255_2297.68_spectrum=111599_uteruspremenopause;rt:2297.68;mz:660.8255;charge:2 -2.46345 0.104155 1 X.(Carbamidomethyl)AHN(Deamidated)FDERVFK.X UniProt_Q96M60 UniProt_Q96M60-2 genCDS_ENST00000299338_15_49328568-49615171_-1 genCDS_ENST00000561064_15_49422710-49615171_-1
Binary file not shown.
@@ -31,4 +31,4 @@ influxdb
# Deep learning packages for tool recommendation
keras==2.2.4
tensorflow==1.12.2
tensorflow==1.15.2
@@ -4,20 +4,20 @@ alabaster==0.7.12
atomicwrites==1.3.0
attrs==19.3.0
babel==2.8.0
certifi==2019.11.28
certifi==2020.4.5.1
chardet==3.0.4
commonmark==0.9.1
configparser==4.0.2 ; python_version < '3.2'
contextlib2==0.6.0.post1 ; python_version < '3.5'
coverage==5.0.3
deprecated==1.2.7
coverage==5.0.4
deprecated==1.2.9
docutils==0.15.2
funcsigs==1.0.2 ; python_version < '3.3'
future==0.18.2
gunicorn==19.10.0
idna==2.9
imagesize==1.2.0
importlib-metadata==1.5.0 ; python_version < '3.8'
importlib-metadata==1.6.0 ; python_version < '3.8'
jinja2==2.11.1
lxml==4.5.0
markdown==3.1.1
@@ -27,17 +27,18 @@ mock==3.0.5
more-itertools==5.0.0
nose==1.3.7
nosehtml==0.4.5
packaging==20.1
packaging==20.3
pathlib2==2.3.5 ; python_version < '3.6'
pathtools==0.1.2
pluggy==0.13.1
port-for==0.4
prettytable==0.7.2
psutil==5.7.0
py==1.8.1
pygithub==1.45
pygments==2.5.2
pyjwt==1.7.1
pyparsing==2.4.6
pyparsing==2.4.7
pytest-cov==2.8.1
pytest-html==1.22.1
pytest-metadata==1.8.0
@@ -61,6 +62,7 @@ twill==2.0
typing==3.7.4.1 ; python_version < '3.5'
urllib3==1.25.8
watchdog==0.10.2
wcwidth==0.1.8
wrapt==1.12.0
wcwidth==0.1.9
wrapt==1.12.1
xmlrunner==1.7.7
zipp==1.2.0
@@ -23,8 +23,8 @@ bcrypt==3.1.7
bdbag==1.5.6
beaker==1.11.0
bioblend==0.13.0
bleach==3.1.1
boltons==20.0.0
bleach==3.1.4
boltons==20.1.0
boto3==1.9.114
boto==2.49.0
botocore==1.12.253
@@ -32,7 +32,7 @@ bx-python==0.8.8
bz2file==0.98 ; python_version < '3.3'
cachecontrol==0.11.7
cachetools==3.1.1
certifi==2019.11.28
certifi==2020.4.5.1
cffi==1.14.0
chardet==3.0.4
cheetah3==3.2.4
@@ -43,18 +43,18 @@ cmd2==0.8.9
coloredlogs==14.0
configparser==4.0.2 ; python_version < '3.2'
contextlib2==0.6.0.post1 ; python_version < '3.5'
cryptography==2.8
cryptography==2.9
cwltool==1.0.20191225192155
debtcollector==1.22.0
decorator==4.4.2
deprecated==1.2.7
deprecated==1.2.9
deprecation==2.0.7
dictobj==0.4
docopt==0.6.2
docutils==0.15.2
dogpile.cache==0.9.0
ecdsa==0.15
enum34==1.1.9 ; python_version < '3.4'
enum34==1.1.10 ; python_version < '3.4'
fabric3==1.14.post1
funcsigs==1.0.2 ; python_version < '3.3'
functools32==3.2.3.post2 ; python_version < '3.2'
@@ -63,13 +63,13 @@ futures==3.3.0 ; python_version == '2.6' or python_version == '2.7'
galaxy-sequence-utils==1.1.5
google-api-python-client==1.7.8
google-auth-httplib2==0.0.3
google-auth==1.11.2
gxformat2==0.10.1
google-auth==1.13.1
gxformat2==0.11.1
h5py==2.10.0
httplib2==0.17.0
humanfriendly==7.1.1
httplib2==0.17.2
humanfriendly==8.1
idna==2.9
importlib-metadata==1.5.0 ; python_version < '3.8'
importlib-metadata==1.6.0 ; python_version < '3.8'
ipaddress==1.0.23 ; python_version < '3.3'
isa-rwval==0.10.7
iso8601==0.1.12
@@ -78,14 +78,14 @@ jmespath==0.9.5
jsonpatch==1.25
jsonpointer==2.0
jsonschema==3.2.0
keystoneauth1==3.18.0
kombu==4.6.7
keystoneauth1==4.0.0
kombu==4.6.8
lockfile==0.12.2
lxml==4.5.0
mako==1.1.1
mako==1.1.2
markdown==3.1.1
markupsafe==1.1.1
mercurial==5.3
mercurial==5.3.2
mistune==0.8.4
monotonic==1.5
msgpack==1.0.0
@@ -102,7 +102,7 @@ numpy==1.16.6
oauth2client==4.1.3
oauthlib==3.1.0
openstacksdk==0.17.0
os-client-config==2.0.0
os-client-config==2.1.0
os-service-types==1.7.0
osc-lib==2.0.0
oslo.config==7.0.0
@@ -111,21 +111,21 @@ oslo.i18n==3.25.1
oslo.log==3.45.2
oslo.serialization==2.29.2
oslo.utils==3.42.1
packaging==20.1
packaging==20.3
paramiko==2.7.1
parsley==1.3
paste==3.4.0
pastedeploy==2.1.0
pastescript==3.2.0
pathlib2==2.3.5 ; python_version < '3.6'
pbr==5.4.4
pbr==5.4.5
prettytable==0.7.2
prov==1.5.1
psutil==5.7.0
pulsar-galaxy-lib==0.14.0.dev1
pulsar-galaxy-lib==0.14.0.dev3
pyasn1-modules==0.2.8
pyasn1==0.4.8
pycparser==2.19
pycparser==2.20
pycryptodome==3.9.7
pyeventsystem==0.1.0
pyinotify==0.9.6 ; sys_platform != 'win32' and sys_platform != 'darwin' and sys_platform != 'sunos5'
@@ -133,9 +133,9 @@ pyjwt==1.7.1
pykwalify==1.7.0
pynacl==1.3.0
pyopenssl==19.1.0
pyparsing==2.4.6
pyperclip==1.7.0
pyrsistent==0.15.7
pyparsing==2.4.7
pyperclip==1.8.0
pyrsistent==0.16.0
pysam==0.15.2
pysftp==0.2.9
python-cinderclient==4.0.0
@@ -149,7 +149,7 @@ python-openid==2.2.5 ; python_version < '3.0'
python-swiftclient==3.6.0
pytz==2019.3
pyuwsgi==2.0.18.post0
pyyaml==5.3
pyyaml==5.3.1
rdflib-jsonld==0.4.0
rdflib==4.2.2
repoze.lru==0.7
@@ -157,7 +157,7 @@ requests-oauthlib==1.3.0
requests-toolbelt==0.9.1
requests==2.23.0
requestsexceptions==1.4.0
rfc3986==1.3.2
rfc3986==1.4.0
routes==2.4.1
rsa==4.0
ruamel.ordereddict==0.4.14 ; platform_python_implementation == 'CPython' and python_version <= '2.7'
@@ -170,17 +170,17 @@ setuptools-scm==3.5.0
shellescape==3.4.1
simplejson==3.17.0
six==1.11.0
social-auth-core[openidconnect]==3.1.0+gx0
social-auth-core[openidconnect]==3.3.0
sqlalchemy-migrate==0.13.0
sqlalchemy-utils==0.36.1
sqlalchemy==1.3.13
sqlalchemy-utils==0.36.3
sqlalchemy==1.3.16
sqlparse==0.3.1
stevedore==1.32.0
subprocess32==3.5.4 ; python_version < '3.0'
svgwrite==1.3.1
tempita==0.5.2
tenacity==4.12.0
typing-extensions==3.7.4.1
typing-extensions==3.7.4.2
typing==3.7.4.1 ; python_version < '3.5'
tzlocal==2.0.0
unicodecsv==0.14.1 ; python_version < '3.0'
@@ -188,9 +188,9 @@ uritemplate==3.0.1
urllib3==1.25.8
vine==1.3.0
warlock==1.3.3
wcwidth==0.1.8
wcwidth==0.1.9
webencodings==0.5.1
webob==1.8.6
whoosh==2.7.4
wrapt==1.12.0
wrapt==1.12.1
zipp==1.2.0
@@ -1,7 +1,7 @@
-i https://pypi.python.org/simple
configparser==4.0.2 ; python_version < '3.2'
entrypoints==0.3
enum34==1.1.9 ; python_version < '3.4'
enum34==1.1.10 ; python_version < '3.4'
flake8-import-order==0.18.1
flake8==3.7.9
functools32==3.2.3.post2 ; python_version < '3.2'
+8
View File
@@ -1141,6 +1141,14 @@ class JobWrapper(HasResourceParameters):
raise Exception('(%s) Unable to create job working directory',
job.id)
@property
def guest_ports(self):
if hasattr(self, "interactivetools"):
guest_ports = [ep.get('port') for ep in self.interactivetools]
return guest_ports
else:
return []
@property
def working_directory(self):
if self.__working_directory is None:
+1 -1
View File
@@ -425,7 +425,7 @@ class BaseJobRunner(object):
compute_tmp_directory = job_wrapper.tmp_directory()
tool = job_wrapper.tool
guest_ports = [ep.get('port') for ep in getattr(job_wrapper, 'interactivetools', [])]
guest_ports = job_wrapper.guest_ports
tool_info = ToolInfo(
tool.containers,
tool.requirements,
+10 -37
View File
@@ -19,12 +19,15 @@ from galaxy.jobs.runners import (
from galaxy.jobs.runners.util.pykube_util import (
DEFAULT_JOB_API_VERSION,
ensure_pykube,
find_job_object_by_name,
galaxy_instance_id,
Job,
job_object_dict,
Pod,
produce_unique_k8s_job_name,
pull_policy,
pykube_client_from_dict,
stop_job,
)
from galaxy.util.bytesize import ByteSize
@@ -201,25 +204,8 @@ class KubernetesJobRunner(AsynchronousJobRunner):
return None
def __get_galaxy_instance_id(self):
"""
Gets the id of the Galaxy instance. This will be added to Jobs and Pods names, so it needs to be DNS friendly,
this means: `The Internet standards (Requests for Comments) for protocols mandate that component hostname labels
may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9',
and the minus sign ('-').`
It looks for the value set on self.runner_params['k8s_galaxy_instance_id'], which might or not be set. The
idea behind this is to allow the Galaxy instance to trust (or not) existing k8s Jobs and Pods that match the
setup of a Job that is being recovered or restarted after a downtime/reboot.
:return:
:rtype:
"""
if "k8s_galaxy_instance_id" in self.runner_params:
if re.match(r"(?!-)[a-z\d-]{1,20}(?<!-)$", self.runner_params['k8s_galaxy_instance_id']):
return self.runner_params['k8s_galaxy_instance_id']
else:
log.error("Galaxy instance '" + self.runner_params['k8s_galaxy_instance_id'] + "' is either too long "
+ '(>20 characters) or it includes non DNS acceptable characters, ignoring it.')
return None
"""Parse the ID of the Galaxy instance from runner params."""
return galaxy_instance_id(self.runner_params)
def __produce_unique_k8s_job_name(self, galaxy_internal_job_id):
# wrapper.get_id_tag() instead of job_id for compatibility with TaskWrappers.
@@ -509,19 +495,7 @@ class KubernetesJobRunner(AsynchronousJobRunner):
def __cleanup_k8s_job(self, job):
k8s_cleanup_job = self.runner_params['k8s_cleanup_job']
job_failed = (job.obj['status']['failed'] > 0
if 'failed' in job.obj['status'] else False)
# Scale down the job just in case even if cleanup is never
job.scale(replicas=0)
if (k8s_cleanup_job == "always" or
(k8s_cleanup_job == "onsuccess" and not job_failed)):
delete_options = {
"apiVersion": "v1",
"kind": "DeleteOptions",
"propagationPolicy": "Background"
}
r = job.api.delete(json=delete_options, **job.api_kwargs())
job.api.raise_for_status(r)
stop_job(job, k8s_cleanup_job)
def __job_failed_due_to_walltime_limit(self, job):
conditions = job.obj['status'].get('conditions') or []
@@ -550,11 +524,10 @@ class KubernetesJobRunner(AsynchronousJobRunner):
"""Attempts to delete a dispatched job to the k8s cluster"""
job = job_wrapper.get_job()
try:
jobs = Job.objects(self._pykube_api).filter(
selector="app=" + self.__produce_unique_k8s_job_name(job.get_id_tag()),
namespace=self.runner_params['k8s_namespace'])
if len(jobs.response['items']) > 0:
job_to_delete = Job(self._pykube_api, jobs.response['items'][0])
name = self.__produce_unique_k8s_job_name(job.get_id_tag())
namespace = self.runner_params['k8s_namespace']
job_to_delete = find_job_object_by_name(self._pykube_api, name, namespace)
if job_to_delete:
self.__cleanup_k8s_job(job_to_delete)
# TODO assert whether job parallelism == 0
# assert not job_to_delete.exists(), "Could not delete job,"+job.job_runner_external_id+" it still exists"
+26 -4
View File
@@ -189,6 +189,7 @@ class PulsarJobRunner(AsynchronousJobRunner):
runner_name = "PulsarJobRunner"
default_build_pulsar_app = False
use_mq = False
poll = True
def __init__(self, app, nworkers, **kwds):
"""Start the job runner."""
@@ -207,12 +208,13 @@ class PulsarJobRunner(AsynchronousJobRunner):
if self.use_mq:
# This is a message queue driven runner, don't monitor
# just setup required callback.
self._init_noop_monitor()
self.client_manager.ensure_has_status_update_callback(self.__async_update)
self.client_manager.ensure_has_ack_consumers()
else:
if self.poll:
self._init_monitor_thread()
else:
self._init_noop_monitor()
def __init_client_manager(self):
pulsar_conf = self.runner_params.get('pulsar_app_config', None)
@@ -262,6 +264,23 @@ class PulsarJobRunner(AsynchronousJobRunner):
return JobDestination(runner="pulsar", params=url_to_destination_params(url))
def check_watched_item(self, job_state):
if self.use_mq:
# Might still need to check pod IPs.
job_wrapper = job_state.job_wrapper
guest_ports = job_wrapper.guest_ports
if len(guest_ports) > 0:
client = self.get_client_from_state(job_state)
job_ip = client.job_ip()
if job_ip:
ports_dict = {}
for guest_port in guest_ports:
ports_dict[str(guest_port)] = dict(host=job_ip, port=guest_port, protocol="http")
self.app.interactivetool_manager.configure_entry_points(job_wrapper.get_job(), ports_dict)
return job_state
else:
return self.check_watched_item_state(job_state)
def check_watched_item_state(self, job_state):
try:
client = self.get_client_from_state(job_state)
status = client.get_status()
@@ -366,6 +385,7 @@ class PulsarJobRunner(AsynchronousJobRunner):
remote_pulsar_app_config=remote_pulsar_app_config,
job_directory_files=job_directory_files,
container=None if not remote_container else remote_container.container_id,
guest_ports=job_wrapper.guest_ports,
)
job_id = pulsar_submit_job(client, client_job_description, remote_job_config)
log.info("Pulsar job submitted with job_id %s" % job_id)
@@ -853,6 +873,7 @@ class PulsarLegacyJobRunner(PulsarJobRunner):
class PulsarMQJobRunner(PulsarJobRunner):
"""Flavor of Pulsar job runner with sensible defaults for message queue communication."""
use_mq = True
poll = False
destination_defaults = dict(
default_file_action="remote_transfer",
@@ -868,7 +889,7 @@ KUBERNETES_DESTINATION_DEFAULTS = {
"default_file_action": "remote_transfer",
"rewrite_parameters": "true",
"jobs_directory": "/pulsar_staging",
"pulsar_container_image": "galaxy/pulsar-pod-staging:0.13.0",
"pulsar_container_image": "galaxy/pulsar-pod-staging:0.14.0",
"remote_container_handling": True,
"k8s_enabled": True,
"url": PARAMETER_SPECIFICATION_IGNORED,
@@ -878,6 +899,7 @@ KUBERNETES_DESTINATION_DEFAULTS = {
class PulsarKubernetesJobRunner(PulsarMQJobRunner):
destination_defaults = KUBERNETES_DESTINATION_DEFAULTS
poll = True # Poll so we can check API for pod IP for ITs.
def _populate_parameter_defaults(self, job_destination):
super(PulsarKubernetesJobRunner, self)._populate_parameter_defaults(job_destination)
@@ -1,5 +1,7 @@
"""Interface layer for pykube library shared between Galaxy and Pulsar."""
import logging
import os
import re
import uuid
try:
@@ -17,8 +19,13 @@ except ImportError as exc:
'this feature, please install it or correct the '
'following error:\nImportError %s' % str(exc))
log = logging.getLogger(__name__)
DEFAULT_JOB_API_VERSION = "batch/v1"
DEFAULT_NAMESPACE = "default"
INSTANCE_ID_INVALID_MESSAGE = ("Galaxy instance [%s] is either too long "
"(>20 characters) or it includes non DNS "
"acceptable characters, ignoring it.")
def ensure_pykube():
@@ -61,6 +68,44 @@ def pull_policy(params):
return None
def find_job_object_by_name(pykube_api, job_name, namespace=None):
return _find_object_by_name(Job, pykube_api, job_name, namespace=namespace)
def find_pod_object_by_name(pykube_api, pod_name, namespace=None):
return _find_object_by_name(Pod, pykube_api, pod_name, namespace=namespace)
def _find_object_by_name(clazz, pykube_api, object_name, namespace=None):
filter_kwd = dict(selector="app=%s" % object_name)
if namespace is not None:
filter_kwd["namespace"] = namespace
objs = clazz.objects(pykube_api).filter(**filter_kwd)
obj = None
if len(objs.response['items']) > 0:
obj = clazz(pykube_api, objs.response['items'][0])
return obj
def stop_job(job, cleanup="always"):
job_failed = (job.obj['status']['failed'] > 0
if 'failed' in job.obj['status'] else False)
# Scale down the job just in case even if cleanup is never
job.scale(replicas=0)
api_delete = cleanup == "always"
if not api_delete and cleanup == "onsuccess" and not job_failed:
api_delete = True
if api_delete:
delete_options = {
"apiVersion": "v1",
"kind": "DeleteOptions",
"propagationPolicy": "Background"
}
r = job.api.delete(json=delete_options, **job.api_kwargs())
job.api.raise_for_status(r)
def job_object_dict(params, job_name, spec):
k8s_job_obj = {
"apiVersion": params.get('k8s_job_api_version', DEFAULT_JOB_API_VERSION),
@@ -77,13 +122,38 @@ def job_object_dict(params, job_name, spec):
return k8s_job_obj
def galaxy_instance_id(params):
"""Parse and validate the id of the Galaxy instance from supplied dict.
This will be added to Jobs and Pods names, so it needs to be DNS friendly,
this means: `The Internet standards (Requests for Comments) for protocols mandate that component hostname labels
may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9',
and the minus sign ('-').`
It looks for the value set on params['k8s_galaxy_instance_id'], which might or not be set. The
idea behind this is to allow the Galaxy instance to trust (or not) existing k8s Jobs and Pods that match the
setup of a Job that is being recovered or restarted after a downtime/reboot.
"""
if "k8s_galaxy_instance_id" in params:
raw_value = params['k8s_galaxy_instance_id']
if re.match(r"(?!-)[a-z\d-]{1,20}(?<!-)$", raw_value):
return raw_value
else:
log.error(INSTANCE_ID_INVALID_MESSAGE % raw_value)
return None
__all__ = (
"DEFAULT_JOB_API_VERSION",
"ensure_pykube",
"find_job_object_by_name",
"find_pod_object_by_name",
"galaxy_instance_id",
"Job",
"job_object_dict",
"Pod",
"produce_unique_k8s_job_name",
"pull_policy",
"pykube_client_from_dict",
"stop_job",
)
+1
View File
@@ -91,6 +91,7 @@ class ConfigSerializer(base.ModelSerializer):
'inactivity_box_content' : _use_config,
'visualizations_visible' : _use_config,
'interactivetools_enable' : _use_config,
'aws_estimate' : _use_config,
'message_box_content' : _use_config,
'message_box_visible' : _use_config,
'message_box_class' : _use_config,
+3 -3
View File
@@ -263,10 +263,10 @@ class InteractiveToolManager(object):
protocol = trans.request.host_url.split('//', 1)[0]
entry_point_encoded_id = trans.security.encode_id(entry_point.id)
entry_point_class = entry_point.__class__.__name__.lower()
entry_point_prefix = self.app.config.interactivetool_prefix
interactivetool_proxy_host = self.app.config.interactivetool_proxy_host or request_host
entry_point_prefix = self.app.config.interactivetools_prefix
interactivetools_proxy_host = self.app.config.interactivetools_proxy_host or request_host
rval = '%s//%s-%s.%s.%s.%s/' % (protocol, entry_point_encoded_id,
entry_point.token, entry_point_class, entry_point_prefix, interactivetool_proxy_host)
entry_point.token, entry_point_class, entry_point_prefix, interactivetools_proxy_host)
if entry_point.entry_url:
rval = '%s/%s' % (rval.rstrip('/'), entry_point.entry_url.lstrip('/'))
return rval
+14
View File
@@ -498,6 +498,20 @@ def summarize_job_metrics(trans, job):
return list(map(metric_to_dict, metrics))
def summarize_destination_params(trans, job):
"""Produce a dict-ified version of job destination parameters ready for tabular rendering.
Precondition: the caller has verified the job is accessible to the user
represented by the trans parameter.
"""
destination_params = {'Runner': job.job_runner_name,
'Runner Job ID': job.job_runner_external_id,
'Handler': job.handler}
destination_params.update(job.destination_params)
return destination_params
def summarize_job_parameters(trans, job):
"""Produce a dict-ified version of job parameters ready for tabular rendering.
+203 -151
View File
@@ -5,6 +5,7 @@ all providers ensure that data can be accessed on the filesystem for running
tools
"""
import abc
import logging
import os
import random
@@ -39,8 +40,9 @@ log = logging.getLogger(__name__)
class ObjectStore(object):
__metaclass__ = abc.ABCMeta
"""ObjectStore abstract interface.
"""ObjectStore interface.
FIELD DESCRIPTIONS (these apply to all the methods in this class):
@@ -82,6 +84,120 @@ class ObjectStore(object):
000/obj.id)
"""
@abc.abstractmethod
def exists(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None):
"""Return True if the object identified by `obj` exists, False otherwise."""
raise NotImplementedError()
@abc.abstractmethod
def create(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Mark the object (`obj`) as existing in the store, but with no content.
This method will create a proper directory structure for
the file if the directory does not already exist.
"""
raise NotImplementedError()
@abc.abstractmethod
def empty(self, obj, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Test if the object identified by `obj` has content.
If the object does not exist raises `ObjectNotFound`.
"""
raise NotImplementedError()
@abc.abstractmethod
def size(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Return size of the object identified by `obj`.
If the object does not exist, return 0.
"""
raise NotImplementedError()
@abc.abstractmethod
def delete(self, obj, entire_dir=False, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Delete the object identified by `obj`.
:type entire_dir: boolean
:param entire_dir: If True, delete the entire directory pointed to by
extra_dir. For safety reasons, this option applies
only for and in conjunction with the extra_dir or
obj_dir options.
"""
raise NotImplementedError()
@abc.abstractmethod
def get_data(self, obj, start=0, count=-1, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Fetch `count` bytes of data offset by `start` bytes using `obj.id`.
If the object does not exist raises `ObjectNotFound`.
:type start: int
:param start: Set the position to start reading the dataset file
:type count: int
:param count: Read at most `count` bytes from the dataset
"""
raise NotImplementedError()
@abc.abstractmethod
def get_filename(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Get the expected filename with absolute path for object with id `obj.id`.
This can be used to access the contents of the object.
"""
raise NotImplementedError()
@abc.abstractmethod
def update_from_file(self, obj, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False, file_name=None, create=False):
"""
Inform the store that the file associated with `obj.id` has been updated.
If `file_name` is provided, update from that file instead of the
default.
If the object does not exist raises `ObjectNotFound`.
:type file_name: string
:param file_name: Use file pointed to by `file_name` as the source for
updating the dataset identified by `obj`
:type create: boolean
:param create: If True and the default dataset does not exist, create
it first.
"""
raise NotImplementedError()
@abc.abstractmethod
def get_object_url(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Return the URL for direct acces if supported, otherwise return None.
Note: need to be careful to not bypass dataset security with this.
"""
raise NotImplementedError()
@abc.abstractmethod
def get_store_usage_percent(self):
"""Return the percentage indicating how full the store is."""
raise NotImplementedError()
@abc.abstractmethod
def get_store_by(self, obj):
"""Return how object is stored (by 'uuid', 'id', or None if not yet saved).
Certain Galaxy remote data features aren't available if objects are stored by 'id'.
"""
raise NotImplementedError()
class BaseObjectStore(ObjectStore):
def __init__(self, config, config_dict=None, **kwargs):
"""
:type config: object
@@ -111,10 +227,6 @@ class ObjectStore(object):
"""Close any connections for this ObjectStore."""
self.running = False
def exists(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None):
"""Return True if the object identified by `obj` exists, False otherwise."""
raise NotImplementedError()
def file_ready(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Check if a file corresponding to a dataset is ready to be used.
@@ -123,102 +235,6 @@ class ObjectStore(object):
"""
return True
def create(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Mark the object (`obj`) as existing in the store, but with no content.
This method will create a proper directory structure for
the file if the directory does not already exist.
"""
raise NotImplementedError()
def empty(self, obj, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Test if the object identified by `obj` has content.
If the object does not exist raises `ObjectNotFound`.
"""
raise NotImplementedError()
def size(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Return size of the object identified by `obj`.
If the object does not exist, return 0.
"""
raise NotImplementedError()
def delete(self, obj, entire_dir=False, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Delete the object identified by `obj`.
:type entire_dir: boolean
:param entire_dir: If True, delete the entire directory pointed to by
extra_dir. For safety reasons, this option applies
only for and in conjunction with the extra_dir or
obj_dir options.
"""
raise NotImplementedError()
def get_data(self, obj, start=0, count=-1, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Fetch `count` bytes of data offset by `start` bytes using `obj.id`.
If the object does not exist raises `ObjectNotFound`.
:type start: int
:param start: Set the position to start reading the dataset file
:type count: int
:param count: Read at most `count` bytes from the dataset
"""
raise NotImplementedError()
def get_filename(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Get the expected filename with absolute path for object with id `obj.id`.
This can be used to access the contents of the object.
"""
raise NotImplementedError()
def update_from_file(self, obj, base_dir=None, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False, file_name=None, create=False):
"""
Inform the store that the file associated with `obj.id` has been updated.
If `file_name` is provided, update from that file instead of the
default.
If the object does not exist raises `ObjectNotFound`.
:type file_name: string
:param file_name: Use file pointed to by `file_name` as the source for
updating the dataset identified by `obj`
:type create: boolean
:param create: If True and the default dataset does not exist, create
it first.
"""
raise NotImplementedError()
def get_object_url(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Return the URL for direct acces if supported, otherwise return None.
Note: need to be careful to not bypass dataset security with this.
"""
raise NotImplementedError()
def get_store_usage_percent(self):
"""Return the percentage indicating how full the store is."""
raise NotImplementedError()
def get_store_by(self, obj):
"""Return how object is stored (by 'uuid', 'id', or None if not yet saved).
Certain Galaxy remote data features aren't available if objects are stored by 'id'.
"""
raise NotImplementedError()
@classmethod
def parse_xml(clazz, config_xml):
"""Parse an XML description of a configuration for this object store.
@@ -251,8 +267,44 @@ class ObjectStore(object):
# job working directories.
return obj.id
def _invoke(self, delegate, obj=None, **kwargs):
return self.__getattribute__("_" + delegate)(obj=obj, **kwargs)
class ConcreteObjectStore(ObjectStore):
def exists(self, obj, **kwargs):
return self._invoke('exists', obj, **kwargs)
def create(self, obj, **kwargs):
return self._invoke('create', obj, **kwargs)
def empty(self, obj, **kwargs):
return self._invoke('empty', obj, **kwargs)
def size(self, obj, **kwargs):
return self._invoke('size', obj, **kwargs)
def delete(self, obj, **kwargs):
return self._invoke('delete', obj, **kwargs)
def get_data(self, obj, **kwargs):
return self._invoke('get_data', obj, **kwargs)
def get_filename(self, obj, **kwargs):
return self._invoke('get_filename', obj, **kwargs)
def update_from_file(self, obj, **kwargs):
return self._invoke('update_from_file', obj, **kwargs)
def get_object_url(self, obj, **kwargs):
return self._invoke('get_object_url', obj, **kwargs)
def get_store_usage_percent(self):
return self._invoke('get_store_usage_percent')
def get_store_by(self, obj, **kwargs):
return self._invoke('get_store_by', obj, **kwargs)
class ConcreteObjectStore(BaseObjectStore):
"""Subclass of ObjectStore for stores that don't delegate (non-nested).
Currently only adds store_by functionality. Which doesn't make
@@ -280,7 +332,7 @@ class ConcreteObjectStore(ObjectStore):
rval["store_by"] = self.store_by
return rval
def get_store_by(self, obj):
def _get_store_by(self, obj):
return self.store_by
@@ -343,7 +395,7 @@ class DiskObjectStore(ConcreteObjectStore):
as_dict["files_dir"] = self.file_path
return as_dict
def _get_filename(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
def __get_filename(self, obj, base_dir=None, dir_only=False, extra_dir=None, extra_dir_at_root=False, alt_name=None, obj_dir=False):
"""
Return the absolute path for the file corresponding to the `obj.id`.
@@ -425,7 +477,7 @@ class DiskObjectStore(ConcreteObjectStore):
path = os.path.join(path, alt_name if alt_name else "dataset_%s.dat" % obj_id)
return os.path.abspath(path)
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
"""Override `ObjectStore`'s stub and check on disk."""
if self.check_old_style:
path = self._construct_path(obj, old_style=True, **kwargs)
@@ -435,9 +487,9 @@ class DiskObjectStore(ConcreteObjectStore):
return True
return os.path.exists(self._construct_path(obj, **kwargs))
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
"""Override `ObjectStore`'s stub by creating any files and folders on disk."""
if not self.exists(obj, **kwargs):
if not self._exists(obj, **kwargs):
path = self._construct_path(obj, **kwargs)
dir_only = kwargs.get('dir_only', False)
# Create directory if it does not exist
@@ -448,18 +500,18 @@ class DiskObjectStore(ConcreteObjectStore):
open(path, 'w').close() # Should be rb?
umask_fix_perms(path, self.config.umask, 0o666)
def empty(self, obj, **kwargs):
def _empty(self, obj, **kwargs):
"""Override `ObjectStore`'s stub by checking file size on disk."""
return self.size(obj, **kwargs) == 0
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
"""Override `ObjectStore`'s stub by return file size on disk.
Returns 0 if the object doesn't exist yet or other error.
"""
if self.exists(obj, **kwargs):
if self._exists(obj, **kwargs):
try:
filepath = self.get_filename(obj, **kwargs)
filepath = self._get_filename(obj, **kwargs)
for _ in range(0, 2):
size = os.path.getsize(filepath)
if size != 0:
@@ -472,31 +524,31 @@ class DiskObjectStore(ConcreteObjectStore):
else:
return 0
def delete(self, obj, entire_dir=False, **kwargs):
def _delete(self, obj, entire_dir=False, **kwargs):
"""Override `ObjectStore`'s stub; delete the file or folder on disk."""
path = self.get_filename(obj, **kwargs)
path = self._get_filename(obj, **kwargs)
extra_dir = kwargs.get('extra_dir', None)
obj_dir = kwargs.get('obj_dir', False)
try:
if entire_dir and (extra_dir or obj_dir):
shutil.rmtree(path)
return True
if self.exists(obj, **kwargs):
if self._exists(obj, **kwargs):
os.remove(path)
return True
except OSError as ex:
log.critical('%s delete error %s' % (self._get_filename(obj, **kwargs), ex))
log.critical('%s delete error %s' % (self.__get_filename(obj, **kwargs), ex))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
"""Override `ObjectStore`'s stub; retrieve data directly from disk."""
data_file = open(self.get_filename(obj, **kwargs), 'r') # Should be rb?
data_file = open(self._get_filename(obj, **kwargs), 'r') # Should be rb?
data_file.seek(start)
content = data_file.read(count)
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
"""
Override `ObjectStore`'s stub.
@@ -514,27 +566,27 @@ class DiskObjectStore(ConcreteObjectStore):
raise ObjectNotFound
return path
def update_from_file(self, obj, file_name=None, create=False, **kwargs):
def _update_from_file(self, obj, file_name=None, create=False, **kwargs):
"""`create` parameter is not used in this implementation."""
preserve_symlinks = kwargs.pop('preserve_symlinks', False)
# FIXME: symlinks and the object store model may not play well together
# these should be handled better, e.g. registering the symlink'd file
# as an object
if create:
self.create(obj, **kwargs)
if file_name and self.exists(obj, **kwargs):
self._create(obj, **kwargs)
if file_name and self._exists(obj, **kwargs):
try:
if preserve_symlinks and os.path.islink(file_name):
force_symlink(os.readlink(file_name), self.get_filename(obj, **kwargs))
force_symlink(os.readlink(file_name), self._get_filename(obj, **kwargs))
else:
path = self.get_filename(obj, **kwargs)
path = self._get_filename(obj, **kwargs)
shutil.copy(file_name, path)
umask_fix_perms(path, self.config.umask, 0o666)
except IOError as ex:
log.critical('Error copying %s to %s: %s' % (file_name, self._get_filename(obj, **kwargs), ex))
log.critical('Error copying %s to %s: %s' % (file_name, self.__get_filename(obj, **kwargs), ex))
raise ex
def get_object_url(self, obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
"""
Override `ObjectStore`'s stub.
@@ -542,13 +594,13 @@ class DiskObjectStore(ConcreteObjectStore):
"""
return None
def get_store_usage_percent(self):
def _get_store_usage_percent(self, **kwargs):
"""Override `ObjectStore`'s stub by return percent storage used."""
st = os.statvfs(self.file_path)
return (float(st.f_blocks - st.f_bavail) / st.f_blocks) * 100
class NestedObjectStore(ObjectStore):
class NestedObjectStore(BaseObjectStore):
"""
Base for ObjectStores that use other ObjectStores.
@@ -567,51 +619,51 @@ class NestedObjectStore(ObjectStore):
store.shutdown()
super(NestedObjectStore, self).shutdown()
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
"""Determine if the `obj` exists in any of the backends."""
return self._call_method('exists', obj, False, False, **kwargs)
return self._call_method('_exists', obj, False, False, **kwargs)
def file_ready(self, obj, **kwargs):
"""Determine if the file for `obj` is ready to be used by any of the backends."""
return self._call_method('file_ready', obj, False, False, **kwargs)
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
"""Create a backing file in a random backend."""
random.choice(list(self.backends.values())).create(obj, **kwargs)
def empty(self, obj, **kwargs):
def _empty(self, obj, **kwargs):
"""For the first backend that has this `obj`, determine if it is empty."""
return self._call_method('empty', obj, True, False, **kwargs)
return self._call_method('_empty', obj, True, False, **kwargs)
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
"""For the first backend that has this `obj`, return its size."""
return self._call_method('size', obj, 0, False, **kwargs)
return self._call_method('_size', obj, 0, False, **kwargs)
def delete(self, obj, **kwargs):
def _delete(self, obj, **kwargs):
"""For the first backend that has this `obj`, delete it."""
return self._call_method('delete', obj, False, False, **kwargs)
return self._call_method('_delete', obj, False, False, **kwargs)
def get_data(self, obj, **kwargs):
def _get_data(self, obj, **kwargs):
"""For the first backend that has this `obj`, get data from it."""
return self._call_method('get_data', obj, ObjectNotFound, True, **kwargs)
return self._call_method('_get_data', obj, ObjectNotFound, True, **kwargs)
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
"""For the first backend that has this `obj`, get its filename."""
return self._call_method('get_filename', obj, ObjectNotFound, True, **kwargs)
return self._call_method('_get_filename', obj, ObjectNotFound, True, **kwargs)
def update_from_file(self, obj, **kwargs):
def _update_from_file(self, obj, **kwargs):
"""For the first backend that has this `obj`, update it from the given file."""
if kwargs.get('create', False):
self.create(obj, **kwargs)
self._create(obj, **kwargs)
kwargs['create'] = False
return self._call_method('update_from_file', obj, ObjectNotFound, True, **kwargs)
return self._call_method('_update_from_file', obj, ObjectNotFound, True, **kwargs)
def get_object_url(self, obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
"""For the first backend that has this `obj`, get its URL."""
return self._call_method('get_object_url', obj, None, False, **kwargs)
return self._call_method('_get_object_url', obj, None, False, **kwargs)
def get_store_by(self, obj):
return self._call_method('get_store_by', obj, None, False)
def _get_store_by(self, obj):
return self._call_method('_get_store_by', obj, None, False)
def _repr_object_for_exception(self, obj):
try:
@@ -776,9 +828,9 @@ class DistributedObjectStore(NestedObjectStore):
self.weighted_backend_ids = new_weighted_backend_ids
self.sleeper.sleep(120) # Test free space every 2 minutes
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
"""The only method in which obj.object_store_id may be None."""
if obj.object_store_id is None or not self.exists(obj, **kwargs):
if obj.object_store_id is None or not self._exists(obj, **kwargs):
if obj.object_store_id is None or obj.object_store_id not in self.backends:
try:
obj.object_store_id = random.choice(self.weighted_backend_ids)
@@ -865,14 +917,14 @@ class HierarchicalObjectStore(NestedObjectStore):
as_dict["backends"] = backends
return as_dict
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
"""Check all child object stores."""
for store in self.backends.values():
if store.exists(obj, **kwargs):
return True
return False
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
"""Call the primary object store."""
self.backends[0].create(obj, **kwargs)
+19 -19
View File
@@ -310,7 +310,7 @@ class AzureBlobObjectStore(ConcreteObjectStore):
# Public Methods #
##################
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
in_cache = in_azure = False
rel_path = self._construct_path(obj, **kwargs)
@@ -357,9 +357,9 @@ class AzureBlobObjectStore(ConcreteObjectStore):
return False
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
if not self.exists(obj, **kwargs):
if not self._exists(obj, **kwargs):
# Pull out locally used fields
extra_dir = kwargs.get('extra_dir', None)
@@ -393,25 +393,25 @@ class AzureBlobObjectStore(ConcreteObjectStore):
open(os.path.join(self.staging_path, rel_path), 'w').close()
self._push_to_os(rel_path, from_string='')
def empty(self, obj, **kwargs):
if self.exists(obj, **kwargs):
return bool(self.size(obj, **kwargs) > 0)
def _empty(self, obj, **kwargs):
if self._exists(obj, **kwargs):
return bool(self._size(obj, **kwargs) > 0)
else:
raise ObjectNotFound('objectstore.empty, object does not exist: %s, kwargs: %s' % (str(obj), str(kwargs)))
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
if self._in_cache(rel_path):
try:
return os.path.getsize(self._get_cache_path(rel_path))
except OSError as ex:
log.info("Could not get size of file '%s' in local cache, will try Azure. Error: %s", rel_path, ex)
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
return self._get_size_in_azure(rel_path)
log.warning("Did not find dataset '%s', returning 0 for size", rel_path)
return 0
def delete(self, obj, entire_dir=False, **kwargs):
def _delete(self, obj, entire_dir=False, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
extra_dir = kwargs.get('extra_dir', None)
base_dir = kwargs.get('base_dir', None)
@@ -445,10 +445,10 @@ class AzureBlobObjectStore(ConcreteObjectStore):
except AzureHttpError:
log.exception("Could not delete blob '%s' from Azure", rel_path)
except OSError:
log.exception('%s delete error', self.get_filename(obj, **kwargs))
log.exception('%s delete error', self._get_filename(obj, **kwargs))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Check cache first and get file if not there
if not self._in_cache(rel_path):
@@ -460,7 +460,7 @@ class AzureBlobObjectStore(ConcreteObjectStore):
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
base_dir = kwargs.get('base_dir', None)
dir_only = kwargs.get('dir_only', False)
@@ -483,7 +483,7 @@ class AzureBlobObjectStore(ConcreteObjectStore):
if self._in_cache(rel_path):
return cache_path
# Check if the file exists in persistent storage and, if it does, pull it into cache
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
if dir_only: # Directories do not get pulled into cache
return cache_path
else:
@@ -495,10 +495,10 @@ class AzureBlobObjectStore(ConcreteObjectStore):
# return cache_path
raise ObjectNotFound('objectstore.get_filename, no cache_path: %s, kwargs: %s' % (str(obj), str(kwargs)))
def update_from_file(self, obj, file_name=None, create=False, **kwargs):
def _update_from_file(self, obj, file_name=None, create=False, **kwargs):
if create is True:
self.create(obj, **kwargs)
elif self.exists(obj, **kwargs):
self._create(obj, **kwargs)
elif self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Chose whether to use the dataset file itself or an alternate file
if file_name:
@@ -520,8 +520,8 @@ class AzureBlobObjectStore(ConcreteObjectStore):
else:
raise ObjectNotFound('objectstore.update_from_file, object does not exist: %s, kwargs: %s' % (str(obj), str(kwargs)))
def get_object_url(self, obj, **kwargs):
if self.exists(obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
try:
url = self.service.make_blob_url(container_name=self.container_name, blob_name=rel_path)
@@ -530,7 +530,7 @@ class AzureBlobObjectStore(ConcreteObjectStore):
log.exception("Trouble generating URL for dataset '%s'", rel_path)
return None
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
return 0.0
##################
+19 -19
View File
@@ -510,7 +510,7 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
os.path.getsize(self._get_cache_path(rel_path)), self._get_size_in_cloud(rel_path))
return False
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
in_cache = False
rel_path = self._construct_path(obj, **kwargs)
@@ -543,8 +543,8 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
else:
return False
def create(self, obj, **kwargs):
if not self.exists(obj, **kwargs):
def _create(self, obj, **kwargs):
if not self._exists(obj, **kwargs):
# Pull out locally used fields
extra_dir = kwargs.get('extra_dir', None)
@@ -572,26 +572,26 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
open(os.path.join(self.staging_path, rel_path), 'w').close()
self._push_to_os(rel_path, from_string='')
def empty(self, obj, **kwargs):
if self.exists(obj, **kwargs):
return bool(self.size(obj, **kwargs) > 0)
def _empty(self, obj, **kwargs):
if self._exists(obj, **kwargs):
return bool(self._size(obj, **kwargs) > 0)
else:
raise ObjectNotFound('objectstore.empty, object does not exist: %s, kwargs: %s'
% (str(obj), str(kwargs)))
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
if self._in_cache(rel_path):
try:
return os.path.getsize(self._get_cache_path(rel_path))
except OSError as ex:
log.info("Could not get size of file '%s' in local cache, will try cloud. Error: %s", rel_path, ex)
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
return self._get_size_in_cloud(rel_path)
log.warning("Did not find dataset '%s', returning 0 for size", rel_path)
return 0
def delete(self, obj, entire_dir=False, **kwargs):
def _delete(self, obj, entire_dir=False, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
extra_dir = kwargs.get('extra_dir', None)
base_dir = kwargs.get('base_dir', None)
@@ -626,10 +626,10 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
except Exception:
log.exception("Could not delete key '%s' from cloud", rel_path)
except OSError:
log.exception('%s delete error', self.get_filename(obj, **kwargs))
log.exception('%s delete error', self._get_filename(obj, **kwargs))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Check cache first and get file if not there
if not self._in_cache(rel_path):
@@ -641,7 +641,7 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
base_dir = kwargs.get('base_dir', None)
dir_only = kwargs.get('dir_only', False)
obj_dir = kwargs.get('obj_dir', False)
@@ -664,7 +664,7 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
if self._in_cache(rel_path):
return cache_path
# Check if the file exists in persistent storage and, if it does, pull it into cache
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
if dir_only: # Directories do not get pulled into cache
return cache_path
else:
@@ -678,10 +678,10 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
% (str(obj), str(kwargs)))
# return cache_path # Until the upload tool does not explicitly create the dataset, return expected path
def update_from_file(self, obj, file_name=None, create=False, **kwargs):
def _update_from_file(self, obj, file_name=None, create=False, **kwargs):
if create:
self.create(obj, **kwargs)
if self.exists(obj, **kwargs):
self._create(obj, **kwargs)
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Chose whether to use the dataset file itself or an alternate file
if file_name:
@@ -703,8 +703,8 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
raise ObjectNotFound('objectstore.update_from_file, object does not exist: %s, kwargs: %s'
% (str(obj), str(kwargs)))
def get_object_url(self, obj, **kwargs):
if self.exists(obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
try:
key = self.bucket.objects.get(rel_path)
@@ -713,5 +713,5 @@ class Cloud(ConcreteObjectStore, CloudConfigMixin):
log.exception("Trouble generating URL for dataset '%s'", rel_path)
return None
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
return 0.0
+19 -19
View File
@@ -420,7 +420,7 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
os.path.getsize(self._get_cache_path(rel_path)), self._get_size_in_irods(rel_path))
return False
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
in_cache = in_irods = False
rel_path = self._construct_path(obj, **kwargs)
@@ -451,8 +451,8 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
else:
return False
def create(self, obj, **kwargs):
if not self.exists(obj, **kwargs):
def _create(self, obj, **kwargs):
if not self._exists(obj, **kwargs):
# Pull out locally used fields
extra_dir = kwargs.get('extra_dir', None)
extra_dir_at_root = kwargs.get('extra_dir_at_root', False)
@@ -479,26 +479,26 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
open(os.path.join(self.staging_path, rel_path), 'w').close()
self._push_to_irods(rel_path, from_string='')
def empty(self, obj, **kwargs):
if self.exists(obj, **kwargs):
return bool(self.size(obj, **kwargs) > 0)
def _empty(self, obj, **kwargs):
if self._exists(obj, **kwargs):
return bool(self._size(obj, **kwargs) > 0)
else:
raise ObjectNotFound('objectstore.empty, object does not exist: %s, kwargs: %s'
% (str(obj), str(kwargs)))
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
if self._in_cache(rel_path):
try:
return os.path.getsize(self._get_cache_path(rel_path))
except OSError as ex:
log.info("Could not get size of file '%s' in local cache, will try S3. Error: %s", rel_path, ex)
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
return self._get_size_in_irods(rel_path)
log.warning("Did not find dataset '%s', returning 0 for size", rel_path)
return 0
def delete(self, obj, entire_dir=False, **kwargs):
def _delete(self, obj, entire_dir=False, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
extra_dir = kwargs.get('extra_dir', None)
base_dir = kwargs.get('base_dir', None)
@@ -558,10 +558,10 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
return True
except OSError:
log.exception('%s delete error', self.get_filename(obj, **kwargs))
log.exception('%s delete error', self._get_filename(obj, **kwargs))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Check cache first and get file if not there
if not self._in_cache(rel_path):
@@ -573,7 +573,7 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
base_dir = kwargs.get('base_dir', None)
dir_only = kwargs.get('dir_only', False)
obj_dir = kwargs.get('obj_dir', False)
@@ -596,7 +596,7 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
if self._in_cache(rel_path):
return cache_path
# Check if the file exists in persistent storage and, if it does, pull it into cache
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
if dir_only: # Directories do not get pulled into cache
return cache_path
else:
@@ -610,10 +610,10 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
% (str(obj), str(kwargs)))
# return cache_path # Until the upload tool does not explicitly create the dataset, return expected path
def update_from_file(self, obj, file_name=None, create=False, **kwargs):
def _update_from_file(self, obj, file_name=None, create=False, **kwargs):
if create:
self.create(obj, **kwargs)
if self.exists(obj, **kwargs):
self._create(obj, **kwargs)
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Chose whether to use the dataset file itself or an alternate file
if file_name:
@@ -636,8 +636,8 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
% (str(obj), str(kwargs)))
# Unlike S3, url is not really applicable to iRODS
def get_object_url(self, obj, **kwargs):
if self.exists(obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
p = Path(rel_path)
@@ -649,5 +649,5 @@ class IRODSObjectStore(DiskObjectStore, CloudConfigMixin):
return data_object_path
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
return 0.0
+18 -18
View File
@@ -221,7 +221,7 @@ class PithosObjectStore(ConcreteObjectStore):
# No need to overwrite "shutdown"
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
"""Check if file exists, fix if file in cache and not on Pithos+
:returns: weather the file exists remotely or in cache
"""
@@ -253,9 +253,9 @@ class PithosObjectStore(ConcreteObjectStore):
return True
return False
def create(self, obj, **kwargs):
def _create(self, obj, **kwargs):
"""Touch a file (aka create empty), if it doesn't exist"""
if not self.exists(obj, **kwargs):
if not self._exists(obj, **kwargs):
# Pull out locally used fields
extra_dir = kwargs.get('extra_dir', None)
extra_dir_at_root = kwargs.get('extra_dir_at_root', False)
@@ -288,18 +288,18 @@ class PithosObjectStore(ConcreteObjectStore):
open(new_file, 'w').close()
self.pithos.upload_from_string(rel_path, '')
def empty(self, obj, **kwargs):
def _empty(self, obj, **kwargs):
"""
:returns: weather the object has content
:raises ObjectNotFound:
"""
if not self.exists(obj, **kwargs):
if not self._exists(obj, **kwargs):
raise ObjectNotFound(
'objectstore.empty, object does not exist: {obj}, '
'kwargs: {kwargs}'.format(obj=obj, kwargs=kwargs))
return bool(self.size(obj, **kwargs))
return bool(self._size(obj, **kwargs))
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
"""
:returns: The size of the object, or 0 if it doesn't exist (sorry for
that, not our fault, the ObjectStore interface is like that some
@@ -321,7 +321,7 @@ class PithosObjectStore(ConcreteObjectStore):
return 0
return int(file['content-length'])
def delete(self, obj, **kwargs):
def _delete(self, obj, **kwargs):
"""Delete the object
:returns: weather the object was deleted
"""
@@ -347,13 +347,13 @@ class PithosObjectStore(ConcreteObjectStore):
self.pithos.del_object(path)
except OSError:
log.exception(
'{0} delete error'.format(self.get_filename(obj, **kwargs)))
'{0} delete error'.format(self._get_filename(obj, **kwargs)))
except ClientError as ce:
log.exception('Could not delete {path} from Pithos, {err}'.format(
path=path, err=ce))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
"""Fetch (e.g., download) data
:param start: Chunk of data starts here
:param count: Fetch at most as many data, fetch all if negative
@@ -369,7 +369,7 @@ class PithosObjectStore(ConcreteObjectStore):
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
"""Get the expected filename with absolute path"""
base_dir = kwargs.get('base_dir', None)
dir_only = kwargs.get('dir_only', False)
@@ -386,7 +386,7 @@ class PithosObjectStore(ConcreteObjectStore):
return cache_path
if self._in_cache(path):
return cache_path
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
if not dir_only:
self._pull_into_cache(path)
return cache_path
@@ -394,11 +394,11 @@ class PithosObjectStore(ConcreteObjectStore):
'objectstore.get_filename, no cache_path: {obj}, '
'kwargs: {kwargs}'.format(obj, kwargs))
def update_from_file(self, obj, **kwargs):
def _update_from_file(self, obj, **kwargs):
"""Update the store when a file is updated"""
if kwargs.get('create'):
self.create(obj, **kwargs)
if not self.exists(obj, **kwargs):
self._create(obj, **kwargs)
if not self._exists(obj, **kwargs):
raise ObjectNotFound(
'objectstore.update_from_file, object does not exist: {obj}, '
'kwargs: {kwargs}'.format(obj, kwargs))
@@ -420,11 +420,11 @@ class PithosObjectStore(ConcreteObjectStore):
with open(cache_path) as f:
self.pithos.upload_object(obj, f)
def get_object_url(self, obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
"""
:returns: URL for direct access, None if no object
"""
if self.exists(obj, **kwargs):
if self._exists(obj, **kwargs):
path = self._construct_path(obj, **kwargs)
try:
return self.pithos.publish_object(path)
@@ -434,7 +434,7 @@ class PithosObjectStore(ConcreteObjectStore):
log.exception('Kamaki: {0}'.format(ce))
return None
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
"""
:returns: percentage indicating how full the store is
"""
+12 -12
View File
@@ -1,6 +1,6 @@
from __future__ import absolute_import # Need to import pulsar_client absolutely.
from ..objectstore import ObjectStore
from ..objectstore import BaseObjectStore
try:
from pulsar.client.manager import ObjectStoreClientManager
@@ -8,7 +8,7 @@ except ImportError:
ObjectStoreClientManager = None
class PulsarObjectStore(ObjectStore):
class PulsarObjectStore(BaseObjectStore):
"""
Object store implementation that delegates to a remote Pulsar server.
@@ -26,38 +26,38 @@ class PulsarObjectStore(ObjectStore):
def __init__(self, config, config_xml):
self.pulsar_client = self.__build_pulsar_client(config_xml)
def exists(self, obj, **kwds):
def _exists(self, obj, **kwds):
return self.pulsar_client.exists(**self.__build_kwds(obj, **kwds))
def file_ready(self, obj, **kwds):
return self.pulsar_client.file_ready(**self.__build_kwds(obj, **kwds))
def create(self, obj, **kwds):
def _create(self, obj, **kwds):
return self.pulsar_client.create(**self.__build_kwds(obj, **kwds))
def empty(self, obj, **kwds):
def _empty(self, obj, **kwds):
return self.pulsar_client.empty(**self.__build_kwds(obj, **kwds))
def size(self, obj, **kwds):
def _size(self, obj, **kwds):
return self.pulsar_client.size(**self.__build_kwds(obj, **kwds))
def delete(self, obj, **kwds):
def _delete(self, obj, **kwds):
return self.pulsar_client.delete(**self.__build_kwds(obj, **kwds))
# TODO: Optimize get_data.
def get_data(self, obj, **kwds):
def _get_data(self, obj, **kwds):
return self.pulsar_client.get_data(**self.__build_kwds(obj, **kwds))
def get_filename(self, obj, **kwds):
def _get_filename(self, obj, **kwds):
return self.pulsar_client.get_filename(**self.__build_kwds(obj, **kwds))
def update_from_file(self, obj, **kwds):
def _update_from_file(self, obj, **kwds):
return self.pulsar_client.update_from_file(**self.__build_kwds(obj, **kwds))
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
return self.pulsar_client.get_store_usage_percent()
def get_object_url(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None):
def _get_object_url(self, obj, extra_dir=None, extra_dir_at_root=False, alt_name=None):
return None
def __build_kwds(self, obj, **kwds):
+19 -19
View File
@@ -504,7 +504,7 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
os.path.getsize(self._get_cache_path(rel_path)), self._get_size_in_s3(rel_path))
return False
def exists(self, obj, **kwargs):
def _exists(self, obj, **kwargs):
in_cache = in_s3 = False
rel_path = self._construct_path(obj, **kwargs)
@@ -537,8 +537,8 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
else:
return False
def create(self, obj, **kwargs):
if not self.exists(obj, **kwargs):
def _create(self, obj, **kwargs):
if not self._exists(obj, **kwargs):
# Pull out locally used fields
extra_dir = kwargs.get('extra_dir', None)
@@ -572,26 +572,26 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
open(os.path.join(self.staging_path, rel_path), 'w').close()
self._push_to_os(rel_path, from_string='')
def empty(self, obj, **kwargs):
if self.exists(obj, **kwargs):
return bool(self.size(obj, **kwargs) > 0)
def _empty(self, obj, **kwargs):
if self._exists(obj, **kwargs):
return bool(self._size(obj, **kwargs) > 0)
else:
raise ObjectNotFound('objectstore.empty, object does not exist: %s, kwargs: %s'
% (str(obj), str(kwargs)))
def size(self, obj, **kwargs):
def _size(self, obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
if self._in_cache(rel_path):
try:
return os.path.getsize(self._get_cache_path(rel_path))
except OSError as ex:
log.info("Could not get size of file '%s' in local cache, will try S3. Error: %s", rel_path, ex)
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
return self._get_size_in_s3(rel_path)
log.warning("Did not find dataset '%s', returning 0 for size", rel_path)
return 0
def delete(self, obj, entire_dir=False, **kwargs):
def _delete(self, obj, entire_dir=False, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
extra_dir = kwargs.get('extra_dir', None)
base_dir = kwargs.get('base_dir', None)
@@ -626,10 +626,10 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
except S3ResponseError:
log.exception("Could not delete key '%s' from S3", rel_path)
except OSError:
log.exception('%s delete error', self.get_filename(obj, **kwargs))
log.exception('%s delete error', self._get_filename(obj, **kwargs))
return False
def get_data(self, obj, start=0, count=-1, **kwargs):
def _get_data(self, obj, start=0, count=-1, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Check cache first and get file if not there
if not self._in_cache(rel_path):
@@ -641,7 +641,7 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
data_file.close()
return content
def get_filename(self, obj, **kwargs):
def _get_filename(self, obj, **kwargs):
base_dir = kwargs.get('base_dir', None)
dir_only = kwargs.get('dir_only', False)
obj_dir = kwargs.get('obj_dir', False)
@@ -664,7 +664,7 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
if self._in_cache(rel_path):
return cache_path
# Check if the file exists in persistent storage and, if it does, pull it into cache
elif self.exists(obj, **kwargs):
elif self._exists(obj, **kwargs):
if dir_only: # Directories do not get pulled into cache
return cache_path
else:
@@ -678,10 +678,10 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
% (str(obj), str(kwargs)))
# return cache_path # Until the upload tool does not explicitly create the dataset, return expected path
def update_from_file(self, obj, file_name=None, create=False, **kwargs):
def _update_from_file(self, obj, file_name=None, create=False, **kwargs):
if create:
self.create(obj, **kwargs)
if self.exists(obj, **kwargs):
self._create(obj, **kwargs)
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
# Chose whether to use the dataset file itself or an alternate file
if file_name:
@@ -703,8 +703,8 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
raise ObjectNotFound('objectstore.update_from_file, object does not exist: %s, kwargs: %s'
% (str(obj), str(kwargs)))
def get_object_url(self, obj, **kwargs):
if self.exists(obj, **kwargs):
def _get_object_url(self, obj, **kwargs):
if self._exists(obj, **kwargs):
rel_path = self._construct_path(obj, **kwargs)
try:
key = Key(self._bucket, rel_path)
@@ -713,7 +713,7 @@ class S3ObjectStore(ConcreteObjectStore, CloudConfigMixin):
log.exception("Trouble generating URL for dataset '%s'", rel_path)
return None
def get_store_usage_percent(self):
def _get_store_usage_percent(self):
return 0.0
def shutdown(self):
+8 -35
View File
@@ -1,12 +1,6 @@
import hashlib
import hmac
from base64 import b64encode
from itertools import starmap
from operator import xor
from os import urandom
from struct import Struct
import six
from galaxy.util import (
safe_str_cmp,
@@ -17,7 +11,7 @@ from galaxy.util import (
SALT_LENGTH = 12
KEY_LENGTH = 24
HASH_FUNCTION = 'sha256'
COST_FACTOR = 10000
COST_FACTOR = 100000
def hash_password(password):
@@ -47,7 +41,7 @@ def hash_password_PBKDF2(password):
# Generate a random salt
salt = b64encode(urandom(SALT_LENGTH))
# Apply the pbkdf2 encoding
hashed_password = pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH, getattr(hashlib, HASH_FUNCTION))
hashed_password = pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH, HASH_FUNCTION)
encoded_password = unicodify(b64encode(hashed_password))
# Format
return 'PBKDF2${0}${1}${2}${3}'.format(HASH_FUNCTION, COST_FACTOR, unicodify(salt), encoded_password)
@@ -57,39 +51,18 @@ def check_password_PBKDF2(guess, hashed):
# Split the database representation to extract cost_factor and salt
name, hash_function, cost_factor, salt, encoded_original = hashed.split('$', 5)
# Hash the guess using the same parameters
hashed_guess = pbkdf2_bin(guess, salt, int(cost_factor), KEY_LENGTH, getattr(hashlib, hash_function))
hashed_guess = pbkdf2_bin(guess, salt, int(cost_factor), KEY_LENGTH, hash_function)
encoded_guess = unicodify(b64encode(hashed_guess))
return safe_str_cmp(encoded_original, encoded_guess)
# Taken from https://github.com/mitsuhiko/python-pbkdf2/blob/master/pbkdf2.py
# (c) Copyright 2011 by Armin Ronacher, BSD LICENSE
_pack_int = Struct('>I').pack
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
def pbkdf2_bin(data, salt, iterations=COST_FACTOR, keylen=KEY_LENGTH, hashfunc=HASH_FUNCTION):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
key of `keylen` bytes. By default SHA-256 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(smart_str(data), None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
digest = h.digest()
if six.PY2:
return digest, [ord(_) for _ in digest]
return digest, digest
buf = []
data = smart_str(data)
salt = smart_str(salt)
for block in range(1, -(-keylen // mac.digest_size) + 1):
digest, rv = _pseudorandom(salt + _pack_int(block))
for _ in range(iterations - 1):
digest, u = _pseudorandom(digest)
rv = starmap(xor, zip(rv, u))
buf.extend(rv)
return bytes(bytearray(buf))[:keylen]
return hashlib.pbkdf2_hmac(hashfunc, data, salt, iterations, keylen)

Some files were not shown because too many files have changed in this diff Show More