diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..1eb072b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ +* flowsym version: +* Python version: +* Operating System: + +### Description + +Describe what you were trying to get done. +Tell us what happened, what went wrong, and what you expected to happen. + +### What I Did + +``` +Paste the command(s) you ran and the output. +If there was a crash, please include the traceback here. +``` diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43091aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE settings +.vscode/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.ipynb_checkpoints/facsim-checkpoint.py b/.ipynb_checkpoints/facsim-checkpoint.py deleted file mode 100644 index 704c247..0000000 --- a/.ipynb_checkpoints/facsim-checkpoint.py +++ /dev/null @@ -1,318 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Jan 20 09:57:16 2020 - -:author: Michael -:author: Luis -""" - -# Check to see if fcsy is installed on machine -import importlib.util - -package_name = 'fcsy' -spec = importlib.util.find_spec(package_name) -if spec is None: - print( - f"{package_name} is not installed, please install {package_name} to write fcs files in the \'measure\' function!") - -import numpy as np -import pandas as pd -import time -from fcsy.fcs import write_fcs - -# from __init__ import spectrum_data - -# Temp - init file in same directory screws up pytest run -spectrum_data = pd.read_csv( - 'data/FPbase_Spectra_updated.csv').fillna(value=0) - - -def create_controls(size, colors=['Blue', 'Cyan', 'Green', 'Yellow', 'Orange', 'Red', 'Far_red', 'NIR', 'IR']): - """ - This is a function that takes a DataFrame size (i.e. number of controls) and - a list of colors the user wants to run controls for. - :param size: - :param colors: - :return: - """ - - # Check to make sure the inputs were of correct type - if type(size) != int: - raise TypeError("size cannot be of type: " + str(type(size))) - elif type(colors) != list: - raise TypeError("Ex cannot be of type: " + str(type(colors))) - - # Controls data - accept whatever colors the user provides - controls_dict = {} - for i in colors: - controls_dict[i] = {'Wavelength': [], 'Excitation Efficiency': [], 'Emission Efficiency': []} - - # Make excitation and emission data easier to read in to dictionary - wavelengths = spectrum_data['Wavelength'] - - green_ex_efficiency = spectrum_data['Fluorescein (FITC) EX'] - red_ex_efficiency = spectrum_data['Kaede (Red) EX'] - blue_ex_efficiency = spectrum_data['Pacific Blue EX'] - far_red_ex_efficiency = spectrum_data['APC (allophycocyanin) AB'] - NIR_ex_efficiency = spectrum_data['PerCP-Cy5.5 AB'] - IR_ex_efficiency = spectrum_data['APC/Cy7 EX'] - cyan_ex_efficiency = spectrum_data['CFP EX'] - yellow_ex_efficiency = spectrum_data['EYFP EX'] - orange_ex_efficiency = spectrum_data['mOrange EX'] - - # Excitation and emission data for each color control - pre-defined information - excitation_dict = {'green': [list(wavelengths), list(green_ex_efficiency)], - 'red': [list(wavelengths), list(red_ex_efficiency)], - 'blue': [list(wavelengths), list(blue_ex_efficiency)], - 'far_red': [list(wavelengths), list(far_red_ex_efficiency)], - 'nir': [list(wavelengths), list(NIR_ex_efficiency)], - 'ir': [list(wavelengths), list(IR_ex_efficiency)], - 'cyan': [list(wavelengths), list(cyan_ex_efficiency)], - 'yellow': [list(wavelengths), list(yellow_ex_efficiency)], - 'orange': [list(wavelengths), list(orange_ex_efficiency)]} - - # Make excitation and emission data easier to read in to dictionary - green_em_efficiency = spectrum_data['Fluorescein (FITC) EM'] - red_em_efficiency = spectrum_data['Kaede (Red) EM'] - blue_em_efficiency = spectrum_data['Pacific Blue EM'] - far_red_em_efficiency = spectrum_data['APC (allophycocyanin) EM'] - NIR_em_efficiency = spectrum_data['PerCP-Cy5.5 EM'] - IR_em_efficiency = spectrum_data['APC/Cy7 EM'] - cyan_em_efficiency = spectrum_data['CFP EM'] - yellow_em_efficiency = spectrum_data['EYFP EM'] - orange_em_efficiency = spectrum_data['mOrange EM'] - - # Excitation and emission data for each color control - pre-defined information - emission_dict = {'green': [list(wavelengths), list(green_em_efficiency)], - 'red': [list(wavelengths), list(red_em_efficiency)], - 'blue': [list(wavelengths), list(blue_em_efficiency)], - 'far_red': [list(wavelengths), list(far_red_em_efficiency)], - 'nir': [list(wavelengths), list(NIR_em_efficiency)], - 'ir': [list(wavelengths), list(IR_em_efficiency)], - 'cyan': [list(wavelengths), list(cyan_em_efficiency)], - 'yellow': [list(wavelengths), list(yellow_em_efficiency)], - 'orange': [list(wavelengths), list(orange_em_efficiency)]} - - # Match colors that the user wants to excitation and emission data - for key, value in controls_dict.items(): - key = key.lower() # Doesn't matter if user entered capital letters or not - if key in excitation_dict: - value['Wavelength'] = [excitation_dict[key][0]] - value['Excitation Efficiency'] = [excitation_dict[key][1]] - value['Emission Efficiency'] = [emission_dict[key][1]] - - else: - raise NameError(str(key) + ' is not an available control, try: ' + - str(list(excitation_dict.keys()))) - - # Create a new dictionary that will keep the associated colors with dataframe objects - results_dict = {} - for key, value in controls_dict.items(): - results_dict[key] = pd.DataFrame(value) - - # Finally, create a list that will hold all DFs while preserving color order - final_control_results = [] - for i in colors: - final_control_results.append(pd.concat([results_dict[i]] * size, ignore_index=True)) - - # Return tuple of the list for easy access of colors - return tuple(final_control_results) - - -def create_sample(size, colors=['Blue', 'Cyan', 'Green', 'Yellow', 'Orange', 'Red', 'Far_red', 'NIR', 'IR'], - weights=[]): - """ - This is a function that takes a defined dataframe length for number of samples (int) - and excitation and emission wavelengths (list,list). Assumes equal probability of each - color unless specified by the user - :param size: - :param colors: - :param weights: - :return: - """ - - - # Check to make sure the inputs were of correct type - if type(size) != int: - raise TypeError("size cannot be of type: " + str(type(size))) - elif type(colors) != list: - raise TypeError("Ex cannot be of type: " + str(type(colors))) - - # Make excitation and emission data easier to read in to dictionary - wavelengths = spectrum_data['Wavelength'] - - green_ex_efficiency = spectrum_data['Fluorescein (FITC) EX'] - red_ex_efficiency = spectrum_data['Kaede (Red) EX'] - blue_ex_efficiency = spectrum_data['Pacific Blue EX'] - far_red_ex_efficiency = spectrum_data['APC (allophycocyanin) AB'] - NIR_ex_efficiency = spectrum_data['PerCP-Cy5.5 AB'] - IR_ex_efficiency = spectrum_data['APC/Cy7 EX'] - cyan_ex_efficiency = spectrum_data['CFP EX'] - yellow_ex_efficiency = spectrum_data['EYFP EX'] - orange_ex_efficiency = spectrum_data['mOrange EX'] - - # Excitation and emission data for each color control - pre-defined information - excitation_dict = {'green': [list(wavelengths), list(green_ex_efficiency)], - 'red': [list(wavelengths), list(red_ex_efficiency)], - 'blue': [list(wavelengths), list(blue_ex_efficiency)], - 'far_red': [list(wavelengths), list(far_red_ex_efficiency)], - 'nir': [list(wavelengths), list(NIR_ex_efficiency)], - 'ir': [list(wavelengths), list(IR_ex_efficiency)], - 'cyan': [list(wavelengths), list(cyan_ex_efficiency)], - 'yellow': [list(wavelengths), list(yellow_ex_efficiency)], - 'orange': [list(wavelengths), list(orange_ex_efficiency)]} - - # Make excitation and emission data easier to read in to dictionary - green_em_efficiency = spectrum_data['Fluorescein (FITC) EM'] - red_em_efficiency = spectrum_data['Kaede (Red) EM'] - blue_em_efficiency = spectrum_data['Pacific Blue EM'] - far_red_em_efficiency = spectrum_data['APC (allophycocyanin) EM'] - NIR_em_efficiency = spectrum_data['PerCP-Cy5.5 EM'] - IR_em_efficiency = spectrum_data['APC/Cy7 EM'] - cyan_em_efficiency = spectrum_data['CFP EM'] - yellow_em_efficiency = spectrum_data['EYFP EM'] - orange_em_efficiency = spectrum_data['mOrange EM'] - - # Excitation and emission data for each color control - pre-defined information - emission_dict = {'green': [list(wavelengths), list(green_em_efficiency)], - 'red': [list(wavelengths), list(red_em_efficiency)], - 'blue': [list(wavelengths), list(blue_em_efficiency)], - 'far_red': [list(wavelengths), list(far_red_em_efficiency)], - 'nir': [list(wavelengths), list(NIR_em_efficiency)], - 'ir': [list(wavelengths), list(IR_em_efficiency)], - 'cyan': [list(wavelengths), list(cyan_em_efficiency)], - 'yellow': [list(wavelengths), list(yellow_em_efficiency)], - 'orange': [list(wavelengths), list(orange_em_efficiency)]} - - # Set dictionary to be made into dataframe - sample_dict = {'Wavelength': [], 'Excitation Efficiency': [], 'Emission Efficiency': []} - - # Make "size" number of cell entries - for i in range(size): - if len(weights) == 0: - color_to_pick = np.random.choice(colors).lower() - else: - color_to_pick = np.random.choice(colors, p=weights).lower() - - sample_dict['Wavelength'].append(excitation_dict[color_to_pick][0]) - sample_dict['Excitation Efficiency'].append(excitation_dict[color_to_pick][1]) - sample_dict['Emission Efficiency'].append(emission_dict[color_to_pick][1]) - - data = pd.DataFrame(sample_dict) - - # Create protein copy number - copies = np.round(np.random.normal(100, size=len(data), scale=20)) - data['Copy number'] = copies - - # Return just the sample dataframe - return data - - -# Bandwidth on lasers is +-5 nm. channels are [450+-25, 525+-25, 600+-30, 665+-15, 720+-30, 785+-30] for filter set 2 -def measure(dataframe, lasers=[405, 488, 561, 638], channels=[1, 2, 3, 4, 5, 6], - create_fcs=True, outfile_name='data/sample_output.fcs'): - """ - This is a function that will measure fluorescence intensity for any given sample - DataFrame and laser/channel parameters. Output will be an fcs file (default) that is - the same size as the sample you ran in the function. Alternatively, you can return - just a pandas DataFrame object by setting return_fcs=False. The user can set the output - file name manually to simulate creating multiple samples and measurements. - """ - # Bandwidth for each fluorescence channel - channels_information = {1: list(range(425, 475)), 2: list(range(500, 550)), 3: list(range(570, 630)), - 4: list(range(650, 680)), - 5: list(range(690, 750)), 6: list(range(755, 805))} - - # This is the list that will hold all of the intensity vectors for each cell - new_dataframe_list = [['FL' + str(i) for i in channels]] - - # where are our laser wavelengths in our input dataframe? - laser_indices = {} - - # For each laser, find the indices for their wavelengths and their gaussian efficiencies - for laser in lasers: - # This part makes a gaussian distribution of each laser+-5 - counts_dict = {} - myarray = np.array(np.round(np.random.normal(loc=laser, scale=2.0, size=10000))) - new_array = [x for x in myarray if laser + 5 >= x >= laser - 5] - - for i in new_array: - if i not in counts_dict.keys(): - counts_dict[i] = list(new_array).count(i) - - max_count = max(counts_dict.values()) - - for key, value in counts_dict.items(): - counts_dict[key] = value / max_count - - # Find the wavelength indices that our lasers hit - make a dictionary with indices as keys and laser - # efficiencies as values - for index2, wave in enumerate(dataframe['Wavelength'][0]): - if wave in counts_dict.keys(): - laser_indices[index2] = counts_dict[wave] - - # figure out unique emission profiles based on color so we know when to end the loop - copy = dataframe.copy() - copy['Emission Efficiency'] = copy['Emission Efficiency'].astype(str) - - # Create numpy arrays to randomly sample from based on the number of excited molecules - emission_reference = {} - - for index, row in dataframe.iterrows(): - if str(row['Emission Efficiency']) not in emission_reference.keys(): - waves_to_add = np.array([round(value * 100) * [row['Wavelength'][index]] for index, value in - enumerate(row['Emission Efficiency']) if value >= 0.01]) - emission_reference[str(row['Emission Efficiency'])] = np.array([y for x in waves_to_add for y in x]) - - if len(emission_reference.keys()) == len(copy['Emission Efficiency'].unique()): - break - - # for each cell that is being analyzed - for index, row in dataframe.iterrows(): - intensity_vector = [] - - # Calculate peak excitation efficiency for our cell given all lasers at once (collinear laser set up) - excitation_max = max([row['Excitation Efficiency'][key] * value for key, value in laser_indices.items()]) - num_excited_proteins = round(row['Copy number'] * excitation_max) - - # Sample emission at wavelengths corresponding to real emission efficiency from FPbase, size=number of - # excited proteins - real_emission_wavelengths = np.random.choice(emission_reference[str(row['Emission Efficiency'])], - size=num_excited_proteins) - - # amp = np.random.choice(list(range(1000,1700,40))) - # For each fluorescence channel, find the appropriate emission values - for channel in channels: - em_chan = channels_information[channel] - - # Find intensity in each channel - NOTE using intersection and set here speed up the code DRAMATICALLY - emission_intensity = len(set(real_emission_wavelengths).intersection(em_chan)) * ( - 1000 + np.random.normal(0, scale=50)) # Average amplification +- noise - - # add intensity in each channel to the vector - intensity_vector.append(float(emission_intensity)) - - new_dataframe_list.append(intensity_vector) - - column_names = new_dataframe_list.pop(0) - - # Create new dataframe and output - output = pd.DataFrame(new_dataframe_list, columns=column_names) - - if create_fcs: - write_fcs(output, outfile_name) - print("FCS file created with filename: " + str(outfile_name)) - - return output - - -# Run the code outside of defining functions -if __name__ == "__main__": - sample_size = 1000 - - sample = create_sample(sample_size) - - start = time.time() - measurements = measure(sample) - stop = time.time() - print("Time to run measure was " + str(round(stop - start, 3)) + " seconds") diff --git a/.ipynb_checkpoints/requirements-checkpoint.txt b/.ipynb_checkpoints/requirements-checkpoint.txt deleted file mode 100644 index 0cc0df2..0000000 --- a/.ipynb_checkpoints/requirements-checkpoint.txt +++ /dev/null @@ -1,4 +0,0 @@ -numpy~=1.18.1 -pandas~=0.24.2 -fcsy~=0.3.1 -pytest~=5.4.2 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..21c3bb7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,29 @@ +# Config file for automatic testing at travis-ci.com + +language: python +python: + - 3.8 + - 3.7 + - 3.6 + - 3.5 + +# Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors +install: pip install -U tox-travis + +# Command to run tests, e.g. python setup.py test +script: tox + +# Assuming you have installed the travis-ci CLI tool, after you +# create the Github repo and add it to Travis, run the +# following command to finish PyPI deployment setup: +# $ travis encrypt --add deploy.password +deploy: + provider: pypi + distributions: sdist bdist_wheel + user: mshavlik; lperezmo + password: + secure: PLEASE_REPLACE_ME + on: + tags: true + repo: mshavlik; lperezmo/flowsym + python: 3.8 diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 0000000..773b3c7 --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,13 @@ +======= +Credits +======= + +Development Lead +---------------- + +* Michael M. Shavlik; Luis Perez Morales + +Contributors +------------ + +None yet. Why not be the first? diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..446a742 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,128 @@ +.. highlight:: shell + +============ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every little bit +helps, and credit will always be given. + +You can contribute in many ways: + +Types of Contributions +---------------------- + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/mshavlik; lperezmo/flowsym/issues. + +If you are reporting a bug, please include: + +* Your operating system name and version. +* Any details about your local setup that might be helpful in troubleshooting. +* Detailed steps to reproduce the bug. + +Fix Bugs +~~~~~~~~ + +Look through the GitHub issues for bugs. Anything tagged with "bug" and "help +wanted" is open to whoever wants to implement it. + +Implement Features +~~~~~~~~~~~~~~~~~~ + +Look through the GitHub issues for features. Anything tagged with "enhancement" +and "help wanted" is open to whoever wants to implement it. + +Write Documentation +~~~~~~~~~~~~~~~~~~~ + +flowsym could always use more documentation, whether as part of the +official flowsym docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to file an issue at https://github.com/mshavlik; lperezmo/flowsym/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Get Started! +------------ + +Ready to contribute? Here's how to set up `flowsym` for local development. + +1. Fork the `flowsym` repo on GitHub. +2. Clone your fork locally:: + + $ git clone git@github.com:your_name_here/flowsym.git + +3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: + + $ mkvirtualenv flowsym + $ cd flowsym/ + $ python setup.py develop + +4. Create a branch for local development:: + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +5. When you're done making changes, check that your changes pass flake8 and the + tests, including testing other Python versions with tox:: + + $ flake8 flowsym tests + $ python setup.py test or pytest + $ tox + + To get flake8 and tox, just pip install them into your virtualenv. + +6. Commit your changes and push your branch to GitHub:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +7. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +Before you submit a pull request, check that it meets these guidelines: + +1. The pull request should include tests. +2. If the pull request adds functionality, the docs should be updated. Put + your new functionality into a function with a docstring, and add the + feature to the list in README.rst. +3. The pull request should work for Python 3.5, 3.6, 3.7 and 3.8, and for PyPy. Check + https://travis-ci.com/mshavlik; lperezmo/flowsym/pull_requests + and make sure that the tests pass for all supported Python versions. + +Tips +---- + +To run a subset of tests:: + +$ pytest tests.test_flowsym + + +Deploying +--------- + +A reminder for the maintainers on how to deploy. +Make sure all your changes are committed (including an entry in HISTORY.rst). +Then run:: + +$ bump2version patch # possible: major / minor / patch +$ git push +$ git push --tags + +Travis will then deploy to PyPI if tests pass. diff --git a/HISTORY.rst b/HISTORY.rst new file mode 100644 index 0000000..a99a090 --- /dev/null +++ b/HISTORY.rst @@ -0,0 +1,8 @@ +======= +History +======= + +0.1.0 (2020-08-21) +------------------ + +* First release on PyPI. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e9fa158 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2020, Michael M. Shavlik; Luis Perez Morales + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..965b2dd --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,11 @@ +include AUTHORS.rst +include CONTRIBUTING.rst +include HISTORY.rst +include LICENSE +include README.rst + +recursive-include tests * +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] + +recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b171145 --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +.PHONY: clean clean-test clean-pyc clean-build docs help +.DEFAULT_GOAL := help + +define BROWSER_PYSCRIPT +import os, webbrowser, sys + +from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT + +define PRINT_HELP_PYSCRIPT +import re, sys + +for line in sys.stdin: + match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) + if match: + target, help = match.groups() + print("%-20s %s" % (target, help)) +endef +export PRINT_HELP_PYSCRIPT + +BROWSER := python -c "$$BROWSER_PYSCRIPT" + +help: + @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) + +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts + +clean-build: ## remove build artifacts + rm -fr build/ + rm -fr dist/ + rm -fr .eggs/ + find . -name '*.egg-info' -exec rm -fr {} + + find . -name '*.egg' -exec rm -f {} + + +clean-pyc: ## remove Python file artifacts + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -fr {} + + +clean-test: ## remove test and coverage artifacts + rm -fr .tox/ + rm -f .coverage + rm -fr htmlcov/ + rm -fr .pytest_cache + +lint: ## check style with flake8 + flake8 flowsym tests + +test: ## run tests quickly with the default Python + pytest + +test-all: ## run tests on every Python version with tox + tox + +coverage: ## check code coverage quickly with the default Python + coverage run --source flowsym -m pytest + coverage report -m + coverage html + $(BROWSER) htmlcov/index.html + +docs: ## generate Sphinx HTML documentation, including API docs + rm -f docs/flowsym.rst + rm -f docs/modules.rst + sphinx-apidoc -o docs/ flowsym + $(MAKE) -C docs clean + $(MAKE) -C docs html + $(BROWSER) docs/_build/html/index.html + +servedocs: docs ## compile the docs watching for changes + watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . + +release: dist ## package and upload a release + twine upload dist/* + +dist: clean ## builds source and wheel package + python setup.py sdist + python setup.py bdist_wheel + ls -l dist + +install: clean ## install the package to the active Python's site-packages + python setup.py install diff --git a/README.md b/README.md deleted file mode 100644 index 598fbd0..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Flowsym -Simulation software of Fluorescence Assisted Cell Sorting diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..2e8803f --- /dev/null +++ b/README.rst @@ -0,0 +1,41 @@ +======= +flowsym +======= + + +.. image:: https://img.shields.io/pypi/v/flowsym.svg + :target: https://pypi.python.org/pypi/flowsym + +.. image:: https://img.shields.io/travis/mshavlik; lperezmo/flowsym.svg + :target: https://travis-ci.com/mshavlik; lperezmo/flowsym + +.. image:: https://readthedocs.org/projects/flowsym/badge/?version=latest + :target: https://flowsym.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + + +.. image:: https://pyup.io/repos/github/mshavlik; lperezmo/flowsym/shield.svg + :target: https://pyup.io/repos/github/mshavlik; lperezmo/flowsym/ + :alt: Updates + + + +A Python API for simulating flow cytometry data + + +* Free software: MIT license +* Documentation: https://flowsym.readthedocs.io. + + +Features +-------- + +* TODO + +Credits +------- + +This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template. + +.. _Cookiecutter: https://github.com/audreyr/cookiecutter +.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..691aecd --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -msphinx +SPHINXPROJ = flowsym +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/authors.rst b/docs/authors.rst new file mode 100644 index 0000000..e122f91 --- /dev/null +++ b/docs/authors.rst @@ -0,0 +1 @@ +.. include:: ../AUTHORS.rst diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..36b61cf --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python +# +# flowsym documentation build configuration file, created by +# sphinx-quickstart on Fri Jun 9 13:47:02 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another +# directory, add these directories to sys.path here. If the directory is +# relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('..')) + +import flowsym + +# -- General configuration --------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'flowsym' +copyright = "2020, Michael M. Shavlik; Luis Perez Morales" +author = "Michael M. Shavlik; Luis Perez Morales" + +# The version info for the project you're documenting, acts as replacement +# for |version| and |release|, also used in various other places throughout +# the built documents. +# +# The short X.Y version. +version = flowsym.__version__ +# The full version, including alpha/beta/rc tags. +release = flowsym.__version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a +# theme further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output --------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'flowsymdoc' + + +# -- Options for LaTeX output ------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass +# [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'flowsym.tex', + 'flowsym Documentation', + 'Michael M. Shavlik; Luis Perez Morales', 'manual'), +] + + +# -- Options for manual page output ------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'flowsym', + 'flowsym Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'flowsym', + 'flowsym Documentation', + author, + 'flowsym', + 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..e582053 --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst diff --git a/docs/history.rst b/docs/history.rst new file mode 100644 index 0000000..2506499 --- /dev/null +++ b/docs/history.rst @@ -0,0 +1 @@ +.. include:: ../HISTORY.rst diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..88cb0cf --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ +Welcome to flowsym's documentation! +====================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + readme + installation + usage + modules + contributing + authors + history + +Indices and tables +================== +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..cb3225c --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,51 @@ +.. highlight:: shell + +============ +Installation +============ + + +Stable release +-------------- + +To install flowsym, run this command in your terminal: + +.. code-block:: console + + $ pip install flowsym + +This is the preferred method to install flowsym, as it will always install the most recent stable release. + +If you don't have `pip`_ installed, this `Python installation guide`_ can guide +you through the process. + +.. _pip: https://pip.pypa.io +.. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/ + + +From sources +------------ + +The sources for flowsym can be downloaded from the `Github repo`_. + +You can either clone the public repository: + +.. code-block:: console + + $ git clone git://github.com/mshavlik; lperezmo/flowsym + +Or download the `tarball`_: + +.. code-block:: console + + $ curl -OJL https://github.com/mshavlik; lperezmo/flowsym/tarball/master + +Once you have a copy of the source, you can install it with: + +.. code-block:: console + + $ python setup.py install + + +.. _Github repo: https://github.com/mshavlik; lperezmo/flowsym +.. _tarball: https://github.com/mshavlik; lperezmo/flowsym/tarball/master diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..ba4219a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=python -msphinx +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=flowsym + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The Sphinx module was not found. Make sure you have Sphinx installed, + echo.then set the SPHINXBUILD environment variable to point to the full + echo.path of the 'sphinx-build' executable. Alternatively you may add the + echo.Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/readme.rst b/docs/readme.rst new file mode 100644 index 0000000..72a3355 --- /dev/null +++ b/docs/readme.rst @@ -0,0 +1 @@ +.. include:: ../README.rst diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..7e0239a --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,7 @@ +===== +Usage +===== + +To use flowsym in a project:: + + import flowsym diff --git a/flowsym.py b/flowsym.py deleted file mode 100644 index 89da4c4..0000000 --- a/flowsym.py +++ /dev/null @@ -1,744 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Jan 20 09:57:16 2020 - -:author: Michael -:author: Luis -""" - -# Check to see if fcsy and hdbscan are installed on machine -import importlib.util - -package_name = 'fcsy' -spec = importlib.util.find_spec(package_name) -if spec is None: - print( - f"{package_name} is not installed, please install {package_name} to write fcs files in the \'measure\' function!") - -package2_name = 'hdbscan' -spec2 = importlib.util.find_spec(package2_name) -if spec2 is None: - print( - f"{package2_name} is not installed, please install {package2_name} to cluster data in the \'cluster\' function!") - -package3_name = 'unidip' -spec3 = importlib.util.find_spec(package3_name) -if spec3 is None: - print( - f"{package3_name} is not installed, please install {package3_name} to perform a dip test in the \'dip_test\' " - f"function!") - -import numpy as np -import pandas as pd -import time -from fcsy.fcs import write_fcs -import hdbscan -import matplotlib.pyplot as plt -import seaborn as sns -from unidip import UniDip -from copy import deepcopy -from scipy.stats import ks_2samp -from sklearn.mixture import GaussianMixture - -# from __init__ import spectrum_data - -# Temp - init file in same directory screws up pytest run -spectrum_data = pd.read_csv( - 'data/FPbase_Spectra_updated.csv').fillna(value=0) - - -def create_controls(size, colors=('blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'far_red', 'nir', 'ir')): - """ - This is a function that takes a DataFrame size (i.e. number of controls) and - a list of colors the user wants to run controls for. - - :type size: int - :param size: - :type colors: list - :param colors: 'blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'far_red', 'NIR', 'IR' - :return: tuple with final control results - """ - - # Check to make sure the inputs were of correct type - if type(size) != int: - raise TypeError("size cannot be of type: " + str(type(size))) - elif type(colors) != list: - raise TypeError("Ex cannot be of type: " + str(type(colors))) - - # Controls data - accept whatever colors the user provides - controls_dict = {} - for i in colors: - controls_dict[i] = {'Wavelength': [], 'Excitation Efficiency': [], 'Emission Efficiency': []} - - # Make excitation and emission data easier to read in to dictionary - wavelengths = spectrum_data['Wavelength'] - - green_ex_efficiency = spectrum_data['Fluorescein (FITC) EX'] - red_ex_efficiency = spectrum_data['Kaede (Red) EX'] - blue_ex_efficiency = spectrum_data['Pacific Blue EX'] - far_red_ex_efficiency = spectrum_data['APC (allophycocyanin) AB'] - NIR_ex_efficiency = spectrum_data['PerCP-Cy5.5 AB'] - IR_ex_efficiency = spectrum_data['APC/Cy7 EX'] - cyan_ex_efficiency = spectrum_data['CFP EX'] - yellow_ex_efficiency = spectrum_data['EYFP EX'] - orange_ex_efficiency = spectrum_data['mOrange EX'] - - # Excitation and emission data for each color control - pre-defined information - excitation_dict = {'green': [list(wavelengths), list(green_ex_efficiency)], - 'red': [list(wavelengths), list(red_ex_efficiency)], - 'blue': [list(wavelengths), list(blue_ex_efficiency)], - 'far_red': [list(wavelengths), list(far_red_ex_efficiency)], - 'nir': [list(wavelengths), list(NIR_ex_efficiency)], - 'ir': [list(wavelengths), list(IR_ex_efficiency)], - 'cyan': [list(wavelengths), list(cyan_ex_efficiency)], - 'yellow': [list(wavelengths), list(yellow_ex_efficiency)], - 'orange': [list(wavelengths), list(orange_ex_efficiency)]} - - # Make excitation and emission data easier to read in to dictionary - green_em_efficiency = spectrum_data['Fluorescein (FITC) EM'] - red_em_efficiency = spectrum_data['Kaede (Red) EM'] - blue_em_efficiency = spectrum_data['Pacific Blue EM'] - far_red_em_efficiency = spectrum_data['APC (allophycocyanin) EM'] - nir_em_efficiency = spectrum_data['PerCP-Cy5.5 EM'] - ir_em_efficiency = spectrum_data['APC/Cy7 EM'] - cyan_em_efficiency = spectrum_data['CFP EM'] - yellow_em_efficiency = spectrum_data['EYFP EM'] - orange_em_efficiency = spectrum_data['mOrange EM'] - - # Excitation and emission data for each color control - pre-defined information - emission_dict = {'green': [list(wavelengths), list(green_em_efficiency)], - 'red': [list(wavelengths), list(red_em_efficiency)], - 'blue': [list(wavelengths), list(blue_em_efficiency)], - 'far_red': [list(wavelengths), list(far_red_em_efficiency)], - 'nir': [list(wavelengths), list(nir_em_efficiency)], - 'ir': [list(wavelengths), list(ir_em_efficiency)], - 'cyan': [list(wavelengths), list(cyan_em_efficiency)], - 'yellow': [list(wavelengths), list(yellow_em_efficiency)], - 'orange': [list(wavelengths), list(orange_em_efficiency)]} - - # Match colors that the user wants to excitation and emission data - for key, value in controls_dict.items(): - key = key.lower() # Doesn't matter if user entered capital letters or not - if key in excitation_dict: - value['Wavelength'] = [excitation_dict[key][0]] - value['Excitation Efficiency'] = [excitation_dict[key][1]] - value['Emission Efficiency'] = [emission_dict[key][1]] - - else: - raise NameError(str(key) + ' is not an available control, try: ' + - str(list(excitation_dict.keys()))) - - # Create a new dictionary that will keep the associated colors with dataframe objects - results_dict = {} - for key, value in controls_dict.items(): - results_dict[key] = pd.DataFrame(value) - - # Finally, create a list that will hold all DFs while preserving color order - final_control_results = [] - for i in colors: - final_control_results.append(pd.concat([results_dict[i]] * size, ignore_index=True)) - - for df in final_control_results: - df['Copy number'] = np.round(np.random.normal(100, size=size, scale=1)) - - # Return tuple of the list for easy access of colors - return tuple(final_control_results) - - -def create_sample(size, colors=['blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'far_red', 'nir', 'ir'], - weights=[]): - """ - This is a function that takes a defined dataframe length for number of samples (int) - and excitation and emission wavelengths (list,list). Assumes equal probability of each - color unless specified by the user. - - :type colors list of strings - :param colors: ['blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'far_red', 'NIR', 'IR'] - :type weights list - :param weights (e.g. [0]) - :type size int - :param size (e.g. 1000 points) - :return: pandas DataFrame - """ - - # Check to make sure the inputs were of correct type - if type(size) != int: - raise TypeError("size cannot be of type: " + str(type(size))) - elif type(colors) != list: - raise TypeError("Color list cannot be of type: " + str(type(colors))) - - # Make excitation and emission data easier to read in to dictionary - wavelengths = spectrum_data['Wavelength'] - - green_ex_efficiency = spectrum_data['Fluorescein (FITC) EX'] - red_ex_efficiency = spectrum_data['Kaede (Red) EX'] - blue_ex_efficiency = spectrum_data['Pacific Blue EX'] - far_red_ex_efficiency = spectrum_data['APC (allophycocyanin) AB'] - nir_ex_efficiency = spectrum_data['PerCP-Cy5.5 AB'] - ir_ex_efficiency = spectrum_data['APC/Cy7 EX'] - cyan_ex_efficiency = spectrum_data['CFP EX'] - yellow_ex_efficiency = spectrum_data['EYFP EX'] - orange_ex_efficiency = spectrum_data['mOrange EX'] - - # Excitation and emission data for each color control - pre-defined information - excitation_dict = {'green': [list(wavelengths), list(green_ex_efficiency)], - 'red': [list(wavelengths), list(red_ex_efficiency)], - 'blue': [list(wavelengths), list(blue_ex_efficiency)], - 'far_red': [list(wavelengths), list(far_red_ex_efficiency)], - 'nir': [list(wavelengths), list(nir_ex_efficiency)], - 'ir': [list(wavelengths), list(ir_ex_efficiency)], - 'cyan': [list(wavelengths), list(cyan_ex_efficiency)], - 'yellow': [list(wavelengths), list(yellow_ex_efficiency)], - 'orange': [list(wavelengths), list(orange_ex_efficiency)]} - - # Make excitation and emission data easier to read in to dictionary - green_em_efficiency = spectrum_data['Fluorescein (FITC) EM'] - red_em_efficiency = spectrum_data['Kaede (Red) EM'] - blue_em_efficiency = spectrum_data['Pacific Blue EM'] - far_red_em_efficiency = spectrum_data['APC (allophycocyanin) EM'] - nir_em_efficiency = spectrum_data['PerCP-Cy5.5 EM'] - ir_em_efficiency = spectrum_data['APC/Cy7 EM'] - cyan_em_efficiency = spectrum_data['CFP EM'] - yellow_em_efficiency = spectrum_data['EYFP EM'] - orange_em_efficiency = spectrum_data['mOrange EM'] - - # Excitation and emission data for each color control - pre-defined information - emission_dict = {'green': [list(wavelengths), list(green_em_efficiency)], - 'red': [list(wavelengths), list(red_em_efficiency)], - 'blue': [list(wavelengths), list(blue_em_efficiency)], - 'far_red': [list(wavelengths), list(far_red_em_efficiency)], - 'nir': [list(wavelengths), list(nir_em_efficiency)], - 'ir': [list(wavelengths), list(ir_em_efficiency)], - 'cyan': [list(wavelengths), list(cyan_em_efficiency)], - 'yellow': [list(wavelengths), list(yellow_em_efficiency)], - 'orange': [list(wavelengths), list(orange_em_efficiency)]} - - # Set dictionary to be made into DataFrame - sample_dict = {'Wavelength': [], 'Excitation Efficiency': [], 'Emission Efficiency': []} - - # Make "size" number of cell entries - for i in range(size): - if len(weights) == 0: - color_to_pick = np.random.choice(colors).lower() - else: - color_to_pick = np.random.choice(colors, p=weights).lower() - - sample_dict['Wavelength'].append(excitation_dict[color_to_pick][0]) - sample_dict['Excitation Efficiency'].append(excitation_dict[color_to_pick][1]) - sample_dict['Emission Efficiency'].append(emission_dict[color_to_pick][1]) - - data = pd.DataFrame(sample_dict) - - # Create protein copy number - copies = np.round(np.random.normal(100, size=len(data), scale=20)) - data['Copy number'] = copies - - # Return just the sample DataFrame - return data - - -# Bandwidth on lasers is +-5 nm. channels are [450+-25, 525+-25, 600+-30, 665+-15, 720+-30, 785+-30] for filter set 2 -def measure(dataframe, lasers=[405, 488, 561, 638], channels=[1, 2, 3, 4, 5, 6], - create_fcs=True, outfile_name='data/sample_output.fcs'): - """ - This is a function that will measure fluorescence intensity for any given sample - DataFrame and laser/channel parameters. Output will be an fcs file (default) that is - the same size as the sample you ran in the function. Alternatively, you can return - just a pandas DataFrame object by setting return_fcs=False. The user can set the output - file name manually to simulate creating multiple samples and measurements. - - :type lasers: list of int - :param dataframe: - :type dataframe: pandas.DataFrame - :param lasers: - :type channels list - :param channels: - :type create_fcs bool - :param create_fcs: - :param outfile_name: - :return: DataFrame and file - """ - # Bandwidth for each fluorescence channel - channels_information = {1: list(range(425, 475)), 2: list(range(500, 550)), 3: list(range(570, 630)), - 4: list(range(650, 680)), - 5: list(range(690, 750)), 6: list(range(755, 805))} - - # This is the list that will hold all of the intensity vectors for each cell - new_dataframe_list = [['FL' + str(i) for i in channels]] - - # where are our laser wavelengths in our input dataframe? - laser_indices = {} - - # For each laser, find the indices for their wavelengths and their gaussian efficiencies - for laser in lasers: - # This part makes a gaussian distribution of each laser+-5 - counts_dict = {} - gaussian_dist_of_laser = np.array(np.round(np.random.normal(loc=laser, scale=2.0, size=10000))) - new_array = [x for x in gaussian_dist_of_laser if laser + 5 >= x >= laser - 5] - - for i in new_array: - if i not in counts_dict.keys(): - counts_dict[i] = list(new_array).count(i) - - max_count = max(counts_dict.values()) - - for key, value in counts_dict.items(): - counts_dict[key] = value / max_count - - # Find the wavelength indices that our lasers hit - make a dictionary with indices as keys and laser - # efficiencies as values - for index2, wave in enumerate(dataframe['Wavelength'][0]): - if wave in counts_dict.keys(): - laser_indices[index2] = counts_dict[wave] - - # figure out unique emission profiles based on color so we know when to end the loop - copy = dataframe.copy() - copy['Emission Efficiency'] = copy['Emission Efficiency'].astype(str) - - # Create numpy arrays to randomly sample from based on the number of excited molecules - emission_reference = {} - - for index, row in dataframe.iterrows(): - if str(row['Emission Efficiency']) not in emission_reference.keys(): - waves_to_add = np.array([round(value * 100) * [row['Wavelength'][index]] for index, value in - enumerate(row['Emission Efficiency']) if value >= 0.01]) - emission_reference[str(row['Emission Efficiency'])] = np.array([y for x in waves_to_add for y in x]) - - if len(emission_reference.keys()) == len(copy['Emission Efficiency'].unique()): - break - - # for each cell that is being analyzed - for index, row in dataframe.iterrows(): - intensity_vector = [] - - # Calculate peak excitation efficiency for our cell given all lasers at once (collinear laser set up) - excitation_max = max([row['Excitation Efficiency'][key] * value for key, value in laser_indices.items()]) - num_excited_proteins = round(row['Copy number'] * excitation_max) - - # Sample emission at wavelengths corresponding to real emission efficiency from FPbase, size=number of - # excited proteins - real_emission_wavelengths = np.random.choice(emission_reference[str(row['Emission Efficiency'])], - size=num_excited_proteins) - - # amp = np.random.choice(list(range(1000,1700,40))) - # For each fluorescence channel, find the appropriate emission values - for channel in channels: - em_chan = channels_information[channel] - - # Find intensity in each channel - NOTE using intersection and set here speed up the code DRAMATICALLY - emission_intensity = len(set(real_emission_wavelengths).intersection(em_chan)) * ( - 1000 + np.random.normal(0, scale=50)) # Average amplification +- noise - - # add intensity in each channel to the vector - intensity_vector.append(float(emission_intensity)) - - new_dataframe_list.append(intensity_vector) - - column_names = new_dataframe_list.pop(0) - - # Create new DataFrame and output - output = pd.DataFrame(new_dataframe_list, columns=column_names) - - if create_fcs: - write_fcs(output, outfile_name) - print("FCS file created with filename: " + str(outfile_name)) - - return output - - -def cluster(measured_data, min_cluster_size=50, savefig=True): - """ - This is a function to cluster flow cytometry data that has been measured in fluorescence channels using - density-based spatial clustering of applications with noise (DBSCAN), which clusters based on density of points - in an unsupervised method. The number of clusters does not need to be explicitly stated by the users. The only - parameter that needs to be optimized is min_cluster_size, which is set to 50 here. But I recommend 1% of the len( - data) Resulting plots are a bar chart showing the number of cells in each cluster and a heatmap of the median - fluorescence intensity in each channel for each cluster. - - Note: clusters that are labeled '0' are cells that the DBSCAN could not cluster. - - Returns a tuple of two dictionaries. The first dictionary is the median fluorescence represented in the heatmap - while the second dictionary holds all the fluorescence vectors for each cluster. Both of these are needed - for a dip test and re-clustering. - - :rtype: tuple of dict - :type measured_data file - :param measured_data - :type min_cluster_size int - :param min_cluster_size - :type savefig bool - :param savefig - :return: - """ - - # Create the clustering object - cluster_obj = hdbscan.HDBSCAN(min_cluster_size=min_cluster_size) - - # Perform the clustering - cluster_obj.fit(measured_data) - - # Find the number of cells in each cluster - cluster_counts = {} - - # clusters are - for i in cluster_obj.labels_: - if i not in cluster_counts.keys(): - cluster_counts[str(i + 1)] = list(cluster_obj.labels_).count(i) - - X = [] - - # Make a 2d array of the vectors - for index, row in measured_data.iterrows(): - X.append([x for x in row]) - - # Make a dictionary for our clusters to hold their associated vectors - cluster_dict = {} - for cluster_num in cluster_obj.labels_: - if cluster_num not in cluster_dict.keys(): - cluster_dict[cluster_num] = [] - - # Add the vector in each cluster - for index, vector in enumerate(X): - cluster_dict[cluster_obj.labels_[index]].append(vector) - - final_dictionary = {} - - # Make a new dictionary which will have the median value for each channel in the vector for a heatmap downstream - for key, value in cluster_dict.items(): - median_values = [] - for i in range(len(value[0])): - median_values.append(np.median([row[i] for row in value])) - final_dictionary["Cluster " + str(key + 1)] = median_values - - df = pd.DataFrame(final_dictionary, index=list(measured_data.columns)) - - fig, ax = plt.subplots(1, 2, figsize=(10, 4)) - sns.heatmap(df.transpose(), cmap='copper') - - cluster_names = [] - count = [] - - for key, value in cluster_counts.items(): - cluster_names.append(key) - count.append(value) - - y_pos = np.arange(len(cluster_names)) - - ax[0].bar(y_pos, count, color='black') - ax[0].set_xticks(y_pos) - ax[0].set_xticklabels(cluster_names) - ax[0].set_xlabel('Cluster') - ax[0].set_ylabel('Counts') - ax[0].set_title('Cells per cluster') - - ax[1].set_title('Fluorescence profile of clusters') - ax[1].set_xlabel('Fluorescence channel') - plt.yticks(rotation=0) - plt.tight_layout() - - if savefig: - plt.savefig("preliminary_clustering") - - return (final_dictionary, cluster_dict) - - -def dip_test(median_FL_data, total_data, alpha=0.05, save_figure=True): - """ - Perform a Hartigan's dip test to check for unimodality in clusters and splits clusters if bimodality is found. - This function will take the highest intensity channel for each cluster and - check for bimodality to correct for errors in clustering similar fluorescencep profiles. - Changing alpha will alter how stringent the dip test is. A higher alpha will result in higher detection - of bimodality, but runs a greater risk of false identification. It is important to note - that this dip test is relatively coarse grained and will not identify very slight populations - of mixed cells (e.g. 10 orange cells clustered with 1000 red cells) - - Returns an updated clustering of the primary clustering after performing a dip test - """ - - # Create a copy of the dictionary so we can retain the original clustering data - change_dict = deepcopy(total_data) - - # Make kde plots - if 'Cluster 0' in median_FL_data.keys(): - fig, ax = plt.subplots(1, len(median_FL_data.keys()) - 1, figsize=(12, 3)) - - else: - fig, ax = plt.subplots(1, len(median_FL_data.keys()), figsize=(12, 3)) - - # Keep track of what plot we're on - i = 0 - - # Get the index of the max fluorescence for each cluster - for key, value in median_FL_data.items(): - cluster_max_FL_index = np.argmax(value) - - # As long as we aren't cluster one, do our dip test and plot - if int(key[-1]) - 1 != -1: - search_key = int(key[-1]) - 1 - - # Intensity in each cluster where the intensity is max - dat = [row[cluster_max_FL_index] for row in total_data[search_key]] - - # Do the dip test - data = np.msort(dat) - intervals = UniDip(data, alpha=alpha).run() - print("Performing dip test on cluster " + str(search_key + 1) + " ... ") - - # Show on the graph where the intervals are - for j in intervals: - ax[i].axvspan(data[j[0]], data[j[1]], color='lightblue', alpha=0.4) - for q in j: - ax[i].axvline(data[q], color='red') - - # Split the clusters that failed the dip test into separate clusters - if len(intervals) > 1: - split_point = int(np.mean([intervals[0][1], intervals[1][0]])) - clust1 = data[:split_point] - clust2 = data[split_point:] - - # Reset current cluster number to cluster 1 and make a new cluster to the dictionary - print("Identified bimodality in cluster " + str(search_key + 1) + ", reclustering data ... ") - change_dict[max(total_data.keys()) + 1] = [row for row in total_data[search_key] if - row[cluster_max_FL_index] in clust2] - change_dict[search_key] = [row for row in total_data[search_key] if row[cluster_max_FL_index] in clust1] - - # Plot data - sns.kdeplot(data, ax=ax[i], color='black') - - ax[i].set(title='Cluster ' + str(search_key + 1), xlabel='FL ' + str(cluster_max_FL_index + 1), yticks=[]) - - # Move to the next plot - i += 1 - - plt.tight_layout() - - # save first figure of the dip test - if save_figure: - plt.savefig("Dip_test_example") - - final_reclustered = {} - - # Make a new dictionary which will have the median value for each channel in the vector for a heatmap downstream - for key, value in change_dict.items(): - med_values = [] - for i in range(len(value[0])): - med_values.append(np.median([row[i] for row in value])) - final_reclustered["Cluster " + str(key + 1)] = med_values - - search = np.random.choice(list(median_FL_data.keys())) - - cols = ['FL' + str(i + 1) for i in range(len(median_FL_data[search]))] - - # Dataframe to create heatmap - reclustered_df = pd.DataFrame(final_reclustered, index=cols) - - # Counts dictionary for barchart - reclustered_counts = {} - - for key, value in change_dict.items(): - reclustered_counts[key] = len(value) - - # Replot the new clusters - print("Plotting reclustered data ...") - - fig2, ax = plt.subplots(1, 2, figsize=(10, 4)) - sns.heatmap(reclustered_df.transpose(), cmap='copper') - - reclust = [] - recount = [] - - for key, value in reclustered_counts.items(): - reclust.append(int(key) + 1) - recount.append(value) - - rey_pos = np.arange(len(reclust)) - - ax[0].bar(rey_pos, recount, color='black') - ax[0].set_xticks(rey_pos) - ax[0].set_xticklabels(reclust) - ax[0].set_xlabel('Cluster') - ax[0].set_ylabel('Counts') - ax[0].set_title('Cells per cluster') - - ax[1].set_title('Fluorescence profile of clusters') - ax[1].set_xlabel('Fluorescence channel') - plt.yticks(rotation=0) - plt.tight_layout() - - if save_figure: - plt.savefig("reclustered_after_dip_test") - - return change_dict - - - -def gaus_recluster(median_FL_data,total_data,tolerance=.25,savefig=True): - """ - Applies a gaussian mixture model with n_components=2 - to try and separate rare populations of cells from - the original clustering. This will apply the model - and then conduct a Kolmogorov-Smirnov 2 sample test - to assess significant differences in distributions of - the split clusters. Two criteria are used to determine - whether a cluster is saved as split, or if it is preserved - as it originally was: - - P-value of Ks2 test: If p-value is below 1e-10 - - Difference in cluster size: if a cluster is split - and the difference between the sizes of the new clusters - is greater than of the total cells in the original - cluster. - - parameters: - median_FL_data - data with median FL for each cluster - - total_data - data with all measured FL for each cluster - - tolerance - how different do the sizes of clusters have to - be before they are considered actually distinct spectrally? - Increase this to be more stringent in splitting clusters. - Decrease the value to allow more reclustering at the cost of - false positives. - - savefig - save figures - - returns: - reclustered - reclustered dataset of all cells analyzed - - """ - index_max = {} - - # Get the max FL channel index for each cluster that is not 0 (i.e. unclustered) - for key, value in median_FL_data.items(): - if key[-1] !='0': - index_max[int(key[-1])-1] = np.argmax(value) - - - fig, ax = plt.subplots(1,len(list(index_max.keys())),figsize=(12,3)) - - # create a copy of the input data to preserve new and old datasets - reclustered = deepcopy(total_data) - - i = 0 - for key,value in total_data.items(): - if key != -1: - - # Max fluorescence channel for each cluster - max_channel = index_max[key] - - # Apply a gaussian mixture model and split into 2 components - gmm = GaussianMixture(n_components=2) - gmm.fit(value) - - # Label each cell in our clusters with the label for how they split - labels = gmm.predict(value) - - # Create a dataframe of the intensity vectors and their new cluster after the split - frame = pd.DataFrame(value) - frame['cluster'] = labels - - # subset dataframe based on new cluster number - pre_clust1 = frame[frame['cluster']==0] - pre_clust2 = frame[frame['cluster']==1] - - # Remove the cluster column. Probably redundant to do things this way - clust1 = pre_clust1[pre_clust1.columns[:-1]] - clust2 = pre_clust2[pre_clust2.columns[:-1]] - - # Do a ks 2 test to see if clusters are different - result = ks_2samp(clust1[max_channel],clust2[max_channel]) - - # Test how different our cluster populations are. If the difference between the sizes is more than , of the - # total, then we'll say we actually found a bimodal population to split - clust_split = abs(len(clust1)-len(clust2))/(len(clust1)+len(clust2)) - - - # Keep the split clusters if they meet our splitting criteria, otherwise retain original clusters from DB scan - if clust_split > tolerance: - if result[1] < 1e-10: - new_val = clust1.values.tolist() - new_val2 = clust2.values.tolist() - - - reclustered[key] = new_val - - reclustered[max(total_data.keys())+1] = new_val2 - - # Provide kde plots of the distributions to show which ones might - sns.kdeplot(clust1[max_channel],ax=ax[i],color='crimson') - sns.kdeplot(clust2[max_channel],ax=ax[i],color='navy') - ax[i].get_legend().remove() - ax[i].set_title("Cluster " + str(key+1) + ' split') - - i += 1 - - - - plt.tight_layout() - - if savefig: - plt.savefig('gaus_mix_cluster_split') - - - final_reclustered = {} - - # Make a new dictionary which will have the median value for each channel in the vector for a heatmap downstream - for key, value in reclustered.items(): - med_values = [] - for i in range(len(value[0])): - med_values.append(np.median([row[i] for row in value])) - final_reclustered["Cluster " + str(key+1)] = med_values - - - # Create a list of column names of the vector (FL1-6) - search = np.random.choice(list(median_FL_data.keys())) - cols = ['FL' + str(i + 1) for i in range(len(median_FL_data[search]))] - - - # Dataframe to create heatmap - reclustered_df = pd.DataFrame(final_reclustered,index=cols) - - - # Counts dictionary for barchart - reclustered_counts = {} - - for key,value in reclustered.items(): - reclustered_counts[key] = len(value) - - - # Replot the new clusters - print("Plotting reclustered data ...") - - fig2, ax = plt.subplots(1,2,figsize=(10,4)) - sns.heatmap(reclustered_df.transpose(),cmap='copper') - - reclust = [] - recount = [] - - for key, value in reclustered_counts.items(): - reclust.append(int(key)+1) - recount.append(value) - - rey_pos = np.arange(len(reclust)) - - ax[0].bar(rey_pos,recount,color='black') - ax[0].set_xticks(rey_pos) - ax[0].set_xticklabels(reclust) - ax[0].set_xlabel('Cluster') - ax[0].set_ylabel('Counts') - ax[0].set_title('Cells per cluster') - - ax[1].set_title('Fluorescence profile of clusters') - ax[1].set_xlabel('Fluorescence channel') - plt.yticks(rotation=0) - plt.tight_layout() - - if savefig: - plt.savefig('reclustered_after_gaus_mix_ks2') - - return reclustered - - - - diff --git a/flowsym/__init__.py b/flowsym/__init__.py new file mode 100644 index 0000000..0c3d049 --- /dev/null +++ b/flowsym/__init__.py @@ -0,0 +1,5 @@ +"""Top-level package for flowsym.""" + +__author__ = """Michael M. Shavlik; Luis Perez Morales""" +__email__ = 'mshavlik@uoregon.edu; lperezmo@uoregon.edu' +__version__ = '0.1.0' diff --git a/flowsym/cli.py b/flowsym/cli.py new file mode 100644 index 0000000..bdb4fc2 --- /dev/null +++ b/flowsym/cli.py @@ -0,0 +1,16 @@ +"""Console script for flowsym.""" +import sys +import click + + +@click.command() +def main(args=None): + """Console script for flowsym.""" + click.echo("Replace this message by putting your code into " + "flowsym.cli.main") + click.echo("See click documentation at https://click.palletsprojects.com/") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) # pragma: no cover diff --git a/data/FPbase_Spectra.csv b/flowsym/data/FPbase_Spectra.csv similarity index 100% rename from data/FPbase_Spectra.csv rename to flowsym/data/FPbase_Spectra.csv diff --git a/data/FPbase_Spectra_updated.csv b/flowsym/data/FPbase_Spectra_updated.csv similarity index 100% rename from data/FPbase_Spectra_updated.csv rename to flowsym/data/FPbase_Spectra_updated.csv diff --git a/data/sample_output.fcs b/flowsym/data/sample_output.fcs similarity index 100% rename from data/sample_output.fcs rename to flowsym/data/sample_output.fcs diff --git a/flowsym/flowsym.py b/flowsym/flowsym.py new file mode 100644 index 0000000..dd0b80e --- /dev/null +++ b/flowsym/flowsym.py @@ -0,0 +1 @@ +"""Main module.""" diff --git a/requirements.txt b/requirements.txt index 38982bd..821e2b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,12 @@ -numpy~=1.18.1 -pandas~=1.0.1 -fcsy~=0.3.1 -pytest~=5.4.2 -matplotlib~=3.1.3 -seaborn~=0.10.0 +pytest~=6.0.1 +click~=7.1.2 +numpy~=1.15.4 +pandas~=0.23.4 hdbscan~=0.8.26 -unidip~=0.1.1 \ No newline at end of file +matplotlib~=3.0.2 +seaborn~=0.9.0 +fcsy~=0.4.0 +unidip~=0.1.1 +scipy~=1.1.0 +scikit-learn~=0.20.1 +setuptools~=49.6.0 diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 0000000..283f5d5 --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1,12 @@ +pip==19.2.3 +bump2version==0.5.11 +wheel==0.33.6 +watchdog==0.9.0 +flake8==3.7.8 +tox==3.14.0 +coverage==4.5.4 +Sphinx==1.8.5 +twine==1.14.0 +Click==7.0 +pytest==4.6.5 +pytest-runner==5.1 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..7f96b19 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,26 @@ +[bumpversion] +current_version = 0.1.0 +commit = True +tag = True + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file:flowsym/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' + +[bdist_wheel] +universal = 1 + +[flake8] +exclude = docs + +[aliases] +# Define setup.py command aliases here +test = pytest + +[tool:pytest] +collect_ignore = ['setup.py'] + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..6393ce3 --- /dev/null +++ b/setup.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +"""The setup script.""" + +from setuptools import setup, find_packages + +with open('README.rst') as readme_file: + readme = readme_file.read() + +with open('HISTORY.rst') as history_file: + history = history_file.read() + +requirements = ['Click>=7.0', ] + +setup_requirements = ['pytest-runner', ] + +test_requirements = ['pytest>=3', ] + +setup( + author="Michael M. Shavlik; Luis Perez Morales", + author_email='mshavlik@uoregon.edu; lperezmo@uoregon.edu', + python_requires='>=3.5', + classifiers=[ + 'Development Status :: 2 - Pre-Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ], + description="A Python API for simulating flow cytometry data", + entry_points={ + 'console_scripts': [ + 'flowsym=flowsym.cli:main', + ], + }, + install_requires=requirements, + license="MIT license", + long_description=readme + '\n\n' + history, + include_package_data=True, + keywords='flowsym', + name='flowsym', + packages=find_packages(include=['flowsym', 'flowsym.*']), + setup_requires=setup_requirements, + test_suite='tests', + tests_require=test_requirements, + url='https://github.com/mshavlik; lperezmo/flowsym', + version='0.1.0', + zip_safe=False, +) diff --git a/test_flowsym.py b/test_flowsym.py deleted file mode 100644 index ba2ce2c..0000000 --- a/test_flowsym.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Apr 2 11:29:28 2020 - -:author: Michael -:author: Luis -""" - -import pytest -import flowsym -import pandas as pd -import numpy as np - - -def test_create_controls(): - """ - Test the create_controls function to make sure that we created - all of our control DataFrames correctly - """ - - greens, reds = flowsym.create_controls(10, ['green', 'red']) # Params for test function - - assert len(greens) == 10 # Did we output dataframe of correct size? - assert type(reds) == type(pd.DataFrame()) # Did we output an actual dataframe object? - assert list(greens.columns) == ['Wavelength', 'Excitation Efficiency', - 'Emission Efficiency'] # Did we make the right columns? - - # Check to make sure wavelengths are equal - for index, val in greens.iterrows(): - assert val['Wavelength'] == reds['Wavelength'][index] - assert val['Excitation Efficiency'] != reds['Excitation Efficiency'][index] - assert val['Emission Efficiency'] != reds['Emission Efficiency'][index] - - # Make sure all excitation or emission efficiencies are the same in a given dataframe - assert greens['Excitation Efficiency'][0] == greens['Excitation Efficiency'][ - np.random.choice(range(1, len(greens)))] - assert reds['Emission Efficiency'][0] == reds['Emission Efficiency'][np.random.choice(range(1, len(reds)))] - - -def test_create_sample(): - """ - Test the create sample function to make sure we made our sample DataFrames correctly - """ - sample = flowsym.create_sample(10, ['blue', 'green', 'NIR']) # Params for test function - - assert len(sample) == 10 # Is dataframe correct size from input step? - assert type(sample) == type(pd.DataFrame()) # Did we actually output a dataframe? - assert list(sample.columns) == ['Wavelength', 'Excitation Efficiency', 'Emission Efficiency', - 'Copy number'] # Are these the columns? - - # Check to make sure excitation wavelengths aren't the same as emission - for index, val in sample.iterrows(): - assert val['Excitation Efficiency'] != val['Emission Efficiency'] - - -# Now that we've tested the create sample function, make a fixture for following function tests -@pytest.fixture() -def sample(): - dataframe = flowsym.create_sample(100) - - return dataframe - - -# Now that we've tested the create controls function, make a fixture for following function tests -@pytest.fixture() -def controls(): - blue, green, red, far_red, NIR, IR = flowsym.create_controls(100) - - return blue, green, red, far_red, NIR, IR - - -def test_measure(sample): - measured = flowsym.measure(sample) - - assert len(list(measured.columns)) == 6 - assert type(measured) == type(pd.DataFrame()) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..b279c39 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Unit test package for flowsym.""" diff --git a/tests/data/FPbase_Spectra.csv b/tests/data/FPbase_Spectra.csv new file mode 100644 index 0000000..cb586b6 --- /dev/null +++ b/tests/data/FPbase_Spectra.csv @@ -0,0 +1,552 @@ +"Wavelength","Pacific Blue EM","Pacific Blue EX","Fluorescein (FITC) EX","Kaede (Red) EM","Kaede (Red) EX","APC (allophycocyanin)","PerCP-Cy5.5","APC (allophycocyanin) EM","Fluorescein (FITC) EM","PerCP-Cy5.5 EM","APC/Cy7 EM","APC/Cy7 EX" +300,,0.239,0.5364 +301,,0.2043,0.5057 +302,,0.1699,0.4783 +303,,0.1429,0.4507 +304,,0.1206,0.4301 +305,,0.1059,0.4099 +306,,0.0895,0.3941 +307,,0.0842,0.3839 +308,,0.0782,0.3712 +309,,0.0706,0.3608 +310,,0.0651,0.3644 +311,,0.0636,0.357,,0.2498 +312,,0.0615,0.3537,,0.2555 +313,,0.0598,0.3561,,0.2603 +314,,0.0587,0.3496,,0.2665 +315,,0.0574,0.3468,,0.273 +316,,0.0583,0.3397,,0.2772 +317,,0.058,0.3387,,0.2849 +318,,0.056,0.3299,,0.2924 +319,,0.0568,0.3225,,0.302 +320,,0.0569,0.3097,,0.3061 +321,,0.0582,0.3008,,0.3149 +322,,0.0617,0.2917,,0.3209 +323,,0.0638,0.2718,,0.3305 +324,,0.0641,0.2572,,0.3361 +325,,0.0666,0.2472,,0.3427 +326,,0.0701,0.2314,,0.351 +327,,0.07,0.2119,,0.36 +328,,0.0755,0.2042,,0.3686 +329,,0.0776,0.1895,,0.3744 +330,,0.0806,0.1826,,0.3902 +331,,0.0848,0.1737,,0.3939 +332,,0.0841,0.1647,,0.4018 +333,,0.0878,0.1565,,0.4051 +334,,0.092,0.152,,0.409 +335,,0.0935,0.1437,,0.4124 +336,,0.0973,0.1403,,0.4125 +337,,0.1018,0.1361,,0.4138 +338,,0.1058,0.1321,,0.4108 +339,,0.1112,0.129,,0.411 +340,,0.1179,0.1315,,0.4042 +341,,0.1227,0.1231,,0.4058 +342,,0.1288,0.1223,,0.4074 +343,,0.1382,0.1192,,0.4066 +344,,0.1428,0.116,,0.4101 +345,,0.1507,0.1138,,0.4138 +346,,0.1573,0.1122,,0.4202 +347,,0.1652,0.1098,,0.4181 +348,,0.172,0.1091,,0.4204 +349,,0.1839,0.107,,0.4184 +350,,0.1893,0.1057,,0.4128,,0.1959 +351,,0.1998,0.1044,,0.4058,,0.197 +352,,0.2123,0.106,,0.398,,0.1984 +353,,0.2212,0.1042,,0.3884,,0.2011 +354,,0.2327,0.1039,,0.3788,,0.2026 +355,,0.245,0.1047,,0.3723,,0.2056 +356,,0.2567,0.1032,,0.369,,0.2093 +357,,0.2665,0.1031,,0.3634,,0.2139 +358,,0.2796,0.1032,,0.3593,,0.2201 +359,,0.2929,0.0999,,0.3636,,0.2259 +360,,0.3058,0.0983,,0.3643,,0.2316 +361,,0.3206,0.0992,,0.3598,,0.2381 +362,,0.332,0.0979,,0.3541,,0.2442 +363,,0.3472,0.0944,,0.353,,0.2517 +364,,0.362,0.0965,,0.3403,,0.2591 +365,,0.3772,0.094,,0.3262,,0.2658 +366,,0.3946,0.0946,,0.3067,,0.2733 +367,,0.4102,0.0943,,0.2849,,0.2794 +368,,0.4277,0.0926,,0.2549,,0.2851 +369,,0.4449,0.0927,,0.2296,,0.2916 +370,,0.4641,0.0932,,0.2078,,0.2984 +371,,0.483,0.0907,,0.1849,,0.3048 +372,,0.5034,0.0888,,0.1664,,0.3115 +373,,0.5235,0.0885,,0.1507,,0.3184 +374,,0.5412,0.0851,,0.14,,0.3258 +375,,0.5618,0.0813,,0.127,,0.332 +376,,0.5843,0.0822,,0.116,,0.3402 +377,,0.6037,0.0793,,0.1071,,0.3478 +378,,0.623,0.0756,,0.1006,,0.3553 +379,,0.6497,0.0755,,0.0953,,0.3625 +380,,0.6652,0.0715,,0.0914,,0.3689 +381,,0.6874,0.0701,,0.0877,,0.3753 +382,,0.7131,0.0696,,0.0841,,0.3799 +383,,0.7323,0.0704,,0.08,,0.3848 +384,,0.7577,0.0673,,0.0769,,0.3899 +385,,0.7755,0.0692,,0.0738,,0.3941 +386,,0.7938,0.0672,,0.0698,,0.3982 +387,,0.8145,0.0656,,0.0687,,0.403 +388,,0.833,0.0654,,0.066,,0.4068 +389,,0.8521,0.063,,0.0638,,0.4114 +390,,0.8694,0.0627,,0.0613,,0.4156 +391,,0.886,0.0618,,0.0595,,0.4204 +392,,0.9006,0.0598,,0.0576,,0.4247 +393,,0.9157,0.059,,0.055,,0.4288 +394,,0.9281,0.0568,,0.0532,,0.4345 +395,,0.9408,0.0558,,0.0529,,0.4402 +396,,0.9526,0.0562,,0.0524,,0.4449 +397,,0.9637,0.0541,,0.0516,,0.4506 +398,,0.9735,0.0525,,0.0505,,0.4568 +399,,0.9814,0.0516,,0.0494,,0.464 +400,,0.9875,0.0517,,0.049,,0.4738 +401,,0.9942,0.0509,,0.05,,0.4845 +402,,0.9974,0.0516,,0.0502,,0.4953 +403,,0.9991,0.0501,,0.0494,,0.505 +404,,1,0.0501,,0.0501,,0.5179 +405,,0.9987,0.0505,,0.0508,,0.5317 +406,,0.9951,0.0527,,0.0506,,0.5446 +407,,0.9898,0.0508,,0.0506,,0.5595 +408,,0.9825,0.0513,,0.0501,,0.5732 +409,,0.9711,0.05,,0.0498,,0.5855 +410,0.0239,0.9583,0.0503,,0.0502,,0.5981 +411,0.017,0.9432,0.0496,,0.051,,0.6101 +412,0.0118,0.9232,0.0506,,0.0511,,0.6222 +413,0.0114,0.902,0.0484,,0.0517,,0.6334 +414,0.0135,0.8772,0.0491,,0.0518,,0.6442 +415,0.0167,0.8521,0.0486,,0.0521,,0.655 +416,0.0207,0.823,0.0497,,0.0528,,0.6636 +417,0.0254,0.7933,0.0513,,0.0544,,0.6725 +418,0.0313,0.76,0.0523,,0.055,,0.6813 +419,0.0381,0.7265,0.0531,,0.0555,,0.6893 +420,0.0462,0.691,0.0557,,0.056,,0.6977 +421,0.0554,0.6524,0.0548,,0.0566,,0.7066 +422,0.0665,0.6167,0.0569,,0.058,,0.7135 +423,0.0793,0.58,0.0569,,0.0594,,0.7208 +424,0.0944,0.5441,0.062,,0.0608,,0.7281 +425,0.112,0.5067,0.0632,,0.0624,,0.7353 +426,0.1321,0.4691,0.0664,,0.0637,,0.7421 +427,0.1544,0.4339,0.0718,,0.066,,0.7497 +428,0.1792,0.3998,0.0759,,0.0664,,0.7573 +429,0.2072,0.3634,0.0787,,0.0685,,0.7657 +430,0.2362,0.3318,0.083,,0.0708,,0.774 +431,0.2683,0.2996,0.0843,,0.0726,,0.7835 +432,0.3036,0.2716,0.0875,,0.0743,,0.7932 +433,0.34,0.2438,0.0901,,0.0757,,0.8027 +434,0.3788,0.2187,0.0956,,0.0787,,0.8117 +435,0.4185,0.1947,0.1012,,0.0813,,0.8217 +436,0.4578,0.1739,0.1024,,0.084,,0.8306 +437,0.499,0.1543,0.1077,,0.0864,,0.8381 +438,0.5431,0.1362,0.1122,,0.0891,,0.8443 +439,0.5882,0.1181,0.1196,,0.0918,,0.85 +440,0.6311,0.1048,0.1231,,0.0953,,0.8545 +441,0.6727,0.0912,0.1301,,0.0977,,0.8572 +442,0.7166,0.0815,0.1324,,0.102,,0.86 +443,0.7553,0.0699,0.1399,,0.1051,,0.8621 +444,0.7904,0.0616,0.1428,,0.1077,,0.8638 +445,0.8253,0.0534,0.1499,,0.1124,,0.865 +446,0.8571,0.0474,0.1563,,0.1166,,0.8659 +447,0.8879,0.0399,0.1657,,0.1215,,0.8673 +448,0.9149,0.0357,0.1703,,0.1257,,0.8664 +449,0.9348,0.0297,0.1803,,0.1294,,0.8664 +450,0.9501,0.0266,0.1875,,0.1331,0.0183,0.8669,,,,,0.03 +451,0.9646,0.0214,0.1972,,0.1355,0.0179,0.8674,,,,,0.03 +452,0.9773,0.019,0.2078,,0.1386,0.0173,0.8673,,,,,0.03 +453,0.987,0.0173,0.2193,,0.1415,0.0167,0.8689,,,,,0.03 +454,0.9948,0.0154,0.2314,,0.1452,0.0162,0.8699,,,,,0.03 +455,1,0.0137,0.2425,,0.1492,0.0158,0.8731,,,,,0.03 +456,0.9958,0.0119,0.2543,,0.1534,0.0151,0.8766,,,,,0.03 +457,0.9936,0.0108,0.2687,,0.1575,0.0146,0.881,,,,,0.03 +458,0.9865,0.0099,0.2822,,0.1644,0.0141,0.8866,,,,,0.03 +459,0.978,0.0082,0.2959,,0.1683,0.0135,0.8906,,,,,0.03 +460,0.9707,0.0071,0.3097,,0.1738,0.013,0.895,,,,,0.03 +461,0.959,0.005,0.3241,,0.1799,0.0126,0.9014,,,,,0.03 +462,0.9443,0.0065,0.3351,,0.1849,0.012,0.9046,,,,,0.03 +463,0.9282,0.0045,0.3481,,0.1888,0.0117,0.9089,,,,,0.03 +464,0.9129,0.0038,0.3606,,0.1962,0.0114,0.9105,,,,,0.03 +465,0.8984,0.0032,0.3754,,0.2024,0.0109,0.9124,,,,,0.03 +466,0.8823,0.0031,0.3832,,0.2076,0.0106,0.9159,,,,,0.03 +467,0.8589,0.0021,0.3977,,0.2128,0.0103,0.9178,,,,,0.03 +468,0.8376,0.002,0.4068,,0.218,0.0101,0.9218,,,,,0.03 +469,0.8171,0.0019,0.4186,,0.2214,0.01,0.9252,,,,,0.03 +470,0.8014,0.0019,0.4274,,0.2276,0.0099,0.9283,,,,,0.03 +471,0.7848,0.0015,0.4374,,0.2321,0.0098,0.9334,,,,,0.03 +472,0.7666,0.0022,0.4487,,0.2383,0.0098,0.9375,,,,,0.03 +473,0.7467,0.0009,0.4597,,0.2468,0.0098,0.9458,,,,,0.03 +474,0.7295,0.0012,0.4684,,0.2532,0.0098,0.9532,,,,,0.03 +475,0.7121,0.0018,0.4798,,0.2606,0.01,0.9598,,,,,0.03 +476,0.6957,0.0016,0.4922,,0.2669,0.0101,0.9656,,,,,0.03 +477,0.6789,0.0013,0.5056,,0.2735,0.0103,0.97,,,,,0.03 +478,0.6615,0.0023,0.5207,,0.2837,0.0104,0.9738,,,,,0.03 +479,0.6433,0.0006,0.5384,,0.291,0.0108,0.9778,,,,,0.03 +480,0.6241,0.0011,0.5555,,0.2975,0.011,0.9805,,,,,0.03 +481,0.6038,0.0012,0.5779,,0.3051,0.0113,0.9849,,,,,0.03 +482,0.587,0.0009,0.5975,,0.3097,0.0116,0.9876,,,,,0.03 +483,0.5703,0.001,0.6249,,0.3138,0.0119,0.9903,,,,,0.03 +484,0.553,0.002,0.65,,0.3159,0.0122,0.9917,,,,,0.03 +485,0.5363,0.0013,0.6789,,0.3235,0.0126,0.9938,,0.0379,,,0.03 +486,0.5204,0.0015,0.7082,,0.3308,0.013,0.9963,,0.0393,,,0.03 +487,0.506,0.002,0.7408,,0.3381,0.0134,0.9988,,0.0432,,,0.03 +488,0.4927,0.0014,0.7733,,0.3527,0.0137,0.9999,,0.052,,,0.03 +489,0.4783,0.0007,0.8061,,0.3688,0.0143,1,,0.0634,,,0.03 +490,0.4625,0.001,0.8364,,0.3825,0.0148,0.9992,,0.077,,,0.03 +491,0.448,0.0006,0.8713,,0.4005,0.0153,0.9958,,0.0939,,,0.03 +492,0.4327,0.0011,0.8986,,0.4188,0.0159,0.9927,,0.1132,,,0.03 +493,0.4186,0.001,0.9259,,0.4354,0.0165,0.9897,,0.1341,,,0.03 +494,0.4064,0.0007,0.9502,,0.4513,0.0171,0.9859,,0.1592,,,0.03 +495,0.3954,0.0006,0.9703,,0.4651,0.0178,0.9846,,0.1902,,,0.03 +496,0.382,0.0006,0.9847,,0.4846,0.0184,0.9835,,0.2255,,,0.03 +497,0.3697,0.0006,0.9969,,0.5036,0.0191,0.9814,,0.2639,,,0.03 +498,0.3575,0.0006,1,,0.5252,0.02,0.9791,,0.3043,,,0.03 +499,0.3453,0.0006,0.9989,,0.5506,0.0208,0.9757,,0.3479,,,0.03 +500,0.3329,0.0005,0.9889,,0.5749,0.0216,0.9748,,0.3987,,,0.03 +501,0.3208,0.0006,0.9731,,0.6056,0.0226,0.9729,,0.4507,,,0.034 +502,0.3091,0.0008,0.9488,,0.6309,0.0237,0.9726,,0.5009,,,0.038 +503,0.2968,0.0012,0.9225,,0.6558,0.0245,0.9724,,0.5509,,,0.042 +504,0.2858,0.0013,0.8866,,0.6791,0.0256,0.9695,,0.6015,,,0.046 +505,0.2726,0.001,0.8488,,0.7018,0.0265,0.9675,,0.6547,,,0.05 +506,0.2627,0.0013,0.805,,0.7219,0.0274,0.9687,,0.7074,,,0.05 +507,0.2525,0.0002,0.7585,,0.7395,0.0289,0.9691,,0.7534,,,0.05 +508,0.2425,0.001,0.7086,,0.7548,0.03,0.9699,,0.7973,,,0.05 +509,0.2336,0.0004,0.6583,,0.7555,0.031,0.971,,0.8373,,,0.05 +510,0.2248,0.0003,0.6068,,0.7531,0.0326,0.9728,,0.8744,,,0.05 +511,0.2163,0.0004,0.5558,,0.7489,0.0339,0.9728,,0.9093,,,0.052 +512,0.2082,0.0006,0.5082,,0.7364,0.0352,0.9738,,0.9358,,,0.054 +513,0.2008,0.0004,0.4603,,0.7164,0.037,0.9734,,0.9584,,,0.056 +514,0.1918,0.0012,0.4136,,0.6913,0.0386,0.9731,,0.9752,,,0.058 +515,0.1847,0.0011,0.3714,,0.6628,0.04,0.9723,,0.9893,,,0.06 +516,0.1775,0.0013,0.3303,,0.6309,0.042,0.9735,,0.9976,,,0.06 +517,0.1701,0.0009,0.2932,,0.6034,0.0437,0.9754,,1,,,0.06 +518,0.1646,0.0017,0.2577,,0.5746,0.0454,0.9736,,0.9958,,,0.06 +519,0.1581,0.0005,0.2259,,0.551,0.0475,0.9719,,0.991,,,0.06 +520,0.1514,0.0013,0.1961,,0.531,0.0493,0.9703,,0.984,0.0003,,0.06 +521,0.1457,0.001,0.1718,,0.5168,0.0511,0.9694,,0.9718,0.0003,,0.062 +522,0.1406,0,0.1466,,0.5119,0.0533,0.9688,,0.954,0.0003,,0.064 +523,0.1354,0.0004,0.1277,,0.5059,0.0552,0.9692,,0.9359,0.0003,,0.066 +524,0.1297,0.0012,0.1102,,0.5069,0.0571,0.9681,,0.9159,0.0003,,0.068 +525,0.1243,0.0006,0.0929,,0.5129,0.0598,0.9664,,0.893,0.0003,,0.07 +526,0.1198,0.0012,0.0801,,0.5201,0.0619,0.9642,,0.8697,0.0003,,0.07 +527,0.115,0,0.0705,,0.534,0.064,0.9645,,0.8447,0.0002,,0.07 +528,0.1111,0.0003,0.0585,,0.5419,0.067,0.9618,,0.8203,0.0003,,0.07 +529,0.1066,0.001,0.0519,,0.5531,0.0693,0.9593,,0.7941,0.0003,,0.07 +530,0.1032,0.001,0.0449,,0.5698,0.0718,0.9553,,0.768,0.0002,,0.07 +531,0.0994,0.0003,0.0386,,0.5776,0.0752,0.9522,,0.7408,0.0002,,0.072 +532,0.0952,0.0006,0.0318,,0.5877,0.0778,0.9458,,0.7134,0.0002,,0.074 +533,0.0912,0.0014,0.0287,,0.5937,0.0807,0.9377,,0.6893,0.0002,,0.076 +534,0.0887,0.0005,0.0235,,0.5963,0.0845,0.9278,,0.666,0.0002,,0.078 +535,0.0845,0.0014,0.0205,,0.5952,0.0876,0.9178,,0.641,0.0002,,0.08 +536,0.0816,0.0015,0.017,,0.5915,0.0909,0.9039,,0.6183,0.0002,,0.084 +537,0.079,0.001,0.0144,,0.5822,0.0954,0.8915,,0.5961,0.0002,,0.088 +538,0.0757,0.0022,0.0111,,0.573,0.0989,0.8796,,0.5737,0.0002,,0.092 +539,0.0734,0.0011,0.0108,,0.5626,0.1026,0.8669,,0.5544,0.0002,,0.096 +540,0.0703,0.0015,0.0086,,0.5482,0.1074,0.8532,,0.5318,0.0002,,0.1 +541,0.0676,0.0016,0.0078,,0.5336,0.1112,0.8373,,0.5149,0.0003,,0.102 +542,0.0651,0.0017,0.0065,,0.5204,0.1151,0.8215,,0.4972,0.0003,,0.104 +543,0.0626,0.0008,0.0074,,0.5089,0.12,0.8053,,0.4827,0.0003,,0.106 +544,0.0601,0.0023,0.0043,,0.4955,0.1242,0.7878,,0.4675,0.0003,,0.108 +545,0.0584,0.0015,0.0041,,0.4876,0.1285,0.7719,,0.4549,0.0003,,0.11 +546,0.0566,0.002,0.002,,0.4839,0.134,0.7541,,0.442,0.0003,,0.114 +547,0.0547,0.0025,0.0031,,0.4794,0.1384,0.7327,,0.4284,0.0003,,0.118 +548,0.0523,0.0025,0.0032,,0.481,0.143,0.7102,,0.4171,0.0003,,0.122 +549,0.05,0.0017,0.0055,,0.4833,0.149,0.6865,,0.4056,0.0003,,0.126 +550,0.0482,,0.0046,,0.4874,0.1539,0.6656,,0.3944,0.0003,,0.13 +551,0.0466,,,0.0654,0.495,0.1589,0.6428,,0.3858,0.0002,,0.13 +552,0.0448,,,0.0678,0.5034,0.1655,0.6189,,0.3745,0.0002,,0.13 +553,0.0428,,,0.0695,0.514,0.1707,0.5941,,0.3643,0.0002,,0.13 +554,0.0413,,,0.0716,0.5244,0.1759,0.5711,,0.3547,0.0002,,0.13 +555,0.04,,,0.0742,0.5407,0.1826,0.5479,,0.3456,0.0002,,0.13 +556,0.0384,,,0.0793,0.557,0.1878,0.5252,,0.3382,0.0002,,0.136 +557,0.0372,,,0.0825,0.5732,0.1932,0.5061,,0.3282,0.0002,,0.142 +558,0.0357,,,0.0882,0.5904,0.2002,0.4865,,0.3179,0.0002,,0.148 +559,0.0349,,,0.0956,0.6126,0.2056,0.4653,,0.3106,0.0002,,0.154 +560,0.0331,,,0.1049,0.6327,0.2112,0.4465,,0.3015,0.0002,,0.16 +561,0.0319,,,0.1152,0.6552,0.2186,0.4287,,0.2934,0.0002,,0.164 +562,0.0306,,,0.1271,0.685,0.2244,0.411,,0.2856,0.0002,,0.168 +563,0.0296,,,0.1442,0.7074,0.2305,0.3933,,0.2762,0.0002,,0.172 +564,0.0288,,,0.1624,0.739,0.2381,0.3766,,0.2675,0.0002,,0.176 +565,0.0274,,,0.187,0.7735,0.2444,0.3627,,0.2575,0.0002,,0.18 +566,0.0265,,,0.2155,0.8046,0.2506,0.3447,,0.2511,0.0002,,0.182 +567,0.0251,,,0.2481,0.8421,0.2586,0.3288,,0.2425,0.0002,,0.184 +568,0.0243,,,0.2872,0.8753,0.2648,0.3133,,0.235,0.0002,,0.186 +569,0.0235,,,0.3331,0.91,0.2715,0.2995,,0.2269,0.0002,,0.188 +570,0.0228,,,0.3824,0.9396,0.28,0.2873,,0.2168,0.0002,,0.19 +571,0.0216,,,0.4423,0.9647,0.2867,0.2757,,0.209,0.0002,,0.198 +572,0.0207,,,0.507,0.9861,0.2941,0.2644,,0.2012,0.0002,,0.206 +573,0.0196,,,0.5731,1,0.3033,0.2545,,0.1948,0.0002,,0.214 +574,0.0192,,,0.6446,0.9981,0.3104,0.2445,,0.1866,0.0002,,0.222 +575,0.0186,,,0.7177,0.9916,0.3183,0.2363,,0.1806,0.0002,,0.23 +576,0.0174,,,0.785,0.9703,0.3282,0.2281,,0.1732,0.0002,,0.238 +577,0.0171,,,0.8495,0.934,0.3358,0.2215,,0.167,0.0002,,0.246 +578,0.0165,,,0.9073,0.889,0.3443,0.2142,,0.1599,0.0002,,0.254 +579,0.0158,,,0.9476,0.8398,0.3554,0.2068,,0.1539,0.0002,,0.262 +580,0.0153,,,0.9818,0.7747,0.3641,0.2004,,0.1497,0.0002,,0.27 +581,0.0148,,,0.997,0.6979,0.374,0.1951,,0.1446,0.0002,,0.274 +582,0.0145,,,1,0.6282,0.3869,0.1897,,0.1389,0.0002,,0.278 +583,0.014,,,0.9848,0.5511,0.3974,0.1851,,0.1341,0.0002,,0.282 +584,0.0135,,,0.9582,0.4793,0.4089,0.1815,,0.1287,0.0002,,0.286 +585,0.0133,,,0.9149,0.4124,0.4236,0.1781,,0.1235,0.0002,,0.29 +586,0.0127,,,0.8678,0.3502,0.4351,0.1746,,0.1189,0.0002,,0.294 +587,0.0123,,,0.8131,0.2934,0.4478,0.1723,,0.1141,0.0002,,0.298 +588,0.0121,,,0.7535,0.2474,0.4636,0.1706,,0.1094,0.0002,,0.302 +589,0.0117,,,0.6936,0.2052,0.4754,0.1685,,0.1059,0.0002,,0.306 +590,0.011,,,0.6366,,0.4875,0.1657,,0.1028,0.0002,,0.31 +591,0.0108,,,0.5811,,0.5013,0.1638,,0.0985,0.0001,,0.32 +592,0.0105,,,0.5318,,0.511,0.162,,0.0944,0.0001,,0.33 +593,0.0103,,,0.4817,,0.5207,0.1598,,0.0911,0.0002,,0.34 +594,0.0095,,,0.4427,,0.5318,0.1587,,0.0878,0.0002,,0.35 +595,0.0095,,,0.4026,,0.5397,0.1576,,0.0844,0.0001,,0.36 +596,0.0092,,,0.3668,,0.5476,0.1563,,0.0828,0.0002,,0.37 +597,0.0088,,,0.3337,,0.5568,0.1555,,0.0792,0.0002,,0.38 +598,0.0087,,,0.3081,,0.5635,0.1561,,0.0768,0.0001,,0.39 +599,0.0085,,,0.284,,0.5705,0.1566,,0.0731,0.0001,,0.4 +600,0.0082,,,0.2648,,0.5785,0.1576,0.0093,0.0708,0.0002,,0.41 +601,0.0079,,,0.2446,,0.5845,0.16,0.0095,0.0696,0.0002,,0.412 +602,0.0075,,,0.2296,,0.5909,0.1628,0.0107,0.067,0.0002,,0.414 +603,0.0073,,,0.2145,,0.5984,0.1666,0.0115,0.0647,0.0002,,0.416 +604,0.0071,,,0.2025,,0.6042,0.1712,0.013,0.0628,0.0002,,0.418 +605,0.007,,,0.1923,,0.6102,0.1765,0.0148,0.0605,0.0002,,0.42 +606,0.0066,,,0.1812,,0.6177,0.183,0.0168,0.0585,0.0002,,0.426 +607,0.0065,,,0.1705,,0.6232,0.1885,0.0189,0.0561,0.0002,,0.432 +608,0.0063,,,0.1622,,0.6294,0.1954,0.0213,0.0552,0.0002,,0.438 +609,0.0064,,,0.1554,,0.637,0.2024,0.0233,0.0533,0.0003,,0.444 +610,0.0059,,,0.1481,,0.6431,0.2093,0.0265,0.0513,0.0003,,0.45 +611,0.0057,,,0.1425,,0.6497,0.2165,0.0294,0.0494,0.0003,,0.456 +612,0.0056,,,0.1388,,0.6579,0.2235,0.0348,0.0482,0.0003,,0.462 +613,0.0054,,,0.1342,,0.6641,0.2304,0.0378,0.0464,0.0004,,0.468 +614,0.005,,,0.1283,,0.6705,0.2367,0.0425,0.0446,0.0004,,0.474 +615,0.0051,,,0.1264,,0.6791,0.2413,0.0471,0.0429,0.0004,,0.48 +616,0.0051,,,0.1242,,0.6852,0.2466,0.0533,0.0411,0.0005,,0.488 +617,0.0048,,,0.1227,,0.6912,0.252,0.0588,0.0403,0.0005,,0.496 +618,0.0047,,,0.1217,,0.6988,0.2578,0.066,0.0387,0.0006,,0.504 +619,0.0045,,,0.1205,,0.7039,0.2621,0.0719,0.0373,0.0006,,0.512 +620,0.0043,,,0.1205,,0.7086,0.2652,0.0788,0.036,0.0007,,0.52 +621,0.0043,,,0.1206,,0.7139,0.2688,0.0857,0.0345,0.0008,,0.522 +622,0.004,,,0.1199,,0.7173,0.2712,0.0948,0.033,0.0009,,0.524 +623,0.004,,,0.12,,0.7203,0.2748,0.1027,0.0323,0.001,,0.526 +624,0.004,,,0.1207,,0.7234,0.2792,0.1106,0.0309,0.001,,0.528 +625,0.0039,,,0.1216,,0.7252,0.2827,0.1191,0.0298,0.0011,,0.53 +626,0.0037,,,0.1202,,0.7266,0.2862,0.1305,0.0292,0.0013,,0.536 +627,0.0035,,,0.1221,,0.728,0.2877,0.139,0.0279,0.0014,,0.542 +628,0.0035,,,0.1221,,0.7289,0.2903,0.1485,0.0278,0.0015,,0.548 +629,0.0034,,,0.1195,,0.7297,0.2922,0.1589,0.0266,0.0017,,0.554 +630,0.0033,,,0.1195,,0.731,0.2922,0.1678,0.0259,0.0019,,0.56 +631,0.0031,,,0.1166,,0.7324,0.2926,0.1791,0.0251,0.0021,,0.564 +632,0.0032,,,0.114,,0.734,0.2915,0.1914,0.0246,0.0023,,0.568 +633,0.003,,,0.111,,0.7372,0.2901,0.2034,0.0234,0.0026,,0.572 +634,0.0029,,,0.1084,,0.7402,0.2881,0.2147,0.0228,0.0028,,0.576 +635,0.003,,,0.1057,,0.7444,0.284,0.228,0.0217,0.003,,0.58 +636,0.0029,,,0.0995,,0.7517,0.2828,0.24,0.021,0.0033,,0.59 +637,0.0028,,,0.096,,0.7585,0.2778,0.2529,0.0206,0.0036,,0.6 +638,0.0027,,,0.0912,,0.767,0.2753,0.268,0.0201,0.0039,,0.61 +639,0.0027,,,0.0867,,0.7808,0.2729,0.2856,0.0187,0.0042,,0.62 +640,0.0027,,,0.0809,,0.7932,0.27,0.3014,0.0184,0.0046,,0.63 +641,0.0025,,,0.0766,,0.8077,0.2685,0.3266,0.018,0.0051,,0.644 +642,0.0026,,,0.0718,,0.8295,0.2667,0.3493,0.0173,0.0056,,0.658 +643,0.0024,,,0.0675,,0.8479,0.2664,0.3761,0.017,0.0062,,0.672 +644,0.0025,,,0.064,,0.8683,0.2675,0.4051,0.0163,0.0069,,0.686 +645,0.0022,,,0.0598,,0.8968,0.2677,0.4347,0.015,0.0077,,0.7 +646,0.0023,,,0.0559,,0.9188,0.2709,0.4729,0.0146,0.0087,,0.71 +647,0.0022,,,0.0516,,0.9411,0.2753,0.5118,0.0144,0.0099,,0.72 +648,0.0022,,,0.0481,,0.9666,0.2803,0.5577,0.0141,0.0113,,0.73 +649,0.0021,,,0.0452,,0.9821,0.2876,0.604,0.0135,0.0131,,0.74 +650,0.0021,,,0.0415,,0.9937,0.2945,0.6541,0.0128,0.015,,0.75 +651,,,,0.0386,,1,0.3045,0.6993,,0.0176,,0.736 +652,,,,0.036,,0.9969,0.3172,0.7519,,0.0206,,0.722 +653,,,,0.0334,,0.9858,0.3315,0.8008,,0.0243,,0.708 +654,,,,0.0309,,0.9587,0.3459,0.8488,,0.0289,,0.694 +655,,,,0.029,,0.929,0.3637,0.8908,,0.0346,,0.68 +656,,,,0.0263,,0.8901,0.3827,0.9279,,0.0417,,0.674 +657,,,,0.0249,,0.8289,0.4025,0.96,,0.05,,0.668 +658,,,,0.0234,,0.777,0.4231,0.9837,,0.0603,,0.662 +659,,,,0.0218,,0.7193,0.4473,0.9943,,0.0725,,0.656 +660,,,,0.0205,,0.641,0.4727,1,,0.0886,,0.65 +661,,,,0.0192,,0.5822,0.4987,0.9971,,0.1073,,0.616 +662,,,,0.018,,0.5233,0.5258,0.9842,,0.1307,,0.582 +663,,,,0.0167,,0.4525,0.5582,0.9601,,0.1598,,0.548 +664,,,,0.0159,,0.404,0.5912,0.9363,,0.1959,,0.514 +665,,,,0.015,,0.3576,0.627,0.9039,,0.2375,,0.48 +666,,,,0.0144,,0.3036,0.6661,0.8641,,0.2877,,0.462 +667,,,,0.0137,,0.2677,0.7087,0.8205,,0.3462,,0.444 +668,,,,0.0129,,0.2346,0.7506,0.7749,,0.4141,,0.426 +669,,,,0.0127,,0.1973,0.788,0.7313,,0.4847,,0.408 +670,,,,0.012,,0.1734,0.8233,0.6877,,0.5615,,0.39 +671,,,,0.0113,,0.1518,0.8517,0.6443,,0.6404,,0.384 +672,,,,0.0105,,0.1281,0.8743,0.6058,,0.7177,,0.378 +673,,,,0.0104,,0.113,0.8886,0.5661,,0.7894,,0.372 +674,,,,0.0101,,0.0996,0.8936,0.5279,,0.8552,,0.366 +675,,,,0.0095,,0.0848,0.8927,0.4924,,0.911,,0.36 +676,,,,0.0093,,0.0755,0.8808,0.4594,,0.9527,,0.364 +677,,,,0.0091,,0.0671,0.86,0.4316,,0.9804,,0.368 +678,,,,0.0085,,0.0575,0.8349,0.405,,0.9967,,0.372 +679,,,,0.0082,,0.0514,0.8058,0.3847,,1,,0.376 +680,,,,0.0081,,0.0458,0.7746,0.3669,,0.9943,,0.38 +681,,,,0.0081,,0.0393,0.7418,0.3472,,0.9804,,0.38 +682,,,,0.008,,0.0349,0.7069,0.3322,,0.9614,,0.38 +683,,,,0.0077,,0.0308,0.6739,0.3184,,0.9386,,0.38 +684,,,,0.0074,,0.0263,0.6407,0.3013,,0.9154,,0.38 +685,,,,0.0073,,0.0233,0.6091,0.2908,,0.8953,,0.38 +686,,,,0.007,,0.0206,0.5793,0.2787,,0.878,,0.38 +687,,,,0.0065,,0.0175,0.5529,0.2704,,0.8646,,0.38 +688,,,,0.0065,,0.0155,0.5273,0.2616,,0.8556,,0.38 +689,,,,0.0067,,0.0136,0.5045,0.2516,,0.8478,,0.38 +690,,,,0.0066,,0.0116,0.4801,0.2464,,0.8437,,0.38 +691,,,,0.006,,0.0102,0.46,0.241,,0.8427,,0.384 +692,,,,0.0061,,0.0089,0.4385,0.2339,,0.8446,,0.388 +693,,,,0.0059,,0.0075,0.415,0.2296,,0.8463,,0.392 +694,,,,0.0058,,0.0067,0.3943,0.2248,,0.8478,,0.396 +695,,,,0.0056,,0.0058,0.3746,0.2195,,0.8487,,0.4 +696,,,,0.0054,,0.0049,0.355,0.2182,,0.8481,,0.402 +697,,,,0.0051,,0.0042,0.3355,0.2134,,0.846,,0.404 +698,,,,0.005,,0.0037,0.3151,0.2105,,0.8422,,0.406 +699,,,,0.0049,,0.0031,0.2965,0.205,,0.8369,,0.408 +700,,,,,,0.0027,0.2753,0.2025,,0.8285,,0.41 +701,,,,,,,0.2572,0.1981,,0.819,,0.412 +702,,,,,,,0.2404,0.1941,,0.8067,,0.414 +703,,,,,,,0.2227,0.1922,,0.793,,0.416 +704,,,,,,,0.2047,0.189,,0.7775,,0.418 +705,,,,,,,0.1865,0.1844,,0.7607,0.01,0.42 +706,,,,,,,0.1694,0.1831,,0.7424,0.01,0.42 +707,,,,,,,0.1544,0.1806,,0.7244,0.01,0.42 +708,,,,,,,0.1393,0.1814,,0.7046,0.01,0.42 +709,,,,,,,0.1276,0.1786,,0.6844,0.01,0.42 +710,,,,,,,0.114,0.176,,0.6635,0.01,0.42 +711,,,,,,,0.1018,0.1756,,0.6438,0.012,0.422 +712,,,,,,,0.0907,0.1755,,0.623,0.014,0.424 +713,,,,,,,0.082,0.1732,,0.6031,0.016,0.426 +714,,,,,,,0.0736,0.173,,0.5833,0.018,0.428 +715,,,,,,,0.0657,0.1719,,0.5639,0.02,0.43 +716,,,,,,,0.0587,0.1705,,0.5446,0.022,0.438 +717,,,,,,,0.0525,0.1707,,0.5264,0.024,0.446 +718,,,,,,,,0.1716,,0.5091,0.026,0.454 +719,,,,,,,,0.1703,,0.4919,0.028,0.462 +720,,,,,,,,0.1696,,0.4751,0.03,0.47 +721,,,,,,,,0.168,,0.4599,0.034,0.482 +722,,,,,,,,0.1657,,0.445,0.038,0.494 +723,,,,,,,,0.1656,,0.4316,0.042,0.506 +724,,,,,,,,0.1653,,0.4192,0.046,0.518 +725,,,,,,,,0.1631,,0.4071,0.05,0.53 +726,,,,,,,,0.1605,,0.3969,0.056,0.542 +727,,,,,,,,0.1554,,0.3871,0.062,0.554 +728,,,,,,,,0.1553,,0.3786,0.068,0.566 +729,,,,,,,,0.1539,,0.3712,0.074,0.578 +730,,,,,,,,0.1489,,0.3641,0.08,0.59 +731,,,,,,,,0.1467,,0.3581,0.098,0.608 +732,,,,,,,,0.1427,,0.3518,0.116,0.626 +733,,,,,,,,0.1397,,0.346,0.134,0.644 +734,,,,,,,,0.1361,,0.3405,0.152,0.662 +735,,,,,,,,0.1321,,0.3339,0.17,0.68 +736,,,,,,,,0.1321,,0.3282,0.176,0.7 +737,,,,,,,,0.1274,,0.322,0.182,0.72 +738,,,,,,,,0.1208,,0.3154,0.188,0.74 +739,,,,,,,,0.1153,,0.3089,0.194,0.76 +740,,,,,,,,0.1118,,0.3028,0.2,0.78 +741,,,,,,,,0.1087,,0.2961,0.23,0.798 +742,,,,,,,,0.1048,,0.2904,0.26,0.816 +743,,,,,,,,0.1019,,0.2842,0.29,0.834 +744,,,,,,,,0.0974,,0.2791,0.32,0.852 +745,,,,,,,,0.0944,,0.2734,0.35,0.87 +746,,,,,,,,0.0888,,0.2682,0.38,0.882 +747,,,,,,,,0.0852,,0.2633,0.41,0.894 +748,,,,,,,,0.0829,,0.2588,0.44,0.906 +749,,,,,,,,0.0804,,0.2537,0.47,0.918 +750,,,,,,,,0.0762,,0.25,0.5,0.93 +751,,,,,,,,,,0.2455,0.524,0.944 +752,,,,,,,,,,0.2417,0.548,0.958 +753,,,,,,,,,,0.2371,0.572,0.972 +754,,,,,,,,,,0.2327,0.596,0.986 +755,,,,,,,,,,0.2278,0.62,1 +756,,,,,,,,,,0.2236,0.66,0.998 +757,,,,,,,,,,0.2188,0.7,0.996 +758,,,,,,,,,,0.2142,0.74,0.994 +759,,,,,,,,,,0.2093,0.78,0.992 +760,,,,,,,,,,0.2051,0.82,0.99 +761,,,,,,,,,,0.2,0.828,0.978 +762,,,,,,,,,,0.1957,0.836,0.966 +763,,,,,,,,,,0.1916,0.844,0.954 +764,,,,,,,,,,0.188,0.852,0.942 +765,,,,,,,,,,0.1835,0.86,0.93 +766,,,,,,,,,,0.1796,0.882,0.898 +767,,,,,,,,,,0.1754,0.904,0.866 +768,,,,,,,,,,0.1715,0.926,0.834 +769,,,,,,,,,,0.1676,0.948,0.802 +770,,,,,,,,,,0.1638,0.97,0.77 +771,,,,,,,,,,0.1598,0.976,0.748 +772,,,,,,,,,,0.156,0.982,0.726 +773,,,,,,,,,,0.1521,0.988,0.704 +774,,,,,,,,,,0.1488,0.994,0.682 +775,,,,,,,,,,0.1453,1,0.66 +776,,,,,,,,,,0.1421,0.996,0.638 +777,,,,,,,,,,0.1386,0.992,0.616 +778,,,,,,,,,,0.1348,0.988,0.594 +779,,,,,,,,,,0.1314,0.984,0.572 +780,,,,,,,,,,0.1281,0.98,0.55 +781,,,,,,,,,,0.1244,0.968,0.518 +782,,,,,,,,,,0.1209,0.956,0.486 +783,,,,,,,,,,0.1171,0.944,0.454 +784,,,,,,,,,,0.1135,0.932,0.422 +785,,,,,,,,,,0.1099,0.92,0.39 +786,,,,,,,,,,0.1067,0.908,0.372 +787,,,,,,,,,,0.1033,0.896,0.354 +788,,,,,,,,,,0.1,0.884,0.336 +789,,,,,,,,,,0.0969,0.872,0.318 +790,,,,,,,,,,0.094,0.86,0.3 +791,,,,,,,,,,0.0913,0.83,0.284 +792,,,,,,,,,,0.0884,0.8,0.268 +793,,,,,,,,,,0.0855,0.77,0.252 +794,,,,,,,,,,0.083,0.74,0.236 +795,,,,,,,,,,0.08,0.71,0.22 +796,,,,,,,,,,0.0776,0.682,0.208 +797,,,,,,,,,,0.0751,0.654,0.196 +798,,,,,,,,,,0.0725,0.626,0.184 +799,,,,,,,,,,0.0704,0.598,0.172 +800,,,,,,,,,,0.0679,0.57,0.16 +801,,,,,,,,,,0.0659,0.546,0.152 +802,,,,,,,,,,0.0639,0.522,0.144 +803,,,,,,,,,,0.0619,0.498,0.136 +804,,,,,,,,,,0.0602,0.474,0.128 +805,,,,,,,,,,0.0583,0.45,0.12 +806,,,,,,,,,,0.0564,0.44,0.11 +807,,,,,,,,,,0.0546,0.43,0.1 +808,,,,,,,,,,0.0529,0.42,0.09 +809,,,,,,,,,,0.0513,0.41,0.08 +810,,,,,,,,,,0.05,0.4,0.07 +811,,,,,,,,,,0.0487,0.378,0.068 +812,,,,,,,,,,0.0473,0.356,0.066 +813,,,,,,,,,,0.0459,0.334,0.064 +814,,,,,,,,,,0.0448,0.312,0.062 +815,,,,,,,,,,0.0437,0.29 +816,,,,,,,,,,0.0429,0.284 +817,,,,,,,,,,0.0418,0.278 +818,,,,,,,,,,0.0408,0.272 +819,,,,,,,,,,0.0397,0.266 +820,,,,,,,,,,0.0386,0.26 +821,,,,,,,,,,0.0374,0.252 +822,,,,,,,,,,0.0366,0.244 +823,,,,,,,,,,0.0356,0.236 +824,,,,,,,,,,0.0347,0.228 +825,,,,,,,,,,0.0337,0.22 +826,,,,,,,,,,0.0331,0.216 +827,,,,,,,,,,0.0324,0.212 +828,,,,,,,,,,0.0316,0.208 +829,,,,,,,,,,0.0309,0.204 +830,,,,,,,,,,0.0302,0.2 +831,,,,,,,,,,0.0294,0.196 +832,,,,,,,,,,0.0289,0.192 +833,,,,,,,,,,0.0282,0.188 +834,,,,,,,,,,0.0276,0.184 +835,,,,,,,,,,0.027,0.18 +836,,,,,,,,,,0.0264,0.178 +837,,,,,,,,,,0.0258,0.176 +838,,,,,,,,,,0.0251,0.174 +839,,,,,,,,,,0.0246,0.172 +840,,,,,,,,,,0.0242,0.17 +841,,,,,,,,,,0.0238,0.164 +842,,,,,,,,,,0.0233,0.158 +843,,,,,,,,,,0.0228,0.152 +844,,,,,,,,,,0.0224,0.146 +845,,,,,,,,,,0.0221 +846,,,,,,,,,,0.0219 +847,,,,,,,,,,0.0218 +848,,,,,,,,,,0.0217 +849,,,,,,,,,,0.0217 +850,,,,,,,,,,0.0213 \ No newline at end of file diff --git a/tests/data/FPbase_Spectra_updated.csv b/tests/data/FPbase_Spectra_updated.csv new file mode 100644 index 0000000..f011908 --- /dev/null +++ b/tests/data/FPbase_Spectra_updated.csv @@ -0,0 +1,552 @@ +"Wavelength","Fluorescein (FITC) EM","EYFP EM","mOrange EM","Kaede (Red) EM","Kaede (Red) EX","CFP EX","CFP EM","EYFP EX","mOrange EX","Pacific Blue EX","Pacific Blue EM","Fluorescein (FITC) EX","APC (allophycocyanin) AB","APC (allophycocyanin) EM","PerCP-Cy5.5 AB","PerCP-Cy5.5 EM","APC/Cy7 EX","APC/Cy7 EM" +300,,,,,,,,,0.1508,0.239,,0.5364 +301,,,,,,,,,0.1395,0.2043,,0.5057 +302,,,,,,0.8529,,,0.1303,0.1699,,0.4783 +303,,,,,,0.8502,,,0.1222,0.1429,,0.4507 +304,,,,,,0.8474,,,0.115,0.1206,,0.4301 +305,,,,,,0.8398,,,0.1097,0.1059,,0.4099 +306,,,,,,0.8321,,,0.1068,0.0895,,0.3941 +307,,,,,,0.8249,,,0.1053,0.0842,,0.3839 +308,,,,,,0.8176,,,0.1054,0.0782,,0.3712 +309,,,,,,0.8111,,,0.1072,0.0706,,0.3608 +310,,,,,,0.8047,,,0.1103,0.0651,,0.3644 +311,,,,,0.2498,0.7997,,,0.1133,0.0636,,0.357 +312,,,,,0.2555,0.7948,,,0.1166,0.0615,,0.3537 +313,,,,,0.2603,0.7906,,,0.1198,0.0598,,0.3561 +314,,,,,0.2665,0.7864,,,0.1232,0.0587,,0.3496 +315,,,,,0.273,0.7822,,,0.1262,0.0574,,0.3468 +316,,,,,0.2772,0.7779,,,0.1282,0.0583,,0.3397 +317,,,,,0.2849,0.7729,,,0.1317,0.058,,0.3387 +318,,,,,0.2924,0.768,,,0.1351,0.056,,0.3299 +319,,,,,0.302,0.7626,,,0.1386,0.0568,,0.3225 +320,,,,,0.3061,0.7573,,,0.1426,0.0569,,0.3097 +321,,,,,0.3149,0.7526,,,0.1481,0.0582,,0.3008 +322,,,,,0.3209,0.748,,,0.1539,0.0617,,0.2917 +323,,,,,0.3305,0.7439,,,0.1605,0.0638,,0.2718 +324,,,,,0.3361,0.7398,,,0.168,0.0641,,0.2572 +325,,,,,0.3427,0.7341,,,0.1745,0.0666,,0.2472 +326,,,,,0.351,0.7283,,,0.1801,0.0701,,0.2314 +327,,,,,0.36,0.7208,,,0.1831,0.07,,0.2119 +328,,,,,0.3686,0.7132,,,0.1842,0.0755,,0.2042 +329,,,,,0.3744,0.7052,,,0.1817,0.0776,,0.1895 +330,,,,,0.3902,0.6972,,,0.1765,0.0806,,0.1826 +331,,,,,0.3939,0.6898,,,0.1686,0.0848,,0.1737 +332,,,,,0.4018,0.6825,,,0.1579,0.0841,,0.1647 +333,,,,,0.4051,0.6763,,,0.146,0.0878,,0.1565 +334,,,,,0.409,0.6702,,,0.1345,0.092,,0.152 +335,,,,,0.4124,0.6646,,,0.1221,0.0935,,0.1437 +336,,,,,0.4125,0.659,,,0.1119,0.0973,,0.1403 +337,,,,,0.4138,0.6526,,,0.1025,0.1018,,0.1361 +338,,,,,0.4108,0.6463,,,0.0939,0.1058,,0.1321 +339,,,,,0.411,0.6389,,,0.0862,0.1112,,0.129 +340,,,,,0.4042,0.6316,,,0.0795,0.1179,,0.1315 +341,,,,,0.4058,0.6249,,,0.0742,0.1227,,0.1231 +342,,,,,0.4074,0.6182,,,0.0692,0.1288,,0.1223 +343,,,,,0.4066,0.6126,,,0.0648,0.1382,,0.1192 +344,,,,,0.4101,0.607,,,0.0616,0.1428,,0.116 +345,,,,,0.4138,0.6025,,,0.0582,0.1507,,0.1138 +346,,,,,0.4202,0.5981,,,0.0556,0.1573,,0.1122 +347,,,,,0.4181,0.5946,,,0.0533,0.1652,,0.1098 +348,,,,,0.4204,0.591,,,0.051,0.172,,0.1091 +349,,,,,0.4184,0.5875,,,0.049,0.1839,,0.107 +350,,,,,0.4128,0.5839,,0.0484,0.0467,0.1893,,0.1057,,,0.1959 +351,,,,,0.4058,0.5798,,0.0483,0.045,0.1998,,0.1044,,,0.197 +352,,,,,0.398,0.5758,,0.0484,0.0429,0.2123,,0.106,,,0.1984 +353,,,,,0.3884,0.5714,,0.049,0.0406,0.2212,,0.1042,,,0.2011 +354,,,,,0.3788,0.567,,0.0497,0.0385,0.2327,,0.1039,,,0.2026 +355,,,,,0.3723,0.5625,,0.0494,0.0365,0.245,,0.1047,,,0.2056 +356,,,,,0.369,0.558,,0.0504,0.0341,0.2567,,0.1032,,,0.2093 +357,,,,,0.3634,0.5538,,0.0508,0.0319,0.2665,,0.1031,,,0.2139 +358,,,,,0.3593,0.5496,,0.0514,0.0296,0.2796,,0.1032,,,0.2201 +359,,,,,0.3636,0.5456,,0.0514,0.0276,0.2929,,0.0999,,,0.2259 +360,,,,,0.3643,0.5416,,0.0514,0.0255,0.3058,,0.0983,,,0.2316 +361,,,,,0.3598,0.5368,,0.0514,0.0236,0.3206,,0.0992,,,0.2381 +362,,,,,0.3541,0.5319,,0.0514,0.022,0.332,,0.0979,,,0.2442 +363,,,,,0.353,0.5256,,0.0514,0.0204,0.3472,,0.0944,,,0.2517 +364,,,,,0.3403,0.5192,,0.0514,0.0189,0.362,,0.0965,,,0.2591 +365,,,,,0.3262,0.5113,,0.0514,0.0179,0.3772,,0.094,,,0.2658 +366,,,,,0.3067,0.5035,,0.0514,0.0169,0.3946,,0.0946,,,0.2733 +367,,,,,0.2849,0.4944,,0.0514,0.016,0.4102,,0.0943,,,0.2794 +368,,,,,0.2549,0.4853,,0.0519,0.0152,0.4277,,0.0926,,,0.2851 +369,,,,,0.2296,0.476,,0.0532,0.0145,0.4449,,0.0927,,,0.2916 +370,,,,,0.2078,0.4667,,0.0534,0.0138,0.4641,,0.0932,,,0.2984 +371,,,,,0.1849,0.4584,,0.0534,0.0131,0.483,,0.0907,,,0.3048 +372,,,,,0.1664,0.4501,,0.0534,0.0125,0.5034,,0.0888,,,0.3115 +373,,,,,0.1507,0.4436,,0.0536,0.0116,0.5235,,0.0885,,,0.3184 +374,,,,,0.14,0.437,,0.0541,0.0106,0.5412,,0.0851,,,0.3258 +375,,,,,0.127,0.4326,,0.0547,0.0097,0.5618,,0.0813,,,0.332 +376,,,,,0.116,0.4281,,0.0546,0.0087,0.5843,,0.0822,,,0.3402 +377,,,,,0.1071,0.4246,,0.0551,0.0077,0.6037,,0.0793,,,0.3478 +378,,,,,0.1006,0.421,,0.056,0.0067,0.623,,0.0756,,,0.3553 +379,,,,,0.0953,0.4178,,0.0556,0.0058,0.6497,,0.0755,,,0.3625 +380,,,,,0.0914,0.4146,,0.0557,0.005,0.6652,,0.0715,,,0.3689 +381,,,,,0.0877,0.4127,,0.0566,0.0043,0.6874,,0.0701,,,0.3753 +382,,,,,0.0841,0.4107,,0.0572,0.0036,0.7131,,0.0696,,,0.3799 +383,,,,,0.08,0.4106,,0.0572,0.003,0.7323,,0.0704,,,0.3848 +384,,,,,0.0769,0.4105,,0.0586,0.0026,0.7577,,0.0673,,,0.3899 +385,,,,,0.0738,0.413,,0.0582,0.0023,0.7755,,0.0692,,,0.3941 +386,,,,,0.0698,0.4155,,0.0591,0.002,0.7938,,0.0672,,,0.3982 +387,,,,,0.0687,0.4207,,0.0602,0.0018,0.8145,,0.0656,,,0.403 +388,,,,,0.066,0.4259,,0.0603,0.0017,0.833,,0.0654,,,0.4068 +389,,,,,0.0638,0.4327,,0.0594,0.0016,0.8521,,0.063,,,0.4114 +390,,,,,0.0613,0.4394,,0.0595,0.0015,0.8694,,0.0627,,,0.4156 +391,,,,,0.0595,0.4467,,0.0615,0.0014,0.886,,0.0618,,,0.4204 +392,,,,,0.0576,0.454,,0.062,0.0014,0.9006,,0.0598,,,0.4247 +393,,,,,0.055,0.4612,,0.0604,0.0015,0.9157,,0.059,,,0.4288 +394,,,,,0.0532,0.4684,,0.0589,0.0014,0.9281,,0.0568,,,0.4345 +395,,,,,0.0529,0.4753,,0.059,0.0015,0.9408,,0.0558,,,0.4402 +396,,,,,0.0524,0.4822,,0.0597,0.0015,0.9526,,0.0562,,,0.4449 +397,,,,,0.0516,0.4896,,0.0601,0.0016,0.9637,,0.0541,,,0.4506 +398,,,,,0.0505,0.4969,,0.0605,0.0016,0.9735,,0.0525,,,0.4568 +399,,,,,0.0494,0.5057,,0.0569,0.0018,0.9814,,0.0516,,,0.464 +400,,,,,0.049,0.5145,,0.0572,0.0018,0.9875,,0.0517,,,0.4738 +401,,,,,0.05,0.5253,,0.0575,0.002,0.9942,,0.0509,,,0.4845 +402,,,,,0.0502,0.5361,,0.0575,0.0021,0.9974,,0.0516,,,0.4953 +403,,,,,0.0494,0.5483,,0.0562,0.0022,0.9991,,0.0501,,,0.505 +404,,,,,0.0501,0.5605,,0.0574,0.0023,1,,0.0501,,,0.5179 +405,,,,,0.0508,0.5735,,0.0572,0.0024,0.9987,,0.0505,,,0.5317 +406,,,,,0.0506,0.5866,,0.0545,0.0025,0.9951,,0.0527,,,0.5446 +407,,,,,0.0506,0.6011,,0.0526,0.0027,0.9898,,0.0508,,,0.5595 +408,,,,,0.0501,0.6155,,0.0551,0.0029,0.9825,,0.0513,,,0.5732 +409,,,,,0.0498,0.6324,,0.0538,0.003,0.9711,,0.05,,,0.5855 +410,,,,,0.0502,0.6493,,0.0525,0.0032,0.9583,0.0239,0.0503,,,0.5981 +411,,,,,0.051,0.6675,,0.0517,0.0034,0.9432,0.017,0.0496,,,0.6101 +412,,,,,0.0511,0.6857,,0.0522,0.0036,0.9232,0.0118,0.0506,,,0.6222 +413,,,,,0.0517,0.7027,,0.051,0.0039,0.902,0.0114,0.0484,,,0.6334 +414,,,,,0.0518,0.7197,,0.0478,0.0041,0.8772,0.0135,0.0491,,,0.6442 +415,,,,,0.0521,0.7337,,0.048,0.0044,0.8521,0.0167,0.0486,,,0.655 +416,,,,,0.0528,0.7477,,0.0472,0.0046,0.823,0.0207,0.0497,,,0.6636 +417,,,,,0.0544,0.7586,,0.0451,0.0049,0.7933,0.0254,0.0513,,,0.6725 +418,,,,,0.055,0.7695,,0.0448,0.0052,0.76,0.0313,0.0523,,,0.6813 +419,,,,,0.0555,0.7784,,0.0435,0.0056,0.7265,0.0381,0.0531,,,0.6893 +420,,,,,0.056,0.7874,,0.0428,0.0059,0.691,0.0462,0.0557,,,0.6977 +421,,,,,0.0566,0.7953,,0.0425,0.0063,0.6524,0.0554,0.0548,,,0.7066 +422,,,,,0.058,0.8032,,0.039,0.0067,0.6167,0.0665,0.0569,,,0.7135 +423,,,,,0.0594,0.8103,,0.0368,0.0071,0.58,0.0793,0.0569,,,0.7208 +424,,,,,0.0608,0.8174,,0.0351,0.0075,0.5441,0.0944,0.062,,,0.7281 +425,,,,,0.0624,0.8241,,0.0356,0.0079,0.5067,0.112,0.0632,,,0.7353 +426,,,,,0.0637,0.8308,,0.035,0.0085,0.4691,0.1321,0.0664,,,0.7421 +427,,,,,0.066,0.8372,,0.0352,0.009,0.4339,0.1544,0.0718,,,0.7497 +428,,,,,0.0664,0.8437,,0.0333,0.0095,0.3998,0.1792,0.0759,,,0.7573 +429,,,,,0.0685,0.8495,,0.0344,0.0101,0.3634,0.2072,0.0787,,,0.7657 +430,,,,,0.0708,0.8552,,0.0337,0.0107,0.3318,0.2362,0.083,,,0.774 +431,,,,,0.0726,0.8603,,0.0304,0.0115,0.2996,0.2683,0.0843,,,0.7835 +432,,,,,0.0743,0.8653,,0.0302,0.0122,0.2716,0.3036,0.0875,,,0.7932 +433,,,,,0.0757,0.8702,,0.0355,0.0129,0.2438,0.34,0.0901,,,0.8027 +434,,,,,0.0787,0.875,,0.0329,0.0137,0.2187,0.3788,0.0956,,,0.8117 +435,,,,,0.0813,0.88,,0.0328,0.0147,0.1947,0.4185,0.1012,,,0.8217 +436,,,,,0.084,0.885,,0.0349,0.0157,0.1739,0.4578,0.1024,,,0.8306 +437,,,,,0.0864,0.8901,,0.0351,0.0165,0.1543,0.499,0.1077,,,0.8381 +438,,,,,0.0891,0.8951,,0.0365,0.0177,0.1362,0.5431,0.1122,,,0.8443 +439,,,,,0.0918,0.9002,,0.0382,0.0187,0.1181,0.5882,0.1196,,,0.85 +440,,,,,0.0953,0.9053,,0.0397,0.0199,0.1048,0.6311,0.1231,,,0.8545 +441,,,,,0.0977,0.91,,0.0447,0.0211,0.0912,0.6727,0.1301,,,0.8572 +442,,,,,0.102,0.9147,,0.0433,0.0227,0.0815,0.7166,0.1324,,,0.86 +443,,,,,0.1051,0.9191,,0.0461,0.0239,0.0699,0.7553,0.1399,,,0.8621 +444,,,,,0.1077,0.9235,,0.0481,0.0255,0.0616,0.7904,0.1428,,,0.8638 +445,,,,,0.1124,0.9288,,0.0505,0.0269,0.0534,0.8253,0.1499,,,0.865 +446,,,,,0.1166,0.9341,,0.0539,0.0284,0.0474,0.8571,0.1563,,,0.8659 +447,,,,,0.1215,0.9404,,0.056,0.0302,0.0399,0.8879,0.1657,,,0.8673 +448,,,,,0.1257,0.9467,,0.0601,0.0319,0.0357,0.9149,0.1703,,,0.8664 +449,,,,,0.1294,0.9532,,0.0631,0.0339,0.0297,0.9348,0.1803,,,0.8664 +450,,,,,0.1331,0.9597,,0.0642,0.0351,0.0266,0.9501,0.1875,0.0183,,0.8669,,0.03 +451,,,,,0.1355,0.9665,,0.0678,0.0371,0.0214,0.9646,0.1972,0.0179,,0.8674,,0.03 +452,,,,,0.1386,0.9732,,0.0725,0.0392,0.019,0.9773,0.2078,0.0173,,0.8673,,0.03 +453,,,,,0.1415,0.9786,,0.0753,0.0411,0.0173,0.987,0.2193,0.0167,,0.8689,,0.03 +454,,,,,0.1452,0.9841,,0.0791,0.0437,0.0154,0.9948,0.2314,0.0162,,0.8699,,0.03 +455,,,,,0.1492,0.992,0.4764,0.0843,0.0459,0.0137,1,0.2425,0.0158,,0.8731,,0.03 +456,,,,,0.1534,0.9999,0.5063,0.086,0.0486,0.0119,0.9958,0.2543,0.0151,,0.8766,,0.03 +457,,,,,0.1575,1,0.5361,0.092,0.0511,0.0108,0.9936,0.2687,0.0146,,0.881,,0.03 +458,,,,,0.1644,0.9975,0.5664,0.0961,0.0538,0.0099,0.9865,0.2822,0.0141,,0.8866,,0.03 +459,,,,,0.1683,0.9966,0.5984,0.0991,0.0565,0.0082,0.978,0.2959,0.0135,,0.8906,,0.03 +460,,,,,0.1738,0.9957,0.6304,0.1032,0.06,0.0071,0.9707,0.3097,0.013,,0.895,,0.03 +461,,,,,0.1799,0.9847,0.6624,0.1081,0.0633,0.005,0.959,0.3241,0.0126,,0.9014,,0.03 +462,,,,,0.1849,0.9705,0.6958,0.1132,0.0667,0.0065,0.9443,0.3351,0.012,,0.9046,,0.03 +463,,,,,0.1888,0.944,0.7297,0.1204,0.0698,0.0045,0.9282,0.3481,0.0117,,0.9089,,0.03 +464,,,,,0.1962,0.9151,0.7637,0.1271,0.0738,0.0038,0.9129,0.3606,0.0114,,0.9105,,0.03 +465,,,,,0.2024,0.8946,0.7905,0.1333,0.0787,0.0032,0.8984,0.3754,0.0109,,0.9124,,0.03 +466,,,,,0.2076,0.8709,0.8152,0.1395,0.0835,0.0031,0.8823,0.3832,0.0106,,0.9159,,0.03 +467,,,,,0.2128,0.8584,0.8398,0.1478,0.0875,0.0021,0.8589,0.3977,0.0103,,0.9178,,0.03 +468,,,,,0.218,0.8467,0.8638,0.1582,0.091,0.002,0.8376,0.4068,0.0101,,0.9218,,0.03 +469,,,,,0.2214,0.8364,0.8876,0.167,0.0961,0.0019,0.8171,0.4186,0.01,,0.9252,,0.03 +470,,,,,0.2276,0.8261,0.9071,0.1785,0.1018,0.0019,0.8014,0.4274,0.0099,,0.9283,,0.03 +471,,,,,0.2321,,0.923,0.1904,0.1072,0.0015,0.7848,0.4374,0.0098,,0.9334,,0.03 +472,,,,,0.2383,,0.9381,0.2037,0.1136,0.0022,0.7666,0.4487,0.0098,,0.9375,,0.03 +473,,,,,0.2468,,0.9514,0.2174,0.1176,0.0009,0.7467,0.4597,0.0098,,0.9458,,0.03 +474,,,,,0.2532,,0.9648,0.2319,0.1223,0.0012,0.7295,0.4684,0.0098,,0.9532,,0.03 +475,,,,,0.2606,,0.9735,0.2474,0.1286,0.0018,0.7121,0.4798,0.01,,0.9598,,0.03 +476,,,,,0.2669,,0.9821,0.2617,0.1338,0.0016,0.6957,0.4922,0.0101,,0.9656,,0.03 +477,,,,,0.2735,,0.988,0.2787,0.139,0.0013,0.6789,0.5056,0.0103,,0.97,,0.03 +478,,,,,0.2837,,0.9939,0.2929,0.1436,0.0023,0.6615,0.5207,0.0104,,0.9738,,0.03 +479,,,,,0.291,,0.997,0.3081,0.1489,0.0006,0.6433,0.5384,0.0108,,0.9778,,0.03 +480,,,,,0.2975,,1,0.3209,0.1534,0.0011,0.6241,0.5555,0.011,,0.9805,,0.03 +481,,,,,0.3051,,0.9964,0.3328,0.1572,0.0012,0.6038,0.5779,0.0113,,0.9849,,0.03 +482,,,,,0.3097,,0.9928,0.3429,0.1618,0.0009,0.587,0.5975,0.0116,,0.9876,,0.03 +483,,,,,0.3138,,0.9871,0.3524,0.1667,0.001,0.5703,0.6249,0.0119,,0.9903,,0.03 +484,,0.0017,,,0.3159,,0.9814,0.3622,0.171,0.002,0.553,0.65,0.0122,,0.9917,,0.03 +485,0.0379,0.0018,,,0.3235,,0.9761,0.366,0.1767,0.0013,0.5363,0.6789,0.0126,,0.9938,,0.03 +486,0.0393,0.0019,,,0.3308,,0.9708,0.3708,0.1828,0.0015,0.5204,0.7082,0.013,,0.9963,,0.03 +487,0.0432,0.0021,,,0.3381,,0.9641,0.3758,0.1883,0.002,0.506,0.7408,0.0134,,0.9988,,0.03 +488,0.052,0.0023,,,0.3527,,0.9573,0.3809,0.1956,0.0014,0.4927,0.7733,0.0137,,0.9999,,0.03 +489,0.0634,0.0025,,,0.3688,,0.9493,0.3848,0.2021,0.0007,0.4783,0.8061,0.0143,,1,,0.03 +490,0.077,0.0027,,,0.3825,,0.9413,0.3904,0.21,0.001,0.4625,0.8364,0.0148,,0.9992,,0.03 +491,0.0939,0.0031,,,0.4005,,0.9333,0.3955,0.2187,0.0006,0.448,0.8713,0.0153,,0.9958,,0.03 +492,0.1132,0.0035,,,0.4188,,0.9253,0.4019,0.2254,0.0011,0.4327,0.8986,0.0159,,0.9927,,0.03 +493,0.1341,0.0039,,,0.4354,,0.9193,0.4116,0.2339,0.001,0.4186,0.9259,0.0165,,0.9897,,0.03 +494,0.1592,0.0047,,,0.4513,,0.9132,0.4199,0.2452,0.0007,0.4064,0.9502,0.0171,,0.9859,,0.03 +495,0.1902,0.0055,,,0.4651,,0.9073,0.4316,0.2565,0.0006,0.3954,0.9703,0.0178,,0.9846,,0.03 +496,0.2255,0.0065,,,0.4846,,0.9013,0.4468,0.2692,0.0006,0.382,0.9847,0.0184,,0.9835,,0.03 +497,0.2639,0.0078,,,0.5036,,0.8937,0.4595,0.2824,0.0006,0.3697,0.9969,0.0191,,0.9814,,0.03 +498,0.3043,0.0092,,,0.5252,,0.8861,0.4795,0.2961,0.0006,0.3575,1,0.02,,0.9791,,0.03 +499,0.3479,0.0114,,,0.5506,,0.8761,0.5012,0.3114,0.0006,0.3453,0.9989,0.0208,,0.9757,,0.03 +500,0.3987,0.0136,,,0.5749,,0.866,0.5234,0.3274,0.0005,0.3329,0.9889,0.0216,,0.9748,,0.03 +501,0.4507,0.0166,,,0.6056,,0.8458,0.5515,0.3436,0.0006,0.3208,0.9731,0.0226,,0.9729,,0.034 +502,0.5009,0.0202,,,0.6309,,0.8255,0.5812,0.3607,0.0008,0.3091,0.9488,0.0237,,0.9726,,0.038 +503,0.5509,0.026,,,0.6558,,0.805,0.6142,0.3777,0.0012,0.2968,0.9225,0.0245,,0.9724,,0.042 +504,0.6015,0.0316,,,0.6791,,0.7845,0.6498,0.3948,0.0013,0.2858,0.8866,0.0256,,0.9695,,0.046 +505,0.6547,0.0403,,,0.7018,,0.7625,0.6903,0.4127,0.001,0.2726,0.8488,0.0265,,0.9675,,0.05 +506,0.7074,0.0501,,,0.7219,,0.7405,0.7313,0.4289,0.0013,0.2627,0.805,0.0274,,0.9687,,0.05 +507,0.7534,0.064,,,0.7395,,0.7223,0.7742,0.4448,0.0002,0.2525,0.7585,0.0289,,0.9691,,0.05 +508,0.7973,0.0788,,,0.7548,,0.704,0.8186,0.4593,0.001,0.2425,0.7086,0.03,,0.9699,,0.05 +509,0.8373,0.0998,,,0.7555,,0.6871,0.8608,0.4719,0.0004,0.2336,0.6583,0.031,,0.971,,0.05 +510,0.8744,0.1232,,,0.7531,,0.6702,0.9018,0.4828,0.0003,0.2248,0.6068,0.0326,,0.9728,,0.05 +511,0.9093,0.1529,,,0.7489,,0.6566,0.939,0.4913,0.0004,0.2163,0.5558,0.0339,,0.9728,,0.052 +512,0.9358,0.1865,,,0.7364,,0.643,0.9673,0.4978,0.0006,0.2082,0.5082,0.0352,,0.9738,,0.054 +513,0.9584,0.2266,,,0.7164,,0.6276,0.9891,0.5032,0.0004,0.2008,0.4603,0.037,,0.9734,,0.056 +514,0.9752,0.2721,,,0.6913,,0.6121,1,0.5057,0.0012,0.1918,0.4136,0.0386,,0.9731,,0.058 +515,0.9893,0.3223,,,0.6628,,0.5973,0.9989,0.5066,0.0011,0.1847,0.3714,0.04,,0.9723,,0.06 +516,0.9976,0.381,,,0.6309,,0.5824,0.9849,0.5078,0.0013,0.1775,0.3303,0.042,,0.9735,,0.06 +517,1,0.4432,,,0.6034,,0.5669,0.9584,0.5075,0.0009,0.1701,0.2932,0.0437,,0.9754,,0.06 +518,0.9958,0.5122,,,0.5746,,0.5513,0.92,0.5058,0.0017,0.1646,0.2577,0.0454,,0.9736,,0.06 +519,0.991,0.581,,,0.551,,0.535,0.8706,0.5054,0.0005,0.1581,0.2259,0.0475,,0.9719,,0.06 +520,0.984,0.6472,,,0.531,,0.5187,0.8119,0.505,0.0013,0.1514,0.1961,0.0493,,0.9703,0.0003,0.06 +521,0.9718,0.7153,,,0.5168,,0.5055,0.7468,0.5055,0.001,0.1457,0.1718,0.0511,,0.9694,0.0003,0.062 +522,0.954,0.7808,,,0.5119,,0.4923,0.678,0.5077,0,0.1406,0.1466,0.0533,,0.9688,0.0003,0.064 +523,0.9359,0.838,,,0.5059,,0.481,0.608,0.5094,0.0004,0.1354,0.1277,0.0552,,0.9692,0.0003,0.066 +524,0.9159,0.8903,,,0.5069,,0.4697,0.5387,0.5153,0.0012,0.1297,0.1102,0.0571,,0.9681,0.0003,0.068 +525,0.893,0.9312,,,0.5129,,0.4565,0.4718,0.5222,0.0006,0.1243,0.0929,0.0598,,0.9664,0.0003,0.07 +526,0.8697,0.9661,,,0.5201,,0.4433,0.4101,0.53,0.0012,0.1198,0.0801,0.0619,,0.9642,0.0003,0.07 +527,0.8447,0.9874,,,0.534,,0.4296,0.3524,0.54,0,0.115,0.0705,0.064,,0.9645,0.0002,0.07 +528,0.8203,0.999,,,0.5419,,0.4159,0.3008,0.5519,0.0003,0.1111,0.0585,0.067,,0.9618,0.0003,0.07 +529,0.7941,1,,,0.5531,,0.404,0.2554,0.566,0.001,0.1066,0.0519,0.0693,,0.9593,0.0003,0.07 +530,0.768,1,0.0204,,0.5698,,0.3921,0.2151,0.5821,0.001,0.1032,0.0449,0.0718,,0.9553,0.0002,0.07 +531,0.7408,0.9832,0.0248,,0.5776,,0.3825,,0.5987,0.0003,0.0994,0.0386,0.0752,,0.9522,0.0002,0.072 +532,0.7134,0.9622,0.0301,,0.5877,,0.3729,,0.6174,0.0006,0.0952,0.0318,0.0778,,0.9458,0.0002,0.074 +533,0.6893,0.9413,0.0369,,0.5937,,0.3594,,0.64,0.0014,0.0912,0.0287,0.0807,,0.9377,0.0002,0.076 +534,0.666,0.9095,0.045,,0.5963,,0.3458,,0.6638,0.0005,0.0887,0.0235,0.0845,,0.9278,0.0002,0.078 +535,0.641,0.8783,0.0556,,0.5952,,0.3369,,0.6888,0.0014,0.0845,0.0205,0.0876,,0.9178,0.0002,0.08 +536,0.6183,0.8467,0.0662,,0.5915,,0.328,,0.7141,0.0015,0.0816,0.017,0.0909,,0.9039,0.0002,0.084 +537,0.5961,0.8126,0.0831,,0.5822,,0.3153,,0.7443,0.001,0.079,0.0144,0.0954,,0.8915,0.0002,0.088 +538,0.5737,0.7782,0.1049,,0.573,,0.3026,,0.7737,0.0022,0.0757,0.0111,0.0989,,0.8796,0.0002,0.092 +539,0.5544,0.743,0.1309,,0.5626,,0.2948,,0.8075,0.0011,0.0734,0.0108,0.1026,,0.8669,0.0002,0.096 +540,0.5318,0.7101,0.155,,0.5482,,0.2871,,0.8383,0.0015,0.0703,0.0086,0.1074,,0.8532,0.0002,0.1 +541,0.5149,0.6811,0.1776,,0.5336,,0.2764,,0.866,0.0016,0.0676,0.0078,0.1112,,0.8373,0.0003,0.102 +542,0.4972,0.6504,0.202,,0.5204,,0.2658,,0.8966,0.0017,0.0651,0.0065,0.1151,,0.8215,0.0003,0.104 +543,0.4827,0.6205,0.236,,0.5089,,0.2579,,0.9252,0.0008,0.0626,0.0074,0.12,,0.8053,0.0003,0.106 +544,0.4675,0.5949,0.2761,,0.4955,,0.25,,0.9502,0.0023,0.0601,0.0043,0.1242,,0.7878,0.0003,0.108 +545,0.4549,0.5676,0.3215,,0.4876,,0.2416,,0.971,0.0015,0.0584,0.0041,0.1285,,0.7719,0.0003,0.11 +546,0.442,0.5466,0.3671,,0.4839,,0.2332,,0.9869,0.002,0.0566,0.002,0.134,,0.7541,0.0003,0.114 +547,0.4284,0.5219,0.416,,0.4794,,0.2245,,0.9959,0.0025,0.0547,0.0031,0.1384,,0.7327,0.0003,0.118 +548,0.4171,0.5027,0.4729,,0.481,,0.2158,,1,0.0025,0.0523,0.0032,0.143,,0.7102,0.0003,0.122 +549,0.4056,0.484,0.5312,,0.4833,,0.2086,,0.9954,0.0017,0.05,0.0055,0.149,,0.6865,0.0003,0.126 +550,0.3944,0.4656,0.5866,,0.4874,,0.2014,,0.9844,,0.0482,0.0046,0.1539,,0.6656,0.0003,0.13 +551,0.3858,0.4522,0.6454,0.0654,0.495,,0.1957,,0.963,,0.0466,,0.1589,,0.6428,0.0002,0.13 +552,0.3745,0.4369,0.6974,0.0678,0.5034,,0.1901,,0.9359,,0.0448,,0.1655,,0.6189,0.0002,0.13 +553,0.3643,0.4238,0.7509,0.0695,0.514,,0.1835,,0.8988,,0.0428,,0.1707,,0.5941,0.0002,0.13 +554,0.3547,0.4152,0.803,0.0716,0.5244,,0.177,,0.856,,0.0413,,0.1759,,0.5711,0.0002,0.13 +555,0.3456,0.4009,0.8469,0.0742,0.5407,,0.1704,,0.8061,,0.04,,0.1826,,0.5479,0.0002,0.13 +556,0.3382,0.3929,0.8903,0.0793,0.557,,0.1638,,0.7546,,0.0384,,0.1878,,0.5252,0.0002,0.136 +557,0.3282,0.3857,0.9231,0.0825,0.5732,,0.1593,,0.6988,,0.0372,,0.1932,,0.5061,0.0002,0.142 +558,0.3179,0.3764,0.952,0.0882,0.5904,,0.1548,,0.6391,,0.0357,,0.2002,,0.4865,0.0002,0.148 +559,0.3106,0.3718,0.9751,0.0956,0.6126,,0.149,,0.5803,,0.0349,,0.2056,,0.4653,0.0002,0.154 +560,0.3015,0.3632,0.9896,0.1049,0.6327,,0.1432,,0.5269,,0.0331,,0.2112,,0.4465,0.0002,0.16 +561,0.2934,0.3553,0.9957,0.1152,0.6552,,0.1377,,0.4712,,0.0319,,0.2186,,0.4287,0.0002,0.164 +562,0.2856,0.3477,1,0.1271,0.685,,0.1323,,0.4179,,0.0306,,0.2244,,0.411,0.0002,0.168 +563,0.2762,0.342,0.996,0.1442,0.7074,,0.1287,,0.3685,,0.0296,,0.2305,,0.3933,0.0002,0.172 +564,0.2675,0.3348,0.9869,0.1624,0.739,,0.1251,,0.3223,,0.0288,,0.2381,,0.3766,0.0002,0.176 +565,0.2575,0.3271,0.9765,0.187,0.7735,,0.1216,,0.2823,,0.0274,,0.2444,,0.3627,0.0002,0.18 +566,0.2511,0.3181,0.9579,0.2155,0.8046,,0.118,,0.2444,,0.0265,,0.2506,,0.3447,0.0002,0.182 +567,0.2425,0.3109,0.9403,0.2481,0.8421,,0.1135,,0.2126,,0.0251,,0.2586,,0.3288,0.0002,0.184 +568,0.235,0.3018,0.9179,0.2872,0.8753,,0.109,,0.1828,,0.0243,,0.2648,,0.3133,0.0002,0.186 +569,0.2269,0.2938,0.8959,0.3331,0.91,,0.1053,,0.1571,,0.0235,,0.2715,,0.2995,0.0002,0.188 +570,0.2168,0.288,0.8716,0.3824,0.9396,,0.1017,,0.1328,,0.0228,,0.28,,0.2873,0.0002,0.19 +571,0.209,0.2774,0.8451,0.4423,0.9647,,0.0988,,0.1135,,0.0216,,0.2867,,0.2757,0.0002,0.198 +572,0.2012,0.2708,0.8184,0.507,0.9861,,0.096,,0.0961,,0.0207,,0.2941,,0.2644,0.0002,0.206 +573,0.1948,0.2602,0.7927,0.5731,1,,0.0927,,0.0814,,0.0196,,0.3033,,0.2545,0.0002,0.214 +574,0.1866,0.2504,0.7663,0.6446,0.9981,,0.0894,,0.0688,,0.0192,,0.3104,,0.2445,0.0002,0.222 +575,0.1806,0.2427,0.7397,0.7177,0.9916,,0.0875,,0.0582,,0.0186,,0.3183,,0.2363,0.0002,0.23 +576,0.1732,0.2362,0.7141,0.785,0.9703,,0.0856,,0.0494,,0.0174,,0.3282,,0.2281,0.0002,0.238 +577,0.167,0.2231,0.6914,0.8495,0.934,,0.0822,,0.0415,,0.0171,,0.3358,,0.2215,0.0002,0.246 +578,0.1599,0.2153,0.6677,0.9073,0.889,,0.0787,,0.0355,,0.0165,,0.3443,,0.2142,0.0002,0.254 +579,0.1539,0.2086,0.647,0.9476,0.8398,,0.0763,,0.0297,,0.0158,,0.3554,,0.2068,0.0002,0.262 +580,0.1497,0.1995,0.6252,0.9818,0.7747,,0.0738,,0.0251,,0.0153,,0.3641,,0.2004,0.0002,0.27 +581,0.1446,0.1911,0.6062,0.997,0.6979,,0.0713,,0.0213,,0.0148,,0.374,,0.1951,0.0002,0.274 +582,0.1389,0.1844,0.59,1,0.6282,,0.0688,,0.0179,,0.0145,,0.3869,,0.1897,0.0002,0.278 +583,0.1341,0.1756,0.5717,0.9848,0.5511,,0.068,,0.0153,,0.014,,0.3974,,0.1851,0.0002,0.282 +584,0.1287,0.1673,0.5567,0.9582,0.4793,,0.0671,,0.0131,,0.0135,,0.4089,,0.1815,0.0002,0.286 +585,0.1235,0.1609,0.5451,0.9149,0.4124,,0.0645,,0.011,,0.0133,,0.4236,,0.1781,0.0002,0.29 +586,0.1189,0.1543,0.5293,0.8678,0.3502,,0.062,,0.0095,,0.0127,,0.4351,,0.1746,0.0002,0.294 +587,0.1141,0.1475,0.519,0.8131,0.2934,,0.0613,,0.0079,,0.0123,,0.4478,,0.1723,0.0002,0.298 +588,0.1094,0.1418,0.5087,0.7535,0.2474,,0.0606,,0.0069,,0.0121,,0.4636,,0.1706,0.0002,0.302 +589,0.1059,0.1352,0.4986,0.6936,0.2052,,0.0594,,0.0059,,0.0117,,0.4754,,0.1685,0.0002,0.306 +590,0.1028,0.1303,0.4921,0.6366,,,0.0581,,0.005,,0.011,,0.4875,,0.1657,0.0002,0.31 +591,0.0985,0.1241,0.4832,0.5811,,,0.0558,,0.0044,,0.0108,,0.5013,,0.1638,0.0001,0.32 +592,0.0944,0.1192,0.4766,0.5318,,,0.0535,,0.0039,,0.0105,,0.511,,0.162,0.0001,0.33 +593,0.0911,0.114,0.4718,0.4817,,,0.0525,,0.0032,,0.0103,,0.5207,,0.1598,0.0002,0.34 +594,0.0878,0.1095,0.466,0.4427,,,0.0515,,0.0028,,0.0095,,0.5318,,0.1587,0.0002,0.35 +595,0.0844,0.1062,0.4605,0.4026,,,0.0506,,0.0025,,0.0095,,0.5397,,0.1576,0.0001,0.36 +596,0.0828,0.1008,0.4556,0.3668,,,0.0497,,0.0021,,0.0092,,0.5476,,0.1563,0.0002,0.37 +597,0.0792,0.0972,0.4489,0.3337,,,0.0486,,0.0018,,0.0088,,0.5568,,0.1555,0.0002,0.38 +598,0.0768,0.0935,0.4441,0.3081,,,,,0.0016,,0.0087,,0.5635,,0.1561,0.0001,0.39 +599,0.0731,0.0892,0.4418,0.284,,,,,0.0015,,0.0085,,0.5705,,0.1566,0.0001,0.4 +600,0.0708,0.0871,0.4354,0.2648,,,,,0.0012,,0.0082,,0.5785,0.0093,0.1576,0.0002,0.41 +601,0.0696,0.0836,0.4289,0.2446,,,,,,,0.0079,,0.5845,0.0095,0.16,0.0002,0.412 +602,0.067,0.081,0.4235,0.2296,,,,,,,0.0075,,0.5909,0.0107,0.1628,0.0002,0.414 +603,0.0647,0.0794,0.4148,0.2145,,,,,,,0.0073,,0.5984,0.0115,0.1666,0.0002,0.416 +604,0.0628,0.0743,0.41,0.2025,,,,,,,0.0071,,0.6042,0.013,0.1712,0.0002,0.418 +605,0.0605,0.0719,0.4042,0.1923,,,,,,,0.007,,0.6102,0.0148,0.1765,0.0002,0.42 +606,0.0585,0.0715,0.3975,0.1812,,,,,,,0.0066,,0.6177,0.0168,0.183,0.0002,0.426 +607,0.0561,0.0674,0.3911,0.1705,,,,,,,0.0065,,0.6232,0.0189,0.1885,0.0002,0.432 +608,0.0552,0.0652,0.3827,0.1622,,,,,,,0.0063,,0.6294,0.0213,0.1954,0.0002,0.438 +609,0.0533,0.0645,0.3747,0.1554,,,,,,,0.0064,,0.637,0.0233,0.2024,0.0003,0.444 +610,0.0513,0.0622,0.3662,0.1481,,,,,,,0.0059,,0.6431,0.0265,0.2093,0.0003,0.45 +611,0.0494,0.0596,0.3605,0.1425,,,,,,,0.0057,,0.6497,0.0294,0.2165,0.0003,0.456 +612,0.0482,0.0572,0.3501,0.1388,,,,,,,0.0056,,0.6579,0.0348,0.2235,0.0003,0.462 +613,0.0464,0.0562,0.3419,0.1342,,,,,,,0.0054,,0.6641,0.0378,0.2304,0.0004,0.468 +614,0.0446,0.0538,0.3318,0.1283,,,,,,,0.005,,0.6705,0.0425,0.2367,0.0004,0.474 +615,0.0429,0.053,0.3218,0.1264,,,,,,,0.0051,,0.6791,0.0471,0.2413,0.0004,0.48 +616,0.0411,0.0518,0.3156,0.1242,,,,,,,0.0051,,0.6852,0.0533,0.2466,0.0005,0.488 +617,0.0403,0.0506,0.3035,0.1227,,,,,,,0.0048,,0.6912,0.0588,0.252,0.0005,0.496 +618,0.0387,0.0478,0.294,0.1217,,,,,,,0.0047,,0.6988,0.066,0.2578,0.0006,0.504 +619,0.0373,0.0464,0.2861,0.1205,,,,,,,0.0045,,0.7039,0.0719,0.2621,0.0006,0.512 +620,0.036,0.045,0.2767,0.1205,,,,,,,0.0043,,0.7086,0.0788,0.2652,0.0007,0.52 +621,0.0345,0.0437,0.2673,0.1206,,,,,,,0.0043,,0.7139,0.0857,0.2688,0.0008,0.522 +622,0.033,0.0426,0.2577,0.1199,,,,,,,0.004,,0.7173,0.0948,0.2712,0.0009,0.524 +623,0.0323,0.0409,0.2512,0.12,,,,,,,0.004,,0.7203,0.1027,0.2748,0.001,0.526 +624,0.0309,0.0399,0.2423,0.1207,,,,,,,0.004,,0.7234,0.1106,0.2792,0.001,0.528 +625,0.0298,0.0398,0.234,0.1216,,,,,,,0.0039,,0.7252,0.1191,0.2827,0.0011,0.53 +626,0.0292,0.037,0.2255,0.1202,,,,,,,0.0037,,0.7266,0.1305,0.2862,0.0013,0.536 +627,0.0279,0.0354,0.2158,0.1221,,,,,,,0.0035,,0.728,0.139,0.2877,0.0014,0.542 +628,0.0278,0.0355,0.2095,0.1221,,,,,,,0.0035,,0.7289,0.1485,0.2903,0.0015,0.548 +629,0.0266,0.0339,0.2023,0.1195,,,,,,,0.0034,,0.7297,0.1589,0.2922,0.0017,0.554 +630,0.0259,0.0324,0.1957,0.1195,,,,,,,0.0033,,0.731,0.1678,0.2922,0.0019,0.56 +631,0.0251,0.0318,0.1897,0.1166,,,,,,,0.0031,,0.7324,0.1791,0.2926,0.0021,0.564 +632,0.0246,0.0303,0.1815,0.114,,,,,,,0.0032,,0.734,0.1914,0.2915,0.0023,0.568 +633,0.0234,0.0296,0.1756,0.111,,,,,,,0.003,,0.7372,0.2034,0.2901,0.0026,0.572 +634,0.0228,0.028,0.1692,0.1084,,,,,,,0.0029,,0.7402,0.2147,0.2881,0.0028,0.576 +635,0.0217,0.0276,0.1633,0.1057,,,,,,,0.003,,0.7444,0.228,0.284,0.003,0.58 +636,0.021,0.0273,0.1575,0.0995,,,,,,,0.0029,,0.7517,0.24,0.2828,0.0033,0.59 +637,0.0206,0.0263,0.1527,0.096,,,,,,,0.0028,,0.7585,0.2529,0.2778,0.0036,0.6 +638,0.0201,0.0255,0.1479,0.0912,,,,,,,0.0027,,0.767,0.268,0.2753,0.0039,0.61 +639,0.0187,0.0237,0.1439,0.0867,,,,,,,0.0027,,0.7808,0.2856,0.2729,0.0042,0.62 +640,0.0184,0.0234,0.1387,0.0809,,,,,,,0.0027,,0.7932,0.3014,0.27,0.0046,0.63 +641,0.018,0.0216,0.1341,0.0766,,,,,,,0.0025,,0.8077,0.3266,0.2685,0.0051,0.644 +642,0.0173,0.0217,0.1299,0.0718,,,,,,,0.0026,,0.8295,0.3493,0.2667,0.0056,0.658 +643,0.017,0.0213,0.1275,0.0675,,,,,,,0.0024,,0.8479,0.3761,0.2664,0.0062,0.672 +644,0.0163,0.0209,0.1236,0.064,,,,,,,0.0025,,0.8683,0.4051,0.2675,0.0069,0.686 +645,0.015,0.0203,0.1188,0.0598,,,,,,,0.0022,,0.8968,0.4347,0.2677,0.0077,0.7 +646,0.0146,0.0193,0.1159,0.0559,,,,,,,0.0023,,0.9188,0.4729,0.2709,0.0087,0.71 +647,0.0144,0.0185,0.1113,0.0516,,,,,,,0.0022,,0.9411,0.5118,0.2753,0.0099,0.72 +648,0.0141,0.0179,0.1085,0.0481,,,,,,,0.0022,,0.9666,0.5577,0.2803,0.0113,0.73 +649,0.0135,0.0172,0.1059,0.0452,,,,,,,0.0021,,0.9821,0.604,0.2876,0.0131,0.74 +650,0.0128,0.0162,0.1026,0.0415,,,,,,,0.0021,,0.9937,0.6541,0.2945,0.015,0.75 +651,,0.0166,0.0996,0.0386,,,,,,,,,1,0.6993,0.3045,0.0176,0.736 +652,,0.0166,0.0975,0.036,,,,,,,,,0.9969,0.7519,0.3172,0.0206,0.722 +653,,0.0158,0.0953,0.0334,,,,,,,,,0.9858,0.8008,0.3315,0.0243,0.708 +654,,0.015,0.0909,0.0309,,,,,,,,,0.9587,0.8488,0.3459,0.0289,0.694 +655,,0.0146,0.0896,0.029,,,,,,,,,0.929,0.8908,0.3637,0.0346,0.68 +656,,0.0146,0.0856,0.0263,,,,,,,,,0.8901,0.9279,0.3827,0.0417,0.674 +657,,0.0138,0.083,0.0249,,,,,,,,,0.8289,0.96,0.4025,0.05,0.668 +658,,0.0134,0.0797,0.0234,,,,,,,,,0.777,0.9837,0.4231,0.0603,0.662 +659,,0.0133,0.0784,0.0218,,,,,,,,,0.7193,0.9943,0.4473,0.0725,0.656 +660,,0.0131,0.0767,0.0205,,,,,,,,,0.641,1,0.4727,0.0886,0.65 +661,,0.0123,0.0739,0.0192,,,,,,,,,0.5822,0.9971,0.4987,0.1073,0.616 +662,,0.0118,0.0721,0.018,,,,,,,,,0.5233,0.9842,0.5258,0.1307,0.582 +663,,0.0121,0.07,0.0167,,,,,,,,,0.4525,0.9601,0.5582,0.1598,0.548 +664,,0.0114,0.0686,0.0159,,,,,,,,,0.404,0.9363,0.5912,0.1959,0.514 +665,,0.0113,0.0663,0.015,,,,,,,,,0.3576,0.9039,0.627,0.2375,0.48 +666,,0.0112,0.0632,0.0144,,,,,,,,,0.3036,0.8641,0.6661,0.2877,0.462 +667,,0.0114,0.0623,0.0137,,,,,,,,,0.2677,0.8205,0.7087,0.3462,0.444 +668,,0.0107,0.0614,0.0129,,,,,,,,,0.2346,0.7749,0.7506,0.4141,0.426 +669,,0.0108,0.0586,0.0127,,,,,,,,,0.1973,0.7313,0.788,0.4847,0.408 +670,,0.0106,0.0572,0.012,,,,,,,,,0.1734,0.6877,0.8233,0.5615,0.39 +671,,0.0101,0.0557,0.0113,,,,,,,,,0.1518,0.6443,0.8517,0.6404,0.384 +672,,0.0095,0.0535,0.0105,,,,,,,,,0.1281,0.6058,0.8743,0.7177,0.378 +673,,0.0094,0.0525,0.0104,,,,,,,,,0.113,0.5661,0.8886,0.7894,0.372 +674,,0.0097,0.051,0.0101,,,,,,,,,0.0996,0.5279,0.8936,0.8552,0.366 +675,,0.0096,0.0493,0.0095,,,,,,,,,0.0848,0.4924,0.8927,0.911,0.36 +676,,0.0095,0.0472,0.0093,,,,,,,,,0.0755,0.4594,0.8808,0.9527,0.364 +677,,0.0089,0.0462,0.0091,,,,,,,,,0.0671,0.4316,0.86,0.9804,0.368 +678,,0.0088,0.0447,0.0085,,,,,,,,,0.0575,0.405,0.8349,0.9967,0.372 +679,,0.0093,0.0435,0.0082,,,,,,,,,0.0514,0.3847,0.8058,1,0.376 +680,,0.0092,0.0416,0.0081,,,,,,,,,0.0458,0.3669,0.7746,0.9943,0.38 +681,,0.0096,0.041,0.0081,,,,,,,,,0.0393,0.3472,0.7418,0.9804,0.38 +682,,0.0083,0.0398,0.008,,,,,,,,,0.0349,0.3322,0.7069,0.9614,0.38 +683,,0.0081,0.0378,0.0077,,,,,,,,,0.0308,0.3184,0.6739,0.9386,0.38 +684,,0.0085,0.0371,0.0074,,,,,,,,,0.0263,0.3013,0.6407,0.9154,0.38 +685,,0.0084,0.0354,0.0073,,,,,,,,,0.0233,0.2908,0.6091,0.8953,0.38 +686,,0.0086,0.0348,0.007,,,,,,,,,0.0206,0.2787,0.5793,0.878,0.38 +687,,0.0082,0.0337,0.0065,,,,,,,,,0.0175,0.2704,0.5529,0.8646,0.38 +688,,0.0076,0.0323,0.0065,,,,,,,,,0.0155,0.2616,0.5273,0.8556,0.38 +689,,0.0081,0.0316,0.0067,,,,,,,,,0.0136,0.2516,0.5045,0.8478,0.38 +690,,0.0077,0.0298,0.0066,,,,,,,,,0.0116,0.2464,0.4801,0.8437,0.38 +691,,0.0074,0.0291,0.006,,,,,,,,,0.0102,0.241,0.46,0.8427,0.384 +692,,0.0082,0.0283,0.0061,,,,,,,,,0.0089,0.2339,0.4385,0.8446,0.388 +693,,0.0079,0.0271,0.0059,,,,,,,,,0.0075,0.2296,0.415,0.8463,0.392 +694,,0.0075,0.0268,0.0058,,,,,,,,,0.0067,0.2248,0.3943,0.8478,0.396 +695,,0.0072,0.026,0.0056,,,,,,,,,0.0058,0.2195,0.3746,0.8487,0.4 +696,,0.0069,0.0242,0.0054,,,,,,,,,0.0049,0.2182,0.355,0.8481,0.402 +697,,0.0074,0.0239,0.0051,,,,,,,,,0.0042,0.2134,0.3355,0.846,0.404 +698,,0.007,0.0238,0.005,,,,,,,,,0.0037,0.2105,0.3151,0.8422,0.406 +699,,0.0071,0.023,0.0049,,,,,,,,,0.0031,0.205,0.2965,0.8369,0.408 +700,,0.007,0.0217,,,,,,,,,,0.0027,0.2025,0.2753,0.8285,0.41 +701,,,,,,,,,,,,,,0.1981,0.2572,0.819,0.412 +702,,,,,,,,,,,,,,0.1941,0.2404,0.8067,0.414 +703,,,,,,,,,,,,,,0.1922,0.2227,0.793,0.416 +704,,,,,,,,,,,,,,0.189,0.2047,0.7775,0.418 +705,,,,,,,,,,,,,,0.1844,0.1865,0.7607,0.42,0.01 +706,,,,,,,,,,,,,,0.1831,0.1694,0.7424,0.42,0.01 +707,,,,,,,,,,,,,,0.1806,0.1544,0.7244,0.42,0.01 +708,,,,,,,,,,,,,,0.1814,0.1393,0.7046,0.42,0.01 +709,,,,,,,,,,,,,,0.1786,0.1276,0.6844,0.42,0.01 +710,,,,,,,,,,,,,,0.176,0.114,0.6635,0.42,0.01 +711,,,,,,,,,,,,,,0.1756,0.1018,0.6438,0.422,0.012 +712,,,,,,,,,,,,,,0.1755,0.0907,0.623,0.424,0.014 +713,,,,,,,,,,,,,,0.1732,0.082,0.6031,0.426,0.016 +714,,,,,,,,,,,,,,0.173,0.0736,0.5833,0.428,0.018 +715,,,,,,,,,,,,,,0.1719,0.0657,0.5639,0.43,0.02 +716,,,,,,,,,,,,,,0.1705,0.0587,0.5446,0.438,0.022 +717,,,,,,,,,,,,,,0.1707,0.0525,0.5264,0.446,0.024 +718,,,,,,,,,,,,,,0.1716,,0.5091,0.454,0.026 +719,,,,,,,,,,,,,,0.1703,,0.4919,0.462,0.028 +720,,,,,,,,,,,,,,0.1696,,0.4751,0.47,0.03 +721,,,,,,,,,,,,,,0.168,,0.4599,0.482,0.034 +722,,,,,,,,,,,,,,0.1657,,0.445,0.494,0.038 +723,,,,,,,,,,,,,,0.1656,,0.4316,0.506,0.042 +724,,,,,,,,,,,,,,0.1653,,0.4192,0.518,0.046 +725,,,,,,,,,,,,,,0.1631,,0.4071,0.53,0.05 +726,,,,,,,,,,,,,,0.1605,,0.3969,0.542,0.056 +727,,,,,,,,,,,,,,0.1554,,0.3871,0.554,0.062 +728,,,,,,,,,,,,,,0.1553,,0.3786,0.566,0.068 +729,,,,,,,,,,,,,,0.1539,,0.3712,0.578,0.074 +730,,,,,,,,,,,,,,0.1489,,0.3641,0.59,0.08 +731,,,,,,,,,,,,,,0.1467,,0.3581,0.608,0.098 +732,,,,,,,,,,,,,,0.1427,,0.3518,0.626,0.116 +733,,,,,,,,,,,,,,0.1397,,0.346,0.644,0.134 +734,,,,,,,,,,,,,,0.1361,,0.3405,0.662,0.152 +735,,,,,,,,,,,,,,0.1321,,0.3339,0.68,0.17 +736,,,,,,,,,,,,,,0.1321,,0.3282,0.7,0.176 +737,,,,,,,,,,,,,,0.1274,,0.322,0.72,0.182 +738,,,,,,,,,,,,,,0.1208,,0.3154,0.74,0.188 +739,,,,,,,,,,,,,,0.1153,,0.3089,0.76,0.194 +740,,,,,,,,,,,,,,0.1118,,0.3028,0.78,0.2 +741,,,,,,,,,,,,,,0.1087,,0.2961,0.798,0.23 +742,,,,,,,,,,,,,,0.1048,,0.2904,0.816,0.26 +743,,,,,,,,,,,,,,0.1019,,0.2842,0.834,0.29 +744,,,,,,,,,,,,,,0.0974,,0.2791,0.852,0.32 +745,,,,,,,,,,,,,,0.0944,,0.2734,0.87,0.35 +746,,,,,,,,,,,,,,0.0888,,0.2682,0.882,0.38 +747,,,,,,,,,,,,,,0.0852,,0.2633,0.894,0.41 +748,,,,,,,,,,,,,,0.0829,,0.2588,0.906,0.44 +749,,,,,,,,,,,,,,0.0804,,0.2537,0.918,0.47 +750,,,,,,,,,,,,,,0.0762,,0.25,0.93,0.5 +751,,,,,,,,,,,,,,,,0.2455,0.944,0.524 +752,,,,,,,,,,,,,,,,0.2417,0.958,0.548 +753,,,,,,,,,,,,,,,,0.2371,0.972,0.572 +754,,,,,,,,,,,,,,,,0.2327,0.986,0.596 +755,,,,,,,,,,,,,,,,0.2278,1,0.62 +756,,,,,,,,,,,,,,,,0.2236,0.998,0.66 +757,,,,,,,,,,,,,,,,0.2188,0.996,0.7 +758,,,,,,,,,,,,,,,,0.2142,0.994,0.74 +759,,,,,,,,,,,,,,,,0.2093,0.992,0.78 +760,,,,,,,,,,,,,,,,0.2051,0.99,0.82 +761,,,,,,,,,,,,,,,,0.2,0.978,0.828 +762,,,,,,,,,,,,,,,,0.1957,0.966,0.836 +763,,,,,,,,,,,,,,,,0.1916,0.954,0.844 +764,,,,,,,,,,,,,,,,0.188,0.942,0.852 +765,,,,,,,,,,,,,,,,0.1835,0.93,0.86 +766,,,,,,,,,,,,,,,,0.1796,0.898,0.882 +767,,,,,,,,,,,,,,,,0.1754,0.866,0.904 +768,,,,,,,,,,,,,,,,0.1715,0.834,0.926 +769,,,,,,,,,,,,,,,,0.1676,0.802,0.948 +770,,,,,,,,,,,,,,,,0.1638,0.77,0.97 +771,,,,,,,,,,,,,,,,0.1598,0.748,0.976 +772,,,,,,,,,,,,,,,,0.156,0.726,0.982 +773,,,,,,,,,,,,,,,,0.1521,0.704,0.988 +774,,,,,,,,,,,,,,,,0.1488,0.682,0.994 +775,,,,,,,,,,,,,,,,0.1453,0.66,1 +776,,,,,,,,,,,,,,,,0.1421,0.638,0.996 +777,,,,,,,,,,,,,,,,0.1386,0.616,0.992 +778,,,,,,,,,,,,,,,,0.1348,0.594,0.988 +779,,,,,,,,,,,,,,,,0.1314,0.572,0.984 +780,,,,,,,,,,,,,,,,0.1281,0.55,0.98 +781,,,,,,,,,,,,,,,,0.1244,0.518,0.968 +782,,,,,,,,,,,,,,,,0.1209,0.486,0.956 +783,,,,,,,,,,,,,,,,0.1171,0.454,0.944 +784,,,,,,,,,,,,,,,,0.1135,0.422,0.932 +785,,,,,,,,,,,,,,,,0.1099,0.39,0.92 +786,,,,,,,,,,,,,,,,0.1067,0.372,0.908 +787,,,,,,,,,,,,,,,,0.1033,0.354,0.896 +788,,,,,,,,,,,,,,,,0.1,0.336,0.884 +789,,,,,,,,,,,,,,,,0.0969,0.318,0.872 +790,,,,,,,,,,,,,,,,0.094,0.3,0.86 +791,,,,,,,,,,,,,,,,0.0913,0.284,0.83 +792,,,,,,,,,,,,,,,,0.0884,0.268,0.8 +793,,,,,,,,,,,,,,,,0.0855,0.252,0.77 +794,,,,,,,,,,,,,,,,0.083,0.236,0.74 +795,,,,,,,,,,,,,,,,0.08,0.22,0.71 +796,,,,,,,,,,,,,,,,0.0776,0.208,0.682 +797,,,,,,,,,,,,,,,,0.0751,0.196,0.654 +798,,,,,,,,,,,,,,,,0.0725,0.184,0.626 +799,,,,,,,,,,,,,,,,0.0704,0.172,0.598 +800,,,,,,,,,,,,,,,,0.0679,0.16,0.57 +801,,,,,,,,,,,,,,,,0.0659,0.152,0.546 +802,,,,,,,,,,,,,,,,0.0639,0.144,0.522 +803,,,,,,,,,,,,,,,,0.0619,0.136,0.498 +804,,,,,,,,,,,,,,,,0.0602,0.128,0.474 +805,,,,,,,,,,,,,,,,0.0583,0.12,0.45 +806,,,,,,,,,,,,,,,,0.0564,0.11,0.44 +807,,,,,,,,,,,,,,,,0.0546,0.1,0.43 +808,,,,,,,,,,,,,,,,0.0529,0.09,0.42 +809,,,,,,,,,,,,,,,,0.0513,0.08,0.41 +810,,,,,,,,,,,,,,,,0.05,0.07,0.4 +811,,,,,,,,,,,,,,,,0.0487,0.068,0.378 +812,,,,,,,,,,,,,,,,0.0473,0.066,0.356 +813,,,,,,,,,,,,,,,,0.0459,0.064,0.334 +814,,,,,,,,,,,,,,,,0.0448,0.062,0.312 +815,,,,,,,,,,,,,,,,0.0437,,0.29 +816,,,,,,,,,,,,,,,,0.0429,,0.284 +817,,,,,,,,,,,,,,,,0.0418,,0.278 +818,,,,,,,,,,,,,,,,0.0408,,0.272 +819,,,,,,,,,,,,,,,,0.0397,,0.266 +820,,,,,,,,,,,,,,,,0.0386,,0.26 +821,,,,,,,,,,,,,,,,0.0374,,0.252 +822,,,,,,,,,,,,,,,,0.0366,,0.244 +823,,,,,,,,,,,,,,,,0.0356,,0.236 +824,,,,,,,,,,,,,,,,0.0347,,0.228 +825,,,,,,,,,,,,,,,,0.0337,,0.22 +826,,,,,,,,,,,,,,,,0.0331,,0.216 +827,,,,,,,,,,,,,,,,0.0324,,0.212 +828,,,,,,,,,,,,,,,,0.0316,,0.208 +829,,,,,,,,,,,,,,,,0.0309,,0.204 +830,,,,,,,,,,,,,,,,0.0302,,0.2 +831,,,,,,,,,,,,,,,,0.0294,,0.196 +832,,,,,,,,,,,,,,,,0.0289,,0.192 +833,,,,,,,,,,,,,,,,0.0282,,0.188 +834,,,,,,,,,,,,,,,,0.0276,,0.184 +835,,,,,,,,,,,,,,,,0.027,,0.18 +836,,,,,,,,,,,,,,,,0.0264,,0.178 +837,,,,,,,,,,,,,,,,0.0258,,0.176 +838,,,,,,,,,,,,,,,,0.0251,,0.174 +839,,,,,,,,,,,,,,,,0.0246,,0.172 +840,,,,,,,,,,,,,,,,0.0242,,0.17 +841,,,,,,,,,,,,,,,,0.0238,,0.164 +842,,,,,,,,,,,,,,,,0.0233,,0.158 +843,,,,,,,,,,,,,,,,0.0228,,0.152 +844,,,,,,,,,,,,,,,,0.0224,,0.146 +845,,,,,,,,,,,,,,,,0.0221 +846,,,,,,,,,,,,,,,,0.0219 +847,,,,,,,,,,,,,,,,0.0218 +848,,,,,,,,,,,,,,,,0.0217 +849,,,,,,,,,,,,,,,,0.0217 +850,,,,,,,,,,,,,,,,0.0213 \ No newline at end of file diff --git a/tests/data/sample_output.fcs b/tests/data/sample_output.fcs new file mode 100644 index 0000000..79b00c7 Binary files /dev/null and b/tests/data/sample_output.fcs differ diff --git a/tests/test_flowsym.py b/tests/test_flowsym.py new file mode 100644 index 0000000..e5f8d32 --- /dev/null +++ b/tests/test_flowsym.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +"""Tests for `flowsym` package.""" + +import pytest + +from click.testing import CliRunner + +from flowsym import flowsym +from flowsym import cli + + +@pytest.fixture +def response(): + """Sample pytest fixture. + + See more at: http://doc.pytest.org/en/latest/fixture.html + """ + # import requests + # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') + + +def test_content(response): + """Sample pytest test function with the pytest fixture as an argument.""" + # from bs4 import BeautifulSoup + # assert 'GitHub' in BeautifulSoup(response.content).title.string + + +def test_command_line_interface(): + """Test the CLI.""" + runner = CliRunner() + result = runner.invoke(cli.main) + assert result.exit_code == 0 + assert 'flowsym.cli.main' in result.output + help_result = runner.invoke(cli.main, ['--help']) + assert help_result.exit_code == 0 + assert '--help Show this message and exit.' in help_result.output diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..76dbb17 --- /dev/null +++ b/tox.ini @@ -0,0 +1,27 @@ +[tox] +envlist = py35, py36, py37, py38, flake8 + +[travis] +python = + 3.8: py38 + 3.7: py37 + 3.6: py36 + 3.5: py35 + +[testenv:flake8] +basepython = python +deps = flake8 +commands = flake8 flowsym tests + +[testenv] +setenv = + PYTHONPATH = {toxinidir} +deps = + -r{toxinidir}/requirements_dev.txt +; If you want to make tox run the tests with the same versions, create a +; requirements.txt with the pinned versions and uncomment the following line: +; -r{toxinidir}/requirements.txt +commands = + pip install -U pip + pytest --basetemp={envtmpdir} +